summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-11-05 21:22:17 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-11-05 21:28:58 +0100
commit124dfe0de2321a4c4a3383c8866f6a1dbd45d635 (patch)
tree4dcc5b51189b0311d77fadcac8785562383e6092
parent5b541a346638429712f8a9db8ced61f1b5ffcec4 (diff)
downloadgnutls-124dfe0de2321a4c4a3383c8866f6a1dbd45d635.tar.gz
Verify that received ECDH public key lies on the curve.
-rw-r--r--lib/auth/ecdh_common.c21
-rw-r--r--lib/crypto-backend.h40
-rw-r--r--lib/gnutls_ecc.c20
-rw-r--r--lib/gnutls_privkey.c3
-rw-r--r--lib/gnutls_pubkey.c10
-rw-r--r--lib/nettle/Makefile.am2
-rw-r--r--lib/nettle/ecc.h8
-rw-r--r--lib/nettle/ecc_free.c2
-rw-r--r--lib/nettle/ecc_make_key.c16
-rw-r--r--lib/nettle/ecc_projective_check_point.c106
-rw-r--r--lib/nettle/ecc_projective_dbl_point.c207
-rw-r--r--lib/nettle/ecc_sign_hash.c2
-rw-r--r--lib/nettle/pk.c38
-rw-r--r--lib/pkcs11_write.c2
-rw-r--r--lib/x509/key_decode.c4
-rw-r--r--lib/x509/key_encode.c4
-rw-r--r--lib/x509/mpi.c2
-rw-r--r--lib/x509/privkey.c18
-rw-r--r--lib/x509/x509_int.h27
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(&params->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(&params->params[3], val, val_size);
+ ret = _gnutls_mpi_scan_nz(&params->params[4], val, val_size);
if (ret < 0)
{
gnutls_assert();
@@ -186,7 +202,7 @@ int ret;
goto cleanup;
}
- ret = _gnutls_mpi_scan_nz(&params->params[4], val, val_size);
+ ret = _gnutls_mpi_scan_nz(&params->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, &params->params[5],
- &params->params[6]);
+ return _gnutls_ecc_ansi_x963_import (der, dersize, &params->params[6],
+ &params->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