2 * PKCS#1 encoding and decoding functions.
3 * This file is believed to contain no code licensed from other parties.
5 * ***** BEGIN LICENSE BLOCK *****
6 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8 * The contents of this file are subject to the Mozilla Public License Version
9 * 1.1 (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
13 * Software distributed under the License is distributed on an "AS IS" basis,
14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15 * for the specific language governing rights and limitations under the
18 * The Original Code is the Netscape security libraries.
20 * The Initial Developer of the Original Code is
21 * Netscape Communications Corporation.
22 * Portions created by the Initial Developer are Copyright (C) 1994-2000
23 * the Initial Developer. All Rights Reserved.
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
40 /* $Id: rsawrapr.c,v 1.11 2006/10/23 21:24:38 wtchang%redhat.com Exp $ */
49 #define RSA_BLOCK_MIN_PAD_LEN 8
50 #define RSA_BLOCK_FIRST_OCTET 0x00
51 #define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00
52 #define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
53 #define RSA_BLOCK_AFTER_PAD_OCTET 0x00
55 #define OAEP_SALT_LEN 8
56 #define OAEP_PAD_LEN 8
57 #define OAEP_PAD_OCTET 0x00
59 #define FLAT_BUFSIZE 512 /* bytes to hold flattened SHA1Context. */
62 SHA1_CloneContext(SHA1Context
*original
)
64 SHA1Context
* clone
= NULL
;
66 int sha1ContextSize
= SHA1_FlattenSize(original
);
68 unsigned char buf
[FLAT_BUFSIZE
];
70 PORT_Assert(sizeof buf
>= sha1ContextSize
);
71 if (sizeof buf
>= sha1ContextSize
) {
74 pBuf
= PORT_Alloc(sha1ContextSize
);
79 frv
= SHA1_Flatten(original
, pBuf
);
80 if (frv
== SECSuccess
) {
81 clone
= SHA1_Resurrect(pBuf
, NULL
);
82 memset(pBuf
, 0, sha1ContextSize
);
91 * Modify data by XORing it with a special hash of salt.
94 oaep_xor_with_h1(unsigned char *data
, unsigned int datalen
,
95 unsigned char *salt
, unsigned int saltlen
)
98 unsigned char *dp
, *dataend
;
99 unsigned char end_octet
;
101 sha1cx
= SHA1_NewContext();
102 if (sha1cx
== NULL
) {
107 * Get a hash of salt started; we will use it several times,
108 * adding in a different end octet (x00, x01, x02, ...).
111 SHA1_Update (sha1cx
, salt
, saltlen
);
115 dataend
= data
+ datalen
;
117 while (dp
< dataend
) {
118 SHA1Context
*sha1cx_h1
;
119 unsigned int sha1len
, sha1off
;
120 unsigned char sha1
[SHA1_LENGTH
];
123 * Create hash of (salt || end_octet)
125 sha1cx_h1
= SHA1_CloneContext (sha1cx
);
126 SHA1_Update (sha1cx_h1
, &end_octet
, 1);
127 SHA1_End (sha1cx_h1
, sha1
, &sha1len
, sizeof(sha1
));
128 SHA1_DestroyContext (sha1cx_h1
, PR_TRUE
);
129 PORT_Assert (sha1len
== SHA1_LENGTH
);
132 * XOR that hash with the data.
133 * When we have fewer than SHA1_LENGTH octets of data
134 * left to xor, use just the low-order ones of the hash.
137 if ((dataend
- dp
) < SHA1_LENGTH
)
138 sha1off
= SHA1_LENGTH
- (dataend
- dp
);
139 while (sha1off
< SHA1_LENGTH
)
140 *dp
++ ^= sha1
[sha1off
++];
143 * Bump for next hash chunk.
148 SHA1_DestroyContext (sha1cx
, PR_TRUE
);
153 * Modify salt by XORing it with a special hash of data.
156 oaep_xor_with_h2(unsigned char *salt
, unsigned int saltlen
,
157 unsigned char *data
, unsigned int datalen
)
159 unsigned char sha1
[SHA1_LENGTH
];
160 unsigned char *psalt
, *psha1
, *saltend
;
164 * Create a hash of data.
166 rv
= SHA1_HashBuf (sha1
, data
, datalen
);
167 if (rv
!= SECSuccess
) {
172 * XOR the low-order octets of that hash with salt.
174 PORT_Assert (saltlen
<= SHA1_LENGTH
);
175 saltend
= salt
+ saltlen
;
177 psha1
= sha1
+ SHA1_LENGTH
- saltlen
;
178 while (psalt
< saltend
) {
179 *psalt
++ ^= *psha1
++;
186 * Format one block of data for public/private key encryption using
187 * the rules defined in PKCS #1.
189 static unsigned char *
190 rsa_FormatOneBlock(unsigned modulusLen
, RSA_BlockType blockType
,
193 unsigned char *block
;
199 block
= (unsigned char *) PORT_Alloc(modulusLen
);
206 * All RSA blocks start with two octets:
209 *bp
++ = RSA_BLOCK_FIRST_OCTET
;
210 *bp
++ = (unsigned char) blockType
;
215 * Blocks intended for private-key operation.
217 case RSA_BlockPrivate0
: /* essentially unused */
218 case RSA_BlockPrivate
: /* preferred method */
220 * 0x00 || BT || Pad || 0x00 || ActualData
221 * 1 1 padLen 1 data->len
222 * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
224 padLen
= modulusLen
- data
->len
- 3;
225 PORT_Assert (padLen
>= RSA_BLOCK_MIN_PAD_LEN
);
226 if (padLen
< RSA_BLOCK_MIN_PAD_LEN
) {
231 blockType
== RSA_BlockPrivate0
232 ? RSA_BLOCK_PRIVATE0_PAD_OCTET
233 : RSA_BLOCK_PRIVATE_PAD_OCTET
,
236 *bp
++ = RSA_BLOCK_AFTER_PAD_OCTET
;
237 PORT_Memcpy (bp
, data
->data
, data
->len
);
241 * Blocks intended for public-key operation.
243 case RSA_BlockPublic
:
246 * 0x00 || BT || Pad || 0x00 || ActualData
247 * 1 1 padLen 1 data->len
248 * Pad is all non-zero random bytes.
250 padLen
= modulusLen
- data
->len
- 3;
251 PORT_Assert (padLen
>= RSA_BLOCK_MIN_PAD_LEN
);
252 if (padLen
< RSA_BLOCK_MIN_PAD_LEN
) {
256 for (i
= 0; i
< padLen
; i
++) {
257 /* Pad with non-zero random data. */
259 rv
= RNG_GenerateGlobalRandomBytes(bp
+ i
, 1);
260 } while (rv
== SECSuccess
&& bp
[i
] == RSA_BLOCK_AFTER_PAD_OCTET
);
261 if (rv
!= SECSuccess
) {
262 sftk_fatalError
= PR_TRUE
;
268 *bp
++ = RSA_BLOCK_AFTER_PAD_OCTET
;
269 PORT_Memcpy (bp
, data
->data
, data
->len
);
274 * Blocks intended for public-key operation, using
275 * Optimal Asymmetric Encryption Padding (OAEP).
279 * 0x00 || BT || Modified2(Salt) || Modified1(PaddedData)
280 * 1 1 OAEP_SALT_LEN OAEP_PAD_LEN + data->len [+ N]
283 * PaddedData is "Pad1 || ActualData [|| Pad2]"
284 * Salt is random data.
286 * Pad2, if present, is random data.
287 * (The "modified" fields are all the same length as the original
288 * unmodified values; they are just xor'd with other values.)
290 * Modified1 is an XOR of PaddedData with a special octet
291 * string constructed of iterated hashing of Salt (see below).
292 * Modified2 is an XOR of Salt with the low-order octets of
293 * the hash of Modified1 (see farther below ;-).
302 rv
= RNG_GenerateGlobalRandomBytes(bp
, OAEP_SALT_LEN
);
303 if (rv
!= SECSuccess
) {
304 sftk_fatalError
= PR_TRUE
;
313 PORT_Memset (bp
, OAEP_PAD_OCTET
, OAEP_PAD_LEN
);
319 PORT_Memcpy (bp
, data
->data
, data
->len
);
325 if (bp
< (block
+ modulusLen
)) {
326 rv
= RNG_GenerateGlobalRandomBytes(bp
, block
- bp
+ modulusLen
);
327 if (rv
!= SECSuccess
) {
328 sftk_fatalError
= PR_TRUE
;
335 * Now we have the following:
336 * 0x00 || BT || Salt || PaddedData
337 * (From this point on, "Pad1 || Data [|| Pad2]" is treated
338 * as the one entity PaddedData.)
340 * We need to turn PaddedData into Modified1.
342 if (oaep_xor_with_h1(block
+ 2 + OAEP_SALT_LEN
,
343 modulusLen
- 2 - OAEP_SALT_LEN
,
344 block
+ 2, OAEP_SALT_LEN
) != SECSuccess
) {
351 * 0x00 || BT || Salt || Modified1(PaddedData)
353 * The remaining task is to turn Salt into Modified2.
355 if (oaep_xor_with_h2(block
+ 2, OAEP_SALT_LEN
,
356 block
+ 2 + OAEP_SALT_LEN
,
357 modulusLen
- 2 - OAEP_SALT_LEN
) != SECSuccess
) {
374 rsa_FormatBlock(SECItem
*result
, unsigned modulusLen
,
375 RSA_BlockType blockType
, SECItem
*data
)
378 * XXX For now assume that the data length fits in a single
379 * XXX encryption block; the ASSERTs below force this.
380 * XXX To fix it, each case will have to loop over chunks whose
381 * XXX lengths satisfy the assertions, until all data is handled.
382 * XXX (Unless RSA has more to say about how to handle data
383 * XXX which does not fit in a single encryption block?)
384 * XXX And I do not know what the result is supposed to be,
385 * XXX so the interface to this function may need to change
386 * XXX to allow for returning multiple blocks, if they are
387 * XXX not wanted simply concatenated one after the other.
391 case RSA_BlockPrivate0
:
392 case RSA_BlockPrivate
:
393 case RSA_BlockPublic
:
395 * 0x00 || BT || Pad || 0x00 || ActualData
397 * The "3" below is the first octet + the second octet + the 0x00
398 * octet that always comes just before the ActualData.
400 PORT_Assert (data
->len
<= (modulusLen
- (3 + RSA_BLOCK_MIN_PAD_LEN
)));
402 result
->data
= rsa_FormatOneBlock(modulusLen
, blockType
, data
);
403 if (result
->data
== NULL
) {
407 result
->len
= modulusLen
;
413 * 0x00 || BT || M1(Salt) || M2(Pad1||ActualData[||Pad2])
415 * The "2" below is the first octet + the second octet.
416 * (The other fields do not contain the clear values, but are
417 * the same length as the clear values.)
419 PORT_Assert (data
->len
<= (modulusLen
- (2 + OAEP_SALT_LEN
422 result
->data
= rsa_FormatOneBlock(modulusLen
, blockType
, data
);
423 if (result
->data
== NULL
) {
427 result
->len
= modulusLen
;
434 * Pad is zeros. The application is responsible for recovering
437 if (data
->len
> modulusLen
) {
440 result
->data
= (unsigned char*)PORT_ZAlloc(modulusLen
);
441 result
->len
= modulusLen
;
442 PORT_Memcpy(result
->data
+(modulusLen
-data
->len
),data
->data
,data
->len
);
455 /* XXX Doesn't set error code */
457 RSA_Sign(NSSLOWKEYPrivateKey
*key
,
458 unsigned char * output
,
459 unsigned int * output_len
,
460 unsigned int maxOutputLen
,
461 unsigned char * input
,
462 unsigned int input_len
)
464 SECStatus rv
= SECSuccess
;
465 unsigned int modulus_len
= nsslowkey_PrivateModulusLen(key
);
469 if (maxOutputLen
< modulus_len
)
471 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
472 if (key
->keyType
!= NSSLOWKEYRSAKey
)
475 unformatted
.len
= input_len
;
476 unformatted
.data
= input
;
477 formatted
.data
= NULL
;
478 rv
= rsa_FormatBlock(&formatted
, modulus_len
, RSA_BlockPrivate
,
480 if (rv
!= SECSuccess
)
483 rv
= RSA_PrivateKeyOpDoubleChecked(&key
->u
.rsa
, output
, formatted
.data
);
484 if (rv
!= SECSuccess
&& PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE
) {
485 sftk_fatalError
= PR_TRUE
;
487 *output_len
= modulus_len
;
492 if (formatted
.data
!= NULL
)
493 PORT_ZFree(formatted
.data
, modulus_len
);
497 /* XXX Doesn't set error code */
499 RSA_CheckSign(NSSLOWKEYPublicKey
*key
,
500 unsigned char * sign
,
501 unsigned int sign_len
,
502 unsigned char * hash
,
503 unsigned int hash_len
)
506 unsigned int modulus_len
= nsslowkey_PublicModulusLen(key
);
508 unsigned char * buffer
;
510 modulus_len
= nsslowkey_PublicModulusLen(key
);
511 if (sign_len
!= modulus_len
)
514 * 0x00 || BT || Pad || 0x00 || ActualData
516 * The "3" below is the first octet + the second octet + the 0x00
517 * octet that always comes just before the ActualData.
519 if (hash_len
> modulus_len
- (3 + RSA_BLOCK_MIN_PAD_LEN
))
521 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
522 if (key
->keyType
!= NSSLOWKEYRSAKey
)
525 buffer
= (unsigned char *)PORT_Alloc(modulus_len
+ 1);
529 rv
= RSA_PublicKeyOp(&key
->u
.rsa
, buffer
, sign
);
530 if (rv
!= SECSuccess
)
534 * check the padding that was used
536 if (buffer
[0] != 0 || buffer
[1] != 1)
538 for (i
= 2; i
< modulus_len
- hash_len
- 1; i
++) {
539 if (buffer
[i
] != 0xff)
546 * make sure we get the same results
548 if (PORT_Memcmp(buffer
+ modulus_len
- hash_len
, hash
, hash_len
) != 0)
560 /* XXX Doesn't set error code */
562 RSA_CheckSignRecover(NSSLOWKEYPublicKey
*key
,
563 unsigned char * data
,
564 unsigned int * data_len
,
565 unsigned int max_output_len
,
566 unsigned char * sign
,
567 unsigned int sign_len
)
570 unsigned int modulus_len
= nsslowkey_PublicModulusLen(key
);
572 unsigned char * buffer
;
574 if (sign_len
!= modulus_len
)
576 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
577 if (key
->keyType
!= NSSLOWKEYRSAKey
)
580 buffer
= (unsigned char *)PORT_Alloc(modulus_len
+ 1);
584 rv
= RSA_PublicKeyOp(&key
->u
.rsa
, buffer
, sign
);
585 if (rv
!= SECSuccess
)
590 * check the padding that was used
592 if (buffer
[0] != 0 || buffer
[1] != 1)
594 for (i
= 2; i
< modulus_len
; i
++) {
595 if (buffer
[i
] == 0) {
596 *data_len
= modulus_len
- i
- 1;
599 if (buffer
[i
] != 0xff)
604 if (*data_len
> max_output_len
)
608 * make sure we get the same results
610 PORT_Memcpy(data
,buffer
+ modulus_len
- *data_len
, *data_len
);
621 /* XXX Doesn't set error code */
623 RSA_EncryptBlock(NSSLOWKEYPublicKey
*key
,
624 unsigned char * output
,
625 unsigned int * output_len
,
626 unsigned int max_output_len
,
627 unsigned char * input
,
628 unsigned int input_len
)
631 unsigned int modulus_len
= nsslowkey_PublicModulusLen(key
);
635 formatted
.data
= NULL
;
636 if (max_output_len
< modulus_len
)
638 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
639 if (key
->keyType
!= NSSLOWKEYRSAKey
)
642 unformatted
.len
= input_len
;
643 unformatted
.data
= input
;
644 formatted
.data
= NULL
;
645 rv
= rsa_FormatBlock(&formatted
, modulus_len
, RSA_BlockPublic
,
647 if (rv
!= SECSuccess
)
650 rv
= RSA_PublicKeyOp(&key
->u
.rsa
, output
, formatted
.data
);
651 if (rv
!= SECSuccess
)
654 PORT_ZFree(formatted
.data
, modulus_len
);
655 *output_len
= modulus_len
;
659 if (formatted
.data
!= NULL
)
660 PORT_ZFree(formatted
.data
, modulus_len
);
664 /* XXX Doesn't set error code */
666 RSA_DecryptBlock(NSSLOWKEYPrivateKey
*key
,
667 unsigned char * output
,
668 unsigned int * output_len
,
669 unsigned int max_output_len
,
670 unsigned char * input
,
671 unsigned int input_len
)
674 unsigned int modulus_len
= nsslowkey_PrivateModulusLen(key
);
676 unsigned char * buffer
;
678 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
679 if (key
->keyType
!= NSSLOWKEYRSAKey
)
681 if (input_len
!= modulus_len
)
684 buffer
= (unsigned char *)PORT_Alloc(modulus_len
+ 1);
688 rv
= RSA_PrivateKeyOp(&key
->u
.rsa
, buffer
, input
);
689 if (rv
!= SECSuccess
) {
690 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE
) {
691 sftk_fatalError
= PR_TRUE
;
696 if (buffer
[0] != 0 || buffer
[1] != 2)
699 for (i
= 2; i
< modulus_len
; i
++) {
700 if (buffer
[i
] == 0) {
701 *output_len
= modulus_len
- i
- 1;
705 if (*output_len
== 0)
707 if (*output_len
> max_output_len
)
710 PORT_Memcpy(output
, buffer
+ modulus_len
- *output_len
, *output_len
);
721 /* XXX Doesn't set error code */
723 * added to make pkcs #11 happy
727 RSA_SignRaw(NSSLOWKEYPrivateKey
*key
,
728 unsigned char * output
,
729 unsigned int * output_len
,
730 unsigned int maxOutputLen
,
731 unsigned char * input
,
732 unsigned int input_len
)
734 SECStatus rv
= SECSuccess
;
735 unsigned int modulus_len
= nsslowkey_PrivateModulusLen(key
);
739 if (maxOutputLen
< modulus_len
)
741 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
742 if (key
->keyType
!= NSSLOWKEYRSAKey
)
745 unformatted
.len
= input_len
;
746 unformatted
.data
= input
;
747 formatted
.data
= NULL
;
748 rv
= rsa_FormatBlock(&formatted
, modulus_len
, RSA_BlockRaw
, &unformatted
);
749 if (rv
!= SECSuccess
)
752 rv
= RSA_PrivateKeyOpDoubleChecked(&key
->u
.rsa
, output
, formatted
.data
);
753 if (rv
!= SECSuccess
&& PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE
) {
754 sftk_fatalError
= PR_TRUE
;
756 *output_len
= modulus_len
;
759 if (formatted
.data
!= NULL
)
760 PORT_ZFree(formatted
.data
, modulus_len
);
764 /* XXX Doesn't set error code */
766 RSA_CheckSignRaw(NSSLOWKEYPublicKey
*key
,
767 unsigned char * sign
,
768 unsigned int sign_len
,
769 unsigned char * hash
,
770 unsigned int hash_len
)
773 unsigned int modulus_len
= nsslowkey_PublicModulusLen(key
);
774 unsigned char * buffer
;
776 if (sign_len
!= modulus_len
)
778 if (hash_len
> modulus_len
)
780 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
781 if (key
->keyType
!= NSSLOWKEYRSAKey
)
784 buffer
= (unsigned char *)PORT_Alloc(modulus_len
+ 1);
788 rv
= RSA_PublicKeyOp(&key
->u
.rsa
, buffer
, sign
);
789 if (rv
!= SECSuccess
)
793 * make sure we get the same results
795 /* NOTE: should we verify the leading zeros? */
796 if (PORT_Memcmp(buffer
+ (modulus_len
-hash_len
), hash
, hash_len
) != 0)
808 /* XXX Doesn't set error code */
810 RSA_CheckSignRecoverRaw(NSSLOWKEYPublicKey
*key
,
811 unsigned char * data
,
812 unsigned int * data_len
,
813 unsigned int max_output_len
,
814 unsigned char * sign
,
815 unsigned int sign_len
)
818 unsigned int modulus_len
= nsslowkey_PublicModulusLen(key
);
820 if (sign_len
!= modulus_len
)
822 if (max_output_len
< modulus_len
)
824 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
825 if (key
->keyType
!= NSSLOWKEYRSAKey
)
828 rv
= RSA_PublicKeyOp(&key
->u
.rsa
, data
, sign
);
829 if (rv
!= SECSuccess
)
832 *data_len
= modulus_len
;
840 /* XXX Doesn't set error code */
842 RSA_EncryptRaw(NSSLOWKEYPublicKey
*key
,
843 unsigned char * output
,
844 unsigned int * output_len
,
845 unsigned int max_output_len
,
846 unsigned char * input
,
847 unsigned int input_len
)
850 unsigned int modulus_len
= nsslowkey_PublicModulusLen(key
);
854 formatted
.data
= NULL
;
855 if (max_output_len
< modulus_len
)
857 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
858 if (key
->keyType
!= NSSLOWKEYRSAKey
)
861 unformatted
.len
= input_len
;
862 unformatted
.data
= input
;
863 formatted
.data
= NULL
;
864 rv
= rsa_FormatBlock(&formatted
, modulus_len
, RSA_BlockRaw
, &unformatted
);
865 if (rv
!= SECSuccess
)
868 rv
= RSA_PublicKeyOp(&key
->u
.rsa
, output
, formatted
.data
);
869 if (rv
!= SECSuccess
)
872 PORT_ZFree(formatted
.data
, modulus_len
);
873 *output_len
= modulus_len
;
877 if (formatted
.data
!= NULL
)
878 PORT_ZFree(formatted
.data
, modulus_len
);
882 /* XXX Doesn't set error code */
884 RSA_DecryptRaw(NSSLOWKEYPrivateKey
*key
,
885 unsigned char * output
,
886 unsigned int * output_len
,
887 unsigned int max_output_len
,
888 unsigned char * input
,
889 unsigned int input_len
)
892 unsigned int modulus_len
= nsslowkey_PrivateModulusLen(key
);
894 if (modulus_len
<= 0)
896 if (modulus_len
> max_output_len
)
898 PORT_Assert(key
->keyType
== NSSLOWKEYRSAKey
);
899 if (key
->keyType
!= NSSLOWKEYRSAKey
)
901 if (input_len
!= modulus_len
)
904 rv
= RSA_PrivateKeyOp(&key
->u
.rsa
, output
, input
);
905 if (rv
!= SECSuccess
) {
906 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE
) {
907 sftk_fatalError
= PR_TRUE
;
912 *output_len
= modulus_len
;