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(unsigned int modulusLen, RSA_BlockType blockType,
108 unsigned char *data, unsigned int 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, unsigned int *result_len,
184 unsigned int modulusLen,
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, 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,
240 unsigned int modulusLen,
241 unsigned int expectedLen,
243 unsigned int *pResultLen)
245 RSA_BlockType blockType;
246 unsigned char *dp, *res;
247 unsigned int i, len = 0;
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 unsigned int padded_len, len = key->bits / 8;
322 if (!RSA_FormatBlock(&padded, &padded_len, len,
323 RSA_BlockPublic, src, src_len))
326 silc_mp_init_set_ui(&mp_tmp, 0);
327 silc_mp_init_set_ui(&mp_dst, 0);
330 silc_mp_bin2mp(padded, padded_len, &mp_tmp);
333 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n);
336 silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
339 memset(padded, 0, padded_len);
341 silc_mp_clear(&mp_tmp);
342 silc_mp_clear(&mp_dst);
347 SILC_PKCS_API_DECRYPT(pkcs1)
349 RsaKey *key = (RsaKey *)context;
352 unsigned char *padded, *unpadded;
353 unsigned int padded_len;
355 silc_mp_init_set_ui(&mp_tmp, 0);
356 silc_mp_init_set_ui(&mp_dst, 0);
359 silc_mp_bin2mp(src, src_len, &mp_tmp);
362 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
365 padded = silc_mp_mp2bin(&mp_dst, key->bits / 8, &padded_len);
368 unpadded = RSA_DecodeOneBlock(padded, padded_len, 0,
369 RSA_BlockPublic, &padded_len);
371 memset(padded, 0, padded_len);
373 silc_mp_clear(&mp_tmp);
374 silc_mp_clear(&mp_dst);
378 /* Copy to destination */
379 memcpy(dst, unpadded, padded_len);
380 *dst_len = padded_len;
382 memset(padded, 0, padded_len);
383 memset(unpadded, 0, padded_len);
386 silc_mp_clear(&mp_tmp);
387 silc_mp_clear(&mp_dst);
392 SILC_PKCS_API_SIGN(pkcs1)
394 RsaKey *key = (RsaKey *)context;
397 unsigned char *padded;
398 unsigned int padded_len;
399 unsigned int len = key->bits / 8;
402 if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPrivate,
406 silc_mp_init_set_ui(&mp_tmp, 0);
407 silc_mp_init_set_ui(&mp_dst, 0);
410 silc_mp_bin2mp(padded, len, &mp_tmp);
413 rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
416 silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
419 memset(padded, 0, padded_len);
421 silc_mp_clear(&mp_tmp);
422 silc_mp_clear(&mp_dst);
427 SILC_PKCS_API_VERIFY(pkcs1)
429 RsaKey *key = (RsaKey *)context;
433 unsigned char *verify, *unpadded;
434 unsigned int verify_len, len = key->bits / 8;
436 silc_mp_init_set_ui(&mp_tmp2, 0);
437 silc_mp_init_set_ui(&mp_dst, 0);
439 /* Format the signature into MP int */
440 silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
443 rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n);
446 verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
449 unpadded = RSA_DecodeOneBlock(verify, len, 0,
450 RSA_BlockPrivate, &verify_len);
452 memset(verify, 0, verify_len);
454 silc_mp_clear(&mp_tmp2);
455 silc_mp_clear(&mp_dst);
460 if (memcmp(data, unpadded, verify_len))
463 memset(verify, 0, verify_len);
464 memset(unpadded, 0, verify_len);
467 silc_mp_clear(&mp_tmp2);
468 silc_mp_clear(&mp_dst);