Integer type name change.
[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 / 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   silc_mp_set_ui(&mp_tmp, 0);
330   silc_mp_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   silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
340   *dst_len = len;
341
342   memset(padded, 0, padded_len);
343   silc_free(padded);
344   silc_mp_uninit(&mp_tmp);
345   silc_mp_uninit(&mp_dst);
346
347   return TRUE;
348 }
349
350 SILC_PKCS_API_DECRYPT(pkcs1)
351 {
352   RsaKey *key = (RsaKey *)context;
353   SilcMPInt mp_tmp;
354   SilcMPInt mp_dst;
355   unsigned char *padded, *unpadded;
356   SilcUInt32 padded_len;
357
358   silc_mp_init(&mp_tmp);
359   silc_mp_init(&mp_dst);
360   silc_mp_set_ui(&mp_tmp, 0);
361   silc_mp_set_ui(&mp_dst, 0);
362
363   /* Data to MP */
364   silc_mp_bin2mp(src, src_len, &mp_tmp);
365
366   /* Decrypt */
367   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
368
369   /* MP to data */
370   padded = silc_mp_mp2bin(&mp_dst, key->bits / 8, &padded_len);
371
372   /* Unpad data */
373   unpadded = RSA_DecodeOneBlock(padded, padded_len, 0, 
374                                 RSA_BlockPublic, &padded_len);
375   if (!unpadded) {
376     memset(padded, 0, padded_len);
377     silc_free(padded);
378     silc_mp_uninit(&mp_tmp);
379     silc_mp_uninit(&mp_dst);
380     return FALSE;
381   }
382
383   /* Copy to destination */
384   memcpy(dst, unpadded, padded_len);
385   *dst_len = padded_len;
386
387   memset(padded, 0, padded_len);
388   memset(unpadded, 0, padded_len);
389   silc_free(padded);
390   silc_free(unpadded);
391   silc_mp_uninit(&mp_tmp);
392   silc_mp_uninit(&mp_dst);
393
394   return TRUE;
395 }
396
397 SILC_PKCS_API_SIGN(pkcs1)
398 {
399   RsaKey *key = (RsaKey *)context;
400   SilcMPInt mp_tmp;
401   SilcMPInt mp_dst;
402   unsigned char *padded;
403   SilcUInt32 padded_len;
404   SilcUInt32 len = key->bits / 8;
405
406   /* Pad data */
407   if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPrivate, 
408                        src, src_len))
409     return FALSE;
410
411   silc_mp_init(&mp_tmp);
412   silc_mp_init(&mp_dst);
413   silc_mp_set_ui(&mp_tmp, 0);
414   silc_mp_set_ui(&mp_dst, 0);
415
416   /* Data to MP */
417   silc_mp_bin2mp(padded, len, &mp_tmp);
418
419   /* Sign */
420   rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n);
421   
422   /* MP to data */
423   silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
424   *dst_len = len;
425
426   memset(padded, 0, padded_len);
427   silc_free(padded);
428   silc_mp_uninit(&mp_tmp);
429   silc_mp_uninit(&mp_dst);
430
431   return TRUE;
432 }
433
434 SILC_PKCS_API_VERIFY(pkcs1)
435 {
436   RsaKey *key = (RsaKey *)context;
437   int ret = TRUE;
438   SilcMPInt mp_tmp2;
439   SilcMPInt mp_dst;
440   unsigned char *verify, *unpadded;
441   SilcUInt32 verify_len, len = key->bits / 8;
442
443   silc_mp_init(&mp_tmp2);
444   silc_mp_init(&mp_dst);
445   silc_mp_set_ui(&mp_tmp2, 0);
446   silc_mp_set_ui(&mp_dst, 0);
447
448   /* Format the signature into MP int */
449   silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
450
451   /* Verify */
452   rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n);
453
454   /* MP to data */
455   verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
456
457   /* Unpad data */
458   unpadded = RSA_DecodeOneBlock(verify, len, 0, 
459                                 RSA_BlockPrivate, &verify_len);
460   if (!unpadded) {
461     memset(verify, 0, verify_len);
462     silc_free(verify);
463     silc_mp_uninit(&mp_tmp2);
464     silc_mp_uninit(&mp_dst);
465     return FALSE;
466   }
467
468   /* Compare */
469   if (memcmp(data, unpadded, verify_len))
470     ret = FALSE;
471
472   memset(verify, 0, verify_len);
473   memset(unpadded, 0, verify_len);
474   silc_free(verify);
475   silc_free(unpadded);
476   silc_mp_uninit(&mp_tmp2);
477   silc_mp_uninit(&mp_dst);
478
479   return ret;
480 }