Coverage Report

Created: 2023-03-26 07:33

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