Coverage Report

Created: 2026-03-31 07:20

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