Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(419)

Side by Side Diff: mozilla/security/nss/lib/softoken/rsawrapr.c

Issue 14249009: Change the NSS and NSPR source tree to the new directory structure to be (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mozilla/security/nss/lib/softoken/pkcs11u.c ('k') | mozilla/security/nss/lib/softoken/sdb.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * PKCS#1 encoding and decoding functions.
3 * This file is believed to contain no code licensed from other parties.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 /* $Id: rsawrapr.c,v 1.22 2013/02/05 02:19:52 ryan.sleevi%gmail.com Exp $ */
9
10 #include "blapi.h"
11 #include "softoken.h"
12
13 #include "lowkeyi.h"
14 #include "secerr.h"
15
16 #define RSA_BLOCK_MIN_PAD_LEN 8
17 #define RSA_BLOCK_FIRST_OCTET 0x00
18 #define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00
19 #define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
20 #define RSA_BLOCK_AFTER_PAD_OCTET 0x00
21
22 /* Needed for RSA-PSS functions */
23 static const unsigned char eightZeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
24
25 /* Constant time comparison of a single byte.
26 * Returns 1 iff a == b, otherwise returns 0.
27 * Note: For ranges of bytes, use constantTimeCompare.
28 */
29 static unsigned char constantTimeEQ8(unsigned char a, unsigned char b) {
30 unsigned char c = ~(a - b | b - a);
31 c >>= 7;
32 return c;
33 }
34
35 /* Constant time comparison of a range of bytes.
36 * Returns 1 iff len bytes of a are identical to len bytes of b, otherwise
37 * returns 0.
38 */
39 static unsigned char constantTimeCompare(const unsigned char *a,
40 const unsigned char *b,
41 unsigned int len) {
42 unsigned char tmp = 0;
43 unsigned int i;
44 for (i = 0; i < len; ++i, ++a, ++b)
45 tmp |= *a ^ *b;
46 return constantTimeEQ8(0x00, tmp);
47 }
48
49 /* Constant time conditional.
50 * Returns a if c is 1, or b if c is 0. The result is undefined if c is
51 * not 0 or 1.
52 */
53 static unsigned int constantTimeCondition(unsigned int c,
54 unsigned int a,
55 unsigned int b)
56 {
57 return (~(c - 1) & a) | ((c - 1) & b);
58 }
59
60 /*
61 * Format one block of data for public/private key encryption using
62 * the rules defined in PKCS #1.
63 */
64 static unsigned char *
65 rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
66 SECItem *data)
67 {
68 unsigned char *block;
69 unsigned char *bp;
70 int padLen;
71 int i, j;
72 SECStatus rv;
73
74 block = (unsigned char *) PORT_Alloc(modulusLen);
75 if (block == NULL)
76 return NULL;
77
78 bp = block;
79
80 /*
81 * All RSA blocks start with two octets:
82 * 0x00 || BlockType
83 */
84 *bp++ = RSA_BLOCK_FIRST_OCTET;
85 *bp++ = (unsigned char) blockType;
86
87 switch (blockType) {
88
89 /*
90 * Blocks intended for private-key operation.
91 */
92 case RSA_BlockPrivate0: /* essentially unused */
93 case RSA_BlockPrivate: /* preferred method */
94 /*
95 * 0x00 || BT || Pad || 0x00 || ActualData
96 * 1 1 padLen 1 data->len
97 * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
98 */
99 padLen = modulusLen - data->len - 3;
100 PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
101 if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
102 PORT_Free (block);
103 return NULL;
104 }
105 PORT_Memset (bp,
106 blockType == RSA_BlockPrivate0
107 ? RSA_BLOCK_PRIVATE0_PAD_OCTET
108 : RSA_BLOCK_PRIVATE_PAD_OCTET,
109 padLen);
110 bp += padLen;
111 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
112 PORT_Memcpy (bp, data->data, data->len);
113 break;
114
115 /*
116 * Blocks intended for public-key operation.
117 */
118 case RSA_BlockPublic:
119
120 /*
121 * 0x00 || BT || Pad || 0x00 || ActualData
122 * 1 1 padLen 1 data->len
123 * Pad is all non-zero random bytes.
124 *
125 * Build the block left to right.
126 * Fill the entire block from Pad to the end with random bytes.
127 * Use the bytes after Pad as a supply of extra random bytes from
128 * which to find replacements for the zero bytes in Pad.
129 * If we need more than that, refill the bytes after Pad with
130 * new random bytes as necessary.
131 */
132 padLen = modulusLen - (data->len + 3);
133 PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
134 if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
135 PORT_Free (block);
136 return NULL;
137 }
138 j = modulusLen - 2;
139 rv = RNG_GenerateGlobalRandomBytes(bp, j);
140 if (rv == SECSuccess) {
141 for (i = 0; i < padLen; ) {
142 unsigned char repl;
143 /* Pad with non-zero random data. */
144 if (bp[i] != RSA_BLOCK_AFTER_PAD_OCTET) {
145 ++i;
146 continue;
147 }
148 if (j <= padLen) {
149 rv = RNG_GenerateGlobalRandomBytes(bp + padLen,
150 modulusLen - (2 + padLen));
151 if (rv != SECSuccess)
152 break;
153 j = modulusLen - 2;
154 }
155 do {
156 repl = bp[--j];
157 } while (repl == RSA_BLOCK_AFTER_PAD_OCTET && j > padLen);
158 if (repl != RSA_BLOCK_AFTER_PAD_OCTET) {
159 bp[i++] = repl;
160 }
161 }
162 }
163 if (rv != SECSuccess) {
164 sftk_fatalError = PR_TRUE;
165 PORT_Free (block);
166 return NULL;
167 }
168 bp += padLen;
169 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
170 PORT_Memcpy (bp, data->data, data->len);
171 break;
172
173 default:
174 PORT_Assert (0);
175 PORT_Free (block);
176 return NULL;
177 }
178
179 return block;
180 }
181
182 static SECStatus
183 rsa_FormatBlock(SECItem *result, unsigned modulusLen,
184 RSA_BlockType blockType, SECItem *data)
185 {
186 /*
187 * XXX For now assume that the data length fits in a single
188 * XXX encryption block; the ASSERTs below force this.
189 * XXX To fix it, each case will have to loop over chunks whose
190 * XXX lengths satisfy the assertions, until all data is handled.
191 * XXX (Unless RSA has more to say about how to handle data
192 * XXX which does not fit in a single encryption block?)
193 * XXX And I do not know what the result is supposed to be,
194 * XXX so the interface to this function may need to change
195 * XXX to allow for returning multiple blocks, if they are
196 * XXX not wanted simply concatenated one after the other.
197 */
198
199 switch (blockType) {
200 case RSA_BlockPrivate0:
201 case RSA_BlockPrivate:
202 case RSA_BlockPublic:
203 /*
204 * 0x00 || BT || Pad || 0x00 || ActualData
205 *
206 * The "3" below is the first octet + the second octet + the 0x00
207 * octet that always comes just before the ActualData.
208 */
209 PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
210
211 result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
212 if (result->data == NULL) {
213 result->len = 0;
214 return SECFailure;
215 }
216 result->len = modulusLen;
217
218 break;
219
220 case RSA_BlockRaw:
221 /*
222 * Pad || ActualData
223 * Pad is zeros. The application is responsible for recovering
224 * the actual data.
225 */
226 if (data->len > modulusLen ) {
227 return SECFailure;
228 }
229 result->data = (unsigned char*)PORT_ZAlloc(modulusLen);
230 result->len = modulusLen;
231 PORT_Memcpy(result->data+(modulusLen-data->len),data->data,data->len);
232 break;
233
234 default:
235 PORT_Assert (0);
236 result->data = NULL;
237 result->len = 0;
238 return SECFailure;
239 }
240
241 return SECSuccess;
242 }
243
244 /* XXX Doesn't set error code */
245 SECStatus
246 RSA_Sign(NSSLOWKEYPrivateKey *key,
247 unsigned char * output,
248 unsigned int * output_len,
249 unsigned int maxOutputLen,
250 unsigned char * input,
251 unsigned int input_len)
252 {
253 SECStatus rv = SECSuccess;
254 unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
255 SECItem formatted;
256 SECItem unformatted;
257
258 if (maxOutputLen < modulus_len)
259 return SECFailure;
260 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
261 if (key->keyType != NSSLOWKEYRSAKey)
262 return SECFailure;
263
264 unformatted.len = input_len;
265 unformatted.data = input;
266 formatted.data = NULL;
267 rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
268 &unformatted);
269 if (rv != SECSuccess)
270 goto done;
271
272 rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
273 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
274 sftk_fatalError = PR_TRUE;
275 }
276 *output_len = modulus_len;
277
278 goto done;
279
280 done:
281 if (formatted.data != NULL)
282 PORT_ZFree(formatted.data, modulus_len);
283 return rv;
284 }
285
286 /* XXX Doesn't set error code */
287 SECStatus
288 RSA_CheckSign(NSSLOWKEYPublicKey *key,
289 unsigned char * sign,
290 unsigned int sign_len,
291 unsigned char * hash,
292 unsigned int hash_len)
293 {
294 SECStatus rv;
295 unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
296 unsigned int i;
297 unsigned char * buffer;
298
299 modulus_len = nsslowkey_PublicModulusLen(key);
300 if (sign_len != modulus_len)
301 goto failure;
302 /*
303 * 0x00 || BT || Pad || 0x00 || ActualData
304 *
305 * The "3" below is the first octet + the second octet + the 0x00
306 * octet that always comes just before the ActualData.
307 */
308 if (hash_len > modulus_len - (3 + RSA_BLOCK_MIN_PAD_LEN))
309 goto failure;
310 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
311 if (key->keyType != NSSLOWKEYRSAKey)
312 goto failure;
313
314 buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
315 if (!buffer)
316 goto failure;
317
318 rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
319 if (rv != SECSuccess)
320 goto loser;
321
322 /*
323 * check the padding that was used
324 */
325 if (buffer[0] != 0 || buffer[1] != 1)
326 goto loser;
327 for (i = 2; i < modulus_len - hash_len - 1; i++) {
328 if (buffer[i] != 0xff)
329 goto loser;
330 }
331 if (buffer[i] != 0)
332 goto loser;
333
334 /*
335 * make sure we get the same results
336 */
337 if (PORT_Memcmp(buffer + modulus_len - hash_len, hash, hash_len) != 0)
338 goto loser;
339
340 PORT_Free(buffer);
341 return SECSuccess;
342
343 loser:
344 PORT_Free(buffer);
345 failure:
346 return SECFailure;
347 }
348
349 /* XXX Doesn't set error code */
350 SECStatus
351 RSA_CheckSignRecover(NSSLOWKEYPublicKey *key,
352 unsigned char * data,
353 unsigned int * data_len,
354 unsigned int max_output_len,
355 unsigned char * sign,
356 unsigned int sign_len)
357 {
358 SECStatus rv;
359 unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
360 unsigned int i;
361 unsigned char * buffer;
362
363 if (sign_len != modulus_len)
364 goto failure;
365 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
366 if (key->keyType != NSSLOWKEYRSAKey)
367 goto failure;
368
369 buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
370 if (!buffer)
371 goto failure;
372
373 rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
374 if (rv != SECSuccess)
375 goto loser;
376 *data_len = 0;
377
378 /*
379 * check the padding that was used
380 */
381 if (buffer[0] != 0 || buffer[1] != 1)
382 goto loser;
383 for (i = 2; i < modulus_len; i++) {
384 if (buffer[i] == 0) {
385 *data_len = modulus_len - i - 1;
386 break;
387 }
388 if (buffer[i] != 0xff)
389 goto loser;
390 }
391 if (*data_len == 0)
392 goto loser;
393 if (*data_len > max_output_len)
394 goto loser;
395
396 /*
397 * make sure we get the same results
398 */
399 PORT_Memcpy(data,buffer + modulus_len - *data_len, *data_len);
400
401 PORT_Free(buffer);
402 return SECSuccess;
403
404 loser:
405 PORT_Free(buffer);
406 failure:
407 return SECFailure;
408 }
409
410 /* XXX Doesn't set error code */
411 SECStatus
412 RSA_EncryptBlock(NSSLOWKEYPublicKey *key,
413 unsigned char * output,
414 unsigned int * output_len,
415 unsigned int max_output_len,
416 unsigned char * input,
417 unsigned int input_len)
418 {
419 SECStatus rv;
420 unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
421 SECItem formatted;
422 SECItem unformatted;
423
424 formatted.data = NULL;
425 if (max_output_len < modulus_len)
426 goto failure;
427 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
428 if (key->keyType != NSSLOWKEYRSAKey)
429 goto failure;
430
431 unformatted.len = input_len;
432 unformatted.data = input;
433 formatted.data = NULL;
434 rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPublic,
435 &unformatted);
436 if (rv != SECSuccess)
437 goto failure;
438
439 rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
440 if (rv != SECSuccess)
441 goto failure;
442
443 PORT_ZFree(formatted.data, modulus_len);
444 *output_len = modulus_len;
445 return SECSuccess;
446
447 failure:
448 if (formatted.data != NULL)
449 PORT_ZFree(formatted.data, modulus_len);
450 return SECFailure;
451 }
452
453 /* XXX Doesn't set error code */
454 SECStatus
455 RSA_DecryptBlock(NSSLOWKEYPrivateKey *key,
456 unsigned char * output,
457 unsigned int * output_len,
458 unsigned int max_output_len,
459 unsigned char * input,
460 unsigned int input_len)
461 {
462 SECStatus rv;
463 unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
464 unsigned int i;
465 unsigned char * buffer;
466
467 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
468 if (key->keyType != NSSLOWKEYRSAKey)
469 goto failure;
470 if (input_len != modulus_len)
471 goto failure;
472
473 buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
474 if (!buffer)
475 goto failure;
476
477 rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input);
478 if (rv != SECSuccess) {
479 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
480 sftk_fatalError = PR_TRUE;
481 }
482 goto loser;
483 }
484
485 if (buffer[0] != 0 || buffer[1] != 2)
486 goto loser;
487 *output_len = 0;
488 for (i = 2; i < modulus_len; i++) {
489 if (buffer[i] == 0) {
490 *output_len = modulus_len - i - 1;
491 break;
492 }
493 }
494 if (*output_len == 0)
495 goto loser;
496 if (*output_len > max_output_len)
497 goto loser;
498
499 PORT_Memcpy(output, buffer + modulus_len - *output_len, *output_len);
500
501 PORT_Free(buffer);
502 return SECSuccess;
503
504 loser:
505 PORT_Free(buffer);
506 failure:
507 return SECFailure;
508 }
509
510 /* XXX Doesn't set error code */
511 /*
512 * added to make pkcs #11 happy
513 * RAW is RSA_X_509
514 */
515 SECStatus
516 RSA_SignRaw(NSSLOWKEYPrivateKey *key,
517 unsigned char * output,
518 unsigned int * output_len,
519 unsigned int maxOutputLen,
520 unsigned char * input,
521 unsigned int input_len)
522 {
523 SECStatus rv = SECSuccess;
524 unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
525 SECItem formatted;
526 SECItem unformatted;
527
528 if (maxOutputLen < modulus_len)
529 return SECFailure;
530 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
531 if (key->keyType != NSSLOWKEYRSAKey)
532 return SECFailure;
533
534 unformatted.len = input_len;
535 unformatted.data = input;
536 formatted.data = NULL;
537 rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
538 if (rv != SECSuccess)
539 goto done;
540
541 rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
542 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
543 sftk_fatalError = PR_TRUE;
544 }
545 *output_len = modulus_len;
546
547 done:
548 if (formatted.data != NULL)
549 PORT_ZFree(formatted.data, modulus_len);
550 return rv;
551 }
552
553 /* XXX Doesn't set error code */
554 SECStatus
555 RSA_CheckSignRaw(NSSLOWKEYPublicKey *key,
556 unsigned char * sign,
557 unsigned int sign_len,
558 unsigned char * hash,
559 unsigned int hash_len)
560 {
561 SECStatus rv;
562 unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
563 unsigned char * buffer;
564
565 if (sign_len != modulus_len)
566 goto failure;
567 if (hash_len > modulus_len)
568 goto failure;
569 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
570 if (key->keyType != NSSLOWKEYRSAKey)
571 goto failure;
572
573 buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
574 if (!buffer)
575 goto failure;
576
577 rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
578 if (rv != SECSuccess)
579 goto loser;
580
581 /*
582 * make sure we get the same results
583 */
584 /* NOTE: should we verify the leading zeros? */
585 if (PORT_Memcmp(buffer + (modulus_len-hash_len), hash, hash_len) != 0)
586 goto loser;
587
588 PORT_Free(buffer);
589 return SECSuccess;
590
591 loser:
592 PORT_Free(buffer);
593 failure:
594 return SECFailure;
595 }
596
597 /* XXX Doesn't set error code */
598 SECStatus
599 RSA_CheckSignRecoverRaw(NSSLOWKEYPublicKey *key,
600 unsigned char * data,
601 unsigned int * data_len,
602 unsigned int max_output_len,
603 unsigned char * sign,
604 unsigned int sign_len)
605 {
606 SECStatus rv;
607 unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
608
609 if (sign_len != modulus_len)
610 goto failure;
611 if (max_output_len < modulus_len)
612 goto failure;
613 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
614 if (key->keyType != NSSLOWKEYRSAKey)
615 goto failure;
616
617 rv = RSA_PublicKeyOp(&key->u.rsa, data, sign);
618 if (rv != SECSuccess)
619 goto failure;
620
621 *data_len = modulus_len;
622 return SECSuccess;
623
624 failure:
625 return SECFailure;
626 }
627
628
629 /* XXX Doesn't set error code */
630 SECStatus
631 RSA_EncryptRaw(NSSLOWKEYPublicKey *key,
632 unsigned char * output,
633 unsigned int * output_len,
634 unsigned int max_output_len,
635 unsigned char * input,
636 unsigned int input_len)
637 {
638 SECStatus rv;
639 unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
640 SECItem formatted;
641 SECItem unformatted;
642
643 formatted.data = NULL;
644 if (max_output_len < modulus_len)
645 goto failure;
646 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
647 if (key->keyType != NSSLOWKEYRSAKey)
648 goto failure;
649
650 unformatted.len = input_len;
651 unformatted.data = input;
652 formatted.data = NULL;
653 rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
654 if (rv != SECSuccess)
655 goto failure;
656
657 rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
658 if (rv != SECSuccess)
659 goto failure;
660
661 PORT_ZFree(formatted.data, modulus_len);
662 *output_len = modulus_len;
663 return SECSuccess;
664
665 failure:
666 if (formatted.data != NULL)
667 PORT_ZFree(formatted.data, modulus_len);
668 return SECFailure;
669 }
670
671 /* XXX Doesn't set error code */
672 SECStatus
673 RSA_DecryptRaw(NSSLOWKEYPrivateKey *key,
674 unsigned char * output,
675 unsigned int * output_len,
676 unsigned int max_output_len,
677 unsigned char * input,
678 unsigned int input_len)
679 {
680 SECStatus rv;
681 unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
682
683 if (modulus_len <= 0)
684 goto failure;
685 if (modulus_len > max_output_len)
686 goto failure;
687 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
688 if (key->keyType != NSSLOWKEYRSAKey)
689 goto failure;
690 if (input_len != modulus_len)
691 goto failure;
692
693 rv = RSA_PrivateKeyOp(&key->u.rsa, output, input);
694 if (rv != SECSuccess) {
695 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
696 sftk_fatalError = PR_TRUE;
697 }
698 goto failure;
699 }
700
701 *output_len = modulus_len;
702 return SECSuccess;
703
704 failure:
705 return SECFailure;
706 }
707
708 /*
709 * Mask generation function MGF1 as defined in PKCS #1 v2.1 / RFC 3447.
710 */
711 static SECStatus
712 MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
713 const unsigned char *mgfSeed, unsigned int mgfSeedLen)
714 {
715 unsigned int digestLen;
716 PRUint32 counter, rounds;
717 unsigned char *tempHash, *temp;
718 const SECHashObject *hash;
719 void *hashContext;
720 unsigned char C[4];
721
722 hash = HASH_GetRawHashObject(hashAlg);
723 if (hash == NULL)
724 return SECFailure;
725
726 hashContext = (*hash->create)();
727 rounds = (maskLen + hash->length - 1) / hash->length;
728 for (counter = 0; counter < rounds; counter++) {
729 C[0] = (unsigned char)((counter >> 24) & 0xff);
730 C[1] = (unsigned char)((counter >> 16) & 0xff);
731 C[2] = (unsigned char)((counter >> 8) & 0xff);
732 C[3] = (unsigned char)(counter & 0xff);
733
734 /* This could be optimized when the clone functions in
735 * rawhash.c are implemented. */
736 (*hash->begin)(hashContext);
737 (*hash->update)(hashContext, mgfSeed, mgfSeedLen);
738 (*hash->update)(hashContext, C, sizeof C);
739
740 tempHash = mask + counter * hash->length;
741 if (counter != (rounds-1)) {
742 (*hash->end)(hashContext, tempHash, &digestLen, hash->length);
743 } else { /* we're in the last round and need to cut the hash */
744 temp = PORT_Alloc(hash->length);
745 (*hash->end)(hashContext, temp, &digestLen, hash->length);
746 PORT_Memcpy(tempHash, temp, maskLen - counter * hash->length);
747 PORT_Free(temp);
748 }
749 }
750 (*hash->destroy)(hashContext, PR_TRUE);
751
752 return SECSuccess;
753 }
754
755 /*
756 * Decodes an EME-OAEP encoded block, validating the encoding in constant
757 * time.
758 * Described in RFC 3447, section 7.1.2.
759 * input contains the encoded block, after decryption.
760 * label is the optional value L that was associated with the message.
761 * On success, the original message and message length will be stored in
762 * output and outputLen.
763 */
764 static SECStatus
765 eme_oaep_decode(unsigned char *output, unsigned int *outputLen,
766 unsigned int maxOutputLen,
767 const unsigned char *input, unsigned int inputLen,
768 HASH_HashType hashAlg, HASH_HashType maskHashAlg,
769 const unsigned char *label, unsigned int labelLen)
770 {
771 const SECHashObject *hash;
772 void *hashContext;
773 SECStatus rv = SECFailure;
774 unsigned char labelHash[HASH_LENGTH_MAX];
775 unsigned int i, maskLen, paddingOffset;
776 unsigned char *mask = NULL, *tmpOutput = NULL;
777 unsigned char isGood, foundPaddingEnd;
778
779 hash = HASH_GetRawHashObject(hashAlg);
780
781 /* 1.c */
782 if (inputLen < (hash->length * 2) + 2) {
783 PORT_SetError(SEC_ERROR_INPUT_LEN);
784 return SECFailure;
785 }
786
787 /* Step 3.a - Generate lHash */
788 hashContext = (*hash->create)();
789 if (hashContext == NULL) {
790 PORT_SetError(SEC_ERROR_NO_MEMORY);
791 return SECFailure;
792 }
793 (*hash->begin)(hashContext);
794 if (labelLen > 0)
795 (*hash->update)(hashContext, label, labelLen);
796 (*hash->end)(hashContext, labelHash, &i, sizeof(labelHash));
797 (*hash->destroy)(hashContext, PR_TRUE);
798
799 tmpOutput = (unsigned char*)PORT_Alloc(inputLen);
800 if (tmpOutput == NULL) {
801 PORT_SetError(SEC_ERROR_NO_MEMORY);
802 goto done;
803 }
804
805 maskLen = inputLen - hash->length - 1;
806 mask = (unsigned char*)PORT_Alloc(maskLen);
807 if (mask == NULL) {
808 PORT_SetError(SEC_ERROR_NO_MEMORY);
809 goto done;
810 }
811
812 PORT_Memcpy(tmpOutput, input, inputLen);
813
814 /* 3.c - Generate seedMask */
815 MGF1(maskHashAlg, mask, hash->length, &tmpOutput[1 + hash->length],
816 inputLen - hash->length - 1);
817 /* 3.d - Unmask seed */
818 for (i = 0; i < hash->length; ++i)
819 tmpOutput[1 + i] ^= mask[i];
820
821 /* 3.e - Generate dbMask */
822 MGF1(maskHashAlg, mask, maskLen, &tmpOutput[1], hash->length);
823 /* 3.f - Unmask DB */
824 for (i = 0; i < maskLen; ++i)
825 tmpOutput[1 + hash->length + i] ^= mask[i];
826
827 /* 3.g - Compare Y, lHash, and PS in constant time
828 * Warning: This code is timing dependent and must not disclose which of
829 * these were invalid.
830 */
831 paddingOffset = 0;
832 isGood = 1;
833 foundPaddingEnd = 0;
834
835 /* Compare Y */
836 isGood &= constantTimeEQ8(0x00, tmpOutput[0]);
837
838 /* Compare lHash and lHash' */
839 isGood &= constantTimeCompare(&labelHash[0],
840 &tmpOutput[1 + hash->length],
841 hash->length);
842
843 /* Compare that the padding is zero or more zero octets, followed by a
844 * 0x01 octet */
845 for (i = 1 + (hash->length * 2); i < inputLen; ++i) {
846 unsigned char isZero = constantTimeEQ8(0x00, tmpOutput[i]);
847 unsigned char isOne = constantTimeEQ8(0x01, tmpOutput[i]);
848 /* non-constant time equivalent:
849 * if (tmpOutput[i] == 0x01 && !foundPaddingEnd)
850 * paddingOffset = i;
851 */
852 paddingOffset = constantTimeCondition(isOne & ~foundPaddingEnd, i,
853 paddingOffset);
854 /* non-constant time equivalent:
855 * if (tmpOutput[i] == 0x01)
856 * foundPaddingEnd = true;
857 *
858 * Note: This may yield false positives, as it will be set whenever
859 * a 0x01 byte is encountered. If there was bad padding (eg:
860 * 0x03 0x02 0x01), foundPaddingEnd will still be set to true, and
861 * paddingOffset will still be set to 2.
862 */
863 foundPaddingEnd = constantTimeCondition(isOne, 1, foundPaddingEnd);
864 /* non-constant time equivalent:
865 * if (tmpOutput[i] != 0x00 && tmpOutput[i] != 0x01 &&
866 * !foundPaddingEnd) {
867 * isGood = false;
868 * }
869 *
870 * Note: This may yield false positives, as a message (and padding)
871 * that is entirely zeros will result in isGood still being true. Thus
872 * it's necessary to check foundPaddingEnd is positive below.
873 */
874 isGood = constantTimeCondition(~foundPaddingEnd & ~isZero, 0, isGood);
875 }
876
877 /* While both isGood and foundPaddingEnd may have false positives, they
878 * cannot BOTH have false positives. If both are not true, then an invalid
879 * message was received. Note, this comparison must still be done in constan t
880 * time so as not to leak either condition.
881 */
882 if (!(isGood & foundPaddingEnd)) {
883 PORT_SetError(SEC_ERROR_BAD_DATA);
884 goto done;
885 }
886
887 /* End timing dependent code */
888
889 ++paddingOffset; /* Skip the 0x01 following the end of PS */
890
891 *outputLen = inputLen - paddingOffset;
892 if (*outputLen > maxOutputLen) {
893 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
894 goto done;
895 }
896
897 if (*outputLen)
898 PORT_Memcpy(output, &tmpOutput[paddingOffset], *outputLen);
899 rv = SECSuccess;
900
901 done:
902 if (mask)
903 PORT_ZFree(mask, maskLen);
904 if (tmpOutput)
905 PORT_ZFree(tmpOutput, inputLen);
906 return rv;
907 }
908
909 /*
910 * Generate an EME-OAEP encoded block for encryption
911 * Described in RFC 3447, section 7.1.1
912 * We use input instead of M for the message to be encrypted
913 * label is the optional value L to be associated with the message.
914 */
915 static SECStatus
916 eme_oaep_encode(unsigned char *em, unsigned int emLen,
917 const unsigned char *input, unsigned int inputLen,
918 HASH_HashType hashAlg, HASH_HashType maskHashAlg,
919 const unsigned char *label, unsigned int labelLen)
920 {
921 const SECHashObject *hash;
922 void *hashContext;
923 SECStatus rv;
924 unsigned char *mask;
925 unsigned int reservedLen, dbMaskLen, i;
926
927 hash = HASH_GetRawHashObject(hashAlg);
928
929 /* Step 1.b */
930 reservedLen = (2 * hash->length) + 2;
931 if (emLen < reservedLen || inputLen > (emLen - reservedLen)) {
932 PORT_SetError(SEC_ERROR_INPUT_LEN);
933 return SECFailure;
934 }
935
936 /*
937 * From RFC 3447, Section 7.1
938 * +----------+---------+-------+
939 * DB = | lHash | PS | M |
940 * +----------+---------+-------+
941 * |
942 * +----------+ V
943 * | seed |--> MGF ---> xor
944 * +----------+ |
945 * | |
946 * +--+ V |
947 * |00| xor <----- MGF <-----|
948 * +--+ | |
949 * | | |
950 * V V V
951 * +--+----------+----------------------------+
952 * EM = |00|maskedSeed| maskedDB |
953 * +--+----------+----------------------------+
954 *
955 * We use mask to hold the result of the MGF functions, and all other
956 * values are generated in their final resting place.
957 */
958 *em = 0x00;
959
960 /* Step 2.a - Generate lHash */
961 hashContext = (*hash->create)();
962 if (hashContext == NULL) {
963 PORT_SetError(SEC_ERROR_NO_MEMORY);
964 return SECFailure;
965 }
966 (*hash->begin)(hashContext);
967 if (labelLen > 0)
968 (*hash->update)(hashContext, label, labelLen);
969 (*hash->end)(hashContext, &em[1 + hash->length], &i, hash->length);
970 (*hash->destroy)(hashContext, PR_TRUE);
971
972 /* Step 2.b - Generate PS */
973 if (emLen - reservedLen - inputLen > 0) {
974 PORT_Memset(em + 1 + (hash->length * 2), 0x00,
975 emLen - reservedLen - inputLen);
976 }
977
978 /* Step 2.c. - Generate DB
979 * DB = lHash || PS || 0x01 || M
980 * Note that PS and lHash have already been placed into em at their
981 * appropriate offsets. This just copies M into place
982 */
983 em[emLen - inputLen - 1] = 0x01;
984 if (inputLen)
985 PORT_Memcpy(em + emLen - inputLen, input, inputLen);
986
987 /* Step 2.d - Generate seed */
988 rv = RNG_GenerateGlobalRandomBytes(em + 1, hash->length);
989 if (rv != SECSuccess) {
990 return rv;
991 }
992
993 /* Step 2.e - Generate dbMask*/
994 dbMaskLen = emLen - hash->length - 1;
995 mask = (unsigned char*)PORT_Alloc(dbMaskLen);
996 if (mask == NULL) {
997 PORT_SetError(SEC_ERROR_NO_MEMORY);
998 return SECFailure;
999 }
1000 MGF1(maskHashAlg, mask, dbMaskLen, em + 1, hash->length);
1001 /* Step 2.f - Compute maskedDB*/
1002 for (i = 0; i < dbMaskLen; ++i)
1003 em[1 + hash->length + i] ^= mask[i];
1004
1005 /* Step 2.g - Generate seedMask */
1006 MGF1(maskHashAlg, mask, hash->length, &em[1 + hash->length], dbMaskLen);
1007 /* Step 2.h - Compute maskedSeed */
1008 for (i = 0; i < hash->length; ++i)
1009 em[1 + i] ^= mask[i];
1010
1011 PORT_ZFree(mask, dbMaskLen);
1012 return SECSuccess;
1013 }
1014
1015 /*
1016 * Encode a RSA-PSS signature.
1017 * Described in RFC 3447, section 9.1.1.
1018 * We use mHash instead of M as input.
1019 * emBits from the RFC is just modBits - 1, see section 8.1.1.
1020 * We only support MGF1 as the MGF.
1021 *
1022 * NOTE: this code assumes modBits is a multiple of 8.
1023 */
1024 static SECStatus
1025 emsa_pss_encode(unsigned char *em, unsigned int emLen,
1026 const unsigned char *mHash, HASH_HashType hashAlg,
1027 HASH_HashType maskHashAlg, unsigned int sLen)
1028 {
1029 const SECHashObject *hash;
1030 void *hash_context;
1031 unsigned char *dbMask;
1032 unsigned int dbMaskLen, i;
1033 SECStatus rv;
1034
1035 hash = HASH_GetRawHashObject(hashAlg);
1036 dbMaskLen = emLen - hash->length - 1;
1037
1038 /* Step 3 */
1039 if (emLen < hash->length + sLen + 2) {
1040 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1041 return SECFailure;
1042 }
1043
1044 /* Step 4 */
1045 rv = RNG_GenerateGlobalRandomBytes(&em[dbMaskLen - sLen], sLen);
1046 if (rv != SECSuccess) {
1047 return rv;
1048 }
1049
1050 /* Step 5 + 6 */
1051 /* Compute H and store it at its final location &em[dbMaskLen]. */
1052 hash_context = (*hash->create)();
1053 if (hash_context == NULL) {
1054 PORT_SetError(SEC_ERROR_NO_MEMORY);
1055 return SECFailure;
1056 }
1057 (*hash->begin)(hash_context);
1058 (*hash->update)(hash_context, eightZeros, 8);
1059 (*hash->update)(hash_context, mHash, hash->length);
1060 (*hash->update)(hash_context, &em[dbMaskLen - sLen], sLen);
1061 (*hash->end)(hash_context, &em[dbMaskLen], &i, hash->length);
1062 (*hash->destroy)(hash_context, PR_TRUE);
1063
1064 /* Step 7 + 8 */
1065 PORT_Memset(em, 0, dbMaskLen - sLen - 1);
1066 em[dbMaskLen - sLen - 1] = 0x01;
1067
1068 /* Step 9 */
1069 dbMask = (unsigned char *)PORT_Alloc(dbMaskLen);
1070 if (dbMask == NULL) {
1071 PORT_SetError(SEC_ERROR_NO_MEMORY);
1072 return SECFailure;
1073 }
1074 MGF1(maskHashAlg, dbMask, dbMaskLen, &em[dbMaskLen], hash->length);
1075
1076 /* Step 10 */
1077 for (i = 0; i < dbMaskLen; i++)
1078 em[i] ^= dbMask[i];
1079 PORT_Free(dbMask);
1080
1081 /* Step 11 */
1082 em[0] &= 0x7f;
1083
1084 /* Step 12 */
1085 em[emLen - 1] = 0xbc;
1086
1087 return SECSuccess;
1088 }
1089
1090 /*
1091 * Verify a RSA-PSS signature.
1092 * Described in RFC 3447, section 9.1.2.
1093 * We use mHash instead of M as input.
1094 * emBits from the RFC is just modBits - 1, see section 8.1.2.
1095 * We only support MGF1 as the MGF.
1096 *
1097 * NOTE: this code assumes modBits is a multiple of 8.
1098 */
1099 static SECStatus
1100 emsa_pss_verify(const unsigned char *mHash,
1101 const unsigned char *em, unsigned int emLen,
1102 HASH_HashType hashAlg, HASH_HashType maskHashAlg,
1103 unsigned int sLen)
1104 {
1105 const SECHashObject *hash;
1106 void *hash_context;
1107 unsigned char *db;
1108 unsigned char *H_; /* H' from the RFC */
1109 unsigned int i, dbMaskLen;
1110 SECStatus rv;
1111
1112 hash = HASH_GetRawHashObject(hashAlg);
1113 dbMaskLen = emLen - hash->length - 1;
1114
1115 /* Step 3 + 4 + 6 */
1116 if ((emLen < (hash->length + sLen + 2)) ||
1117 (em[emLen - 1] != 0xbc) ||
1118 ((em[0] & 0x80) != 0)) {
1119 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1120 return SECFailure;
1121 }
1122
1123 /* Step 7 */
1124 db = (unsigned char *)PORT_Alloc(dbMaskLen);
1125 if (db == NULL) {
1126 PORT_SetError(SEC_ERROR_NO_MEMORY);
1127 return SECFailure;
1128 }
1129 /* &em[dbMaskLen] points to H, used as mgfSeed */
1130 MGF1(maskHashAlg, db, dbMaskLen, &em[dbMaskLen], hash->length);
1131
1132 /* Step 8 */
1133 for (i = 0; i < dbMaskLen; i++) {
1134 db[i] ^= em[i];
1135 }
1136
1137 /* Step 9 */
1138 db[0] &= 0x7f;
1139
1140 /* Step 10 */
1141 for (i = 0; i < (dbMaskLen - sLen - 1); i++) {
1142 if (db[i] != 0) {
1143 PORT_Free(db);
1144 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1145 return SECFailure;
1146 }
1147 }
1148 if (db[dbMaskLen - sLen - 1] != 0x01) {
1149 PORT_Free(db);
1150 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1151 return SECFailure;
1152 }
1153
1154 /* Step 12 + 13 */
1155 H_ = (unsigned char *)PORT_Alloc(hash->length);
1156 if (H_ == NULL) {
1157 PORT_Free(db);
1158 PORT_SetError(SEC_ERROR_NO_MEMORY);
1159 return SECFailure;
1160 }
1161 hash_context = (*hash->create)();
1162 if (hash_context == NULL) {
1163 PORT_Free(db);
1164 PORT_Free(H_);
1165 PORT_SetError(SEC_ERROR_NO_MEMORY);
1166 return SECFailure;
1167 }
1168 (*hash->begin)(hash_context);
1169 (*hash->update)(hash_context, eightZeros, 8);
1170 (*hash->update)(hash_context, mHash, hash->length);
1171 (*hash->update)(hash_context, &db[dbMaskLen - sLen], sLen);
1172 (*hash->end)(hash_context, H_, &i, hash->length);
1173 (*hash->destroy)(hash_context, PR_TRUE);
1174
1175 PORT_Free(db);
1176
1177 /* Step 14 */
1178 if (PORT_Memcmp(H_, &em[dbMaskLen], hash->length) != 0) {
1179 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1180 rv = SECFailure;
1181 } else {
1182 rv = SECSuccess;
1183 }
1184
1185 PORT_Free(H_);
1186 return rv;
1187 }
1188
1189 static HASH_HashType
1190 GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech)
1191 {
1192 switch (mech) {
1193 case CKM_SHA_1:
1194 case CKG_MGF1_SHA1:
1195 return HASH_AlgSHA1;
1196 case CKM_SHA224:
1197 case CKG_MGF1_SHA224:
1198 return HASH_AlgSHA224;
1199 case CKM_SHA256:
1200 case CKG_MGF1_SHA256:
1201 return HASH_AlgSHA256;
1202 case CKM_SHA384:
1203 case CKG_MGF1_SHA384:
1204 return HASH_AlgSHA384;
1205 case CKM_SHA512:
1206 case CKG_MGF1_SHA512:
1207 return HASH_AlgSHA512;
1208 default:
1209 return HASH_AlgNULL;
1210 }
1211 }
1212
1213 /* MGF1 is the only supported MGF. */
1214 SECStatus
1215 RSA_CheckSignPSS(CK_RSA_PKCS_PSS_PARAMS *pss_params,
1216 NSSLOWKEYPublicKey *key,
1217 const unsigned char *sign, unsigned int sign_len,
1218 const unsigned char *hash, unsigned int hash_len)
1219 {
1220 HASH_HashType hashAlg;
1221 HASH_HashType maskHashAlg;
1222 SECStatus rv;
1223 unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
1224 unsigned char *buffer;
1225
1226 if (sign_len != modulus_len) {
1227 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1228 return SECFailure;
1229 }
1230
1231 hashAlg = GetHashTypeFromMechanism(pss_params->hashAlg);
1232 maskHashAlg = GetHashTypeFromMechanism(pss_params->mgf);
1233 if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
1234 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1235 return SECFailure;
1236 }
1237
1238 buffer = (unsigned char *)PORT_Alloc(modulus_len);
1239 if (!buffer) {
1240 PORT_SetError(SEC_ERROR_NO_MEMORY);
1241 return SECFailure;
1242 }
1243
1244 rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
1245 if (rv != SECSuccess) {
1246 PORT_Free(buffer);
1247 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1248 return SECFailure;
1249 }
1250
1251 rv = emsa_pss_verify(hash, buffer, modulus_len, hashAlg,
1252 maskHashAlg, pss_params->sLen);
1253 PORT_Free(buffer);
1254
1255 return rv;
1256 }
1257
1258 /* MGF1 is the only supported MGF. */
1259 SECStatus
1260 RSA_SignPSS(CK_RSA_PKCS_PSS_PARAMS *pss_params, NSSLOWKEYPrivateKey *key,
1261 unsigned char *output, unsigned int *output_len,
1262 unsigned int max_output_len,
1263 const unsigned char *input, unsigned int input_len)
1264 {
1265 SECStatus rv = SECSuccess;
1266 unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
1267 unsigned char *pss_encoded = NULL;
1268 HASH_HashType hashAlg;
1269 HASH_HashType maskHashAlg;
1270
1271 if (max_output_len < modulus_len) {
1272 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1273 return SECFailure;
1274 }
1275 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
1276 if (key->keyType != NSSLOWKEYRSAKey) {
1277 PORT_SetError(SEC_ERROR_INVALID_KEY);
1278 return SECFailure;
1279 }
1280
1281 hashAlg = GetHashTypeFromMechanism(pss_params->hashAlg);
1282 maskHashAlg = GetHashTypeFromMechanism(pss_params->mgf);
1283 if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
1284 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1285 return SECFailure;
1286 }
1287
1288 pss_encoded = (unsigned char *)PORT_Alloc(modulus_len);
1289 if (pss_encoded == NULL) {
1290 PORT_SetError(SEC_ERROR_NO_MEMORY);
1291 return SECFailure;
1292 }
1293 rv = emsa_pss_encode(pss_encoded, modulus_len, input, hashAlg,
1294 maskHashAlg, pss_params->sLen);
1295 if (rv != SECSuccess)
1296 goto done;
1297
1298 rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, pss_encoded);
1299 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
1300 sftk_fatalError = PR_TRUE;
1301 }
1302 *output_len = modulus_len;
1303
1304 done:
1305 PORT_Free(pss_encoded);
1306 return rv;
1307 }
1308
1309 /* MGF1 is the only supported MGF. */
1310 SECStatus
1311 RSA_EncryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
1312 NSSLOWKEYPublicKey *key,
1313 unsigned char *output, unsigned int *outputLen,
1314 unsigned int maxOutputLen,
1315 const unsigned char *input, unsigned int inputLen)
1316 {
1317 SECStatus rv = SECFailure;
1318 unsigned int modulusLen = nsslowkey_PublicModulusLen(key);
1319 unsigned char *oaepEncoded = NULL;
1320 unsigned char *sourceData = NULL;
1321 unsigned int sourceDataLen = 0;
1322
1323 HASH_HashType hashAlg;
1324 HASH_HashType maskHashAlg;
1325
1326 if (maxOutputLen < modulusLen) {
1327 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1328 return SECFailure;
1329 }
1330 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
1331 if (key->keyType != NSSLOWKEYRSAKey) {
1332 PORT_SetError(SEC_ERROR_INVALID_KEY);
1333 return SECFailure;
1334 }
1335
1336 hashAlg = GetHashTypeFromMechanism(oaepParams->hashAlg);
1337 maskHashAlg = GetHashTypeFromMechanism(oaepParams->mgf);
1338 if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
1339 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1340 return SECFailure;
1341 }
1342
1343 /* The PKCS#11 source parameter is the "source" of the label parameter.
1344 * The only defined source is explicitly specified, in which case, the
1345 * label is an optional byte string in pSourceData. If ulSourceDataLen is
1346 * zero, then pSourceData MUST be NULL - otherwise, it must be non-NULL.
1347 */
1348 if (oaepParams->source != CKZ_DATA_SPECIFIED) {
1349 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1350 return SECFailure;
1351 }
1352 sourceData = (unsigned char*)oaepParams->pSourceData;
1353 sourceDataLen = oaepParams->ulSourceDataLen;
1354 if ((sourceDataLen == 0 && sourceData != NULL) ||
1355 (sourceDataLen > 0 && sourceData == NULL)) {
1356 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1357 return SECFailure;
1358 }
1359
1360 oaepEncoded = (unsigned char *)PORT_Alloc(modulusLen);
1361 if (oaepEncoded == NULL) {
1362 PORT_SetError(SEC_ERROR_NO_MEMORY);
1363 return SECFailure;
1364 }
1365 rv = eme_oaep_encode(oaepEncoded, modulusLen, input, inputLen,
1366 hashAlg, maskHashAlg, sourceData, sourceDataLen);
1367 if (rv != SECSuccess)
1368 goto done;
1369
1370 rv = RSA_PublicKeyOp(&key->u.rsa, output, oaepEncoded);
1371 if (rv != SECSuccess)
1372 goto done;
1373 *outputLen = modulusLen;
1374
1375 done:
1376 PORT_Free(oaepEncoded);
1377 return rv;
1378 }
1379
1380 /* MGF1 is the only supported MGF. */
1381 SECStatus
1382 RSA_DecryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
1383 NSSLOWKEYPrivateKey *key,
1384 unsigned char *output, unsigned int *outputLen,
1385 unsigned int maxOutputLen,
1386 const unsigned char *input, unsigned int inputLen)
1387 {
1388 SECStatus rv = SECFailure;
1389 unsigned int modulusLen = nsslowkey_PrivateModulusLen(key);
1390 unsigned char *oaepEncoded = NULL;
1391 unsigned char *sourceData = NULL;
1392 unsigned int sourceDataLen = 0;
1393
1394 HASH_HashType hashAlg = GetHashTypeFromMechanism(oaepParams->hashAlg);
1395 HASH_HashType maskHashAlg = GetHashTypeFromMechanism(oaepParams->mgf);
1396
1397 if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
1398 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1399 return SECFailure;
1400 }
1401
1402 if (inputLen != modulusLen) {
1403 PORT_SetError(SEC_ERROR_INPUT_LEN);
1404 return SECFailure;
1405 }
1406 PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
1407 if (key->keyType != NSSLOWKEYRSAKey) {
1408 PORT_SetError(SEC_ERROR_INVALID_KEY);
1409 return SECFailure;
1410 }
1411
1412 /* The PKCS#11 source parameter is the "source" of the label parameter.
1413 * The only defined source is explicitly specified, in which case, the
1414 * label is an optional byte string in pSourceData. If ulSourceDataLen is
1415 * zero, then pSourceData MUST be NULL - otherwise, it must be non-NULL.
1416 */
1417 if (oaepParams->source != CKZ_DATA_SPECIFIED) {
1418 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1419 return SECFailure;
1420 }
1421 sourceData = (unsigned char*)oaepParams->pSourceData;
1422 sourceDataLen = oaepParams->ulSourceDataLen;
1423 if ((sourceDataLen == 0 && sourceData != NULL) ||
1424 (sourceDataLen > 0 && sourceData == NULL)) {
1425 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1426 return SECFailure;
1427 }
1428
1429 oaepEncoded = (unsigned char *)PORT_Alloc(modulusLen);
1430 if (oaepEncoded == NULL) {
1431 PORT_SetError(SEC_ERROR_NO_MEMORY);
1432 return SECFailure;
1433 }
1434
1435 rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, oaepEncoded, input);
1436 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
1437 sftk_fatalError = PR_TRUE;
1438 goto done;
1439 }
1440
1441 rv = eme_oaep_decode(output, outputLen, maxOutputLen, oaepEncoded,
1442 modulusLen, hashAlg, maskHashAlg, sourceData,
1443 sourceDataLen);
1444
1445 done:
1446 if (oaepEncoded)
1447 PORT_ZFree(oaepEncoded, modulusLen);
1448 return rv;
1449 }
OLDNEW
« no previous file with comments | « mozilla/security/nss/lib/softoken/pkcs11u.c ('k') | mozilla/security/nss/lib/softoken/sdb.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698