From 3e79af7d30c9c71029873ebad4dead13d09e298c Mon Sep 17 00:00:00 2001 From: Vadim Sukhomlinov Date: Tue, 21 Sep 2021 16:12:01 -0700 Subject: cr50: move several few static inline functions into dcrypto/internal.h Several functions like lo32(), hi32(), clz() were defined into bn.c, but clz and ctz are used in fips_rand.c. Move these functions into internal.h to allow reuse. Both __builtin_ctz() and __builtin_clz() have undefined behavior for argument which is zero. Explicitly set result to 32 in such case. It was the case for __builtin_clz() in bn.c, but not for variants used in TRNG health tests. BUG=None TEST=make BOARD=cr50 CRYPTO_TEST=1; TCG tests Signed-off-by: Vadim Sukhomlinov Change-Id: Ifc6fa7f820080bdad0f14fc079163f4976369724 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3174592 Reviewed-by: Vadim Sukhomlinov Reviewed-by: Vadim Bendebury Reviewed-by: Andrey Pronin Tested-by: Vadim Sukhomlinov Commit-Queue: Vadim Sukhomlinov --- board/cr50/dcrypto/bn.c | 33 ++------------------------------- board/cr50/dcrypto/fips_rand.c | 9 +++++---- board/cr50/dcrypto/internal.h | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/board/cr50/dcrypto/bn.c b/board/cr50/dcrypto/bn.c index 446d2b98eb..4fecca8295 100644 --- a/board/cr50/dcrypto/bn.c +++ b/board/cr50/dcrypto/bn.c @@ -503,35 +503,6 @@ static void bn_mul_ex(struct LITE_BIGNUM *c, BN_DIGIT(c, i + b->dmax - 1) = carry; } -/* Functions to convert between uint32_t and uint64_t */ -static inline uint32_t lo32(uint64_t v) -{ - return (uint32_t)v; -} -static inline uint32_t hi32(uint64_t v) -{ - return (uint32_t)(v >> 32); -} -static inline uint64_t make64(uint32_t hi, uint32_t lo) -{ - return (((uint64_t)hi) << 32) | lo; -} - -static inline uint32_t lo16(uint32_t v) -{ - return (uint32_t)(v)&0xffff; -} - -static inline uint32_t hi16(uint32_t v) -{ - return (uint32_t)(v >> 16); -} - -/* make Clang's host behavior of clz match Soteria and avoid UBSAN error */ -static inline int clz(unsigned int x) -{ - return (x) ? __builtin_clz(x) : 32; -} /** * Unsigned division of 64-bit integer with 32-bit divisor, used to implement @@ -590,7 +561,7 @@ uint64_t udiv32(uint64_t n, uint32_t d0) if (d0 == 0 || n1 == 0) return n0 / d0; - bm = clz(d0); + bm = count_leading_zeros(d0); if (d0 > n1) { /* 0q = nn / 0D */ /* make the most significant bit of the denominator set. */ if (bm != 0) { @@ -671,7 +642,7 @@ static int bn_div_ex(struct LITE_BIGNUM *q, return bn_div_word_ex(q, r, u, m, vtop); /* Compute shift factor to make v have high bit set */ - s = clz(vtop); + s = count_leading_zeros(vtop); vtop <<= s; /* Normalize u and v into un and vn. diff --git a/board/cr50/dcrypto/fips_rand.c b/board/cr50/dcrypto/fips_rand.c index 4529a1cfbf..e3dcf4d298 100644 --- a/board/cr50/dcrypto/fips_rand.c +++ b/board/cr50/dcrypto/fips_rand.c @@ -63,11 +63,12 @@ static struct { static bool repetition_count_test(uint32_t rnd) { uint32_t clz, ctz, clo, cto; + /* count repeating 0 and 1 bits from each side */ - clz = __builtin_clz(rnd); /* # of leading 0s */ - ctz = __builtin_ctz(rnd); /* # of trailing 0s */ - clo = __builtin_clz(~rnd); /* # of leading 1s */ - cto = __builtin_ctz(~rnd); /* # of trailing 1s */ + clz = count_leading_zeros(rnd); /* # of leading 0s */ + ctz = count_trailing_zeros(rnd); /* # of trailing 0s */ + clo = count_leading_zeros(~rnd); /* # of leading 1s */ + cto = count_trailing_zeros(~rnd); /* # of trailing 1s */ /** * check that number of trailing 0/1 in current sample added to diff --git a/board/cr50/dcrypto/internal.h b/board/cr50/dcrypto/internal.h index e07389542c..7d64fc69b3 100644 --- a/board/cr50/dcrypto/internal.h +++ b/board/cr50/dcrypto/internal.h @@ -340,6 +340,42 @@ static inline uint64_t rol64(uint64_t value, int bits) return (value << bits) | (value >> (64 - bits)); } +/* Functions to convert between uint32_t and uint64_t */ +static inline uint32_t lo32(uint64_t v) +{ + return (uint32_t)v; +} +static inline uint32_t hi32(uint64_t v) +{ + return (uint32_t)(v >> 32); +} +static inline uint64_t make64(uint32_t hi, uint32_t lo) +{ + return (((uint64_t)hi) << 32) | lo; +} + +static inline uint32_t lo16(uint32_t v) +{ + return (uint32_t)(v)&0xffff; +} + +static inline uint32_t hi16(uint32_t v) +{ + return (uint32_t)(v >> 16); +} + +static inline int count_leading_zeros(uint32_t x) +{ + /* __builtin_clz(0) is undefined, so explicitly return bit size. */ + return (x) ? __builtin_clz(x) : 32; +} + +static inline int count_trailing_zeros(uint32_t x) +{ + /* __builtin_ctz(0) is undefined, so explicitly return bit size. */ + return (x) ? __builtin_ctz(x) : 32; +} + /* stack based allocation */ #ifndef alloca #define alloca __builtin_alloca -- cgit v1.2.1