Merged silc_1_0_branch to trunk.
[silc.git] / lib / silccrypt / pkcs1.c
1 /* $Id$ */
2 /* 
3    PKCS #1 RSA wrapper.
4
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
7    and changed.
8
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.
13
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.
17
18    Note:
19
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.
28
29    Any questions and comments regarding this modified version should be
30    sent to priikone@silcnet.org.
31
32    References: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc,
33                ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1.asc,
34                and RFC 2437.
35
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.
39 */
40
41 /*
42  * PKCS#1 encoding and decoding functions.
43  * This file is believed to contain no code licensed from other parties.
44  *
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/
49  * 
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.
54  * 
55  * The Original Code is the Netscape security libraries.
56  * 
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
60  * Rights Reserved.
61  * 
62  * Contributor(s):
63  * 
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
74  * GPL.
75  *
76  * $Id$
77  */
78
79 #include "silcincludes.h"
80 #include "rsa_internal.h"
81 #include "rsa.h"
82
83 #define RSA_BLOCK_MIN_PAD_LEN           8
84 #define RSA_BLOCK_FIRST_OCTET           0x00
85 #define RSA_BLOCK_PRIVATE0_PAD_OCTET    0x00
86 #define RSA_BLOCK_PRIVATE_PAD_OCTET     0xff
87 #define RSA_BLOCK_AFTER_PAD_OCTET       0x00
88
89 /*
90  * RSA block types
91  *
92  * The actual values are important -- they are fixed, *not* arbitrary.
93  * The explicit value assignments are not needed (because C would give
94  * us those same values anyway) but are included as a reminder...
95  */
96 typedef enum {
97     RSA_BlockPrivate0 = 0,      /* unused, really */
98     RSA_BlockPrivate = 1,       /* pad for a private-key operation */
99     RSA_BlockPublic = 2,        /* pad for a public-key operation */
100     RSA_BlockTotal
101 } RSA_BlockType;
102
103 /*
104  * Format one block of data for public/private key encryption using
105  * the rules defined in PKCS #1.
106  */
107 static unsigned char *
108 RSA_FormatOneBlock(SilcUInt32 modulusLen, RSA_BlockType blockType,
109                    unsigned char *data, SilcUInt32 data_len)
110 {
111     unsigned char *block;
112     unsigned char *bp;
113     int padLen;
114     int i;
115
116     block = (unsigned char *) silc_malloc(modulusLen);
117     if (block == NULL)
118         return NULL;
119
120     bp = block;
121
122     /*
123      * All RSA blocks start with two octets:
124      *  0x00 || BlockType
125      */
126     *bp++ = RSA_BLOCK_FIRST_OCTET;
127     *bp++ = (unsigned char) blockType;
128
129     switch (blockType) {
130
131       /*
132        * Blocks intended for private-key operation.
133        */
134       case RSA_BlockPrivate0: /* essentially unused */
135       case RSA_BlockPrivate:     /* preferred method */
136         /*
137          * 0x00 || BT || Pad || 0x00 || ActualData
138          *   1      1   padLen    1      data_len
139          * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
140          */
141         padLen = modulusLen - data_len - 3;
142         assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
143         memset(bp,
144                    blockType == RSA_BlockPrivate0
145                         ? RSA_BLOCK_PRIVATE0_PAD_OCTET
146                         : RSA_BLOCK_PRIVATE_PAD_OCTET,
147                    padLen);
148         bp += padLen;
149         *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
150         memcpy(bp, data, data_len);
151         break;
152
153       /*
154        * Blocks intended for public-key operation.
155        */
156       case RSA_BlockPublic:
157         /*
158          * 0x00 || BT || Pad || 0x00 || ActualData
159          *   1      1   padLen    1      data_len
160          * Pad is all non-zero random bytes.
161          */
162         padLen = modulusLen - data_len - 3;
163         assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
164         for (i = 0; i < padLen; i++) {
165             /* Pad with non-zero random data. */
166             do {
167               bp[i] = silc_rng_global_get_byte();
168             } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
169         }
170         bp += padLen;
171         *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
172         memcpy(bp, data, data_len);
173         break;
174
175       default:
176         silc_free(block);
177         return NULL;
178     }
179
180     return block;
181 }
182
183 static int
184 RSA_FormatBlock(unsigned char **result, SilcUInt32 *result_len,
185                 SilcUInt32 modulusLen,
186                 RSA_BlockType blockType, unsigned char *data,
187                 SilcUInt32 data_len)
188 {
189     /*
190      * XXX For now assume that the data length fits in a single
191      * XXX encryption block; the ASSERTs below force this.
192      * XXX To fix it, each case will have to loop over chunks whose
193      * XXX lengths satisfy the assertions, until all data is handled.
194      * XXX (Unless RSA has more to say about how to handle data
195      * XXX which does not fit in a single encryption block?)
196      * XXX And I do not know what the result is supposed to be,
197      * XXX so the interface to this function may need to change
198      * XXX to allow for returning multiple blocks, if they are
199      * XXX not wanted simply concatenated one after the other.
200      */
201
202     switch (blockType) {
203       case RSA_BlockPrivate0:
204       case RSA_BlockPrivate:
205       case RSA_BlockPublic:
206         /*
207          * 0x00 || BT || Pad || 0x00 || ActualData
208          *
209          * The "3" below is the first octet + the second octet + the 0x00
210          * octet that always comes just before the ActualData.
211          */
212         assert(data_len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
213
214         *result = RSA_FormatOneBlock(modulusLen, blockType, data, data_len);
215         if (result == NULL) {
216             *result_len = 0;
217             return FALSE;
218         }
219         *result_len = modulusLen;
220
221         break;
222
223       default:
224         *result = NULL;
225         *result_len = 0;
226         return FALSE;
227     }
228
229     return TRUE;
230 }
231
232 /*
233  * Takes a formatted block and returns the data part.
234  * (This is the inverse of RSA_FormatOneBlock().)
235  * In some formats the start of the data is ambiguous;
236  * if it is non-zero, expectedLen will disambiguate.
237  *
238  */
239 unsigned char *
240 RSA_DecodeOneBlock(unsigned char *data,
241                    SilcUInt32 modulusLen,
242                    SilcUInt32 expectedLen,
243                    RSA_BlockType bt,
244                    SilcUInt32 *pResultLen)
245 {
246     RSA_BlockType blockType;
247     unsigned char *dp, *res;
248     SilcUInt32 i, len = 0;
249
250     dp = data;
251     if (dp[0] != RSA_BLOCK_FIRST_OCTET) {
252         return NULL;
253     }
254
255     blockType = (RSA_BlockType)dp[1];
256     if (blockType != bt)
257       return NULL;
258
259     if (modulusLen < 2 + 1)
260       return NULL;
261
262     dp += 2;
263
264     switch (blockType) {
265       case RSA_BlockPrivate0:
266         /* Ignored */
267         res = (unsigned char *) silc_malloc(modulusLen);
268         memcpy(res, data, modulusLen);
269         break;
270
271       case RSA_BlockPrivate:
272         for (i = 0; i < modulusLen; i++) {
273             if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET)
274                 break;
275         }
276         if (i == modulusLen)
277             return NULL;
278         len = modulusLen - (dp - data);
279         res = (unsigned char *) silc_malloc(len);
280         if (res == NULL) {
281             return NULL;
282         }
283         memcpy(res, dp, len);
284         break;
285
286       case RSA_BlockPublic:
287         for (i = 0; i < modulusLen; i++) {
288             if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET)
289                 break;
290         }
291         if (i == modulusLen)
292             return NULL;
293         len = modulusLen - (dp - data);
294         res = (unsigned char *) silc_malloc(len);
295         if (res == NULL) {
296             return NULL;
297         }
298         memcpy(res, dp, len);
299         break;
300
301       default:
302         return NULL;
303     }
304
305     if (pResultLen)
306       *pResultLen = len;
307     return res;
308 }
309
310 /*
311  * SILC PKCS API for PKCS #1
312  *
313  * Note all the other PKCS API functions are used from the rsa.c.
314  * See the definitions in rsa.c and in silcpkcs.c.
315  */
316
317 SILC_PKCS_API_ENCRYPT(pkcs1)
318 {
319   RsaKey *key = (RsaKey *)context;
320   SilcMPInt mp_tmp;
321   SilcMPInt mp_dst;
322   unsigned char *padded;
323   SilcUInt32 padded_len, len = (key->bits + 7) / 8;
324
325   /* Pad data */
326   if (!RSA_FormatBlock(&padded, &padded_len, len,
327                        RSA_BlockPublic, src, src_len))
328     return FALSE;
329
330   silc_mp_init(&mp_tmp);
331   silc_mp_init(&mp_dst);
332
333   /* Data to MP */
334   silc_mp_bin2mp(padded, padded_len, &mp_tmp);
335
336   /* Encrypt */
337   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n);
338   
339   /* MP to data */
340   silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
341   *dst_len = len;
342
343   memset(padded, 0, padded_len);
344   silc_free(padded);
345   silc_mp_uninit(&mp_tmp);
346   silc_mp_uninit(&mp_dst);
347
348   return TRUE;
349 }
350
351 SILC_PKCS_API_DECRYPT(pkcs1)
352 {
353   RsaKey *key = (RsaKey *)context;
354   SilcMPInt mp_tmp;
355   SilcMPInt mp_dst;
356   unsigned char *padded, *unpadded;
357   SilcUInt32 padded_len;
358
359   silc_mp_init(&mp_tmp);
360   silc_mp_init(&mp_dst);
361
362   /* Data to MP */
363   silc_mp_bin2mp(src, src_len, &mp_tmp);
364
365   /* Decrypt */
366   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
367
368   /* MP to data */
369   padded = silc_mp_mp2bin(&mp_dst, (key->bits + 7) / 8, &padded_len);
370
371   /* Unpad data */
372   unpadded = RSA_DecodeOneBlock(padded, padded_len, 0, 
373                                 RSA_BlockPublic, &padded_len);
374   if (!unpadded) {
375     memset(padded, 0, padded_len);
376     silc_free(padded);
377     silc_mp_uninit(&mp_tmp);
378     silc_mp_uninit(&mp_dst);
379     return FALSE;
380   }
381
382   /* Copy to destination */
383   memcpy(dst, unpadded, padded_len);
384   *dst_len = padded_len;
385
386   memset(padded, 0, padded_len);
387   memset(unpadded, 0, padded_len);
388   silc_free(padded);
389   silc_free(unpadded);
390   silc_mp_uninit(&mp_tmp);
391   silc_mp_uninit(&mp_dst);
392
393   return TRUE;
394 }
395
396 SILC_PKCS_API_SIGN(pkcs1)
397 {
398   RsaKey *key = (RsaKey *)context;
399   SilcMPInt mp_tmp;
400   SilcMPInt mp_dst;
401   unsigned char *padded;
402   SilcUInt32 padded_len;
403   SilcUInt32 len = (key->bits + 7) / 8;
404
405   /* Pad data */
406   if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPrivate, 
407                        src, src_len))
408     return FALSE;
409
410   silc_mp_init(&mp_tmp);
411   silc_mp_init(&mp_dst);
412
413   /* Data to MP */
414   silc_mp_bin2mp(padded, len, &mp_tmp);
415
416   /* Sign */
417   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
418   
419   /* MP to data */
420   silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
421   *dst_len = len;
422
423   memset(padded, 0, padded_len);
424   silc_free(padded);
425   silc_mp_uninit(&mp_tmp);
426   silc_mp_uninit(&mp_dst);
427
428   return TRUE;
429 }
430
431 SILC_PKCS_API_VERIFY(pkcs1)
432 {
433   RsaKey *key = (RsaKey *)context;
434   int ret = TRUE;
435   SilcMPInt mp_tmp2;
436   SilcMPInt mp_dst;
437   unsigned char *verify, *unpadded;
438   SilcUInt32 verify_len, len = (key->bits + 7) / 8;
439
440   silc_mp_init(&mp_tmp2);
441   silc_mp_init(&mp_dst);
442
443   /* Format the signature into MP int */
444   silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
445
446   /* Verify */
447   rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n);
448
449   /* MP to data */
450   verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
451
452   /* Unpad data */
453   unpadded = RSA_DecodeOneBlock(verify, len, 0, 
454                                 RSA_BlockPrivate, &verify_len);
455   if (!unpadded) {
456     memset(verify, 0, verify_len);
457     silc_free(verify);
458     silc_mp_uninit(&mp_tmp2);
459     silc_mp_uninit(&mp_dst);
460     return FALSE;
461   }
462
463   /* Compare */
464   if (memcmp(data, unpadded, verify_len))
465     ret = FALSE;
466
467   memset(verify, 0, verify_len);
468   memset(unpadded, 0, verify_len);
469   silc_free(verify);
470   silc_free(unpadded);
471   silc_mp_uninit(&mp_tmp2);
472   silc_mp_uninit(&mp_dst);
473
474   return ret;
475 }