documented fix
[gnutls.git] / lib / nettle / pk.c
blob505c6b4048d094424e8704b729bcb7d6e24ec8d6
1 /*
2 * Copyright (C) 2010
3 * Free Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GNUTLS.
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.
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.
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
26 /* This file contains the functions needed for RSA/DSA public key
27 * encryption and signatures.
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>
46 #define TOMPZ(x) (*((mpz_t*)(x)))
48 static void
49 rnd_func (void *_ctx, unsigned length, uint8_t * data)
51 _gnutls_rnd (GNUTLS_RND_RANDOM, data, length);
54 static void
55 _dsa_params_to_pubkey (const gnutls_pk_params_st * pk_params,
56 struct dsa_public_key *pub)
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));
64 static void
65 _dsa_params_to_privkey (const gnutls_pk_params_st * pk_params,
66 struct dsa_private_key *pub)
68 memcpy (&pub->x, pk_params->params[4], sizeof (mpz_t));
71 static void
72 _rsa_params_to_privkey (const gnutls_pk_params_st * pk_params,
73 struct rsa_private_key *priv)
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));
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)
90 int ret;
92 /* make a sexp from pkey */
93 switch (algo)
95 case GNUTLS_PK_RSA:
97 bigint_t p;
99 if (_gnutls_mpi_scan_nz (&p, plaintext->data, plaintext->size) != 0)
101 gnutls_assert ();
102 return GNUTLS_E_MPI_SCAN_FAILED;
105 mpz_powm (p, p, TOMPZ (pk_params->params[1]) /*e */ ,
106 TOMPZ (pk_params->params[0] /*m */ ));
108 ret = _gnutls_mpi_dprint_size (p, ciphertext, plaintext->size);
109 _gnutls_mpi_release (&p);
111 if (ret < 0)
113 gnutls_assert ();
114 goto cleanup;
117 break;
119 default:
120 gnutls_assert ();
121 ret = GNUTLS_E_INTERNAL_ERROR;
122 goto cleanup;
125 ret = 0;
127 cleanup:
129 return ret;
132 /* returns the blinded c and the inverse of a random
133 * number r;
135 static bigint_t
136 rsa_blind (bigint_t c, bigint_t e, bigint_t n, bigint_t * _ri)
138 bigint_t nc = NULL, r = NULL, ri = NULL;
140 /* nc = c*(r^e)
141 * ri = r^(-1)
143 nc = _gnutls_mpi_alloc_like (n);
144 if (nc == NULL)
146 gnutls_assert ();
147 return NULL;
150 ri = _gnutls_mpi_alloc_like (n);
151 if (nc == NULL)
153 gnutls_assert ();
154 goto fail;
157 r = _gnutls_mpi_randomize (NULL, _gnutls_mpi_get_nbits (n),
158 GNUTLS_RND_NONCE);
159 if (r == NULL)
161 gnutls_assert ();
162 goto fail;
165 /* invert r */
166 if (mpz_invert (ri, r, n) == 0)
168 gnutls_assert ();
169 goto fail;
172 /* r = r^e */
174 _gnutls_mpi_powm (r, r, e, n);
176 _gnutls_mpi_mulm (nc, c, r, n);
178 *_ri = ri;
180 _gnutls_mpi_release (&r);
182 return nc;
183 fail:
184 _gnutls_mpi_release (&nc);
185 _gnutls_mpi_release (&r);
186 return NULL;
189 /* c = c*ri mod n
191 static inline void
192 rsa_unblind (bigint_t c, bigint_t ri, bigint_t n)
194 _gnutls_mpi_mulm (c, c, ri, n);
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)
203 int ret;
205 /* make a sexp from pkey */
206 switch (algo)
208 case GNUTLS_PK_RSA:
210 struct rsa_private_key priv;
211 bigint_t c, ri, nc;
213 if (_gnutls_mpi_scan_nz (&c, ciphertext->data, ciphertext->size) != 0)
215 gnutls_assert ();
216 return GNUTLS_E_MPI_SCAN_FAILED;
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)
224 gnutls_assert ();
225 return GNUTLS_E_MEMORY_ERROR;
228 memset(&priv, 0, sizeof(priv));
229 _rsa_params_to_privkey (pk_params, &priv);
231 rsa_compute_root (&priv, TOMPZ (nc), TOMPZ (nc));
233 rsa_unblind (nc, ri, pk_params->params[0] /*m */ );
235 ret = _gnutls_mpi_dprint_size (nc, plaintext, ciphertext->size);
237 _gnutls_mpi_release (&nc);
238 _gnutls_mpi_release (&ri);
240 if (ret < 0)
242 gnutls_assert ();
243 goto cleanup;
246 break;
248 default:
249 gnutls_assert ();
250 ret = GNUTLS_E_INTERNAL_ERROR;
251 goto cleanup;
254 ret = 0;
256 cleanup:
258 return ret;
261 /* in case of DSA puts into data, r,s
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)
269 int ret, hash;
271 switch (algo)
274 case GNUTLS_PK_DSA:
276 struct dsa_public_key pub;
277 struct dsa_private_key priv;
278 struct dsa_signature sig;
279 unsigned int hash_len;
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);
286 dsa_signature_init (&sig);
288 hash = _gnutls_dsa_q_to_hash (pub.q, &hash_len);
289 if (hash_len > vdata->size)
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;
296 ret =
297 _dsa_sign (&pub, &priv, NULL, rnd_func,
298 hash_len, vdata->data, &sig);
299 if (ret == 0)
301 gnutls_assert ();
302 ret = GNUTLS_E_PK_SIGN_FAILED;
303 goto dsa_fail;
306 ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);
308 dsa_fail:
309 dsa_signature_clear (&sig);
311 if (ret < 0)
313 gnutls_assert ();
314 goto cleanup;
316 break;
318 case GNUTLS_PK_RSA:
320 struct rsa_private_key priv;
321 bigint_t hash, nc, ri;
323 if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0)
325 gnutls_assert ();
326 return GNUTLS_E_MPI_SCAN_FAILED;
329 memset(&priv, 0, sizeof(priv));
330 _rsa_params_to_privkey (pk_params, &priv);
332 nc = rsa_blind (hash, pk_params->params[1] /*e */ ,
333 pk_params->params[0] /*m */ , &ri);
335 _gnutls_mpi_release (&hash);
337 if (nc == NULL)
339 gnutls_assert ();
340 ret = GNUTLS_E_MEMORY_ERROR;
341 goto rsa_fail;
344 rsa_compute_root (&priv, TOMPZ (nc), TOMPZ (nc));
346 rsa_unblind (nc, ri, pk_params->params[0] /*m */ );
348 ret = _gnutls_mpi_dprint (nc, signature);
350 rsa_fail:
351 _gnutls_mpi_release (&nc);
352 _gnutls_mpi_release (&ri);
354 if (ret < 0)
356 gnutls_assert ();
357 goto cleanup;
360 break;
362 default:
363 gnutls_assert ();
364 ret = GNUTLS_E_INTERNAL_ERROR;
365 goto cleanup;
368 ret = 0;
370 cleanup:
372 return ret;
375 static int
376 _int_rsa_verify (const gnutls_pk_params_st * pk_params,
377 bigint_t m, bigint_t s)
379 int res;
381 mpz_t m1;
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;
387 mpz_init (m1);
389 mpz_powm (m1, TOMPZ (s), TOMPZ (pk_params->params[1]),
390 TOMPZ (pk_params->params[0]));
392 res = !mpz_cmp (TOMPZ (m), m1);
394 mpz_clear (m1);
396 if (res == 0)
397 res = GNUTLS_E_PK_SIG_VERIFY_FAILED;
398 else
399 res = 0;
401 return res;
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)
410 int ret, hash;
411 bigint_t tmp[2] = { NULL, NULL };
413 switch (algo)
415 case GNUTLS_PK_DSA:
417 struct dsa_public_key pub;
418 struct dsa_signature sig;
419 unsigned int hash_len;
421 ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
422 if (ret < 0)
424 gnutls_assert ();
425 goto cleanup;
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));
432 hash = _gnutls_dsa_q_to_hash (pub.q, &hash_len);
434 if (hash_len > vdata->size)
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;
441 ret = _dsa_verify (&pub, hash_len, vdata->data, &sig);
442 if (ret == 0)
444 gnutls_assert();
445 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
447 else
448 ret = 0;
450 _gnutls_mpi_release (&tmp[0]);
451 _gnutls_mpi_release (&tmp[1]);
452 break;
454 case GNUTLS_PK_RSA:
456 bigint_t hash;
458 if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0)
460 gnutls_assert ();
461 return GNUTLS_E_MPI_SCAN_FAILED;
464 ret = _gnutls_mpi_scan_nz (&tmp[0], signature->data, signature->size);
465 if (ret < 0)
467 gnutls_assert ();
468 goto cleanup;
471 ret = _int_rsa_verify (pk_params, hash, tmp[0]);
472 _gnutls_mpi_release (&tmp[0]);
473 _gnutls_mpi_release (&hash);
474 break;
476 default:
477 gnutls_assert ();
478 ret = GNUTLS_E_INTERNAL_ERROR;
479 goto cleanup;
482 cleanup:
484 return ret;
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)
492 int ret, i;
493 int q_bits;
495 memset(params, 0, sizeof(*params));
497 switch (algo)
500 case GNUTLS_PK_DSA:
502 struct dsa_public_key pub;
503 struct dsa_private_key priv;
505 dsa_public_key_init (&pub);
506 dsa_private_key_init (&priv);
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;
515 ret =
516 dsa_generate_keypair (&pub, &priv, NULL,
517 rnd_func, NULL, NULL, level, q_bits);
518 if (ret != 1)
520 gnutls_assert ();
521 ret = GNUTLS_E_INTERNAL_ERROR;
522 goto dsa_fail;
525 params->params_nr = 0;
526 for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
528 params->params[i] = _gnutls_mpi_alloc_like (&pub.p);
529 if (params->params[i] == NULL)
531 ret = GNUTLS_E_MEMORY_ERROR;
532 goto dsa_fail;
534 params->params_nr++;
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);
544 dsa_fail:
545 dsa_private_key_clear (&priv);
546 dsa_public_key_clear (&pub);
548 if (ret < 0)
549 goto fail;
551 break;
553 case GNUTLS_PK_RSA:
555 struct rsa_public_key pub;
556 struct rsa_private_key priv;
558 rsa_public_key_init (&pub);
559 rsa_private_key_init (&priv);
561 _gnutls_mpi_set_ui (&pub.e, 65537);
563 ret =
564 rsa_generate_keypair (&pub, &priv, NULL,
565 rnd_func, NULL, NULL, level, 0);
566 if (ret != 1)
568 gnutls_assert ();
569 ret = GNUTLS_E_INTERNAL_ERROR;
570 goto rsa_fail;
573 params->params_nr = 0;
574 for (i = 0; i < RSA_PRIVATE_PARAMS; i++)
576 params->params[i] = _gnutls_mpi_alloc_like (&pub.n);
577 if (params->params[i] == NULL)
579 ret = GNUTLS_E_MEMORY_ERROR;
580 goto rsa_fail;
582 params->params_nr++;
586 ret = 0;
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);
597 rsa_fail:
598 rsa_private_key_clear (&priv);
599 rsa_public_key_clear (&pub);
601 if (ret < 0)
602 goto fail;
604 break;
606 default:
607 gnutls_assert ();
608 return GNUTLS_E_INVALID_REQUEST;
611 return 0;
613 fail:
615 for (i = 0; i < params->params_nr; i++)
617 _gnutls_mpi_release (&params->params[i]);
619 params->params_nr = 0;
621 return ret;
625 static int
626 wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo,
627 gnutls_direction_t direction,
628 gnutls_pk_params_st * params)
630 int result;
632 if (direction == GNUTLS_IMPORT && algo == GNUTLS_PK_RSA)
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.
639 mpz_invert (TOMPZ (params->params[5]),
640 TOMPZ (params->params[4]), TOMPZ (params->params[3]));
642 /* calculate exp1 [6] and exp2 [7] */
643 _gnutls_mpi_release (&params->params[6]);
644 _gnutls_mpi_release (&params->params[7]);
646 result = _gnutls_calc_rsa_exp (params->params, RSA_PRIVATE_PARAMS - 2);
647 if (result < 0)
649 gnutls_assert ();
650 return result;
652 params->params_nr = RSA_PRIVATE_PARAMS;
655 return 0;
658 int crypto_pk_prio = INT_MAX;
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,