Coverage Report

Created: 2025-07-23 07:18

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