diff --git a/libica-sles15sp2-x25519-x448-fix-handling-of-non-canonical-values.patch b/libica-sles15sp2-x25519-x448-fix-handling-of-non-canonical-values.patch new file mode 100644 index 0000000..47298b7 --- /dev/null +++ b/libica-sles15sp2-x25519-x448-fix-handling-of-non-canonical-values.patch @@ -0,0 +1,131 @@ +From a3b36ef136e304a1e2dc12ef7b96686202cbd00d Mon Sep 17 00:00:00 2001 +From: Patrick Steuer +Date: Wed, 13 Nov 2019 17:12:43 +0100 +Subject: [PATCH] x25519,x448: fix handling of non-canonical values + +Reduce the peer public key's u-coordinate if it is >= p. + +Signed-off-by: Patrick Steuer +--- + src/s390_ecc.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 91 insertions(+) + +diff --git a/src/s390_ecc.c b/src/s390_ecc.c +index 7654959..62799ee 100644 +--- a/src/s390_ecc.c ++++ b/src/s390_ecc.c +@@ -557,6 +557,91 @@ struct { \ + return rc; + } + ++/* ++ * 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 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; ++ } ++} ++ ++ ++static void s390_x25519_mod_p(unsigned char u[32]) ++{ ++ unsigned char u_red[32]; ++ unsigned int c = 0; ++ int i; ++ ++ memcpy(u_red, u, sizeof(u_red)); ++ ++ c += (unsigned int)u_red[31] + 19; ++ u_red[31] = (unsigned char)c; ++ c >>= 8; ++ ++ for (i = 30; i >= 0; i--) { ++ c += (unsigned int)u_red[i]; ++ u_red[i] = (unsigned char)c; ++ c >>= 8; ++ } ++ ++ 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 s390_x448_mod_p(unsigned char u[56]) ++{ ++ unsigned char u_red[56]; ++ unsigned int c = 0; ++ int i; ++ ++ memcpy(u_red, u, sizeof(u_red)); ++ ++ c += (unsigned int)u_red[55] + 1; ++ u_red[55] = (unsigned char)c; ++ c >>= 8; ++ ++ for (i = 54; i >= 28; i--) { ++ c += (unsigned int)u_red[i]; ++ u_red[i] = (unsigned char)c; ++ c >>= 8; ++ } ++ ++ c += (unsigned int)u_red[27] + 1; ++ u_red[27] = (unsigned char)c; ++ c >>= 8; ++ ++ for (i = 26; i >= 0; i--) { ++ c += (unsigned int)u_red[i]; ++ u_red[i] = (unsigned char)c; ++ c >>= 8; ++ } ++ ++ constant_time_cond_swap_buff(0 - (unsigned char)c, ++ u, u_red, sizeof(u_red)); ++} ++ + int scalar_mulx_cpacf(unsigned char *res_u, + const unsigned char *scalar, + const unsigned char *u, +@@ -598,6 +683,9 @@ struct { \ + s390_flip_endian_32(param.X25519.u, param.X25519.u); + s390_flip_endian_32(param.X25519.scalar, param.X25519.scalar); + ++ /* reduce non-canonical values */ ++ s390_x25519_mod_p(param.X25519.u); ++ + fc = s390_pcc_functions[SCALAR_MULTIPLY_X25519].hw_fc; + rc = s390_pcc(fc, ¶m) ? EIO : 0; + +@@ -619,6 +707,9 @@ struct { \ + s390_flip_endian_64(param.X448.u, param.X448.u); + s390_flip_endian_64(param.X448.scalar, param.X448.scalar); + ++ /* reduce non-canonical values */ ++ s390_x448_mod_p(param.X448.u + 8); ++ + fc = s390_pcc_functions[SCALAR_MULTIPLY_X448].hw_fc; + rc = s390_pcc(fc, ¶m) ? EIO : 0; + +-- +2.13.7 + diff --git a/libica.changes b/libica.changes index 51362b1..ac7f105 100644 --- a/libica.changes +++ b/libica.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Nov 14 22:45:16 UTC 2019 - Mark Post + +- Added libica-sles15sp2-x25519-x448-fix-handling-of-non-canonical-values.patch + (bsc#1156768) + ------------------------------------------------------------------- Tue Oct 15 18:53:36 UTC 2019 - Mark Post diff --git a/libica.spec b/libica.spec index 5d45c5b..71a360c 100644 --- a/libica.spec +++ b/libica.spec @@ -37,6 +37,7 @@ Source4: z90crypt Source5: z90crypt.service Source6: baselibs.conf Source7: %{name}-rpmlintrc +Patch1: libica-sles15sp2-x25519-x448-fix-handling-of-non-canonical-values.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: gcc-c++