Coverage Report

Created: 2024-06-20 06:28

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