From 677c4a012a7e72b5f2dd239639034f01fad850bf Mon Sep 17 00:00:00 2001 From: Patrick Steuer Date: Sun, 3 Nov 2019 00:32:04 +0100 Subject: s390x assembly pack: process x25519 and x448 non-canonical values ...in constant time. Signed-off-by: Patrick Steuer Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/10339) --- crypto/ec/ecx_meth.c | 17 +++++++++-------- include/internal/constant_time.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 776e88de36..d141fe7b81 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -854,6 +854,7 @@ static const EVP_PKEY_METHOD ed448_pkey_meth = { #ifdef S390X_EC_ASM # include "s390x_arch.h" +# include "internal/constant_time.h" static void s390x_x25519_mod_p(unsigned char u[32]) { @@ -867,16 +868,16 @@ static void s390x_x25519_mod_p(unsigned char u[32]) u_red[31] = (unsigned char)c; c >>= 8; - for (i = 30; c > 0 && i >= 0; i--) { + for (i = 30; i >= 0; i--) { c += (unsigned int)u_red[i]; u_red[i] = (unsigned char)c; c >>= 8; } - if (u_red[0] & 0x80) { - u_red[0] &= 0x7f; - memcpy(u, u_red, sizeof(u_red)); - } + c = (u_red[0] & 0x80) >> 7; + u_red[0] &= 0x7f; + constant_time_cond_swap_buff(0 - (unsigned char)c, + u, u_red, sizeof(u_red)); } static void s390x_x448_mod_p(unsigned char u[56]) @@ -901,14 +902,14 @@ static void s390x_x448_mod_p(unsigned char u[56]) u_red[27] = (unsigned char)c; c >>= 8; - for (i = 26; c > 0 && i >= 0; i--) { + for (i = 26; i >= 0; i--) { c += (unsigned int)u_red[i]; u_red[i] = (unsigned char)c; c >>= 8; } - if (c) - memcpy(u, u_red, sizeof(u_red)); + constant_time_cond_swap_buff(0 - (unsigned char)c, + u, u_red, sizeof(u_red)); } static int s390x_x25519_mul(unsigned char u_dst[32], diff --git a/include/internal/constant_time.h b/include/internal/constant_time.h index d98dae9545..dc75e31df1 100644 --- a/include/internal/constant_time.h +++ b/include/internal/constant_time.h @@ -352,6 +352,34 @@ static ossl_inline void constant_time_cond_swap_64(uint64_t mask, uint64_t *a, *b ^= xor; } +/* + * mask must be 0xFF or 0x00. + * "constant time" is per len. + * + * if (mask) { + * unsigned char tmp[len]; + * + * memcpy(tmp, a, len); + * memcpy(a, b); + * memcpy(b, tmp); + * } + */ +static ossl_inline void constant_time_cond_swap_buff(unsigned char mask, + unsigned char *a, + unsigned char *b, + size_t len) +{ + size_t i; + unsigned char tmp; + + for (i = 0; i < len; i++) { + tmp = a[i] ^ b[i]; + tmp &= mask; + a[i] ^= tmp; + b[i] ^= tmp; + } +} + /* * table is a two dimensional array of bytes. Each row has rowsize elements. * Copies row number idx into out. rowsize and numrows are not considered -- cgit v1.2.3