9b596d9b93203616280a11db6a26dfd85eceb209
[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     dp += 2;
260
261     switch (blockType) {
262       case RSA_BlockPrivate0:
263         /* Ignored */
264         res = (unsigned char *) silc_malloc(modulusLen);
265         memcpy(res, data, modulusLen);
266         break;
267
268       case RSA_BlockPrivate:
269         for (i = 0; i < modulusLen; i++) {
270             if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET)
271                 break;
272         }
273         if (i == modulusLen)
274             return NULL;
275         len = modulusLen - (dp - data);
276         res = (unsigned char *) silc_malloc(len);
277         if (res == NULL) {
278             return NULL;
279         }
280         memcpy(res, dp, len);
281         break;
282
283       case RSA_BlockPublic:
284         for (i = 0; i < modulusLen; i++) {
285             if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET)
286                 break;
287         }
288         if (i == modulusLen)
289             return NULL;
290         len = modulusLen - (dp - data);
291         res = (unsigned char *) silc_malloc(len);
292         if (res == NULL) {
293             return NULL;
294         }
295         memcpy(res, dp, len);
296         break;
297
298       default:
299         return NULL;
300     }
301
302     if (pResultLen)
303       *pResultLen = len;
304     return res;
305 }
306
307 /*
308  * SILC PKCS API for PKCS #1
309  *
310  * Note all the other PKCS API functions are used from the rsa.c.
311  * See the definitions in rsa.c and in silcpkcs.c.
312  */
313
314 SILC_PKCS_API_ENCRYPT(pkcs1)
315 {
316   RsaKey *key = (RsaKey *)context;
317   SilcMPInt mp_tmp;
318   SilcMPInt mp_dst;
319   unsigned char *padded;
320   SilcUInt32 padded_len, len = (key->bits + 7) / 8;
321
322   /* Pad data */
323   if (!RSA_FormatBlock(&padded, &padded_len, len,
324                        RSA_BlockPublic, src, src_len))
325     return FALSE;
326
327   silc_mp_init(&mp_tmp);
328   silc_mp_init(&mp_dst);
329
330   /* Data to MP */
331   silc_mp_bin2mp(padded, padded_len, &mp_tmp);
332
333   /* Encrypt */
334   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n);
335   
336   /* MP to data */
337   silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
338   *dst_len = len;
339
340   memset(padded, 0, padded_len);
341   silc_free(padded);
342   silc_mp_uninit(&mp_tmp);
343   silc_mp_uninit(&mp_dst);
344
345   return TRUE;
346 }
347
348 SILC_PKCS_API_DECRYPT(pkcs1)
349 {
350   RsaKey *key = (RsaKey *)context;
351   SilcMPInt mp_tmp;
352   SilcMPInt mp_dst;
353   unsigned char *padded, *unpadded;
354   SilcUInt32 padded_len;
355
356   silc_mp_init(&mp_tmp);
357   silc_mp_init(&mp_dst);
358
359   /* Data to MP */
360   silc_mp_bin2mp(src, src_len, &mp_tmp);
361
362   /* Decrypt */
363   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
364
365   /* MP to data */
366   padded = silc_mp_mp2bin(&mp_dst, (key->bits + 7) / 8, &padded_len);
367
368   /* Unpad data */
369   unpadded = RSA_DecodeOneBlock(padded, padded_len, 0, 
370                                 RSA_BlockPublic, &padded_len);
371   if (!unpadded) {
372     memset(padded, 0, padded_len);
373     silc_free(padded);
374     silc_mp_uninit(&mp_tmp);
375     silc_mp_uninit(&mp_dst);
376     return FALSE;
377   }
378
379   /* Copy to destination */
380   memcpy(dst, unpadded, padded_len);
381   *dst_len = padded_len;
382
383   memset(padded, 0, padded_len);
384   memset(unpadded, 0, padded_len);
385   silc_free(padded);
386   silc_free(unpadded);
387   silc_mp_uninit(&mp_tmp);
388   silc_mp_uninit(&mp_dst);
389
390   return TRUE;
391 }
392
393 SILC_PKCS_API_SIGN(pkcs1)
394 {
395   RsaKey *key = (RsaKey *)context;
396   SilcMPInt mp_tmp;
397   SilcMPInt mp_dst;
398   unsigned char *padded;
399   SilcUInt32 padded_len;
400   SilcUInt32 len = (key->bits + 7) / 8;
401
402   /* Pad data */
403   if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPrivate, 
404                        src, src_len))
405     return FALSE;
406
407   silc_mp_init(&mp_tmp);
408   silc_mp_init(&mp_dst);
409
410   /* Data to MP */
411   silc_mp_bin2mp(padded, len, &mp_tmp);
412
413   /* Sign */
414   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
415   
416   /* MP to data */
417   silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
418   *dst_len = len;
419
420   memset(padded, 0, padded_len);
421   silc_free(padded);
422   silc_mp_uninit(&mp_tmp);
423   silc_mp_uninit(&mp_dst);
424
425   return TRUE;
426 }
427
428 SILC_PKCS_API_VERIFY(pkcs1)
429 {
430   RsaKey *key = (RsaKey *)context;
431   int ret = TRUE;
432   SilcMPInt mp_tmp2;
433   SilcMPInt mp_dst;
434   unsigned char *verify, *unpadded;
435   SilcUInt32 verify_len, len = (key->bits + 7) / 8;
436
437   silc_mp_init(&mp_tmp2);
438   silc_mp_init(&mp_dst);
439
440   /* Format the signature into MP int */
441   silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
442
443   /* Verify */
444   rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n);
445
446   /* MP to data */
447   verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
448
449   /* Unpad data */
450   unpadded = RSA_DecodeOneBlock(verify, len, 0, 
451                                 RSA_BlockPrivate, &verify_len);
452   if (!unpadded) {
453     memset(verify, 0, verify_len);
454     silc_free(verify);
455     silc_mp_uninit(&mp_tmp2);
456     silc_mp_uninit(&mp_dst);
457     return FALSE;
458   }
459
460   /* Compare */
461   if (memcmp(data, unpadded, verify_len))
462     ret = FALSE;
463
464   memset(verify, 0, verify_len);
465   memset(unpadded, 0, verify_len);
466   silc_free(verify);
467   silc_free(unpadded);
468   silc_mp_uninit(&mp_tmp2);
469   silc_mp_uninit(&mp_dst);
470
471   return ret;
472 }