c3136f58eef0d4b39e9d625279dd07e429120a97
[silc.git] / lib / silccrypt / pkcs1.c
1 /* 
2    PKCS #1 RSA wrapper.
3
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.
6
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.
11
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.
15
16    Note:
17
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.
26
27    Any questions and comments regarding this modified version should be
28    sent to priikone@poseidon.pspt.fi.
29
30    References: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc,
31                ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1.asc,
32                and RFC 2437.
33
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
36    to this file, below.
37 */
38
39 /*
40  * PKCS#1 encoding and decoding functions.
41  * This file is believed to contain no code licensed from other parties.
42  *
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/
47  * 
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.
52  * 
53  * The Original Code is the Netscape security libraries.
54  * 
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
58  * Rights Reserved.
59  * 
60  * Contributor(s):
61  * 
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
72  * GPL.
73  *
74  * $Id$
75  */
76
77 #include "silcincludes.h"
78
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
84
85 /*
86  * RSA block types
87  *
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...
91  */
92 typedef enum {
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 */
96     RSA_BlockTotal
97 } RSA_BlockType;
98
99 /*
100  * Format one block of data for public/private key encryption using
101  * the rules defined in PKCS #1.
102  */
103 static unsigned char *
104 RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
105                    unsigned char *data, unsigned int data_len)
106 {
107     unsigned char *block;
108     unsigned char *bp;
109     int padLen;
110     int i;
111
112     block = (unsigned char *) silc_malloc(modulusLen);
113     if (block == NULL)
114         return NULL;
115
116     bp = block;
117
118     /*
119      * All RSA blocks start with two octets:
120      *  0x00 || BlockType
121      */
122     *bp++ = RSA_BLOCK_FIRST_OCTET;
123     *bp++ = (unsigned char) blockType;
124
125     switch (blockType) {
126
127       /*
128        * Blocks intended for private-key operation.
129        */
130       case RSA_BlockPrivate0: /* essentially unused */
131       case RSA_BlockPrivate:     /* preferred method */
132         /*
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.
136          */
137         padLen = modulusLen - data_len - 3;
138         assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
139         memset(bp,
140                    blockType == RSA_BlockPrivate0
141                         ? RSA_BLOCK_PRIVATE0_PAD_OCTET
142                         : RSA_BLOCK_PRIVATE_PAD_OCTET,
143                    padLen);
144         bp += padLen;
145         *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
146         memcpy(bp, data, data_len);
147         break;
148
149       /*
150        * Blocks intended for public-key operation.
151        */
152       case RSA_BlockPublic:
153
154         /*
155          * 0x00 || BT || Pad || 0x00 || ActualData
156          *   1      1   padLen    1      data_len
157          * Pad is all non-zero random bytes.
158          */
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. */
163             do {
164                 RNG_GenerateGlobalRandomBytes(bp + i, 1);
165             } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
166         }
167         bp += padLen;
168         *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
169         memcpy(bp, data, data_len);
170
171         break;
172
173       default:
174         assert(0);
175         silc_free(block);
176         return NULL;
177     }
178
179     return block;
180 }
181
182 static int
183 RSA_FormatBlock(unsigned char **result, unsigned int *result_len,
184                 unsigned modulusLen,
185                 RSA_BlockType blockType, unsigned char *data,
186                 unsigned int data_len)
187 {
188     /*
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.
199      */
200
201     switch (blockType) {
202       case RSA_BlockPrivate0:
203       case RSA_BlockPrivate:
204       case RSA_BlockPublic:
205         /*
206          * 0x00 || BT || Pad || 0x00 || ActualData
207          *
208          * The "3" below is the first octet + the second octet + the 0x00
209          * octet that always comes just before the ActualData.
210          */
211         assert(data_len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
212
213         *result = RSA_FormatOneBlock(modulusLen, blockType, data);
214         if (result == NULL) {
215             *result_len = 0;
216             return FALSE;
217         }
218         *result_len = modulusLen;
219
220         break;
221
222       default:
223         *result = NULL;
224         *result_len = 0;
225         return FALSE;
226     }
227
228     return TRUE;
229 }
230
231 /*
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.
236  *
237  */
238 unsigned char *
239 RSA_DecodeOneBlock(unsigned char *data,
240                    unsigned int modulusLen,
241                    unsigned int expectedLen,
242                    RSA_BlockType bt,
243                    unsigned int *pResultLen)
244 {
245     RSA_BlockType blockType;
246     unsigned char *dp, *res;
247     unsigned int i, len;
248
249     dp = data;
250     if (*dp++ != RSA_BLOCK_FIRST_OCTET) {
251         return NULL;
252     }
253
254     blockType = (RSA_BlockType)*dp++;
255     if (blockType != bt)
256       return NULL;
257
258     switch (blockType) {
259       case RSA_BlockPrivate0:
260         /* Ignored */
261         res = (unsigned char *) silc_malloc(modulusLen);
262         memcpy(res, data, modulusLen);
263         break;
264
265       case RSA_BlockPrivate:
266         for (i = 0; i < modulusLen; i++) {
267             if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET)
268                 break;
269         }
270         if ((i == modulusLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
271             return NULL;
272         }
273         dp++;
274         len = modulusLen - (dp - data);
275         res = (unsigned char *) silc_malloc(len);
276         if (res == NULL) {
277             return NULL;
278         }
279         memcpy(res, dp, len);
280         break;
281
282       case RSA_BlockPublic:
283         for (i = 0; i < modulusLen; i++) {
284             if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET)
285                 break;
286         }
287         if (i == modulusLen) {
288             return NULL;
289         }
290         dp++;
291         len = modulusLen - (dp - data);
292         res = (unsigned char *) silc_malloc(len);
293         if (res == NULL) {
294             return NULL;
295         }
296         memcpy(res, dp, len);
297         break;
298
299       default:
300         return NULL;
301     }
302
303     if (pResultLen)
304       *pResultLen = len;
305     return res;
306 }
307
308 /*
309  * SILC PKCS API for PKCS #1
310  *
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.
313  */
314
315 SILC_PKCS_API_ENCRYPT(pkcs1)
316 {
317   RsaKey *key = (RsaKey *)context;
318   int i, ret = TRUE;
319   SilcInt mp_tmp;
320   SilcInt mp_dst;
321   unsigned char *padded;
322   unsigned int padded_len;
323
324   /* Pad data */
325   if (!RSA_FormatBlock(&padded, &padded_len, key->bits / 8,
326                        RSA_BlockPublic, src, src_len))
327     return FALSE;
328
329   silc_mp_init_set_ui(&mp_tmp, 0);
330   silc_mp_init_set_ui(&mp_dst, 0);
331
332   /* Data to MP */
333   silc_mp_bin2mp(padded, padded_len, &mp_tmp);
334
335   /* Encrypt */
336   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n);
337   
338   /* MP to data */
339   if (!silc_mp_mp2bin_noalloc(&mp_dst, dst, key->bits / 8, dst_len))
340     ret = FALSE;
341
342   memset(padded, 0, padded_len);
343   silc_free(padded);
344   silc_mp_clear(&mp_tmp);
345   silc_mp_clear(&mp_dst);
346
347   return ret;
348 }
349
350 SILC_PKCS_API_DECRYPT(pkcs1)
351 {
352   RsaKey *key = (RsaKey *)context;
353   int i, tmplen;
354   SilcInt mp_tmp;
355   SilcInt mp_dst;
356   unsigned char *padded, *unpadded;
357   unsigned int padded_len;
358
359   silc_mp_init_set_ui(&mp_tmp, 0);
360   silc_mp_init_set_ui(&mp_dst, 0);
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, &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_clear(&mp_tmp);
378     silc_mp_clear(&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_clear(&mp_tmp);
391   silc_mp_clear(&mp_dst);
392
393   return TRUE;
394 }
395
396 SILC_PKCS_API_SIGN(pkcs1)
397 {
398   RsaKey *key = (RsaKey *)context;
399   int i, ret = TRUE;
400   SilcInt mp_tmp;
401   SilcInt mp_dst;
402   unsigned char *padded;
403   unsigned int padded_len;
404
405   /* Pad data */
406   if (!RSA_FormatBlock(&padded, &padded_len, key->bits / 8,
407                        RSA_BlockPrivate, src, src_len))
408     return FALSE;
409
410   silc_mp_init_set_ui(&mp_tmp, 0);
411   silc_mp_init_set_ui(&mp_dst, 0);
412
413   /* Data to MP */
414   silc_mp_bin2mp(padded, 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   if (!silc_mp_mp2bin_noalloc(&mp_dst, dst, key->bits / 8, dst_len))
421     ret = FALSE;
422
423   memset(padded, 0, padded_len);
424   silc_free(padded);
425   silc_mp_clear(&mp_tmp);
426   silc_mp_clear(&mp_dst);
427
428   return ret;
429 }
430
431 SILC_PKCS_API_VERIFY(pkcs1)
432 {
433   RsaKey *key = (RsaKey *)context;
434   int i, ret = TRUE;
435   SilcInt mp_tmp, mp_tmp2;
436   SilcInt mp_dst;
437   unsigned char *verify, unpadded;
438   unsigned int verify_len;
439
440   silc_mp_init_set_ui(&mp_tmp2, 0);
441   silc_mp_init_set_ui(&mp_dst, 0);
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, &verify_len);
451
452   /* Unpad data */
453   unpadded = RSA_DecodeOneBlock(verify, verify_len, 0, 
454                                 RSA_BlockPrivate, &verify_len);
455   if (!unpadded) {
456     memset(verify, 0, verify_len);
457     silc_free(verify);
458     silc_mp_clear(&mp_tmp2);
459     silc_mp_clear(&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_clear(&mp_tmp2);
472   silc_mp_clear(&mp_dst);
473
474   return ret;
475 }