Corrected bugs in record parsing.
[gnutls.git] / lib / nettle / pk.c
blob30129bb14fdfda7fd5b295b296460092086befc6
1 /*
2 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file contains the functions needed for RSA/DSA public key
24 * encryption and signatures.
27 #include <gnutls_int.h>
28 #include <gnutls_mpi.h>
29 #include <gnutls_pk.h>
30 #include <gnutls_errors.h>
31 #include <gnutls_datum.h>
32 #include <gnutls_global.h>
33 #include <gnutls_sig.h>
34 #include <gnutls_num.h>
35 #include <x509/x509_int.h>
36 #include <x509/common.h>
37 #include <random.h>
38 #include <gnutls_pk.h>
39 #include <nettle/dsa.h>
40 #include <nettle/rsa.h>
41 #include <random.h>
42 #include <gnutls/crypto.h>
43 #include "ecc.h"
45 #define TOMPZ(x) (*((mpz_t*)(x)))
47 static inline int is_supported_curve(int curve);
49 static void
50 rnd_func (void *_ctx, unsigned length, uint8_t * data)
52 _gnutls_rnd (GNUTLS_RND_RANDOM, data, length);
55 static void
56 _dsa_params_to_pubkey (const gnutls_pk_params_st * pk_params,
57 struct dsa_public_key *pub)
59 memcpy (&pub->p, pk_params->params[0], sizeof (mpz_t));
60 memcpy (&pub->q, pk_params->params[1], sizeof (mpz_t));
61 memcpy (&pub->g, pk_params->params[2], sizeof (mpz_t));
62 memcpy (&pub->y, pk_params->params[3], sizeof (mpz_t));
65 static void
66 _dsa_params_to_privkey (const gnutls_pk_params_st * pk_params,
67 struct dsa_private_key *pub)
69 memcpy (&pub->x, pk_params->params[4], sizeof (mpz_t));
72 static void
73 _rsa_params_to_privkey (const gnutls_pk_params_st * pk_params,
74 struct rsa_private_key *priv)
76 memcpy (&priv->d, pk_params->params[2], sizeof (mpz_t));
77 memcpy (&priv->p, pk_params->params[3], sizeof (mpz_t));
78 memcpy (&priv->q, pk_params->params[4], sizeof (mpz_t));
79 memcpy (&priv->c, pk_params->params[5], sizeof (mpz_t));
80 memcpy (&priv->a, pk_params->params[6], sizeof (mpz_t));
81 memcpy (&priv->b, pk_params->params[7], sizeof (mpz_t));
82 priv->size = nettle_mpz_sizeinbase_256_u(TOMPZ(pk_params->params[RSA_MODULUS]));
85 static void
86 _rsa_params_to_pubkey (const gnutls_pk_params_st * pk_params,
87 struct rsa_public_key *pub)
89 memcpy (&pub->n, pk_params->params[RSA_MODULUS], sizeof (mpz_t));
90 memcpy (&pub->e, pk_params->params[RSA_PUB], sizeof (mpz_t));
91 pub->size = nettle_mpz_sizeinbase_256_u(pub->n);
94 static void
95 _ecc_params_to_privkey(const gnutls_pk_params_st * pk_params,
96 ecc_key * priv)
98 priv->type = PK_PRIVATE;
99 memcpy(&priv->prime, pk_params->params[ECC_PRIME], sizeof(mpz_t));
100 memcpy(&priv->order, pk_params->params[ECC_ORDER], sizeof(mpz_t));
101 memcpy(&priv->A, pk_params->params[ECC_A], sizeof(mpz_t));
102 memcpy(&priv->B, pk_params->params[ECC_B], sizeof(mpz_t));
103 memcpy(&priv->Gx, pk_params->params[ECC_GX], sizeof(mpz_t));
104 memcpy(&priv->Gy, pk_params->params[ECC_GY], sizeof(mpz_t));
105 memcpy(&priv->pubkey.x, pk_params->params[ECC_X], sizeof(mpz_t));
106 memcpy(&priv->pubkey.y, pk_params->params[ECC_Y], sizeof(mpz_t));
107 memcpy(&priv->k, pk_params->params[ECC_K], sizeof(mpz_t));
108 mpz_init_set_ui(priv->pubkey.z, 1);
111 static void _ecc_params_clear(ecc_key * key)
113 mpz_clear(key->pubkey.z);
116 static void
117 _ecc_params_to_pubkey(const gnutls_pk_params_st * pk_params,
118 ecc_key * pub)
120 pub->type = PK_PUBLIC;
121 memcpy(&pub->prime, pk_params->params[ECC_PRIME], sizeof(mpz_t));
122 memcpy(&pub->order, pk_params->params[ECC_ORDER], sizeof(mpz_t));
123 memcpy(&pub->A, pk_params->params[ECC_A], sizeof(mpz_t));
124 memcpy(&pub->B, pk_params->params[ECC_B], sizeof(mpz_t));
125 memcpy(&pub->Gx, pk_params->params[ECC_GX], sizeof(mpz_t));
126 memcpy(&pub->Gy, pk_params->params[ECC_GY], sizeof(mpz_t));
127 memcpy(&pub->pubkey.x, pk_params->params[ECC_X], sizeof(mpz_t));
128 memcpy(&pub->pubkey.y, pk_params->params[ECC_Y], sizeof(mpz_t));
129 mpz_init_set_ui(pub->pubkey.z, 1);
132 static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, gnutls_datum_t * out,
133 const gnutls_pk_params_st * priv,
134 const gnutls_pk_params_st * pub)
136 int ret;
138 switch (algo)
140 case GNUTLS_PK_EC:
142 ecc_key ecc_pub, ecc_priv;
143 int curve = priv->flags;
144 unsigned long sz;
146 out->data = NULL;
148 if (is_supported_curve(curve) == 0)
149 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
151 _ecc_params_to_pubkey(pub, &ecc_pub);
152 _ecc_params_to_privkey(priv, &ecc_priv);
153 sz = ECC_BUF_SIZE;
155 if (ecc_projective_check_point(&ecc_pub.pubkey, pub->params[ECC_B], pub->params[ECC_PRIME]) != 0)
157 ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
158 goto ecc_cleanup;
161 out->data = gnutls_malloc(sz);
162 if (out->data == NULL)
164 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
165 goto ecc_cleanup;
168 ret = ecc_shared_secret(&ecc_priv, &ecc_pub, out->data, &sz);
169 if (ret != 0)
170 ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
172 ecc_cleanup:
173 _ecc_params_clear(&ecc_pub);
174 _ecc_params_clear(&ecc_priv);
176 if (ret < 0)
178 gnutls_free(out->data);
179 return ret;
182 out->size = sz;
183 break;
185 default:
186 gnutls_assert ();
187 ret = GNUTLS_E_INTERNAL_ERROR;
188 goto cleanup;
191 ret = 0;
193 cleanup:
195 return ret;
198 static int
199 _wrap_nettle_pk_encrypt (gnutls_pk_algorithm_t algo,
200 gnutls_datum_t * ciphertext,
201 const gnutls_datum_t * plaintext,
202 const gnutls_pk_params_st * pk_params)
204 int ret;
205 mpz_t p;
207 mpz_init(p);
209 switch (algo)
211 case GNUTLS_PK_RSA:
213 struct rsa_public_key pub;
215 _rsa_params_to_pubkey (pk_params, &pub);
217 ret = rsa_encrypt(&pub, NULL, rnd_func, plaintext->size, plaintext->data, p);
218 if (ret == 0)
220 ret = gnutls_assert_val(GNUTLS_E_ENCRYPTION_FAILED);
221 goto cleanup;
224 ret = _gnutls_mpi_dprint_size (p, ciphertext, plaintext->size);
225 if (ret < 0)
227 gnutls_assert ();
228 goto cleanup;
231 break;
233 default:
234 gnutls_assert ();
235 ret = GNUTLS_E_INTERNAL_ERROR;
236 goto cleanup;
239 ret = 0;
241 cleanup:
243 mpz_clear(p);
244 return ret;
247 static int
248 _wrap_nettle_pk_decrypt (gnutls_pk_algorithm_t algo,
249 gnutls_datum_t * plaintext,
250 const gnutls_datum_t * ciphertext,
251 const gnutls_pk_params_st * pk_params)
253 int ret;
255 plaintext->data = NULL;
257 /* make a sexp from pkey */
258 switch (algo)
260 case GNUTLS_PK_RSA:
262 struct rsa_private_key priv;
263 struct rsa_public_key pub;
264 unsigned length;
265 bigint_t c;
267 _rsa_params_to_privkey (pk_params, &priv);
268 _rsa_params_to_pubkey (pk_params, &pub);
270 if (_gnutls_mpi_scan_nz (&c, ciphertext->data, ciphertext->size) != 0)
272 ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
273 goto cleanup;
276 length = pub.size;
277 plaintext->data = gnutls_malloc(length);
278 if (plaintext->data == NULL)
280 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
281 goto cleanup;
284 ret = rsa_decrypt_tr(&pub, &priv, NULL, rnd_func, &length, plaintext->data,
285 TOMPZ(c));
286 _gnutls_mpi_release (&c);
287 plaintext->size = length;
289 if (ret == 0)
291 ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
292 goto cleanup;
295 break;
297 default:
298 gnutls_assert ();
299 ret = GNUTLS_E_INTERNAL_ERROR;
300 goto cleanup;
303 ret = 0;
305 cleanup:
306 if (ret < 0)
307 gnutls_free(plaintext->data);
309 return ret;
312 /* in case of DSA puts into data, r,s
314 static int
315 _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo,
316 gnutls_datum_t * signature,
317 const gnutls_datum_t * vdata,
318 const gnutls_pk_params_st * pk_params)
320 int ret;
321 unsigned int hash;
322 unsigned int hash_len;
324 switch (algo)
326 case GNUTLS_PK_EC: /* we do ECDSA */
328 ecc_key priv;
329 struct dsa_signature sig;
330 int curve_id = pk_params->flags;
332 if (is_supported_curve(curve_id) == 0)
333 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
335 _ecc_params_to_privkey(pk_params, &priv);
337 dsa_signature_init (&sig);
339 hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
340 if (hash_len > vdata->size)
342 gnutls_assert ();
343 _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len);
344 hash_len = vdata->size;
347 ret = ecc_sign_hash(vdata->data, hash_len,
348 &sig, NULL, rnd_func, &priv, curve_id);
349 if (ret != 0)
351 gnutls_assert ();
352 ret = GNUTLS_E_PK_SIGN_FAILED;
353 goto ecdsa_fail;
356 ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);
358 ecdsa_fail:
359 dsa_signature_clear (&sig);
360 _ecc_params_clear( &priv);
362 if (ret < 0)
364 gnutls_assert ();
365 goto cleanup;
367 break;
369 case GNUTLS_PK_DSA:
371 struct dsa_public_key pub;
372 struct dsa_private_key priv;
373 struct dsa_signature sig;
375 memset(&priv, 0, sizeof(priv));
376 memset(&pub, 0, sizeof(pub));
377 _dsa_params_to_pubkey (pk_params, &pub);
378 _dsa_params_to_privkey (pk_params, &priv);
380 dsa_signature_init (&sig);
382 hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
383 if (hash_len > vdata->size)
385 gnutls_assert ();
386 _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len);
387 hash_len = vdata->size;
390 ret =
391 _dsa_sign (&pub, &priv, NULL, rnd_func,
392 hash_len, vdata->data, &sig);
393 if (ret == 0)
395 gnutls_assert ();
396 ret = GNUTLS_E_PK_SIGN_FAILED;
397 goto dsa_fail;
400 ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);
402 dsa_fail:
403 dsa_signature_clear (&sig);
405 if (ret < 0)
407 gnutls_assert ();
408 goto cleanup;
410 break;
412 case GNUTLS_PK_RSA:
414 struct rsa_private_key priv;
415 struct rsa_public_key pub;
416 mpz_t s;
418 _rsa_params_to_privkey (pk_params, &priv);
419 _rsa_params_to_pubkey (pk_params, &pub);
421 mpz_init(s);
423 ret = rsa_pkcs1_sign_tr(&pub, &priv, NULL, rnd_func,
424 vdata->size, vdata->data, s);
425 if (ret == 0)
427 gnutls_assert();
428 ret = GNUTLS_E_PK_SIGN_FAILED;
429 goto rsa_fail;
432 ret = _gnutls_mpi_dprint (s, signature);
434 rsa_fail:
435 mpz_clear(s);
437 if (ret < 0)
439 gnutls_assert ();
440 goto cleanup;
443 break;
445 default:
446 gnutls_assert ();
447 ret = GNUTLS_E_INTERNAL_ERROR;
448 goto cleanup;
451 ret = 0;
453 cleanup:
455 return ret;
458 static int
459 _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo,
460 const gnutls_datum_t * vdata,
461 const gnutls_datum_t * signature,
462 const gnutls_pk_params_st * pk_params)
464 int ret;
465 unsigned int hash_len;
466 bigint_t tmp[2] = { NULL, NULL };
468 switch (algo)
470 case GNUTLS_PK_EC: /* ECDSA */
472 ecc_key pub;
473 struct dsa_signature sig;
474 int stat;
475 int curve_id = pk_params->flags;
477 if (is_supported_curve(curve_id) == 0)
478 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
480 ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
481 if (ret < 0)
483 gnutls_assert ();
484 goto cleanup;
487 _ecc_params_to_pubkey(pk_params, &pub);
488 memcpy (&sig.r, tmp[0], sizeof (sig.r));
489 memcpy (&sig.s, tmp[1], sizeof (sig.s));
491 _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
492 if (hash_len > vdata->size)
493 hash_len = vdata->size;
495 ret = ecc_verify_hash(&sig, vdata->data, hash_len, &stat, &pub, curve_id);
496 if (ret != 0 || stat != 1)
498 gnutls_assert();
499 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
501 else
502 ret = 0;
504 _gnutls_mpi_release (&tmp[0]);
505 _gnutls_mpi_release (&tmp[1]);
506 _ecc_params_clear( &pub);
507 break;
509 case GNUTLS_PK_DSA:
511 struct dsa_public_key pub;
512 struct dsa_signature sig;
514 ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
515 if (ret < 0)
517 gnutls_assert ();
518 goto cleanup;
520 memset(&pub, 0, sizeof(pub));
521 _dsa_params_to_pubkey (pk_params, &pub);
522 memcpy (&sig.r, tmp[0], sizeof (sig.r));
523 memcpy (&sig.s, tmp[1], sizeof (sig.s));
525 _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
526 if (hash_len > vdata->size)
527 hash_len = vdata->size;
529 ret = _dsa_verify (&pub, hash_len, vdata->data, &sig);
530 if (ret == 0)
532 gnutls_assert();
533 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
535 else
536 ret = 0;
538 _gnutls_mpi_release (&tmp[0]);
539 _gnutls_mpi_release (&tmp[1]);
540 break;
542 case GNUTLS_PK_RSA:
544 struct rsa_public_key pub;
546 _rsa_params_to_pubkey (pk_params, &pub);
548 ret = _gnutls_mpi_scan_nz (&tmp[0], signature->data, signature->size);
549 if (ret < 0)
551 gnutls_assert ();
552 goto cleanup;
555 ret = rsa_pkcs1_verify (&pub, vdata->size, vdata->data, TOMPZ(tmp[0]));
556 if (ret == 0)
557 ret = gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
558 else ret = 0;
560 _gnutls_mpi_release (&tmp[0]);
561 break;
563 default:
564 gnutls_assert ();
565 ret = GNUTLS_E_INTERNAL_ERROR;
566 goto cleanup;
569 cleanup:
571 return ret;
574 static inline int is_supported_curve(int curve)
576 if (gnutls_ecc_curve_get_name(curve) != NULL)
577 return 1;
578 else
579 return 0;
583 static int
584 wrap_nettle_pk_generate_params (gnutls_pk_algorithm_t algo,
585 unsigned int level /*bits */ ,
586 gnutls_pk_params_st * params)
588 int ret;
589 unsigned int i, q_bits;
591 memset(params, 0, sizeof(*params));
593 switch (algo)
596 case GNUTLS_PK_DSA:
598 struct dsa_public_key pub;
599 struct dsa_private_key priv;
601 dsa_public_key_init (&pub);
602 dsa_private_key_init (&priv);
604 /* the best would be to use _gnutls_pk_bits_to_subgroup_bits()
605 * but we do NIST DSA here */
606 if (level <= 1024)
607 q_bits = 160;
608 else
609 q_bits = 256;
611 ret =
612 dsa_generate_keypair (&pub, &priv, NULL,
613 rnd_func, NULL, NULL, level, q_bits);
614 if (ret != 1)
616 gnutls_assert ();
617 ret = GNUTLS_E_INTERNAL_ERROR;
618 goto dsa_fail;
621 params->params_nr = 0;
622 for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
624 params->params[i] = _gnutls_mpi_alloc_like (&pub.p);
625 if (params->params[i] == NULL)
627 ret = GNUTLS_E_MEMORY_ERROR;
628 goto dsa_fail;
630 params->params_nr++;
633 ret = 0;
634 _gnutls_mpi_set (params->params[0], pub.p);
635 _gnutls_mpi_set (params->params[1], pub.q);
636 _gnutls_mpi_set (params->params[2], pub.g);
637 _gnutls_mpi_set (params->params[3], pub.y);
638 _gnutls_mpi_set (params->params[4], priv.x);
640 dsa_fail:
641 dsa_private_key_clear (&priv);
642 dsa_public_key_clear (&pub);
644 if (ret < 0)
645 goto fail;
647 break;
649 case GNUTLS_PK_RSA:
651 struct rsa_public_key pub;
652 struct rsa_private_key priv;
654 rsa_public_key_init (&pub);
655 rsa_private_key_init (&priv);
657 _gnutls_mpi_set_ui (&pub.e, 65537);
659 ret =
660 rsa_generate_keypair (&pub, &priv, NULL,
661 rnd_func, NULL, NULL, level, 0);
662 if (ret != 1)
664 gnutls_assert ();
665 ret = GNUTLS_E_INTERNAL_ERROR;
666 goto rsa_fail;
669 params->params_nr = 0;
670 for (i = 0; i < RSA_PRIVATE_PARAMS; i++)
672 params->params[i] = _gnutls_mpi_alloc_like (&pub.n);
673 if (params->params[i] == NULL)
675 ret = GNUTLS_E_MEMORY_ERROR;
676 goto rsa_fail;
678 params->params_nr++;
682 ret = 0;
684 _gnutls_mpi_set (params->params[0], pub.n);
685 _gnutls_mpi_set (params->params[1], pub.e);
686 _gnutls_mpi_set (params->params[2], priv.d);
687 _gnutls_mpi_set (params->params[3], priv.p);
688 _gnutls_mpi_set (params->params[4], priv.q);
689 _gnutls_mpi_set (params->params[5], priv.c);
690 _gnutls_mpi_set (params->params[6], priv.a);
691 _gnutls_mpi_set (params->params[7], priv.b);
693 rsa_fail:
694 rsa_private_key_clear (&priv);
695 rsa_public_key_clear (&pub);
697 if (ret < 0)
698 goto fail;
700 break;
702 case GNUTLS_PK_EC:
704 ecc_key key;
705 ecc_set_type tls_ecc_set;
706 const gnutls_ecc_curve_entry_st *st;
708 st = _gnutls_ecc_curve_get_params(level);
709 if (st == NULL)
710 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
712 tls_ecc_set.size = st->size;
713 tls_ecc_set.prime = st->prime;
714 tls_ecc_set.order = st->order;
715 tls_ecc_set.Gx = st->Gx;
716 tls_ecc_set.Gy = st->Gy;
717 tls_ecc_set.A = st->A;
718 tls_ecc_set.B = st->B;
720 ret = ecc_make_key(NULL, rnd_func, &key, &tls_ecc_set, st->id);
721 if (ret != 0)
722 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
724 params->params_nr = 0;
725 for (i = 0; i < ECC_PRIVATE_PARAMS; i++)
727 params->params[i] = _gnutls_mpi_alloc_like(&key.prime);
728 if (params->params[i] == NULL)
730 ret = GNUTLS_E_MEMORY_ERROR;
731 goto ecc_fail;
733 params->params_nr++;
735 params->flags = level;
737 mpz_set(TOMPZ(params->params[ECC_PRIME]), key.prime);
738 mpz_set(TOMPZ(params->params[ECC_ORDER]), key.order);
739 mpz_set(TOMPZ(params->params[ECC_A]), key.A);
740 mpz_set(TOMPZ(params->params[ECC_B]), key.B);
741 mpz_set(TOMPZ(params->params[ECC_GX]), key.Gx);
742 mpz_set(TOMPZ(params->params[ECC_GY]), key.Gy);
743 mpz_set(TOMPZ(params->params[ECC_X]), key.pubkey.x);
744 mpz_set(TOMPZ(params->params[ECC_Y]), key.pubkey.y);
745 mpz_set(TOMPZ(params->params[ECC_K]), key.k);
747 ecc_fail:
748 ecc_free(&key);
750 if (ret < 0)
751 goto fail;
753 break;
755 default:
756 gnutls_assert ();
757 return GNUTLS_E_INVALID_REQUEST;
760 return 0;
762 fail:
764 for (i = 0; i < params->params_nr; i++)
766 _gnutls_mpi_release (&params->params[i]);
768 params->params_nr = 0;
770 return ret;
773 static int
774 wrap_nettle_pk_verify_params (gnutls_pk_algorithm_t algo,
775 const gnutls_pk_params_st * params)
777 int ret;
779 switch (algo)
781 case GNUTLS_PK_RSA:
783 bigint_t t1 = NULL, t2 = NULL;
785 if (params->params_nr != RSA_PRIVATE_PARAMS)
786 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
788 t1 = _gnutls_mpi_new (256);
789 if (t1 == NULL)
790 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
792 _gnutls_mpi_mulm (t1, params->params[RSA_PRIME1], params->params[RSA_PRIME2], params->params[RSA_MODULUS]);
793 if (_gnutls_mpi_cmp_ui(t1, 0) != 0)
795 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
796 goto rsa_cleanup;
799 mpz_invert (TOMPZ(t1), TOMPZ (params->params[RSA_PRIME2]), TOMPZ (params->params[RSA_PRIME1]));
800 if (_gnutls_mpi_cmp(t1, params->params[RSA_COEF]) != 0)
802 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
803 goto rsa_cleanup;
806 /* [RSA_PRIME1] = d % p-1, [RSA_PRIME2] = d % q-1 */
807 _gnutls_mpi_sub_ui (t1, params->params[RSA_PRIME1], 1);
808 t2 = _gnutls_mpi_mod (params->params[RSA_PRIV], t1);
809 if (t2 == NULL)
811 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
812 goto rsa_cleanup;
815 if (_gnutls_mpi_cmp(params->params[RSA_E1], t2) != 0)
817 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
818 goto rsa_cleanup;
821 _gnutls_mpi_sub_ui (t1, params->params[RSA_PRIME2], 1);
822 _gnutls_mpi_release(&t2);
824 t2 = _gnutls_mpi_mod (params->params[RSA_PRIV], t1);
825 if (t2 == NULL)
827 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
828 goto rsa_cleanup;
831 if (_gnutls_mpi_cmp(params->params[RSA_E2], t2) != 0)
833 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
834 goto rsa_cleanup;
837 ret = 0;
839 rsa_cleanup:
840 _gnutls_mpi_release(&t1);
841 _gnutls_mpi_release(&t2);
844 break;
845 case GNUTLS_PK_DSA:
847 bigint_t t1 = NULL;
849 if (params->params_nr != DSA_PRIVATE_PARAMS)
850 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
852 t1 = _gnutls_mpi_new (256);
853 if (t1 == NULL)
854 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
856 _gnutls_mpi_powm (t1, params->params[DSA_G], params->params[DSA_X], params->params[DSA_P]);
858 if (_gnutls_mpi_cmp(t1, params->params[DSA_Y]) != 0)
860 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
861 goto dsa_cleanup;
864 ret = 0;
866 dsa_cleanup:
867 _gnutls_mpi_release(&t1);
870 break;
871 case GNUTLS_PK_EC:
873 int curve = params->flags;
874 ecc_key ecc_priv;
875 ecc_point *R;
876 ecc_point zero;
878 if (params->params_nr != ECC_PRIVATE_PARAMS)
879 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
881 if (is_supported_curve(curve) == 0)
882 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
884 _ecc_params_to_privkey(params, &ecc_priv);
885 R = ecc_new_point();
887 /* verify that x,y lie on the curve */
888 ret = ecc_projective_check_point(&ecc_priv.pubkey, TOMPZ(params->params[ECC_B]), params->params[ECC_PRIME]);
889 if (ret != 0)
891 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
892 goto ecc_cleanup;
895 memcpy(&zero.x, ecc_priv.Gx, sizeof(mpz_t));
896 memcpy(&zero.y, ecc_priv.Gy, sizeof(mpz_t));
897 memcpy(&zero.z, ecc_priv.pubkey.z, sizeof(mpz_t)); /* z = 1 */
899 /* verify that k*(Gx,Gy)=(x,y) */
900 ret = ecc_mulmod_cached(ecc_priv.k, curve, R, TOMPZ(params->params[ECC_A]), TOMPZ(params->params[ECC_PRIME]), 1);
901 if (ret != 0)
903 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
904 goto ecc_cleanup;
907 if (mpz_cmp(ecc_priv.pubkey.x, R->x) != 0 || mpz_cmp(ecc_priv.pubkey.y, R->y) != 0)
909 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
910 goto ecc_cleanup;
913 ret = 0;
915 ecc_cleanup:
916 _ecc_params_clear(&ecc_priv);
917 ecc_del_point(R);
919 break;
920 default:
921 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
924 return ret;
927 static int calc_rsa_exp (gnutls_pk_params_st* params)
929 bigint_t tmp = _gnutls_mpi_alloc_like (params->params[0]);
931 if (params->params_nr < RSA_PRIVATE_PARAMS - 2)
933 gnutls_assert ();
934 return GNUTLS_E_INTERNAL_ERROR;
937 if (tmp == NULL)
939 gnutls_assert ();
940 return GNUTLS_E_MEMORY_ERROR;
943 /* [6] = d % p-1, [7] = d % q-1 */
944 _gnutls_mpi_sub_ui (tmp, params->params[3], 1);
945 params->params[6] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp);
947 _gnutls_mpi_sub_ui (tmp, params->params[4], 1);
948 params->params[7] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp);
950 _gnutls_mpi_release (&tmp);
952 if (params->params[7] == NULL || params->params[6] == NULL)
954 gnutls_assert ();
955 return GNUTLS_E_MEMORY_ERROR;
958 return 0;
962 static int
963 wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo,
964 gnutls_direction_t direction,
965 gnutls_pk_params_st * params)
967 int result;
969 if (direction == GNUTLS_IMPORT && algo == GNUTLS_PK_RSA)
971 /* do not trust the generated values. Some old private keys
972 * generated by us have mess on the values. Those were very
973 * old but it seemed some of the shipped example private
974 * keys were as old.
976 mpz_invert (TOMPZ (params->params[RSA_COEF]),
977 TOMPZ (params->params[RSA_PRIME2]), TOMPZ (params->params[RSA_PRIME1]));
979 /* calculate exp1 [6] and exp2 [7] */
980 _gnutls_mpi_release (&params->params[RSA_E1]);
981 _gnutls_mpi_release (&params->params[RSA_E2]);
983 result = calc_rsa_exp (params);
984 if (result < 0)
986 gnutls_assert ();
987 return result;
989 params->params_nr = RSA_PRIVATE_PARAMS;
992 return 0;
995 static int
996 extract_digest_info(const struct rsa_public_key *key,
997 unsigned *length, uint8_t *digest_info,
998 const mpz_t signature)
1000 unsigned i;
1001 int ret;
1002 mpz_t m;
1003 uint8_t *em;
1005 if (key->size == 0 || *length < key->size)
1006 return 0;
1008 em = gnutls_malloc(key->size);
1009 if (em == NULL)
1010 return 0;
1012 mpz_init (m);
1014 mpz_powm(m, signature, key->e, key->n);
1016 nettle_mpz_get_str_256(key->size, em, m);
1017 mpz_clear(m);
1019 if (em[0] != 0 || em[1] != 1)
1021 ret = 0;
1022 goto cleanup;
1025 for (i = 2; i < key->size; i++)
1027 if (em[i] == 0 && i > 2)
1028 break;
1030 if (em[i] != 0xff)
1032 ret = 0;
1033 goto cleanup;
1037 i++;
1038 memcpy(digest_info, &em[i], key->size-i);
1039 *length = key->size-i;
1041 ret = 1;
1042 cleanup:
1043 gnutls_free(em);
1045 return ret;
1048 /* Given a signature and parameters, it should return
1049 * the hash algorithm used in the signature. This is a kludge
1050 * but until we deprecate gnutls_pubkey_get_verify_algorithm()
1051 * we depend on it.
1053 static int wrap_nettle_hash_algorithm (gnutls_pk_algorithm_t pk,
1054 const gnutls_datum_t * sig, gnutls_pk_params_st * issuer_params,
1055 gnutls_digest_algorithm_t* hash_algo)
1057 uint8_t digest[MAX_HASH_SIZE];
1058 uint8_t digest_info[MAX_HASH_SIZE*3];
1059 gnutls_datum_t di;
1060 unsigned digest_size;
1061 mpz_t s;
1062 struct rsa_public_key pub;
1063 int ret;
1065 mpz_init(s);
1067 switch (pk)
1069 case GNUTLS_PK_DSA:
1070 case GNUTLS_PK_EC:
1072 if (hash_algo)
1073 *hash_algo = _gnutls_dsa_q_to_hash (pk, issuer_params, NULL);
1075 ret = 0;
1076 break;
1077 case GNUTLS_PK_RSA:
1078 if (sig == NULL)
1079 { /* return a sensible algorithm */
1080 if (hash_algo)
1081 *hash_algo = GNUTLS_DIG_SHA256;
1082 return 0;
1085 _rsa_params_to_pubkey (issuer_params, &pub);
1087 digest_size = sizeof(digest);
1089 nettle_mpz_set_str_256_u(s, sig->size, sig->data);
1091 digest_size = sizeof (digest_info);
1092 ret = extract_digest_info( &pub, &digest_size, digest_info, s);
1093 if (ret == 0)
1095 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
1096 gnutls_assert ();
1097 goto cleanup;
1100 di.data = digest_info;
1101 di.size = digest_size;
1103 digest_size = sizeof(digest);
1104 if ((ret =
1105 decode_ber_digest_info (&di, hash_algo, digest,
1106 &digest_size)) < 0)
1108 gnutls_assert ();
1109 goto cleanup;
1112 if (digest_size != _gnutls_hash_get_algo_len (*hash_algo))
1114 gnutls_assert ();
1115 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
1116 goto cleanup;
1119 ret = 0;
1120 break;
1122 default:
1123 gnutls_assert ();
1124 ret = GNUTLS_E_INTERNAL_ERROR;
1127 cleanup:
1128 mpz_clear(s);
1129 return ret;
1134 int crypto_pk_prio = INT_MAX;
1136 gnutls_crypto_pk_st _gnutls_pk_ops = {
1137 .hash_algorithm = wrap_nettle_hash_algorithm,
1138 .encrypt = _wrap_nettle_pk_encrypt,
1139 .decrypt = _wrap_nettle_pk_decrypt,
1140 .sign = _wrap_nettle_pk_sign,
1141 .verify = _wrap_nettle_pk_verify,
1142 .verify_params = wrap_nettle_pk_verify_params,
1143 .generate = wrap_nettle_pk_generate_params,
1144 .pk_fixup_private_params = wrap_nettle_pk_fixup,
1145 .derive = _wrap_nettle_pk_derive,