Coverage Report

Created: 2026-11-12 07:51

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