aboutsummaryrefslogtreecommitdiff
path: root/crypto/ec
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2019-05-28 20:13:54 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2019-05-28 20:13:54 +0000
commit10d08b8de39401736faf1f37a8c6121cdd6814c8 (patch)
tree3eb1a0ee652178757d91d9bab8053aa7bece8c27 /crypto/ec
parentd98e9d8878016a75426544bc9110d4ce403abf61 (diff)
Diffstat (limited to 'crypto/ec')
-rw-r--r--crypto/ec/ec2_oct.c21
-rw-r--r--crypto/ec/ec_lib.c22
-rw-r--r--crypto/ec/ec_mult.c4
-rw-r--r--crypto/ec/ecp_nistp521.c11
-rw-r--r--crypto/ec/ecp_oct.c12
-rw-r--r--crypto/ec/ectest.c98
6 files changed, 135 insertions, 33 deletions
diff --git a/crypto/ec/ec2_oct.c b/crypto/ec/ec2_oct.c
index 0d04cc692303..5da3cd8bf51c 100644
--- a/crypto/ec/ec2_oct.c
+++ b/crypto/ec/ec2_oct.c
@@ -14,7 +14,7 @@
*
*/
/* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -299,7 +299,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
BN_CTX *ctx)
{
point_conversion_form_t form;
- int y_bit;
+ int y_bit, m;
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y, *yxi;
size_t field_len, enc_len;
@@ -332,7 +332,8 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
return EC_POINT_set_to_infinity(group, point);
}
- field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+ m = EC_GROUP_get_degree(group);
+ field_len = (m + 7) / 8;
enc_len =
(form ==
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
@@ -357,7 +358,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
if (!BN_bin2bn(buf + 1, field_len, x))
goto err;
- if (BN_ucmp(x, &group->field) >= 0) {
+ if (BN_num_bits(x) > m) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
@@ -369,7 +370,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
} else {
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
goto err;
- if (BN_ucmp(y, &group->field) >= 0) {
+ if (BN_num_bits(y) > m) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
@@ -382,16 +383,14 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
}
}
+ /*
+ * EC_POINT_set_affine_coordinates_GF2m is responsible for checking that
+ * the point is on the curve.
+ */
if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
goto err;
}
- /* test required by X9.62 */
- if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
- }
-
ret = 1;
err:
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index df56484b5ee2..cd2c420176f7 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -3,7 +3,7 @@
* Originally written by Bodo Moeller for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -872,7 +872,15 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+ if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
+ return 0;
+
+ if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
+ ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
+ EC_R_POINT_IS_NOT_ON_CURVE);
+ return 0;
+ }
+ return 1;
}
#ifndef OPENSSL_NO_EC2M
@@ -890,7 +898,15 @@ int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+ if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
+ return 0;
+
+ if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
+ ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
+ EC_R_POINT_IS_NOT_ON_CURVE);
+ return 0;
+ }
+ return 1;
}
#endif
diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c
index da71526818f8..a784a99ce91e 100644
--- a/crypto/ec/ec_mult.c
+++ b/crypto/ec/ec_mult.c
@@ -3,7 +3,7 @@
* Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -519,7 +519,7 @@ static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
ret = 1;
err:
- EC_POINT_free(s);
+ EC_POINT_clear_free(s);
BN_CTX_end(ctx);
BN_CTX_free(new_ctx);
diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c
index 90989c5a0769..1a42068c01f9 100644
--- a/crypto/ec/ecp_nistp521.c
+++ b/crypto/ec/ecp_nistp521.c
@@ -356,10 +356,15 @@ static void felem_diff64(felem out, const felem in)
static void felem_diff_128_64(largefelem out, const felem in)
{
/*
- * In order to prevent underflow, we add 0 mod p before subtracting.
+ * In order to prevent underflow, we add 64p mod p (which is equivalent
+ * to 0 mod p) before subtracting. p is 2^521 - 1, i.e. in binary a 521
+ * digit number with all bits set to 1. See "The representation of field
+ * elements" comment above for a description of how limbs are used to
+ * represent a number. 64p is represented with 8 limbs containing a number
+ * with 58 bits set and one limb with a number with 57 bits set.
*/
- static const limb two63m6 = (((limb) 1) << 62) - (((limb) 1) << 5);
- static const limb two63m5 = (((limb) 1) << 62) - (((limb) 1) << 4);
+ static const limb two63m6 = (((limb) 1) << 63) - (((limb) 1) << 6);
+ static const limb two63m5 = (((limb) 1) << 63) - (((limb) 1) << 5);
out[0] += two63m6 - in[0];
out[1] += two63m5 - in[1];
diff --git a/crypto/ec/ecp_oct.c b/crypto/ec/ecp_oct.c
index 1bc3f39ad15f..6943ceeec6d2 100644
--- a/crypto/ec/ecp_oct.c
+++ b/crypto/ec/ecp_oct.c
@@ -5,7 +5,7 @@
* OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -408,16 +408,14 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
}
}
+ /*
+ * EC_POINT_set_affine_coordinates_GFp is responsible for checking that
+ * the point is on the curve.
+ */
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
goto err;
}
- /* test required by X9.62 */
- if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
- }
-
ret = 1;
err:
diff --git a/crypto/ec/ectest.c b/crypto/ec/ectest.c
index 5e1ef5093383..73f73744576a 100644
--- a/crypto/ec/ectest.c
+++ b/crypto/ec/ectest.c
@@ -3,7 +3,7 @@
* Originally written by Bodo Moeller for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -325,7 +325,7 @@ static void prime_field_tests(void)
EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 =
NULL, *P_384 = NULL, *P_521 = NULL;
EC_POINT *P, *Q, *R;
- BIGNUM *x, *y, *z;
+ BIGNUM *x, *y, *z, *yplusone;
unsigned char buf[100];
size_t i, len;
int k;
@@ -405,7 +405,8 @@ static void prime_field_tests(void)
x = BN_new();
y = BN_new();
z = BN_new();
- if (!x || !y || !z)
+ yplusone = BN_new();
+ if (x == NULL || y == NULL || z == NULL || yplusone == NULL)
ABORT;
if (!BN_hex2bn(&x, "D"))
@@ -542,6 +543,14 @@ static void prime_field_tests(void)
ABORT;
if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32"))
ABORT;
+ if (!BN_add(yplusone, y, BN_value_one()))
+ ABORT;
+ /*
+ * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
+ * and therefore setting the coordinates should fail.
+ */
+ if (EC_POINT_set_affine_coordinates_GFp(group, P, x, yplusone, ctx))
+ ABORT;
if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
ABORT;
if (EC_POINT_is_on_curve(group, P, ctx) <= 0)
@@ -613,6 +622,15 @@ static void prime_field_tests(void)
if (0 != BN_cmp(y, z))
ABORT;
+ if (!BN_add(yplusone, y, BN_value_one()))
+ ABORT;
+ /*
+ * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
+ * and therefore setting the coordinates should fail.
+ */
+ if (EC_POINT_set_affine_coordinates_GFp(group, P, x, yplusone, ctx))
+ ABORT;
+
fprintf(stdout, "verify degree ...");
if (EC_GROUP_get_degree(group) != 192)
ABORT;
@@ -668,6 +686,15 @@ static void prime_field_tests(void)
if (0 != BN_cmp(y, z))
ABORT;
+ if (!BN_add(yplusone, y, BN_value_one()))
+ ABORT;
+ /*
+ * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
+ * and therefore setting the coordinates should fail.
+ */
+ if (EC_POINT_set_affine_coordinates_GFp(group, P, x, yplusone, ctx))
+ ABORT;
+
fprintf(stdout, "verify degree ...");
if (EC_GROUP_get_degree(group) != 224)
ABORT;
@@ -728,6 +755,15 @@ static void prime_field_tests(void)
if (0 != BN_cmp(y, z))
ABORT;
+ if (!BN_add(yplusone, y, BN_value_one()))
+ ABORT;
+ /*
+ * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
+ * and therefore setting the coordinates should fail.
+ */
+ if (EC_POINT_set_affine_coordinates_GFp(group, P, x, yplusone, ctx))
+ ABORT;
+
fprintf(stdout, "verify degree ...");
if (EC_GROUP_get_degree(group) != 256)
ABORT;
@@ -783,6 +819,15 @@ static void prime_field_tests(void)
if (0 != BN_cmp(y, z))
ABORT;
+ if (!BN_add(yplusone, y, BN_value_one()))
+ ABORT;
+ /*
+ * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
+ * and therefore setting the coordinates should fail.
+ */
+ if (EC_POINT_set_affine_coordinates_GFp(group, P, x, yplusone, ctx))
+ ABORT;
+
fprintf(stdout, "verify degree ...");
if (EC_GROUP_get_degree(group) != 384)
ABORT;
@@ -844,6 +889,15 @@ static void prime_field_tests(void)
if (0 != BN_cmp(y, z))
ABORT;
+ if (!BN_add(yplusone, y, BN_value_one()))
+ ABORT;
+ /*
+ * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
+ * and therefore setting the coordinates should fail.
+ */
+ if (EC_POINT_set_affine_coordinates_GFp(group, P, x, yplusone, ctx))
+ ABORT;
+
fprintf(stdout, "verify degree ...");
if (EC_GROUP_get_degree(group) != 521)
ABORT;
@@ -858,6 +912,10 @@ static void prime_field_tests(void)
/* more tests using the last curve */
+ /* Restore the point that got mangled in the (x, y + 1) test. */
+ if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
+ ABORT;
+
if (!EC_POINT_copy(Q, P))
ABORT;
if (EC_POINT_is_at_infinity(group, Q))
@@ -987,6 +1045,7 @@ static void prime_field_tests(void)
BN_free(x);
BN_free(y);
BN_free(z);
+ BN_free(yplusone);
if (P_160)
EC_GROUP_free(P_160);
@@ -1007,6 +1066,13 @@ static void prime_field_tests(void)
# ifdef OPENSSL_EC_BIN_PT_COMP
# define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
if (!BN_hex2bn(&x, _x)) ABORT; \
+ if (!BN_hex2bn(&y, _y)) ABORT; \
+ if (!BN_add(yplusone, y, BN_value_one())) ABORT; \
+ /* \
+ * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, \
+ * and therefore setting the coordinates should fail. \
+ */ \
+ if (EC_POINT_set_affine_coordinates_GF2m(group, P, x, yplusone, ctx)) ABORT; \
if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
if (!BN_hex2bn(&z, _order)) ABORT; \
@@ -1025,6 +1091,12 @@ static void prime_field_tests(void)
# define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
if (!BN_hex2bn(&x, _x)) ABORT; \
if (!BN_hex2bn(&y, _y)) ABORT; \
+ if (!BN_add(yplusone, y, BN_value_one())) ABORT; \
+ /* \
+ * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, \
+ * and therefore setting the coordinates should fail. \
+ */ \
+ if (EC_POINT_set_affine_coordinates_GF2m(group, P, x, yplusone, ctx)) ABORT; \
if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
if (!BN_hex2bn(&z, _order)) ABORT; \
@@ -1062,7 +1134,7 @@ static void char2_field_tests(void)
EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 =
NULL, *C2_B571 = NULL;
EC_POINT *P, *Q, *R;
- BIGNUM *x, *y, *z, *cof;
+ BIGNUM *x, *y, *z, *cof, *yplusone;
unsigned char buf[100];
size_t i, len;
int k;
@@ -1076,7 +1148,7 @@ static void char2_field_tests(void)
p = BN_new();
a = BN_new();
b = BN_new();
- if (!p || !a || !b)
+ if (p == NULL || a == NULL || b == NULL)
ABORT;
if (!BN_hex2bn(&p, "13"))
@@ -1142,7 +1214,8 @@ static void char2_field_tests(void)
y = BN_new();
z = BN_new();
cof = BN_new();
- if (!x || !y || !z || !cof)
+ yplusone = BN_new();
+ if (x == NULL || y == NULL || z == NULL || cof == NULL || yplusone == NULL)
ABORT;
if (!BN_hex2bn(&x, "6"))
@@ -1504,6 +1577,7 @@ static void char2_field_tests(void)
BN_free(y);
BN_free(z);
BN_free(cof);
+ BN_free(yplusone);
if (C2_K163)
EC_GROUP_free(C2_K163);
@@ -1672,7 +1746,7 @@ static const struct nistp_test_params nistp_tests_params[] = {
static void nistp_single_test(const struct nistp_test_params *test)
{
BN_CTX *ctx;
- BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
+ BIGNUM *p, *a, *b, *x, *y, *n, *m, *order, *yplusone;
EC_GROUP *NISTP;
EC_POINT *G, *P, *Q, *Q_CHECK;
@@ -1687,6 +1761,7 @@ static void nistp_single_test(const struct nistp_test_params *test)
m = BN_new();
n = BN_new();
order = BN_new();
+ yplusone = BN_new();
NISTP = EC_GROUP_new(test->meth());
if (!NISTP)
@@ -1709,6 +1784,14 @@ static void nistp_single_test(const struct nistp_test_params *test)
ABORT;
if (!BN_hex2bn(&y, test->Qy))
ABORT;
+ if (!BN_add(yplusone, y, BN_value_one()))
+ ABORT;
+ /*
+ * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
+ * and therefore setting the coordinates should fail.
+ */
+ if (EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, yplusone, ctx))
+ ABORT;
if (!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx))
ABORT;
if (!BN_hex2bn(&x, test->Gx))
@@ -1811,6 +1894,7 @@ static void nistp_single_test(const struct nistp_test_params *test)
BN_free(x);
BN_free(y);
BN_free(order);
+ BN_free(yplusone);
BN_CTX_free(ctx);
}