ReactOS 0.4.17-dev-1005-g171e1de
rsa_padding.c
Go to the documentation of this file.
1//
2// rsa_padding.c RSA padding algorithms
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6
7#include "precomp.h"
8
9#define ASN1_SEQUENCE_BYTE (0x30)
10#define ASN1_OCTET_STRING_BYTE (0x04)
11
12#define PKCS_BLOCKTYPE_1 (0x01) // This is not used, added here for completeness
13#define PKCS_BLOCKTYPE_2 (0x02)
14
15//
16// Note: we could optimize these OID lists by using the same byte sequence for
17// the long and short versions.
18//
20{
21 {12, (BYTE *)"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00"},
22 {10, (BYTE *)"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05"},
23};
24
26{
27 {9, (BYTE *)"\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00"},
28 {7, (BYTE *)"\x06\x05\x2b\x0e\x03\x02\x1a"}
29};
30
32{
33 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00"},
34 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04"}
35};
36
38{
39 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00"},
40 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01"}
41};
42
44{
45 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00"},
46 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02"}
47};
48
50{
51 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00"},
52 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03"}
53};
54
56{
57 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00"},
58 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05"}
59};
60
62{
63 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00"},
64 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06"}
65};
66
68{
69 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x07\x05\x00"},
70 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x07"}
71};
72
74{
75 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x08\x05\x00"},
76 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x08"}
77};
78
80{
81 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x09\x05\x00"},
82 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x09"}
83};
84
86{
87 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0a\x05\x00"},
88 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0a"}
89};
90
92{
93 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0b\x05\x00"},
94 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0b"}
95};
96
98{
99 {13, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0c\x05\x00"},
100 {11, (BYTE *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0c"}
101};
102
103VOID
106 _In_ PCSYMCRYPT_HASH hashAlgorithm,
107 _In_ PVOID pHashState,
109 SIZE_T cbSrc,
111 SIZE_T cbDst )
112{
113 SIZE_T cIterations = 0;
114
115 BYTE rgbHash[SYMCRYPT_HASH_MAX_RESULT_SIZE] = { 0 };
116 BYTE rgbCount[sizeof(UINT32)] = { 0 };
117 PBYTE pbCount = NULL;
118 SIZE_T cbMaskRemaining = cbDst;
119 PBYTE pbMaskIndex = pbDst;
120
121 BOOLEAN fAvoidDWORDReverse = FALSE;
122
123 SIZE_T cbHashAlg = SymCryptHashResultSize( hashAlgorithm );
124
125 cIterations = (cbDst + (cbHashAlg - 1)) / cbHashAlg;
126 if (cIterations < 256)
127 {
128 fAvoidDWORDReverse = TRUE;
129 }
130
131 for (UINT32 i = 0; i < cIterations; i++)
132 {
133 SymCryptHashInit( hashAlgorithm, pHashState );
134
135 // hash the seed
136 SymCryptHashAppend( hashAlgorithm, pHashState, pbSrc, cbSrc );
137
138 // Reverse the count bytes
139 pbCount = (BYTE*)&i;
140 if (fAvoidDWORDReverse)
141 {
142 rgbCount[3] = pbCount[0];
143 }
144 else
145 {
146 for (UINT32 j = 0; j < sizeof(UINT32); j++)
147 {
148 rgbCount[j] = pbCount[sizeof(UINT32) - j - 1];
149 }
150 }
151
152 // hash the count
153 SymCryptHashAppend( hashAlgorithm, pHashState, rgbCount, sizeof(UINT32) );
154
155 // copy the bytes from this hash into the mask buffer
156 if (cbMaskRemaining >= cbHashAlg)
157 {
158 SymCryptHashResult( hashAlgorithm, pHashState, pbMaskIndex, cbHashAlg );
159
160 cbMaskRemaining -= cbHashAlg;
161 pbMaskIndex += cbHashAlg;
162 }
163 else
164 {
165 SymCryptHashResult( hashAlgorithm, pHashState, rgbHash, cbHashAlg );
166
167 memcpy( pbMaskIndex, rgbHash, cbMaskRemaining);
168 break;
169 }
170 }
171}
172
173//
174// PKCS1 Encryption Format:
175// 0x00 || 0x02 || PS || 0x00 || M
176//
177//
181 _In_reads_bytes_( cbPlaintext ) PCBYTE pbPlaintext,
182 SIZE_T cbPlaintext,
183 _Out_writes_bytes_( cbPkcs1Format ) PBYTE pbPkcs1Format,
184 SIZE_T cbPkcs1Format )
185{
186 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
187
188 // Format: 00 02 <PS> 00 <M>
189 // <PS> 8 or more padding bytes, random, all nonzero
190 // <M> message, length between 0 and cbPKCS1Format - 11.
191 // See RFC 3447 for more details.
192
193 SIZE_T cbPS;
194 SIZE_T i;
195
196 // ensure output buffer is big enough (padding has 11 bytes overhead)
197 if( cbPkcs1Format < (cbPlaintext + 11) )
198 {
199 scError = SYMCRYPT_INVALID_ARGUMENT;
200 goto cleanup;
201 }
202
203 cbPS = cbPkcs1Format - (cbPlaintext + 3);
204
205 pbPkcs1Format[0] = 0x00;
206 pbPkcs1Format[1] = PKCS_BLOCKTYPE_2;
207
208 scError = SymCryptCallbackRandom( &pbPkcs1Format[2], cbPS );
209 if( scError != SYMCRYPT_NO_ERROR )
210 {
211 goto cleanup;
212 }
213
214 // Make sure that none of the bytes in PS is zero (as per specs)
215 for( i = 0; i < cbPS; i++ )
216 {
217 while( pbPkcs1Format[2 + i] == 0x00 )
218 {
219 scError = SymCryptCallbackRandom( &pbPkcs1Format[2+i], 1 );
220 if( scError != SYMCRYPT_NO_ERROR )
221 {
222 goto cleanup;
223 }
224 }
225 }
226
227 pbPkcs1Format[2 + cbPS] = 0x00;
228
229 memcpy(pbPkcs1Format + 3 + cbPS, pbPlaintext, cbPlaintext);
230
231cleanup:
232 return scError;
233}
234
238 _Inout_updates_bytes_( cbPkcs1Buffer ) PBYTE pbPkcs1Format,
239 SIZE_T cbPkcs1Format,
240 SIZE_T cbPkcs1Buffer,
241 _Out_writes_bytes_opt_( cbPlaintext ) PBYTE pbPlaintext,
242 SIZE_T cbPlaintext,
243 _Out_ SIZE_T *pcbPlaintext )
244{
245 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
246 UINT32 mPaddingError = 0;
247 UINT32 mBufferSizeError = 0;
248
249 UINT32 cbPlaintextResult = 0;
250 UINT32 i;
251 UINT32 mByteIsZero;
252 UINT32 mLengthFound;
253 UINT32 iFirstZero;
254 UINT32 cbPlaintextTruncated;
255
256 SYMCRYPT_ASSERT( cbPkcs1Buffer >= cbPkcs1Format );
257 SYMCRYPT_ASSERT( cbPkcs1Buffer >= 32 ); // Requirements for SymcryptScsRotateBuffer
258 SYMCRYPT_ASSERT( (cbPkcs1Buffer & (cbPkcs1Buffer - 1)) == 0 ); // must be a power of 2
259 SYMCRYPT_ASSERT( cbPkcs1Buffer <= (1 << 30 )); // Ensure we can use 31-bit masking operations
260
261 // Format: 00 02 <PS> 00 <M>
262 // <PS> 8 or more padding bytes, random, all nonzero
263 // <M> message, length between 0 and cbPKCS1Format - 11.
264 // See RFC 3447 for more details.
265 // We do not reveal the buffer contents through side-channels to avoid Bleichenbacher-style attacks
266 // This includes the plaintext length, which is determined by the location of the 00 byte
267
268 if ( cbPkcs1Format < 11 )
269 {
270 // cbPKCS1Format is public, so the if() is safe. 11 is the total overhead
271 scError = SYMCRYPT_INVALID_ARGUMENT;
272 goto cleanup;
273 }
274 // this also implies that cbPkcs1Buffer >= 16
275
276 // Check the leading bytes
277 mPaddingError |= SymCryptMask32IsNonzeroU31( pbPkcs1Format[0] ); // First byte must be = 0
278 mPaddingError |= SymCryptMask32NeqU31( pbPkcs1Format[1], PKCS_BLOCKTYPE_2 ); // Second byte must be = 2
279
280 iFirstZero = 0;
281 mLengthFound = 0;
282 for (i = 2; i < cbPkcs1Format; i++)
283 {
284 mByteIsZero = SymCryptMask32IsZeroU31( pbPkcs1Format[i] );
285
286 // remember the index of the first zero byte
287 iFirstZero |= i & mByteIsZero & ~mLengthFound;
288 mLengthFound |= mByteIsZero;
289 }
290 mPaddingError |= ~mLengthFound;
291
292 // At this point:
293 // - iFirstZero points to the first zero byte, or is 0 if there is no zero byte
294 // - mPaddingError is set if no zero byte was found
295
296 // It is an error if the first zero is at index < 10 as <PS> needs to be at least 8 bytes
297 mPaddingError |= SymCryptMask32LtU31( iFirstZero, 10 );
298
299 // Compute the # bytes of the message; 0 if there was a padding error
300 cbPlaintextResult = ~mPaddingError & ((UINT32)(cbPkcs1Format - iFirstZero - 1));
301
302 // We're done if the caller didn't want the actual message, but only the size.
303 // We do that before checking the size of the plaintext buffer so that callers who
304 // only want the size do not get an error.
305 if( pbPlaintext == NULL )
306 {
307 // Condition is public.
308 goto cleanup;
309 }
310
311 // Checking that the output buffer is large enough is a bit tricky as we have a SIZE_T as
312 // buffer size, but we like to work on 31-bit integers as they have better mask algorithm perf.
313 // We can truncate the SIZE_T and check for equality, which is side-channel safe.
314 cbPlaintextTruncated = ((UINT32) cbPlaintext) & 0x7fffffff; // Truncate to 31 bits
315 if( cbPlaintextTruncated == cbPlaintext )
316 {
317 // Condition is public as we write the whole plaintext buffer anyway.
318 mBufferSizeError = SymCryptMask32LtU31( cbPlaintextTruncated, cbPlaintextResult );
319 }
320
321 // The message starts at iFirstZero + 1, which is a variable location so we can't just memcpy it without
322 // revealing information through side channels.
323 // Instead we rotate the buffer left (side-channel safe) so that the message appears at the front.
324 // Rotation constant is such that the message appears at the start.
325 SymCryptScsRotateBuffer( pbPkcs1Format, cbPkcs1Buffer, (iFirstZero + 1) & (cbPkcs1Buffer - 1) );
326
327 // The ScsCopy function can copy the data to the destination buffer, but the input buffer must be
328 // as long as the output buffer. We can't just use cbPlaintext as the output buffer size, as it is
329 // unbounded. But we can limit it to cbPkcs1Format as that is the public key size and is public.
330 SymCryptScsCopy( pbPkcs1Format, cbPlaintextResult, pbPlaintext, SYMCRYPT_MIN( cbPlaintext, cbPkcs1Format ) );
331
332cleanup:
333 // Update scError with the two error masks. Padding error given highest priority.
334 scError ^= mBufferSizeError & (scError ^ SYMCRYPT_BUFFER_TOO_SMALL);
335 scError ^= mPaddingError & (scError ^ SYMCRYPT_INVALID_ARGUMENT);
336
337 *pcbPlaintext = cbPlaintextResult;
338 return scError;
339}
340
341//
342// OAEP Encryption Format:
343// +----------+---------+-------+
344// DB = | lHash | PS | M |
345// +----------+---------+-------+
346// |
347// +----------+ V
348// | seed |--> MGF ---> xor
349// +----------+ |
350// | |
351// +--+ V |
352// |00| xor <----- MGF <-----|
353// +--+ | |
354// | | |
355// V V V
356// +--+----------+----------------------------+
357// EM = |00|maskedSeed| maskedDB |
358// +--+----------+----------------------------+
359//
360// PS = zero or more bytes 0x00 || 0x01
361//
365 _In_reads_bytes_( cbPlaintext ) PCBYTE pbPlaintext,
366 SIZE_T cbPlaintext,
367 _In_ PCSYMCRYPT_HASH hashAlgorithm,
368 _In_reads_bytes_( cbLabel ) PCBYTE pbLabel,
369 SIZE_T cbLabel,
372 _Out_writes_bytes_( cbOaepFormat ) PBYTE pbOaepFormat,
373 SIZE_T cbOaepFormat,
376{
377 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
378
379 PVOID pHashState;
380
381 PBYTE pbSeedInternal;
382 PBYTE pbSeedMask;
383 PBYTE pbDB;
384 PBYTE pbDBMask;
385
386 SIZE_T cbDB;
387 SIZE_T cbPS;
388
389 SIZE_T cbHash = SymCryptHashResultSize( hashAlgorithm );
390 SIZE_T cbHashState = SymCryptHashStateSize( hashAlgorithm );
391
393
394 // OAEP overhead is 2 + 2 * size of hash result
395 if( cbOaepFormat < (cbPlaintext + (cbHash * 2) + 2) ||
396 ((pbSeed!=NULL) && (cbSeed>cbHash)) ||
397 ((pbSeed==NULL) && (cbSeed!=0)) )
398 {
399 scError = SYMCRYPT_INVALID_ARGUMENT;
400 goto cleanup;
401 }
402
403 cbPS = cbOaepFormat - (cbPlaintext + (cbHash * 2) + 2);
404 cbDB = cbOaepFormat - (cbHash + 1);
405
406 SYMCRYPT_ASSERT( cbScratch >= cbHashState + (cbHash * 2) + (cbDB * 2) );
407
408 pHashState = (PVOID) pbScratch;
409 pbSeedInternal = pbScratch + cbHashState;
410 pbSeedMask = pbSeedInternal + cbHash;
411 pbDB = pbSeedMask + cbHash;
412 pbDBMask = pbDB + cbDB;
413
414 // hash the label
415 SymCryptHash( hashAlgorithm, pbLabel, cbLabel, pbDB, cbHash );
416
417 SymCryptWipe(pbDB + cbHash, cbPS);
418 pbDB[cbHash + cbPS] = 0x01;
419
420 // dcl - are we quite sure that none of these numbers are under attacker control?
421 memcpy(pbDB + cbHash + cbPS + 1, pbPlaintext, cbPlaintext);
422
423 if (NULL == pbSeed)
424 {
425 // generate the random seed (same length as the hash result)
426 scError = SymCryptCallbackRandom( pbSeedInternal, cbHash );
427 if (scError != SYMCRYPT_NO_ERROR)
428 {
429 goto cleanup;
430 }
431 }
432 else
433 {
434 SymCryptWipe( pbSeedInternal, cbHash );
435 memcpy(pbSeedInternal, pbSeed, cbSeed);
436 }
437
438 // MGF(seed)
440 hashAlgorithm,
441 pHashState,
442 pbSeedInternal,
443 cbHash,
444 pbDBMask,
445 cbDB);
446
447 // set the most significant byte to 0x00
448 pbOaepFormat[0] = 0x00;
449
450 // XOR the DB and the mask MGF(seed)
451 for (UINT32 i = 0; i < cbDB; i++)
452 {
453 pbOaepFormat[cbHash + 1 + i] = pbDB[i] ^ pbDBMask[i];
454 }
455
456 // MGF(masked DB)
458 hashAlgorithm,
459 pHashState,
460 pbOaepFormat + cbHash + 1,
461 cbDB,
462 pbSeedMask,
463 cbHash);
464
465 // XOR the seed and the seed mask MGF(masked DB)
466 for (UINT32 i = 0; i < cbHash; i++)
467 {
468 pbOaepFormat[1 + i] = pbSeedInternal[i] ^ pbSeedMask[i];
469 }
470
471 scError = SYMCRYPT_NO_ERROR;
472
473cleanup:
474
475 return scError;
476}
477
481 _In_reads_bytes_( cbOAEPFormat )
482 PCBYTE pbOAEPFormat,
483 SIZE_T cbOAEPFormat,
484 _In_ PCSYMCRYPT_HASH hashAlgorithm,
485 _In_reads_bytes_( cbLabel ) PCBYTE pbLabel,
486 SIZE_T cbLabel,
488 _Out_writes_bytes_( cbPlaintext )
489 PBYTE pbPlaintext,
490 SIZE_T cbPlaintext,
491 _Out_ SIZE_T *pcbPlaintext,
493 PBYTE pbScratch,
495{
496 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
497
498 PVOID pHashState;
499
500 PBYTE pbSeedMask;
502 PBYTE pbDBMask;
503 PBYTE pbDB;
504 PBYTE pbLabelHash;
505 UINT32 mPaddingError;
506
507 SIZE_T cbDB;
508
509 SIZE_T cnt = 0;
510
511 SIZE_T cbHashAlg = SymCryptHashResultSize( hashAlgorithm );
512 SIZE_T cbHashState = SymCryptHashStateSize( hashAlgorithm );
513
515
516 if (flags != 0)
517 {
518 scError = SYMCRYPT_INVALID_ARGUMENT;
519 goto cleanup;
520 }
521
522 // check if the most significant byte is set to 0x00
523 mPaddingError = SymCryptMask32IsNonzeroU31( pbOAEPFormat[0] );
524
525 // Padding overhead is 2 hash values plus 2 bytes
526 if( cbOAEPFormat < (2*cbHashAlg + 2) )
527 {
528 scError = SYMCRYPT_INVALID_ARGUMENT;
529 goto cleanup;
530 }
531
532 cbDB = cbOAEPFormat - (cbHashAlg + 1);
533
534 SYMCRYPT_ASSERT( cbScratch >= cbHashState + (cbHashAlg * 3) + (cbDB * 2) );
535
536 pHashState = (PVOID) pbScratch;
537 pbSeedMask = pbScratch + cbHashState;
538 pbSeed = pbSeedMask + cbHashAlg;
539 pbDBMask = pbSeed + cbHashAlg;
540 pbDB = pbDBMask + cbDB;
541 pbLabelHash = pbDB + cbDB;
542
543 // MGF(masked DB)
545 hashAlgorithm,
546 pHashState,
547 pbOAEPFormat + cbHashAlg + 1,
548 cbDB,
549 pbSeedMask,
550 cbHashAlg);
551
552 // XOR the masked seed and the seed mask MGF(masked DB)
553 for (UINT32 i = 0; i < cbHashAlg; i++)
554 {
555 pbSeed[i] = pbOAEPFormat[1 + i] ^ pbSeedMask[i];
556 }
557
558 // MGF(seed)
560 hashAlgorithm,
561 pHashState,
562 pbSeed,
563 cbHashAlg,
564 pbDBMask,
565 cbDB);
566
567 // XOR the masked DB and the mask MGF(seed)
568 for (UINT32 i = 0; i < cbDB; i++)
569 {
570 pbDB[i] = pbOAEPFormat[cbHashAlg + 1 + i] ^ pbDBMask[i];
571 }
572
573 // hash the label
574 SymCryptHash( hashAlgorithm, pbLabel, cbLabel, pbLabelHash, cbHashAlg );
575
576 // check the label hash
577 mPaddingError |= SymCryptMask32IsZeroU31( SymCryptEqual( pbLabelHash, pbDB, cbHashAlg ) );
578
579 //
580 // At this point we have verified the leading 0 byte and the label hash, with any
581 // errors in mPaddingError. We could continue to make the entire padding removal
582 // side-channel safe like we do in the PKCS1 padding case, but that is not necessary.
583 // The side-channel only leaks data if the attacker can trigger two different behaviours
584 // and derive information from the difference.
585 // This is relatively easy to do with something like a match on 1 or 2 bytes because the
586 // chance of satisfying the check on a random input is still useful. But here we have
587 // matched 33 bytes (assuming a 32-byte hash) and the Bleichenbacher style attacks don't
588 // work beyond this point. Basically, these attacks produce ciphertexts without knowing
589 // the corresponding plaintext, and the chance of the label hash matching is something
590 // like 2^{-256}. So these ciphertexts will always fail right here, and there is no
591 // difference of behaviour that leaks data to the attacker.
592 // Thus, we can switch back to normal processing of the errors here.
593 //
594
595 if( mPaddingError != 0 )
596 {
597 scError = SYMCRYPT_INVALID_ARGUMENT;
598 goto cleanup;
599 }
600
601 // check the PS
602 for (cnt = cbHashAlg; cnt < cbDB; cnt++)
603 {
604 if (pbDB[cnt] == 0x01)
605 {
606 cnt++;
607 break;
608 }
609 else if (pbDB[cnt] != 0x00)
610 {
611 scError = SYMCRYPT_INVALID_ARGUMENT;
612 goto cleanup;
613 }
614 }
615
616 if (pbDB[cnt - 1] != 0x01)
617 {
618 scError = SYMCRYPT_INVALID_ARGUMENT;
619 goto cleanup;
620 }
621
622 // the rest is data
623 *pcbPlaintext = cbDB - cnt;
624
625 if(NULL == pbPlaintext)
626 {
627 scError = SYMCRYPT_NO_ERROR;
628 goto cleanup;
629 }
630
631 if (cbPlaintext < *pcbPlaintext)
632 {
633 scError = SYMCRYPT_BUFFER_TOO_SMALL;
634 goto cleanup;
635 }
636
637 memcpy(pbPlaintext, pbDB + cnt, *pcbPlaintext);
638
639 scError = SYMCRYPT_NO_ERROR;
640
641cleanup:
642
643 return scError;
644}
645
646//
647// PKCS1 Signature Format:
648//
653 SIZE_T cbHash,
654 _In_reads_bytes_( cbHashOid )
655 PCBYTE pbHashOid,
656 SIZE_T cbHashOid,
658 _Out_writes_bytes_( cbPKCS1Format )
659 PBYTE pbPKCS1Format,
660 SIZE_T cbPKCS1Format )
661{
662 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
663
664 SIZE_T cbEncoding;
665 SIZE_T cbPadding;
666 SIZE_T cbOidOffset;
667
668 BOOLEAN fInsertASN1 = TRUE;
669
671 {
672 scError = SYMCRYPT_INVALID_ARGUMENT;
673 goto cleanup;
674 }
675
676 // Simple check to avoid funky behavior if cbHash is close to SIZE_MAX
677 if (cbHash >= cbPKCS1Format)
678 {
679 scError = SYMCRYPT_INVALID_ARGUMENT;
680 goto cleanup;
681 }
682
683 fInsertASN1 = ((flags & SYMCRYPT_FLAG_RSA_PKCS1_NO_ASN1) == 0);
684
685 if (fInsertASN1)
686 {
687 if ( (pbHashOid!=NULL) && (cbHashOid>0) )
688 {
689 // determine the length of the ASN1 Encoding
690 // 2 sequence bytes, 1 id byte and 3 length bytes
691 cbEncoding = 6 + cbHashOid + cbHash;
692 }
693 else
694 {
695 if (cbHashOid > 0)
696 {
697 // The caller has passed a NULL hash and a non 0 size for it.
698 // We can't guess the intent, hence we fail
699 scError = SYMCRYPT_INVALID_ARGUMENT;
700 goto cleanup;
701 }
702
703 // special case for MD5 hash without OID
704 cbEncoding = 2 + cbHash;
705 }
706
707 // we don't support encodings longer than 128 bytes,
708 // with this check we know that the length of the OID as
709 // well as the length of the hash value will each fit in
710 // one byte
711 if (cbEncoding > 0x80)
712 {
713 scError = SYMCRYPT_INVALID_ARGUMENT;
714 goto cleanup;
715 }
716 }
717 else
718 {
719 cbEncoding = cbHash;
720 }
721
722 // In a few scenarios (involving small RSA keys), the new large SHA
723 // hashes are too big to be signed by the specified key.
724 // There must be at least 8 bytes of 0xff.
725 if (3 + 8 + cbEncoding > cbPKCS1Format)
726 {
727 scError = SYMCRYPT_INVALID_ARGUMENT;
728 goto cleanup;
729 }
730
731 cbPadding = cbPKCS1Format - 3 - cbEncoding;
732
733
734 // insert the block type and delimiters
735 pbPKCS1Format[0] = 0x00;
736 pbPKCS1Format[1] = 0x01;
737 pbPKCS1Format[2 + cbPadding] = 0x00;
738
739 // insert the type 1 padding
740 memset(pbPKCS1Format + 2, 0xff, cbPadding);
741
742 if (fInsertASN1)
743 {
744 cbOidOffset = 1;
745 if ( (pbHashOid!=NULL) && (cbHashOid>0) )
746 {
747 // insert the algorithm encoding
748 pbPKCS1Format[2 + cbPadding + 1] = ASN1_SEQUENCE_BYTE;
749 pbPKCS1Format[2 + cbPadding + 2] = (BYTE)cbEncoding - 2;
750
751 // insert the sequence string byte, length of the hash and the hash value
752 pbPKCS1Format[2 + cbPadding + 3] = ASN1_SEQUENCE_BYTE;
753 pbPKCS1Format[2 + cbPadding + 4] = (BYTE)cbHashOid;
754 cbOidOffset += 4;
755 memcpy(pbPKCS1Format + 2 + cbPadding + cbOidOffset, pbHashOid, cbHashOid);
756 }
757
758 // insert the octet string byte, length of the hash and the hash value
759 pbPKCS1Format[2 + cbPadding + cbOidOffset + cbHashOid] = ASN1_OCTET_STRING_BYTE;
760 pbPKCS1Format[2 + cbPadding + cbOidOffset + cbHashOid + 1] = (BYTE)cbHash;
761 memcpy(pbPKCS1Format + 2 + cbPadding + cbOidOffset + cbHashOid + 2, pbHash, cbHash);
762 }
763 else
764 {
765 memcpy(pbPKCS1Format + 3 + cbPadding, pbHash, cbHash);
766 }
767
768 scError = SYMCRYPT_NO_ERROR;
769
770cleanup:
771
772 return scError;
773}
774
775//
776// Check if a PKCS1 padding is valid with regard to a hash oid
777//
782 SIZE_T cbHash,
783 _In_reads_bytes_( cbHashOid )
784 PCBYTE pbHashOid,
785 SIZE_T cbHashOid,
786 _In_reads_bytes_( cbPKCS1Format )
787 PCBYTE pbPKCS1Format,
789 _Out_writes_bytes_( cbPKCS1Format )
790 PBYTE pbScratch,
791 SIZE_T cbPKCS1Format)
792{
793 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
794
795 SymCryptWipe(pbScratch, cbPKCS1Format);
796
798 pbHash,
799 cbHash,
800 pbHashOid,
801 cbHashOid,
802 flags,
803 pbScratch,
804 cbPKCS1Format );
805 if (scError != SYMCRYPT_NO_ERROR)
806 {
807 goto cleanup;
808 }
809
810 if ( SymCryptEqual(pbScratch, pbPKCS1Format, cbPKCS1Format) )
811 {
812 scError = SYMCRYPT_NO_ERROR;
813 }
814 else
815 {
816 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
817 }
818
819cleanup:
820
821 return scError;
822}
823
824
829 SIZE_T cbHash,
830 _In_reads_( nOIDCount ) PCSYMCRYPT_OID pHashOIDs,
831 _In_ SIZE_T nOIDCount,
832 _In_reads_bytes_( cbPKCS1Format )
833 PCBYTE pbPKCS1Format,
834 SIZE_T cbPKCS1Format,
837 PBYTE pbScratch,
839{
840 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
841 UINT32 i = 0;
842
844 SYMCRYPT_ASSERT( cbScratch >= cbPKCS1Format );
845
847 {
848 scError = SYMCRYPT_INVALID_ARGUMENT;
849 goto cleanup;
850 }
851
852 //
853 // Verify padding and the hash value
854 //
855 if (pHashOIDs)
856 {
857 for (i = 0; i < nOIDCount; i++)
858 {
860 pbHash,
861 cbHash,
862 pHashOIDs[i].pbOID,
863 pHashOIDs[i].cbOID,
864 pbPKCS1Format,
865 0,
866 pbScratch,
867 cbPKCS1Format );
868 if (scError == SYMCRYPT_NO_ERROR)
869 {
870 break;
871 }
872 }
873 }
874
875 if ((pHashOIDs == NULL ) ||
876 (scError != SYMCRYPT_NO_ERROR &&
878 {
879 // if no OID is passed in, or
880 // OID is passed in but failed verification, but OID is optional
882 pbHash,
883 cbHash,
884 NULL,
885 0,
886 pbPKCS1Format,
888 pbScratch,
889 cbPKCS1Format );
890 }
891
892cleanup:
893
894 return scError;
895}
896
897//
898// PSS Signature Format:
899// +--------+----------+----------+
900// M' = |Padding1| Hash M | salt |
901// +--------+----------+----------+
902// |
903// +--------+----------+ V
904// DB = |Padding2| salt | Hash
905// +--------+----------+ |
906// | |
907// V | +--+
908// xor <--- MGF <---| |bc|
909// | | +--+
910// | | |
911// V V V
912// +-------------------+----------+--+
913// EM = | maskedDB | H |bc|
914// +-------------------+----------+--+
915//
920 SIZE_T cbHash,
921 _In_ PCSYMCRYPT_HASH hashAlgorithm,
922 _In_reads_bytes_opt_( cbSalt )
923 PCBYTE pbSalt,
924 _In_range_(0, cbPSSFormat) SIZE_T cbSalt,
927 _Out_writes_bytes_( cbPSSFormat )
928 PBYTE pbPSSFormat,
929 SIZE_T cbPSSFormat,
931 PBYTE pbScratch,
933{
934 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
935
936 PVOID pHashState;
937
938 PBYTE pbMPrime;
939 PBYTE pbDB;
940 PBYTE pbDBMask;
941
942 SIZE_T cbDB;
943 SIZE_T cbMPrime;
944 SIZE_T cbPadding2;
945
946 SIZE_T dwZeroBits = 0; // Number of bits of the leftmost bit to be zeroed
947
948 SIZE_T cbHashAlg = SymCryptHashResultSize( hashAlgorithm );
949 SIZE_T cbHashState = SymCryptHashStateSize( hashAlgorithm );
950
952
953 if ((cbPSSFormat == 0) || (pbPSSFormat == NULL))
954 {
955 scError = SYMCRYPT_INVALID_ARGUMENT;
956 goto cleanup;
957 }
958
959 // Corner case of RFC 3447 for PSS:
960 // If nBitsOfModulus == 1 mod 8, then emBits = nBitsOfModulus - 1 == 0 mod 8
961 // Thus the size of the input buffer in bytes is emLen = ceil(emBits /8),
962 // one smaller than the size of the modulus. Fix this here by setting the
963 // leftmost byte of the output equal to 0.
964 if (nBitsOfModulus%8 == 1)
965 {
966 pbPSSFormat[0] = 0;
967 pbPSSFormat++;
968 cbPSSFormat--;
969 }
970
971 if ((flags!=0) ||
972 (cbPSSFormat < (cbHashAlg + cbSalt + 2)) )
973 {
974 scError = SYMCRYPT_INVALID_ARGUMENT;
975 goto cleanup;
976 }
977
978 cbDB = cbPSSFormat - (cbHashAlg + 1);
979 cbPadding2 = cbDB - cbSalt - 1;
980 cbMPrime = 8 + cbHash + cbSalt;
981
982 SYMCRYPT_ASSERT( cbScratch >= cbHashState + cbMPrime + (cbDB * 2) );
983
984 pHashState = (PVOID) pbScratch;
985 pbMPrime = pbScratch + cbHashState;
986 pbDB = pbMPrime + cbMPrime;
987 pbDBMask = pbDB + cbDB;
988
989 // set up the M Prime
990 SymCryptWipe(pbMPrime, 8);
991 memcpy(pbMPrime + 8, pbHash, cbHash);
992
993 if (NULL == pbSalt)
994 {
995 // generate the random salt
996 scError = SymCryptCallbackRandom(
997 pbMPrime + 8 + cbHash,
998 cbSalt);
999 if (scError != SYMCRYPT_NO_ERROR)
1000 {
1001 goto cleanup;
1002 }
1003 }
1004 else
1005 {
1006 // copy the salt passed
1007 memcpy(pbMPrime + 8 + cbHash, pbSalt, cbSalt);
1008 }
1009
1010 // hash the MPrime
1011 SymCryptHash( hashAlgorithm, pbMPrime, cbMPrime, pbPSSFormat + cbDB, cbHashAlg );
1012
1013 // copy the same salt into the DB
1014 SymCryptWipe(pbDB, cbPadding2);
1015 pbDB[cbPadding2] = 0x01;
1016 memcpy(pbDB + cbPadding2 + 1, pbMPrime + 8 + cbHash, cbSalt);
1017
1018 // MGF(Hash of MPrime)
1020 hashAlgorithm,
1021 pHashState,
1022 pbPSSFormat + cbDB,
1023 cbHashAlg,
1024 pbDBMask,
1025 cbDB);
1026
1027 // XOR the DB and the mask MGF(seed)
1028 for (UINT32 i = 0; i < cbDB; i++)
1029 {
1030 pbPSSFormat[i] = pbDB[i] ^ pbDBMask[i];
1031 }
1032
1033 // calculate the number of bits to be zeroed
1034 dwZeroBits = 8*cbPSSFormat + 1 - nBitsOfModulus;
1035
1036 // mask off dwZeroBits worth of the encoded message
1037 pbPSSFormat[0] &= (BYTE)(0xff >> dwZeroBits);
1038
1039 // set the least significant byte of pbPSSFormat to bc
1040 pbPSSFormat[cbPSSFormat - 1] = 0xbc;
1041
1042 scError = SYMCRYPT_NO_ERROR;
1043
1044cleanup:
1045
1046 return scError;
1047}
1048
1052 _In_reads_bytes_( cbHash ) PCBYTE pbHash,
1053 SIZE_T cbHash,
1054 _In_ PCSYMCRYPT_HASH hashAlgorithm,
1055 _In_range_(0, cbPSSFormat) SIZE_T cbSalt,
1056 _In_reads_bytes_( cbPSSFormat )
1057 PCBYTE pbPSSFormat,
1058 SIZE_T cbPSSFormat,
1060 UINT32 flags,
1062 PBYTE pbScratch,
1064{
1065 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1066
1067 PVOID pHashState;
1068
1069 PBYTE pbDBMask;
1070 PBYTE pbMPrime;
1071 PBYTE pbMPrimeHash;
1072 PCBYTE pbHashOfMPrimeIndex;
1073
1074 SIZE_T cbDB;
1075 SIZE_T cbMPrime;
1076 SIZE_T cbPadding2;
1077 SIZE_T cbSaltObserved;
1078
1079 SIZE_T dwZeroBits = 0; // Number of bits of the leftmost bit to be zeroed
1080
1081 SIZE_T cbHashAlg = SymCryptHashResultSize( hashAlgorithm );
1082 SIZE_T cbHashState = SymCryptHashStateSize( hashAlgorithm );
1083
1085
1087 (cbPSSFormat == 0) ||
1088 (pbPSSFormat == NULL))
1089 {
1090 scError = SYMCRYPT_INVALID_ARGUMENT;
1091 goto cleanup;
1092 }
1093
1094 // Corner case of RFC 3447 for PSS:
1095 // If nBitsOfModulus == 1 mod 8, then emBits = nBitsOfModulus - 1 == 0 mod 8
1096 // Thus the size of the input buffer in bytes is emLen = ceil(emBits /8),
1097 // one smaller than the size of the modulus. Fix this here by checking that the
1098 // leftmost byte of the input equals 0.
1099 if (nBitsOfModulus%8 == 1)
1100 {
1101 if (pbPSSFormat[0] != 0)
1102 {
1103 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
1104 goto cleanup;
1105 }
1106 pbPSSFormat++;
1107 cbPSSFormat--;
1108 }
1109
1110 // calculate the number of bits to be zeroed
1111 dwZeroBits = 8*cbPSSFormat + 1 - nBitsOfModulus;
1112
1113 // check the most significant dwZeroBits bits to ensure they're zero and
1114 // check the least significant byte
1115 if( (cbPSSFormat < (cbHashAlg + cbSalt + 2)) ||
1116 (pbPSSFormat[0] & (BYTE)(0xff << (8 - dwZeroBits))) != 0 ||
1117 pbPSSFormat[cbPSSFormat - 1] != 0xbc
1118 )
1119 {
1120 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
1121 goto cleanup;
1122 }
1123
1124 cbDB = cbPSSFormat - (cbHashAlg + 1);
1125
1126 pHashState = (PVOID) pbScratch;
1127 pbDBMask = pbScratch + cbHashState;
1128
1129 // index to hash of M Prime
1130 pbHashOfMPrimeIndex = pbPSSFormat + (cbPSSFormat - (cbHashAlg + 1));
1131
1132 // MGF(masked DB)
1134 hashAlgorithm,
1135 pHashState,
1136 pbHashOfMPrimeIndex,
1137 cbHashAlg,
1138 pbDBMask,
1139 cbDB);
1140
1141 // XOR the DB and the DB mask and store the result in pbDBMask (not needed after this)
1142 for (UINT32 i = 0; i < cbDB; i++)
1143 {
1144 pbDBMask[i] = pbPSSFormat[i] ^ pbDBMask[i];
1145 }
1146
1147 // mask off the first dwZeroBits
1148 pbDBMask[0] &= (BYTE)(0xff >> dwZeroBits);
1149
1150 // find the length of the all-zeroes padding2 in pbDBMask
1151 // padding2 must be terminated by a 0x01 byte
1152 for (cbPadding2 = 0; cbPadding2 < (cbDB - cbSalt); cbPadding2++)
1153 {
1154 if (pbDBMask[cbPadding2] == 0x01)
1155 {
1156 // we have reached the end of padding2
1157 break;
1158 }
1159
1160 if (pbDBMask[cbPadding2] != 0x00)
1161 {
1162 // non-zero byte in what should be padding2
1163 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
1164 goto cleanup;
1165 }
1166 }
1167
1168 // Here we have either:
1169 // cbPadding2 == cbDB - cbSalt, which means the padding is too long
1170 // or
1171 // cbPadding2 <= cbDB - cbSalt - 1, and we have broken out of the loop when we found the 0x01 byte
1172 if( cbPadding2 == cbDB - cbSalt )
1173 {
1174 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
1175 goto cleanup;
1176 }
1177
1178 cbSaltObserved = cbDB - cbPadding2 - 1;
1179 // cbSalt <= cbDB - cbPadding2 - 1 = cbSaltObserved
1180 // so cbSaltObserved is acceptable value for signature verification
1181 // with SYMCRYPT_FLAG_RSA_PSS_VERIFY_WITH_MINIMUM_SALT
1182
1184 cbSaltObserved != cbSalt )
1185 {
1186 // When SYMCRYPT_FLAG_RSA_PSS_VERIFY_WITH_MINIMUM_SALT not specified,
1187 // we require salt length observed to exactly match the caller provided salt length
1188 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
1189 goto cleanup;
1190 }
1191
1192 pbMPrime = pbDBMask + cbDB;
1193 cbMPrime = 8 + cbHash + cbSaltObserved;
1194 pbMPrimeHash = pbMPrime + cbMPrime;
1195
1196 SYMCRYPT_ASSERT( cbScratch >= cbHashState + cbDB + cbMPrime + cbHashAlg );
1197
1198 // create the M Prime
1199 SymCryptWipe(pbMPrime, 8);
1200 memcpy(pbMPrime + 8, pbHash, cbHash);
1201 memcpy(pbMPrime + 8 + cbHash,
1202 pbDBMask + (cbDB - cbSaltObserved),
1203 cbSaltObserved);
1204
1205 // hash the M Prime
1206 SymCryptHash( hashAlgorithm, pbMPrime, cbMPrime, pbMPrimeHash, cbHashAlg );
1207
1208 if ( !SymCryptEqual(pbPSSFormat + cbDB, pbMPrimeHash, cbHashAlg) )
1209 {
1210 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
1211 goto cleanup;
1212 }
1213
1214 scError = SYMCRYPT_NO_ERROR;
1215
1216cleanup:
1217 return scError;
1218}
unsigned char BOOLEAN
Definition: actypes.h:127
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static void cleanup(void)
Definition: main.c:1335
GLbitfield flags
Definition: glext.h:7161
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptCallbackRandom(BYTE *buf, SIZE_T size)
Definition: implglue.c:56
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Out_writes_bytes_opt_(s)
Definition: no_sal2.h:228
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_range_(l, h)
Definition: no_sal2.h:368
#define _Inout_updates_bytes_(s)
Definition: no_sal2.h:184
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define _In_reads_bytes_opt_(s)
Definition: no_sal2.h:224
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
BYTE * PBYTE
Definition: pedump.c:66
const SYMCRYPT_OID SymCryptSha3_256OidList[]
Definition: rsa_padding.c:73
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaPkcs1CheckSignaturePadding(_In_reads_bytes_(cbHash) PCBYTE pbHash, SIZE_T cbHash, _In_reads_bytes_(cbHashOid) PCBYTE pbHashOid, SIZE_T cbHashOid, _In_reads_bytes_(cbPKCS1Format) PCBYTE pbPKCS1Format, UINT32 flags, _Out_writes_bytes_(cbPKCS1Format) PBYTE pbScratch, SIZE_T cbPKCS1Format)
Definition: rsa_padding.c:780
const SYMCRYPT_OID SymCryptSha512_256OidList[]
Definition: rsa_padding.c:61
const SYMCRYPT_OID SymCryptSha256OidList[]
Definition: rsa_padding.c:37
#define ASN1_SEQUENCE_BYTE
Definition: rsa_padding.c:9
const SYMCRYPT_OID SymCryptSha384OidList[]
Definition: rsa_padding.c:43
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaOaepRemoveEncryptionPadding(_In_reads_bytes_(cbOAEPFormat) PCBYTE pbOAEPFormat, SIZE_T cbOAEPFormat, _In_ PCSYMCRYPT_HASH hashAlgorithm, _In_reads_bytes_(cbLabel) PCBYTE pbLabel, SIZE_T cbLabel, UINT32 flags, _Out_writes_bytes_(cbPlaintext) PBYTE pbPlaintext, SIZE_T cbPlaintext, _Out_ SIZE_T *pcbPlaintext, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: rsa_padding.c:480
const SYMCRYPT_OID SymCryptShake256OidList[]
Definition: rsa_padding.c:97
const SYMCRYPT_OID SymCryptSha3_384OidList[]
Definition: rsa_padding.c:79
const SYMCRYPT_OID SymCryptSha512OidList[]
Definition: rsa_padding.c:49
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaPssVerifySignaturePadding(_In_reads_bytes_(cbHash) PCBYTE pbHash, SIZE_T cbHash, _In_ PCSYMCRYPT_HASH hashAlgorithm, _In_range_(0, cbPSSFormat) SIZE_T cbSalt, _In_reads_bytes_(cbPSSFormat) PCBYTE pbPSSFormat, SIZE_T cbPSSFormat, UINT32 nBitsOfModulus, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: rsa_padding.c:1051
const SYMCRYPT_OID SymCryptSha3_224OidList[]
Definition: rsa_padding.c:67
#define PKCS_BLOCKTYPE_2
Definition: rsa_padding.c:13
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaPkcs1ApplySignaturePadding(_In_reads_bytes_(cbHash) PCBYTE pbHash, SIZE_T cbHash, _In_reads_bytes_(cbHashOid) PCBYTE pbHashOid, SIZE_T cbHashOid, UINT32 flags, _Out_writes_bytes_(cbPKCS1Format) PBYTE pbPKCS1Format, SIZE_T cbPKCS1Format)
Definition: rsa_padding.c:651
const SYMCRYPT_OID SymCryptShake128OidList[]
Definition: rsa_padding.c:91
const SYMCRYPT_OID SymCryptSha224OidList[]
Definition: rsa_padding.c:31
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaPkcs1VerifySignaturePadding(_In_reads_bytes_(cbHash) PCBYTE pbHash, SIZE_T cbHash, _In_reads_(nOIDCount) PCSYMCRYPT_OID pHashOIDs, _In_ SIZE_T nOIDCount, _In_reads_bytes_(cbPKCS1Format) PCBYTE pbPKCS1Format, SIZE_T cbPKCS1Format, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: rsa_padding.c:827
const SYMCRYPT_OID SymCryptMd5OidList[]
Definition: rsa_padding.c:19
VOID SYMCRYPT_CALL SymCryptRsaPaddingMaskGeneration(_In_ PCSYMCRYPT_HASH hashAlgorithm, _In_ PVOID pHashState, _In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, _Out_writes_bytes_(cbDst) PBYTE pbDst, SIZE_T cbDst)
Definition: rsa_padding.c:105
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaPkcs1RemoveEncryptionPadding(_Inout_updates_bytes_(cbPkcs1Buffer) PBYTE pbPkcs1Format, SIZE_T cbPkcs1Format, SIZE_T cbPkcs1Buffer, _Out_writes_bytes_opt_(cbPlaintext) PBYTE pbPlaintext, SIZE_T cbPlaintext, _Out_ SIZE_T *pcbPlaintext)
Definition: rsa_padding.c:237
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaPssApplySignaturePadding(_In_reads_bytes_(cbHash) PCBYTE pbHash, SIZE_T cbHash, _In_ PCSYMCRYPT_HASH hashAlgorithm, _In_reads_bytes_opt_(cbSalt) PCBYTE pbSalt, _In_range_(0, cbPSSFormat) SIZE_T cbSalt, UINT32 nBitsOfModulus, UINT32 flags, _Out_writes_bytes_(cbPSSFormat) PBYTE pbPSSFormat, SIZE_T cbPSSFormat, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: rsa_padding.c:918
#define ASN1_OCTET_STRING_BYTE
Definition: rsa_padding.c:10
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaPkcs1ApplyEncryptionPadding(_In_reads_bytes_(cbPlaintext) PCBYTE pbPlaintext, SIZE_T cbPlaintext, _Out_writes_bytes_(cbPkcs1Format) PBYTE pbPkcs1Format, SIZE_T cbPkcs1Format)
Definition: rsa_padding.c:180
const SYMCRYPT_OID SymCryptSha3_512OidList[]
Definition: rsa_padding.c:85
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRsaOaepApplyEncryptionPadding(_In_reads_bytes_(cbPlaintext) PCBYTE pbPlaintext, SIZE_T cbPlaintext, _In_ PCSYMCRYPT_HASH hashAlgorithm, _In_reads_bytes_(cbLabel) PCBYTE pbLabel, SIZE_T cbLabel, _In_reads_bytes_opt_(cbSeed) PCBYTE pbSeed, SIZE_T cbSeed, _Out_writes_bytes_(cbOaepFormat) PBYTE pbOaepFormat, SIZE_T cbOaepFormat, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: rsa_padding.c:364
const SYMCRYPT_OID SymCryptSha1OidList[]
Definition: rsa_padding.c:25
const SYMCRYPT_OID SymCryptSha512_224OidList[]
Definition: rsa_padding.c:55
UINT32 UINT32 UINT32 UINT32 cbScratch
#define memset(x, y, z)
Definition: compat.h:39
static const BYTE pbHash[]
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
#define SYMCRYPT_FLAG_RSA_PKCS1_NO_ASN1
Definition: symcrypt.h:8671
VOID SYMCRYPT_CALL SymCryptHashAppend(_In_ PCSYMCRYPT_HASH pHash, _Inout_updates_bytes_(pHash->stateSize) PVOID pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: hash.c:182
#define SYMCRYPT_FLAG_RSA_PSS_VERIFY_WITH_MINIMUM_SALT
Definition: symcrypt.h:8674
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
VOID SYMCRYPT_CALL SymCryptHashInit(_In_ PCSYMCRYPT_HASH pHash, _Out_writes_bytes_(pHash->stateSize) PVOID pState)
Definition: hash.c:173
SIZE_T SYMCRYPT_CALL SymCryptHashResultSize(_In_ PCSYMCRYPT_HASH pHash)
Definition: hash.c:132
#define SYMCRYPT_FLAG_RSA_PKCS1_OPTIONAL_HASH_OID
Definition: symcrypt.h:8672
VOID SYMCRYPT_CALL SymCryptHash(_In_ PCSYMCRYPT_HASH pHash, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData, _Out_writes_(SYMCRYPT_MIN(cbResult, pHash->resultSize)) PBYTE pbResult, SIZE_T cbResult)
Definition: hash.c:155
BOOLEAN SYMCRYPT_CALL SymCryptEqual(_In_reads_(cbBytes) PCBYTE pbSrc1, _In_reads_(cbBytes) PCBYTE pbSrc2, SIZE_T cbBytes)
Definition: equal.c:11
VOID SYMCRYPT_CALL SymCryptHashResult(_In_ PCSYMCRYPT_HASH pHash, _Inout_updates_bytes_(pHash->stateSize) PVOID pState, _Out_writes_(SYMCRYPT_MIN(cbResult, pHash->resultSize)) PBYTE pbResult, SIZE_T cbResult)
Definition: hash.c:193
SIZE_T SYMCRYPT_CALL SymCryptHashStateSize(_In_ PCSYMCRYPT_HASH pHash)
Definition: hash.c:147
SYMCRYPT_ERROR
Definition: symcrypt.h:227
PCBYTE pbSrc
#define SYMCRYPT_CALL
#define SYMCRYPT_HASH_MAX_RESULT_SIZE
const SYMCRYPT_HASH * PCSYMCRYPT_HASH
#define SYMCRYPT_MIN(_a, _b)
PCBYTE PBYTE pbDst
UINT32 nBitsOfModulus
UINT32 cbSeed
const BYTE * PCBYTE
PBYTE pbSeed
VOID SYMCRYPT_CALL SymCryptScsRotateBuffer(_Inout_updates_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, SIZE_T lshift)
Definition: scsTools.c:179
UINT32 SYMCRYPT_CALL SymCryptMask32IsNonzeroU31(UINT32 v)
Definition: scsTools.c:28
UINT32 SYMCRYPT_CALL SymCryptMask32IsZeroU31(UINT32 v)
Definition: scsTools.c:36
UINT32 SYMCRYPT_CALL SymCryptMask32NeqU31(UINT32 a, UINT32 b)
Definition: scsTools.c:43
UINT32 SYMCRYPT_CALL SymCryptMask32LtU31(UINT32 a, UINT32 b)
Definition: scsTools.c:53
VOID SYMCRYPT_CALL SymCryptScsCopy(_In_reads_(cbDst) PCBYTE pbSrc, SIZE_T cbSrc, _Out_writes_(cbDst) PBYTE pbDst, SIZE_T cbDst)
Definition: scsTools.c:108
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
_In_ size_t cnt
Definition: wcstombs.cpp:43
unsigned char BYTE
Definition: xxhash.c:193