From 483b8aae4d95beca443c0713936e62e82672dd97 Mon Sep 17 00:00:00 2001 From: Rene Meusel Date: Tue, 19 Sep 2023 17:47:49 +0200 Subject: [PATCH] multi-target load_{be,le} legacy adapters --- src/lib/utils/ghash/ghash.cpp | 11 +- src/lib/utils/loadstor.h | 228 ++++++---------------------------- 2 files changed, 44 insertions(+), 195 deletions(-) diff --git a/src/lib/utils/ghash/ghash.cpp b/src/lib/utils/ghash/ghash.cpp index 38604afdbed..8c3b1ed6c2a 100644 --- a/src/lib/utils/ghash/ghash.cpp +++ b/src/lib/utils/ghash/ghash.cpp @@ -13,6 +13,8 @@ #include #include +#include + namespace Botan { std::string GHASH::provider() const { @@ -177,9 +179,12 @@ void GHASH::add_final_block(secure_vector& hash, size_t ad_len, size_t * stack buffer is fine here since the text len is public * and the length of the AD is probably not sensitive either. */ - uint8_t final_block[GCM_BS]; - store_be(final_block, 8 * ad_len, 8 * text_len); - ghash_update(hash, {final_block, GCM_BS}); + std::array final_block; + + const uint64_t ad_bits = 8 * ad_len; + const uint64_t text_bits = 8 * text_len; + store_be(final_block, ad_bits, text_bits); + ghash_update(hash, final_block); } void GHASH::final(std::span mac) { diff --git a/src/lib/utils/loadstor.h b/src/lib/utils/loadstor.h index 2277b90c770..92f154e2fe8 100644 --- a/src/lib/utils/loadstor.h +++ b/src/lib/utils/loadstor.h @@ -224,55 +224,29 @@ inline constexpr void load_le(InR&& in, Ts&... outs) { } /** -* Load two little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -*/ -template -inline constexpr void load_le(const uint8_t in[], T& x0, T& x1) { - x0 = load_le(in, 0); - x1 = load_le(in, 1); -} - -/** -* Load four little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written +* Load many big-endian unsigned integers +* @param in a pointer to some bytes +* @param outs a arbitrary-length parameter list of unsigned integers to be loaded */ -template -inline constexpr void load_le(const uint8_t in[], T& x0, T& x1, T& x2, T& x3) { - x0 = load_le(in, 0); - x1 = load_le(in, 1); - x2 = load_le(in, 2); - x3 = load_le(in, 3); +template + requires all_same_v +inline constexpr void load_be(const uint8_t in[], Ts&... outs) { + constexpr auto bytes = (sizeof(outs) + ...); + // asserts that *in points to the correct amount of memory + load_be(std::span(in, bytes), outs...); } /** -* Load eight little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -* @param x4 where the fifth word will be written -* @param x5 where the sixth word will be written -* @param x6 where the seventh word will be written -* @param x7 where the eighth word will be written +* Load many little-endian unsigned integers +* @param in a pointer to some bytes +* @param outs a arbitrary-length parameter list of unsigned integers to be loaded */ -template -inline constexpr void load_le(const uint8_t in[], T& x0, T& x1, T& x2, T& x3, T& x4, T& x5, T& x6, T& x7) { - x0 = load_le(in, 0); - x1 = load_le(in, 1); - x2 = load_le(in, 2); - x3 = load_le(in, 3); - x4 = load_le(in, 4); - x5 = load_le(in, 5); - x6 = load_le(in, 6); - x7 = load_le(in, 7); +template + requires all_same_v +inline constexpr void load_le(const uint8_t in[], Ts&... outs) { + constexpr auto bytes = (sizeof(outs) + ...); + // asserts that *in points to the correct amount of memory + load_le(std::span(in, bytes), outs...); } /** @@ -299,58 +273,6 @@ inline constexpr void load_le(T out[], const uint8_t in[], size_t count) { } } -/** -* Load two big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -*/ -template -inline constexpr void load_be(const uint8_t in[], T& x0, T& x1) { - x0 = load_be(in, 0); - x1 = load_be(in, 1); -} - -/** -* Load four big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -*/ -template -inline constexpr void load_be(const uint8_t in[], T& x0, T& x1, T& x2, T& x3) { - x0 = load_be(in, 0); - x1 = load_be(in, 1); - x2 = load_be(in, 2); - x3 = load_be(in, 3); -} - -/** -* Load eight big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -* @param x4 where the fifth word will be written -* @param x5 where the sixth word will be written -* @param x6 where the seventh word will be written -* @param x7 where the eighth word will be written -*/ -template -inline constexpr void load_be(const uint8_t in[], T& x0, T& x1, T& x2, T& x3, T& x4, T& x5, T& x6, T& x7) { - x0 = load_be(in, 0); - x1 = load_be(in, 1); - x2 = load_be(in, 2); - x3 = load_be(in, 3); - x4 = load_be(in, 4); - x5 = load_be(in, 5); - x6 = load_be(in, 6); - x7 = load_be(in, 7); -} - /** * Load a variable number of big-endian words * @param out the output array of words @@ -481,107 +403,29 @@ inline constexpr void store_le(OutR&& out, Ts... ins) { } /** -* Store two little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -*/ -template -inline constexpr void store_le(uint8_t out[], T x0, T x1) { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); -} - -/** -* Store two big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -*/ -template -inline constexpr void store_be(uint8_t out[], T x0, T x1) { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); -} - -/** -* Store four little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -*/ -template -inline constexpr void store_le(uint8_t out[], T x0, T x1, T x2, T x3) { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - store_le(x2, out + (2 * sizeof(T))); - store_le(x3, out + (3 * sizeof(T))); -} - -/** -* Store four big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -*/ -template -inline constexpr void store_be(uint8_t out[], T x0, T x1, T x2, T x3) { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - store_be(x2, out + (2 * sizeof(T))); - store_be(x3, out + (3 * sizeof(T))); -} - -/** -* Store eight little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -* @param x4 the fifth word -* @param x5 the sixth word -* @param x6 the seventh word -* @param x7 the eighth word +* Store many big-endian unsigned integers +* @param ins a pointer to some bytes to be written +* @param out a arbitrary-length parameter list of unsigned integers to be stored */ -template -inline constexpr void store_le(uint8_t out[], T x0, T x1, T x2, T x3, T x4, T x5, T x6, T x7) { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - store_le(x2, out + (2 * sizeof(T))); - store_le(x3, out + (3 * sizeof(T))); - store_le(x4, out + (4 * sizeof(T))); - store_le(x5, out + (5 * sizeof(T))); - store_le(x6, out + (6 * sizeof(T))); - store_le(x7, out + (7 * sizeof(T))); +template + requires all_same_v +inline constexpr void store_be(uint8_t out[], Ts... ins) { + constexpr auto bytes = (sizeof(ins) + ...); + // asserts that *out points to the correct amount of memory + store_be(std::span(out, bytes), ins...); } /** -* Store eight big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -* @param x4 the fifth word -* @param x5 the sixth word -* @param x6 the seventh word -* @param x7 the eighth word +* Store many little-endian unsigned integers +* @param ins a pointer to some bytes to be written +* @param out a arbitrary-length parameter list of unsigned integers to be stored */ -template -inline constexpr void store_be(uint8_t out[], T x0, T x1, T x2, T x3, T x4, T x5, T x6, T x7) { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - store_be(x2, out + (2 * sizeof(T))); - store_be(x3, out + (3 * sizeof(T))); - store_be(x4, out + (4 * sizeof(T))); - store_be(x5, out + (5 * sizeof(T))); - store_be(x6, out + (6 * sizeof(T))); - store_be(x7, out + (7 * sizeof(T))); +template + requires all_same_v +inline constexpr void store_le(uint8_t out[], Ts... ins) { + constexpr auto bytes = (sizeof(ins) + ...); + // asserts that *out points to the correct amount of memory + store_le(std::span(out, bytes), ins...); } template