From: Benjamin Barenblat Subject: Make randen_slow endian-correct Forwarded: yes Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/33541e751039a8c4bd3a395dd1a3a0928885814a Pay attention to the platform endianness when pulling bytes out of each AES block, and use platform-endian round keys. The author works at Google. Upstream applied this patch as Piper revision 383878281 and exported it to GitHub; the Applied-Upstream URL above points to the exported commit. --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -296,6 +296,7 @@ ":platform", "//absl/base:config", "//absl/base:core_headers", + "//absl/base:endian", "//absl/numeric:int128", ], ) --- a/absl/random/internal/randen_slow.cc +++ b/absl/random/internal/randen_slow.cc @@ -19,6 +19,7 @@ #include #include "absl/base/attributes.h" +#include "absl/base/internal/endian.h" #include "absl/numeric/int128.h" #include "absl/random/internal/platform.h" #include "absl/random/internal/randen_traits.h" @@ -40,7 +41,7 @@ // AES portions based on rijndael-alg-fst.c, // https://fastcrypto.org/front/misc/rijndael-alg-fst.c, and modified for -// little-endianness. +// platform-endianness. // // Implementation of // http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf @@ -251,6 +252,7 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 AesRound(const Vector128& state, const Vector128& round_key) { Vector128 result; +#ifdef ABSL_IS_LITTLE_ENDIAN result.s[0] = round_key.s[0] ^ // te0[uint8_t(state.s[0])] ^ // te1[uint8_t(state.s[1] >> 8)] ^ // @@ -271,6 +273,28 @@ te1[uint8_t(state.s[0] >> 8)] ^ // te2[uint8_t(state.s[1] >> 16)] ^ // te3[uint8_t(state.s[2] >> 24)]; +#else + result.s[0] = round_key.s[0] ^ // + te0[uint8_t(state.s[0])] ^ // + te1[uint8_t(state.s[3] >> 8)] ^ // + te2[uint8_t(state.s[2] >> 16)] ^ // + te3[uint8_t(state.s[1] >> 24)]; + result.s[1] = round_key.s[1] ^ // + te0[uint8_t(state.s[1])] ^ // + te1[uint8_t(state.s[0] >> 8)] ^ // + te2[uint8_t(state.s[3] >> 16)] ^ // + te3[uint8_t(state.s[2] >> 24)]; + result.s[2] = round_key.s[2] ^ // + te0[uint8_t(state.s[2])] ^ // + te1[uint8_t(state.s[1] >> 8)] ^ // + te2[uint8_t(state.s[0] >> 16)] ^ // + te3[uint8_t(state.s[3] >> 24)]; + result.s[3] = round_key.s[3] ^ // + te0[uint8_t(state.s[3])] ^ // + te1[uint8_t(state.s[2] >> 8)] ^ // + te2[uint8_t(state.s[1] >> 16)] ^ // + te3[uint8_t(state.s[0] >> 24)]; +#endif return result; } @@ -380,7 +404,11 @@ const void* RandenSlow::GetKeys() { // Round keys for one AES per Feistel round and branch. // The canonical implementation uses first digits of Pi. +#ifdef ABSL_IS_LITTLE_ENDIAN return kRandenRoundKeys; +#else + return kRandenRoundKeysBE; +#endif } void RandenSlow::Absorb(const void* seed_void, void* state_void) {