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, including the SILC PKCS API code that is
37 not part of the Mozilla code, falls under the same license (MPL or GPL)
38 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(unsigned int modulusLen, RSA_BlockType blockType,
108 unsigned char *data, unsigned int data_len)
110 unsigned char *block;
114 block = (unsigned char *) silc_malloc(modulusLen);
121 * All RSA blocks start with two octets:
124 *bp++ = RSA_BLOCK_FIRST_OCTET;
125 *bp++ = (unsigned char) blockType;
130 * Blocks intended for private-key operation.
132 case RSA_BlockPrivate0: /* essentially unused */
133 case RSA_BlockPrivate: /* preferred method */
135 * 0x00 || BT || Pad || 0x00 || ActualData
136 * 1 1 padLen 1 data_len
137 * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
139 padLen = modulusLen - data_len - 3;
140 assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
142 blockType == RSA_BlockPrivate0
143 ? RSA_BLOCK_PRIVATE0_PAD_OCTET
144 : RSA_BLOCK_PRIVATE_PAD_OCTET,
147 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
148 memcpy(bp, data, data_len);
152 * Blocks intended for public-key operation.
154 case RSA_BlockPublic:
156 /* XXX For now we can't do this because we can't get the
157 SilcRNG object down to this level. */
165 * 0x00 || BT || Pad || 0x00 || ActualData
166 * 1 1 padLen 1 data_len
167 * Pad is all non-zero random bytes.
169 padLen = modulusLen - data_len - 3;
170 assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
171 for (i = 0; i < padLen; i++) {
172 /* Pad with non-zero random data. */
174 RNG_GenerateGlobalRandomBytes(bp + i, 1);
175 } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
178 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
179 memcpy(bp, data, data_len);
193 RSA_FormatBlock(unsigned char **result, unsigned int *result_len,
194 unsigned int modulusLen,
195 RSA_BlockType blockType, unsigned char *data,
196 unsigned int data_len)
199 * XXX For now assume that the data length fits in a single
200 * XXX encryption block; the ASSERTs below force this.
201 * XXX To fix it, each case will have to loop over chunks whose
202 * XXX lengths satisfy the assertions, until all data is handled.
203 * XXX (Unless RSA has more to say about how to handle data
204 * XXX which does not fit in a single encryption block?)
205 * XXX And I do not know what the result is supposed to be,
206 * XXX so the interface to this function may need to change
207 * XXX to allow for returning multiple blocks, if they are
208 * XXX not wanted simply concatenated one after the other.
212 case RSA_BlockPrivate0:
213 case RSA_BlockPrivate:
214 case RSA_BlockPublic:
216 * 0x00 || BT || Pad || 0x00 || ActualData
218 * The "3" below is the first octet + the second octet + the 0x00
219 * octet that always comes just before the ActualData.
221 assert(data_len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
223 *result = RSA_FormatOneBlock(modulusLen, blockType, data, data_len);
224 if (result == NULL) {
228 *result_len = modulusLen;
242 * Takes a formatted block and returns the data part.
243 * (This is the inverse of RSA_FormatOneBlock().)
244 * In some formats the start of the data is ambiguous;
245 * if it is non-zero, expectedLen will disambiguate.
249 RSA_DecodeOneBlock(unsigned char *data,
250 unsigned int modulusLen,
251 unsigned int expectedLen,
253 unsigned int *pResultLen)
255 RSA_BlockType blockType;
256 unsigned char *dp, *res;
257 unsigned int i, len = 0;
260 if (dp[0] != RSA_BLOCK_FIRST_OCTET) {
264 blockType = (RSA_BlockType)dp[1];
271 case RSA_BlockPrivate0:
273 res = (unsigned char *) silc_malloc(modulusLen);
274 memcpy(res, data, modulusLen);
277 case RSA_BlockPrivate:
278 for (i = 0; i < modulusLen; i++) {
279 if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET)
284 len = modulusLen - (dp - data);
285 res = (unsigned char *) silc_malloc(len);
289 memcpy(res, dp, len);
292 case RSA_BlockPublic:
293 for (i = 0; i < modulusLen; i++) {
294 if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET)
299 len = modulusLen - (dp - data);
300 res = (unsigned char *) silc_malloc(len);
304 memcpy(res, dp, len);
317 * SILC PKCS API for PKCS #1
319 * Note all the other PKCS API functions are used from the rsa.c.
320 * See the definitions in rsa.c and in silcpkcs.c.
323 SILC_PKCS_API_ENCRYPT(pkcs1)
325 RsaKey *key = (RsaKey *)context;
328 unsigned char *padded;
329 unsigned int padded_len, len = key->bits / 8;
332 if (!RSA_FormatBlock(&padded, &padded_len, len,
333 RSA_BlockPublic, src, src_len))
336 silc_mp_init_set_ui(&mp_tmp, 0);
337 silc_mp_init_set_ui(&mp_dst, 0);
340 silc_mp_bin2mp(padded, padded_len, &mp_tmp);
343 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n);
346 silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
349 memset(padded, 0, padded_len);
351 silc_mp_clear(&mp_tmp);
352 silc_mp_clear(&mp_dst);
357 SILC_PKCS_API_DECRYPT(pkcs1)
359 RsaKey *key = (RsaKey *)context;
362 unsigned char *padded, *unpadded;
363 unsigned int padded_len;
365 silc_mp_init_set_ui(&mp_tmp, 0);
366 silc_mp_init_set_ui(&mp_dst, 0);
369 silc_mp_bin2mp(src, src_len, &mp_tmp);
372 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
375 padded = silc_mp_mp2bin(&mp_dst, key->bits / 8, &padded_len);
378 unpadded = RSA_DecodeOneBlock(padded, padded_len, 0,
379 RSA_BlockPublic, &padded_len);
381 memset(padded, 0, padded_len);
383 silc_mp_clear(&mp_tmp);
384 silc_mp_clear(&mp_dst);
388 /* Copy to destination */
389 memcpy(dst, unpadded, padded_len);
390 *dst_len = padded_len;
392 memset(padded, 0, padded_len);
393 memset(unpadded, 0, padded_len);
396 silc_mp_clear(&mp_tmp);
397 silc_mp_clear(&mp_dst);
402 SILC_PKCS_API_SIGN(pkcs1)
404 RsaKey *key = (RsaKey *)context;
407 unsigned char *padded;
408 unsigned int padded_len;
409 unsigned int len = key->bits / 8;
412 if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPrivate,
416 silc_mp_init_set_ui(&mp_tmp, 0);
417 silc_mp_init_set_ui(&mp_dst, 0);
420 silc_mp_bin2mp(padded, len, &mp_tmp);
423 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
426 silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
429 memset(padded, 0, padded_len);
431 silc_mp_clear(&mp_tmp);
432 silc_mp_clear(&mp_dst);
437 SILC_PKCS_API_VERIFY(pkcs1)
439 RsaKey *key = (RsaKey *)context;
443 unsigned char *verify, *unpadded;
444 unsigned int verify_len, len = key->bits / 8;
446 silc_mp_init_set_ui(&mp_tmp2, 0);
447 silc_mp_init_set_ui(&mp_dst, 0);
449 /* Format the signature into MP int */
450 silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
453 rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n);
456 verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
459 unpadded = RSA_DecodeOneBlock(verify, len, 0,
460 RSA_BlockPrivate, &verify_len);
462 memset(verify, 0, verify_len);
464 silc_mp_clear(&mp_tmp2);
465 silc_mp_clear(&mp_dst);
470 if (memcmp(data, unpadded, verify_len))
473 memset(verify, 0, verify_len);
474 memset(unpadded, 0, verify_len);
477 silc_mp_clear(&mp_tmp2);
478 silc_mp_clear(&mp_dst);