diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-11-05 21:22:17 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-11-05 21:28:58 +0100 |
commit | 124dfe0de2321a4c4a3383c8866f6a1dbd45d635 (patch) | |
tree | 4dcc5b51189b0311d77fadcac8785562383e6092 | |
parent | 5b541a346638429712f8a9db8ced61f1b5ffcec4 (diff) | |
download | gnutls-124dfe0de2321a4c4a3383c8866f6a1dbd45d635.tar.gz |
Verify that received ECDH public key lies on the curve.
-rw-r--r-- | lib/auth/ecdh_common.c | 21 | ||||
-rw-r--r-- | lib/crypto-backend.h | 40 | ||||
-rw-r--r-- | lib/gnutls_ecc.c | 20 | ||||
-rw-r--r-- | lib/gnutls_privkey.c | 3 | ||||
-rw-r--r-- | lib/gnutls_pubkey.c | 10 | ||||
-rw-r--r-- | lib/nettle/Makefile.am | 2 | ||||
-rw-r--r-- | lib/nettle/ecc.h | 8 | ||||
-rw-r--r-- | lib/nettle/ecc_free.c | 2 | ||||
-rw-r--r-- | lib/nettle/ecc_make_key.c | 16 | ||||
-rw-r--r-- | lib/nettle/ecc_projective_check_point.c | 106 | ||||
-rw-r--r-- | lib/nettle/ecc_projective_dbl_point.c | 207 | ||||
-rw-r--r-- | lib/nettle/ecc_sign_hash.c | 2 | ||||
-rw-r--r-- | lib/nettle/pk.c | 38 | ||||
-rw-r--r-- | lib/pkcs11_write.c | 2 | ||||
-rw-r--r-- | lib/x509/key_decode.c | 4 | ||||
-rw-r--r-- | lib/x509/key_encode.c | 4 | ||||
-rw-r--r-- | lib/x509/mpi.c | 2 | ||||
-rw-r--r-- | lib/x509/privkey.c | 18 | ||||
-rw-r--r-- | lib/x509/x509_int.h | 27 |
19 files changed, 233 insertions, 299 deletions
diff --git a/lib/auth/ecdh_common.c b/lib/auth/ecdh_common.c index 2b3672b853..2ea3d9534a 100644 --- a/lib/auth/ecdh_common.c +++ b/lib/auth/ecdh_common.c @@ -51,13 +51,14 @@ int ret; pub.params[2] = session->key->ecdh_params.params[2]; pub.params[3] = session->key->ecdh_params.params[3]; pub.params[4] = session->key->ecdh_params.params[4]; - pub.params[5] = session->key->ecdh_x; - pub.params[6] = session->key->ecdh_y; - pub.params[7] = _gnutls_mpi_new(1); - if (pub.params[7] == NULL) + pub.params[5] = session->key->ecdh_params.params[5]; + pub.params[6] = session->key->ecdh_x; + pub.params[7] = session->key->ecdh_y; + pub.params[8] = _gnutls_mpi_new(1); + if (pub.params[8] == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - _gnutls_mpi_set_ui(pub.params[7], 1); + _gnutls_mpi_set_ui(pub.params[8], 1); if (psk_key == NULL) ret = _gnutls_pk_derive(GNUTLS_PK_ECC, &session->key->key, &session->key->ecdh_params, &pub); @@ -86,7 +87,7 @@ int ret; ret = 0; cleanup: - _gnutls_mpi_release(&pub.params[7]); + _gnutls_mpi_release(&pub.params[8]); /* no longer needed */ _gnutls_mpi_release (&session->key->ecdh_x); @@ -148,8 +149,8 @@ _gnutls_gen_ecdh_common_client_kx_int (gnutls_session_t session, if (ret < 0) return gnutls_assert_val(ret); - ret = _gnutls_ecc_ansi_x963_export(curve, session->key->ecdh_params.params[5] /* x */, - session->key->ecdh_params.params[6] /* y */, &out); + ret = _gnutls_ecc_ansi_x963_export(curve, session->key->ecdh_params.params[6] /* x */, + session->key->ecdh_params.params[7] /* y */, &out); if (ret < 0) return gnutls_assert_val(ret); @@ -234,8 +235,8 @@ int _gnutls_ecdh_common_print_server_kx (gnutls_session_t session, gnutls_buffer if (ret < 0) return gnutls_assert_val(ret); - ret = _gnutls_ecc_ansi_x963_export(curve, session->key->ecdh_params.params[5] /* x */, - session->key->ecdh_params.params[6] /* y */, &out); + ret = _gnutls_ecc_ansi_x963_export(curve, session->key->ecdh_params.params[6] /* x */, + session->key->ecdh_params.params[7] /* y */, &out); if (ret < 0) return gnutls_assert_val(ret); diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h index d0ba265378..0a2002534a 100644 --- a/lib/crypto-backend.h +++ b/lib/crypto-backend.h @@ -183,6 +183,35 @@ void gnutls_pk_params_release (gnutls_pk_params_st * p); void gnutls_pk_params_init (gnutls_pk_params_st * p); + +#define MAX_PUBLIC_PARAMS_SIZE 4 /* ok for RSA and DSA */ + +/* parameters should not be larger than this limit */ +#define DSA_PUBLIC_PARAMS 4 +#define RSA_PUBLIC_PARAMS 2 +#define ECC_PUBLIC_PARAMS 8 + + +#define MAX_PRIV_PARAMS_SIZE GNUTLS_MAX_PK_PARAMS /* ok for RSA and DSA */ + +/* parameters should not be larger than this limit */ +#define DSA_PRIVATE_PARAMS 5 +#define RSA_PRIVATE_PARAMS 8 +#define ECC_PRIVATE_PARAMS 9 + +#if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0 +#error INCREASE MAX_PRIV_PARAMS +#endif + +#if MAX_PRIV_PARAMS_SIZE - ECC_PRIVATE_PARAMS < 0 +#error INCREASE MAX_PRIV_PARAMS +#endif + +#if MAX_PRIV_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0 +#error INCREASE MAX_PRIV_PARAMS +#endif + + /* params are: * RSA: * [0] is modulus @@ -208,11 +237,12 @@ * [0] is prime * [1] is order * [2] is A - * [3] is Gx - * [4] is Gy - * [5] is x - * [6] is y - * [7] is k (private key) + * [3] is B + * [4] is Gx + * [5] is Gy + * [6] is x + * [7] is y + * [8] is k (private key) */ /** diff --git a/lib/gnutls_ecc.c b/lib/gnutls_ecc.c index cd2a4b3556..4d85f9f112 100644 --- a/lib/gnutls_ecc.c +++ b/lib/gnutls_ecc.c @@ -161,6 +161,22 @@ int ret; goto cleanup; } params->params_nr++; + + val_size = sizeof(val); + ret = _gnutls_hex2bin(st->B, strlen(st->B), val, &val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + ret = _gnutls_mpi_scan_nz(¶ms->params[3], val, val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + params->params_nr++; val_size = sizeof(val); ret = _gnutls_hex2bin(st->Gx, strlen(st->Gx), val, &val_size); @@ -170,7 +186,7 @@ int ret; goto cleanup; } - ret = _gnutls_mpi_scan_nz(¶ms->params[3], val, val_size); + ret = _gnutls_mpi_scan_nz(¶ms->params[4], val, val_size); if (ret < 0) { gnutls_assert(); @@ -186,7 +202,7 @@ int ret; goto cleanup; } - ret = _gnutls_mpi_scan_nz(¶ms->params[4], val, val_size); + ret = _gnutls_mpi_scan_nz(¶ms->params[5], val, val_size); if (ret < 0) { gnutls_assert(); diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index f572ce5e92..3b43eaf52a 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -165,6 +165,7 @@ privkey_to_pubkey (gnutls_pk_algorithm_t pk, pub->params[4] = _gnutls_mpi_copy (priv->params[4]); pub->params[5] = _gnutls_mpi_copy (priv->params[5]); pub->params[6] = _gnutls_mpi_copy (priv->params[6]); + pub->params[7] = _gnutls_mpi_copy (priv->params[7]); pub->params_nr = ECC_PUBLIC_PARAMS; pub->flags = priv->flags; @@ -172,7 +173,7 @@ privkey_to_pubkey (gnutls_pk_algorithm_t pk, if (pub->params[0] == NULL || pub->params[1] == NULL || pub->params[2] == NULL || pub->params[3] == NULL || pub->params[4] == NULL || pub->params[5] == NULL || - pub->params[6] == NULL) + pub->params[6] == NULL || pub->params[7] == NULL) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index 52a0720562..74ce0b80f5 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -738,7 +738,7 @@ gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve, *curve = key->params.flags; /* X */ - ret = _gnutls_mpi_dprint_lz (key->params.params[5], x); + ret = _gnutls_mpi_dprint_lz (key->params.params[6], x); if (ret < 0) { gnutls_assert (); @@ -746,7 +746,7 @@ gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve, } /* Y */ - ret = _gnutls_mpi_dprint_lz (key->params.params[6], y); + ret = _gnutls_mpi_dprint_lz (key->params.params[7], y); if (ret < 0) { gnutls_assert (); @@ -1135,7 +1135,7 @@ gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key, if (ret < 0) return gnutls_assert_val(ret); - if (_gnutls_mpi_scan_nz (&key->params.params[5], x->data, x->size)) + if (_gnutls_mpi_scan_nz (&key->params.params[6], x->data, x->size)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; @@ -1143,7 +1143,7 @@ gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key, } key->params.params_nr++; - if (_gnutls_mpi_scan_nz (&key->params.params[6], y->data, y->size)) + if (_gnutls_mpi_scan_nz (&key->params.params[7], y->data, y->size)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; @@ -1197,7 +1197,7 @@ gnutls_pubkey_import_ecc_x962 (gnutls_pubkey_t key, } ret = _gnutls_ecc_ansi_x963_import(ecpoint->data, ecpoint->size, - &key->params.params[5], &key->params.params[6]); + &key->params.params[6], &key->params.params[7]); if (ret < 0) { gnutls_assert (); diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am index 86afffc4f9..24552dc943 100644 --- a/lib/nettle/Makefile.am +++ b/lib/nettle/Makefile.am @@ -36,5 +36,5 @@ noinst_LTLIBRARIES = libcrypto.la libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c rnd.c init.c egd.c egd.h \ multi.c ecc_free.c ecc.h ecc_make_key.c ecc_shared_secret.c \ ecc_map.c ecc_mulmod.c ecc_points.c ecc_projective_dbl_point_3.c \ - ecc_projective_add_point.c ecc_projective_dbl_point.c \ + ecc_projective_add_point.c ecc_projective_check_point.c \ ecc_sign_hash.c ecc_verify_hash.c gnettle.h diff --git a/lib/nettle/ecc.h b/lib/nettle/ecc.h index ea2b837488..d5a5fa013e 100644 --- a/lib/nettle/ecc.h +++ b/lib/nettle/ecc.h @@ -69,6 +69,7 @@ typedef struct { mpz_t prime; mpz_t order; mpz_t A; + mpz_t B; mpz_t Gx; mpz_t Gy; @@ -79,12 +80,11 @@ typedef struct { mpz_t k; } ecc_key; -int ecc_test(void); void ecc_sizes(int *low, int *high); int ecc_get_size(ecc_key *key); int ecc_make_key(void *random_ctx, nettle_random_func random, ecc_key *key, const ecc_set_type *dp); -int ecc_make_key_ex(void *random_ctx, nettle_random_func random, ecc_key *key, mpz_t prime, mpz_t order, mpz_t A, mpz_t Gx, mpz_t Gy); +int ecc_make_key_ex(void *random_ctx, nettle_random_func random, ecc_key *key, mpz_t prime, mpz_t order, mpz_t A, mpz_t B, mpz_t Gx, mpz_t Gy); void ecc_free(ecc_key *key); int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, @@ -115,6 +115,10 @@ int ecc_mulmod(mpz_t k, ecc_point *G, ecc_point *R, mpz_t a, mpz_t modulus, int /* map P to affine from projective */ int ecc_map(ecc_point *P, mpz_t modulus); +/* check whether a point lies on the curve */ +int ecc_projective_check_point (ecc_point * P, mpz_t b, mpz_t modulus); + /* helper functions */ int mp_init_multi(mpz_t *a, ...); void mp_clear_multi(mpz_t *a, ...); + diff --git a/lib/nettle/ecc_free.c b/lib/nettle/ecc_free.c index ab04d033db..d5708ddb5e 100644 --- a/lib/nettle/ecc_free.c +++ b/lib/nettle/ecc_free.c @@ -37,7 +37,7 @@ void ecc_free (ecc_key * key) { mp_clear_multi (&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, - &key->prime, &key->order, &key->Gx, &key->Gy, &key->A, NULL); + &key->prime, &key->order, &key->Gx, &key->Gy, &key->A, &key->B, NULL); } /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_free.c,v $ */ diff --git a/lib/nettle/ecc_make_key.c b/lib/nettle/ecc_make_key.c index 3476276d97..4972eabb30 100644 --- a/lib/nettle/ecc_make_key.c +++ b/lib/nettle/ecc_make_key.c @@ -43,7 +43,7 @@ int ecc_make_key_ex (void *random_ctx, nettle_random_func random, ecc_key * key, - mpz_t prime, mpz_t order, mpz_t A, mpz_t Gx, mpz_t Gy) + mpz_t prime, mpz_t order, mpz_t A, mpz_t B, mpz_t Gx, mpz_t Gy) { int err; ecc_point *base; @@ -67,7 +67,7 @@ ecc_make_key_ex (void *random_ctx, nettle_random_func random, ecc_key * key, /* setup the key variables */ if ((err = mp_init_multi (&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, - &key->prime, &key->order, &key->A, &key->Gx, &key->Gy, + &key->prime, &key->order, &key->A, &key->B, &key->Gx, &key->Gy, NULL)) != 0) { goto ERR_BUF; @@ -85,6 +85,7 @@ ecc_make_key_ex (void *random_ctx, nettle_random_func random, ecc_key * key, mpz_set (key->Gx, Gx); mpz_set (key->Gy, Gy); mpz_set (key->A, A); + mpz_set (key->B, B); mpz_set (base->x, key->Gx); mpz_set (base->y, key->Gy); @@ -111,7 +112,7 @@ ecc_make_key_ex (void *random_ctx, nettle_random_func random, ecc_key * key, goto cleanup; errkey: mp_clear_multi (&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, - &key->order, &key->prime, &key->Gx, &key->Gy, &key->A, + &key->order, &key->prime, &key->Gx, &key->Gy, &key->A, &key->B, NULL); cleanup: ecc_del_point (base); @@ -124,11 +125,11 @@ int ecc_make_key (void *random_ctx, nettle_random_func random, ecc_key * key, const ecc_set_type * dp) { - mpz_t prime, order, Gx, Gy, A; + mpz_t prime, order, Gx, Gy, A, B; int err; /* setup the key variables */ - if ((err = mp_init_multi (&prime, &order, &A, &Gx, &Gy, NULL)) != 0) + if ((err = mp_init_multi (&prime, &order, &A, &B, &Gx, &Gy, NULL)) != 0) { goto cleanup; } @@ -139,10 +140,11 @@ ecc_make_key (void *random_ctx, nettle_random_func random, ecc_key * key, mpz_set_str (Gx, (char *) dp->Gx, 16); mpz_set_str (Gy, (char *) dp->Gy, 16); mpz_set_str (A, (char *) dp->A, 16); + mpz_set_str (B, (char *) dp->B, 16); - err = ecc_make_key_ex (random_ctx, random, key, prime, order, A, Gx, Gy); + err = ecc_make_key_ex (random_ctx, random, key, prime, order, A, B, Gx, Gy); - mp_clear_multi (&prime, &order, &A, &Gx, &Gy, NULL); + mp_clear_multi (&prime, &order, &A, &B, &Gx, &Gy, NULL); cleanup: return err; } diff --git a/lib/nettle/ecc_projective_check_point.c b/lib/nettle/ecc_projective_check_point.c new file mode 100644 index 0000000000..42abeea18b --- /dev/null +++ b/lib/nettle/ecc_projective_check_point.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * This file is part of GNUTLS. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +#include "ecc.h" +#include <gnutls_errors.h> + +#ifdef ECC_SECP_CURVES_ONLY + +/* + @file ecc_projective_check_point.c +*/ + +/* + Checks whether a point lies on the curve y^2 = x^3 - 3x + b + @param P The point to check + @param modulus The modulus of the field the ECC curve is in + @param b The "B" value of the curve + @return 0 on success +*/ +int ecc_projective_check_point (ecc_point * P, mpz_t b, mpz_t modulus) +{ + mpz_t t1, t2, t3; + int err; + + if (P == NULL || b == NULL || modulus == NULL) + return -1; + + if ((err = mp_init_multi (&t1, &t2, &t3, NULL)) != 0) + { + return err; + } + + if (mpz_cmp_ui (P->z, 1) != 0) + { + gnutls_assert (); + return -1; + } + + /* t1 = Z * Z */ + mpz_mul (t1, P->y, P->y); + mpz_mod (t1, t1, modulus); /* t1 = y^2 */ + + mpz_mul (t2, P->x, P->x); + mpz_mod (t2, t2, modulus); + + mpz_mul (t2, P->x, t2); + mpz_mod (t2, t2, modulus); /* t2 = x^3 */ + + mpz_add (t3, P->x, P->x); + if (mpz_cmp (t3, modulus) >= 0) + { + mpz_sub (t3, t3, modulus); + } + + mpz_add (t3, t3, P->x); /* t3 = 3x */ + if (mpz_cmp (t3, modulus) >= 0) + { + mpz_sub (t3, t3, modulus); + } + + mpz_sub (t1, t1, t2); /* t1 = y^2 - x^3 */ + if (mpz_cmp_ui (t1, 0) < 0) + { + mpz_add (t1, t1, modulus); + } + + mpz_add (t1, t1, t3); /* t1 = y^2 - x^3 + 3x */ + if (mpz_cmp (t1, modulus) >= 0) + { + mpz_sub (t1, t1, modulus); + } + + mpz_sub (t1, t1, b); /* t1 = y^2 - x^3 + 3x - b */ + if (mpz_cmp_ui (t1, 0) < 0) + { + mpz_add (t1, t1, modulus); + } + + if (mpz_cmp_ui (t1, 0) != 0) + { + return -1; + } + else + { + return 0; + } +} + +#endif diff --git a/lib/nettle/ecc_projective_dbl_point.c b/lib/nettle/ecc_projective_dbl_point.c deleted file mode 100644 index 2df4e52769..0000000000 --- a/lib/nettle/ecc_projective_dbl_point.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* Implements ECC point doubling over Z/pZ for curve y^2 = x^3 + ax + b - */ -#include "ecc.h" - -#ifndef ECC_SECP_CURVES_ONLY - -/* - Double an ECC point - @param P The point to double - @param R [out] The destination of the double - @param a The "a" value from curve - @param modulus The modulus of the field the ECC curve is in - @return 0 on success -*/ -int -ecc_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a, - mpz_t modulus) -{ - mpz_t t1, m, s; - int err; - - if (P == NULL || R == NULL || modulus == NULL) - return -1; - - /* - algorithm used: - if (Y == 0) - return POINT_AT_INFINITY - S = 4*X*Y^2 - M = 3*X^2 + a*Z^4 - X' = M^2 - 2*S - Y' = M*(S - X') - 8*Y^4 - Z' = 2*Y*Z - return (X', Y', Z') - */ - - if (mpz_cmp_ui(P->y, 0) == 0) - { - /* point at infinity - * under jacobian coordinates - */ - mpz_set(R->x, 1); - mpz_set(R->y, 1); - mpz_set(R->z, 0); - - return 0; - } - - if ((err = mp_init_multi (&t1, &m, &s, NULL)) != 0) - { - return err; - } - - if (P != R) - { - mpz_set (R->x, P->x); - mpz_set (R->y, P->y); - mpz_set (R->z, P->z); - } - - - /* m = Z * Z */ - mpz_mul (m, R->z, R->z); - mpz_mod (m, m, modulus); - - /* Calculate Z and get rid of it */ - /* Z = Y * Z */ - mpz_mul (R->z, R->y, R->z); - mpz_mod (R->z, R->z, modulus); - /* Z = 2Z */ - mpz_add (R->z, R->z, R->z); - if (mpz_cmp (R->z, modulus) >= 0) - { - mpz_sub (R->z, R->z, modulus); - } - - /* continue with M and S calculations */ - - /* m = m * m = z^4 */ - mpz_mul (m, m, m); - mpz_mod (m, m, modulus); - - /* m = a * m = a*z^4 */ - mpz_mul (m, a, m); - mpz_mod (m, m, modulus); - - /* Y = 2y */ - mpz_add (R->y, R->y, R->y); - if (mpz_cmp (R->y, modulus) >= 0) - { - mpz_sub (R->y, R->y, modulus); - } - - /* Y = Y * Y = 4y^2 */ - mpz_mul (R->y, R->y, R->y); - mpz_mod (R->y, R->y, modulus); - - /* s = X*Y = 4xy^2 */ - mpz_mul (s, R->x, R->y); - mpz_mod (s, s, modulus); - - /* X = x^2 */ - mpz_mul (R->x, R->x, R->x); - mpz_mod (R->x, R->x, modulus); - - /* t1 = 2X = 2x^2 */ - mpz_add (t1, R->x, R->x); - if (mpz_cmp (t1, modulus) >= 0) - { - mpz_sub (t1, t1, modulus); - } - - /* t1 = t1+X = 3X = 3x^2 */ - mpz_add (t1, t1, R->x); - if (mpz_cmp (t1, modulus) >= 0) - { - mpz_sub (t1, t1, modulus); - } - - /* m = t1+m = 3x^2 + a*z^4 */ - mpz_add (m, m, t1); - if (mpz_cmp (m, modulus) >= 0) - { - mpz_sub (m, m, modulus); - } - - /* - X' = M^2 - 2*S - Y' = M*(S - X') - 8*Y^4 - */ - - /* Y = Y*Y = 16y^4 */ - mpz_mul (R->y, R->y, R->y); - mpz_mod (R->y, R->y, modulus); - - /* Y = 8y^4 */ - if (mpz_odd_p (R->y)) - { - mpz_add (R->y, R->y, modulus); - } - mpz_divexact_ui (R->y, R->y, 2); - - /* X = m^2 */ - mpz_mul (R->x, m, m); - mpz_mod (R->x, R->x, modulus); - - /* X = X - s = m^2 - s */ - mpz_sub (R->x, R->x, s); - if (mpz_cmp_ui (R->x, 0) < 0) - { - mpz_add (R->x, R->x, modulus); - } - - /* X = X - s = m^2 - 2s */ - mpz_sub (R->x, R->x, s); - if (mpz_cmp_ui (R->x, 0) < 0) - { - mpz_add (R->x, R->x, modulus); - } - - /* t1 = s - X */ - mpz_sub (t1, s, R->x); - if (mpz_cmp_ui (t1, 0) < 0) - { - mpz_add (t1, t1, modulus); - } - - /* t1 = M * t1 = M * (s-X) */ - mpz_mul (t1, m, t1); - mpz_mod (t1, t1, modulus); - - /* Y = t1 - Y = (M * (s-X)) - 8y^4 */ - mpz_sub (R->y, t1, R->y); - if (mpz_cmp_ui (R->y, 0) < 0) - { - mpz_add (R->y, R->y, modulus); - } - - err = 0; - - mp_clear_multi (&t1, &m, &s, NULL); - return err; -} - -#endif diff --git a/lib/nettle/ecc_sign_hash.c b/lib/nettle/ecc_sign_hash.c index ab7f94309d..04c3f1d0c8 100644 --- a/lib/nettle/ecc_sign_hash.c +++ b/lib/nettle/ecc_sign_hash.c @@ -72,7 +72,7 @@ ecc_sign_hash (const unsigned char *in, unsigned long inlen, { if ((err = ecc_make_key_ex (random_ctx, random, &pubkey, key->prime, - key->order, key->A, key->Gx, key->Gy)) != 0) + key->order, key->A, key->B, key->Gx, key->Gy)) != 0) { goto errnokey; } diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 794a2c99be..826c27b064 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -89,11 +89,12 @@ _ecc_params_to_privkey(const gnutls_pk_params_st * pk_params, memcpy(&priv->prime, pk_params->params[0], sizeof(mpz_t)); memcpy(&priv->order, pk_params->params[1], sizeof(mpz_t)); memcpy(&priv->A, pk_params->params[2], sizeof(mpz_t)); - memcpy(&priv->Gx, pk_params->params[3], sizeof(mpz_t)); - memcpy(&priv->Gy, pk_params->params[4], sizeof(mpz_t)); - memcpy(&priv->pubkey.x, pk_params->params[5], sizeof(mpz_t)); - memcpy(&priv->pubkey.y, pk_params->params[6], sizeof(mpz_t)); - memcpy(&priv->k, pk_params->params[7], sizeof(mpz_t)); + memcpy(&priv->B, pk_params->params[3], sizeof(mpz_t)); + memcpy(&priv->Gx, pk_params->params[4], sizeof(mpz_t)); + memcpy(&priv->Gy, pk_params->params[5], sizeof(mpz_t)); + memcpy(&priv->pubkey.x, pk_params->params[6], sizeof(mpz_t)); + memcpy(&priv->pubkey.y, pk_params->params[7], sizeof(mpz_t)); + memcpy(&priv->k, pk_params->params[8], sizeof(mpz_t)); mpz_init_set_ui(priv->pubkey.z, 1); } @@ -110,10 +111,11 @@ _ecc_params_to_pubkey(const gnutls_pk_params_st * pk_params, memcpy(&pub->prime, pk_params->params[0], sizeof(mpz_t)); memcpy(&pub->order, pk_params->params[1], sizeof(mpz_t)); memcpy(&pub->A, pk_params->params[2], sizeof(mpz_t)); - memcpy(&pub->Gx, pk_params->params[3], sizeof(mpz_t)); - memcpy(&pub->Gy, pk_params->params[4], sizeof(mpz_t)); - memcpy(&pub->pubkey.x, pk_params->params[5], sizeof(mpz_t)); - memcpy(&pub->pubkey.y, pk_params->params[6], sizeof(mpz_t)); + memcpy(&pub->B, pk_params->params[3], sizeof(mpz_t)); + memcpy(&pub->Gx, pk_params->params[4], sizeof(mpz_t)); + memcpy(&pub->Gy, pk_params->params[5], sizeof(mpz_t)); + memcpy(&pub->pubkey.x, pk_params->params[6], sizeof(mpz_t)); + memcpy(&pub->pubkey.y, pk_params->params[7], sizeof(mpz_t)); mpz_init_set_ui(pub->pubkey.z, 1); } @@ -138,6 +140,12 @@ static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, gnutls_datum_t * o _ecc_params_to_pubkey(pub, &ecc_pub); _ecc_params_to_privkey(priv, &ecc_priv); + + if (ecc_projective_check_point(&ecc_pub.pubkey, pub->params[3], pub->params[0]) != 0) + { + ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto ecc_cleanup; + } sz = ECC_BUF_SIZE; out->data = gnutls_malloc(sz); @@ -792,6 +800,7 @@ rsa_fail: tls_ecc_set.Gx = st->Gx; tls_ecc_set.Gy = st->Gy; tls_ecc_set.A = st->A; + tls_ecc_set.B = st->B; ret = ecc_make_key(NULL, rnd_func, &key, &tls_ecc_set); if (ret != 0) @@ -813,11 +822,12 @@ rsa_fail: mpz_set(TOMPZ(params->params[0]), key.prime); mpz_set(TOMPZ(params->params[1]), key.order); mpz_set(TOMPZ(params->params[2]), key.A); - mpz_set(TOMPZ(params->params[3]), key.Gx); - mpz_set(TOMPZ(params->params[4]), key.Gy); - mpz_set(TOMPZ(params->params[5]), key.pubkey.x); - mpz_set(TOMPZ(params->params[6]), key.pubkey.y); - mpz_set(TOMPZ(params->params[7]), key.k); + mpz_set(TOMPZ(params->params[3]), key.B); + mpz_set(TOMPZ(params->params[4]), key.Gx); + mpz_set(TOMPZ(params->params[5]), key.Gy); + mpz_set(TOMPZ(params->params[6]), key.pubkey.x); + mpz_set(TOMPZ(params->params[7]), key.pubkey.y); + mpz_set(TOMPZ(params->params[8]), key.k); ecc_fail: ecc_free(&key); diff --git a/lib/pkcs11_write.c b/lib/pkcs11_write.c index b87855a69e..8d867fb605 100644 --- a/lib/pkcs11_write.c +++ b/lib/pkcs11_write.c @@ -447,7 +447,7 @@ gnutls_pkcs11_copy_x509_privkey (const char *token_url, goto cleanup; } - ret = _gnutls_mpi_dprint_lz(&key->params.params[7], &x); + ret = _gnutls_mpi_dprint_lz(&key->params.params[8], &x); if (ret < 0) { gnutls_assert (); diff --git a/lib/x509/key_decode.c b/lib/x509/key_decode.c index a13a72529e..7d430e81fe 100644 --- a/lib/x509/key_decode.c +++ b/lib/x509/key_decode.c @@ -102,8 +102,8 @@ _gnutls_x509_read_ecc_pubkey (opaque * der, int dersize, gnutls_pk_params_st * p /* Eventhough RFC5480 defines the public key to be an ECPoint (i.e. OCTET STRING), * it is actually copied in raw there. Why do they use ASN.1 anyway? */ - return _gnutls_ecc_ansi_x963_import (der, dersize, ¶ms->params[5], - ¶ms->params[6]); + return _gnutls_ecc_ansi_x963_import (der, dersize, ¶ms->params[6], + ¶ms->params[7]); } diff --git a/lib/x509/key_encode.c b/lib/x509/key_encode.c index 42df697989..1caf72172c 100644 --- a/lib/x509/key_encode.c +++ b/lib/x509/key_encode.c @@ -118,7 +118,7 @@ _gnutls_x509_write_ecc_pubkey (gnutls_pk_params_st * params, if (params->params_nr < ECC_PUBLIC_PARAMS) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - result = _gnutls_ecc_ansi_x963_export(params->flags, params->params[5], params->params[6], /*&out*/der); + result = _gnutls_ecc_ansi_x963_export(params->flags, params->params[6], params->params[7], /*&out*/der); if (result < 0) return gnutls_assert_val(result); @@ -580,7 +580,7 @@ _gnutls_asn1_encode_ecc (ASN1_TYPE * c2, gnutls_pk_params_st * params) if (params->params_nr != ECC_PRIVATE_PARAMS || oid == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - ret = _gnutls_ecc_ansi_x963_export(params->flags, params->params[5], params->params[6], &pubkey); + ret = _gnutls_ecc_ansi_x963_export(params->flags, params->params[6], params->params[7], &pubkey); if (ret < 0) return gnutls_assert_val(ret); diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c index e4a2a6c6f4..cf90bf9a91 100644 --- a/lib/x509/mpi.c +++ b/lib/x509/mpi.c @@ -29,8 +29,6 @@ #include "common.h" #include "x509_int.h" #include <gnutls_num.h> -#include <gnutls_ecc.h> - /* Reads an Integer from the DER encoded data */ diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index 8a2ec3cf5c..f7d7f3d01a 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -307,8 +307,8 @@ _gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key, goto error; } - ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[5], - &pkey->params.params[6]); + ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[6], + &pkey->params.params[7]); _gnutls_free_datum(&out); if (ret < 0) @@ -319,7 +319,7 @@ _gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key, pkey->params.params_nr += 2; /* read the private key */ - ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[7]); + ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[8]); if (ret < 0) { gnutls_assert(); @@ -860,7 +860,7 @@ gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key, if (ret < 0) return gnutls_assert_val(ret); - if (_gnutls_mpi_scan_nz (&key->params.params[5], x->data, x->size)) + if (_gnutls_mpi_scan_nz (&key->params.params[6], x->data, x->size)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; @@ -868,7 +868,7 @@ gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key, } key->params.params_nr++; - if (_gnutls_mpi_scan_nz (&key->params.params[6], y->data, y->size)) + if (_gnutls_mpi_scan_nz (&key->params.params[7], y->data, y->size)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; @@ -876,7 +876,7 @@ gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key, } key->params.params_nr++; - if (_gnutls_mpi_scan_nz (&key->params.params[7], k->data, k->size)) + if (_gnutls_mpi_scan_nz (&key->params.params[8], k->data, k->size)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; @@ -1022,7 +1022,7 @@ int gnutls_x509_privkey_export_ecc_raw (gnutls_x509_privkey_t key, *curve = key->params.flags; /* X */ - ret = _gnutls_mpi_dprint_lz (key->params.params[5], x); + ret = _gnutls_mpi_dprint_lz (key->params.params[6], x); if (ret < 0) { gnutls_assert (); @@ -1030,7 +1030,7 @@ int gnutls_x509_privkey_export_ecc_raw (gnutls_x509_privkey_t key, } /* Y */ - ret = _gnutls_mpi_dprint_lz (key->params.params[6], y); + ret = _gnutls_mpi_dprint_lz (key->params.params[7], y); if (ret < 0) { gnutls_assert (); @@ -1040,7 +1040,7 @@ int gnutls_x509_privkey_export_ecc_raw (gnutls_x509_privkey_t key, /* K */ - ret = _gnutls_mpi_dprint_lz (key->params.params[7], k); + ret = _gnutls_mpi_dprint_lz (key->params.params[8], k); if (ret < 0) { gnutls_assert (); diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h index 6976b07624..c0dbf7e2d4 100644 --- a/lib/x509/x509_int.h +++ b/lib/x509/x509_int.h @@ -70,33 +70,6 @@ typedef struct gnutls_pkcs7_int ASN1_TYPE pkcs7; } gnutls_pkcs7_int; -#define MAX_PUBLIC_PARAMS_SIZE 4 /* ok for RSA and DSA */ - -/* parameters should not be larger than this limit */ -#define DSA_PUBLIC_PARAMS 4 -#define RSA_PUBLIC_PARAMS 2 -#define ECC_PUBLIC_PARAMS 7 - - -#define MAX_PRIV_PARAMS_SIZE GNUTLS_MAX_PK_PARAMS /* ok for RSA and DSA */ - -/* parameters should not be larger than this limit */ -#define DSA_PRIVATE_PARAMS 5 -#define RSA_PRIVATE_PARAMS 8 -#define ECC_PRIVATE_PARAMS 8 - -#if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0 -#error INCREASE MAX_PRIV_PARAMS -#endif - -#if MAX_PRIV_PARAMS_SIZE - ECC_PRIVATE_PARAMS < 0 -#error INCREASE MAX_PRIV_PARAMS -#endif - -#if MAX_PRIV_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0 -#error INCREASE MAX_PRIV_PARAMS -#endif - typedef struct gnutls_x509_privkey_int { /* the size of params depends on the public |