Added check to prevent generating a DH pubkey of 1.
[gnutls:gnutls.git] / lib / nettle / pk.c
1 /*
2  * Copyright (C) 2010-2012 Free Software Foundation, Inc.
3  * Copyright (C) 2013 Nikos Mavrogiannopoulos
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 License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>
21  *
22  */
23
24 /* This file contains the functions needed for RSA/DSA public key
25  * encryption and signatures. 
26  */
27
28 #include <gnutls_int.h>
29 #include <gnutls_mpi.h>
30 #include <gnutls_pk.h>
31 #include <gnutls_errors.h>
32 #include <gnutls_datum.h>
33 #include <gnutls_global.h>
34 #include <gnutls_sig.h>
35 #include <gnutls_num.h>
36 #include <x509/x509_int.h>
37 #include <x509/common.h>
38 #include <random.h>
39 #include <gnutls_pk.h>
40 #include <nettle/dsa.h>
41 #include <dsa-fips.h>
42 #include <nettle/rsa.h>
43 #include <gnutls/crypto.h>
44 #include <nettle/bignum.h>
45 #include <nettle/ecc.h>
46 #include <nettle/ecdsa.h>
47 #include <nettle/ecc-curve.h>
48 #include <fips.h>
49
50 #define TOMPZ(x) (*((mpz_t*)(x)))
51
52 static inline const struct ecc_curve *get_supported_curve(int curve);
53
54 static void rnd_func(void *_ctx, unsigned length, uint8_t * data)
55 {
56         if (_gnutls_rnd(GNUTLS_RND_RANDOM, data, length) < 0) {
57 #ifdef ENABLE_FIPS140
58                 _gnutls_switch_fips_state(FIPS_STATE_ERROR);
59 #else
60                 abort();
61 #endif
62         }
63 }
64
65 static void
66 ecc_scalar_zclear (struct ecc_scalar *s)
67 {
68         memset(s->p, 0, ecc_size(s->ecc)*sizeof(mp_limb_t));
69         ecc_scalar_clear(s);
70 }
71
72 static void 
73 ecc_point_zclear (struct ecc_point *p)
74 {
75         memset(p->p, 0, ecc_size_a(p->ecc)*sizeof(mp_limb_t));
76         ecc_point_clear(p);
77 }
78   
79
80 static void
81 _dsa_params_to_pubkey(const gnutls_pk_params_st * pk_params,
82                       struct dsa_public_key *pub)
83 {
84         memcpy(&pub->p, pk_params->params[DSA_P], sizeof(mpz_t));
85
86         if (pk_params->params[DSA_Q])
87                 memcpy(&pub->q, pk_params->params[DSA_Q], sizeof(mpz_t));
88         memcpy(&pub->g, pk_params->params[DSA_G], sizeof(mpz_t));
89         
90         if (pk_params->params[DSA_Y] != NULL)
91                 memcpy(&pub->y, pk_params->params[DSA_Y], sizeof(mpz_t));
92 }
93
94 static void
95 _dsa_params_to_privkey(const gnutls_pk_params_st * pk_params,
96                        struct dsa_private_key *pub)
97 {
98         memcpy(&pub->x, pk_params->params[4], sizeof(mpz_t));
99 }
100
101 static void
102 _rsa_params_to_privkey(const gnutls_pk_params_st * pk_params,
103                        struct rsa_private_key *priv)
104 {
105         memcpy(&priv->d, pk_params->params[2], sizeof(mpz_t));
106         memcpy(&priv->p, pk_params->params[3], sizeof(mpz_t));
107         memcpy(&priv->q, pk_params->params[4], sizeof(mpz_t));
108         memcpy(&priv->c, pk_params->params[5], sizeof(mpz_t));
109         memcpy(&priv->a, pk_params->params[6], sizeof(mpz_t));
110         memcpy(&priv->b, pk_params->params[7], sizeof(mpz_t));
111         priv->size =
112             nettle_mpz_sizeinbase_256_u(TOMPZ
113                                         (pk_params->params[RSA_MODULUS]));
114 }
115
116 static void
117 _rsa_params_to_pubkey(const gnutls_pk_params_st * pk_params,
118                       struct rsa_public_key *pub)
119 {
120         memcpy(&pub->n, pk_params->params[RSA_MODULUS], sizeof(mpz_t));
121         memcpy(&pub->e, pk_params->params[RSA_PUB], sizeof(mpz_t));
122         pub->size = nettle_mpz_sizeinbase_256_u(pub->n);
123 }
124
125 static int
126 _ecc_params_to_privkey(const gnutls_pk_params_st * pk_params,
127                        struct ecc_scalar *priv,
128                        const struct ecc_curve *curve)
129 {
130         ecc_scalar_init(priv, curve);
131         if (ecc_scalar_set(priv, pk_params->params[ECC_K]) == 0)
132                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
133
134         return 0;
135 }
136
137 static int
138 _ecc_params_to_pubkey(const gnutls_pk_params_st * pk_params,
139                       struct ecc_point *pub, const struct ecc_curve *curve)
140 {
141         ecc_point_init(pub, curve);
142         if (ecc_point_set
143             (pub, pk_params->params[ECC_X], pk_params->params[ECC_Y]) == 0)
144                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
145
146         return 0;
147 }
148
149 static void
150 ecc_shared_secret(struct ecc_scalar *private_key,
151                   struct ecc_point *public_key, void *out, unsigned size)
152 {
153         struct ecc_point r;
154         mpz_t x;
155
156         mpz_init(x);
157         ecc_point_init(&r, public_key->ecc);
158
159         ecc_point_mul(&r, private_key, public_key);
160
161         ecc_point_get(&r, x, NULL);
162         nettle_mpz_get_str_256(size, out, x);
163
164         mpz_clear(x);
165         ecc_point_clear(&r);
166
167         return;
168 }
169
170 #define MAX_DH_BITS 16*1024
171
172 /* This is used for DH or ECDH key derivation. In DH for example
173  * it is given the peers Y and our x, and calculates Y^x 
174  */
175 static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo,
176                                   gnutls_datum_t * out,
177                                   const gnutls_pk_params_st * priv,
178                                   const gnutls_pk_params_st * pub)
179 {
180         int ret;
181
182         switch (algo) {
183         case GNUTLS_PK_DH: {
184                 bigint_t f, x, prime;
185                 bigint_t k = NULL, ff;
186                 unsigned int bits;
187                 
188                 f = pub->params[DH_Y];
189                 x = priv->params[DH_X];
190                 prime = priv->params[DH_P];
191
192                 ff = _gnutls_mpi_modm(NULL, f, prime);
193                 _gnutls_mpi_add_ui(ff, ff, 1);
194
195                 /* check if f==0,1,p-1. 
196                  * or (ff=f+1) equivalently ff==1,2,p */
197                 if ((_gnutls_mpi_cmp_ui(ff, 2) == 0)
198                     || (_gnutls_mpi_cmp_ui(ff, 1) == 0)
199                     || (_gnutls_mpi_cmp(ff, prime) == 0)) {
200                         gnutls_assert();
201                         ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
202                         goto dh_cleanup;
203                 }
204
205                 /* prevent denial of service */
206                 bits = _gnutls_mpi_get_nbits(prime);
207                 if (bits == 0 || bits > MAX_DH_BITS) {
208                         gnutls_assert();
209                         ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
210                         goto dh_cleanup;
211                 }
212
213                 k = _gnutls_mpi_alloc_like(prime);
214                 if (k == NULL) {
215                         gnutls_assert();
216                         ret = GNUTLS_E_MEMORY_ERROR;
217                         goto dh_cleanup;
218                 }
219
220                 _gnutls_mpi_powm(k, f, x, prime);
221                 
222                 ret = _gnutls_mpi_dprint(k, out);
223                 if (ret < 0) {
224                         gnutls_assert();
225                         goto dh_cleanup;
226                 }
227
228                 ret = 0;
229 dh_cleanup:
230                 _gnutls_mpi_release(&ff);
231                 zrelease_temp_mpi_key(&k);
232                 if (ret < 0)
233                         goto cleanup;
234                 
235                 break;
236         }
237         case GNUTLS_PK_EC:
238                 {
239                         struct ecc_scalar ecc_priv;
240                         struct ecc_point ecc_pub;
241                         const struct ecc_curve *curve;
242
243                         out->data = NULL;
244
245                         curve = get_supported_curve(priv->flags);
246                         if (curve == NULL)
247                                 return
248                                     gnutls_assert_val
249                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
250
251                         ret = _ecc_params_to_pubkey(pub, &ecc_pub, curve);
252                         if (ret < 0)
253                                 return gnutls_assert_val(ret);
254
255                         ret =
256                             _ecc_params_to_privkey(priv, &ecc_priv, curve);
257                         if (ret < 0) {
258                                 ecc_point_clear(&ecc_pub);
259                                 return gnutls_assert_val(ret);
260                         }
261
262                         out->size = gnutls_ecc_curve_get_size(priv->flags);
263                         /*ecc_size(curve)*sizeof(mp_limb_t); */
264                         out->data = gnutls_malloc(out->size);
265                         if (out->data == NULL) {
266                                 ret =
267                                     gnutls_assert_val
268                                     (GNUTLS_E_MEMORY_ERROR);
269                                 goto ecc_cleanup;
270                         }
271
272                         ecc_shared_secret(&ecc_priv, &ecc_pub, out->data,
273                                           out->size);
274
275                       ecc_cleanup:
276                         ecc_point_clear(&ecc_pub);
277                         ecc_scalar_zclear(&ecc_priv);
278                         if (ret < 0)
279                                 goto cleanup;
280                         break;
281                 }
282         default:
283                 gnutls_assert();
284                 ret = GNUTLS_E_INTERNAL_ERROR;
285                 goto cleanup;
286         }
287
288         ret = 0;
289
290       cleanup:
291
292         return ret;
293 }
294
295 static int
296 _wrap_nettle_pk_encrypt(gnutls_pk_algorithm_t algo,
297                         gnutls_datum_t * ciphertext,
298                         const gnutls_datum_t * plaintext,
299                         const gnutls_pk_params_st * pk_params)
300 {
301         int ret;
302         mpz_t p;
303
304         mpz_init(p);
305
306         switch (algo) {
307         case GNUTLS_PK_RSA:
308                 {
309                         struct rsa_public_key pub;
310
311                         _rsa_params_to_pubkey(pk_params, &pub);
312
313                         ret =
314                             rsa_encrypt(&pub, NULL, rnd_func,
315                                         plaintext->size, plaintext->data,
316                                         p);
317                         if (ret == 0) {
318                                 ret =
319                                     gnutls_assert_val
320                                     (GNUTLS_E_ENCRYPTION_FAILED);
321                                 goto cleanup;
322                         }
323
324                         ret =
325                             _gnutls_mpi_dprint_size(p, ciphertext,
326                                                     pub.size);
327                         if (ret < 0) {
328                                 gnutls_assert();
329                                 goto cleanup;
330                         }
331
332                         break;
333                 }
334         default:
335                 gnutls_assert();
336                 ret = GNUTLS_E_INTERNAL_ERROR;
337                 goto cleanup;
338         }
339
340         ret = 0;
341
342       cleanup:
343         mpz_clear(p);
344
345         FAIL_IF_FIPS_ERROR;
346         return ret;
347 }
348
349 static int
350 _wrap_nettle_pk_decrypt(gnutls_pk_algorithm_t algo,
351                         gnutls_datum_t * plaintext,
352                         const gnutls_datum_t * ciphertext,
353                         const gnutls_pk_params_st * pk_params)
354 {
355         int ret;
356
357         plaintext->data = NULL;
358
359         /* make a sexp from pkey */
360         switch (algo) {
361         case GNUTLS_PK_RSA:
362                 {
363                         struct rsa_private_key priv;
364                         struct rsa_public_key pub;
365                         unsigned length;
366                         bigint_t c;
367
368                         _rsa_params_to_privkey(pk_params, &priv);
369                         _rsa_params_to_pubkey(pk_params, &pub);
370
371                         if (ciphertext->size != pub.size)
372                                 return
373                                     gnutls_assert_val
374                                     (GNUTLS_E_DECRYPTION_FAILED);
375
376                         if (_gnutls_mpi_scan_nz
377                             (&c, ciphertext->data,
378                              ciphertext->size) != 0) {
379                                 ret =
380                                     gnutls_assert_val
381                                     (GNUTLS_E_MPI_SCAN_FAILED);
382                                 goto cleanup;
383                         }
384
385                         length = pub.size;
386                         plaintext->data = gnutls_malloc(length);
387                         if (plaintext->data == NULL) {
388                                 ret =
389                                     gnutls_assert_val
390                                     (GNUTLS_E_MEMORY_ERROR);
391                                 goto cleanup;
392                         }
393
394                         ret =
395                             rsa_decrypt_tr(&pub, &priv, NULL, rnd_func,
396                                            &length, plaintext->data,
397                                            TOMPZ(c));
398                         _gnutls_mpi_release(&c);
399                         plaintext->size = length;
400
401                         if (ret == 0) {
402                                 ret =
403                                     gnutls_assert_val
404                                     (GNUTLS_E_DECRYPTION_FAILED);
405                                 goto cleanup;
406                         }
407
408                         break;
409                 }
410         default:
411                 gnutls_assert();
412                 ret = GNUTLS_E_INTERNAL_ERROR;
413                 goto cleanup;
414         }
415
416         ret = 0;
417
418       cleanup:
419         if (ret < 0)
420                 gnutls_free(plaintext->data);
421
422         FAIL_IF_FIPS_ERROR;
423         return ret;
424 }
425
426 /* in case of DSA puts into data, r,s
427  */
428 static int
429 _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
430                      gnutls_datum_t * signature,
431                      const gnutls_datum_t * vdata,
432                      const gnutls_pk_params_st * pk_params)
433 {
434         int ret;
435         unsigned int hash_len;
436         const mac_entry_st *me;
437
438         switch (algo) {
439         case GNUTLS_PK_EC:      /* we do ECDSA */
440                 {
441                         struct ecc_scalar priv;
442                         struct dsa_signature sig;
443                         int curve_id = pk_params->flags;
444                         const struct ecc_curve *curve;
445
446                         curve = get_supported_curve(curve_id);
447                         if (curve == NULL)
448                                 return
449                                     gnutls_assert_val
450                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
451
452                         ret =
453                             _ecc_params_to_privkey(pk_params, &priv,
454                                                    curve);
455                         if (ret < 0)
456                                 return gnutls_assert_val(ret);
457
458                         dsa_signature_init(&sig);
459
460                         me = _gnutls_dsa_q_to_hash(algo, pk_params,
461                                                    &hash_len);
462
463                         if (hash_len > vdata->size) {
464                                 gnutls_assert();
465                                 _gnutls_debug_log
466                                     ("Security level of algorithm requires hash %s(%d) or better\n",
467                                      _gnutls_mac_get_name(me), hash_len);
468                                 hash_len = vdata->size;
469                         }
470
471                         ecdsa_sign(&priv, NULL, rnd_func, hash_len,
472                                    vdata->data, &sig);
473
474                         ret =
475                             _gnutls_encode_ber_rs(signature, &sig.r,
476                                                   &sig.s);
477
478                         dsa_signature_clear(&sig);
479                         ecc_scalar_zclear(&priv);
480
481                         if (ret < 0) {
482                                 gnutls_assert();
483                                 goto cleanup;
484                         }
485                         break;
486                 }
487         case GNUTLS_PK_DSA:
488                 {
489                         struct dsa_public_key pub;
490                         struct dsa_private_key priv;
491                         struct dsa_signature sig;
492
493                         memset(&priv, 0, sizeof(priv));
494                         memset(&pub, 0, sizeof(pub));
495                         _dsa_params_to_pubkey(pk_params, &pub);
496                         _dsa_params_to_privkey(pk_params, &priv);
497
498                         dsa_signature_init(&sig);
499
500                         me = _gnutls_dsa_q_to_hash(algo, pk_params,
501                                                    &hash_len);
502
503                         if (hash_len > vdata->size) {
504                                 gnutls_assert();
505                                 _gnutls_debug_log
506                                     ("Security level of algorithm requires hash %s(%d) or better (have: %d)\n",
507                                      _gnutls_mac_get_name(me), hash_len, (int)vdata->size);
508                                 hash_len = vdata->size;
509                         }
510
511                         ret =
512                             _dsa_sign(&pub, &priv, NULL, rnd_func,
513                                       hash_len, vdata->data, &sig);
514                         if (ret == 0) {
515                                 gnutls_assert();
516                                 ret = GNUTLS_E_PK_SIGN_FAILED;
517                                 goto dsa_fail;
518                         }
519
520                         ret =
521                             _gnutls_encode_ber_rs(signature, &sig.r,
522                                                   &sig.s);
523
524                       dsa_fail:
525                         dsa_signature_clear(&sig);
526
527                         if (ret < 0) {
528                                 gnutls_assert();
529                                 goto cleanup;
530                         }
531                         break;
532                 }
533         case GNUTLS_PK_RSA:
534                 {
535                         struct rsa_private_key priv;
536                         struct rsa_public_key pub;
537                         mpz_t s;
538
539                         _rsa_params_to_privkey(pk_params, &priv);
540                         _rsa_params_to_pubkey(pk_params, &pub);
541
542                         mpz_init(s);
543
544                         ret =
545                             rsa_pkcs1_sign_tr(&pub, &priv, NULL, rnd_func,
546                                               vdata->size, vdata->data, s);
547                         if (ret == 0) {
548                                 gnutls_assert();
549                                 ret = GNUTLS_E_PK_SIGN_FAILED;
550                                 goto rsa_fail;
551                         }
552
553                         ret =
554                             _gnutls_mpi_dprint_size(s, signature,
555                                                     pub.size);
556
557                       rsa_fail:
558                         mpz_clear(s);
559
560                         if (ret < 0) {
561                                 gnutls_assert();
562                                 goto cleanup;
563                         }
564
565                         break;
566                 }
567         default:
568                 gnutls_assert();
569                 ret = GNUTLS_E_INTERNAL_ERROR;
570                 goto cleanup;
571         }
572
573         ret = 0;
574
575       cleanup:
576
577         FAIL_IF_FIPS_ERROR;
578         return ret;
579 }
580
581 static int
582 _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
583                        const gnutls_datum_t * vdata,
584                        const gnutls_datum_t * signature,
585                        const gnutls_pk_params_st * pk_params)
586 {
587         int ret;
588         unsigned int hash_len;
589         bigint_t tmp[2] = { NULL, NULL };
590
591         switch (algo) {
592         case GNUTLS_PK_EC:      /* ECDSA */
593                 {
594                         struct ecc_point pub;
595                         struct dsa_signature sig;
596                         int curve_id = pk_params->flags;
597                         const struct ecc_curve *curve;
598
599                         curve = get_supported_curve(curve_id);
600                         if (curve == NULL)
601                                 return
602                                     gnutls_assert_val
603                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
604
605                         ret =
606                             _gnutls_decode_ber_rs(signature, &tmp[0],
607                                                   &tmp[1]);
608                         if (ret < 0)
609                                 return gnutls_assert_val(ret);
610
611                         ret =
612                             _ecc_params_to_pubkey(pk_params, &pub, curve);
613                         if (ret < 0) {
614                                 gnutls_assert();
615                                 goto cleanup;
616                         }
617
618                         memcpy(&sig.r, tmp[0], sizeof(sig.r));
619                         memcpy(&sig.s, tmp[1], sizeof(sig.s));
620
621                         _gnutls_dsa_q_to_hash(algo, pk_params, &hash_len);
622
623                         if (hash_len > vdata->size)
624                                 hash_len = vdata->size;
625
626                         ret =
627                             ecdsa_verify(&pub, hash_len, vdata->data,
628                                          &sig);
629                         if (ret == 0) {
630                                 gnutls_assert();
631                                 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
632                         } else
633                                 ret = 0;
634
635                         ecc_point_clear(&pub);
636                         break;
637                 }
638         case GNUTLS_PK_DSA:
639                 {
640                         struct dsa_public_key pub;
641                         struct dsa_signature sig;
642
643                         ret =
644                             _gnutls_decode_ber_rs(signature, &tmp[0],
645                                                   &tmp[1]);
646                         if (ret < 0) {
647                                 gnutls_assert();
648                                 goto cleanup;
649                         }
650                         memset(&pub, 0, sizeof(pub));
651                         _dsa_params_to_pubkey(pk_params, &pub);
652                         memcpy(&sig.r, tmp[0], sizeof(sig.r));
653                         memcpy(&sig.s, tmp[1], sizeof(sig.s));
654
655                         _gnutls_dsa_q_to_hash(algo, pk_params, &hash_len);
656
657                         if (hash_len > vdata->size)
658                                 hash_len = vdata->size;
659
660                         ret =
661                             _dsa_verify(&pub, hash_len, vdata->data, &sig);
662                         if (ret == 0) {
663                                 gnutls_assert();
664                                 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
665                         } else
666                                 ret = 0;
667
668                         break;
669                 }
670         case GNUTLS_PK_RSA:
671                 {
672                         struct rsa_public_key pub;
673
674                         _rsa_params_to_pubkey(pk_params, &pub);
675
676                         if (signature->size != pub.size)
677                                 return
678                                     gnutls_assert_val
679                                     (GNUTLS_E_PK_SIG_VERIFY_FAILED);
680
681                         ret =
682                             _gnutls_mpi_scan_nz(&tmp[0], signature->data,
683                                                 signature->size);
684                         if (ret < 0) {
685                                 gnutls_assert();
686                                 goto cleanup;
687                         }
688
689                         ret =
690                             rsa_pkcs1_verify(&pub, vdata->size,
691                                              vdata->data, TOMPZ(tmp[0]));
692                         if (ret == 0)
693                                 ret =
694                                     gnutls_assert_val
695                                     (GNUTLS_E_PK_SIG_VERIFY_FAILED);
696                         else
697                                 ret = 0;
698
699                         break;
700                 }
701         default:
702                 gnutls_assert();
703                 ret = GNUTLS_E_INTERNAL_ERROR;
704                 goto cleanup;
705         }
706
707       cleanup:
708
709         _gnutls_mpi_release(&tmp[0]);
710         _gnutls_mpi_release(&tmp[1]);
711         return ret;
712 }
713
714 static inline const struct ecc_curve *get_supported_curve(int curve)
715 {
716         switch (curve) {
717 #ifdef ENABLE_NON_SUITEB_CURVES
718         case GNUTLS_ECC_CURVE_SECP192R1:
719                 return &nettle_secp_192r1;
720         case GNUTLS_ECC_CURVE_SECP224R1:
721                 return &nettle_secp_224r1;
722 #endif
723         case GNUTLS_ECC_CURVE_SECP256R1:
724                 return &nettle_secp_256r1;
725         case GNUTLS_ECC_CURVE_SECP384R1:
726                 return &nettle_secp_384r1;
727         case GNUTLS_ECC_CURVE_SECP521R1:
728                 return &nettle_secp_521r1;
729         default:
730                 return NULL;
731         }
732 }
733
734 static int _wrap_nettle_pk_curve_exists(gnutls_ecc_curve_t curve)
735 {
736         return ((get_supported_curve(curve)!=NULL)?1:0);
737 }
738
739 /* Generates algorithm's parameters. That is:
740  *  For DSA: p, q, and g are generated.
741  *  For RSA: nothing
742  *  For ECDSA: just checks the curve is ok
743  */
744 static int
745 wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
746                                unsigned int level /*bits or curve*/ ,
747                                gnutls_pk_params_st * params)
748 {
749         int ret;
750         unsigned int i, q_bits;
751
752         params->algo = algo;
753
754         switch (algo) {
755         case GNUTLS_PK_DSA:
756         case GNUTLS_PK_DH:
757                 {
758                         struct dsa_public_key pub;
759                         struct dsa_private_key priv;
760                         struct dss_params_validation_seeds cert;
761                         unsigned index;
762
763                         dsa_public_key_init(&pub);
764                         dsa_private_key_init(&priv);
765                         
766                         q_bits = _gnutls_pk_bits_to_subgroup_bits(level);
767                         if (q_bits == 0)
768                                 return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
769
770 #ifdef ENABLE_FIPS140
771                         if (algo==GNUTLS_PK_DSA)
772                                 index = 1;
773                         else
774                                 index = 2;
775
776                         ret =
777                             dsa_generate_dss_keypair(&pub, &priv, &cert,
778                                                  index,
779                                                  NULL, rnd_func, 
780                                                  NULL, NULL,
781                                                  level, q_bits);
782                         if (ret != 1) {
783                                 gnutls_assert();
784                                 ret = GNUTLS_E_PK_GENERATION_ERROR;
785                                 goto dsa_fail;
786                         }
787                         
788                         /* verify the generated parameters */
789                         ret = dsa_validate_dss_keypair(&pub, &cert, index);
790                         if (ret != 1) {
791                                 gnutls_assert();
792                                 ret = GNUTLS_E_PK_GENERATION_ERROR;
793                                 goto dsa_fail;
794                         }
795 #else
796                         ret =
797                             dsa_generate_keypair(&pub, &priv,
798                                                  NULL, rnd_func, 
799                                                  NULL, NULL,
800                                                  level, q_bits);
801                         if (ret != 1) {
802                                 gnutls_assert();
803                                 ret = GNUTLS_E_PK_GENERATION_ERROR;
804                                 goto dsa_fail;
805                         }
806 #endif
807
808                         params->params_nr = 0;
809                         for (i = 0; i < DSA_PRIVATE_PARAMS-2; i++) {
810                                 params->params[i] =
811                                     _gnutls_mpi_alloc_like(&pub.p);
812                                 if (params->params[i] == NULL) {
813                                         ret = GNUTLS_E_MEMORY_ERROR;
814                                         goto dsa_fail;
815                                 }
816                                 params->params_nr++;
817                         }
818
819                         ret = 0;
820                         _gnutls_mpi_set(params->params[0], pub.p);
821                         _gnutls_mpi_set(params->params[1], pub.q);
822                         _gnutls_mpi_set(params->params[2], pub.g);
823
824                       dsa_fail:
825                         dsa_private_key_clear(&priv);
826                         dsa_public_key_clear(&pub);
827
828                         if (ret < 0)
829                                 goto fail;
830
831                         break;
832                 }
833         case GNUTLS_PK_RSA:
834         case GNUTLS_PK_EC:
835                 ret = 0;
836                 break;
837         default:
838                 gnutls_assert();
839                 return GNUTLS_E_INVALID_REQUEST;
840         }
841
842         FAIL_IF_FIPS_ERROR;
843         return 0;
844
845       fail:
846
847         for (i = 0; i < params->params_nr; i++) {
848                 _gnutls_mpi_release(&params->params[i]);
849         }
850         params->params_nr = 0;
851
852         FAIL_IF_FIPS_ERROR;
853         return ret;
854 }
855
856 /* To generate a DH key either q must be set in the params or
857  * level should be set to the number of required bits.
858  */
859 static int
860 wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo,
861                                unsigned int level /*bits */ ,
862                                gnutls_pk_params_st * params)
863 {
864         int ret;
865         unsigned int i;
866
867         switch (algo) {
868         case GNUTLS_PK_DSA:
869         case GNUTLS_PK_DH:
870                 {
871                         struct dsa_public_key pub;
872                         mpz_t r;
873                         mpz_t x, y;
874                         int max_tries;
875                         unsigned have_q = 0;
876                         
877                         if (algo != params->algo)
878                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
879
880                         _dsa_params_to_pubkey(params, &pub);
881                         
882                         if (params->params[DSA_Q] != NULL)
883                                 have_q = 1;
884                                 
885                         if (algo == GNUTLS_PK_DSA && have_q == 0)
886                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
887
888                         mpz_init(r);
889                         mpz_init(x);
890                         mpz_init(y);
891                         
892                         max_tries = 3;
893                         do {
894                                 if (have_q) {
895                                         mpz_set(r, pub.q);
896                                         mpz_sub_ui(r, r, 2);
897                                         nettle_mpz_random(x, NULL, rnd_func, r);
898                                         mpz_add_ui(x, x, 1);
899                                 } else {
900                                         if (level == 0)
901                                                 level = mpz_sizeinbase(pub.p, 2);
902                                         nettle_mpz_random_size(x, NULL, rnd_func, level);
903
904                                         if (level >= mpz_sizeinbase(pub.p, 2))
905                                                 mpz_mod(x, x, pub.p);
906                                 }
907
908                                 mpz_powm(y, pub.g, x, pub.p);
909
910                                 max_tries--;
911                                 if (max_tries <= 0) {
912                                         gnutls_assert();
913                                         ret = GNUTLS_E_RANDOM_FAILED;
914                                         goto dsa_fail;
915                                 }
916                         } while(mpz_cmp_ui(y, 1) == 0);
917                         
918                         params->params[DSA_Y] = _gnutls_mpi_alloc_like(&pub.p);
919                         if (params->params[DSA_Y] == NULL) {
920                                 ret = GNUTLS_E_MEMORY_ERROR;
921                                 goto dsa_fail;
922                         }
923
924                         params->params[DSA_X] = _gnutls_mpi_alloc_like(&pub.p);
925                         if (params->params[DSA_X] == NULL) {
926                                 _gnutls_mpi_release(&params->params[DSA_Y]);
927                                 ret = GNUTLS_E_MEMORY_ERROR;
928                                 goto dsa_fail;
929                         }
930
931                         _gnutls_mpi_set(params->params[DSA_Y], y);
932                         _gnutls_mpi_set(params->params[DSA_X], x);
933                         params->params_nr += 2;
934
935                         ret = 0;
936
937                       dsa_fail:
938                         mpz_clear(r);
939                         mpz_clear(x);
940                         mpz_clear(y);
941
942                         if (ret < 0)
943                                 goto fail;
944
945                         break;
946                 }
947         case GNUTLS_PK_RSA:
948                 {
949                         struct rsa_public_key pub;
950                         struct rsa_private_key priv;
951
952                         rsa_public_key_init(&pub);
953                         rsa_private_key_init(&priv);
954
955                         _gnutls_mpi_set_ui(&pub.e, 65537);
956
957                         ret =
958                             rsa_generate_keypair(&pub, &priv, NULL,
959                                                  rnd_func, NULL, NULL,
960                                                  level, 0);
961                         if (ret != 1) {
962                                 gnutls_assert();
963                                 ret = GNUTLS_E_INTERNAL_ERROR;
964                                 goto rsa_fail;
965                         }
966
967                         params->params_nr = 0;
968                         for (i = 0; i < RSA_PRIVATE_PARAMS; i++) {
969                                 params->params[i] =
970                                     _gnutls_mpi_alloc_like(&pub.n);
971                                 if (params->params[i] == NULL) {
972                                         ret = GNUTLS_E_MEMORY_ERROR;
973                                         goto rsa_fail;
974                                 }
975                                 params->params_nr++;
976
977                         }
978
979                         ret = 0;
980
981                         _gnutls_mpi_set(params->params[0], pub.n);
982                         _gnutls_mpi_set(params->params[1], pub.e);
983                         _gnutls_mpi_set(params->params[2], priv.d);
984                         _gnutls_mpi_set(params->params[3], priv.p);
985                         _gnutls_mpi_set(params->params[4], priv.q);
986                         _gnutls_mpi_set(params->params[5], priv.c);
987                         _gnutls_mpi_set(params->params[6], priv.a);
988                         _gnutls_mpi_set(params->params[7], priv.b);
989
990                       rsa_fail:
991                         rsa_private_key_clear(&priv);
992                         rsa_public_key_clear(&pub);
993
994                         if (ret < 0)
995                                 goto fail;
996
997                         break;
998                 }
999         case GNUTLS_PK_EC:
1000                 {
1001                         struct ecc_scalar key;
1002                         struct ecc_point pub;
1003                         const struct ecc_curve *curve;
1004
1005                         curve = get_supported_curve(level);
1006                         if (curve == NULL)
1007                                 return
1008                                     gnutls_assert_val
1009                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
1010
1011                         ecc_scalar_init(&key, curve);
1012                         ecc_point_init(&pub, curve);
1013
1014                         ecdsa_generate_keypair(&pub, &key, NULL, rnd_func);
1015
1016                         params->params[ECC_X] = _gnutls_mpi_new(0);
1017                         params->params[ECC_Y] = _gnutls_mpi_new(0);
1018                         params->params[ECC_K] = _gnutls_mpi_new(0);
1019
1020                         if (params->params[ECC_X] == NULL
1021                             || params->params[ECC_Y] == NULL
1022                             || params->params[ECC_K] == NULL) {
1023                                 _gnutls_mpi_release(&params->
1024                                                     params[ECC_X]);
1025                                 _gnutls_mpi_release(&params->
1026                                                     params[ECC_Y]);
1027                                 _gnutls_mpi_release(&params->
1028                                                     params[ECC_K]);
1029                                 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1030                                 goto ecc_fail;
1031                         }
1032
1033                         params->flags = level;
1034                         params->params_nr = ECC_PRIVATE_PARAMS;
1035
1036                         ecc_point_get(&pub, TOMPZ(params->params[ECC_X]),
1037                                       TOMPZ(params->params[ECC_Y]));
1038                         ecc_scalar_get(&key, TOMPZ(params->params[ECC_K]));
1039
1040                         ret = 0;
1041
1042                       ecc_fail:
1043                         ecc_point_clear(&pub);
1044                         ecc_scalar_clear(&key);
1045                         
1046                         if (ret < 0)
1047                                 goto fail;
1048
1049                         break;
1050                 }
1051         default:
1052                 gnutls_assert();
1053                 return GNUTLS_E_INVALID_REQUEST;
1054         }
1055
1056         FAIL_IF_FIPS_ERROR;
1057         return 0;
1058
1059       fail:
1060
1061         for (i = 0; i < params->params_nr; i++) {
1062                 _gnutls_mpi_release(&params->params[i]);
1063         }
1064         params->params_nr = 0;
1065
1066         FAIL_IF_FIPS_ERROR;
1067         return ret;
1068 }
1069
1070 static int
1071 wrap_nettle_pk_verify_params(gnutls_pk_algorithm_t algo,
1072                              const gnutls_pk_params_st * params)
1073 {
1074         int ret;
1075
1076         switch (algo) {
1077         case GNUTLS_PK_RSA:
1078                 {
1079                         bigint_t t1 = NULL, t2 = NULL;
1080
1081                         if (params->params_nr != RSA_PRIVATE_PARAMS)
1082                                 return
1083                                     gnutls_assert_val
1084                                     (GNUTLS_E_INVALID_REQUEST);
1085
1086                         t1 = _gnutls_mpi_new(256);
1087                         if (t1 == NULL)
1088                                 return
1089                                     gnutls_assert_val
1090                                     (GNUTLS_E_MEMORY_ERROR);
1091
1092                         _gnutls_mpi_mulm(t1, params->params[RSA_PRIME1],
1093                                          params->params[RSA_PRIME2],
1094                                          params->params[RSA_MODULUS]);
1095                         if (_gnutls_mpi_cmp_ui(t1, 0) != 0) {
1096                                 ret =
1097                                     gnutls_assert_val
1098                                     (GNUTLS_E_ILLEGAL_PARAMETER);
1099                                 goto rsa_cleanup;
1100                         }
1101
1102                         mpz_invert(TOMPZ(t1),
1103                                    TOMPZ(params->params[RSA_PRIME2]),
1104                                    TOMPZ(params->params[RSA_PRIME1]));
1105                         if (_gnutls_mpi_cmp(t1, params->params[RSA_COEF])
1106                             != 0) {
1107                                 ret =
1108                                     gnutls_assert_val
1109                                     (GNUTLS_E_ILLEGAL_PARAMETER);
1110                                 goto rsa_cleanup;
1111                         }
1112
1113                         /* [RSA_PRIME1] = d % p-1, [RSA_PRIME2] = d % q-1 */
1114                         _gnutls_mpi_sub_ui(t1, params->params[RSA_PRIME1],
1115                                            1);
1116                         t2 = _gnutls_mpi_modm(NULL, params->params[RSA_PRIV], t1);
1117                         if (t2 == NULL) {
1118                                 ret =
1119                                     gnutls_assert_val
1120                                     (GNUTLS_E_MEMORY_ERROR);
1121                                 goto rsa_cleanup;
1122                         }
1123
1124                         if (_gnutls_mpi_cmp(params->params[RSA_E1], t2) !=
1125                             0) {
1126                                 ret =
1127                                     gnutls_assert_val
1128                                     (GNUTLS_E_ILLEGAL_PARAMETER);
1129                                 goto rsa_cleanup;
1130                         }
1131
1132                         _gnutls_mpi_sub_ui(t1, params->params[RSA_PRIME2],
1133                                            1);
1134                         zrelease_mpi_key(&t2);
1135
1136                         t2 = _gnutls_mpi_modm(NULL, params->params[RSA_PRIV], t1);
1137                         if (t2 == NULL) {
1138                                 ret =
1139                                     gnutls_assert_val
1140                                     (GNUTLS_E_MEMORY_ERROR);
1141                                 goto rsa_cleanup;
1142                         }
1143
1144                         if (_gnutls_mpi_cmp(params->params[RSA_E2], t2) !=
1145                             0) {
1146                                 ret =
1147                                     gnutls_assert_val
1148                                     (GNUTLS_E_ILLEGAL_PARAMETER);
1149                                 goto rsa_cleanup;
1150                         }
1151
1152                         ret = 0;
1153
1154                       rsa_cleanup:
1155                         zrelease_mpi_key(&t1);
1156                         zrelease_mpi_key(&t2);
1157                 }
1158
1159                 break;
1160         case GNUTLS_PK_DSA:
1161                 {
1162                         bigint_t t1 = NULL;
1163
1164                         if (params->params_nr != DSA_PRIVATE_PARAMS)
1165                                 return
1166                                     gnutls_assert_val
1167                                     (GNUTLS_E_INVALID_REQUEST);
1168
1169                         t1 = _gnutls_mpi_new(256);
1170                         if (t1 == NULL)
1171                                 return
1172                                     gnutls_assert_val
1173                                     (GNUTLS_E_MEMORY_ERROR);
1174
1175                         _gnutls_mpi_powm(t1, params->params[DSA_G],
1176                                          params->params[DSA_X],
1177                                          params->params[DSA_P]);
1178
1179                         if (_gnutls_mpi_cmp(t1, params->params[DSA_Y]) !=
1180                             0) {
1181                                 ret =
1182                                     gnutls_assert_val
1183                                     (GNUTLS_E_ILLEGAL_PARAMETER);
1184                                 goto dsa_cleanup;
1185                         }
1186
1187                         ret = 0;
1188
1189                       dsa_cleanup:
1190                         zrelease_mpi_key(&t1);
1191                 }
1192
1193                 break;
1194         case GNUTLS_PK_EC:
1195                 {
1196                         struct ecc_point r, pub;
1197                         struct ecc_scalar priv;
1198                         mpz_t x1, y1, x2, y2;
1199                         const struct ecc_curve *curve;
1200
1201                         if (params->params_nr != ECC_PRIVATE_PARAMS)
1202                                 return
1203                                     gnutls_assert_val
1204                                     (GNUTLS_E_INVALID_REQUEST);
1205
1206                         curve = get_supported_curve(params->flags);
1207                         if (curve == NULL)
1208                                 return
1209                                     gnutls_assert_val
1210                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
1211
1212                         ret = _ecc_params_to_pubkey(params, &pub, curve);
1213                         if (ret < 0)
1214                                 return gnutls_assert_val(ret);
1215
1216                         ret = _ecc_params_to_privkey(params, &priv, curve);
1217                         if (ret < 0) {
1218                                 ecc_point_clear(&pub);
1219                                 return gnutls_assert_val(ret);
1220                         }
1221
1222                         ecc_point_init(&r, curve);
1223                         /* verify that x,y lie on the curve */
1224                         ret =
1225                             ecc_point_set(&r, TOMPZ(params->params[ECC_X]),
1226                                           TOMPZ(params->params[ECC_Y]));
1227                         if (ret == 0) {
1228                                 ret =
1229                                     gnutls_assert_val
1230                                     (GNUTLS_E_ILLEGAL_PARAMETER);
1231                                 goto ecc_cleanup;
1232                         }
1233                         ecc_point_clear(&r);
1234
1235                         ecc_point_init(&r, curve);
1236                         ecc_point_mul_g(&r, &priv);
1237
1238                         mpz_init(x1);
1239                         mpz_init(y1);
1240                         ecc_point_get(&r, x1, y1);
1241                         ecc_point_zclear(&r);
1242
1243                         mpz_init(x2);
1244                         mpz_init(y2);
1245                         ecc_point_get(&pub, x2, y2);
1246
1247                         /* verify that k*(Gx,Gy)=(x,y) */
1248                         if (mpz_cmp(x1, x2) != 0 || mpz_cmp(y1, y2) != 0) {
1249                                 ret =
1250                                     gnutls_assert_val
1251                                     (GNUTLS_E_ILLEGAL_PARAMETER);
1252                                 goto ecc_cleanup;
1253                         }
1254
1255                         ret = 0;
1256
1257                       ecc_cleanup:
1258                         ecc_scalar_zclear(&priv);
1259                         ecc_point_clear(&pub);
1260                 }
1261                 break;
1262         default:
1263                 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1264         }
1265
1266         return ret;
1267 }
1268
1269 static int calc_rsa_exp(gnutls_pk_params_st * params)
1270 {
1271         bigint_t tmp = _gnutls_mpi_alloc_like(params->params[0]);
1272
1273         if (params->params_nr < RSA_PRIVATE_PARAMS - 2) {
1274                 gnutls_assert();
1275                 return GNUTLS_E_INTERNAL_ERROR;
1276         }
1277
1278         if (tmp == NULL) {
1279                 gnutls_assert();
1280                 return GNUTLS_E_MEMORY_ERROR;
1281         }
1282
1283         /* [6] = d % p-1, [7] = d % q-1 */
1284         _gnutls_mpi_sub_ui(tmp, params->params[3], 1);
1285         params->params[6] =
1286             _gnutls_mpi_modm(NULL, params->params[2] /*d */ , tmp);
1287
1288         _gnutls_mpi_sub_ui(tmp, params->params[4], 1);
1289         params->params[7] =
1290             _gnutls_mpi_modm(NULL, params->params[2] /*d */ , tmp);
1291
1292         zrelease_mpi_key(&tmp);
1293
1294         if (params->params[7] == NULL || params->params[6] == NULL) {
1295                 gnutls_assert();
1296                 return GNUTLS_E_MEMORY_ERROR;
1297         }
1298
1299         return 0;
1300 }
1301
1302
1303 static int
1304 wrap_nettle_pk_fixup(gnutls_pk_algorithm_t algo,
1305                      gnutls_direction_t direction,
1306                      gnutls_pk_params_st * params)
1307 {
1308         int result;
1309
1310         if (direction == GNUTLS_IMPORT && algo == GNUTLS_PK_RSA) {
1311                 /* do not trust the generated values. Some old private keys
1312                  * generated by us have mess on the values. Those were very
1313                  * old but it seemed some of the shipped example private
1314                  * keys were as old.
1315                  */
1316                 mpz_invert(TOMPZ(params->params[RSA_COEF]),
1317                            TOMPZ(params->params[RSA_PRIME2]),
1318                            TOMPZ(params->params[RSA_PRIME1]));
1319
1320                 /* calculate exp1 [6] and exp2 [7] */
1321                 zrelease_mpi_key(&params->params[RSA_E1]);
1322                 zrelease_mpi_key(&params->params[RSA_E2]);
1323
1324                 result = calc_rsa_exp(params);
1325                 if (result < 0) {
1326                         gnutls_assert();
1327                         return result;
1328                 }
1329                 params->params_nr = RSA_PRIVATE_PARAMS;
1330         }
1331
1332         return 0;
1333 }
1334
1335 static int
1336 extract_digest_info(const struct rsa_public_key *key,
1337                     gnutls_datum_t * di, uint8_t ** rdi,
1338                     const mpz_t signature)
1339 {
1340         unsigned i;
1341         int ret;
1342         mpz_t m;
1343         uint8_t *em;
1344
1345         if (key->size == 0)
1346                 return 0;
1347
1348         em = gnutls_malloc(key->size);
1349         if (em == NULL)
1350                 return 0;
1351
1352         mpz_init(m);
1353
1354         mpz_powm(m, signature, key->e, key->n);
1355
1356         nettle_mpz_get_str_256(key->size, em, m);
1357         mpz_clear(m);
1358
1359         if (em[0] != 0 || em[1] != 1) {
1360                 ret = 0;
1361                 goto cleanup;
1362         }
1363
1364         for (i = 2; i < key->size; i++) {
1365                 if (em[i] == 0 && i > 2)
1366                         break;
1367
1368                 if (em[i] != 0xff) {
1369                         ret = 0;
1370                         goto cleanup;
1371                 }
1372         }
1373
1374         i++;
1375
1376         *rdi = em;
1377
1378         di->data = &em[i];
1379         di->size = key->size - i;
1380
1381         return 1;
1382
1383 cleanup:
1384         memset(em, 0, sizeof(key->size));
1385         gnutls_free(em);
1386
1387         return ret;
1388 }
1389
1390 /* Given a signature and parameters, it should return
1391  * the hash algorithm used in the signature. This is a kludge
1392  * but until we deprecate gnutls_pubkey_get_verify_algorithm()
1393  * we depend on it.
1394  */
1395 static int wrap_nettle_hash_algorithm(gnutls_pk_algorithm_t pk,
1396                                       const gnutls_datum_t * sig,
1397                                       gnutls_pk_params_st * issuer_params,
1398                                       gnutls_digest_algorithm_t *
1399                                       hash_algo)
1400 {
1401         uint8_t digest[MAX_HASH_SIZE];
1402         uint8_t *rdi = NULL;
1403         gnutls_datum_t di;
1404         unsigned digest_size;
1405         mpz_t s;
1406         struct rsa_public_key pub;
1407         const mac_entry_st *me;
1408         int ret;
1409
1410         mpz_init(s);
1411
1412         switch (pk) {
1413         case GNUTLS_PK_DSA:
1414         case GNUTLS_PK_EC:
1415
1416                 me = _gnutls_dsa_q_to_hash(pk, issuer_params, NULL);
1417                 if (hash_algo)
1418                         *hash_algo = me->id;
1419
1420                 ret = 0;
1421                 break;
1422         case GNUTLS_PK_RSA:
1423                 if (sig == NULL) {      /* return a sensible algorithm */
1424                         if (hash_algo)
1425                                 *hash_algo = GNUTLS_DIG_SHA256;
1426                         return 0;
1427                 }
1428
1429                 _rsa_params_to_pubkey(issuer_params, &pub);
1430
1431                 digest_size = sizeof(digest);
1432
1433                 nettle_mpz_set_str_256_u(s, sig->size, sig->data);
1434
1435                 ret = extract_digest_info(&pub, &di, &rdi, s);
1436                 if (ret == 0) {
1437                         ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
1438                         gnutls_assert();
1439                         goto cleanup;
1440                 }
1441
1442                 digest_size = sizeof(digest);
1443                 if ((ret =
1444                      decode_ber_digest_info(&di, hash_algo, digest,
1445                                             &digest_size)) < 0) {
1446                         gnutls_assert();
1447                         goto cleanup;
1448                 }
1449
1450                 if (digest_size !=
1451                     _gnutls_hash_get_algo_len(mac_to_entry(*hash_algo))) {
1452                         gnutls_assert();
1453                         ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
1454                         goto cleanup;
1455                 }
1456
1457                 ret = 0;
1458                 break;
1459
1460         default:
1461                 gnutls_assert();
1462                 ret = GNUTLS_E_INTERNAL_ERROR;
1463         }
1464
1465       cleanup:
1466         mpz_clear(s);
1467         gnutls_free(rdi);
1468         return ret;
1469
1470 }
1471
1472
1473 int crypto_pk_prio = INT_MAX;
1474
1475 gnutls_crypto_pk_st _gnutls_pk_ops = {
1476         .hash_algorithm = wrap_nettle_hash_algorithm,
1477         .encrypt = _wrap_nettle_pk_encrypt,
1478         .decrypt = _wrap_nettle_pk_decrypt,
1479         .sign = _wrap_nettle_pk_sign,
1480         .verify = _wrap_nettle_pk_verify,
1481         .verify_params = wrap_nettle_pk_verify_params,
1482         .generate_params = wrap_nettle_pk_generate_params,
1483         .generate_keys = wrap_nettle_pk_generate_keys,
1484         .pk_fixup_private_params = wrap_nettle_pk_fixup,
1485         .derive = _wrap_nettle_pk_derive,
1486         .curve_exists = _wrap_nettle_pk_curve_exists,
1487 };