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