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,
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>
40 #include <gnutls_pk.h>
41 #include <nettle/dsa.h>
42 #include <nettle/rsa.h>
44 #include <gnutls/crypto.h>
46 #define TOMPZ(x) (*((mpz_t*)(x)))
49 rnd_func (void *_ctx, unsigned length, uint8_t * data)
51 _gnutls_rnd (GNUTLS_RND_RANDOM, data, length);
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));
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));
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));
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)
92 /* make a sexp from pkey */
99 if (_gnutls_mpi_scan_nz (&p, plaintext->data, plaintext->size) != 0)
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);
121 ret = GNUTLS_E_INTERNAL_ERROR;
132 /* returns the blinded c and the inverse of a random
136 rsa_blind (bigint_t c, bigint_t e, bigint_t n, bigint_t * _ri)
138 bigint_t nc = NULL, r = NULL, ri = NULL;
143 nc = _gnutls_mpi_alloc_like (n);
150 ri = _gnutls_mpi_alloc_like (n);
157 r = _gnutls_mpi_randomize (NULL, _gnutls_mpi_get_nbits (n),
166 if (mpz_invert (ri, r, n) == 0)
174 _gnutls_mpi_powm (r, r, e, n);
176 _gnutls_mpi_mulm (nc, c, r, n);
180 _gnutls_mpi_release (&r);
184 _gnutls_mpi_release (&nc);
185 _gnutls_mpi_release (&r);
192 rsa_unblind (bigint_t c, bigint_t ri, bigint_t n)
194 _gnutls_mpi_mulm (c, c, ri, n);
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)
205 /* make a sexp from pkey */
210 struct rsa_private_key priv;
213 if (_gnutls_mpi_scan_nz (&c, ciphertext->data, ciphertext->size) != 0)
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);
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);
250 ret = GNUTLS_E_INTERNAL_ERROR;
261 /* in case of DSA puts into data, r,s
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)
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)
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;
297 _dsa_sign (&pub, &priv, NULL, rnd_func,
298 hash_len, vdata->data, &sig);
302 ret = GNUTLS_E_PK_SIGN_FAILED;
306 ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);
309 dsa_signature_clear (&sig);
320 struct rsa_private_key priv;
321 bigint_t hash, nc, ri;
323 if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0)
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);
340 ret = GNUTLS_E_MEMORY_ERROR;
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);
351 _gnutls_mpi_release (&nc);
352 _gnutls_mpi_release (&ri);
364 ret = GNUTLS_E_INTERNAL_ERROR;
376 _int_rsa_verify (const gnutls_pk_params_st * pk_params,
377 bigint_t m, bigint_t s)
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;
389 mpz_powm (m1, TOMPZ (s), TOMPZ (pk_params->params[1]),
390 TOMPZ (pk_params->params[0]));
392 res = !mpz_cmp (TOMPZ (m), m1);
397 res = GNUTLS_E_PK_SIG_VERIFY_FAILED;
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)
411 bigint_t tmp[2] = { NULL, NULL };
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]);
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)
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);
445 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
450 _gnutls_mpi_release (&tmp[0]);
451 _gnutls_mpi_release (&tmp[1]);
458 if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0)
461 return GNUTLS_E_MPI_SCAN_FAILED;
464 ret = _gnutls_mpi_scan_nz (&tmp[0], signature->data, signature->size);
471 ret = _int_rsa_verify (pk_params, hash, tmp[0]);
472 _gnutls_mpi_release (&tmp[0]);
473 _gnutls_mpi_release (&hash);
478 ret = GNUTLS_E_INTERNAL_ERROR;
488 wrap_nettle_pk_generate_params (gnutls_pk_algorithm_t algo,
489 unsigned int level /*bits */ ,
490 gnutls_pk_params_st * params)
495 memset(params, 0, sizeof(*params));
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 */
516 dsa_generate_keypair (&pub, &priv, NULL,
517 rnd_func, NULL, NULL, level, q_bits);
521 ret = GNUTLS_E_INTERNAL_ERROR;
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;
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);
545 dsa_private_key_clear (&priv);
546 dsa_public_key_clear (&pub);
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);
564 rsa_generate_keypair (&pub, &priv, NULL,
565 rnd_func, NULL, NULL, level, 0);
569 ret = GNUTLS_E_INTERNAL_ERROR;
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;
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);
598 rsa_private_key_clear (&priv);
599 rsa_public_key_clear (&pub);
608 return GNUTLS_E_INVALID_REQUEST;
615 for (i = 0; i < params->params_nr; i++)
617 _gnutls_mpi_release (¶ms->params[i]);
619 params->params_nr = 0;
626 wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo,
627 gnutls_direction_t direction,
628 gnutls_pk_params_st * params)
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
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 (¶ms->params[6]);
644 _gnutls_mpi_release (¶ms->params[7]);
646 result = _gnutls_calc_rsa_exp (params->params, RSA_PRIVATE_PARAMS - 2);
652 params->params_nr = RSA_PRIVATE_PARAMS;
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,