Coverage Report

Created: 2025-11-16 07:49

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