// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
// symbols from arbitrary system and other headers, since it may be built
// with different flags from other targets, using different levels of
// optimization, potentially introducing ODR violations.

#include "absl/random/internal/randen_hwaes.h"

#include <cstdint>
#include <cstring>

#include "absl/base/attributes.h"
#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen_traits.h"

// ABSL_RANDEN_HWAES_IMPL indicates whether this file will contain
// a hardware accelerated implementation of randen, or whether it
// will contain stubs that exit the process.
#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
// The platform.h directives are sufficient to indicate whether
// we should build accelerated implementations for x86.
#if (ABSL_HAVE_ACCELERATED_AES || ABSL_RANDOM_INTERNAL_AES_DISPATCH)
#define ABSL_RANDEN_HWAES_IMPL 1
#endif
#elif defined(ABSL_ARCH_PPC)
// The platform.h directives are sufficient to indicate whether
// we should build accelerated implementations for PPC.
//
// NOTE: This has mostly been tested on 64-bit Power variants,
// and not embedded cpus such as powerpc32-8540
#if ABSL_HAVE_ACCELERATED_AES
#define ABSL_RANDEN_HWAES_IMPL 1
#endif
#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)
// ARM is somewhat more complicated. We might support crypto natively...
#if ABSL_HAVE_ACCELERATED_AES || \
    (defined(__ARM_NEON) && defined(__ARM_FEATURE_CRYPTO))
#define ABSL_RANDEN_HWAES_IMPL 1

#elif ABSL_RANDOM_INTERNAL_AES_DISPATCH && !defined(__APPLE__) && \
    (defined(__GNUC__) && __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 9)
// ...or, on GCC, we can use an ASM directive to
// instruct the assember to allow crypto instructions.
#define ABSL_RANDEN_HWAES_IMPL 1
#define ABSL_RANDEN_HWAES_IMPL_CRYPTO_DIRECTIVE 1
#endif
#else
// HWAES is unsupported by these architectures / platforms:
//   __myriad2__
//   __mips__
//
// Other architectures / platforms are unknown.
//
// See the Abseil documentation on supported macros at:
// https://abseil.io/docs/cpp/platforms/macros
#endif

#if !defined(ABSL_RANDEN_HWAES_IMPL)
// No accelerated implementation is supported.
// The RandenHwAes functions are stubs that print an error and exit.

#include <cstdio>
#include <cstdlib>

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {

// No accelerated implementation.
bool HasRandenHwAesImplementation() { return false; }

// NOLINTNEXTLINE
const void* RandenHwAes::GetKeys() {
  // Attempted to dispatch to an unsupported dispatch target.
  const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
  fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
  exit(1);
  return nullptr;
}

// NOLINTNEXTLINE
void RandenHwAes::Absorb(const void*, void*) {
  // Attempted to dispatch to an unsupported dispatch target.
  const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
  fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
  exit(1);
}

// NOLINTNEXTLINE
void RandenHwAes::Generate(const void*, void*) {
  // Attempted to dispatch to an unsupported dispatch target.
  const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
  fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
  exit(1);
}

}  // namespace random_internal
ABSL_NAMESPACE_END
}  // namespace absl

#else  // defined(ABSL_RANDEN_HWAES_IMPL)
//
// Accelerated implementations are supported.
// We need the per-architecture includes and defines.
//
namespace {

using absl::random_internal::RandenTraits;

// Randen operates on 128-bit vectors.
struct alignas(16) u64x2 {
  uint64_t data[2];
};

}  // namespace

// TARGET_CRYPTO defines a crypto attribute for each architecture.
//
// NOTE: Evaluate whether we should eliminate ABSL_TARGET_CRYPTO.
#if (defined(__clang__) || defined(__GNUC__))
#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
#define ABSL_TARGET_CRYPTO __attribute__((target("aes")))
#elif defined(ABSL_ARCH_PPC)
#define ABSL_TARGET_CRYPTO __attribute__((target("crypto")))
#else
#define ABSL_TARGET_CRYPTO
#endif
#else
#define ABSL_TARGET_CRYPTO
#endif

#if defined(ABSL_ARCH_PPC)
// NOTE: Keep in mind that PPC can operate in little-endian or big-endian mode,
// however the PPC altivec vector registers (and thus the AES instructions)
// always operate in big-endian mode.

#include <altivec.h>
// <altivec.h> #defines vector __vector; in C++, this is bad form.
#undef vector
#undef bool

// Rely on the PowerPC AltiVec vector operations for accelerated AES
// instructions. GCC support of the PPC vector types is described in:
// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/PowerPC-AltiVec_002fVSX-Built-in-Functions.html
//
// Already provides operator^=.
using Vector128 = __vector unsigned long long;  // NOLINT(runtime/int)

namespace {
inline ABSL_TARGET_CRYPTO Vector128 ReverseBytes(const Vector128& v) {
  // Reverses the bytes of the vector.
  const __vector unsigned char perm = {15, 14, 13, 12, 11, 10, 9, 8,
                                       7,  6,  5,  4,  3,  2,  1, 0};
  return vec_perm(v, v, perm);
}

// WARNING: these load/store in native byte order. It is OK to load and then
// store an unchanged vector, but interpreting the bits as a number or input
// to AES will have undefined results.
inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
  return vec_vsx_ld(0, reinterpret_cast<const Vector128*>(from));
}

inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
  vec_vsx_st(v, 0, reinterpret_cast<Vector128*>(to));
}

// One round of AES. "round_key" is a public constant for breaking the
// symmetry of AES (ensures previously equal columns differ afterwards).
inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
                                             const Vector128& round_key) {
  return Vector128(__builtin_crypto_vcipher(state, round_key));
}

// Enables native loads in the round loop by pre-swapping.
inline ABSL_TARGET_CRYPTO void SwapEndian(u64x2* state) {
  for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) {
    Vector128Store(ReverseBytes(Vector128Load(state + block)), state + block);
  }
}

}  // namespace

#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)

// This asm directive will cause the file to be compiled with crypto extensions
// whether or not the cpu-architecture supports it.
#if ABSL_RANDEN_HWAES_IMPL_CRYPTO_DIRECTIVE
asm(".arch_extension  crypto\n");

// Override missing defines.
#if !defined(__ARM_NEON)
#define __ARM_NEON 1
#endif

#if !defined(__ARM_FEATURE_CRYPTO)
#define __ARM_FEATURE_CRYPTO 1
#endif

#endif

// Rely on the ARM NEON+Crypto advanced simd types, defined in <arm_neon.h>.
// uint8x16_t is the user alias for underlying __simd128_uint8_t type.
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0073a/IHI0073A_arm_neon_intrinsics_ref.pdf
//
// <arm_neon> defines the following
//
// typedef __attribute__((neon_vector_type(16))) uint8_t uint8x16_t;
// typedef __attribute__((neon_vector_type(16))) int8_t int8x16_t;
// typedef __attribute__((neon_polyvector_type(16))) int8_t poly8x16_t;
//
// vld1q_v
// vst1q_v
// vaeseq_v
// vaesmcq_v
#include <arm_neon.h>

// Already provides operator^=.
using Vector128 = uint8x16_t;

namespace {

inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
  return vld1q_u8(reinterpret_cast<const uint8_t*>(from));
}

inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
  vst1q_u8(reinterpret_cast<uint8_t*>(to), v);
}

// One round of AES. "round_key" is a public constant for breaking the
// symmetry of AES (ensures previously equal columns differ afterwards).
inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
                                             const Vector128& round_key) {
  // It is important to always use the full round function - omitting the
  // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf]
  // and does not help because we never decrypt.
  //
  // Note that ARM divides AES instructions differently than x86 / PPC,
  // And we need to skip the first AddRoundKey step and add an extra
  // AddRoundKey step to the end. Lucky for us this is just XOR.
  return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key;
}

inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {}

}  // namespace

#elif defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
// On x86 we rely on the aesni instructions
#include <wmmintrin.h>

namespace {

// Vector128 class is only wrapper for __m128i, benchmark indicates that it's
// faster than using __m128i directly.
class Vector128 {
 public:
  // Convert from/to intrinsics.
  inline explicit Vector128(const __m128i& Vector128) : data_(Vector128) {}

  inline __m128i data() const { return data_; }

  inline Vector128& operator^=(const Vector128& other) {
    data_ = _mm_xor_si128(data_, other.data());
    return *this;
  }

 private:
  __m128i data_;
};

inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
  return Vector128(_mm_load_si128(reinterpret_cast<const __m128i*>(from)));
}

inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
  _mm_store_si128(reinterpret_cast<__m128i*>(to), v.data());
}

// One round of AES. "round_key" is a public constant for breaking the
// symmetry of AES (ensures previously equal columns differ afterwards).
inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
                                             const Vector128& round_key) {
  // It is important to always use the full round function - omitting the
  // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf]
  // and does not help because we never decrypt.
  return Vector128(_mm_aesenc_si128(state.data(), round_key.data()));
}

inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {}

}  // namespace

#endif

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#endif

// At this point, all of the platform-specific features have been defined /
// implemented.
//
// REQUIRES: using Vector128 = ...
// REQUIRES: Vector128 Vector128Load(void*) {...}
// REQUIRES: void Vector128Store(Vector128, void*) {...}
// REQUIRES: Vector128 AesRound(Vector128, Vector128) {...}
// REQUIRES: void SwapEndian(uint64_t*) {...}
//
// PROVIDES: absl::random_internal::RandenHwAes::Absorb
// PROVIDES: absl::random_internal::RandenHwAes::Generate
namespace {

// Block shuffles applies a shuffle to the entire state between AES rounds.
// Improved odd-even shuffle from "New criterion for diffusion property".
inline ABSL_TARGET_CRYPTO void BlockShuffle(u64x2* state) {
  static_assert(RandenTraits::kFeistelBlocks == 16,
                "Expecting 16 FeistelBlocks.");

  constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = {
      7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12};

  const Vector128 v0 = Vector128Load(state + shuffle[0]);
  const Vector128 v1 = Vector128Load(state + shuffle[1]);
  const Vector128 v2 = Vector128Load(state + shuffle[2]);
  const Vector128 v3 = Vector128Load(state + shuffle[3]);
  const Vector128 v4 = Vector128Load(state + shuffle[4]);
  const Vector128 v5 = Vector128Load(state + shuffle[5]);
  const Vector128 v6 = Vector128Load(state + shuffle[6]);
  const Vector128 v7 = Vector128Load(state + shuffle[7]);
  const Vector128 w0 = Vector128Load(state + shuffle[8]);
  const Vector128 w1 = Vector128Load(state + shuffle[9]);
  const Vector128 w2 = Vector128Load(state + shuffle[10]);
  const Vector128 w3 = Vector128Load(state + shuffle[11]);
  const Vector128 w4 = Vector128Load(state + shuffle[12]);
  const Vector128 w5 = Vector128Load(state + shuffle[13]);
  const Vector128 w6 = Vector128Load(state + shuffle[14]);
  const Vector128 w7 = Vector128Load(state + shuffle[15]);

  Vector128Store(v0, state + 0);
  Vector128Store(v1, state + 1);
  Vector128Store(v2, state + 2);
  Vector128Store(v3, state + 3);
  Vector128Store(v4, state + 4);
  Vector128Store(v5, state + 5);
  Vector128Store(v6, state + 6);
  Vector128Store(v7, state + 7);
  Vector128Store(w0, state + 8);
  Vector128Store(w1, state + 9);
  Vector128Store(w2, state + 10);
  Vector128Store(w3, state + 11);
  Vector128Store(w4, state + 12);
  Vector128Store(w5, state + 13);
  Vector128Store(w6, state + 14);
  Vector128Store(w7, state + 15);
}

// Feistel round function using two AES subrounds. Very similar to F()
// from Simpira v2, but with independent subround keys. Uses 17 AES rounds
// per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in
// parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel
// XORs are 'free' (included in the second AES instruction).
inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound(
    u64x2* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
  static_assert(RandenTraits::kFeistelBlocks == 16,
                "Expecting 16 FeistelBlocks.");

  // MSVC does a horrible job at unrolling loops.
  // So we unroll the loop by hand to improve the performance.
  const Vector128 s0 = Vector128Load(state + 0);
  const Vector128 s1 = Vector128Load(state + 1);
  const Vector128 s2 = Vector128Load(state + 2);
  const Vector128 s3 = Vector128Load(state + 3);
  const Vector128 s4 = Vector128Load(state + 4);
  const Vector128 s5 = Vector128Load(state + 5);
  const Vector128 s6 = Vector128Load(state + 6);
  const Vector128 s7 = Vector128Load(state + 7);
  const Vector128 s8 = Vector128Load(state + 8);
  const Vector128 s9 = Vector128Load(state + 9);
  const Vector128 s10 = Vector128Load(state + 10);
  const Vector128 s11 = Vector128Load(state + 11);
  const Vector128 s12 = Vector128Load(state + 12);
  const Vector128 s13 = Vector128Load(state + 13);
  const Vector128 s14 = Vector128Load(state + 14);
  const Vector128 s15 = Vector128Load(state + 15);

  // Encode even blocks with keys.
  const Vector128 e0 = AesRound(s0, Vector128Load(keys + 0));
  const Vector128 e2 = AesRound(s2, Vector128Load(keys + 1));
  const Vector128 e4 = AesRound(s4, Vector128Load(keys + 2));
  const Vector128 e6 = AesRound(s6, Vector128Load(keys + 3));
  const Vector128 e8 = AesRound(s8, Vector128Load(keys + 4));
  const Vector128 e10 = AesRound(s10, Vector128Load(keys + 5));
  const Vector128 e12 = AesRound(s12, Vector128Load(keys + 6));
  const Vector128 e14 = AesRound(s14, Vector128Load(keys + 7));

  // Encode odd blocks with even output from above.
  const Vector128 o1 = AesRound(e0, s1);
  const Vector128 o3 = AesRound(e2, s3);
  const Vector128 o5 = AesRound(e4, s5);
  const Vector128 o7 = AesRound(e6, s7);
  const Vector128 o9 = AesRound(e8, s9);
  const Vector128 o11 = AesRound(e10, s11);
  const Vector128 o13 = AesRound(e12, s13);
  const Vector128 o15 = AesRound(e14, s15);

  // Store odd blocks. (These will be shuffled later).
  Vector128Store(o1, state + 1);
  Vector128Store(o3, state + 3);
  Vector128Store(o5, state + 5);
  Vector128Store(o7, state + 7);
  Vector128Store(o9, state + 9);
  Vector128Store(o11, state + 11);
  Vector128Store(o13, state + 13);
  Vector128Store(o15, state + 15);

  return keys + 8;
}

// Cryptographic permutation based via type-2 Generalized Feistel Network.
// Indistinguishable from ideal by chosen-ciphertext adversaries using less than
// 2^64 queries if the round function is a PRF. This is similar to the b=8 case
// of Simpira v2, but more efficient than its generic construction for b=16.
inline ABSL_TARGET_CRYPTO void Permute(
    u64x2* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
  // (Successfully unrolled; the first iteration jumps into the second half)
#ifdef __clang__
#pragma clang loop unroll_count(2)
#endif
  for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) {
    keys = FeistelRound(state, keys);
    BlockShuffle(state);
  }
}

}  // namespace

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {

bool HasRandenHwAesImplementation() { return true; }

const void* ABSL_TARGET_CRYPTO RandenHwAes::GetKeys() {
  // Round keys for one AES per Feistel round and branch.
  // The canonical implementation uses first digits of Pi.
#if defined(ABSL_ARCH_PPC)
  return kRandenRoundKeysBE;
#else
  return kRandenRoundKeys;
#endif
}

// NOLINTNEXTLINE
void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void,
                                            void* state_void) {
  static_assert(RandenTraits::kCapacityBytes / sizeof(Vector128) == 1,
                "Unexpected Randen kCapacityBlocks");
  static_assert(RandenTraits::kStateBytes / sizeof(Vector128) == 16,
                "Unexpected Randen kStateBlocks");

  auto* state =
      reinterpret_cast<u64x2 * ABSL_RANDOM_INTERNAL_RESTRICT>(state_void);
  const auto* seed =
      reinterpret_cast<const u64x2 * ABSL_RANDOM_INTERNAL_RESTRICT>(seed_void);

  Vector128 b1 = Vector128Load(state + 1);
  b1 ^= Vector128Load(seed + 0);
  Vector128Store(b1, state + 1);

  Vector128 b2 = Vector128Load(state + 2);
  b2 ^= Vector128Load(seed + 1);
  Vector128Store(b2, state + 2);

  Vector128 b3 = Vector128Load(state + 3);
  b3 ^= Vector128Load(seed + 2);
  Vector128Store(b3, state + 3);

  Vector128 b4 = Vector128Load(state + 4);
  b4 ^= Vector128Load(seed + 3);
  Vector128Store(b4, state + 4);

  Vector128 b5 = Vector128Load(state + 5);
  b5 ^= Vector128Load(seed + 4);
  Vector128Store(b5, state + 5);

  Vector128 b6 = Vector128Load(state + 6);
  b6 ^= Vector128Load(seed + 5);
  Vector128Store(b6, state + 6);

  Vector128 b7 = Vector128Load(state + 7);
  b7 ^= Vector128Load(seed + 6);
  Vector128Store(b7, state + 7);

  Vector128 b8 = Vector128Load(state + 8);
  b8 ^= Vector128Load(seed + 7);
  Vector128Store(b8, state + 8);

  Vector128 b9 = Vector128Load(state + 9);
  b9 ^= Vector128Load(seed + 8);
  Vector128Store(b9, state + 9);

  Vector128 b10 = Vector128Load(state + 10);
  b10 ^= Vector128Load(seed + 9);
  Vector128Store(b10, state + 10);

  Vector128 b11 = Vector128Load(state + 11);
  b11 ^= Vector128Load(seed + 10);
  Vector128Store(b11, state + 11);

  Vector128 b12 = Vector128Load(state + 12);
  b12 ^= Vector128Load(seed + 11);
  Vector128Store(b12, state + 12);

  Vector128 b13 = Vector128Load(state + 13);
  b13 ^= Vector128Load(seed + 12);
  Vector128Store(b13, state + 13);

  Vector128 b14 = Vector128Load(state + 14);
  b14 ^= Vector128Load(seed + 13);
  Vector128Store(b14, state + 14);

  Vector128 b15 = Vector128Load(state + 15);
  b15 ^= Vector128Load(seed + 14);
  Vector128Store(b15, state + 15);
}

// NOLINTNEXTLINE
void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void,
                                              void* state_void) {
  static_assert(RandenTraits::kCapacityBytes == sizeof(Vector128),
                "Capacity mismatch");

  auto* state = reinterpret_cast<u64x2*>(state_void);
  const auto* keys = reinterpret_cast<const u64x2*>(keys_void);

  const Vector128 prev_inner = Vector128Load(state);

  SwapEndian(state);

  Permute(state, keys);

  SwapEndian(state);

  // Ensure backtracking resistance.
  Vector128 inner = Vector128Load(state);
  inner ^= prev_inner;
  Vector128Store(inner, state);
}

#ifdef __clang__
#pragma clang diagnostic pop
#endif

}  // namespace random_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // (ABSL_RANDEN_HWAES_IMPL)
