5 Heavily modified to work under SILC, rewrote all interfaces, code that
6 is not needed in SILC has been removed for good, and some code was fixed
9 For example, RSA_DecodeOneBlock was not used at all by Mozilla, however,
10 I took this code in to use after doing some fixing (it had some bugs).
11 Also, OAEP is removed totally for now. I'm not sure whether OAEP could
12 be used in the future with SILC but not for now.
14 This file also implements partial SILC PKCS API for RSA with PKCS #1.
15 It is partial because all the other functions but encrypt, decrypt,
16 sign and verify are common.
20 The mandatory PKCS #1 implementation in SILC must be compliant to either
21 PKCS #1 version 1.5 or PKCS #1 version 2 with the following notes:
22 The signature encoding is always in same format as the encryption
23 encoding regardles of the PKCS #1 version. The signature with
24 appendix (with hash algorithm OID in the data) must not be used
25 in the SILC. Rationale for this is that there is no binding between
26 the PKCS #1 OIDs and the hash algorithms used in the SILC protocol.
27 Hence, the encoding is always in PKCS #1 version 1.5 format.
29 Any questions and comments regarding this modified version should be
30 sent to priikone@poseidon.pspt.fi.
32 References: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc,
33 ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1.asc,
36 Copyright notice: All code in this file, including the SILC PKCS API
37 code that is not part of the Mozilla code, falls under the same license
38 (MPL or GPL) found attached to this file, below.
42 * PKCS#1 encoding and decoding functions.
43 * This file is believed to contain no code licensed from other parties.
45 * The contents of this file are subject to the Mozilla Public
46 * License Version 1.1 (the "License"); you may not use this file
47 * except in compliance with the License. You may obtain a copy of
48 * the License at http://www.mozilla.org/MPL/
50 * Software distributed under the License is distributed on an "AS
51 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
52 * implied. See the License for the specific language governing
53 * rights and limitations under the License.
55 * The Original Code is the Netscape security libraries.
57 * The Initial Developer of the Original Code is Netscape
58 * Communications Corporation. Portions created by Netscape are
59 * Copyright (C) 1994-2000 Netscape Communications Corporation. All
64 * Alternatively, the contents of this file may be used under the
65 * terms of the GNU General Public License Version 2 or later (the
66 * "GPL"), in which case the provisions of the GPL are applicable
67 * instead of those above. If you wish to allow use of your
68 * version of this file only under the terms of the GPL and not to
69 * allow others to use your version of this file under the MPL,
70 * indicate your decision by deleting the provisions above and
71 * replace them with the notice and other provisions required by
72 * the GPL. If you do not delete the provisions above, a recipient
73 * may use your version of this file under either the MPL or the
79 #include "silcincludes.h"
82 #define RSA_BLOCK_MIN_PAD_LEN 8
83 #define RSA_BLOCK_FIRST_OCTET 0x00
84 #define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00
85 #define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
86 #define RSA_BLOCK_AFTER_PAD_OCTET 0x00
91 * The actual values are important -- they are fixed, *not* arbitrary.
92 * The explicit value assignments are not needed (because C would give
93 * us those same values anyway) but are included as a reminder...
96 RSA_BlockPrivate0 = 0, /* unused, really */
97 RSA_BlockPrivate = 1, /* pad for a private-key operation */
98 RSA_BlockPublic = 2, /* pad for a public-key operation */
103 * Format one block of data for public/private key encryption using
104 * the rules defined in PKCS #1.
106 static unsigned char *
107 RSA_FormatOneBlock(uint32 modulusLen, RSA_BlockType blockType,
108 unsigned char *data, uint32 data_len)
110 unsigned char *block;
115 block = (unsigned char *) silc_malloc(modulusLen);
122 * All RSA blocks start with two octets:
125 *bp++ = RSA_BLOCK_FIRST_OCTET;
126 *bp++ = (unsigned char) blockType;
131 * Blocks intended for private-key operation.
133 case RSA_BlockPrivate0: /* essentially unused */
134 case RSA_BlockPrivate: /* preferred method */
136 * 0x00 || BT || Pad || 0x00 || ActualData
137 * 1 1 padLen 1 data_len
138 * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
140 padLen = modulusLen - data_len - 3;
141 assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
143 blockType == RSA_BlockPrivate0
144 ? RSA_BLOCK_PRIVATE0_PAD_OCTET
145 : RSA_BLOCK_PRIVATE_PAD_OCTET,
148 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
149 memcpy(bp, data, data_len);
153 * Blocks intended for public-key operation.
155 case RSA_BlockPublic:
157 * 0x00 || BT || Pad || 0x00 || ActualData
158 * 1 1 padLen 1 data_len
159 * Pad is all non-zero random bytes.
161 padLen = modulusLen - data_len - 3;
162 assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
163 for (i = 0; i < padLen; i++) {
164 /* Pad with non-zero random data. */
166 silc_rng_global_get_byte(bp + i);
167 } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
170 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
171 memcpy(bp, data, data_len);
183 RSA_FormatBlock(unsigned char **result, uint32 *result_len,
185 RSA_BlockType blockType, unsigned char *data,
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, data_len);
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,
245 RSA_BlockType blockType;
246 unsigned char *dp, *res;
250 if (dp[0] != RSA_BLOCK_FIRST_OCTET) {
254 blockType = (RSA_BlockType)dp[1];
261 case RSA_BlockPrivate0:
263 res = (unsigned char *) silc_malloc(modulusLen);
264 memcpy(res, data, modulusLen);
267 case RSA_BlockPrivate:
268 for (i = 0; i < modulusLen; i++) {
269 if (*dp++ != RSA_BLOCK_PRIVATE_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)
289 len = modulusLen - (dp - data);
290 res = (unsigned char *) silc_malloc(len);
294 memcpy(res, dp, len);
307 * SILC PKCS API for PKCS #1
309 * Note all the other PKCS API functions are used from the rsa.c.
310 * See the definitions in rsa.c and in silcpkcs.c.
313 SILC_PKCS_API_ENCRYPT(pkcs1)
315 RsaKey *key = (RsaKey *)context;
318 unsigned char *padded;
319 uint32 padded_len, len = key->bits / 8;
322 if (!RSA_FormatBlock(&padded, &padded_len, len,
323 RSA_BlockPublic, src, src_len))
326 silc_mp_init(&mp_tmp);
327 silc_mp_init(&mp_dst);
328 silc_mp_set_ui(&mp_tmp, 0);
329 silc_mp_set_ui(&mp_dst, 0);
332 silc_mp_bin2mp(padded, padded_len, &mp_tmp);
335 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n);
338 silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
341 memset(padded, 0, padded_len);
343 silc_mp_uninit(&mp_tmp);
344 silc_mp_uninit(&mp_dst);
349 SILC_PKCS_API_DECRYPT(pkcs1)
351 RsaKey *key = (RsaKey *)context;
354 unsigned char *padded, *unpadded;
357 silc_mp_init(&mp_tmp);
358 silc_mp_init(&mp_dst);
359 silc_mp_set_ui(&mp_tmp, 0);
360 silc_mp_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, key->bits / 8, &padded_len);
372 unpadded = RSA_DecodeOneBlock(padded, padded_len, 0,
373 RSA_BlockPublic, &padded_len);
375 memset(padded, 0, padded_len);
377 silc_mp_uninit(&mp_tmp);
378 silc_mp_uninit(&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_uninit(&mp_tmp);
391 silc_mp_uninit(&mp_dst);
396 SILC_PKCS_API_SIGN(pkcs1)
398 RsaKey *key = (RsaKey *)context;
401 unsigned char *padded;
403 uint32 len = key->bits / 8;
406 if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPrivate,
410 silc_mp_init(&mp_tmp);
411 silc_mp_init(&mp_dst);
412 silc_mp_set_ui(&mp_tmp, 0);
413 silc_mp_set_ui(&mp_dst, 0);
416 silc_mp_bin2mp(padded, len, &mp_tmp);
419 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
422 silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
425 memset(padded, 0, padded_len);
427 silc_mp_uninit(&mp_tmp);
428 silc_mp_uninit(&mp_dst);
433 SILC_PKCS_API_VERIFY(pkcs1)
435 RsaKey *key = (RsaKey *)context;
439 unsigned char *verify, *unpadded;
440 uint32 verify_len, len = key->bits / 8;
442 silc_mp_init(&mp_tmp2);
443 silc_mp_init(&mp_dst);
444 silc_mp_set_ui(&mp_tmp2, 0);
445 silc_mp_set_ui(&mp_dst, 0);
447 /* Format the signature into MP int */
448 silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
451 rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n);
454 verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
457 unpadded = RSA_DecodeOneBlock(verify, len, 0,
458 RSA_BlockPrivate, &verify_len);
460 memset(verify, 0, verify_len);
462 silc_mp_uninit(&mp_tmp2);
463 silc_mp_uninit(&mp_dst);
468 if (memcmp(data, unpadded, verify_len))
471 memset(verify, 0, verify_len);
472 memset(unpadded, 0, verify_len);
475 silc_mp_uninit(&mp_tmp2);
476 silc_mp_uninit(&mp_dst);