Coverage Report

Created: 2025-03-18 06:55

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