From 4d8777cbb6e640d258c5bd812161f4602544f391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 21 Nov 2019 10:02:58 +0100 Subject: [PATCH] Move p from curve structure to its own constant This removes an indirection, which both makes the code smaller and decreases the number of glitching opportunities for an attacker. --- include/tinycrypt/ecc.h | 8 +--- tinycrypt/ecc.c | 90 ++++++++++++++++++++++++----------------- tinycrypt/ecc_dsa.c | 8 ++-- 3 files changed, 58 insertions(+), 48 deletions(-) diff --git a/include/tinycrypt/ecc.h b/include/tinycrypt/ecc.h index 5a4184503..75e6e9213 100644 --- a/include/tinycrypt/ecc.h +++ b/include/tinycrypt/ecc.h @@ -124,7 +124,6 @@ typedef uint64_t uECC_dword_t; struct uECC_Curve_t; typedef const struct uECC_Curve_t * uECC_Curve; struct uECC_Curve_t { - uECC_word_t p[NUM_ECC_WORDS]; uECC_word_t n[NUM_ECC_WORDS]; uECC_word_t G[NUM_ECC_WORDS * 2]; uECC_word_t b[NUM_ECC_WORDS]; @@ -155,14 +154,11 @@ void vli_mmod_fast_secp256r1(unsigned int *result, unsigned int *product); ((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8)) #define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8) +extern const uECC_word_t curve_p[NUM_ECC_WORDS]; + /* definition of curve NIST p-256: */ static const struct uECC_Curve_t curve_secp256r1 = { { - BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), - BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00), - BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), - BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF) - }, { BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3), BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC), BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c index c43ee725f..6f96bd939 100644 --- a/tinycrypt/ecc.c +++ b/tinycrypt/ecc.c @@ -68,6 +68,14 @@ #include "mbedtls/platform_util.h" #include +/* Parameters for curve NIST P-256 aka secp256r1 */ +const uECC_word_t curve_p[NUM_ECC_WORDS] = { + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF) +}; + /* IMPORTANT: Make sure a cryptographically-secure PRNG is set and the platform * has access to enough entropy in order to feed the PRNG regularly. */ #if default_RNG_defined @@ -585,6 +593,8 @@ void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1, uECC_word_t t5[NUM_ECC_WORDS]; wordcount_t num_words = NUM_ECC_WORDS; + (void) curve; + if (uECC_vli_isZero(Z1)) { return; } @@ -595,15 +605,15 @@ void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1, uECC_vli_modMult_fast(Y1, Y1, Z1); /* t2 = y1*z1 = z3 */ uECC_vli_modMult_fast(Z1, Z1, Z1); /* t3 = z1^2 */ - uECC_vli_modAdd(X1, X1, Z1, curve->p); /* t1 = x1 + z1^2 */ - uECC_vli_modAdd(Z1, Z1, Z1, curve->p); /* t3 = 2*z1^2 */ - uECC_vli_modSub(Z1, X1, Z1, curve->p); /* t3 = x1 - z1^2 */ + uECC_vli_modAdd(X1, X1, Z1, curve_p); /* t1 = x1 + z1^2 */ + uECC_vli_modAdd(Z1, Z1, Z1, curve_p); /* t3 = 2*z1^2 */ + uECC_vli_modSub(Z1, X1, Z1, curve_p); /* t3 = x1 - z1^2 */ uECC_vli_modMult_fast(X1, X1, Z1); /* t1 = x1^2 - z1^4 */ - uECC_vli_modAdd(Z1, X1, X1, curve->p); /* t3 = 2*(x1^2 - z1^4) */ - uECC_vli_modAdd(X1, X1, Z1, curve->p); /* t1 = 3*(x1^2 - z1^4) */ + uECC_vli_modAdd(Z1, X1, X1, curve_p); /* t3 = 2*(x1^2 - z1^4) */ + uECC_vli_modAdd(X1, X1, Z1, curve_p); /* t1 = 3*(x1^2 - z1^4) */ if (uECC_vli_testBit(X1, 0)) { - uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p); + uECC_word_t l_carry = uECC_vli_add(X1, X1, curve_p); uECC_vli_rshift1(X1); X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); } else { @@ -612,12 +622,12 @@ void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1, /* t1 = 3/2*(x1^2 - z1^4) = B */ uECC_vli_modMult_fast(Z1, X1, X1); /* t3 = B^2 */ - uECC_vli_modSub(Z1, Z1, t5, curve->p); /* t3 = B^2 - A */ - uECC_vli_modSub(Z1, Z1, t5, curve->p); /* t3 = B^2 - 2A = x3 */ - uECC_vli_modSub(t5, t5, Z1, curve->p); /* t5 = A - x3 */ + uECC_vli_modSub(Z1, Z1, t5, curve_p); /* t3 = B^2 - A */ + uECC_vli_modSub(Z1, Z1, t5, curve_p); /* t3 = B^2 - 2A = x3 */ + uECC_vli_modSub(t5, t5, Z1, curve_p); /* t5 = A - x3 */ uECC_vli_modMult_fast(X1, X1, t5); /* t1 = B * (A - x3) */ /* t4 = B * (A - x3) - y1^4 = y3: */ - uECC_vli_modSub(t4, X1, t4, curve->p); + uECC_vli_modSub(t4, X1, t4, curve_p); uECC_vli_set(X1, Z1); uECC_vli_set(Z1, Y1); @@ -637,10 +647,10 @@ static void x_side_default(uECC_word_t *result, uECC_word_t _3[NUM_ECC_WORDS] = {3}; /* -a = 3 */ uECC_vli_modMult_fast(result, x, x); /* r = x^2 */ - uECC_vli_modSub(result, result, _3, curve->p); /* r = x^2 - 3 */ + uECC_vli_modSub(result, result, _3, curve_p); /* r = x^2 - 3 */ uECC_vli_modMult_fast(result, result, x); /* r = x^3 - 3x */ /* r = x^3 - 3x + b: */ - uECC_vli_modAdd(result, result, curve->b, curve->p); + uECC_vli_modAdd(result, result, curve->b, curve_p); } uECC_Curve uECC_secp256r1(void) @@ -738,13 +748,13 @@ void vli_mmod_fast_secp256r1(unsigned int *result, unsigned int*product) if (carry < 0) { do { - carry += uECC_vli_add(result, result, curve_secp256r1.p); + carry += uECC_vli_add(result, result, curve_p); } while (carry < 0); } else { while (carry || - uECC_vli_cmp_unsafe(curve_secp256r1.p, result) != 1) { - carry -= uECC_vli_sub(result, result, curve_secp256r1.p); + uECC_vli_cmp_unsafe(curve_p, result) != 1) { + carry -= uECC_vli_sub(result, result, curve_p); } } } @@ -795,20 +805,22 @@ static void XYcZ_add_rnd(uECC_word_t * X1, uECC_word_t * Y1, uECC_word_t t5[NUM_ECC_WORDS]; const uECC_Curve curve = &curve_secp256r1; - uECC_vli_modSub(t5, X2, X1, curve->p); /* t5 = x2 - x1 */ + (void) curve; + + uECC_vli_modSub(t5, X2, X1, curve_p); /* t5 = x2 - x1 */ uECC_vli_modMult_rnd(t5, t5, t5, s); /* t5 = (x2 - x1)^2 = A */ uECC_vli_modMult_rnd(X1, X1, t5, s); /* t1 = x1*A = B */ uECC_vli_modMult_rnd(X2, X2, t5, s); /* t3 = x2*A = C */ - uECC_vli_modSub(Y2, Y2, Y1, curve->p); /* t4 = y2 - y1 */ + uECC_vli_modSub(Y2, Y2, Y1, curve_p); /* t4 = y2 - y1 */ uECC_vli_modMult_rnd(t5, Y2, Y2, s); /* t5 = (y2 - y1)^2 = D */ - uECC_vli_modSub(t5, t5, X1, curve->p); /* t5 = D - B */ - uECC_vli_modSub(t5, t5, X2, curve->p); /* t5 = D - B - C = x3 */ - uECC_vli_modSub(X2, X2, X1, curve->p); /* t3 = C - B */ + uECC_vli_modSub(t5, t5, X1, curve_p); /* t5 = D - B */ + uECC_vli_modSub(t5, t5, X2, curve_p); /* t5 = D - B - C = x3 */ + uECC_vli_modSub(X2, X2, X1, curve_p); /* t3 = C - B */ uECC_vli_modMult_rnd(Y1, Y1, X2, s); /* t2 = y1*(C - B) */ - uECC_vli_modSub(X2, X1, t5, curve->p); /* t3 = B - x3 */ + uECC_vli_modSub(X2, X1, t5, curve_p); /* t3 = B - x3 */ uECC_vli_modMult_rnd(Y2, Y2, X2, s); /* t4 = (y2 - y1)*(B - x3) */ - uECC_vli_modSub(Y2, Y2, Y1, curve->p); /* t4 = y3 */ + uECC_vli_modSub(Y2, Y2, Y1, curve_p); /* t4 = y3 */ uECC_vli_set(X2, t5); } @@ -835,30 +847,32 @@ static void XYcZ_addC_rnd(uECC_word_t * X1, uECC_word_t * Y1, uECC_word_t t7[NUM_ECC_WORDS]; const uECC_Curve curve = &curve_secp256r1; - uECC_vli_modSub(t5, X2, X1, curve->p); /* t5 = x2 - x1 */ + (void) curve; + + uECC_vli_modSub(t5, X2, X1, curve_p); /* t5 = x2 - x1 */ uECC_vli_modMult_rnd(t5, t5, t5, s); /* t5 = (x2 - x1)^2 = A */ uECC_vli_modMult_rnd(X1, X1, t5, s); /* t1 = x1*A = B */ uECC_vli_modMult_rnd(X2, X2, t5, s); /* t3 = x2*A = C */ - uECC_vli_modAdd(t5, Y2, Y1, curve->p); /* t5 = y2 + y1 */ - uECC_vli_modSub(Y2, Y2, Y1, curve->p); /* t4 = y2 - y1 */ + uECC_vli_modAdd(t5, Y2, Y1, curve_p); /* t5 = y2 + y1 */ + uECC_vli_modSub(Y2, Y2, Y1, curve_p); /* t4 = y2 - y1 */ - uECC_vli_modSub(t6, X2, X1, curve->p); /* t6 = C - B */ + uECC_vli_modSub(t6, X2, X1, curve_p); /* t6 = C - B */ uECC_vli_modMult_rnd(Y1, Y1, t6, s); /* t2 = y1 * (C - B) = E */ - uECC_vli_modAdd(t6, X1, X2, curve->p); /* t6 = B + C */ + uECC_vli_modAdd(t6, X1, X2, curve_p); /* t6 = B + C */ uECC_vli_modMult_rnd(X2, Y2, Y2, s); /* t3 = (y2 - y1)^2 = D */ - uECC_vli_modSub(X2, X2, t6, curve->p); /* t3 = D - (B + C) = x3 */ + uECC_vli_modSub(X2, X2, t6, curve_p); /* t3 = D - (B + C) = x3 */ - uECC_vli_modSub(t7, X1, X2, curve->p); /* t7 = B - x3 */ + uECC_vli_modSub(t7, X1, X2, curve_p); /* t7 = B - x3 */ uECC_vli_modMult_rnd(Y2, Y2, t7, s); /* t4 = (y2 - y1)*(B - x3) */ /* t4 = (y2 - y1)*(B - x3) - E = y3: */ - uECC_vli_modSub(Y2, Y2, Y1, curve->p); + uECC_vli_modSub(Y2, Y2, Y1, curve_p); uECC_vli_modMult_rnd(t7, t5, t5, s); /* t7 = (y2 + y1)^2 = F */ - uECC_vli_modSub(t7, t7, t6, curve->p); /* t7 = F - (B + C) = x3' */ - uECC_vli_modSub(t6, t7, X1, curve->p); /* t6 = x3' - B */ + uECC_vli_modSub(t7, t7, t6, curve_p); /* t7 = F - (B + C) = x3' */ + uECC_vli_modSub(t6, t7, X1, curve_p); /* t6 = x3' - B */ uECC_vli_modMult_rnd(t6, t6, t5, s); /* t6 = (y2+y1)*(x3' - B) */ /* t2 = (y2+y1)*(x3' - B) - E = y3': */ - uECC_vli_modSub(Y1, t6, Y1, curve->p); + uECC_vli_modSub(Y1, t6, Y1, curve_p); uECC_vli_set(X1, t7); } @@ -896,10 +910,10 @@ static void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point, XYcZ_addC_rnd(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], ws); /* Find final 1/Z value. */ - uECC_vli_modSub(z, Rx[1], Rx[0], curve->p); /* X1 - X0 */ + uECC_vli_modSub(z, Rx[1], Rx[0], curve_p); /* X1 - X0 */ uECC_vli_modMult_fast(z, z, Ry[1 - nb]); /* Yb * (X1 - X0) */ uECC_vli_modMult_fast(z, z, point); /* xP * Yb * (X1 - X0) */ - uECC_vli_modInv(z, z, curve->p); /* 1 / (xP * Yb * (X1 - X0))*/ + uECC_vli_modInv(z, z, curve_p); /* 1 / (xP * Yb * (X1 - X0))*/ /* yP / (xP * Yb * (X1 - X0)) */ uECC_vli_modMult_fast(z, z, point + num_words); /* Xb * yP / (xP * Yb * (X1 - X0)) */ @@ -956,7 +970,7 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point, /* If an RNG function was specified, get a random initial Z value to * protect against side-channel attacks such as Template SPA */ if (g_rng_function) { - if (!uECC_generate_random_int(k2[carry], curve->p, num_words)) { + if (!uECC_generate_random_int(k2[carry], curve_p, num_words)) { r = 0; goto clear_and_out; } @@ -1052,8 +1066,8 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) } /* x and y must be smaller than p. */ - if (uECC_vli_cmp_unsafe(curve->p, point) != 1 || - uECC_vli_cmp_unsafe(curve->p, point + num_words) != 1) { + if (uECC_vli_cmp_unsafe(curve_p, point) != 1 || + uECC_vli_cmp_unsafe(curve_p, point + num_words) != 1) { return -2; } diff --git a/tinycrypt/ecc_dsa.c b/tinycrypt/ecc_dsa.c index 591c8808e..fc2a3fe3e 100644 --- a/tinycrypt/ecc_dsa.c +++ b/tinycrypt/ecc_dsa.c @@ -258,9 +258,9 @@ int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash, uECC_vli_set(sum + num_words, _public + num_words); uECC_vli_set(tx, curve->G); uECC_vli_set(ty, curve->G + num_words); - uECC_vli_modSub(z, sum, tx, curve->p); /* z = x2 - x1 */ + uECC_vli_modSub(z, sum, tx, curve_p); /* z = x2 - x1 */ XYcZ_add(tx, ty, sum, sum + num_words, curve); - uECC_vli_modInv(z, z, curve->p); /* z = 1/z */ + uECC_vli_modInv(z, z, curve_p); /* z = 1/z */ apply_z(sum, sum + num_words, z); /* Use Shamir's trick to calculate u1*G + u2*Q */ @@ -288,13 +288,13 @@ int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash, uECC_vli_set(tx, point); uECC_vli_set(ty, point + num_words); apply_z(tx, ty, z); - uECC_vli_modSub(tz, rx, tx, curve->p); /* Z = x2 - x1 */ + uECC_vli_modSub(tz, rx, tx, curve_p); /* Z = x2 - x1 */ XYcZ_add(tx, ty, rx, ry, curve); uECC_vli_modMult_fast(z, z, tz); } } - uECC_vli_modInv(z, z, curve->p); /* Z = 1/Z */ + uECC_vli_modInv(z, z, curve_p); /* Z = 1/Z */ apply_z(rx, ry, z); /* v = x1 (mod n) */