From 0bcd38f7d8a3ae4ba6bd287fcc0ad07b7a1ef2ba Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 6 Jun 2022 08:40:09 +1000 Subject: [PATCH] ECC, DH: improve encrypted memory implementations --- wolfcrypt/src/ecc.c | 16 ++++++++++++++++ wolfcrypt/src/tfm.c | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index ba9f6a87d..91cea9625 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2788,26 +2788,33 @@ static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, err = mp_init(mu); if (err == MP_OKAY) err = mp_montgomery_calc_normalization(mu, modulus); + /* Generate random value to multiply into p->z. */ if (err == MP_OKAY) err = wc_ecc_gen_k(rng, size, ty, modulus); + /* Convert to montogmery form. */ if (err == MP_OKAY) err = mp_mulmod(ty, mu, modulus, ty); + /* Multiply random value into p->z. */ if (err == MP_OKAY) err = mp_mul(p->z, ty, p->z); if (err == MP_OKAY) err = mp_montgomery_reduce(p->z, modulus, mp); + /* Square random value for X (X' = X / Z^2). */ if (err == MP_OKAY) err = mp_sqr(ty, tx); if (err == MP_OKAY) err = mp_montgomery_reduce(tx, modulus, mp); + /* Multiply square of random by random value for Y. */ if (err == MP_OKAY) err = mp_mul(ty, tx, ty); if (err == MP_OKAY) err = mp_montgomery_reduce(ty, modulus, mp); + /* Multiply square into X. */ if (err == MP_OKAY) err = mp_mul(p->x, tx, p->x); if (err == MP_OKAY) err = mp_montgomery_reduce(p->x, modulus, mp); + /* Multiply cube into Y (Y' = Y / Z^3). */ if (err == MP_OKAY) err = mp_mul(p->y, ty, p->y); if (err == MP_OKAY) @@ -3108,12 +3115,21 @@ static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q, /* Ensure 'swap' changes to a previously unseen value. */ swap += (kt->dp[j] >> cnt) + swap; + /* R[0] = 2*R[0] */ err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus, mp); if (err == MP_OKAY) { + /* R[0] = R[1] + R[0] */ err = ecc_projective_add_point_safe(R[set + 0], R[set + 1], R[set + 0], a, modulus, mp, &infinity); } + /* R[1]->z * 2 - same point. */ + mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z); + mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x); + mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x); + mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y); + mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y); + mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y); } /* Step 4: end for */ /* Swap back if last bit is 0. */ diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 0744837cd..f9115f1c4 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -2423,12 +2423,16 @@ static int _fp_exptmod_nct(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) #ifdef TFM_TIMING_RESISTANT #if DIGIT_BIT <= 16 #define WINSIZE 2 + #define WINMASK 0x3 #elif DIGIT_BIT <= 32 #define WINSIZE 3 + #define WINMASK 0x7 #elif DIGIT_BIT <= 64 #define WINSIZE 4 + #define WINMASK 0xf #elif DIGIT_BIT <= 128 #define WINSIZE 5 + #define WINMASK 0x1f #endif /* y = 2**x (mod b) @@ -2544,7 +2548,12 @@ static int _fp_exptmod_base_2(fp_int * X, int digits, fp_int * P, y = (int)(buf >> (DIGIT_BIT - 1)) & 1; buf <<= (fp_digit)1; /* add bit to the window */ + #ifndef WC_PROTECT_ENCRYPTED_MEM bitbuf |= (y << (WINSIZE - ++bitcpy)); + #else + /* Ensure value changes even when y is zero. */ + bitbuf += (WINMASK + 1) + (y << (WINSIZE - ++bitcpy)); + #endif if (bitcpy == WINSIZE) { /* ok window is filled so square as required and multiply */ @@ -2567,7 +2576,12 @@ static int _fp_exptmod_base_2(fp_int * X, int digits, fp_int * P, } /* then multiply by 2^bitbuf */ + #ifndef WC_PROTECT_ENCRYPTED_MEM err = fp_mul_2d(res, bitbuf, res); + #else + /* Get the window bits. */ + err = fp_mul_2d(res, bitbuf & WINMASK, res); + #endif if (err != FP_OKAY) { #ifdef WOLFSSL_SMALL_STACK XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -2592,7 +2606,12 @@ static int _fp_exptmod_base_2(fp_int * X, int digits, fp_int * P, /* empty window and reset */ bitcpy = 0; + #ifndef WC_PROTECT_ENCRYPTED_MEM bitbuf = 0; + #else + /* Ensure value is new even when bottom bits are 0. */ + bitbuf = (WINMASK + 1) + (bitbuf & ~WINMASK); + #endif } }