Tizen 2.0 Release
[external/libgnutls26.git] / lib / nettle / pk.c
1 /*
2  * Copyright (C) 2010
3  * Free Software Foundation, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GNUTLS.
8  *
9  * The GNUTLS library 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 <x509/x509_int.h>
38 #include <x509/common.h>
39 #include <random.h>
40 #include <gnutls_pk.h>
41 #include <nettle/dsa.h>
42 #include <nettle/rsa.h>
43 #include <random.h>
44 #include <gnutls/crypto.h>
45
46 #define TOMPZ(x) (*((mpz_t*)(x)))
47
48 static void
49 rnd_func (void *_ctx, unsigned length, uint8_t * data)
50 {
51   _gnutls_rnd (GNUTLS_RND_RANDOM, data, length);
52 }
53
54 static void
55 _dsa_params_to_pubkey (const gnutls_pk_params_st * pk_params,
56                        struct dsa_public_key *pub)
57 {
58   memcpy (&pub->p, pk_params->params[0], sizeof (mpz_t));
59   memcpy (&pub->q, pk_params->params[1], sizeof (mpz_t));
60   memcpy (&pub->g, pk_params->params[2], sizeof (mpz_t));
61   memcpy (&pub->y, pk_params->params[3], sizeof (mpz_t));
62 }
63
64 static void
65 _dsa_params_to_privkey (const gnutls_pk_params_st * pk_params,
66                         struct dsa_private_key *pub)
67 {
68   memcpy (&pub->x, pk_params->params[4], sizeof (mpz_t));
69 }
70
71 static void
72 _rsa_params_to_privkey (const gnutls_pk_params_st * pk_params,
73                         struct rsa_private_key *priv)
74 {
75   memcpy (&priv->d, pk_params->params[2], sizeof (mpz_t));
76   memcpy (&priv->p, pk_params->params[3], sizeof (mpz_t));
77   memcpy (&priv->q, pk_params->params[4], sizeof (mpz_t));
78   memcpy (&priv->c, pk_params->params[5], sizeof (mpz_t));
79   memcpy (&priv->a, pk_params->params[6], sizeof (mpz_t));
80   memcpy (&priv->b, pk_params->params[7], sizeof (mpz_t));
81
82 }
83
84 static int
85 _wrap_nettle_pk_encrypt (gnutls_pk_algorithm_t algo,
86                          gnutls_datum_t * ciphertext,
87                          const gnutls_datum_t * plaintext,
88                          const gnutls_pk_params_st * pk_params)
89 {
90   int ret;
91
92   /* make a sexp from pkey */
93   switch (algo)
94     {
95     case GNUTLS_PK_RSA:
96       {
97         bigint_t p;
98
99         if (_gnutls_mpi_scan_nz (&p, plaintext->data, plaintext->size) != 0)
100           {
101             gnutls_assert ();
102             return GNUTLS_E_MPI_SCAN_FAILED;
103           }
104
105         mpz_powm (p, p, TOMPZ (pk_params->params[1]) /*e */ ,
106                   TOMPZ (pk_params->params[0] /*m */ ));
107
108         ret = _gnutls_mpi_dprint_size (p, ciphertext, plaintext->size);
109         _gnutls_mpi_release (&p);
110
111         if (ret < 0)
112           {
113             gnutls_assert ();
114             goto cleanup;
115           }
116
117         break;
118       }
119     default:
120       gnutls_assert ();
121       ret = GNUTLS_E_INTERNAL_ERROR;
122       goto cleanup;
123     }
124
125   ret = 0;
126
127 cleanup:
128
129   return ret;
130 }
131
132 /* returns the blinded c and the inverse of a random
133  * number r;
134  */
135 static bigint_t
136 rsa_blind (bigint_t c, bigint_t e, bigint_t n, bigint_t * _ri)
137 {
138   bigint_t nc = NULL, r = NULL, ri = NULL;
139
140   /* nc = c*(r^e)
141    * ri = r^(-1)
142    */
143   nc = _gnutls_mpi_alloc_like (n);
144   if (nc == NULL)
145     {
146       gnutls_assert ();
147       return NULL;
148     }
149
150   ri = _gnutls_mpi_alloc_like (n);
151   if (nc == NULL)
152     {
153       gnutls_assert ();
154       goto fail;
155     }
156
157   r = _gnutls_mpi_randomize (NULL, _gnutls_mpi_get_nbits (n),
158                              GNUTLS_RND_NONCE);
159   if (r == NULL)
160     {
161       gnutls_assert ();
162       goto fail;
163     }
164
165   /* invert r */
166   if (mpz_invert (ri, r, n) == 0)
167     {
168       gnutls_assert ();
169       goto fail;
170     }
171
172   /* r = r^e */
173
174   _gnutls_mpi_powm (r, r, e, n);
175
176   _gnutls_mpi_mulm (nc, c, r, n);
177
178   *_ri = ri;
179
180   _gnutls_mpi_release (&r);
181
182   return nc;
183 fail:
184   _gnutls_mpi_release (&nc);
185   _gnutls_mpi_release (&r);
186   return NULL;
187 }
188
189 /* c = c*ri mod n
190  */
191 static inline void
192 rsa_unblind (bigint_t c, bigint_t ri, bigint_t n)
193 {
194   _gnutls_mpi_mulm (c, c, ri, n);
195 }
196
197 static int
198 _wrap_nettle_pk_decrypt (gnutls_pk_algorithm_t algo,
199                          gnutls_datum_t * plaintext,
200                          const gnutls_datum_t * ciphertext,
201                          const gnutls_pk_params_st * pk_params)
202 {
203   int ret;
204
205   /* make a sexp from pkey */
206   switch (algo)
207     {
208     case GNUTLS_PK_RSA:
209       {
210         struct rsa_private_key priv;
211         bigint_t c, ri, nc;
212
213         if (_gnutls_mpi_scan_nz (&c, ciphertext->data, ciphertext->size) != 0)
214           {
215             gnutls_assert ();
216             return GNUTLS_E_MPI_SCAN_FAILED;
217           }
218
219         nc = rsa_blind (c, pk_params->params[1] /*e */ ,
220                         pk_params->params[0] /*m */ , &ri);
221         _gnutls_mpi_release (&c);
222         if (nc == NULL)
223           {
224             gnutls_assert ();
225             return GNUTLS_E_MEMORY_ERROR;
226           }
227
228         memset(&priv, 0, sizeof(priv));
229         _rsa_params_to_privkey (pk_params, &priv);
230
231         rsa_compute_root (&priv, TOMPZ (nc), TOMPZ (nc));
232
233         rsa_unblind (nc, ri, pk_params->params[0] /*m */ );
234
235         ret = _gnutls_mpi_dprint_size (nc, plaintext, ciphertext->size);
236
237         _gnutls_mpi_release (&nc);
238         _gnutls_mpi_release (&ri);
239
240         if (ret < 0)
241           {
242             gnutls_assert ();
243             goto cleanup;
244           }
245
246         break;
247       }
248     default:
249       gnutls_assert ();
250       ret = GNUTLS_E_INTERNAL_ERROR;
251       goto cleanup;
252     }
253
254   ret = 0;
255
256 cleanup:
257
258   return ret;
259 }
260
261 /* in case of DSA puts into data, r,s
262  */
263 static int
264 _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo,
265                       gnutls_datum_t * signature,
266                       const gnutls_datum_t * vdata,
267                       const gnutls_pk_params_st * pk_params)
268 {
269   int ret, hash;
270
271   switch (algo)
272     {
273
274     case GNUTLS_PK_DSA:
275       {
276         struct dsa_public_key pub;
277         struct dsa_private_key priv;
278         struct dsa_signature sig;
279         unsigned int hash_len;
280
281         memset(&priv, 0, sizeof(priv));
282         memset(&pub, 0, sizeof(pub));
283         _dsa_params_to_pubkey (pk_params, &pub);
284         _dsa_params_to_privkey (pk_params, &priv);
285
286         dsa_signature_init (&sig);
287
288         hash = _gnutls_dsa_q_to_hash (pub.q, &hash_len);
289         if (hash_len > vdata->size)
290           {
291             gnutls_assert ();
292             _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len);
293             hash_len = vdata->size;
294           }
295
296         ret =
297           _dsa_sign (&pub, &priv, NULL, rnd_func,
298                      hash_len, vdata->data, &sig);
299         if (ret == 0)
300           {
301             gnutls_assert ();
302             ret = GNUTLS_E_PK_SIGN_FAILED;
303             goto dsa_fail;
304           }
305
306         ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);
307
308       dsa_fail:
309         dsa_signature_clear (&sig);
310
311         if (ret < 0)
312           {
313             gnutls_assert ();
314             goto cleanup;
315           }
316         break;
317       }
318     case GNUTLS_PK_RSA:
319       {
320         struct rsa_private_key priv;
321         bigint_t hash, nc, ri;
322
323         if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0)
324           {
325             gnutls_assert ();
326             return GNUTLS_E_MPI_SCAN_FAILED;
327           }
328
329         memset(&priv, 0, sizeof(priv));
330         _rsa_params_to_privkey (pk_params, &priv);
331
332         nc = rsa_blind (hash, pk_params->params[1] /*e */ ,
333                         pk_params->params[0] /*m */ , &ri);
334
335         _gnutls_mpi_release (&hash);
336
337         if (nc == NULL)
338           {
339             gnutls_assert ();
340             ret = GNUTLS_E_MEMORY_ERROR;
341             goto rsa_fail;
342           }
343
344         rsa_compute_root (&priv, TOMPZ (nc), TOMPZ (nc));
345
346         rsa_unblind (nc, ri, pk_params->params[0] /*m */ );
347
348         ret = _gnutls_mpi_dprint (nc, signature);
349
350 rsa_fail:
351         _gnutls_mpi_release (&nc);
352         _gnutls_mpi_release (&ri);
353
354         if (ret < 0)
355           {
356             gnutls_assert ();
357             goto cleanup;
358           }
359
360         break;
361       }
362     default:
363       gnutls_assert ();
364       ret = GNUTLS_E_INTERNAL_ERROR;
365       goto cleanup;
366     }
367
368   ret = 0;
369
370 cleanup:
371
372   return ret;
373 }
374
375 static int
376 _int_rsa_verify (const gnutls_pk_params_st * pk_params,
377                  bigint_t m, bigint_t s)
378 {
379   int res;
380
381   mpz_t m1;
382
383   if ((mpz_sgn (TOMPZ (s)) <= 0)
384       || (mpz_cmp (TOMPZ (s), TOMPZ (pk_params->params[0])) >= 0))
385     return GNUTLS_E_PK_SIG_VERIFY_FAILED;
386
387   mpz_init (m1);
388
389   mpz_powm (m1, TOMPZ (s), TOMPZ (pk_params->params[1]),
390             TOMPZ (pk_params->params[0]));
391
392   res = !mpz_cmp (TOMPZ (m), m1);
393
394   mpz_clear (m1);
395
396   if (res == 0)
397     res = GNUTLS_E_PK_SIG_VERIFY_FAILED;
398   else
399     res = 0;
400
401   return res;
402 }
403
404 static int
405 _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo,
406                         const gnutls_datum_t * vdata,
407                         const gnutls_datum_t * signature,
408                         const gnutls_pk_params_st * pk_params)
409 {
410   int ret, hash;
411   bigint_t tmp[2] = { NULL, NULL };
412
413   switch (algo)
414     {
415     case GNUTLS_PK_DSA:
416       {
417         struct dsa_public_key pub;
418         struct dsa_signature sig;
419         unsigned int hash_len;
420
421         ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
422         if (ret < 0)
423           {
424             gnutls_assert ();
425             goto cleanup;
426           }
427         memset(&pub, 0, sizeof(pub));
428         _dsa_params_to_pubkey (pk_params, &pub);
429         memcpy (&sig.r, tmp[0], sizeof (sig.r));
430         memcpy (&sig.s, tmp[1], sizeof (sig.s));
431
432         hash = _gnutls_dsa_q_to_hash (pub.q, &hash_len);
433
434         if (hash_len > vdata->size)
435           {
436             gnutls_assert ();
437             _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len);
438             hash_len = vdata->size;
439           }
440
441         ret = _dsa_verify (&pub, hash_len, vdata->data, &sig);
442         if (ret == 0)
443           {
444             gnutls_assert();
445             ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
446           }
447         else
448           ret = 0;
449
450         _gnutls_mpi_release (&tmp[0]);
451         _gnutls_mpi_release (&tmp[1]);
452         break;
453       }
454     case GNUTLS_PK_RSA:
455       {
456         bigint_t hash;
457
458         if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0)
459           {
460             gnutls_assert ();
461             return GNUTLS_E_MPI_SCAN_FAILED;
462           }
463
464         ret = _gnutls_mpi_scan_nz (&tmp[0], signature->data, signature->size);
465         if (ret < 0)
466           {
467             gnutls_assert ();
468             goto cleanup;
469           }
470
471         ret = _int_rsa_verify (pk_params, hash, tmp[0]);
472         _gnutls_mpi_release (&tmp[0]);
473         _gnutls_mpi_release (&hash);
474         break;
475       }
476     default:
477       gnutls_assert ();
478       ret = GNUTLS_E_INTERNAL_ERROR;
479       goto cleanup;
480     }
481
482 cleanup:
483
484   return ret;
485 }
486
487 static int
488 wrap_nettle_pk_generate_params (gnutls_pk_algorithm_t algo,
489                                 unsigned int level /*bits */ ,
490                                 gnutls_pk_params_st * params)
491 {
492   int ret, i;
493   int q_bits;
494
495   memset(params, 0, sizeof(*params));
496
497   switch (algo)
498     {
499
500     case GNUTLS_PK_DSA:
501       {
502         struct dsa_public_key pub;
503         struct dsa_private_key priv;
504
505         dsa_public_key_init (&pub);
506         dsa_private_key_init (&priv);
507
508         /* the best would be to use _gnutls_pk_bits_to_subgroup_bits()
509          * but we do NIST DSA here */
510         if (level <= 1024)
511           q_bits = 160;
512         else
513           q_bits = 256;
514
515         ret =
516           dsa_generate_keypair (&pub, &priv, NULL,
517                                 rnd_func, NULL, NULL, level, q_bits);
518         if (ret != 1)
519           {
520             gnutls_assert ();
521             ret = GNUTLS_E_INTERNAL_ERROR;
522             goto dsa_fail;
523           }
524
525         params->params_nr = 0;
526         for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
527           {
528             params->params[i] = _gnutls_mpi_alloc_like (&pub.p);
529             if (params->params[i] == NULL)
530               {
531                 ret = GNUTLS_E_MEMORY_ERROR;
532                 goto dsa_fail;
533               }
534             params->params_nr++;
535           }
536
537         ret = 0;
538         _gnutls_mpi_set (params->params[0], pub.p);
539         _gnutls_mpi_set (params->params[1], pub.q);
540         _gnutls_mpi_set (params->params[2], pub.g);
541         _gnutls_mpi_set (params->params[3], pub.y);
542         _gnutls_mpi_set (params->params[4], priv.x);
543
544 dsa_fail:
545         dsa_private_key_clear (&priv);
546         dsa_public_key_clear (&pub);
547
548         if (ret < 0)
549           goto fail;
550
551         break;
552       }
553     case GNUTLS_PK_RSA:
554       {
555         struct rsa_public_key pub;
556         struct rsa_private_key priv;
557
558         rsa_public_key_init (&pub);
559         rsa_private_key_init (&priv);
560
561         _gnutls_mpi_set_ui (&pub.e, 65537);
562
563         ret =
564           rsa_generate_keypair (&pub, &priv, NULL,
565                                 rnd_func, NULL, NULL, level, 0);
566         if (ret != 1)
567           {
568             gnutls_assert ();
569             ret = GNUTLS_E_INTERNAL_ERROR;
570             goto rsa_fail;
571           }
572
573         params->params_nr = 0;
574         for (i = 0; i < RSA_PRIVATE_PARAMS; i++)
575           {
576             params->params[i] = _gnutls_mpi_alloc_like (&pub.n);
577             if (params->params[i] == NULL)
578               {
579                 ret = GNUTLS_E_MEMORY_ERROR;
580                 goto rsa_fail;
581               }
582             params->params_nr++;
583
584           }
585           
586         ret = 0;
587
588         _gnutls_mpi_set (params->params[0], pub.n);
589         _gnutls_mpi_set (params->params[1], pub.e);
590         _gnutls_mpi_set (params->params[2], priv.d);
591         _gnutls_mpi_set (params->params[3], priv.p);
592         _gnutls_mpi_set (params->params[4], priv.q);
593         _gnutls_mpi_set (params->params[5], priv.c);
594         _gnutls_mpi_set (params->params[6], priv.a);
595         _gnutls_mpi_set (params->params[7], priv.b);
596
597 rsa_fail:
598         rsa_private_key_clear (&priv);
599         rsa_public_key_clear (&pub);
600
601         if (ret < 0)
602           goto fail;
603
604         break;
605       }
606     default:
607       gnutls_assert ();
608       return GNUTLS_E_INVALID_REQUEST;
609     }
610
611   return 0;
612
613 fail:
614
615   for (i = 0; i < params->params_nr; i++)
616     {
617       _gnutls_mpi_release (&params->params[i]);
618     }
619   params->params_nr = 0;
620
621   return ret;
622 }
623
624
625 static int
626 wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo,
627                       gnutls_direction_t direction,
628                       gnutls_pk_params_st * params)
629 {
630   int result;
631
632   if (direction == GNUTLS_IMPORT && algo == GNUTLS_PK_RSA)
633     {
634       /* do not trust the generated values. Some old private keys
635        * generated by us have mess on the values. Those were very
636        * old but it seemed some of the shipped example private
637        * keys were as old.
638        */
639       mpz_invert (TOMPZ (params->params[5]),
640                   TOMPZ (params->params[4]), TOMPZ (params->params[3]));
641
642       /* calculate exp1 [6] and exp2 [7] */
643       _gnutls_mpi_release (&params->params[6]);
644       _gnutls_mpi_release (&params->params[7]);
645
646       result = _gnutls_calc_rsa_exp (params->params, RSA_PRIVATE_PARAMS - 2);
647       if (result < 0)
648         {
649           gnutls_assert ();
650           return result;
651         }
652       params->params_nr = RSA_PRIVATE_PARAMS;
653     }
654
655   return 0;
656 }
657
658 int crypto_pk_prio = INT_MAX;
659
660 gnutls_crypto_pk_st _gnutls_pk_ops = {
661   .encrypt = _wrap_nettle_pk_encrypt,
662   .decrypt = _wrap_nettle_pk_decrypt,
663   .sign = _wrap_nettle_pk_sign,
664   .verify = _wrap_nettle_pk_verify,
665   .generate = wrap_nettle_pk_generate_params,
666   .pk_fixup_private_params = wrap_nettle_pk_fixup,
667 };