LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/nettle - pk.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 1190 1543 77.1 %
Date: 2020-10-30 04:50:48 Functions: 38 39 97.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2010-2012 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2013-2017 Nikos Mavrogiannopoulos
       4             :  * Copyright (C) 2016-2017 Red Hat, Inc.
       5             :  *
       6             :  * Author: Nikos Mavrogiannopoulos
       7             :  *
       8             :  * This file is part of GNUTLS.
       9             :  *
      10             :  * The GNUTLS library is free software; you can redistribute it and/or
      11             :  * modify it under the terms of the GNU Lesser General Public License
      12             :  * as published by the Free Software Foundation; either version 2.1 of
      13             :  * the License, or (at your option) any later version.
      14             :  *
      15             :  * This library is distributed in the hope that it will be useful, but
      16             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :  * Lesser General Public License for more details.
      19             :  *
      20             :  * You should have received a copy of the GNU Lesser General Public License
      21             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      22             :  *
      23             :  */
      24             : 
      25             : /* This file contains the functions needed for RSA/DSA public key
      26             :  * encryption and signatures.
      27             :  */
      28             : 
      29             : #include "gnutls_int.h"
      30             : #include <mpi.h>
      31             : #include <pk.h>
      32             : #include "errors.h"
      33             : #include <datum.h>
      34             : #include <global.h>
      35             : #include <tls-sig.h>
      36             : #include <num.h>
      37             : #include <x509/x509_int.h>
      38             : #include <x509/common.h>
      39             : #include <random.h>
      40             : #include <pk.h>
      41             : #include <nettle/dsa.h>
      42             : #include <dsa-fips.h>
      43             : #include <rsa-fips.h>
      44             : #include <nettle/rsa.h>
      45             : #include <gnutls/crypto.h>
      46             : #include <nettle/bignum.h>
      47             : #include <nettle/ecc.h>
      48             : #include <nettle/ecdsa.h>
      49             : #include <nettle/ecc-curve.h>
      50             : #include <nettle/curve25519.h>
      51             : #if !NEED_INT_ECC
      52             : #include <nettle/curve448.h>
      53             : #else
      54             : #include "ecc/curve448.h"
      55             : #include "ecc/eddsa.h"
      56             : #endif
      57             : #include <nettle/eddsa.h>
      58             : #include <nettle/version.h>
      59             : #if ENABLE_GOST
      60             : #if NEED_INT_ECC
      61             : #include "ecc/gostdsa.h"
      62             : #include "ecc-gost-curve.h"
      63             : #else
      64             : #include <nettle/gostdsa.h>
      65             : #define gost_point_mul_g ecc_point_mul_g
      66             : #define gost_point_set ecc_point_set
      67             : #endif
      68             : #include "gost/gostdsa2.h"
      69             : #endif
      70             : #include "int/ecdsa-compute-k.h"
      71             : #include "int/dsa-compute-k.h"
      72             : #include <gnettle.h>
      73             : #include <fips.h>
      74             : #include "dh.h"
      75             : 
      76             : static inline const struct ecc_curve *get_supported_nist_curve(int curve);
      77             : static inline const struct ecc_curve *get_supported_gost_curve(int curve);
      78             : 
      79             : /* When these callbacks are used for a nettle operation, the
      80             :  * caller must check the macro HAVE_LIB_ERROR() after the operation
      81             :  * is complete. If the macro is true, the operation is to be considered
      82             :  * failed (meaning the random generation failed).
      83             :  */
      84      201372 : static void rnd_key_func(void *_ctx, size_t length, uint8_t * data)
      85             : {
      86      201372 :         if (gnutls_rnd(GNUTLS_RND_KEY, data, length) < 0) {
      87           0 :                 _gnutls_switch_lib_state(LIB_STATE_ERROR);
      88             :         }
      89      201372 : }
      90             : 
      91       17116 : static void rnd_tmpkey_func(void *_ctx, size_t length, uint8_t * data)
      92             : {
      93       17116 :         if (gnutls_rnd(GNUTLS_RND_RANDOM, data, length) < 0) {
      94           0 :                 _gnutls_switch_lib_state(LIB_STATE_ERROR);
      95             :         }
      96       17116 : }
      97             : 
      98       18185 : static void rnd_nonce_func(void *_ctx, size_t length, uint8_t * data)
      99             : {
     100       18185 :         if (gnutls_rnd(GNUTLS_RND_NONCE, data, length) < 0) {
     101           2 :                 _gnutls_switch_lib_state(LIB_STATE_ERROR);
     102             :         }
     103       18185 : }
     104             : 
     105          13 : static void rnd_mpz_func(void *_ctx, size_t length, uint8_t * data)
     106             : {
     107          13 :         mpz_t *k = _ctx;
     108          13 :         nettle_mpz_get_str_256 (length, data, *k);
     109          13 : }
     110             : 
     111           0 : static void rnd_nonce_func_fallback(void *_ctx, size_t length, uint8_t * data)
     112             : {
     113           0 :         if (unlikely(_gnutls_get_lib_state() != LIB_STATE_SELFTEST)) {
     114           0 :                 _gnutls_switch_lib_state(LIB_STATE_ERROR);
     115             :         }
     116             : 
     117           0 :         memset(data, 0xAA, length);
     118           0 : }
     119             : 
     120             : static void
     121        9997 : ecc_scalar_zclear (struct ecc_scalar *s)
     122             : {
     123        9997 :         zeroize_key(s->p, ecc_size(s->ecc)*sizeof(mp_limb_t));
     124        9997 :         ecc_scalar_clear(s);
     125        9997 : }
     126             : 
     127             : static void
     128         960 : ecc_point_zclear (struct ecc_point *p)
     129             : {
     130         960 :         zeroize_key(p->p, ecc_size_a(p->ecc)*sizeof(mp_limb_t));
     131         960 :         ecc_point_clear(p);
     132         960 : }
     133             :  
     134             : static void
     135        4327 : _dsa_params_get(const gnutls_pk_params_st * pk_params,
     136             :                 struct dsa_params *pub)
     137             : {
     138        4327 :         memcpy(pub->p, pk_params->params[DSA_P], SIZEOF_MPZT);
     139             : 
     140        4327 :         if (pk_params->params[DSA_Q])
     141        2677 :                 memcpy(&pub->q, pk_params->params[DSA_Q], SIZEOF_MPZT);
     142        4327 :         memcpy(pub->g, pk_params->params[DSA_G], SIZEOF_MPZT);
     143        4327 : }
     144             : 
     145             : static void
     146       19496 : _rsa_params_to_privkey(const gnutls_pk_params_st * pk_params,
     147             :                        struct rsa_private_key *priv)
     148             : {
     149       19496 :         memcpy(priv->d, pk_params->params[RSA_PRIV], SIZEOF_MPZT);
     150       19496 :         memcpy(priv->p, pk_params->params[RSA_PRIME1], SIZEOF_MPZT);
     151       19496 :         memcpy(priv->q, pk_params->params[RSA_PRIME2], SIZEOF_MPZT);
     152       19496 :         memcpy(priv->c, pk_params->params[RSA_COEF], SIZEOF_MPZT);
     153       19496 :         memcpy(priv->a, pk_params->params[RSA_E1], SIZEOF_MPZT);
     154       19496 :         memcpy(priv->b, pk_params->params[RSA_E2], SIZEOF_MPZT);
     155             :         /* we do not rsa_private_key_prepare() because it involves a multiplication.
     156             :          * we call it once when we import the parameters */
     157       38992 :         priv->size =
     158       19496 :             nettle_mpz_sizeinbase_256_u(TOMPZ
     159             :                                         (pk_params->params[RSA_MODULUS]));
     160       19496 : }
     161             : 
     162             : /* returns a negative value on invalid pubkey */
     163             : static int
     164       23268 : _rsa_params_to_pubkey(const gnutls_pk_params_st * pk_params,
     165             :                       struct rsa_public_key *pub)
     166             : {
     167       23268 :         memcpy(pub->n, pk_params->params[RSA_MODULUS], SIZEOF_MPZT);
     168       23268 :         memcpy(pub->e, pk_params->params[RSA_PUB], SIZEOF_MPZT);
     169       23268 :         if (rsa_public_key_prepare(pub) == 0)
     170           4 :                 return gnutls_assert_val(GNUTLS_E_PK_INVALID_PUBKEY);
     171             : 
     172             :         return 0;
     173             : }
     174             : 
     175             : static int
     176        9391 : _ecc_params_to_privkey(const gnutls_pk_params_st * pk_params,
     177             :                        struct ecc_scalar *priv,
     178             :                        const struct ecc_curve *curve)
     179             : {
     180        9391 :         ecc_scalar_init(priv, curve);
     181        9391 :         if (ecc_scalar_set(priv, pk_params->params[ECC_K]) == 0) {
     182           0 :                 ecc_scalar_clear(priv);
     183           0 :                 return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);
     184             :         }
     185             : 
     186             :         return 0;
     187             : }
     188             : 
     189             : static int
     190       10291 : _ecc_params_to_pubkey(const gnutls_pk_params_st * pk_params,
     191             :                       struct ecc_point *pub, const struct ecc_curve *curve)
     192             : {
     193       10291 :         ecc_point_init(pub, curve);
     194       10291 :         if (ecc_point_set
     195       10291 :             (pub, pk_params->params[ECC_X], pk_params->params[ECC_Y]) == 0) {
     196          22 :                 ecc_point_clear(pub);
     197          32 :                 return gnutls_assert_val(GNUTLS_E_PK_INVALID_PUBKEY);
     198             :         }
     199             : 
     200             :         return 0;
     201             : }
     202             : 
     203             : #if ENABLE_GOST
     204             : static int
     205         696 : _gost_params_to_privkey(const gnutls_pk_params_st * pk_params,
     206             :                        struct ecc_scalar *priv,
     207             :                        const struct ecc_curve *curve)
     208             : {
     209         696 :         ecc_scalar_init(priv, curve);
     210         696 :         if (ecc_scalar_set(priv, pk_params->params[GOST_K]) == 0) {
     211           0 :                 ecc_scalar_clear(priv);
     212           0 :                 return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);
     213             :         }
     214             : 
     215             :         return 0;
     216             : }
     217             : 
     218             : static int
     219        1672 : _gost_params_to_pubkey(const gnutls_pk_params_st * pk_params,
     220             :                        struct ecc_point *pub, const struct ecc_curve *curve)
     221             : {
     222        1672 :         ecc_point_init(pub, curve);
     223        1672 :         if (gost_point_set
     224        1672 :             (pub, pk_params->params[GOST_X], pk_params->params[GOST_Y]) == 0) {
     225           0 :                 ecc_point_clear(pub);
     226           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     227             :         }
     228             : 
     229             :         return 0;
     230             : }
     231             : #endif
     232             : 
     233             : static int
     234        4945 : ecc_shared_secret(struct ecc_scalar *private_key,
     235             :                   struct ecc_point *public_key, void *out, unsigned size)
     236             : {
     237        4945 :         struct ecc_point r;
     238        4945 :         mpz_t x, y;
     239        4945 :         int ret = 0;
     240             : 
     241        4945 :         mpz_init(x);
     242        4945 :         mpz_init(y);
     243        4945 :         ecc_point_init(&r, public_key->ecc);
     244             : 
     245        4945 :         ecc_point_mul(&r, private_key, public_key);
     246             : 
     247        4945 :         ecc_point_get(&r, x, y);
     248             : 
     249             :         /* Check if the point is not an identity element.  Note that this cannot
     250             :          * happen in nettle implementation, because it cannot represent an
     251             :          * infinity point. */
     252        4945 :         if (mpz_cmp_ui(x, 0) == 0 && mpz_cmp_ui(y, 0) == 0) {
     253           0 :                 ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
     254           0 :                 goto cleanup;
     255             :         }
     256             : 
     257        4945 :         nettle_mpz_get_str_256(size, out, x);
     258             : 
     259        4945 :  cleanup:
     260        4945 :         mpz_clear(x);
     261        4945 :         mpz_clear(y);
     262        4945 :         ecc_point_clear(&r);
     263             : 
     264        4945 :         return ret;
     265             : }
     266             : 
     267             : #define MAX_DH_BITS DEFAULT_MAX_VERIFY_BITS
     268             : /* This is used when we have no idea on the structure
     269             :  * of p-1 used by the peer. It is still a conservative
     270             :  * choice, but small than what we've been using before.
     271             :  */
     272             : #define DH_EXPONENT_SIZE(p_size) (2*_gnutls_pk_bits_to_subgroup_bits(p_size))
     273             : 
     274             : static inline int
     275        1643 : edwards_curve_mul(gnutls_pk_algorithm_t algo,
     276             :                   uint8_t *q, const uint8_t *n, const uint8_t *p)
     277             : {
     278        1643 :         switch (algo) {
     279         333 :         case GNUTLS_PK_ECDH_X25519:
     280         333 :                 curve25519_mul(q, n, p);
     281         333 :                 return 0;
     282        1310 :         case GNUTLS_PK_ECDH_X448:
     283        1310 :                 curve448_mul(q, n, p);
     284        1310 :                 return 0;
     285             :         default:
     286           0 :                 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
     287             :         }
     288             : }
     289             : 
     290             : /* This is used for DH or ECDH key derivation. In DH for example
     291             :  * it is given the peers Y and our x, and calculates Y^x
     292             :  */
     293       10636 : static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo,
     294             :                                   gnutls_datum_t * out,
     295             :                                   const gnutls_pk_params_st * priv,
     296             :                                   const gnutls_pk_params_st * pub,
     297             :                                   const gnutls_datum_t * nonce,
     298             :                                   unsigned int flags)
     299             : {
     300       10636 :         int ret;
     301             : 
     302       10636 :         switch (algo) {
     303        3955 :         case GNUTLS_PK_DH: {
     304        3955 :                 bigint_t f, x, q, prime;
     305        3955 :                 bigint_t k = NULL, primesub1 = NULL, r = NULL;
     306        3955 :                 unsigned int bits;
     307             : 
     308        3955 :                 if (nonce != NULL)
     309           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     310             : 
     311        3955 :                 f = pub->params[DH_Y];
     312        3955 :                 x = priv->params[DH_X];
     313        3955 :                 q = priv->params[DH_Q];
     314        3955 :                 prime = priv->params[DH_P];
     315             : 
     316        3955 :                 ret = _gnutls_mpi_init_multi(&k, &primesub1, &r, NULL);
     317        3955 :                 if (ret < 0)
     318           0 :                         return gnutls_assert_val(ret);
     319             : 
     320        3955 :                 ret = _gnutls_mpi_sub_ui(primesub1, prime, 1);
     321        3955 :                 if (ret < 0) {
     322           0 :                         gnutls_assert();
     323           0 :                         goto dh_cleanup;
     324             :                 }
     325             : 
     326             :                 /* check if f==0,1, or f >= p-1 */
     327        3955 :                 if ((_gnutls_mpi_cmp_ui(f, 1) == 0)
     328        3946 :                     || (_gnutls_mpi_cmp_ui(f, 0) == 0)
     329        3946 :                     || (_gnutls_mpi_cmp(f, primesub1) >= 0)) {
     330          30 :                         gnutls_assert();
     331          30 :                         ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
     332          30 :                         goto dh_cleanup;
     333             :                 }
     334             : 
     335             :                 /* if we have Q check that y ^ q mod p == 1 */
     336        3925 :                 if (q != NULL) {
     337        2416 :                         ret = _gnutls_mpi_powm(r, f, q, prime);
     338        2416 :                         if (ret < 0) {
     339           0 :                                 gnutls_assert();
     340           0 :                                 goto dh_cleanup;
     341             :                         }
     342        2416 :                         ret = _gnutls_mpi_cmp_ui(r, 1);
     343        2416 :                         if (ret != 0) {
     344           2 :                                 gnutls_assert();
     345           2 :                                 ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
     346           2 :                                 goto dh_cleanup;
     347             :                         }
     348             :                 } else if ((flags & PK_DERIVE_TLS13) &&
     349             :                            _gnutls_fips_mode_enabled()) {
     350             :                         /* Mandatory in FIPS mode for TLS 1.3 */
     351             :                         ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
     352             :                         goto dh_cleanup;
     353             :                 }
     354             : 
     355             :                 /* prevent denial of service */
     356        3923 :                 bits = _gnutls_mpi_get_nbits(prime);
     357        3923 :                 if (bits == 0 || bits > MAX_DH_BITS) {
     358           0 :                         gnutls_assert();
     359           0 :                         ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
     360           0 :                         goto dh_cleanup;
     361             :                 }
     362             : 
     363             : 
     364        3923 :                 ret = _gnutls_mpi_powm(k, f, x, prime);
     365        3923 :                 if (ret < 0) {
     366           0 :                         gnutls_assert();
     367           0 :                         goto dh_cleanup;
     368             :                 }
     369             : 
     370             :                 /* check if k==0,1, or k = p-1 */
     371        3923 :                 if ((_gnutls_mpi_cmp_ui(k, 1) == 0)
     372        3923 :                     || (_gnutls_mpi_cmp_ui(k, 0) == 0)
     373        3923 :                     || (_gnutls_mpi_cmp(k, primesub1) == 0)) {
     374           0 :                         gnutls_assert();
     375           0 :                         ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
     376           0 :                         goto dh_cleanup;
     377             :                 }
     378             : 
     379        3923 :                 if (flags & PK_DERIVE_TLS13) {
     380        1719 :                         ret =
     381        1719 :                             _gnutls_mpi_dprint_size(k, out,
     382        1719 :                                                     (bits+7)/8);
     383             :                 } else {
     384        2204 :                         ret = _gnutls_mpi_dprint(k, out);
     385             :                 }
     386             : 
     387        3923 :                 if (ret < 0) {
     388           0 :                         gnutls_assert();
     389           0 :                         goto dh_cleanup;
     390             :                 }
     391             : 
     392             :                 ret = 0;
     393        3955 : dh_cleanup:
     394        3955 :                 _gnutls_mpi_release(&r);
     395        3955 :                 _gnutls_mpi_release(&primesub1);
     396        3955 :                 zrelease_temp_mpi_key(&k);
     397        3955 :                 if (ret < 0)
     398          32 :                         goto cleanup;
     399             : 
     400        3923 :                 break;
     401             :         }
     402        4964 :         case GNUTLS_PK_EC:
     403             :                 {
     404        4964 :                         struct ecc_scalar ecc_priv;
     405        4964 :                         struct ecc_point ecc_pub;
     406        4964 :                         const struct ecc_curve *curve;
     407             : 
     408        4964 :                         out->data = NULL;
     409             : 
     410        4964 :                         if (nonce != NULL)
     411          19 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     412             : 
     413        4964 :                         curve = get_supported_nist_curve(priv->curve);
     414        4964 :                         if (curve == NULL)
     415           0 :                                 return
     416           0 :                                     gnutls_assert_val
     417             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
     418             : 
     419        4964 :                         ret = _ecc_params_to_pubkey(pub, &ecc_pub, curve);
     420        4964 :                         if (ret < 0)
     421          29 :                                 return gnutls_assert_val(ret);
     422             : 
     423        4945 :                         ret =
     424        4945 :                             _ecc_params_to_privkey(priv, &ecc_priv, curve);
     425        4945 :                         if (ret < 0) {
     426           0 :                                 ecc_point_clear(&ecc_pub);
     427           0 :                                 return gnutls_assert_val(ret);
     428             :                         }
     429             : 
     430        4945 :                         out->size = gnutls_ecc_curve_get_size(priv->curve);
     431             :                         /*ecc_size(curve)*sizeof(mp_limb_t); */
     432        4945 :                         out->data = gnutls_malloc(out->size);
     433        4945 :                         if (out->data == NULL) {
     434           0 :                                 ret =
     435           0 :                                     gnutls_assert_val
     436             :                                     (GNUTLS_E_MEMORY_ERROR);
     437           0 :                                 goto ecc_cleanup;
     438             :                         }
     439             : 
     440        4945 :                         ret = ecc_shared_secret(&ecc_priv, &ecc_pub, out->data,
     441             :                                                 out->size);
     442        4945 :                         if (ret < 0)
     443           0 :                                 gnutls_free(out->data);
     444             : 
     445        4945 :                       ecc_cleanup:
     446        4945 :                         ecc_point_clear(&ecc_pub);
     447        4945 :                         ecc_scalar_zclear(&ecc_priv);
     448        4945 :                         if (ret < 0)
     449           0 :                                 goto cleanup;
     450        4945 :                         break;
     451             :                 }
     452        1643 :         case GNUTLS_PK_ECDH_X25519:
     453             :         case GNUTLS_PK_ECDH_X448:
     454             :                 {
     455        1643 :                         unsigned size = gnutls_ecc_curve_get_size(priv->curve);
     456             : 
     457        1643 :                         if (nonce != NULL)
     458           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     459             : 
     460             :                         /* The point is in pub, while the private part (scalar) in priv. */
     461             : 
     462        1643 :                         if (size == 0 || priv->raw_priv.size != size)
     463           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     464             : 
     465        1643 :                         out->data = gnutls_malloc(size);
     466        1643 :                         if (out->data == NULL) {
     467           0 :                                 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     468           0 :                                 goto cleanup;
     469             :                         }
     470             : 
     471        1643 :                         out->size = size;
     472             : 
     473        1643 :                         ret = edwards_curve_mul(algo, out->data, priv->raw_priv.data, pub->raw_pub.data);
     474        1643 :                         if (ret < 0)
     475           0 :                                 goto cleanup;
     476             : 
     477        1643 :                         if (_gnutls_mem_is_zero(out->data, out->size)) {
     478          11 :                                 gnutls_free(out->data);
     479          11 :                                 gnutls_assert();
     480          11 :                                 ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
     481          11 :                                 goto cleanup;
     482             :                         }
     483             :                         break;
     484             :                 }
     485             : #if ENABLE_GOST
     486          74 :         case GNUTLS_PK_GOST_01:
     487             :         case GNUTLS_PK_GOST_12_256:
     488             :         case GNUTLS_PK_GOST_12_512:
     489             :         {
     490          74 :                 struct ecc_scalar ecc_priv;
     491          74 :                 struct ecc_point ecc_pub;
     492          74 :                 const struct ecc_curve *curve;
     493             : 
     494          74 :                 out->data = NULL;
     495             : 
     496          74 :                 curve = get_supported_gost_curve(priv->curve);
     497          74 :                 if (curve == NULL)
     498           0 :                         return
     499           0 :                             gnutls_assert_val
     500             :                             (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
     501             : 
     502          74 :                 if (nonce == NULL)
     503           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     504             : 
     505          74 :                 ret = _gost_params_to_pubkey(pub, &ecc_pub, curve);
     506          74 :                 if (ret < 0)
     507           0 :                         return gnutls_assert_val(ret);
     508             : 
     509          74 :                 ret = _gost_params_to_privkey(priv, &ecc_priv, curve);
     510          74 :                 if (ret < 0) {
     511           0 :                         ecc_point_clear(&ecc_pub);
     512           0 :                         return gnutls_assert_val(ret);
     513             :                 }
     514             : 
     515          74 :                 out->size = 2 * gnutls_ecc_curve_get_size(priv->curve);
     516          74 :                 out->data = gnutls_malloc(out->size);
     517          74 :                 if (out->data == NULL) {
     518           0 :                         ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     519           0 :                         goto gost_cleanup;
     520             :                 }
     521             : 
     522          74 :                 gostdsa_vko(&ecc_priv, &ecc_pub,
     523          74 :                             nonce->size, nonce->data,
     524             :                             out->data);
     525             : 
     526          74 :               gost_cleanup:
     527          74 :                 ecc_point_clear(&ecc_pub);
     528          74 :                 ecc_scalar_zclear(&ecc_priv);
     529          74 :                 if (ret < 0)
     530           0 :                         goto cleanup;
     531          74 :                 break;
     532             :         }
     533             : #endif
     534           0 :         default:
     535           0 :                 gnutls_assert();
     536           0 :                 ret = GNUTLS_E_INTERNAL_ERROR;
     537           0 :                 goto cleanup;
     538             :         }
     539             : 
     540             :         ret = 0;
     541             : 
     542             :       cleanup:
     543             : 
     544             :         return ret;
     545             : }
     546             : 
     547             : static int
     548         233 : _wrap_nettle_pk_encrypt(gnutls_pk_algorithm_t algo,
     549             :                         gnutls_datum_t * ciphertext,
     550             :                         const gnutls_datum_t * plaintext,
     551             :                         const gnutls_pk_params_st * pk_params)
     552             : {
     553         233 :         int ret;
     554         233 :         mpz_t p;
     555             : 
     556         233 :         mpz_init(p);
     557             : 
     558         233 :         switch (algo) {
     559         232 :         case GNUTLS_PK_RSA:
     560             :                 {
     561         232 :                         struct rsa_public_key pub;
     562         232 :                         nettle_random_func *random_func;
     563             : 
     564         232 :                         ret = _rsa_params_to_pubkey(pk_params, &pub);
     565         232 :                         if (ret < 0) {
     566           0 :                                 gnutls_assert();
     567           0 :                                 goto cleanup;
     568             :                         }
     569             : 
     570         232 :                         if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
     571             :                                 random_func = rnd_nonce_func_fallback;
     572             :                         else
     573         232 :                                 random_func = rnd_nonce_func;
     574         232 :                         ret =
     575         464 :                             rsa_encrypt(&pub, NULL, random_func,
     576         232 :                                         plaintext->size, plaintext->data,
     577             :                                         p);
     578         232 :                         if (ret == 0 || HAVE_LIB_ERROR()) {
     579           0 :                                 ret =
     580           0 :                                     gnutls_assert_val
     581             :                                     (GNUTLS_E_ENCRYPTION_FAILED);
     582           0 :                                 goto cleanup;
     583             :                         }
     584             : 
     585         232 :                         ret =
     586         232 :                             _gnutls_mpi_dprint_size(p, ciphertext,
     587             :                                                     pub.size);
     588         232 :                         if (ret < 0) {
     589           0 :                                 gnutls_assert();
     590           0 :                                 goto cleanup;
     591             :                         }
     592             : 
     593         232 :                         break;
     594             :                 }
     595           1 :         default:
     596           1 :                 gnutls_assert();
     597           1 :                 ret = GNUTLS_E_INVALID_REQUEST;
     598           1 :                 goto cleanup;
     599             :         }
     600             : 
     601         232 :         ret = 0;
     602             : 
     603         233 :       cleanup:
     604         233 :         mpz_clear(p);
     605             : 
     606         233 :         FAIL_IF_LIB_ERROR;
     607             :         return ret;
     608             : }
     609             : 
     610             : static int
     611          29 : _wrap_nettle_pk_decrypt(gnutls_pk_algorithm_t algo,
     612             :                         gnutls_datum_t * plaintext,
     613             :                         const gnutls_datum_t * ciphertext,
     614             :                         const gnutls_pk_params_st * pk_params)
     615             : {
     616          29 :         int ret;
     617             : 
     618          29 :         plaintext->data = NULL;
     619             : 
     620             :         /* make a sexp from pkey */
     621          29 :         switch (algo) {
     622          29 :         case GNUTLS_PK_RSA:
     623             :                 {
     624          29 :                         struct rsa_private_key priv;
     625          29 :                         struct rsa_public_key pub;
     626          29 :                         size_t length;
     627          29 :                         bigint_t c;
     628          29 :                         nettle_random_func *random_func;
     629             : 
     630          29 :                         _rsa_params_to_privkey(pk_params, &priv);
     631          29 :                         ret = _rsa_params_to_pubkey(pk_params, &pub);
     632          29 :                         if (ret < 0)
     633           0 :                                 return
     634           1 :                                     gnutls_assert_val(ret);
     635             : 
     636          29 :                         if (ciphertext->size != pub.size)
     637           1 :                                 return
     638           1 :                                     gnutls_assert_val
     639             :                                     (GNUTLS_E_DECRYPTION_FAILED);
     640             : 
     641          28 :                         if (_gnutls_mpi_init_scan_nz
     642          28 :                             (&c, ciphertext->data,
     643             :                              ciphertext->size) != 0) {
     644           1 :                                 ret =
     645           1 :                                     gnutls_assert_val
     646             :                                     (GNUTLS_E_MPI_SCAN_FAILED);
     647           4 :                                 goto cleanup;
     648             :                         }
     649             : 
     650          27 :                         length = pub.size;
     651          27 :                         plaintext->data = gnutls_malloc(length);
     652          27 :                         if (plaintext->data == NULL) {
     653           0 :                                 ret =
     654           0 :                                     gnutls_assert_val
     655             :                                     (GNUTLS_E_MEMORY_ERROR);
     656           0 :                                 goto cleanup;
     657             :                         }
     658             : 
     659          27 :                         if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
     660             :                                 random_func = rnd_nonce_func_fallback;
     661             :                         else
     662          27 :                                 random_func = rnd_nonce_func;
     663          27 :                         ret =
     664          27 :                             rsa_decrypt_tr(&pub, &priv, NULL, random_func,
     665             :                                            &length, plaintext->data,
     666             :                                            TOMPZ(c));
     667          27 :                         _gnutls_mpi_release(&c);
     668          27 :                         plaintext->size = length;
     669             : 
     670          27 :                         if (ret == 0 || HAVE_LIB_ERROR()) {
     671           3 :                                 ret =
     672           3 :                                     gnutls_assert_val
     673             :                                     (GNUTLS_E_DECRYPTION_FAILED);
     674           3 :                                 goto cleanup;
     675             :                         }
     676             : 
     677          24 :                         break;
     678             :                 }
     679           0 :         default:
     680           0 :                 gnutls_assert();
     681           0 :                 ret = GNUTLS_E_INTERNAL_ERROR;
     682           0 :                 goto cleanup;
     683             :         }
     684             : 
     685          24 :         ret = 0;
     686             : 
     687             :       cleanup:
     688          28 :         if (ret < 0)
     689           4 :                 gnutls_free(plaintext->data);
     690             : 
     691          28 :         FAIL_IF_LIB_ERROR;
     692             :         return ret;
     693             : }
     694             : 
     695             : /* Note: we do not allocate in this function to avoid asymettric
     696             :  * unallocation (which creates a side channel) in case of failure
     697             :  * */
     698             : static int
     699        1856 : _wrap_nettle_pk_decrypt2(gnutls_pk_algorithm_t algo,
     700             :                          const gnutls_datum_t * ciphertext,
     701             :                          unsigned char * plaintext,
     702             :                          size_t plaintext_size,
     703             :                          const gnutls_pk_params_st * pk_params)
     704             : {
     705        1856 :         struct rsa_private_key priv;
     706        1856 :         struct rsa_public_key pub;
     707        1856 :         bigint_t c;
     708        1856 :         uint32_t is_err;
     709        1856 :         int ret;
     710        1856 :         nettle_random_func *random_func;
     711             : 
     712        1856 :         if (algo != GNUTLS_PK_RSA || plaintext == NULL) {
     713           0 :                 gnutls_assert();
     714           0 :                 return GNUTLS_E_INTERNAL_ERROR;
     715             :         }
     716             : 
     717        1856 :         _rsa_params_to_privkey(pk_params, &priv);
     718        1856 :         ret = _rsa_params_to_pubkey(pk_params, &pub);
     719        1856 :         if (ret < 0)
     720           0 :                 return gnutls_assert_val(ret);
     721             : 
     722        1856 :         if (ciphertext->size != pub.size)
     723          21 :                 return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
     724             : 
     725        1838 :         if (_gnutls_mpi_init_scan_nz(&c, ciphertext->data,
     726             :                                      ciphertext->size) != 0) {
     727           2 :                 return gnutls_assert_val (GNUTLS_E_MPI_SCAN_FAILED);
     728             :         }
     729             : 
     730        1837 :         if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
     731             :                 random_func = rnd_nonce_func_fallback;
     732             :         else
     733        1837 :                 random_func = rnd_nonce_func;
     734        1837 :         ret = rsa_sec_decrypt(&pub, &priv, NULL, random_func,
     735             :                              plaintext_size, plaintext, TOMPZ(c));
     736             :         /* after this point, any conditional on failure that cause differences
     737             :          * in execution may create a timing or cache access pattern side
     738             :          * channel that can be used as an oracle, so thread very carefully */
     739        1837 :         _gnutls_mpi_release(&c);
     740             :         /* Here HAVE_LIB_ERROR() should be fine as it doesn't have
     741             :          * branches in it and returns a bool */
     742        1837 :         is_err = HAVE_LIB_ERROR();
     743             :         /* if is_err != 0 */
     744        1837 :         is_err = CONSTCHECK_NOT_EQUAL(is_err, 0);
     745             :         /* or ret == 0 */
     746        1837 :         is_err |= CONSTCHECK_EQUAL(ret, 0);
     747             :         /* then return GNUTLS_E_DECRYPTION_FAILED */
     748        1837 :         return (int)((is_err * UINT_MAX) & GNUTLS_E_DECRYPTION_FAILED);
     749             : }
     750             : 
     751             : #define CHECK_INVALID_RSA_PSS_PARAMS(dig_size, salt_size, pub_size, err) \
     752             :         if (unlikely(dig_size + salt_size + 2 > pub_size)) \
     753             :                 return gnutls_assert_val(err)
     754             : 
     755             : static int
     756        4343 : _rsa_pss_sign_digest_tr(gnutls_digest_algorithm_t dig,
     757             :                         const struct rsa_public_key *pub,
     758             :                         const struct rsa_private_key *priv,
     759             :                         void *rnd_ctx, nettle_random_func *rnd_func,
     760             :                         size_t salt_size,
     761             :                         const uint8_t *digest,
     762             :                         mpz_t s)
     763             : {
     764        4343 :         int (*sign_func)(const struct rsa_public_key *,
     765             :                         const struct rsa_private_key *,
     766             :                         void *, nettle_random_func *,
     767             :                         size_t, const uint8_t *,
     768             :                         const uint8_t *,
     769             :                         mpz_t);
     770        4343 :         uint8_t *salt = NULL;
     771        4343 :         size_t hash_size;
     772        4343 :         int ret;
     773             : 
     774        4343 :         switch (dig) {
     775             :         case GNUTLS_DIG_SHA256:
     776             :                 sign_func = rsa_pss_sha256_sign_digest_tr;
     777             :                 hash_size = 32;
     778             :                 break;
     779          23 :         case GNUTLS_DIG_SHA384:
     780          23 :                 sign_func = rsa_pss_sha384_sign_digest_tr;
     781          23 :                 hash_size = 48;
     782          23 :                 break;
     783          16 :         case GNUTLS_DIG_SHA512:
     784          16 :                 sign_func = rsa_pss_sha512_sign_digest_tr;
     785          16 :                 hash_size = 64;
     786          16 :                 break;
     787           0 :         default:
     788           0 :                 gnutls_assert();
     789             :                 return GNUTLS_E_UNKNOWN_ALGORITHM;
     790             :         }
     791             : 
     792             :         /* This is also checked in pss_encode_mgf1, but error out earlier.  */
     793        4343 :         CHECK_INVALID_RSA_PSS_PARAMS(hash_size, salt_size, pub->size, GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
     794             : 
     795        4343 :         if (salt_size > 0) {
     796        4343 :                 salt = gnutls_malloc(salt_size);
     797        4343 :                 if (salt == NULL)
     798           0 :                         return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     799             : 
     800        4343 :                 ret = gnutls_rnd(GNUTLS_RND_NONCE, salt, salt_size);
     801        4343 :                 if (ret < 0) {
     802           0 :                         gnutls_assert();
     803           0 :                         goto cleanup;
     804             :                 }
     805             :         }
     806             : 
     807        4343 :         ret = sign_func(pub, priv, rnd_ctx, rnd_func, salt_size, salt,
     808             :                         digest, s);
     809        4343 :         if (ret == 0) {
     810           0 :                 gnutls_assert();
     811             :                 ret = GNUTLS_E_PK_SIGN_FAILED;
     812             :         } else
     813             :                 ret = 0;
     814             : 
     815        4343 :  cleanup:
     816        4343 :         gnutls_free(salt);
     817        4343 :         return ret;
     818             : }
     819             : 
     820             : static inline gnutls_ecc_curve_t
     821        8315 : get_eddsa_curve(gnutls_pk_algorithm_t algo)
     822             : {
     823        8315 :         switch (algo) {
     824             :         case GNUTLS_PK_EDDSA_ED25519:
     825             :                 return GNUTLS_ECC_CURVE_ED25519;
     826        3355 :         case GNUTLS_PK_EDDSA_ED448:
     827        3355 :                 return GNUTLS_ECC_CURVE_ED448;
     828             :         default:
     829           0 :                 return gnutls_assert_val(GNUTLS_ECC_CURVE_INVALID);
     830             :         }
     831             : }
     832             : 
     833             : static inline int
     834          31 : eddsa_sign(gnutls_pk_algorithm_t algo,
     835             :            const uint8_t *pub,
     836             :            const uint8_t *priv,
     837             :            size_t length, const uint8_t *msg,
     838             :            uint8_t *signature)
     839             : {
     840          31 :         switch (algo) {
     841          26 :         case GNUTLS_PK_EDDSA_ED25519:
     842          26 :                 ed25519_sha512_sign(pub, priv, length, msg, signature);
     843          26 :                 return 0;
     844           5 :         case GNUTLS_PK_EDDSA_ED448:
     845           5 :                 ed448_shake256_sign(pub, priv, length, msg, signature);
     846           5 :                 return 0;
     847             :         default:
     848           0 :                 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
     849             :         }
     850             : }
     851             : 
     852             : /* This is the lower-level part of privkey_sign_raw_data().
     853             :  *
     854             :  * It accepts data in the appropriate hash form, i.e., DigestInfo
     855             :  * for PK_RSA, hash for PK_ECDSA, PK_DSA, PK_RSA_PSS, and raw data
     856             :  * for Ed25519 and Ed448.
     857             :  *
     858             :  * in case of EC/DSA, signed data are encoded into r,s values
     859             :  */
     860             : static int
     861       16682 : _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
     862             :                      gnutls_datum_t * signature,
     863             :                      const gnutls_datum_t * vdata,
     864             :                      const gnutls_pk_params_st * pk_params,
     865             :                      const gnutls_x509_spki_st * sign_params)
     866             : {
     867       16682 :         int ret;
     868       16682 :         unsigned int hash_len;
     869       16682 :         const mac_entry_st *me;
     870             : 
     871       16682 :         if (IS_EC(algo)) {
     872             :                 /* check if the curve relates to the algorithm used */
     873        3500 :                 if (gnutls_ecc_curve_get_pk(pk_params->curve) != algo)
     874           0 :                         return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
     875             :         }
     876             : 
     877             :         /* deterministic ECDSA/DSA is prohibited under FIPS except in
     878             :          * the selftests */
     879       16682 :         if (_gnutls_fips_mode_enabled() &&
     880             :             _gnutls_get_lib_state() != LIB_STATE_SELFTEST &&
     881             :             (algo == GNUTLS_PK_DSA || algo == GNUTLS_PK_ECDSA) &&
     882             :             (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE))
     883             :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     884             : 
     885       16682 :         switch (algo) {
     886          31 :         case GNUTLS_PK_EDDSA_ED25519:   /* we do EdDSA */
     887             :         case GNUTLS_PK_EDDSA_ED448:
     888             :                 {
     889          31 :                         const gnutls_ecc_curve_entry_st *e;
     890             : 
     891          31 :                         if (unlikely(get_eddsa_curve(algo) != pk_params->curve))
     892           0 :                                 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
     893             : 
     894          31 :                         e = _gnutls_ecc_curve_get_params(pk_params->curve);
     895          31 :                         if (e == NULL)
     896           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     897             : 
     898          31 :                         signature->data = gnutls_malloc(e->sig_size);
     899          31 :                         if (signature->data == NULL) {
     900           0 :                                 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     901           0 :                                 goto cleanup;
     902             :                         }
     903             : 
     904          31 :                         signature->size = e->sig_size;
     905             : 
     906          31 :                         if (pk_params->raw_pub.size != e->size || pk_params->raw_priv.size != e->size) {
     907           0 :                                 ret = gnutls_assert_val(GNUTLS_E_PK_SIGN_FAILED);
     908           0 :                                 goto cleanup;
     909             :                         }
     910             : 
     911          62 :                         ret = eddsa_sign(algo,
     912          31 :                                          pk_params->raw_pub.data,
     913          31 :                                          pk_params->raw_priv.data,
     914          31 :                                          vdata->size, vdata->data,
     915             :                                          signature->data);
     916          31 :                         if (ret < 0)
     917           0 :                                 goto cleanup;
     918             : 
     919             :                         break;
     920             :                 }
     921             : #if ENABLE_GOST
     922         549 :         case GNUTLS_PK_GOST_01:
     923             :         case GNUTLS_PK_GOST_12_256:
     924             :         case GNUTLS_PK_GOST_12_512:
     925             :                 {
     926         549 :                         struct ecc_scalar priv;
     927         549 :                         struct dsa_signature sig;
     928         549 :                         const struct ecc_curve *curve;
     929             : 
     930         549 :                         curve = get_supported_gost_curve(pk_params->curve);
     931         549 :                         if (curve == NULL)
     932           0 :                                 return
     933           0 :                                     gnutls_assert_val
     934             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
     935             : 
     936         549 :                         ret =
     937         549 :                             _ecc_params_to_privkey(pk_params, &priv,
     938             :                                                    curve);
     939         549 :                         if (ret < 0)
     940           0 :                                 return gnutls_assert_val(ret);
     941             : 
     942             :                         /* This call will return a valid MAC entry and
     943             :                          * getters will check that is not null anyway. */
     944         549 :                         me = hash_to_entry(_gnutls_gost_digest(pk_params->algo));
     945        1098 :                         if (_gnutls_mac_get_algo_len(me) != vdata->size) {
     946           0 :                                 gnutls_assert();
     947           0 :                                 _gnutls_debug_log
     948             :                                     ("Security level of algorithm requires hash %s(%zd)\n",
     949             :                                      _gnutls_mac_get_name(me),
     950             :                                      _gnutls_mac_get_algo_len(me));
     951           0 :                                 return GNUTLS_E_INVALID_REQUEST;
     952             :                         }
     953             : 
     954         549 :                         dsa_signature_init(&sig);
     955             : 
     956         549 :                         gostdsa_sign(&priv, NULL, rnd_tmpkey_func,
     957         549 :                                      vdata->size, vdata->data, &sig);
     958             : 
     959         549 :                         ret =
     960        1098 :                             _gnutls_encode_gost_rs(signature, &sig.r, &sig.s,
     961         549 :                                                    (ecc_bit_size(curve) + 7) / 8);
     962             : 
     963         549 :                         dsa_signature_clear(&sig);
     964         549 :                         ecc_scalar_zclear(&priv);
     965             : 
     966         549 :                         if (ret < 0) {
     967           0 :                                 gnutls_assert();
     968           0 :                                 goto cleanup;
     969             :                         }
     970         549 :                         break;
     971             :                 }
     972             : #endif
     973        3469 :         case GNUTLS_PK_ECDSA:   /* we do ECDSA */
     974             :                 {
     975        3469 :                         struct ecc_scalar priv;
     976        3469 :                         struct dsa_signature sig;
     977        3469 :                         int curve_id = pk_params->curve;
     978        3469 :                         const struct ecc_curve *curve;
     979        3469 :                         mpz_t k;
     980        3469 :                         void *random_ctx;
     981        3469 :                         nettle_random_func *random_func;
     982             : 
     983        3469 :                         curve = get_supported_nist_curve(curve_id);
     984        3469 :                         if (curve == NULL)
     985           0 :                                 return
     986           0 :                                     gnutls_assert_val
     987             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
     988             : 
     989        3469 :                         ret =
     990        3469 :                             _ecc_params_to_privkey(pk_params, &priv,
     991             :                                                    curve);
     992        3469 :                         if (ret < 0)
     993           0 :                                 return gnutls_assert_val(ret);
     994             : 
     995        3469 :                         dsa_signature_init(&sig);
     996             : 
     997        3469 :                         me = _gnutls_dsa_q_to_hash(pk_params,
     998             :                                                    &hash_len);
     999             : 
    1000        3469 :                         if (hash_len > vdata->size) {
    1001         433 :                                 gnutls_assert();
    1002         450 :                                 _gnutls_debug_log
    1003             :                                     ("Security level of algorithm requires hash %s(%d) or better\n",
    1004             :                                      _gnutls_mac_get_name(me), hash_len);
    1005         433 :                                 hash_len = vdata->size;
    1006             :                         }
    1007             : 
    1008        3469 :                         mpz_init(k);
    1009        3469 :                         if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST ||
    1010        3469 :                             (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) {
    1011          20 :                                 ret = _gnutls_ecdsa_compute_k(k,
    1012             :                                                               curve_id,
    1013          10 :                                                               pk_params->params[ECC_K],
    1014          10 :                                                               DIG_TO_MAC(sign_params->dsa_dig),
    1015          10 :                                                               vdata->data,
    1016          10 :                                                               vdata->size);
    1017          10 :                                 if (ret < 0)
    1018           0 :                                         goto ecdsa_cleanup;
    1019             :                                 random_ctx = &k;
    1020             :                                 random_func = rnd_mpz_func;
    1021             :                         } else {
    1022             :                                 random_ctx = NULL;
    1023             :                                 random_func = rnd_nonce_func;
    1024             :                         }
    1025        3469 :                         ecdsa_sign(&priv, random_ctx, random_func, hash_len,
    1026        3469 :                                    vdata->data, &sig);
    1027             : 
    1028             :                         /* prevent memory leaks */
    1029        3469 :                         if (HAVE_LIB_ERROR()) {
    1030           0 :                                 ret = GNUTLS_E_LIB_IN_ERROR_STATE;
    1031           0 :                                 goto ecdsa_cleanup;
    1032             :                         }
    1033             : 
    1034        3469 :                         ret =
    1035        3469 :                             _gnutls_encode_ber_rs(signature, &sig.r,
    1036             :                                                   &sig.s);
    1037             : 
    1038        3469 :  ecdsa_cleanup:
    1039        3469 :                         dsa_signature_clear(&sig);
    1040        3469 :                         ecc_scalar_zclear(&priv);
    1041        3469 :                         mpz_clear(k);
    1042             : 
    1043        3469 :                         if (ret < 0) {
    1044           0 :                                 gnutls_assert();
    1045           0 :                                 goto cleanup;
    1046             :                         }
    1047        3469 :                         break;
    1048             :                 }
    1049          80 :         case GNUTLS_PK_DSA:
    1050             :                 {
    1051          80 :                         struct dsa_params pub;
    1052          80 :                         bigint_t priv;
    1053          80 :                         struct dsa_signature sig;
    1054          80 :                         mpz_t k;
    1055          80 :                         void *random_ctx;
    1056          80 :                         nettle_random_func *random_func;
    1057             : 
    1058          80 :                         memset(&priv, 0, sizeof(priv));
    1059          80 :                         memset(&pub, 0, sizeof(pub));
    1060          80 :                         _dsa_params_get(pk_params, &pub);
    1061             : 
    1062          80 :                         priv = pk_params->params[DSA_X];
    1063             : 
    1064          80 :                         dsa_signature_init(&sig);
    1065             : 
    1066          80 :                         me = _gnutls_dsa_q_to_hash(pk_params,
    1067             :                                                    &hash_len);
    1068             : 
    1069          80 :                         if (hash_len > vdata->size) {
    1070           4 :                                 gnutls_assert();
    1071           4 :                                 _gnutls_debug_log
    1072             :                                     ("Security level of algorithm requires hash %s(%d) or better (have: %d)\n",
    1073             :                                      _gnutls_mac_get_name(me), hash_len, (int)vdata->size);
    1074           4 :                                 hash_len = vdata->size;
    1075             :                         }
    1076             : 
    1077          80 :                         mpz_init(k);
    1078          80 :                         if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST ||
    1079          80 :                             (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) {
    1080           6 :                                 ret = _gnutls_dsa_compute_k(k,
    1081             :                                                             pub.q,
    1082             :                                                             TOMPZ(priv),
    1083           3 :                                                             DIG_TO_MAC(sign_params->dsa_dig),
    1084           3 :                                                             vdata->data,
    1085           3 :                                                             vdata->size);
    1086           3 :                                 if (ret < 0)
    1087           0 :                                         goto dsa_fail;
    1088             :                                 /* cancel-out dsa_sign's addition of 1 to random data */
    1089           3 :                                 mpz_sub_ui (k, k, 1);
    1090           3 :                                 random_ctx = &k;
    1091           3 :                                 random_func = rnd_mpz_func;
    1092             :                         } else {
    1093             :                                 random_ctx = NULL;
    1094             :                                 random_func = rnd_nonce_func;
    1095             :                         }
    1096          80 :                         ret =
    1097         160 :                             dsa_sign(&pub, TOMPZ(priv), random_ctx, random_func,
    1098          80 :                                      hash_len, vdata->data, &sig);
    1099          80 :                         if (ret == 0 || HAVE_LIB_ERROR()) {
    1100           1 :                                 gnutls_assert();
    1101           1 :                                 ret = GNUTLS_E_PK_SIGN_FAILED;
    1102           1 :                                 goto dsa_fail;
    1103             :                         }
    1104             : 
    1105          79 :                         ret =
    1106          79 :                             _gnutls_encode_ber_rs(signature, &sig.r,
    1107             :                                                   &sig.s);
    1108             : 
    1109          80 :  dsa_fail:
    1110          80 :                         dsa_signature_clear(&sig);
    1111          80 :                         mpz_clear(k);
    1112             : 
    1113          80 :                         if (ret < 0) {
    1114           1 :                                 gnutls_assert();
    1115           1 :                                 goto cleanup;
    1116             :                         }
    1117          79 :                         break;
    1118             :                 }
    1119        8210 :         case GNUTLS_PK_RSA:
    1120             :                 {
    1121        8210 :                         struct rsa_private_key priv;
    1122        8210 :                         struct rsa_public_key pub;
    1123        8210 :                         nettle_random_func *random_func;
    1124        8210 :                         mpz_t s;
    1125             : 
    1126        8210 :                         _rsa_params_to_privkey(pk_params, &priv);
    1127        8210 :                         ret = _rsa_params_to_pubkey(pk_params, &pub);
    1128        8210 :                         if (ret < 0)
    1129           0 :                                 return
    1130           0 :                                     gnutls_assert_val(ret);
    1131             : 
    1132        8210 :                         mpz_init(s);
    1133             : 
    1134        8210 :                         if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
    1135             :                                 random_func = rnd_nonce_func_fallback;
    1136             :                         else
    1137        8210 :                                 random_func = rnd_nonce_func;
    1138        8210 :                         ret =
    1139       16420 :                             rsa_pkcs1_sign_tr(&pub, &priv, NULL, random_func,
    1140        8210 :                                               vdata->size, vdata->data, s);
    1141        8210 :                         if (ret == 0 || HAVE_LIB_ERROR()) {
    1142           1 :                                 gnutls_assert();
    1143           1 :                                 ret = GNUTLS_E_PK_SIGN_FAILED;
    1144           1 :                                 goto rsa_fail;
    1145             :                         }
    1146             : 
    1147        8209 :                         ret =
    1148        8209 :                             _gnutls_mpi_dprint_size(s, signature,
    1149             :                                                     pub.size);
    1150             : 
    1151        8210 :                       rsa_fail:
    1152        8210 :                         mpz_clear(s);
    1153             : 
    1154        8210 :                         if (ret < 0) {
    1155           1 :                                 gnutls_assert();
    1156           1 :                                 goto cleanup;
    1157             :                         }
    1158             : 
    1159        8209 :                         break;
    1160             :                 }
    1161        4343 :         case GNUTLS_PK_RSA_PSS:
    1162             :                 {
    1163        4343 :                         struct rsa_private_key priv;
    1164        4343 :                         struct rsa_public_key pub;
    1165        4343 :                         mpz_t s;
    1166             : 
    1167        4343 :                         _rsa_params_to_privkey(pk_params, &priv);
    1168        4343 :                         ret = _rsa_params_to_pubkey(pk_params, &pub);
    1169        4343 :                         if (ret < 0)
    1170           0 :                                 return
    1171           0 :                                     gnutls_assert_val(ret);
    1172             : 
    1173        4343 :                         mpz_init(s);
    1174             : 
    1175        4343 :                         ret =
    1176        8686 :                             _rsa_pss_sign_digest_tr(sign_params->rsa_pss_dig,
    1177             :                                                     &pub, &priv,
    1178             :                                                     NULL, rnd_nonce_func,
    1179        4343 :                                                     sign_params->salt_size,
    1180        4343 :                                                     vdata->data, s);
    1181        4343 :                         if (ret < 0) {
    1182           0 :                                 gnutls_assert();
    1183           0 :                                 ret = GNUTLS_E_PK_SIGN_FAILED;
    1184           0 :                                 goto rsa_pss_fail;
    1185             :                         }
    1186             : 
    1187        4343 :                         ret =
    1188        4343 :                             _gnutls_mpi_dprint_size(s, signature,
    1189             :                                                     pub.size);
    1190             : 
    1191        4343 :                       rsa_pss_fail:
    1192        4343 :                         mpz_clear(s);
    1193             : 
    1194        4343 :                         if (ret < 0) {
    1195           0 :                                 gnutls_assert();
    1196           0 :                                 goto cleanup;
    1197             :                         }
    1198             : 
    1199        4343 :                         break;
    1200             :                 }
    1201           0 :         default:
    1202           0 :                 gnutls_assert();
    1203           0 :                 ret = GNUTLS_E_INTERNAL_ERROR;
    1204           0 :                 goto cleanup;
    1205             :         }
    1206             : 
    1207             :         ret = 0;
    1208             : 
    1209       16682 :       cleanup:
    1210             : 
    1211       16682 :         FAIL_IF_LIB_ERROR;
    1212             :         return ret;
    1213             : }
    1214             : 
    1215             : static int
    1216        1199 : _rsa_pss_verify_digest(gnutls_digest_algorithm_t dig,
    1217             :                        const struct rsa_public_key *pub,
    1218             :                        size_t salt_size,
    1219             :                        const uint8_t *digest,
    1220             :                        size_t digest_size,
    1221             :                        const mpz_t s)
    1222             : {
    1223        1199 :         int (*verify_func) (const struct rsa_public_key *,
    1224             :                             size_t,
    1225             :                             const uint8_t *,
    1226             :                             const mpz_t);
    1227        1199 :         size_t hash_size;
    1228             : 
    1229        1199 :         switch (dig) {
    1230             :         case GNUTLS_DIG_SHA256:
    1231             :                 verify_func = rsa_pss_sha256_verify_digest;
    1232             :                 hash_size = 32;
    1233             :                 break;
    1234          15 :         case GNUTLS_DIG_SHA384:
    1235          15 :                 verify_func = rsa_pss_sha384_verify_digest;
    1236          15 :                 hash_size = 48;
    1237          15 :                 break;
    1238          15 :         case GNUTLS_DIG_SHA512:
    1239          15 :                 verify_func = rsa_pss_sha512_verify_digest;
    1240          15 :                 hash_size = 64;
    1241          15 :                 break;
    1242           0 :         default:
    1243           0 :                 gnutls_assert();
    1244             :                 return 0;
    1245             :         }
    1246             : 
    1247        1199 :         if (digest_size != hash_size)
    1248           0 :                 return gnutls_assert_val(0);
    1249             : 
    1250        1199 :         CHECK_INVALID_RSA_PSS_PARAMS(hash_size, salt_size, pub->size, 0);
    1251             : 
    1252        1199 :         return verify_func(pub, salt_size, digest, s);
    1253             : }
    1254             : 
    1255             : static inline int
    1256          84 : eddsa_verify(gnutls_pk_algorithm_t algo,
    1257             :              const uint8_t *pub,
    1258             :              size_t length, const uint8_t *msg,
    1259             :              const uint8_t *signature)
    1260             : {
    1261          84 :         int ret;
    1262             : 
    1263          84 :         switch (algo) {
    1264          78 :         case GNUTLS_PK_EDDSA_ED25519:
    1265          78 :                 ret = ed25519_sha512_verify(pub, length, msg, signature);
    1266          78 :                 if (ret == 0)
    1267           4 :                         return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
    1268             :                 return 0;
    1269           6 :         case GNUTLS_PK_EDDSA_ED448:
    1270           6 :                 ret = ed448_shake256_verify(pub, length, msg, signature);
    1271           6 :                 if (ret == 0)
    1272           0 :                         return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
    1273             :                 return 0;
    1274             :         default:
    1275           0 :                 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
    1276             :         }
    1277             : }
    1278             : 
    1279             : static int
    1280       15727 : _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
    1281             :                        const gnutls_datum_t * vdata,
    1282             :                        const gnutls_datum_t * signature,
    1283             :                        const gnutls_pk_params_st * pk_params,
    1284             :                        const gnutls_x509_spki_st * sign_params)
    1285             : {
    1286       15727 :         int ret;
    1287       15727 :         unsigned int hash_len;
    1288       15727 :         bigint_t tmp[2] = { NULL, NULL };
    1289             : 
    1290       15727 :         if (IS_EC(algo)) {
    1291             :                 /* check if the curve relates to the algorithm used */
    1292        4985 :                 if (gnutls_ecc_curve_get_pk(pk_params->curve) != algo)
    1293           0 :                         return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    1294             :         }
    1295             : 
    1296       15727 :         switch (algo) {
    1297          84 :         case GNUTLS_PK_EDDSA_ED25519:   /* we do EdDSA */
    1298             :         case GNUTLS_PK_EDDSA_ED448:
    1299             :                 {
    1300          84 :                         const gnutls_ecc_curve_entry_st *e;
    1301             : 
    1302          84 :                         if (unlikely(get_eddsa_curve(algo) != pk_params->curve))
    1303           0 :                                 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    1304             : 
    1305          84 :                         e = _gnutls_ecc_curve_get_params(pk_params->curve);
    1306          84 :                         if (e == NULL)
    1307           0 :                                 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    1308             : 
    1309          84 :                         if (signature->size != e->sig_size)
    1310           0 :                                 return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
    1311             : 
    1312          84 :                         if (pk_params->raw_pub.size != e->size)
    1313           0 :                                 return gnutls_assert_val(GNUTLS_E_PK_SIGN_FAILED);
    1314             : 
    1315          84 :                         ret = eddsa_verify(algo,
    1316          84 :                                            pk_params->raw_pub.data,
    1317          84 :                                            vdata->size, vdata->data,
    1318          84 :                                            signature->data);
    1319          84 :                         break;
    1320             :                 }
    1321             : #if ENABLE_GOST
    1322        2066 :         case GNUTLS_PK_GOST_01:
    1323             :         case GNUTLS_PK_GOST_12_256:
    1324             :         case GNUTLS_PK_GOST_12_512:
    1325             :                 {
    1326        2066 :                         struct ecc_point pub;
    1327        2066 :                         struct dsa_signature sig;
    1328        2066 :                         const struct ecc_curve *curve;
    1329        2066 :                         const mac_entry_st *me;
    1330             : 
    1331        2066 :                         curve = get_supported_gost_curve(pk_params->curve);
    1332        2066 :                         if (curve == NULL)
    1333           0 :                                 return
    1334        1000 :                                     gnutls_assert_val
    1335             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    1336             : 
    1337             :                         /* This call will return a valid MAC entry and
    1338             :                          * getters will check that is not null anyway. */
    1339        2066 :                         me = hash_to_entry(_gnutls_gost_digest(pk_params->algo));
    1340        4132 :                         if (_gnutls_mac_get_algo_len(me) != vdata->size)
    1341        1000 :                                 return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
    1342             : 
    1343        1066 :                         ret =
    1344        1066 :                             _gnutls_decode_gost_rs(signature, &tmp[0],
    1345             :                                                   &tmp[1]);
    1346        1066 :                         if (ret < 0)
    1347           0 :                                 return gnutls_assert_val(ret);
    1348             : 
    1349        1066 :                         ret =
    1350        1066 :                             _gost_params_to_pubkey(pk_params, &pub, curve);
    1351        1066 :                         if (ret < 0) {
    1352           0 :                                 gnutls_assert();
    1353           0 :                                 goto cleanup;
    1354             :                         }
    1355             : 
    1356        1066 :                         memcpy(sig.r, tmp[0], SIZEOF_MPZT);
    1357        1066 :                         memcpy(sig.s, tmp[1], SIZEOF_MPZT);
    1358             : 
    1359        1066 :                         ret = gostdsa_verify(&pub, vdata->size, vdata->data, &sig);
    1360        1066 :                         if (ret == 0) {
    1361           6 :                                 gnutls_assert();
    1362             :                                 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
    1363             :                         } else
    1364             :                                 ret = 0;
    1365             : 
    1366        1066 :                         ecc_point_clear(&pub);
    1367        1066 :                         break;
    1368             :                 }
    1369             : #endif
    1370        4901 :         case GNUTLS_PK_ECDSA:   /* ECDSA */
    1371             :                 {
    1372        4901 :                         struct ecc_point pub;
    1373        4901 :                         struct dsa_signature sig;
    1374        4901 :                         int curve_id = pk_params->curve;
    1375        4901 :                         const struct ecc_curve *curve;
    1376             : 
    1377        4901 :                         curve = get_supported_nist_curve(curve_id);
    1378        4901 :                         if (curve == NULL)
    1379           0 :                                 return
    1380           2 :                                     gnutls_assert_val
    1381             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    1382             : 
    1383        4901 :                         ret =
    1384        4901 :                             _gnutls_decode_ber_rs(signature, &tmp[0],
    1385             :                                                   &tmp[1]);
    1386        4901 :                         if (ret < 0)
    1387           2 :                                 return gnutls_assert_val(ret);
    1388             : 
    1389        4899 :                         ret =
    1390        4899 :                             _ecc_params_to_pubkey(pk_params, &pub, curve);
    1391        4899 :                         if (ret < 0) {
    1392           3 :                                 gnutls_assert();
    1393           3 :                                 goto cleanup;
    1394             :                         }
    1395             : 
    1396        4896 :                         memcpy(sig.r, tmp[0], SIZEOF_MPZT);
    1397        4896 :                         memcpy(sig.s, tmp[1], SIZEOF_MPZT);
    1398             : 
    1399        4896 :                         _gnutls_dsa_q_to_hash(pk_params, &hash_len);
    1400             : 
    1401        4896 :                         if (hash_len > vdata->size)
    1402        1518 :                                 hash_len = vdata->size;
    1403             : 
    1404        4896 :                         ret =
    1405        4896 :                             ecdsa_verify(&pub, hash_len, vdata->data,
    1406             :                                          &sig);
    1407        4896 :                         if (ret == 0) {
    1408         840 :                                 gnutls_assert();
    1409             :                                 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
    1410             :                         } else
    1411             :                                 ret = 0;
    1412             : 
    1413        4896 :                         ecc_point_clear(&pub);
    1414        4896 :                         break;
    1415             :                 }
    1416          78 :         case GNUTLS_PK_DSA:
    1417             :                 {
    1418          78 :                         struct dsa_params pub;
    1419          78 :                         struct dsa_signature sig;
    1420          78 :                         bigint_t y;
    1421             : 
    1422          78 :                         ret =
    1423          78 :                             _gnutls_decode_ber_rs(signature, &tmp[0],
    1424             :                                                   &tmp[1]);
    1425          78 :                         if (ret < 0) {
    1426           1 :                                 gnutls_assert();
    1427           1 :                                 goto cleanup;
    1428             :                         }
    1429          77 :                         memset(&pub, 0, sizeof(pub));
    1430          77 :                         _dsa_params_get(pk_params, &pub);
    1431          77 :                         y = pk_params->params[DSA_Y];
    1432             : 
    1433          77 :                         memcpy(sig.r, tmp[0], SIZEOF_MPZT);
    1434          77 :                         memcpy(sig.s, tmp[1], SIZEOF_MPZT);
    1435             : 
    1436          77 :                         _gnutls_dsa_q_to_hash(pk_params, &hash_len);
    1437             : 
    1438          77 :                         if (hash_len > vdata->size)
    1439           4 :                                 hash_len = vdata->size;
    1440             : 
    1441          77 :                         ret =
    1442          77 :                             dsa_verify(&pub, TOMPZ(y), hash_len, vdata->data, &sig);
    1443          77 :                         if (ret == 0) {
    1444           6 :                                 gnutls_assert();
    1445             :                                 ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
    1446             :                         } else
    1447             :                                 ret = 0;
    1448             : 
    1449          77 :                         break;
    1450             :                 }
    1451        7394 :         case GNUTLS_PK_RSA:
    1452             :                 {
    1453        7394 :                         struct rsa_public_key pub;
    1454             : 
    1455        7394 :                         ret = _rsa_params_to_pubkey(pk_params, &pub);
    1456        7394 :                         if (ret < 0)
    1457           3 :                                 return
    1458           9 :                                     gnutls_assert_val(ret);
    1459             : 
    1460        7391 :                         if (signature->size != pub.size)
    1461           6 :                                 return
    1462           6 :                                     gnutls_assert_val
    1463             :                                     (GNUTLS_E_PK_SIG_VERIFY_FAILED);
    1464             : 
    1465        7385 :                         ret =
    1466        7385 :                             _gnutls_mpi_init_scan_nz(&tmp[0], signature->data,
    1467             :                                                 signature->size);
    1468        7385 :                         if (ret < 0) {
    1469           1 :                                 gnutls_assert();
    1470           1 :                                 goto cleanup;
    1471             :                         }
    1472             : 
    1473        7384 :                         ret =
    1474       14768 :                             rsa_pkcs1_verify(&pub, vdata->size,
    1475        7384 :                                              vdata->data, TOMPZ(tmp[0]));
    1476        7384 :                         if (ret == 0)
    1477         236 :                                 ret =
    1478        7384 :                                     gnutls_assert_val
    1479             :                                     (GNUTLS_E_PK_SIG_VERIFY_FAILED);
    1480             :                         else
    1481             :                                 ret = 0;
    1482             : 
    1483        7384 :                         break;
    1484             :                 }
    1485        1204 :         case GNUTLS_PK_RSA_PSS:
    1486             :                 {
    1487        1204 :                         struct rsa_public_key pub;
    1488             : 
    1489        1204 :                         ret = _rsa_params_to_pubkey(pk_params, &pub);
    1490        1204 :                         if (ret < 0)
    1491           1 :                                 return
    1492           4 :                                     gnutls_assert_val(ret);
    1493             : 
    1494        1203 :                         if (signature->size != pub.size)
    1495           3 :                                 return
    1496           3 :                                     gnutls_assert_val
    1497             :                                     (GNUTLS_E_PK_SIG_VERIFY_FAILED);
    1498             : 
    1499        1200 :                         ret =
    1500        1200 :                             _gnutls_mpi_init_scan_nz(&tmp[0], signature->data,
    1501             :                                                      signature->size);
    1502        1200 :                         if (ret < 0) {
    1503           1 :                                 gnutls_assert();
    1504           1 :                                 goto cleanup;
    1505             :                         }
    1506             : 
    1507        2398 :                         ret = _rsa_pss_verify_digest(sign_params->rsa_pss_dig,
    1508             :                                                      &pub,
    1509        1199 :                                                      sign_params->salt_size,
    1510        1199 :                                                      vdata->data, vdata->size,
    1511        1199 :                                                      TOMPZ(tmp[0]));
    1512        1199 :                         if (ret == 0)
    1513         222 :                                 ret =
    1514        1199 :                                     gnutls_assert_val
    1515             :                                     (GNUTLS_E_PK_SIG_VERIFY_FAILED);
    1516             :                         else
    1517             :                                 ret = 0;
    1518             : 
    1519        1199 :                         break;
    1520             :                 }
    1521           0 :         default:
    1522           0 :                 gnutls_assert();
    1523           0 :                 ret = GNUTLS_E_INTERNAL_ERROR;
    1524           0 :                 goto cleanup;
    1525             :         }
    1526             : 
    1527       14712 :       cleanup:
    1528             : 
    1529       14712 :         _gnutls_mpi_release(&tmp[0]);
    1530       14712 :         _gnutls_mpi_release(&tmp[1]);
    1531       14712 :         FAIL_IF_LIB_ERROR;
    1532             :         return ret;
    1533             : }
    1534             : 
    1535      180838 : static inline const struct ecc_curve *get_supported_nist_curve(int curve)
    1536             : {
    1537      180838 :         switch (curve) {
    1538             : #ifdef ENABLE_NON_SUITEB_CURVES
    1539             :         case GNUTLS_ECC_CURVE_SECP192R1:
    1540             :                 return nettle_get_secp_192r1();
    1541             :         case GNUTLS_ECC_CURVE_SECP224R1:
    1542             :                 return nettle_get_secp_224r1();
    1543             : #endif
    1544       83907 :         case GNUTLS_ECC_CURVE_SECP256R1:
    1545       83907 :                 return nettle_get_secp_256r1();
    1546       45825 :         case GNUTLS_ECC_CURVE_SECP384R1:
    1547       45825 :                 return nettle_get_secp_384r1();
    1548       45437 :         case GNUTLS_ECC_CURVE_SECP521R1:
    1549       45437 :                 return nettle_get_secp_521r1();
    1550             :         default:
    1551             :                 return NULL;
    1552             :         }
    1553             : }
    1554             : 
    1555             : static inline const char *get_supported_nist_curve_order(int curve)
    1556             : {
    1557             :         static const struct {
    1558             :                 int curve;
    1559             :                 const char *order;
    1560             :         } orders[] = {
    1561             : #ifdef ENABLE_NON_SUITEB_CURVES
    1562             :                 { GNUTLS_ECC_CURVE_SECP192R1,
    1563             :                   "ffffffffffffffffffffffff99def836"
    1564             :                   "146bc9b1b4d22831" },
    1565             :                 { GNUTLS_ECC_CURVE_SECP224R1,
    1566             :                   "ffffffffffffffffffffffffffff16a2"
    1567             :                   "e0b8f03e13dd29455c5c2a3d" },
    1568             : #endif
    1569             :                 { GNUTLS_ECC_CURVE_SECP256R1,
    1570             :                   "ffffffff00000000ffffffffffffffff"
    1571             :                   "bce6faada7179e84f3b9cac2fc632551" },
    1572             :                 { GNUTLS_ECC_CURVE_SECP384R1,
    1573             :                   "ffffffffffffffffffffffffffffffff"
    1574             :                   "ffffffffffffffffc7634d81f4372ddf"
    1575             :                   "581a0db248b0a77aecec196accc52973" },
    1576             :                 { GNUTLS_ECC_CURVE_SECP521R1,
    1577             :                   "1fffffffffffffffffffffffffffffff"
    1578             :                   "ffffffffffffffffffffffffffffffff"
    1579             :                   "ffa51868783bf2f966b7fcc0148f709a"
    1580             :                   "5d03bb5c9b8899c47aebb6fb71e91386"
    1581             :                   "409" },
    1582             :         };
    1583             :         size_t i;
    1584             : 
    1585             :         for (i = 0; i < sizeof(orders)/sizeof(orders[0]); i++) {
    1586             :                 if (orders[i].curve == curve)
    1587             :                         return orders[i].order;
    1588             :         }
    1589             :         return NULL;
    1590             : }
    1591             : 
    1592             : static inline const char *get_supported_nist_curve_modulus(int curve)
    1593             : {
    1594             :         static const struct {
    1595             :                 int curve;
    1596             :                 const char *order;
    1597             :         } orders[] = {
    1598             : #ifdef ENABLE_NON_SUITEB_CURVES
    1599             :                 { GNUTLS_ECC_CURVE_SECP192R1,
    1600             :                   "fffffffffffffffffffffffffffffffe"
    1601             :                   "ffffffffffffffff" },
    1602             :                 { GNUTLS_ECC_CURVE_SECP224R1,
    1603             :                   "ffffffffffffffffffffffffffffffff"
    1604             :                   "000000000000000000000001" },
    1605             : #endif
    1606             :                 { GNUTLS_ECC_CURVE_SECP256R1,
    1607             :                   "ffffffff000000010000000000000000"
    1608             :                   "00000000ffffffffffffffffffffffff" },
    1609             :                 { GNUTLS_ECC_CURVE_SECP384R1,
    1610             :                   "ffffffffffffffffffffffffffffffff"
    1611             :                   "fffffffffffffffffffffffffffffffe"
    1612             :                   "ffffffff0000000000000000ffffffff" },
    1613             :                 { GNUTLS_ECC_CURVE_SECP521R1,
    1614             :                   "1ff"
    1615             :                   "ffffffffffffffffffffffffffffffff"
    1616             :                   "ffffffffffffffffffffffffffffffff"
    1617             :                   "ffffffffffffffffffffffffffffffff"
    1618             :                   "ffffffffffffffffffffffffffffffff" },
    1619             :         };
    1620             :         size_t i;
    1621             : 
    1622             :         for (i = 0; i < sizeof(orders)/sizeof(orders[0]); i++) {
    1623             :                 if (orders[i].curve == curve)
    1624             :                         return orders[i].order;
    1625             :         }
    1626             :         return NULL;
    1627             : }
    1628             : 
    1629        9527 : static inline const struct ecc_curve *get_supported_gost_curve(int curve)
    1630             : {
    1631        9527 :         switch (curve) {
    1632             : #if ENABLE_GOST
    1633        4223 :         case GNUTLS_ECC_CURVE_GOST256CPA:
    1634             :         case GNUTLS_ECC_CURVE_GOST256CPXA:
    1635             :         case GNUTLS_ECC_CURVE_GOST256B:
    1636        4223 :                 return nettle_get_gost_gc256b();
    1637        2050 :         case GNUTLS_ECC_CURVE_GOST512A:
    1638        2050 :                 return nettle_get_gost_gc512a();
    1639             : #endif
    1640             :         default:
    1641             :                 return NULL;
    1642             :         }
    1643             : }
    1644             : 
    1645      255216 : static int _wrap_nettle_pk_curve_exists(gnutls_ecc_curve_t curve)
    1646             : {
    1647      255216 :         switch (curve) {
    1648             :                 case GNUTLS_ECC_CURVE_ED25519:
    1649             :                 case GNUTLS_ECC_CURVE_X25519:
    1650             :                 case GNUTLS_ECC_CURVE_ED448:
    1651             :                 case GNUTLS_ECC_CURVE_X448:
    1652             :                         return 1;
    1653      160273 :                 default:
    1654      160273 :                         return ((get_supported_nist_curve(curve)!=NULL ||
    1655      160273 :                                  get_supported_gost_curve(curve)!=NULL)?1:0);
    1656             :         }
    1657             : }
    1658             : 
    1659             : /* Generates algorithm's parameters. That is:
    1660             :  *  For DSA: p, q, and g are generated.
    1661             :  *  For RSA: nothing
    1662             :  *  For ECDSA/EDDSA: nothing
    1663             :  */
    1664             : static int
    1665        1264 : wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
    1666             :                                unsigned int level /*bits or curve*/ ,
    1667             :                                gnutls_pk_params_st * params)
    1668             : {
    1669        1264 :         int ret;
    1670        1264 :         unsigned int i, q_bits;
    1671             : 
    1672        1264 :         params->algo = algo;
    1673             : 
    1674        1264 :         switch (algo) {
    1675          17 :         case GNUTLS_PK_DSA:
    1676             :         case GNUTLS_PK_DH:
    1677             :                 {
    1678          17 :                         struct dsa_params pub;
    1679          17 :                         struct dss_params_validation_seeds cert;
    1680          17 :                         unsigned index;
    1681             : 
    1682          17 :                         dsa_params_init(&pub);
    1683             : 
    1684          17 :                         if (GNUTLS_BITS_HAVE_SUBGROUP(level)) {
    1685           0 :                                 q_bits = GNUTLS_BITS_TO_SUBGROUP(level);
    1686           0 :                                 level = GNUTLS_BITS_TO_GROUP(level);
    1687             :                         } else {
    1688          17 :                                 q_bits = _gnutls_pk_bits_to_subgroup_bits(level);
    1689             :                         }
    1690             : 
    1691          17 :                         if (q_bits == 0)
    1692           0 :                                 return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
    1693             : 
    1694          17 :                         if (_gnutls_fips_mode_enabled() != 0 || params->pkflags & GNUTLS_PK_FLAG_PROVABLE) {
    1695          11 :                                 if (algo==GNUTLS_PK_DSA)
    1696             :                                         index = 1;
    1697             :                                 else
    1698           0 :                                         index = 2;
    1699             : 
    1700          11 :                                 if (params->palgo != 0 && params->palgo != GNUTLS_DIG_SHA384) {
    1701           0 :                                         ret = GNUTLS_E_INVALID_REQUEST;
    1702           0 :                                         goto dsa_fail;
    1703             :                                 }
    1704             : 
    1705          11 :                                 params->palgo = GNUTLS_DIG_SHA384;
    1706             : 
    1707          11 :                                 if (params->seed_size) {
    1708           9 :                                         ret =
    1709           9 :                                                 _dsa_generate_dss_pqg(&pub, &cert,
    1710           9 :                                                         index, params->seed_size, params->seed,
    1711             :                                                         NULL, NULL, level, q_bits);
    1712             :                                 } else {
    1713           2 :                                         ret =
    1714           2 :                                                 dsa_generate_dss_pqg(&pub, &cert,
    1715             :                                                         index, NULL, rnd_tmpkey_func,
    1716             :                                                         NULL, NULL, level, q_bits);
    1717             :                                 }
    1718          11 :                                 if (ret != 1 || HAVE_LIB_ERROR()) {
    1719           0 :                                         gnutls_assert();
    1720           0 :                                         ret = GNUTLS_E_PK_GENERATION_ERROR;
    1721           0 :                                         goto dsa_fail;
    1722             :                                 }
    1723             : 
    1724          11 :                                 if (cert.seed_length && cert.seed_length < sizeof(params->seed)) {
    1725          11 :                                         params->seed_size = cert.seed_length;
    1726          11 :                                         memcpy(params->seed, cert.seed, cert.seed_length);
    1727             :                                 }
    1728             : 
    1729             :                                 /* verify the generated parameters */
    1730          11 :                                 ret = dsa_validate_dss_pqg(&pub, &cert, index);
    1731          11 :                                 if (ret != 1) {
    1732           0 :                                         gnutls_assert();
    1733           0 :                                         ret = GNUTLS_E_PK_GENERATION_ERROR;
    1734           0 :                                         goto dsa_fail;
    1735             :                                 }
    1736             :                         } else {
    1737           6 :                                 if (q_bits < 160)
    1738           1 :                                         q_bits = 160;
    1739             : 
    1740           6 :                                 ret = dsa_generate_params(&pub, NULL, rnd_tmpkey_func,
    1741             :                                                           NULL, NULL, level, q_bits);
    1742           6 :                                 if (ret != 1 || HAVE_LIB_ERROR()) {
    1743           0 :                                         gnutls_assert();
    1744           0 :                                         ret = GNUTLS_E_PK_GENERATION_ERROR;
    1745           0 :                                         goto dsa_fail;
    1746             :                                 }
    1747             :                         }
    1748             : 
    1749          17 :                         params->params_nr = 0;
    1750             : 
    1751          17 :                         ret = _gnutls_mpi_init_multi(&params->params[DSA_P], &params->params[DSA_Q],
    1752             :                                         &params->params[DSA_G], NULL);
    1753          17 :                         if (ret < 0) {
    1754           0 :                                 gnutls_assert();
    1755           0 :                                 goto dsa_fail;
    1756             :                         }
    1757          17 :                         params->params_nr = 3;
    1758             : 
    1759          17 :                         mpz_set(TOMPZ(params->params[DSA_P]), pub.p);
    1760          17 :                         mpz_set(TOMPZ(params->params[DSA_Q]), pub.q);
    1761          17 :                         mpz_set(TOMPZ(params->params[DSA_G]), pub.g);
    1762             : 
    1763          17 :                         ret = 0;
    1764             : 
    1765          17 :                       dsa_fail:
    1766          17 :                         dsa_params_clear(&pub);
    1767             : 
    1768          17 :                         if (ret < 0)
    1769           0 :                                 goto fail;
    1770             : 
    1771          17 :                         break;
    1772             :                 }
    1773             :         case GNUTLS_PK_RSA_PSS:
    1774             :         case GNUTLS_PK_RSA:
    1775             :         case GNUTLS_PK_ECDSA:
    1776             :         case GNUTLS_PK_EDDSA_ED25519:
    1777             :         case GNUTLS_PK_EDDSA_ED448:
    1778             : #if ENABLE_GOST
    1779             :         case GNUTLS_PK_GOST_01:
    1780             :         case GNUTLS_PK_GOST_12_256:
    1781             :         case GNUTLS_PK_GOST_12_512:
    1782             : #endif
    1783             :                 break;
    1784           0 :         default:
    1785           0 :                 gnutls_assert();
    1786             :                 return GNUTLS_E_INVALID_REQUEST;
    1787             :         }
    1788             : 
    1789        1264 :         FAIL_IF_LIB_ERROR;
    1790             :         return 0;
    1791             : 
    1792           0 :       fail:
    1793             : 
    1794           0 :         for (i = 0; i < params->params_nr; i++) {
    1795           0 :                 _gnutls_mpi_release(&params->params[i]);
    1796             :         }
    1797           0 :         params->params_nr = 0;
    1798             : 
    1799           0 :         FAIL_IF_LIB_ERROR;
    1800             :         return ret;
    1801             : }
    1802             : 
    1803             : #ifdef ENABLE_FIPS140
    1804             : int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params,
    1805             :                             gnutls_datum_t *priv_key, gnutls_datum_t *pub_key);
    1806             : 
    1807             : int _gnutls_dh_compute_key(gnutls_dh_params_t dh_params,
    1808             :                            const gnutls_datum_t *priv_key, const gnutls_datum_t *pub_key,
    1809             :                            const gnutls_datum_t *peer_key, gnutls_datum_t *Z);
    1810             : 
    1811             : int _gnutls_ecdh_compute_key(gnutls_ecc_curve_t curve,
    1812             :                            const gnutls_datum_t *x, const gnutls_datum_t *y,
    1813             :                            const gnutls_datum_t *k,
    1814             :                            const gnutls_datum_t *peer_x, const gnutls_datum_t *peer_y,
    1815             :                            gnutls_datum_t *Z);
    1816             : 
    1817             : int _gnutls_ecdh_generate_key(gnutls_ecc_curve_t curve,
    1818             :                               gnutls_datum_t *x, gnutls_datum_t *y,
    1819             :                               gnutls_datum_t *k);
    1820             : 
    1821             : 
    1822             : int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params,
    1823             :                             gnutls_datum_t *priv_key, gnutls_datum_t *pub_key)
    1824             : {
    1825             :         gnutls_pk_params_st params;
    1826             :         int ret;
    1827             : 
    1828             :         gnutls_pk_params_init(&params);
    1829             :         params.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]);
    1830             :         params.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]);
    1831             : 
    1832             :         params.params_nr = 3; /* include empty q */
    1833             :         params.algo = GNUTLS_PK_DH;
    1834             : 
    1835             :         priv_key->data = NULL;
    1836             :         pub_key->data = NULL;
    1837             : 
    1838             :         ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, dh_params->q_bits, &params, 0);
    1839             :         if (ret < 0) {
    1840             :                 return gnutls_assert_val(ret);
    1841             :         }
    1842             : 
    1843             :         ret =
    1844             :             _gnutls_mpi_dprint_lz(params.params[DH_X], priv_key);
    1845             :         if (ret < 0) {
    1846             :                 gnutls_assert();
    1847             :                 goto fail;
    1848             :         }
    1849             : 
    1850             :         ret =
    1851             :             _gnutls_mpi_dprint_lz(params.params[DH_Y], pub_key);
    1852             :         if (ret < 0) {
    1853             :                 gnutls_assert();
    1854             :                 goto fail;
    1855             :         }
    1856             : 
    1857             :         ret = 0;
    1858             :         goto cleanup;
    1859             :  fail:
    1860             :         gnutls_free(pub_key->data);
    1861             :         gnutls_free(priv_key->data);
    1862             :  cleanup:
    1863             :         gnutls_pk_params_clear(&params);
    1864             :         return ret;
    1865             : }
    1866             : 
    1867             : /* Note that the value of Z will have the leading bytes stripped if they are zero -
    1868             :  * which follows the TLS approach. */
    1869             : int _gnutls_dh_compute_key(gnutls_dh_params_t dh_params,
    1870             :                            const gnutls_datum_t *priv_key, const gnutls_datum_t *pub_key,
    1871             :                            const gnutls_datum_t *peer_key, gnutls_datum_t *Z)
    1872             : {
    1873             :         gnutls_pk_params_st pub, priv;
    1874             :         int ret;
    1875             : 
    1876             :         gnutls_pk_params_init(&pub);
    1877             :         gnutls_pk_params_init(&priv);
    1878             :         pub.algo = GNUTLS_PK_DH;
    1879             : 
    1880             :         if (_gnutls_mpi_init_scan_nz
    1881             :                     (&pub.params[DH_Y], peer_key->data,
    1882             :                      peer_key->size) != 0) {
    1883             :                 ret =
    1884             :                     gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    1885             :                 goto cleanup;
    1886             :         }
    1887             : 
    1888             :         priv.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]);
    1889             :         priv.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]);
    1890             :         if (dh_params->params[2])
    1891             :                 priv.params[DH_Q] = _gnutls_mpi_copy(dh_params->params[2]);
    1892             : 
    1893             :         if (_gnutls_mpi_init_scan_nz
    1894             :                     (&priv.params[DH_X], priv_key->data,
    1895             :                      priv_key->size) != 0) {
    1896             :                 ret =
    1897             :                     gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    1898             :                 goto cleanup;
    1899             :         }
    1900             : 
    1901             :         priv.params_nr = 3; /* include, possibly empty, q */
    1902             :         priv.algo = GNUTLS_PK_DH;
    1903             : 
    1904             :         Z->data = NULL;
    1905             : 
    1906             :         ret = _gnutls_pk_derive(GNUTLS_PK_DH, Z, &priv, &pub);
    1907             :         if (ret < 0) {
    1908             :                 gnutls_assert();
    1909             :                 goto cleanup;
    1910             :         }
    1911             : 
    1912             :         ret = 0;
    1913             :  cleanup:
    1914             :         gnutls_pk_params_clear(&pub);
    1915             :         gnutls_pk_params_clear(&priv);
    1916             :         return ret;
    1917             : }
    1918             : 
    1919             : int _gnutls_ecdh_generate_key(gnutls_ecc_curve_t curve,
    1920             :                               gnutls_datum_t *x, gnutls_datum_t *y,
    1921             :                               gnutls_datum_t *k)
    1922             : {
    1923             :         gnutls_pk_params_st params;
    1924             :         int ret;
    1925             : 
    1926             :         gnutls_pk_params_init(&params);
    1927             :         params.curve = curve;
    1928             :         params.algo = GNUTLS_PK_ECDSA;
    1929             : 
    1930             :         x->data = NULL;
    1931             :         y->data = NULL;
    1932             :         k->data = NULL;
    1933             : 
    1934             :         ret = _gnutls_pk_generate_keys(GNUTLS_PK_ECDSA, curve, &params, 0);
    1935             :         if (ret < 0) {
    1936             :                 return gnutls_assert_val(ret);
    1937             :         }
    1938             : 
    1939             :         ret =
    1940             :             _gnutls_mpi_dprint_lz(params.params[ECC_X], x);
    1941             :         if (ret < 0) {
    1942             :                 gnutls_assert();
    1943             :                 goto fail;
    1944             :         }
    1945             : 
    1946             :         ret =
    1947             :             _gnutls_mpi_dprint_lz(params.params[ECC_Y], y);
    1948             :         if (ret < 0) {
    1949             :                 gnutls_assert();
    1950             :                 goto fail;
    1951             :         }
    1952             : 
    1953             :         ret =
    1954             :             _gnutls_mpi_dprint_lz(params.params[ECC_K], k);
    1955             :         if (ret < 0) {
    1956             :                 gnutls_assert();
    1957             :                 goto fail;
    1958             :         }
    1959             : 
    1960             :         ret = 0;
    1961             :         goto cleanup;
    1962             :  fail:
    1963             :         gnutls_free(y->data);
    1964             :         gnutls_free(x->data);
    1965             :         gnutls_free(k->data);
    1966             :  cleanup:
    1967             :         gnutls_pk_params_clear(&params);
    1968             :         return ret;
    1969             : }
    1970             : 
    1971             : int _gnutls_ecdh_compute_key(gnutls_ecc_curve_t curve,
    1972             :                            const gnutls_datum_t *x, const gnutls_datum_t *y,
    1973             :                            const gnutls_datum_t *k,
    1974             :                            const gnutls_datum_t *peer_x, const gnutls_datum_t *peer_y,
    1975             :                            gnutls_datum_t *Z)
    1976             : {
    1977             :         gnutls_pk_params_st pub, priv;
    1978             :         int ret;
    1979             : 
    1980             :         gnutls_pk_params_init(&pub);
    1981             :         gnutls_pk_params_init(&priv);
    1982             : 
    1983             :         pub.algo = GNUTLS_PK_ECDSA;
    1984             :         pub.curve = curve;
    1985             : 
    1986             :         if (_gnutls_mpi_init_scan_nz
    1987             :                     (&pub.params[ECC_Y], peer_y->data,
    1988             :                      peer_y->size) != 0) {
    1989             :                 ret =
    1990             :                     gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    1991             :                 goto cleanup;
    1992             :         }
    1993             : 
    1994             :         if (_gnutls_mpi_init_scan_nz
    1995             :                     (&pub.params[ECC_X], peer_x->data,
    1996             :                      peer_x->size) != 0) {
    1997             :                 ret =
    1998             :                     gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    1999             :                 goto cleanup;
    2000             :         }
    2001             : 
    2002             :         pub.params_nr = 2;
    2003             : 
    2004             :         if (_gnutls_mpi_init_scan_nz
    2005             :                     (&priv.params[ECC_Y], y->data,
    2006             :                      y->size) != 0) {
    2007             :                 ret =
    2008             :                     gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    2009             :                 goto cleanup;
    2010             :         }
    2011             : 
    2012             :         if (_gnutls_mpi_init_scan_nz
    2013             :                     (&priv.params[ECC_X], x->data,
    2014             :                      x->size) != 0) {
    2015             :                 ret =
    2016             :                     gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    2017             :                 goto cleanup;
    2018             :         }
    2019             : 
    2020             :         if (_gnutls_mpi_init_scan_nz
    2021             :                     (&priv.params[ECC_K], k->data,
    2022             :                      k->size) != 0) {
    2023             :                 ret =
    2024             :                     gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    2025             :                 goto cleanup;
    2026             :         }
    2027             : 
    2028             : 
    2029             :         priv.params_nr = 3;
    2030             :         priv.algo = GNUTLS_PK_ECDSA;
    2031             :         priv.curve = curve;
    2032             : 
    2033             :         Z->data = NULL;
    2034             : 
    2035             :         ret = _gnutls_pk_derive(GNUTLS_PK_ECDSA, Z, &priv, &pub);
    2036             :         if (ret < 0) {
    2037             :                 gnutls_assert();
    2038             :                 goto cleanup;
    2039             :         }
    2040             : 
    2041             :         ret = 0;
    2042             :  cleanup:
    2043             :         gnutls_pk_params_clear(&pub);
    2044             :         gnutls_pk_params_clear(&priv);
    2045             :         return ret;
    2046             : }
    2047             : 
    2048             : static int pct_test(gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* params)
    2049             : {
    2050             : int ret;
    2051             : gnutls_datum_t sig = {NULL, 0};
    2052             : const char const_data[20] = "onetwothreefourfive";
    2053             : const char const_data_sha256[32] = "onetwothreefourfivesixseveneight";
    2054             : const char const_data_sha384[48] = "onetwothreefourfivesixseveneightnineteneleventwe";
    2055             : const char const_data_sha512[64] = "onetwothreefourfivesixseveneightnineteneleventwelvethirteenfourt";
    2056             : gnutls_datum_t ddata, tmp = {NULL,0};
    2057             : char* gen_data = NULL;
    2058             : gnutls_x509_spki_st spki;
    2059             : 
    2060             :         memcpy(&spki, &params->spki, sizeof(spki));
    2061             : 
    2062             :         if (algo == GNUTLS_PK_DSA || algo == GNUTLS_PK_EC) {
    2063             :                 unsigned hash_len;
    2064             : 
    2065             :                 _gnutls_dsa_q_to_hash(params, &hash_len);
    2066             :                 gen_data = gnutls_malloc(hash_len);
    2067             :                 gnutls_rnd(GNUTLS_RND_NONCE, gen_data, hash_len);
    2068             : 
    2069             :                 ddata.data = (void*)gen_data;
    2070             :                 ddata.size = hash_len;
    2071             :         } else if (algo == GNUTLS_PK_GOST_01 || algo == GNUTLS_PK_GOST_12_256) {
    2072             :                 ddata.data = (void*)const_data_sha256;
    2073             :                 ddata.size = sizeof(const_data_sha256);
    2074             :         } else if (algo == GNUTLS_PK_GOST_12_512) {
    2075             :                 ddata.data = (void*)const_data_sha512;
    2076             :                 ddata.size = sizeof(const_data_sha512);
    2077             :         } else if (algo == GNUTLS_PK_RSA_PSS) {
    2078             :                 if (spki.rsa_pss_dig == GNUTLS_DIG_UNKNOWN)
    2079             :                         spki.rsa_pss_dig = GNUTLS_DIG_SHA256;
    2080             : 
    2081             :                 switch (spki.rsa_pss_dig) {
    2082             :                 case GNUTLS_DIG_SHA256:
    2083             :                         ddata.data = (void*)const_data_sha256;
    2084             :                         ddata.size = sizeof(const_data_sha256);
    2085             :                         break;
    2086             :                 case GNUTLS_DIG_SHA384:
    2087             :                         ddata.data = (void*)const_data_sha384;
    2088             :                         ddata.size = sizeof(const_data_sha384);
    2089             :                         break;
    2090             :                 case GNUTLS_DIG_SHA512:
    2091             :                         ddata.data = (void*)const_data_sha512;
    2092             :                         ddata.size = sizeof(const_data_sha512);
    2093             :                         break;
    2094             :                 default:
    2095             :                         ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
    2096             :                         goto cleanup;
    2097             :                 }
    2098             :         } else {
    2099             :                 ddata.data = (void*)const_data;
    2100             :                 ddata.size = sizeof(const_data);
    2101             :         }
    2102             : 
    2103             :         switch (algo) {
    2104             :         case GNUTLS_PK_RSA:
    2105             :                 ret = _gnutls_pk_encrypt(algo, &sig, &ddata, params);
    2106             :                 if (ret < 0) {
    2107             :                         ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
    2108             :                         goto cleanup;
    2109             :                 }
    2110             : 
    2111             :                 if (ddata.size == sig.size && memcmp(ddata.data, sig.data, sig.size) == 0) {
    2112             :                         ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
    2113             :                         gnutls_assert();
    2114             :                         goto cleanup;
    2115             :                 }
    2116             : 
    2117             :                 ret = _gnutls_pk_decrypt(algo, &tmp, &sig, params);
    2118             :                 if (ret < 0) {
    2119             :                         ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
    2120             :                         gnutls_assert();
    2121             :                         goto cleanup;
    2122             :                 }
    2123             : 
    2124             :                 if (tmp.size != ddata.size || memcmp(tmp.data, ddata.data, tmp.size) != 0) {
    2125             :                         ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
    2126             :                         gnutls_assert();
    2127             :                         goto cleanup;
    2128             :                 }
    2129             : 
    2130             :                 free(sig.data);
    2131             :                 sig.data = NULL;
    2132             : 
    2133             :                 FALLTHROUGH;
    2134             :         case GNUTLS_PK_EC: /* we only do keys for ECDSA */
    2135             :         case GNUTLS_PK_EDDSA_ED25519:
    2136             :         case GNUTLS_PK_EDDSA_ED448:
    2137             :         case GNUTLS_PK_DSA:
    2138             :         case GNUTLS_PK_RSA_PSS:
    2139             :         case GNUTLS_PK_GOST_01:
    2140             :         case GNUTLS_PK_GOST_12_256:
    2141             :         case GNUTLS_PK_GOST_12_512:
    2142             :                 ret = _gnutls_pk_sign(algo, &sig, &ddata, params, &spki);
    2143             :                 if (ret < 0) {
    2144             :                         ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
    2145             :                         goto cleanup;
    2146             :                 }
    2147             : 
    2148             :                 ret = _gnutls_pk_verify(algo, &ddata, &sig, params, &spki);
    2149             :                 if (ret < 0) {
    2150             :                         ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR);
    2151             :                         gnutls_assert();
    2152             :                         goto cleanup;
    2153             :                 }
    2154             :                 break;
    2155             :         case GNUTLS_PK_DH:
    2156             :         case GNUTLS_PK_ECDH_X25519:
    2157             :         case GNUTLS_PK_ECDH_X448:
    2158             :                 ret = 0;
    2159             :                 goto cleanup;
    2160             :         default:
    2161             :                 ret = gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM);
    2162             :                 goto cleanup;
    2163             :         }
    2164             : 
    2165             :         ret = 0;
    2166             : cleanup:
    2167             :         if (ret == GNUTLS_E_PK_GENERATION_ERROR) {
    2168             :                 _gnutls_switch_lib_state(LIB_STATE_ERROR);
    2169             :         }
    2170             :         gnutls_free(gen_data);
    2171             :         gnutls_free(sig.data);
    2172             :         gnutls_free(tmp.data);
    2173             :         return ret;
    2174             : }
    2175             : #endif
    2176             : 
    2177             : static inline int
    2178        8200 : eddsa_public_key(gnutls_pk_algorithm_t algo,
    2179             :                  uint8_t *pub, const uint8_t *priv)
    2180             : {
    2181        8200 :         switch (algo) {
    2182        4856 :         case GNUTLS_PK_EDDSA_ED25519:
    2183        4856 :                 ed25519_sha512_public_key(pub, priv);
    2184        4856 :                 return 0;
    2185        3344 :         case GNUTLS_PK_EDDSA_ED448:
    2186        3344 :                 ed448_shake256_public_key(pub, priv);
    2187        3344 :                 return 0;
    2188             :         default:
    2189           0 :                 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
    2190             :         }
    2191             : }
    2192             : 
    2193             : static inline int
    2194        3412 : edwards_curve_mul_g(gnutls_pk_algorithm_t algo,
    2195             :                     uint8_t *q, const uint8_t *n)
    2196             : {
    2197        3412 :         switch (algo) {
    2198        2097 :         case GNUTLS_PK_ECDH_X25519:
    2199        2097 :                 curve25519_mul_g(q, n);
    2200        2097 :                 return 0;
    2201        1315 :         case GNUTLS_PK_ECDH_X448:
    2202        1315 :                 curve448_mul_g(q, n);
    2203        1315 :                 return 0;
    2204             :         default:
    2205           0 :                 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    2206             :         }
    2207             : }
    2208             : 
    2209             : static inline int
    2210             : dh_find_q(const gnutls_pk_params_st *pk_params, mpz_t q)
    2211             : {
    2212             :         gnutls_datum_t prime = { NULL, 0 };
    2213             :         gnutls_datum_t generator = { NULL, 0 };
    2214             :         uint8_t *data_q;
    2215             :         size_t n_q;
    2216             :         bigint_t _q;
    2217             :         int ret = 0;
    2218             : 
    2219             :         ret = _gnutls_mpi_dprint(pk_params->params[DSA_P], &prime);
    2220             :         if (ret < 0) {
    2221             :                 gnutls_assert();
    2222             :                 goto cleanup;
    2223             :         }
    2224             : 
    2225             :         ret = _gnutls_mpi_dprint(pk_params->params[DSA_G], &generator);
    2226             :         if (ret < 0) {
    2227             :                 gnutls_assert();
    2228             :                 goto cleanup;
    2229             :         }
    2230             : 
    2231             :         if (!_gnutls_dh_prime_match_fips_approved(prime.data,
    2232             :                                                   prime.size,
    2233             :                                                   generator.data,
    2234             :                                                   generator.size,
    2235             :                                                   &data_q,
    2236             :                                                   &n_q)) {
    2237             :                 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2238             :                 goto cleanup;
    2239             :         }
    2240             : 
    2241             :         if (_gnutls_mpi_init_scan_nz(&_q, data_q, n_q) != 0) {
    2242             :                 ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    2243             :                 goto cleanup;
    2244             :         }
    2245             : 
    2246             :         mpz_set(q, TOMPZ(_q));
    2247             :         _gnutls_mpi_release(&_q);
    2248             : 
    2249             :  cleanup:
    2250             :         gnutls_free(prime.data);
    2251             :         gnutls_free(generator.data);
    2252             : 
    2253             :         return ret;
    2254             : }
    2255             : 
    2256             : /* To generate a DH key either q must be set in the params or
    2257             :  * level should be set to the number of required bits.
    2258             :  */
    2259             : static int
    2260       15260 : wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo,
    2261             :                                unsigned int level /*bits or curve */ ,
    2262             :                                gnutls_pk_params_st * params,
    2263             :                                unsigned ephemeral /*non-zero if they are ephemeral keys */)
    2264             : {
    2265       15260 :         int ret;
    2266       15260 :         unsigned int i;
    2267       15260 :         unsigned rnd_level;
    2268       15260 :         nettle_random_func *rnd_func;
    2269             : 
    2270       15260 :         if (IS_EC(algo)) {
    2271             :                 /* check if the curve relates to the algorithm used */
    2272       10220 :                 if (gnutls_ecc_curve_get_pk(level) != algo)
    2273           0 :                         return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    2274             :         }
    2275             : 
    2276       15260 :         if (ephemeral) {
    2277             :                 rnd_level = GNUTLS_RND_RANDOM;
    2278             :                 rnd_func = rnd_tmpkey_func;
    2279             :         } else {
    2280        1263 :                 rnd_func = rnd_key_func;
    2281        1263 :                 rnd_level = GNUTLS_RND_KEY;
    2282             :         }
    2283             : 
    2284       15260 :         switch (algo) {
    2285        4170 :         case GNUTLS_PK_DSA:
    2286             : #ifdef ENABLE_FIPS140
    2287             :                 if (_gnutls_fips_mode_enabled() != 0) {
    2288             :                         struct dsa_params pub;
    2289             :                         mpz_t x, y;
    2290             : 
    2291             :                         if (params->params[DSA_Q] == NULL)
    2292             :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2293             : 
    2294             :                         _dsa_params_get(params, &pub);
    2295             : 
    2296             :                         mpz_init(x);
    2297             :                         mpz_init(y);
    2298             : 
    2299             :                         ret =
    2300             :                             dsa_generate_dss_keypair(&pub, y, x,
    2301             :                                                  NULL, rnd_func,
    2302             :                                                  NULL, NULL);
    2303             :                         if (ret != 1 || HAVE_LIB_ERROR()) {
    2304             :                                 gnutls_assert();
    2305             :                                 ret = GNUTLS_E_PK_GENERATION_ERROR;
    2306             :                                 goto dsa_fail;
    2307             :                         }
    2308             : 
    2309             :                         ret = _gnutls_mpi_init_multi(&params->params[DSA_Y], &params->params[DSA_X], NULL);
    2310             :                         if (ret < 0) {
    2311             :                                 gnutls_assert();
    2312             :                                 goto dsa_fail;
    2313             :                         }
    2314             : 
    2315             :                         mpz_set(TOMPZ(params->params[DSA_Y]), y);
    2316             :                         mpz_set(TOMPZ(params->params[DSA_X]), x);
    2317             :                         params->params_nr += 2;
    2318             : 
    2319             :                       dsa_fail:
    2320             :                         mpz_clear(x);
    2321             :                         mpz_clear(y);
    2322             : 
    2323             :                         if (ret < 0)
    2324             :                                 goto fail;
    2325             : 
    2326             :                         break;
    2327             :                 }
    2328             : #endif
    2329        4170 :                 FALLTHROUGH;
    2330             :         case GNUTLS_PK_DH:
    2331             :                 {
    2332        4170 :                         struct dsa_params pub;
    2333        4170 :                         mpz_t r;
    2334        4170 :                         mpz_t x, y;
    2335        4170 :                         int max_tries;
    2336        4170 :                         unsigned have_q = 0;
    2337        4170 :                         mpz_t q;
    2338        4170 :                         mpz_t primesub1;
    2339        4170 :                         mpz_t ypowq;
    2340             : 
    2341        4170 :                         if (algo != params->algo)
    2342           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2343             : 
    2344        4170 :                         _dsa_params_get(params, &pub);
    2345             : 
    2346        4170 :                         if (params->params[DSA_Q] != NULL)
    2347        2520 :                                 have_q = 1;
    2348             : 
    2349             :                         /* This check is for the case !ENABLE_FIPS140 */
    2350        4170 :                         if (algo == GNUTLS_PK_DSA && have_q == 0)
    2351           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2352             : 
    2353        4170 :                         mpz_init(r);
    2354        4170 :                         mpz_init(x);
    2355        4170 :                         mpz_init(y);
    2356             : 
    2357        4170 :                         mpz_init(q);
    2358        4170 :                         mpz_init(primesub1);
    2359        4170 :                         mpz_init(ypowq);
    2360             : 
    2361        4170 :                         max_tries = 3;
    2362        4172 :                         do {
    2363        4172 :                                 if (have_q) {
    2364        2520 :                                         mpz_set(r, pub.q);
    2365        2520 :                                         mpz_sub_ui(r, r, 2);
    2366        2520 :                                         nettle_mpz_random(x, NULL, rnd_func, r);
    2367        2520 :                                         mpz_add_ui(x, x, 1);
    2368             :                                 } else {
    2369        1652 :                                         unsigned size = mpz_sizeinbase(pub.p, 2);
    2370        1652 :                                         if (level == 0)
    2371          93 :                                                 level = MIN(size, DH_EXPONENT_SIZE(size));
    2372        1652 :                                         nettle_mpz_random_size(x, NULL, rnd_func, level);
    2373             : 
    2374        1652 :                                         if (level >= size)
    2375           0 :                                                 mpz_mod(x, x, pub.p);
    2376             :                                 }
    2377             : 
    2378        4172 :                                 mpz_powm(y, pub.g, x, pub.p);
    2379             : 
    2380        4172 :                                 max_tries--;
    2381        4172 :                                 if (max_tries <= 0) {
    2382           1 :                                         gnutls_assert();
    2383           1 :                                         ret = GNUTLS_E_RANDOM_FAILED;
    2384           1 :                                         goto dh_fail;
    2385             :                                 }
    2386             : 
    2387        4171 :                                 if (HAVE_LIB_ERROR()) {
    2388           0 :                                         gnutls_assert();
    2389           0 :                                         ret = GNUTLS_E_LIB_IN_ERROR_STATE;
    2390           0 :                                         goto dh_fail;
    2391             :                                 }
    2392             : 
    2393        4171 :                         } while(mpz_cmp_ui(y, 1) == 0);
    2394             : 
    2395             : #ifdef ENABLE_FIPS140
    2396             :                         if (_gnutls_fips_mode_enabled()) {
    2397             :                                 /* Perform FFC full public key validation checks
    2398             :                                  * according to SP800-56A (revision 3), 5.6.2.3.1.
    2399             :                                  */
    2400             : 
    2401             :                                 /* Step 1: 2 <= y <= p - 2 */
    2402             :                                 mpz_sub_ui(primesub1, pub.p, 1);
    2403             : 
    2404             :                                 if (mpz_cmp_ui(y, 2) < 0 || mpz_cmp(y, primesub1) >= 0) {
    2405             :                                         ret = gnutls_assert_val(GNUTLS_E_RANDOM_FAILED);
    2406             :                                         goto dh_fail;
    2407             :                                 }
    2408             : 
    2409             :                                 /* Step 2: 1 = y^q mod p */
    2410             :                                 if (have_q)
    2411             :                                         mpz_set(q, pub.q);
    2412             :                                 else {
    2413             :                                         ret = dh_find_q(params, q);
    2414             :                                         if (ret < 0)
    2415             :                                                 goto dh_fail;
    2416             :                                 }
    2417             : 
    2418             :                                 mpz_powm(ypowq, y, q, pub.p);
    2419             :                                 if (mpz_cmp_ui(ypowq, 1) != 0) {
    2420             :                                         ret = gnutls_assert_val(GNUTLS_E_RANDOM_FAILED);
    2421             :                                         goto dh_fail;
    2422             :                                 }
    2423             :                         }
    2424             : #endif
    2425             : 
    2426        4169 :                         ret = _gnutls_mpi_init_multi(&params->params[DSA_Y], &params->params[DSA_X], NULL);
    2427        4169 :                         if (ret < 0) {
    2428           0 :                                 gnutls_assert();
    2429           0 :                                 goto dh_fail;
    2430             :                         }
    2431             : 
    2432        4169 :                         mpz_set(TOMPZ(params->params[DSA_Y]), y);
    2433        4169 :                         mpz_set(TOMPZ(params->params[DSA_X]), x);
    2434        4169 :                         params->params_nr += 2;
    2435             : 
    2436        4169 :                         ret = 0;
    2437             : 
    2438        4170 :                       dh_fail:
    2439        4170 :                         mpz_clear(r);
    2440        4170 :                         mpz_clear(x);
    2441        4170 :                         mpz_clear(y);
    2442        4170 :                         mpz_clear(q);
    2443        4170 :                         mpz_clear(primesub1);
    2444        4170 :                         mpz_clear(ypowq);
    2445             : 
    2446        4170 :                         if (ret < 0)
    2447           1 :                                 goto fail;
    2448             : 
    2449        4169 :                         break;
    2450             :                 }
    2451         323 :         case GNUTLS_PK_RSA_PSS:
    2452             :         case GNUTLS_PK_RSA:
    2453             :                 {
    2454         323 :                         struct rsa_public_key pub;
    2455         323 :                         struct rsa_private_key priv;
    2456             : 
    2457         323 :                         rsa_public_key_init(&pub);
    2458         323 :                         rsa_private_key_init(&priv);
    2459             : 
    2460         323 :                         mpz_set_ui(pub.e, 65537);
    2461             : 
    2462         323 :                         if ((params->pkflags & GNUTLS_PK_FLAG_PROVABLE) || _gnutls_fips_mode_enabled() != 0) {
    2463           7 :                                 params->pkflags |= GNUTLS_PK_FLAG_PROVABLE;
    2464           7 :                                 if (params->palgo != 0 && params->palgo != GNUTLS_DIG_SHA384) {
    2465           0 :                                         ret = GNUTLS_E_INVALID_REQUEST;
    2466           0 :                                         goto rsa_fail;
    2467             :                                 }
    2468             : 
    2469           7 :                                 params->palgo = GNUTLS_DIG_SHA384;
    2470             : 
    2471           7 :                                 if (params->seed_size) {
    2472           7 :                                         ret = _rsa_generate_fips186_4_keypair(&pub, &priv,
    2473           7 :                                                 params->seed_size, params->seed,
    2474             :                                                 NULL, NULL, level);
    2475             :                                 } else {
    2476             :                                         unsigned retries = 0;
    2477             :                                         /* The provable RSA key generation process is deterministic
    2478             :                                          * but has an internal maximum iteration counter and when
    2479             :                                          * exceed will fail for certain random seeds. This is a very
    2480             :                                          * rare condition, but it nevertheless happens and even CI builds fail
    2481             :                                          * occasionally. When we generate the random seed internally, remediate
    2482             :                                          * by retrying a different seed on failure. */
    2483           0 :                                         do {
    2484           0 :                                                 params->seed_size = sizeof(params->seed);
    2485           0 :                                                 ret =
    2486           0 :                                                     rsa_generate_fips186_4_keypair(&pub, &priv, NULL,
    2487             :                                                          rnd_func, NULL, NULL,
    2488           0 :                                                          &params->seed_size, params->seed,
    2489             :                                                          level);
    2490           0 :                                         } while (ret != 1 && ++retries < 3);
    2491             :                                 }
    2492             :                         } else {
    2493         316 :                                 ret =
    2494         316 :                                     rsa_generate_keypair(&pub, &priv, NULL,
    2495             :                                                  rnd_func, NULL, NULL,
    2496             :                                                  level, 0);
    2497             :                         }
    2498         323 :                         if (ret != 1 || HAVE_LIB_ERROR()) {
    2499           0 :                                 gnutls_assert();
    2500           0 :                                 ret = GNUTLS_E_PK_GENERATION_ERROR;
    2501           0 :                                 goto rsa_fail;
    2502             :                         }
    2503             : 
    2504         323 :                         params->params_nr = 0;
    2505        2907 :                         for (i = 0; i < RSA_PRIVATE_PARAMS; i++) {
    2506        2584 :                                 ret = _gnutls_mpi_init(&params->params[i]);
    2507        2584 :                                 if (ret < 0) {
    2508           0 :                                         gnutls_assert();
    2509           0 :                                         goto rsa_fail;
    2510             :                                 }
    2511        2584 :                                 params->params_nr++;
    2512             :                         }
    2513             : 
    2514         323 :                         mpz_set(TOMPZ(params->params[RSA_MODULUS]), pub.n);
    2515         323 :                         mpz_set(TOMPZ(params->params[RSA_PUB]), pub.e);
    2516         323 :                         mpz_set(TOMPZ(params->params[RSA_PRIV]), priv.d);
    2517         323 :                         mpz_set(TOMPZ(params->params[RSA_PRIME1]), priv.p);
    2518         323 :                         mpz_set(TOMPZ(params->params[RSA_PRIME2]), priv.q);
    2519         323 :                         mpz_set(TOMPZ(params->params[RSA_COEF]), priv.c);
    2520         323 :                         mpz_set(TOMPZ(params->params[RSA_E1]), priv.a);
    2521         323 :                         mpz_set(TOMPZ(params->params[RSA_E2]), priv.b);
    2522             : 
    2523         323 :                         ret = 0;
    2524             : 
    2525         323 :                       rsa_fail:
    2526         323 :                         rsa_private_key_clear(&priv);
    2527         323 :                         rsa_public_key_clear(&pub);
    2528             : 
    2529         323 :                         if (ret < 0)
    2530           0 :                                 goto fail;
    2531             : 
    2532         323 :                         break;
    2533             :                 }
    2534           5 :         case GNUTLS_PK_EDDSA_ED25519:
    2535             :         case GNUTLS_PK_EDDSA_ED448:
    2536             :                 {
    2537           5 :                         unsigned size = gnutls_ecc_curve_get_size(level);
    2538             : 
    2539           5 :                         if (params->pkflags & GNUTLS_PK_FLAG_PROVABLE)
    2540           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2541             : 
    2542           5 :                         if (unlikely(get_eddsa_curve(algo) != level))
    2543           0 :                                 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    2544             : 
    2545           5 :                         if (size == 0)
    2546           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2547             : 
    2548           5 :                         params->curve = level;
    2549             : 
    2550           5 :                         params->raw_priv.data = gnutls_malloc(size);
    2551           5 :                         if (params->raw_priv.data == NULL)
    2552           0 :                                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
    2553             : 
    2554           5 :                         params->raw_pub.data = gnutls_malloc(size);
    2555           5 :                         if (params->raw_pub.data == NULL) {
    2556           0 :                                 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
    2557           0 :                                 goto fail;
    2558             :                         }
    2559             : 
    2560           5 :                         ret = gnutls_rnd(rnd_level, params->raw_priv.data, size);
    2561           5 :                         if (ret < 0) {
    2562           0 :                                 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
    2563           0 :                                 goto fail;
    2564             :                         }
    2565           5 :                         params->raw_pub.size = size;
    2566           5 :                         params->raw_priv.size = size;
    2567             : 
    2568          10 :                         ret = eddsa_public_key(algo,
    2569           5 :                                                params->raw_pub.data,
    2570           5 :                                                params->raw_priv.data);
    2571           5 :                         if (ret < 0)
    2572           0 :                                 goto fail;
    2573             : 
    2574             :                         break;
    2575             :                 }
    2576        6803 :         case GNUTLS_PK_ECDSA:
    2577        6803 :                 if (params->pkflags & GNUTLS_PK_FLAG_PROVABLE)
    2578           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2579             : 
    2580             :                 {
    2581        6803 :                         struct ecc_scalar key;
    2582        6803 :                         struct ecc_point pub;
    2583        6803 :                         const struct ecc_curve *curve;
    2584        6803 :                         struct ecc_scalar n;
    2585        6803 :                         struct ecc_scalar m;
    2586        6803 :                         struct ecc_point r;
    2587        6803 :                         mpz_t x, y, xx, yy, nn, mm;
    2588             : 
    2589        6803 :                         curve = get_supported_nist_curve(level);
    2590        6803 :                         if (curve == NULL)
    2591           0 :                                 return
    2592           0 :                                     gnutls_assert_val
    2593             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    2594             : 
    2595        6803 :                         mpz_init(x);
    2596        6803 :                         mpz_init(y);
    2597        6803 :                         mpz_init(xx);
    2598        6803 :                         mpz_init(yy);
    2599        6803 :                         mpz_init(nn);
    2600        6803 :                         mpz_init(mm);
    2601             : 
    2602        6803 :                         ecc_scalar_init(&key, curve);
    2603        6803 :                         ecc_point_init(&pub, curve);
    2604        6803 :                         ecc_scalar_init(&n, curve);
    2605        6803 :                         ecc_scalar_init(&m, curve);
    2606        6803 :                         ecc_point_init(&r, curve);
    2607             : 
    2608        6803 :                         ecdsa_generate_keypair(&pub, &key, NULL, rnd_func);
    2609        6803 :                         if (HAVE_LIB_ERROR()) {
    2610           0 :                                 ret = gnutls_assert_val(GNUTLS_E_LIB_IN_ERROR_STATE);
    2611           0 :                                 goto ecc_fail;
    2612             :                         }
    2613             : 
    2614        6803 :                         ret = _gnutls_mpi_init_multi(&params->params[ECC_X], &params->params[ECC_Y],
    2615             :                                         &params->params[ECC_K], NULL);
    2616        6803 :                         if (ret < 0) {
    2617           0 :                                 gnutls_assert();
    2618           0 :                                 goto ecc_fail;
    2619             :                         }
    2620             : 
    2621        6803 :                         params->curve = level;
    2622        6803 :                         params->params_nr = ECC_PRIVATE_PARAMS;
    2623             : 
    2624        6803 :                         ecc_point_get(&pub, x, y);
    2625             : 
    2626             : #ifdef ENABLE_FIPS140
    2627             :                         if (_gnutls_fips_mode_enabled()) {
    2628             :                                 /* Perform ECC full public key validation checks
    2629             :                                  * according to SP800-56A (revision 3), 5.6.2.3.3.
    2630             :                                  */
    2631             : 
    2632             :                                 const char *order, *modulus;
    2633             : 
    2634             :                                 /* Step 1: verify that Q is not an identity
    2635             :                                  * element (an infinity point).  Note that this
    2636             :                                  * cannot happen in the nettle implementation,
    2637             :                                  * because it cannot represent an infinity point
    2638             :                                  * on curves. */
    2639             :                                 if (mpz_cmp_ui(x, 0) == 0 && mpz_cmp_ui(y, 0) == 0) {
    2640             :                                         ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
    2641             :                                         goto ecc_fail;
    2642             :                                 }
    2643             : 
    2644             :                                 /* Step 2: verify that both coordinates of Q are
    2645             :                                  * in the range [0, p - 1].
    2646             :                                  *
    2647             :                                  * Step 3: verify that Q lie on the curve
    2648             :                                  *
    2649             :                                  * Both checks are performed in nettle.  */
    2650             :                                 if (!ecc_point_set(&r, x, y)) {
    2651             :                                         ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
    2652             :                                         goto ecc_fail;
    2653             :                                 }
    2654             : 
    2655             :                                 /* Step 4: verify that n * Q, where n is the
    2656             :                                  * curve order, result in an identity element
    2657             :                                  *
    2658             :                                  * Since nettle internally cannot represent an
    2659             :                                  * identity element on curves, we validate this
    2660             :                                  * instead:
    2661             :                                  *
    2662             :                                  *   (n - 1) * Q = -Q
    2663             :                                  *
    2664             :                                  * That effectively means: n * Q = -Q + Q = O
    2665             :                                  */
    2666             :                                 order = get_supported_nist_curve_order(level);
    2667             :                                 if (unlikely(order == NULL)) {
    2668             :                                         ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
    2669             :                                         goto ecc_fail;
    2670             :                                 }
    2671             : 
    2672             :                                 ret = mpz_set_str(nn, order, 16);
    2673             :                                 if (unlikely(ret < 0)) {
    2674             :                                         ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    2675             :                                         goto ecc_fail;
    2676             :                                 }
    2677             : 
    2678             :                                 modulus = get_supported_nist_curve_modulus(level);
    2679             :                                 if (unlikely(modulus == NULL)) {
    2680             :                                         ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
    2681             :                                         goto ecc_fail;
    2682             :                                 }
    2683             : 
    2684             :                                 ret = mpz_set_str(mm, modulus, 16);
    2685             :                                 if (unlikely(ret < 0)) {
    2686             :                                         ret = gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
    2687             :                                         goto ecc_fail;
    2688             :                                 }
    2689             : 
    2690             :                                 /* (n - 1) * Q = -Q */
    2691             :                                 mpz_sub_ui (nn, nn, 1);
    2692             :                                 ecc_scalar_set(&n, nn);
    2693             :                                 ecc_point_mul(&r, &n, &r);
    2694             :                                 ecc_point_get(&r, xx, yy);
    2695             :                                 mpz_sub (mm, mm, y);
    2696             : 
    2697             :                                 if (mpz_cmp(xx, x) != 0 || mpz_cmp(yy, mm) != 0) {
    2698             :                                         ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
    2699             :                                         goto ecc_fail;
    2700             :                                 }
    2701             :                         }
    2702             : #endif
    2703             : 
    2704        6803 :                         mpz_set(TOMPZ(params->params[ECC_X]), x);
    2705        6803 :                         mpz_set(TOMPZ(params->params[ECC_Y]), y);
    2706             : 
    2707        6803 :                         ecc_scalar_get(&key, TOMPZ(params->params[ECC_K]));
    2708             : 
    2709        6803 :                         ret = 0;
    2710             : 
    2711        6803 :                       ecc_fail:
    2712        6803 :                         mpz_clear(x);
    2713        6803 :                         mpz_clear(y);
    2714        6803 :                         mpz_clear(xx);
    2715        6803 :                         mpz_clear(yy);
    2716        6803 :                         mpz_clear(nn);
    2717        6803 :                         mpz_clear(mm);
    2718        6803 :                         ecc_point_clear(&pub);
    2719        6803 :                         ecc_scalar_clear(&key);
    2720        6803 :                         ecc_point_clear(&r);
    2721        6803 :                         ecc_scalar_clear(&n);
    2722        6803 :                         ecc_scalar_clear(&m);
    2723             : 
    2724        6803 :                         if (ret < 0)
    2725           0 :                                 goto fail;
    2726             : 
    2727        6803 :                         break;
    2728             :                 }
    2729             : #if ENABLE_GOST
    2730         547 :         case GNUTLS_PK_GOST_01:
    2731             :         case GNUTLS_PK_GOST_12_256:
    2732             :         case GNUTLS_PK_GOST_12_512:
    2733         547 :                 if (params->pkflags & GNUTLS_PK_FLAG_PROVABLE)
    2734           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2735             : 
    2736             :                 {
    2737         547 :                         struct ecc_scalar key;
    2738         547 :                         struct ecc_point pub;
    2739         547 :                         const struct ecc_curve *curve;
    2740         547 :                         const mac_entry_st *me;
    2741             : 
    2742         547 :                         curve = get_supported_gost_curve(level);
    2743         547 :                         if (curve == NULL)
    2744           0 :                                 return
    2745           0 :                                     gnutls_assert_val
    2746             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    2747             : 
    2748         547 :                         me = hash_to_entry(_gnutls_gost_digest(algo));
    2749         547 :                         if (!me || me->output_size * 8 != ecc_bit_size(curve))
    2750           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2751             : 
    2752         547 :                         ecc_scalar_init(&key, curve);
    2753         547 :                         ecc_point_init(&pub, curve);
    2754             : 
    2755         547 :                         gostdsa_generate_keypair(&pub, &key, NULL, rnd_key_func);
    2756         547 :                         if (HAVE_LIB_ERROR()) {
    2757           0 :                                 ret = gnutls_assert_val(GNUTLS_E_LIB_IN_ERROR_STATE);
    2758           0 :                                 goto ecc_fail;
    2759             :                         }
    2760             : 
    2761             : 
    2762         547 :                         ret = _gnutls_mpi_init_multi(&params->params[GOST_X], &params->params[GOST_Y],
    2763             :                                         &params->params[GOST_K], NULL);
    2764         547 :                         if (ret < 0) {
    2765           0 :                                 gnutls_assert();
    2766           0 :                                 goto gost_fail;
    2767             :                         }
    2768             : 
    2769         547 :                         params->curve = level;
    2770         547 :                         params->params_nr = GOST_PRIVATE_PARAMS;
    2771             : 
    2772         547 :                         ecc_point_get(&pub, TOMPZ(params->params[GOST_X]),
    2773         547 :                                       TOMPZ(params->params[GOST_Y]));
    2774         547 :                         ecc_scalar_get(&key, TOMPZ(params->params[GOST_K]));
    2775             : 
    2776         547 :                         ret = 0;
    2777             : 
    2778         547 :                       gost_fail:
    2779         547 :                         ecc_point_clear(&pub);
    2780         547 :                         ecc_scalar_clear(&key);
    2781             : 
    2782         547 :                         if (ret < 0)
    2783           0 :                                 goto fail;
    2784             : 
    2785         547 :                         break;
    2786             :                 }
    2787             : #endif
    2788        3412 :         case GNUTLS_PK_ECDH_X25519:
    2789             :         case GNUTLS_PK_ECDH_X448:
    2790             :                 {
    2791        3412 :                         unsigned size = gnutls_ecc_curve_get_size(level);
    2792             : 
    2793        3412 :                         if (size == 0)
    2794           0 :                                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    2795             : 
    2796        3412 :                         params->curve = level;
    2797             : 
    2798        3412 :                         params->raw_priv.data = gnutls_malloc(size);
    2799        3412 :                         if (params->raw_priv.data == NULL)
    2800           0 :                                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
    2801             : 
    2802        3412 :                         params->raw_pub.data = gnutls_malloc(size);
    2803        3412 :                         if (params->raw_pub.data == NULL) {
    2804           0 :                                 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
    2805           0 :                                 goto fail;
    2806             :                         }
    2807             : 
    2808        3412 :                         ret = gnutls_rnd(rnd_level, params->raw_priv.data, size);
    2809        3412 :                         if (ret < 0) {
    2810           0 :                                 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
    2811           0 :                                 goto fail;
    2812             :                         }
    2813        3412 :                         params->raw_pub.size = size;
    2814        3412 :                         params->raw_priv.size = size;
    2815             : 
    2816        3412 :                         ret = edwards_curve_mul_g(algo, params->raw_pub.data, params->raw_priv.data);
    2817        3412 :                         if (ret < 0)
    2818           0 :                                 goto fail;
    2819             :                         break;
    2820             :                 }
    2821           0 :         default:
    2822           0 :                 gnutls_assert();
    2823             :                 return GNUTLS_E_INVALID_REQUEST;
    2824             :         }
    2825             : 
    2826       15259 :         params->algo = algo;
    2827             : 
    2828             : #ifdef ENABLE_FIPS140
    2829             :         ret = pct_test(algo, params);
    2830             :         if (ret < 0) {
    2831             :                 gnutls_assert();
    2832             :                 goto fail;
    2833             :         }
    2834             : #endif
    2835             : 
    2836       15259 :         FAIL_IF_LIB_ERROR;
    2837             :         return 0;
    2838             : 
    2839           1 :       fail:
    2840             : 
    2841           4 :         for (i = 0; i < params->params_nr; i++) {
    2842           5 :                 _gnutls_mpi_release(&params->params[i]);
    2843             :         }
    2844           1 :         params->params_nr = 0;
    2845           1 :         gnutls_free(params->raw_priv.data);
    2846           1 :         gnutls_free(params->raw_pub.data);
    2847             : 
    2848           1 :         FAIL_IF_LIB_ERROR;
    2849             :         return ret;
    2850             : }
    2851             : 
    2852             : 
    2853             : static int
    2854        1370 : wrap_nettle_pk_verify_priv_params(gnutls_pk_algorithm_t algo,
    2855             :                              const gnutls_pk_params_st * params)
    2856             : {
    2857        1370 :         int ret;
    2858             : 
    2859        1370 :         switch (algo) {
    2860         365 :         case GNUTLS_PK_RSA:
    2861             :         case GNUTLS_PK_RSA_PSS:
    2862             :                 {
    2863         365 :                         bigint_t t1 = NULL, t2 = NULL;
    2864             : 
    2865         365 :                         if (params->params_nr != RSA_PRIVATE_PARAMS)
    2866           0 :                                 return
    2867           0 :                                     gnutls_assert_val
    2868             :                                     (GNUTLS_E_INVALID_REQUEST);
    2869             : 
    2870         365 :                         ret = _gnutls_mpi_init_multi(&t1, &t2, NULL);
    2871         365 :                         if (ret < 0)
    2872           0 :                                 return
    2873           0 :                                     gnutls_assert_val(ret);
    2874             : 
    2875         365 :                         _gnutls_mpi_mulm(t1, params->params[RSA_PRIME1],
    2876             :                                          params->params[RSA_PRIME2],
    2877             :                                          params->params[RSA_MODULUS]);
    2878         365 :                         if (_gnutls_mpi_cmp_ui(t1, 0) != 0) {
    2879           0 :                                 ret =
    2880           0 :                                     gnutls_assert_val
    2881             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    2882           0 :                                 goto rsa_cleanup;
    2883             :                         }
    2884             : 
    2885         365 :                         mpz_invert(TOMPZ(t1),
    2886         365 :                                    TOMPZ(params->params[RSA_PRIME2]),
    2887         365 :                                    TOMPZ(params->params[RSA_PRIME1]));
    2888         365 :                         if (_gnutls_mpi_cmp(t1, params->params[RSA_COEF])
    2889             :                             != 0) {
    2890           0 :                                 ret =
    2891           0 :                                     gnutls_assert_val
    2892             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    2893           0 :                                 goto rsa_cleanup;
    2894             :                         }
    2895             : 
    2896             :                         /* [RSA_PRIME1] = d % p-1, [RSA_PRIME2] = d % q-1 */
    2897         365 :                         _gnutls_mpi_sub_ui(t1, params->params[RSA_PRIME1],
    2898             :                                            1);
    2899         365 :                         ret = _gnutls_mpi_modm(t2, params->params[RSA_PRIV], t1);
    2900         365 :                         if (ret < 0) {
    2901           0 :                                 ret =
    2902           0 :                                     gnutls_assert_val
    2903             :                                     (GNUTLS_E_MEMORY_ERROR);
    2904           0 :                                 goto rsa_cleanup;
    2905             :                         }
    2906             : 
    2907         365 :                         if (_gnutls_mpi_cmp(params->params[RSA_E1], t2) !=
    2908             :                             0) {
    2909           0 :                                 ret =
    2910           0 :                                     gnutls_assert_val
    2911             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    2912           0 :                                 goto rsa_cleanup;
    2913             :                         }
    2914             : 
    2915         365 :                         _gnutls_mpi_sub_ui(t1, params->params[RSA_PRIME2],
    2916             :                                            1);
    2917             : 
    2918         365 :                         ret = _gnutls_mpi_modm(t2, params->params[RSA_PRIV], t1);
    2919         365 :                         if (ret < 0) {
    2920           0 :                                 ret =
    2921           0 :                                     gnutls_assert_val
    2922             :                                     (GNUTLS_E_MEMORY_ERROR);
    2923           0 :                                 goto rsa_cleanup;
    2924             :                         }
    2925             : 
    2926         365 :                         if (_gnutls_mpi_cmp(params->params[RSA_E2], t2) !=
    2927             :                             0) {
    2928           0 :                                 ret =
    2929           0 :                                     gnutls_assert_val
    2930             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    2931           0 :                                 goto rsa_cleanup;
    2932             :                         }
    2933             : 
    2934             :                         ret = 0;
    2935             : 
    2936         365 :                       rsa_cleanup:
    2937         365 :                         zrelease_mpi_key(&t1);
    2938         365 :                         zrelease_mpi_key(&t2);
    2939             :                 }
    2940             : 
    2941         365 :                 break;
    2942          24 :         case GNUTLS_PK_DSA:
    2943             :                 {
    2944          24 :                         bigint_t t1 = NULL;
    2945             : 
    2946          24 :                         if (params->params_nr != DSA_PRIVATE_PARAMS)
    2947           0 :                                 return
    2948           0 :                                     gnutls_assert_val
    2949             :                                     (GNUTLS_E_INVALID_REQUEST);
    2950             : 
    2951          24 :                         ret = _gnutls_mpi_init(&t1);
    2952          24 :                         if (ret < 0)
    2953           0 :                                 return
    2954           0 :                                     gnutls_assert_val(ret);
    2955             : 
    2956          24 :                         ret = _gnutls_mpi_powm(t1, params->params[DSA_G],
    2957             :                                          params->params[DSA_X],
    2958             :                                          params->params[DSA_P]);
    2959          24 :                         if (ret < 0) {
    2960           0 :                                 gnutls_assert();
    2961           0 :                                 goto dsa_cleanup;
    2962             :                         }
    2963             : 
    2964          24 :                         if (_gnutls_mpi_cmp(t1, params->params[DSA_Y]) !=
    2965             :                             0) {
    2966           0 :                                 ret =
    2967           0 :                                     gnutls_assert_val
    2968             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    2969           0 :                                 goto dsa_cleanup;
    2970             :                         }
    2971             : 
    2972             :                         ret = 0;
    2973             : 
    2974          24 :                       dsa_cleanup:
    2975          24 :                         zrelease_mpi_key(&t1);
    2976             :                 }
    2977             : 
    2978          24 :                 break;
    2979         428 :         case GNUTLS_PK_ECDSA:
    2980             :                 {
    2981         428 :                         struct ecc_point r, pub;
    2982         428 :                         struct ecc_scalar priv;
    2983         428 :                         mpz_t x1, y1, x2, y2;
    2984         428 :                         const struct ecc_curve *curve;
    2985             : 
    2986         428 :                         if (params->params_nr != ECC_PRIVATE_PARAMS)
    2987           0 :                                 return
    2988           0 :                                     gnutls_assert_val
    2989             :                                     (GNUTLS_E_INVALID_REQUEST);
    2990             : 
    2991         428 :                         curve = get_supported_nist_curve(params->curve);
    2992         428 :                         if (curve == NULL)
    2993           0 :                                 return
    2994           0 :                                     gnutls_assert_val
    2995             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    2996             : 
    2997         428 :                         ret = _ecc_params_to_pubkey(params, &pub, curve);
    2998         428 :                         if (ret < 0)
    2999           0 :                                 return gnutls_assert_val(ret);
    3000             : 
    3001         428 :                         ret = _ecc_params_to_privkey(params, &priv, curve);
    3002         428 :                         if (ret < 0) {
    3003           0 :                                 ecc_point_clear(&pub);
    3004           0 :                                 return gnutls_assert_val(ret);
    3005             :                         }
    3006             : 
    3007         428 :                         ecc_point_init(&r, curve);
    3008             :                         /* verify that x,y lie on the curve */
    3009         428 :                         ret =
    3010         856 :                             ecc_point_set(&r, TOMPZ(params->params[ECC_X]),
    3011         428 :                                           TOMPZ(params->params[ECC_Y]));
    3012         428 :                         if (ret == 0) {
    3013           0 :                                 ret =
    3014           0 :                                     gnutls_assert_val
    3015             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    3016           0 :                                 goto ecc_cleanup;
    3017             :                         }
    3018         428 :                         ecc_point_clear(&r);
    3019             : 
    3020         428 :                         ecc_point_init(&r, curve);
    3021         428 :                         ecc_point_mul_g(&r, &priv);
    3022             : 
    3023         428 :                         mpz_init(x1);
    3024         428 :                         mpz_init(y1);
    3025         428 :                         ecc_point_get(&r, x1, y1);
    3026         428 :                         ecc_point_zclear(&r);
    3027             : 
    3028         428 :                         mpz_init(x2);
    3029         428 :                         mpz_init(y2);
    3030         428 :                         ecc_point_get(&pub, x2, y2);
    3031             : 
    3032             :                         /* verify that k*(Gx,Gy)=(x,y) */
    3033         428 :                         if (mpz_cmp(x1, x2) != 0 || mpz_cmp(y1, y2) != 0) {
    3034           1 :                                 ret =
    3035           1 :                                     gnutls_assert_val
    3036             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    3037           1 :                                 goto ecc_cleanup;
    3038             :                         }
    3039             : 
    3040             :                         ret = 0;
    3041             : 
    3042         428 :                       ecc_cleanup:
    3043         428 :                         ecc_scalar_zclear(&priv);
    3044         428 :                         ecc_point_clear(&pub);
    3045             : 
    3046         428 :                         mpz_clear(x1);
    3047         428 :                         mpz_clear(y1);
    3048         428 :                         mpz_clear(x2);
    3049         428 :                         mpz_clear(y2);
    3050             :                 }
    3051         428 :                 break;
    3052          21 :         case GNUTLS_PK_EDDSA_ED25519:
    3053             :         case GNUTLS_PK_EDDSA_ED448: {
    3054          21 :                 gnutls_ecc_curve_t curve;
    3055          21 :                 const gnutls_ecc_curve_entry_st *e;
    3056          21 :                 uint8_t pub[57]; /* can accommodate both curves */
    3057             : 
    3058          21 :                 curve = get_eddsa_curve(algo);
    3059          21 :                 e = _gnutls_ecc_curve_get_params(curve);
    3060          21 :                 if (e == NULL)
    3061           1 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    3062             : 
    3063          21 :                 if (params->raw_pub.data == NULL) {
    3064             :                         return 0; /* nothing to verify */
    3065             :                 }
    3066             : 
    3067          21 :                 if (params->raw_pub.size != e->size)
    3068           0 :                         return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
    3069             : 
    3070          21 :                 ret = eddsa_public_key(algo, pub, params->raw_priv.data);
    3071          21 :                 if (ret < 0)
    3072             :                         return ret;
    3073             : 
    3074          21 :                 if (memcmp(params->raw_pub.data, pub, e->size) != 0)
    3075           1 :                         return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
    3076             : 
    3077          20 :                 ret = 0;
    3078          20 :                 break;
    3079             :         }
    3080             : #if ENABLE_GOST
    3081         532 :         case GNUTLS_PK_GOST_01:
    3082             :         case GNUTLS_PK_GOST_12_256:
    3083             :         case GNUTLS_PK_GOST_12_512:
    3084             :                 {
    3085         532 :                         struct ecc_point r, pub;
    3086         532 :                         struct ecc_scalar priv;
    3087         532 :                         mpz_t x1, y1, x2, y2;
    3088         532 :                         const struct ecc_curve *curve;
    3089             : 
    3090         532 :                         if (params->params_nr != GOST_PRIVATE_PARAMS)
    3091           0 :                                 return
    3092           0 :                                     gnutls_assert_val
    3093             :                                     (GNUTLS_E_INVALID_REQUEST);
    3094             : 
    3095         532 :                         curve = get_supported_gost_curve(params->curve);
    3096         532 :                         if (curve == NULL)
    3097           0 :                                 return
    3098           0 :                                     gnutls_assert_val
    3099             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    3100             : 
    3101         532 :                         ret = _gost_params_to_pubkey(params, &pub, curve);
    3102         532 :                         if (ret < 0)
    3103           0 :                                 return gnutls_assert_val(ret);
    3104             : 
    3105         532 :                         ret = _gost_params_to_privkey(params, &priv, curve);
    3106         532 :                         if (ret < 0) {
    3107           0 :                                 ecc_point_clear(&pub);
    3108           0 :                                 return gnutls_assert_val(ret);
    3109             :                         }
    3110             : 
    3111         532 :                         ecc_point_init(&r, curve);
    3112             :                         /* verify that x,y lie on the curve */
    3113         532 :                         ret =
    3114        1064 :                             gost_point_set(&r, TOMPZ(params->params[GOST_X]),
    3115         532 :                                           TOMPZ(params->params[GOST_Y]));
    3116         532 :                         if (ret == 0) {
    3117           0 :                                 ret =
    3118           0 :                                     gnutls_assert_val
    3119             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    3120           0 :                                 goto gost_cleanup;
    3121             :                         }
    3122         532 :                         ecc_point_clear(&r);
    3123             : 
    3124         532 :                         ecc_point_init(&r, curve);
    3125         532 :                         gost_point_mul_g(&r, &priv);
    3126             : 
    3127         532 :                         mpz_init(x1);
    3128         532 :                         mpz_init(y1);
    3129         532 :                         ecc_point_get(&r, x1, y1);
    3130         532 :                         ecc_point_zclear(&r);
    3131             : 
    3132         532 :                         mpz_init(x2);
    3133         532 :                         mpz_init(y2);
    3134         532 :                         ecc_point_get(&pub, x2, y2);
    3135             : 
    3136             :                         /* verify that k*(Gx,Gy)=(x,y) */
    3137         532 :                         if (mpz_cmp(x1, x2) != 0 || mpz_cmp(y1, y2) != 0) {
    3138           0 :                                 ret =
    3139           0 :                                     gnutls_assert_val
    3140             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    3141           0 :                                 goto gost_cleanup;
    3142             :                         }
    3143             : 
    3144             :                         ret = 0;
    3145             : 
    3146         532 :                       gost_cleanup:
    3147         532 :                         ecc_scalar_zclear(&priv);
    3148         532 :                         ecc_point_clear(&pub);
    3149             : 
    3150         532 :                         mpz_clear(x1);
    3151         532 :                         mpz_clear(y1);
    3152         532 :                         mpz_clear(x2);
    3153         532 :                         mpz_clear(y2);
    3154             :                 }
    3155         532 :                 break;
    3156             : #endif
    3157             :         default:
    3158           0 :                 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    3159             :         }
    3160             : 
    3161             :         return ret;
    3162             : }
    3163             : 
    3164             : static int
    3165           1 : wrap_nettle_pk_verify_pub_params(gnutls_pk_algorithm_t algo,
    3166             :                              const gnutls_pk_params_st * params)
    3167             : {
    3168           1 :         int ret;
    3169             : 
    3170           1 :         switch (algo) {
    3171             :         case GNUTLS_PK_RSA:
    3172             :         case GNUTLS_PK_RSA_PSS:
    3173             :         case GNUTLS_PK_DSA:
    3174             :         case GNUTLS_PK_EDDSA_ED25519:
    3175             :         case GNUTLS_PK_EDDSA_ED448:
    3176             :                 return 0;
    3177           0 :         case GNUTLS_PK_ECDSA:
    3178             :                 {
    3179             :                         /* just verify that x and y lie on the curve */
    3180           0 :                         struct ecc_point r, pub;
    3181           0 :                         const struct ecc_curve *curve;
    3182             : 
    3183           0 :                         if (params->params_nr != ECC_PUBLIC_PARAMS)
    3184           0 :                                 return
    3185           0 :                                     gnutls_assert_val
    3186             :                                     (GNUTLS_E_INVALID_REQUEST);
    3187             : 
    3188           0 :                         curve = get_supported_nist_curve(params->curve);
    3189           0 :                         if (curve == NULL)
    3190           0 :                                 return
    3191           0 :                                     gnutls_assert_val
    3192             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    3193             : 
    3194           0 :                         ret = _ecc_params_to_pubkey(params, &pub, curve);
    3195           0 :                         if (ret < 0)
    3196           0 :                                 return gnutls_assert_val(ret);
    3197             : 
    3198           0 :                         ecc_point_init(&r, curve);
    3199             :                         /* verify that x,y lie on the curve */
    3200           0 :                         ret =
    3201           0 :                             ecc_point_set(&r, TOMPZ(params->params[ECC_X]),
    3202           0 :                                           TOMPZ(params->params[ECC_Y]));
    3203           0 :                         if (ret == 0) {
    3204           0 :                                 ret =
    3205           0 :                                     gnutls_assert_val
    3206             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    3207           0 :                                 goto ecc_cleanup;
    3208             :                         }
    3209           0 :                         ecc_point_clear(&r);
    3210             : 
    3211           0 :                         ret = 0;
    3212             : 
    3213           0 :                       ecc_cleanup:
    3214           0 :                         ecc_point_clear(&pub);
    3215             :                 }
    3216           0 :                 break;
    3217             : #if ENABLE_GOST
    3218           0 :         case GNUTLS_PK_GOST_01:
    3219             :         case GNUTLS_PK_GOST_12_256:
    3220             :         case GNUTLS_PK_GOST_12_512:
    3221             :                 {
    3222             :                         /* just verify that x and y lie on the curve */
    3223           0 :                         struct ecc_point r, pub;
    3224           0 :                         const struct ecc_curve *curve;
    3225             : 
    3226           0 :                         if (params->params_nr != GOST_PUBLIC_PARAMS)
    3227           0 :                                 return
    3228           0 :                                     gnutls_assert_val
    3229             :                                     (GNUTLS_E_INVALID_REQUEST);
    3230             : 
    3231           0 :                         curve = get_supported_gost_curve(params->curve);
    3232           0 :                         if (curve == NULL)
    3233           0 :                                 return
    3234           0 :                                     gnutls_assert_val
    3235             :                                     (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    3236             : 
    3237           0 :                         ret = _gost_params_to_pubkey(params, &pub, curve);
    3238           0 :                         if (ret < 0)
    3239           0 :                                 return gnutls_assert_val(ret);
    3240             : 
    3241           0 :                         ecc_point_init(&r, curve);
    3242             :                         /* verify that x,y lie on the curve */
    3243           0 :                         ret =
    3244           0 :                             ecc_point_set(&r, TOMPZ(params->params[GOST_X]),
    3245           0 :                                           TOMPZ(params->params[GOST_Y]));
    3246           0 :                         if (ret == 0) {
    3247           0 :                                 ret =
    3248           0 :                                     gnutls_assert_val
    3249             :                                     (GNUTLS_E_ILLEGAL_PARAMETER);
    3250           0 :                                 goto gost_cleanup;
    3251             :                         }
    3252           0 :                         ecc_point_clear(&r);
    3253             : 
    3254           0 :                         ret = 0;
    3255             : 
    3256           0 :                       gost_cleanup:
    3257           0 :                         ecc_point_clear(&pub);
    3258             :                 }
    3259           0 :                 break;
    3260             : #endif
    3261             :         default:
    3262           0 :                 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    3263             :         }
    3264             : 
    3265             :         return ret;
    3266             : }
    3267             : 
    3268        5063 : static int calc_rsa_exp(gnutls_pk_params_st * params)
    3269             : {
    3270        5063 :         bigint_t tmp;
    3271        5063 :         int ret;
    3272             : 
    3273        5063 :         if (params->params_nr < RSA_PRIVATE_PARAMS - 2) {
    3274           0 :                 gnutls_assert();
    3275           0 :                 return GNUTLS_E_INTERNAL_ERROR;
    3276             :         }
    3277             : 
    3278        5063 :         params->params[RSA_E1] = params->params[RSA_E2] = NULL;
    3279             : 
    3280        5063 :         ret = _gnutls_mpi_init_multi(&tmp, &params->params[RSA_E1], &params->params[RSA_E2], NULL);
    3281        5063 :         if (ret < 0)
    3282           0 :                 return gnutls_assert_val(ret);
    3283             : 
    3284             :         /* [6] = d % p-1, [7] = d % q-1 */
    3285        5063 :         _gnutls_mpi_sub_ui(tmp, params->params[RSA_PRIME1], 1);
    3286        5063 :         ret =
    3287        5063 :             _gnutls_mpi_modm(params->params[RSA_E1], params->params[RSA_PRIV] /*d */ , tmp);
    3288        5063 :         if (ret < 0)
    3289           3 :                 goto fail;
    3290             : 
    3291        5060 :         _gnutls_mpi_sub_ui(tmp, params->params[RSA_PRIME2], 1);
    3292        5060 :         ret =
    3293        5060 :             _gnutls_mpi_modm(params->params[RSA_E2], params->params[RSA_PRIV] /*d */ , tmp);
    3294        5060 :         if (ret < 0)
    3295           2 :                 goto fail;
    3296             : 
    3297        5058 :         zrelease_mpi_key(&tmp);
    3298             : 
    3299             :         return 0;
    3300             : 
    3301           5 : fail:
    3302           5 :         zrelease_mpi_key(&tmp);
    3303           5 :         zrelease_mpi_key(&params->params[RSA_E1]);
    3304           5 :         zrelease_mpi_key(&params->params[RSA_E2]);
    3305             : 
    3306             :         return ret;
    3307             : }
    3308             : 
    3309           1 : static int calc_rsa_priv(gnutls_pk_params_st * params)
    3310             : {
    3311           1 :         bigint_t lcm, p1, q1;
    3312           1 :         int ret;
    3313             : 
    3314           1 :         params->params[RSA_PRIV] = NULL;
    3315             : 
    3316           1 :         ret = _gnutls_mpi_init_multi(&params->params[RSA_PRIV], &lcm, &p1, &q1, NULL);
    3317           1 :         if (ret < 0)
    3318           0 :                 return gnutls_assert_val(ret);
    3319             : 
    3320             :         /* lcm(p - 1, q - 1) */
    3321           1 :         mpz_sub_ui(p1, params->params[RSA_PRIME1], 1);
    3322           1 :         mpz_sub_ui(q1, params->params[RSA_PRIME2], 1);
    3323           1 :         mpz_lcm(lcm, p1, q1);
    3324             : 
    3325           1 :         zrelease_mpi_key(&p1);
    3326           1 :         zrelease_mpi_key(&q1);
    3327             : 
    3328             :         /* d = e^{-1} (mod lcm) */
    3329           1 :         ret = mpz_invert(params->params[RSA_PRIV], params->params[RSA_PUB], lcm);
    3330             : 
    3331           1 :         zrelease_mpi_key(&lcm);
    3332             : 
    3333           1 :         if (ret == 0) {
    3334           0 :                 zrelease_mpi_key(&params->params[RSA_PRIV]);
    3335           0 :                 return GNUTLS_E_INVALID_REQUEST;
    3336             :         }
    3337             : 
    3338             :         return 0;
    3339             : }
    3340             : 
    3341             : static int
    3342       16679 : wrap_nettle_pk_fixup(gnutls_pk_algorithm_t algo,
    3343             :                      gnutls_direction_t direction,
    3344             :                      gnutls_pk_params_st * params)
    3345             : {
    3346       16679 :         int ret;
    3347             : 
    3348       16679 :         if (direction != GNUTLS_IMPORT)
    3349             :                 return 0;
    3350             : 
    3351       16322 :         if (algo == GNUTLS_PK_RSA) {
    3352        5071 :                 struct rsa_private_key priv;
    3353             : 
    3354        5071 :                 if (params->params[RSA_PRIV] == NULL) {
    3355           1 :                         ret = calc_rsa_priv(params);
    3356           1 :                         if (ret < 0)
    3357          21 :                                 return gnutls_assert_val(ret);
    3358           1 :                         params->params_nr++;
    3359             :                 }
    3360             : 
    3361             :                 /* do not trust the generated values. Some old private keys
    3362             :                  * generated by us have mess on the values. Those were very
    3363             :                  * old but it seemed some of the shipped example private
    3364             :                  * keys were as old.
    3365             :                  */
    3366        5071 :                 if (params->params_nr < RSA_PRIVATE_PARAMS - 3)
    3367           0 :                         return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);
    3368             : 
    3369        5071 :                 if (params->params[RSA_COEF] == NULL) {
    3370           5 :                         ret = _gnutls_mpi_init(&params->params[RSA_COEF]);
    3371           5 :                         if (ret < 0)
    3372           0 :                                 return gnutls_assert_val(ret);
    3373             :                 }
    3374             : 
    3375        5071 :                 if (mpz_cmp_ui(TOMPZ(params->params[RSA_PRIME1]), 0) == 0)
    3376           3 :                         return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);
    3377             : 
    3378        5068 :                 if (mpz_invert(TOMPZ(params->params[RSA_COEF]),
    3379        5068 :                                TOMPZ(params->params[RSA_PRIME2]),
    3380             :                                TOMPZ(params->params[RSA_PRIME1])) == 0)
    3381           5 :                         return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);
    3382             : 
    3383             :                 /* calculate exp1 [6] and exp2 [7] */
    3384        5063 :                 zrelease_mpi_key(&params->params[RSA_E1]);
    3385        5063 :                 zrelease_mpi_key(&params->params[RSA_E2]);
    3386             : 
    3387             :                 /* marks RSA_COEF as present */
    3388        5063 :                 params->params_nr = RSA_PRIVATE_PARAMS - 2;
    3389        5063 :                 ret = calc_rsa_exp(params);
    3390        5063 :                 if (ret < 0)
    3391           5 :                         return gnutls_assert_val(ret);
    3392             : 
    3393        5058 :                 params->params_nr = RSA_PRIVATE_PARAMS;
    3394             : 
    3395             :                 /* perform nettle's internal checks */
    3396        5058 :                 _rsa_params_to_privkey(params, &priv);
    3397        5058 :                 ret = rsa_private_key_prepare(&priv);
    3398        5058 :                 if (ret == 0) {
    3399           8 :                         return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);
    3400             :                 }
    3401       11251 :         } else if (algo == GNUTLS_PK_EDDSA_ED25519 ||
    3402       11251 :                    algo == GNUTLS_PK_EDDSA_ED448) {
    3403        8174 :                 if (unlikely(get_eddsa_curve(algo) != params->curve))
    3404           0 :                         return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    3405             : 
    3406        8174 :                 if (params->raw_priv.data == NULL)
    3407           0 :                         return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);
    3408             : 
    3409        8174 :                 if (params->raw_pub.data == NULL) {
    3410        4087 :                         params->raw_pub.data = gnutls_malloc(params->raw_priv.size);
    3411             :                 }
    3412             : 
    3413        8174 :                 if (params->raw_pub.data == NULL)
    3414           0 :                         return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
    3415             : 
    3416       16348 :                 ret = eddsa_public_key(algo,
    3417             :                                        params->raw_pub.data,
    3418        8174 :                                        params->raw_priv.data);
    3419        8174 :                 if (ret < 0) {
    3420           0 :                         gnutls_free(params->raw_pub.data);
    3421           0 :                         return ret;
    3422             :                 }
    3423             : 
    3424        8174 :                 params->raw_pub.size = params->raw_priv.size;
    3425        3077 :         } else if (algo == GNUTLS_PK_RSA_PSS) {
    3426          99 :                 if (params->params_nr < RSA_PRIVATE_PARAMS - 3)
    3427           0 :                         return gnutls_assert_val(GNUTLS_E_PK_INVALID_PRIVKEY);
    3428             : 
    3429          99 :                 if (params->spki.rsa_pss_dig != 0) {
    3430          75 :                         unsigned pub_size = nettle_mpz_sizeinbase_256_u(TOMPZ(params->params[RSA_MODULUS]));
    3431             :                         /* sanity check for private key */
    3432          75 :                         CHECK_INVALID_RSA_PSS_PARAMS(gnutls_hash_get_len(params->spki.rsa_pss_dig),
    3433             :                                                      params->spki.salt_size, pub_size,
    3434             :                                                      GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
    3435             :                 }
    3436             : 
    3437             :         }
    3438             : #if ENABLE_GOST
    3439        2978 :         else if (algo == GNUTLS_PK_GOST_01 ||
    3440        2978 :                  algo == GNUTLS_PK_GOST_12_256 ||
    3441             :                  algo == GNUTLS_PK_GOST_12_512) {
    3442          90 :                 struct ecc_point r;
    3443          90 :                 struct ecc_scalar priv;
    3444          90 :                 const struct ecc_curve *curve;
    3445             : 
    3446          90 :                 if (params->params_nr != GOST_PRIVATE_PARAMS)
    3447           0 :                         return gnutls_assert_val
    3448             :                                 (GNUTLS_E_INVALID_REQUEST);
    3449             : 
    3450          90 :                 curve = get_supported_gost_curve(params->curve);
    3451          90 :                 if (curve == NULL)
    3452           0 :                         return gnutls_assert_val
    3453             :                                 (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
    3454             : 
    3455          90 :                 if (ecc_bit_size(curve) < _gnutls_mpi_get_nbits(params->params[GOST_K]))
    3456           2 :                         gostdsa_unmask_key(curve, TOMPZ(params->params[GOST_K]));
    3457             : 
    3458          90 :                 ret = _gost_params_to_privkey(params, &priv, curve);
    3459          90 :                 if (ret < 0) {
    3460           0 :                         return gnutls_assert_val(ret);
    3461             :                 }
    3462             : 
    3463          90 :                 ecc_point_init(&r, curve);
    3464          90 :                 gost_point_mul_g(&r, &priv);
    3465             : 
    3466          90 :                 ecc_point_get(&r, params->params[GOST_X],
    3467          90 :                                   params->params[GOST_Y]);
    3468             : 
    3469          90 :                 ecc_point_clear(&r);
    3470          90 :                 ecc_scalar_clear(&priv);
    3471             :         }
    3472             : #endif
    3473             : 
    3474             :         return 0;
    3475             : }
    3476             : 
    3477             : int crypto_pk_prio = INT_MAX;
    3478             : 
    3479             : gnutls_crypto_pk_st _gnutls_pk_ops = {
    3480             :         .encrypt = _wrap_nettle_pk_encrypt,
    3481             :         .decrypt = _wrap_nettle_pk_decrypt,
    3482             :         .decrypt2 = _wrap_nettle_pk_decrypt2,
    3483             :         .sign = _wrap_nettle_pk_sign,
    3484             :         .verify = _wrap_nettle_pk_verify,
    3485             :         .verify_priv_params = wrap_nettle_pk_verify_priv_params,
    3486             :         .verify_pub_params = wrap_nettle_pk_verify_pub_params,
    3487             :         .generate_params = wrap_nettle_pk_generate_params,
    3488             :         .generate_keys = wrap_nettle_pk_generate_keys,
    3489             :         .pk_fixup_private_params = wrap_nettle_pk_fixup,
    3490             :         .derive = _wrap_nettle_pk_derive,
    3491             :         .curve_exists = _wrap_nettle_pk_curve_exists,
    3492             : };

Generated by: LCOV version 1.14