Coverage Report

Created: 2024-07-23 07:36

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