summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2018-06-25 06:00:18 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2018-07-08 12:26:19 -0400
commitea169a30a6bf6782a05a51d2b9cf73db151eab8b (patch)
tree448a0a4cd4213edf339e00245ff1999ad120e298
parente4e4730698c9138f09ed73dadd1f35d4bb95ada5 (diff)
crypto: ecdh - add public key verification test
According to SP800-56A section 5.6.2.1, the public key to be processed for the ECDH operation shall be checked for appropriateness. When the public key is considered to be an ephemeral key, the partial validation test as defined in SP800-56A section 5.6.2.3.4 can be applied. The partial verification test requires the presence of the field elements of a and b. For the implemented NIST curves, b is defined in FIPS 186-4 appendix D.1.2. The element a is implicitly given with the Weierstrass equation given in D.1.2 where a = p - 3. Without the test, the NIST ACVP testing fails. After adding this check, the NIST ACVP testing passes. Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/ecc.c42
-rw-r--r--crypto/ecc_curve_defs.h22
2 files changed, 56 insertions, 8 deletions
diff --git a/crypto/ecc.c b/crypto/ecc.c
index 815541309a95..8facafd67802 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -1019,6 +1019,36 @@ out:
1019 return ret; 1019 return ret;
1020} 1020}
1021 1021
1022/* SP800-56A section 5.6.2.3.4 partial verification: ephemeral keys only */
1023static int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
1024 struct ecc_point *pk)
1025{
1026 u64 yy[ECC_MAX_DIGITS], xxx[ECC_MAX_DIGITS], w[ECC_MAX_DIGITS];
1027
1028 /* Check 1: Verify key is not the zero point. */
1029 if (ecc_point_is_zero(pk))
1030 return -EINVAL;
1031
1032 /* Check 2: Verify key is in the range [1, p-1]. */
1033 if (vli_cmp(curve->p, pk->x, pk->ndigits) != 1)
1034 return -EINVAL;
1035 if (vli_cmp(curve->p, pk->y, pk->ndigits) != 1)
1036 return -EINVAL;
1037
1038 /* Check 3: Verify that y^2 == (x^3 + a·x + b) mod p */
1039 vli_mod_square_fast(yy, pk->y, curve->p, pk->ndigits); /* y^2 */
1040 vli_mod_square_fast(xxx, pk->x, curve->p, pk->ndigits); /* x^2 */
1041 vli_mod_mult_fast(xxx, xxx, pk->x, curve->p, pk->ndigits); /* x^3 */
1042 vli_mod_mult_fast(w, curve->a, pk->x, curve->p, pk->ndigits); /* a·x */
1043 vli_mod_add(w, w, curve->b, curve->p, pk->ndigits); /* a·x + b */
1044 vli_mod_add(w, w, xxx, curve->p, pk->ndigits); /* x^3 + a·x + b */
1045 if (vli_cmp(yy, w, pk->ndigits) != 0) /* Equation */
1046 return -EINVAL;
1047
1048 return 0;
1049
1050}
1051
1022int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, 1052int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
1023 const u64 *private_key, const u64 *public_key, 1053 const u64 *private_key, const u64 *public_key,
1024 u64 *secret) 1054 u64 *secret)
@@ -1046,16 +1076,20 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
1046 goto out; 1076 goto out;
1047 } 1077 }
1048 1078
1079 ecc_swap_digits(public_key, pk->x, ndigits);
1080 ecc_swap_digits(&public_key[ndigits], pk->y, ndigits);
1081 ret = ecc_is_pubkey_valid_partial(curve, pk);
1082 if (ret)
1083 goto err_alloc_product;
1084
1085 ecc_swap_digits(private_key, priv, ndigits);
1086
1049 product = ecc_alloc_point(ndigits); 1087 product = ecc_alloc_point(ndigits);
1050 if (!product) { 1088 if (!product) {
1051 ret = -ENOMEM; 1089 ret = -ENOMEM;
1052 goto err_alloc_product; 1090 goto err_alloc_product;
1053 } 1091 }
1054 1092
1055 ecc_swap_digits(public_key, pk->x, ndigits);
1056 ecc_swap_digits(&public_key[ndigits], pk->y, ndigits);
1057 ecc_swap_digits(private_key, priv, ndigits);
1058
1059 ecc_point_mult(product, pk, priv, rand_z, curve->p, ndigits); 1093 ecc_point_mult(product, pk, priv, rand_z, curve->p, ndigits);
1060 1094
1061 ecc_swap_digits(product->x, secret, ndigits); 1095 ecc_swap_digits(product->x, secret, ndigits);
diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
index b80f45da829c..94e883a9403f 100644
--- a/crypto/ecc_curve_defs.h
+++ b/crypto/ecc_curve_defs.h
@@ -13,9 +13,11 @@ struct ecc_curve {
13 struct ecc_point g; 13 struct ecc_point g;
14 u64 *p; 14 u64 *p;
15 u64 *n; 15 u64 *n;
16 u64 *a;
17 u64 *b;
16}; 18};
17 19
18/* NIST P-192 */ 20/* NIST P-192: a = p - 3 */
19static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull, 21static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
20 0x188DA80EB03090F6ull }; 22 0x188DA80EB03090F6ull };
21static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull, 23static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull,
@@ -24,6 +26,10 @@ static u64 nist_p192_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull,
24 0xFFFFFFFFFFFFFFFFull }; 26 0xFFFFFFFFFFFFFFFFull };
25static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull, 27static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull,
26 0xFFFFFFFFFFFFFFFFull }; 28 0xFFFFFFFFFFFFFFFFull };
29static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
30 0xFFFFFFFFFFFFFFFEull };
31static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
32 0x64210519E59C80E7ull };
27static struct ecc_curve nist_p192 = { 33static struct ecc_curve nist_p192 = {
28 .name = "nist_192", 34 .name = "nist_192",
29 .g = { 35 .g = {
@@ -32,10 +38,12 @@ static struct ecc_curve nist_p192 = {
32 .ndigits = 3, 38 .ndigits = 3,
33 }, 39 },
34 .p = nist_p192_p, 40 .p = nist_p192_p,
35 .n = nist_p192_n 41 .n = nist_p192_n,
42 .a = nist_p192_a,
43 .b = nist_p192_b
36}; 44};
37 45
38/* NIST P-256 */ 46/* NIST P-256: a = p - 3 */
39static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull, 47static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
40 0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull }; 48 0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull };
41static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull, 49static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,
@@ -44,6 +52,10 @@ static u64 nist_p256_p[] = { 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull,
44 0x0000000000000000ull, 0xFFFFFFFF00000001ull }; 52 0x0000000000000000ull, 0xFFFFFFFF00000001ull };
45static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull, 53static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
46 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull }; 54 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull };
55static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
56 0x0000000000000000ull, 0xFFFFFFFF00000001ull };
57static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
58 0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
47static struct ecc_curve nist_p256 = { 59static struct ecc_curve nist_p256 = {
48 .name = "nist_256", 60 .name = "nist_256",
49 .g = { 61 .g = {
@@ -52,7 +64,9 @@ static struct ecc_curve nist_p256 = {
52 .ndigits = 4, 64 .ndigits = 4,
53 }, 65 },
54 .p = nist_p256_p, 66 .p = nist_p256_p,
55 .n = nist_p256_n 67 .n = nist_p256_n,
68 .a = nist_p256_a,
69 .b = nist_p256_b
56}; 70};
57 71
58#endif 72#endif