4 Heavily modified to work under SILC, code that is not needed in SILC has
5 been removed for good, and some code was fixed and changed.
7 For example, RSA_DecodeOneBlock was not used at all by Mozilla, however,
8 I took this code in to use after doing some fixing. Also, OAEP is removed
9 totally for now. I'm not sure whether OAEP could be used in the future
10 with SILC but not for now.
12 This file also implements partial SILC PKCS API for RSA with PKCS #1.
13 It is partial because all the other functions but encrypt, decrypt,
14 sign and verify are common.
18 The mandatory PKCS #1 implementation in SILC must be compliant to either
19 PKCS #1 version 1.5 or PKCS #1 version 2 with the following notes:
20 The signature encoding is always in same format as the encryption
21 encoding regardles of the PKCS #1 version. The signature with
22 appendix (with hash algorithm OID in the data) must not be used
23 in the SILC. Rationale for this is that there is no binding between
24 the PKCS #1 OIDs and the hash algorithms used in the SILC protocol.
25 Hence, the encoding is always in PKCS #1 version 1.5 format.
27 Any questions and comments regarding this modified version should be
28 sent to priikone@poseidon.pspt.fi.
30 References: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc,
31 ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1.asc,
34 Copyright notice: All code, including the SILC PKCS API code that is
35 not part of the Mozilla code, falls under the same license found attached
40 * PKCS#1 encoding and decoding functions.
41 * This file is believed to contain no code licensed from other parties.
43 * The contents of this file are subject to the Mozilla Public
44 * License Version 1.1 (the "License"); you may not use this file
45 * except in compliance with the License. You may obtain a copy of
46 * the License at http://www.mozilla.org/MPL/
48 * Software distributed under the License is distributed on an "AS
49 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
50 * implied. See the License for the specific language governing
51 * rights and limitations under the License.
53 * The Original Code is the Netscape security libraries.
55 * The Initial Developer of the Original Code is Netscape
56 * Communications Corporation. Portions created by Netscape are
57 * Copyright (C) 1994-2000 Netscape Communications Corporation. All
62 * Alternatively, the contents of this file may be used under the
63 * terms of the GNU General Public License Version 2 or later (the
64 * "GPL"), in which case the provisions of the GPL are applicable
65 * instead of those above. If you wish to allow use of your
66 * version of this file only under the terms of the GPL and not to
67 * allow others to use your version of this file under the MPL,
68 * indicate your decision by deleting the provisions above and
69 * replace them with the notice and other provisions required by
70 * the GPL. If you do not delete the provisions above, a recipient
71 * may use your version of this file under either the MPL or the
77 #include "silcincludes.h"
79 #define RSA_BLOCK_MIN_PAD_LEN 8
80 #define RSA_BLOCK_FIRST_OCTET 0x00
81 #define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00
82 #define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
83 #define RSA_BLOCK_AFTER_PAD_OCTET 0x00
88 * The actual values are important -- they are fixed, *not* arbitrary.
89 * The explicit value assignments are not needed (because C would give
90 * us those same values anyway) but are included as a reminder...
93 RSA_BlockPrivate0 = 0, /* unused, really */
94 RSA_BlockPrivate = 1, /* pad for a private-key operation */
95 RSA_BlockPublic = 2, /* pad for a public-key operation */
100 * Format one block of data for public/private key encryption using
101 * the rules defined in PKCS #1.
103 static unsigned char *
104 RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
105 unsigned char *data, unsigned int data_len)
107 unsigned char *block;
112 block = (unsigned char *) silc_malloc(modulusLen);
119 * All RSA blocks start with two octets:
122 *bp++ = RSA_BLOCK_FIRST_OCTET;
123 *bp++ = (unsigned char) blockType;
128 * Blocks intended for private-key operation.
130 case RSA_BlockPrivate0: /* essentially unused */
131 case RSA_BlockPrivate: /* preferred method */
133 * 0x00 || BT || Pad || 0x00 || ActualData
134 * 1 1 padLen 1 data_len
135 * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
137 padLen = modulusLen - data_len - 3;
138 assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
140 blockType == RSA_BlockPrivate0
141 ? RSA_BLOCK_PRIVATE0_PAD_OCTET
142 : RSA_BLOCK_PRIVATE_PAD_OCTET,
145 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
146 memcpy(bp, data, data_len);
150 * Blocks intended for public-key operation.
152 case RSA_BlockPublic:
155 * 0x00 || BT || Pad || 0x00 || ActualData
156 * 1 1 padLen 1 data_len
157 * Pad is all non-zero random bytes.
159 padLen = modulusLen - data_len - 3;
160 assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
161 for (i = 0; i < padLen; i++) {
162 /* Pad with non-zero random data. */
164 RNG_GenerateGlobalRandomBytes(bp + i, 1);
165 } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
168 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
169 memcpy(bp, data, data_len);
183 RSA_FormatBlock(unsigned char **result, unsigned int *result_len,
185 RSA_BlockType blockType, unsigned char *data,
186 unsigned int data_len)
189 * XXX For now assume that the data length fits in a single
190 * XXX encryption block; the ASSERTs below force this.
191 * XXX To fix it, each case will have to loop over chunks whose
192 * XXX lengths satisfy the assertions, until all data is handled.
193 * XXX (Unless RSA has more to say about how to handle data
194 * XXX which does not fit in a single encryption block?)
195 * XXX And I do not know what the result is supposed to be,
196 * XXX so the interface to this function may need to change
197 * XXX to allow for returning multiple blocks, if they are
198 * XXX not wanted simply concatenated one after the other.
202 case RSA_BlockPrivate0:
203 case RSA_BlockPrivate:
204 case RSA_BlockPublic:
206 * 0x00 || BT || Pad || 0x00 || ActualData
208 * The "3" below is the first octet + the second octet + the 0x00
209 * octet that always comes just before the ActualData.
211 assert(data_len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
213 *result = RSA_FormatOneBlock(modulusLen, blockType, data);
214 if (result == NULL) {
218 *result_len = modulusLen;
232 * Takes a formatted block and returns the data part.
233 * (This is the inverse of RSA_FormatOneBlock().)
234 * In some formats the start of the data is ambiguous;
235 * if it is non-zero, expectedLen will disambiguate.
239 RSA_DecodeOneBlock(unsigned char *data,
240 unsigned int modulusLen,
241 unsigned int expectedLen,
243 unsigned int *pResultLen)
245 RSA_BlockType blockType;
246 unsigned char *dp, *res;
250 if (*dp++ != RSA_BLOCK_FIRST_OCTET) {
254 blockType = (RSA_BlockType)*dp++;
259 case RSA_BlockPrivate0:
261 res = (unsigned char *) silc_malloc(modulusLen);
262 memcpy(res, data, modulusLen);
265 case RSA_BlockPrivate:
266 for (i = 0; i < modulusLen; i++) {
267 if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET)
270 if ((i == modulusLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
274 len = modulusLen - (dp - data);
275 res = (unsigned char *) silc_malloc(len);
279 memcpy(res, dp, len);
282 case RSA_BlockPublic:
283 for (i = 0; i < modulusLen; i++) {
284 if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET)
287 if (i == modulusLen) {
291 len = modulusLen - (dp - data);
292 res = (unsigned char *) silc_malloc(len);
296 memcpy(res, dp, len);
309 * SILC PKCS API for PKCS #1
311 * Note all the other PKCS API functions are used from the rsa.c.
312 * See the definitions in rsa.c and in silcpkcs.c.
315 SILC_PKCS_API_ENCRYPT(pkcs1)
317 RsaKey *key = (RsaKey *)context;
321 unsigned char *padded;
322 unsigned int padded_len;
325 if (!RSA_FormatBlock(&padded, &padded_len, key->bits / 8,
326 RSA_BlockPublic, src, src_len))
329 silc_mp_init_set_ui(&mp_tmp, 0);
330 silc_mp_init_set_ui(&mp_dst, 0);
333 silc_mp_bin2mp(padded, padded_len, &mp_tmp);
336 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n);
339 if (!silc_mp_mp2bin_noalloc(&mp_dst, dst, key->bits / 8, dst_len))
342 memset(padded, 0, padded_len);
344 silc_mp_clear(&mp_tmp);
345 silc_mp_clear(&mp_dst);
350 SILC_PKCS_API_DECRYPT(pkcs1)
352 RsaKey *key = (RsaKey *)context;
356 unsigned char *padded, *unpadded;
357 unsigned int padded_len;
359 silc_mp_init_set_ui(&mp_tmp, 0);
360 silc_mp_init_set_ui(&mp_dst, 0);
363 silc_mp_bin2mp(src, src_len, &mp_tmp);
366 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
369 padded = silc_mp_mp2bin(&mp_dst, &padded_len);
372 unpadded = RSA_DecodeOneBlock(padded, padded_len, 0,
373 RSA_BlockPublic, &padded_len);
375 memset(padded, 0, padded_len);
377 silc_mp_clear(&mp_tmp);
378 silc_mp_clear(&mp_dst);
382 /* Copy to destination */
383 memcpy(dst, unpadded, padded_len);
384 *dst_len = padded_len;
386 memset(padded, 0, padded_len);
387 memset(unpadded, 0, padded_len);
390 silc_mp_clear(&mp_tmp);
391 silc_mp_clear(&mp_dst);
396 SILC_PKCS_API_SIGN(pkcs1)
398 RsaKey *key = (RsaKey *)context;
402 unsigned char *padded;
403 unsigned int padded_len;
406 if (!RSA_FormatBlock(&padded, &padded_len, key->bits / 8,
407 RSA_BlockPrivate, src, src_len))
410 silc_mp_init_set_ui(&mp_tmp, 0);
411 silc_mp_init_set_ui(&mp_dst, 0);
414 silc_mp_bin2mp(padded, padded_len, &mp_tmp);
417 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
420 if (!silc_mp_mp2bin_noalloc(&mp_dst, dst, key->bits / 8, dst_len))
423 memset(padded, 0, padded_len);
425 silc_mp_clear(&mp_tmp);
426 silc_mp_clear(&mp_dst);
431 SILC_PKCS_API_VERIFY(pkcs1)
433 RsaKey *key = (RsaKey *)context;
435 SilcInt mp_tmp, mp_tmp2;
437 unsigned char *verify, unpadded;
438 unsigned int verify_len;
440 silc_mp_init_set_ui(&mp_tmp2, 0);
441 silc_mp_init_set_ui(&mp_dst, 0);
443 /* Format the signature into MP int */
444 silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
447 rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n);
450 verify = silc_mp_mp2bin(&mp_dst, &verify_len);
453 unpadded = RSA_DecodeOneBlock(verify, verify_len, 0,
454 RSA_BlockPrivate, &verify_len);
456 memset(verify, 0, verify_len);
458 silc_mp_clear(&mp_tmp2);
459 silc_mp_clear(&mp_dst);
464 if (memcmp(data, unpadded, verify_len))
467 memset(verify, 0, verify_len);
468 memset(unpadded, 0, verify_len);
471 silc_mp_clear(&mp_tmp2);
472 silc_mp_clear(&mp_dst);