Tizen 2.0 Release
[external/libgnutls26.git] / lib / gnutls_pk.c
1 /*
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010
3  * Free Software Foundation, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA
23  *
24  */
25
26 /* This file contains the functions needed for RSA/DSA public key
27  * encryption and signatures. 
28  */
29
30 #include <gnutls_int.h>
31 #include <gnutls_mpi.h>
32 #include <gnutls_pk.h>
33 #include <gnutls_errors.h>
34 #include <gnutls_datum.h>
35 #include <gnutls_global.h>
36 #include <gnutls_num.h>
37 #include "debug.h"
38 #include <x509/x509_int.h>
39 #include <x509/common.h>
40 #include <random.h>
41
42 /* Do PKCS-1 RSA encryption. 
43  * params is modulus, public exp.
44  */
45 int
46 _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
47                            const gnutls_datum_t * plaintext,
48                            bigint_t * params, unsigned params_len,
49                            unsigned btype)
50 {
51   unsigned int i, pad;
52   int ret;
53   opaque *edata, *ps;
54   size_t k, psize;
55   size_t mod_bits;
56   gnutls_pk_params_st pk_params;
57   gnutls_datum_t to_encrypt, encrypted;
58
59   for (i = 0; i < params_len; i++)
60     pk_params.params[i] = params[i];
61   pk_params.params_nr = params_len;
62
63   mod_bits = _gnutls_mpi_get_nbits (params[0]);
64   k = mod_bits / 8;
65   if (mod_bits % 8 != 0)
66     k++;
67
68   if (plaintext->size > k - 11)
69     {
70       gnutls_assert ();
71       return GNUTLS_E_PK_ENCRYPTION_FAILED;
72     }
73
74   edata = gnutls_malloc (k);
75   if (edata == NULL)
76     {
77       gnutls_assert ();
78       return GNUTLS_E_MEMORY_ERROR;
79     }
80
81   /* EB = 00||BT||PS||00||D 
82    * (use block type 'btype')
83    */
84
85   edata[0] = 0;
86   edata[1] = btype;
87   psize = k - 3 - plaintext->size;
88
89   ps = &edata[2];
90   switch (btype)
91     {
92     case 2:
93       /* using public key */
94       if (params_len < RSA_PUBLIC_PARAMS)
95         {
96           gnutls_assert ();
97           gnutls_free (edata);
98           return GNUTLS_E_INTERNAL_ERROR;
99         }
100
101       ret = _gnutls_rnd (GNUTLS_RND_RANDOM, ps, psize);
102       if (ret < 0)
103         {
104           gnutls_assert ();
105           gnutls_free (edata);
106           return ret;
107         }
108       for (i = 0; i < psize; i++)
109         while (ps[i] == 0)
110           {
111             ret = _gnutls_rnd (GNUTLS_RND_RANDOM, &ps[i], 1);
112             if (ret < 0)
113               {
114                 gnutls_assert ();
115                 gnutls_free (edata);
116                 return ret;
117               }
118           }
119       break;
120     case 1:
121       /* using private key */
122
123       if (params_len < RSA_PRIVATE_PARAMS)
124         {
125           gnutls_assert ();
126           gnutls_free (edata);
127           return GNUTLS_E_INTERNAL_ERROR;
128         }
129
130       for (i = 0; i < psize; i++)
131         ps[i] = 0xff;
132       break;
133     default:
134       gnutls_assert ();
135       gnutls_free (edata);
136       return GNUTLS_E_INTERNAL_ERROR;
137     }
138
139   ps[psize] = 0;
140   memcpy (&ps[psize + 1], plaintext->data, plaintext->size);
141
142   to_encrypt.data = edata;
143   to_encrypt.size = k;
144
145   if (btype == 2)               /* encrypt */
146     ret =
147       _gnutls_pk_encrypt (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params);
148   else                          /* sign */
149     ret =
150       _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params);
151
152   gnutls_free (edata);
153
154   if (ret < 0)
155     {
156       gnutls_assert ();
157       return ret;
158     }
159
160   psize = encrypted.size;
161   if (psize < k)
162     {
163       /* padding psize */
164       pad = k - psize;
165       psize = k;
166     }
167   else if (psize == k)
168     {
169       /* pad = 0; 
170        * no need to do anything else
171        */
172       ciphertext->data = encrypted.data;
173       ciphertext->size = encrypted.size;
174       return 0;
175     }
176   else
177     {                           /* psize > k !!! */
178       /* This is an impossible situation */
179       gnutls_assert ();
180       _gnutls_free_datum (&encrypted);
181       return GNUTLS_E_INTERNAL_ERROR;
182     }
183
184   ciphertext->data = gnutls_malloc (psize);
185   if (ciphertext->data == NULL)
186     {
187       gnutls_assert ();
188       _gnutls_free_datum (&encrypted);
189       return GNUTLS_E_MEMORY_ERROR;
190     }
191
192   memcpy (&ciphertext->data[pad], encrypted.data, encrypted.size);
193   for (i = 0; i < pad; i++)
194     ciphertext->data[i] = 0;
195
196   ciphertext->size = k;
197
198   _gnutls_free_datum (&encrypted);
199
200   return 0;
201 }
202
203
204 /* Do PKCS-1 RSA decryption. 
205  * params is modulus, public exp., private key
206  * Can decrypt block type 1 and type 2 packets.
207  */
208 int
209 _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
210                            const gnutls_datum_t * ciphertext,
211                            bigint_t * params, unsigned params_len,
212                            unsigned btype)
213 {
214   unsigned int k, i;
215   int ret;
216   size_t esize, mod_bits;
217   gnutls_pk_params_st pk_params;
218
219   if (params_len > GNUTLS_MAX_PK_PARAMS)
220     return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
221
222   for (i = 0; i < params_len; i++)
223     pk_params.params[i] = params[i];
224   pk_params.params_nr = params_len;
225
226   mod_bits = _gnutls_mpi_get_nbits (params[0]);
227   k = mod_bits / 8;
228   if (mod_bits % 8 != 0)
229     k++;
230
231   esize = ciphertext->size;
232
233   if (esize != k)
234     {
235       gnutls_assert ();
236       return GNUTLS_E_PK_DECRYPTION_FAILED;
237     }
238
239   /* we can use btype to see if the private key is
240    * available.
241    */
242   if (btype == 2)
243     {
244       ret =
245         _gnutls_pk_decrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params);
246     }
247   else
248     {
249       ret =
250         _gnutls_pk_encrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params);
251     }
252
253   if (ret < 0)
254     {
255       gnutls_assert ();
256       return ret;
257     }
258
259   /* EB = 00||BT||PS||00||D
260    * (use block type 'btype')
261    *
262    * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
263    * avoid attacks similar to the one described by Bleichenbacher in:
264    * "Chosen Ciphertext Attacks against Protocols Based on RSA
265    * Encryption Standard PKCS #1".
266    */
267   if (plaintext->data[0] != 0 || plaintext->data[1] != btype)
268     {
269       gnutls_assert ();
270       return GNUTLS_E_DECRYPTION_FAILED;
271     }
272
273   ret = GNUTLS_E_DECRYPTION_FAILED;
274   switch (btype)
275     {
276     case 2:
277       for (i = 2; i < plaintext->size; i++)
278         {
279           if (plaintext->data[i] == 0)
280             {
281               ret = 0;
282               break;
283             }
284         }
285       break;
286     case 1:
287       for (i = 2; i < plaintext->size; i++)
288         {
289           if (plaintext->data[i] == 0 && i > 2)
290             {
291               ret = 0;
292               break;
293             }
294           if (plaintext->data[i] != 0xff)
295             {
296               _gnutls_handshake_log ("PKCS #1 padding error");
297               _gnutls_free_datum (plaintext);
298               /* PKCS #1 padding error.  Don't use
299                  GNUTLS_E_PKCS1_WRONG_PAD here.  */
300               break;
301             }
302         }
303       break;
304     default:
305       gnutls_assert ();
306       _gnutls_free_datum (plaintext);
307       break;
308     }
309   i++;
310
311   if (ret < 0)
312     {
313       gnutls_assert ();
314       _gnutls_free_datum (plaintext);
315       return GNUTLS_E_DECRYPTION_FAILED;
316     }
317
318   memmove (plaintext->data, &plaintext->data[i], esize - i);
319   plaintext->size = esize - i;
320
321   return 0;
322 }
323
324
325 int
326 _gnutls_rsa_verify (const gnutls_datum_t * vdata,
327                     const gnutls_datum_t * ciphertext, bigint_t * params,
328                     int params_len, int btype)
329 {
330
331   gnutls_datum_t plain;
332   int ret;
333
334   /* decrypt signature */
335   if ((ret =
336        _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params, params_len,
337                                   btype)) < 0)
338     {
339       gnutls_assert ();
340       return ret;
341     }
342
343   if (plain.size != vdata->size)
344     {
345       gnutls_assert ();
346       _gnutls_free_datum (&plain);
347       return GNUTLS_E_PK_SIG_VERIFY_FAILED;
348     }
349
350   if (memcmp (plain.data, vdata->data, plain.size) != 0)
351     {
352       gnutls_assert ();
353       _gnutls_free_datum (&plain);
354       return GNUTLS_E_PK_SIG_VERIFY_FAILED;
355     }
356
357   _gnutls_free_datum (&plain);
358
359   return 0;                     /* ok */
360 }
361
362 /* encodes the Dss-Sig-Value structure
363  */
364 int
365 _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
366 {
367   ASN1_TYPE sig;
368   int result;
369
370   if ((result =
371        asn1_create_element (_gnutls_get_gnutls_asn (),
372                             "GNUTLS.DSASignatureValue",
373                             &sig)) != ASN1_SUCCESS)
374     {
375       gnutls_assert ();
376       return _gnutls_asn2err (result);
377     }
378
379   result = _gnutls_x509_write_int (sig, "r", r, 1);
380   if (result < 0)
381     {
382       gnutls_assert ();
383       asn1_delete_structure (&sig);
384       return result;
385     }
386
387   result = _gnutls_x509_write_int (sig, "s", s, 1);
388   if (result < 0)
389     {
390       gnutls_assert ();
391       asn1_delete_structure (&sig);
392       return result;
393     }
394
395   result = _gnutls_x509_der_encode (sig, "", sig_value, 0);
396
397   asn1_delete_structure (&sig);
398
399   if (result < 0)
400     {
401       gnutls_assert ();
402       return result;
403     }
404
405   return 0;
406 }
407
408
409 /* Do DSA signature calculation. params is p, q, g, y, x in that order.
410  */
411 int
412 _gnutls_dsa_sign (gnutls_datum_t * signature,
413                   const gnutls_datum_t * hash, bigint_t * params,
414                   unsigned int params_len)
415 {
416   int ret;
417   size_t i;
418   size_t k;
419   gnutls_pk_params_st pk_params;
420
421   for (i = 0; i < params_len; i++)
422     pk_params.params[i] = params[i];
423   pk_params.params_nr = params_len;
424
425   k = hash->size;
426   if (k < 20)
427     {                           /* SHA1 or better only */
428       gnutls_assert ();
429       return GNUTLS_E_PK_SIGN_FAILED;
430     }
431
432   ret = _gnutls_pk_sign (GNUTLS_PK_DSA, signature, hash, &pk_params);
433   /* rs[0], rs[1] now hold r,s */
434
435   if (ret < 0)
436     {
437       gnutls_assert ();
438       return ret;
439     }
440
441   return 0;
442 }
443
444 /* decodes the Dss-Sig-Value structure
445  */
446 int
447 _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r,
448                        bigint_t * s)
449 {
450   ASN1_TYPE sig;
451   int result;
452
453   if ((result =
454        asn1_create_element (_gnutls_get_gnutls_asn (),
455                             "GNUTLS.DSASignatureValue",
456                             &sig)) != ASN1_SUCCESS)
457     {
458       gnutls_assert ();
459       return _gnutls_asn2err (result);
460     }
461
462   result = asn1_der_decoding (&sig, sig_value->data, sig_value->size, NULL);
463   if (result != ASN1_SUCCESS)
464     {
465       gnutls_assert ();
466       asn1_delete_structure (&sig);
467       return _gnutls_asn2err (result);
468     }
469
470   result = _gnutls_x509_read_int (sig, "r", r);
471   if (result < 0)
472     {
473       gnutls_assert ();
474       asn1_delete_structure (&sig);
475       return result;
476     }
477
478   result = _gnutls_x509_read_int (sig, "s", s);
479   if (result < 0)
480     {
481       gnutls_assert ();
482       _gnutls_mpi_release (s);
483       asn1_delete_structure (&sig);
484       return result;
485     }
486
487   asn1_delete_structure (&sig);
488
489   return 0;
490 }
491
492 /* params is p, q, g, y in that order
493  */
494 int
495 _gnutls_dsa_verify (const gnutls_datum_t * vdata,
496                     const gnutls_datum_t * sig_value, bigint_t * params,
497                     int params_len)
498 {
499
500   int ret, i;
501   gnutls_pk_params_st pk_params;
502
503   for (i = 0; i < params_len; i++)
504     pk_params.params[i] = params[i];
505   pk_params.params_nr = params_len;
506
507   if (vdata->size < 20)
508     { /* SHA1 or better only */
509       gnutls_assert ();
510       return GNUTLS_E_PK_SIG_VERIFY_FAILED;
511     }
512
513   /* decrypt signature */
514   ret = _gnutls_pk_verify (GNUTLS_PK_DSA, vdata, sig_value, &pk_params);
515
516   if (ret < 0)
517     {
518       gnutls_assert ();
519       return ret;
520     }
521
522   return 0;                     /* ok */
523 }
524
525 /* some generic pk functions */
526 static int
527 _generate_params (int algo, bigint_t * resarr, unsigned int *resarr_len,
528                   int bits)
529 {
530   gnutls_pk_params_st params;
531   int ret;
532   unsigned int i;
533
534   ret = _gnutls_pk_ops.generate (algo, bits, &params);
535
536   if (ret < 0)
537     {
538       gnutls_assert ();
539       return ret;
540     }
541
542   if (resarr && resarr_len && *resarr_len >= params.params_nr)
543     {
544       *resarr_len = params.params_nr;
545       for (i = 0; i < params.params_nr; i++)
546         resarr[i] = params.params[i];
547     }
548   else
549     {
550       gnutls_pk_params_release(&params);
551       gnutls_assert ();
552       return GNUTLS_E_INVALID_REQUEST;
553     }
554   return 0;
555 }
556
557
558
559 int
560 _gnutls_rsa_generate_params (bigint_t * resarr, unsigned int *resarr_len,
561                              int bits)
562 {
563   return _generate_params (GNUTLS_PK_RSA, resarr, resarr_len, bits);
564 }
565
566 int
567 _gnutls_dsa_generate_params (bigint_t * resarr, unsigned int *resarr_len,
568                              int bits)
569 {
570   return _generate_params (GNUTLS_PK_DSA, resarr, resarr_len, bits);
571 }
572
573 int
574 _gnutls_pk_params_copy (gnutls_pk_params_st * dst, bigint_t * params,
575                         int params_len)
576 {
577   int i, j;
578   dst->params_nr = 0;
579
580   if (params_len == 0 || params == NULL)
581     {
582       gnutls_assert ();
583       return GNUTLS_E_INVALID_REQUEST;
584     }
585
586   for (i = 0; i < params_len; i++)
587     {
588       dst->params[i] = _gnutls_mpi_set (NULL, params[i]);
589       if (dst->params[i] == NULL)
590         {
591           for (j = 0; j < i; j++)
592             _gnutls_mpi_release (&dst->params[j]);
593           return GNUTLS_E_MEMORY_ERROR;
594         }
595       dst->params_nr++;
596     }
597
598   return 0;
599 }
600
601 void
602 gnutls_pk_params_init (gnutls_pk_params_st * p)
603 {
604   memset (p, 0, sizeof (gnutls_pk_params_st));
605 }
606
607 void
608 gnutls_pk_params_release (gnutls_pk_params_st * p)
609 {
610   unsigned int i;
611   for (i = 0; i < p->params_nr; i++)
612     {
613       _gnutls_mpi_release (&p->params[i]);
614     }
615 }
616
617 int
618 _gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size)
619 {
620   bigint_t tmp = _gnutls_mpi_alloc_like (params[0]);
621
622   if (params_size < RSA_PRIVATE_PARAMS - 2)
623     {
624       gnutls_assert ();
625       return GNUTLS_E_INTERNAL_ERROR;
626     }
627
628   if (tmp == NULL)
629     {
630       gnutls_assert ();
631       return GNUTLS_E_MEMORY_ERROR;
632     }
633
634   /* [6] = d % p-1, [7] = d % q-1 */
635   _gnutls_mpi_sub_ui (tmp, params[3], 1);
636   params[6] = _gnutls_mpi_mod (params[2] /*d */ , tmp);
637
638   _gnutls_mpi_sub_ui (tmp, params[4], 1);
639   params[7] = _gnutls_mpi_mod (params[2] /*d */ , tmp);
640
641   _gnutls_mpi_release (&tmp);
642
643   if (params[7] == NULL || params[6] == NULL)
644     {
645       gnutls_assert ();
646       return GNUTLS_E_MEMORY_ERROR;
647     }
648
649   return 0;
650 }
651
652 int
653 _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk, bigint_t * params,
654                                int params_size,
655                                gnutls_digest_algorithm_t * dig,
656                                unsigned int *mand)
657 {
658   if (mand)
659     {
660       if (pk == GNUTLS_PK_DSA)
661         *mand = 1;
662       else
663         *mand = 0;
664     }
665
666   return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) dig,
667                                         NULL, pk, params, params_size);
668
669 }