23inline constexpr std::uint64_t
kIntegrityIv = 0xA6A6A6A6A6A6A6A6ULL;
28using AesBlockFn =
Error (*)(
const std::uint8_t in[16], std::uint8_t out[16],
void* ctx);
30[[nodiscard]]
inline std::uint64_t
LoadBe64(
const std::uint8_t* p)
noexcept {
31 return (
static_cast<std::uint64_t
>(p[0]) << 56) | (
static_cast<std::uint64_t
>(p[1]) << 48) |
32 (
static_cast<std::uint64_t
>(p[2]) << 40) | (
static_cast<std::uint64_t
>(p[3]) << 32) |
33 (
static_cast<std::uint64_t
>(p[4]) << 24) | (
static_cast<std::uint64_t
>(p[5]) << 16) |
34 (
static_cast<std::uint64_t
>(p[6]) << 8) |
static_cast<std::uint64_t
>(p[7]);
37inline void StoreBe64(std::uint8_t* p, std::uint64_t v)
noexcept {
38 p[0] =
static_cast<std::uint8_t
>(v >> 56);
39 p[1] =
static_cast<std::uint8_t
>(v >> 48);
40 p[2] =
static_cast<std::uint8_t
>(v >> 40);
41 p[3] =
static_cast<std::uint8_t
>(v >> 32);
42 p[4] =
static_cast<std::uint8_t
>(v >> 24);
43 p[5] =
static_cast<std::uint8_t
>(v >> 16);
44 p[6] =
static_cast<std::uint8_t
>(v >> 8);
45 p[7] =
static_cast<std::uint8_t
>(v);
52[[nodiscard]]
inline Error Unwrap(
const std::uint8_t* wrapped, std::size_t wrapped_len, std::uint8_t* out,
53 std::size_t out_cap, std::size_t* out_len,
AesBlockFn decrypt,
55 if (out_len ==
nullptr) {
59 if (wrapped ==
nullptr || out ==
nullptr || decrypt ==
nullptr) {
62 if ((wrapped_len < 24U) || ((wrapped_len % 8U) != 0U)) {
65 const std::size_t n = (wrapped_len / 8U) - 1U;
66 const std::size_t plain_len = n * 8U;
67 if (out_cap < plain_len) {
75 for (std::size_t i = 0; i < n; ++i) {
76 r[i] =
LoadBe64(wrapped + 8U * (i + 1U));
78 for (
int j = 5; j >= 0; --j) {
79 for (std::size_t i = n; i >= 1U; --i) {
80 const std::uint64_t t =
static_cast<std::uint64_t
>(n) *
static_cast<std::uint64_t
>(j) + i;
82 std::uint8_t block[16]{};
85 std::uint8_t outb[16]{};
86 const Error e = decrypt(block, outb, ctx);
97 for (std::size_t i = 0; i < n; ++i) {
100 *out_len = plain_len;
108[[nodiscard]]
inline Error Wrap(
const std::uint8_t* plain, std::size_t plain_len, std::uint8_t* out,
109 std::size_t out_cap, std::size_t* out_len,
AesBlockFn encrypt,
110 void* ctx)
noexcept {
111 if (out_len ==
nullptr) {
115 if (plain ==
nullptr || out ==
nullptr || encrypt ==
nullptr) {
118 if ((plain_len < 16U) || ((plain_len % 8U) != 0U)) {
121 const std::size_t n = plain_len / 8U;
122 const std::size_t wrapped_len = (n + 1U) * 8U;
126 if (out_cap < wrapped_len) {
130 std::uint64_t r[8]{};
131 for (std::size_t i = 0; i < n; ++i) {
134 for (
int j = 0; j <= 5; ++j) {
135 for (std::size_t i = 1U; i <= n; ++i) {
136 std::uint8_t block[16]{};
139 std::uint8_t outb[16]{};
140 const Error e = encrypt(block, outb, ctx);
145 const std::uint64_t t =
static_cast<std::uint64_t
>(n) *
static_cast<std::uint64_t
>(j) + i;
151 for (std::size_t i = 0; i < n; ++i) {
154 *out_len = wrapped_len;
Definition se050_rfc3394.hpp:21
constexpr std::size_t kAes256CekLen
Definition se050_rfc3394.hpp:24
std::uint64_t LoadBe64(const std::uint8_t *p) noexcept
Definition se050_rfc3394.hpp:30
constexpr std::uint64_t kIntegrityIv
Definition se050_rfc3394.hpp:23
Error Unwrap(const std::uint8_t *wrapped, std::size_t wrapped_len, std::uint8_t *out, std::size_t out_cap, std::size_t *out_len, AesBlockFn decrypt, void *ctx) noexcept
RFC 3394 unwrap. wrapped_len must be 8*(n+1) with n >= 2.
Definition se050_rfc3394.hpp:52
Error Wrap(const std::uint8_t *plain, std::size_t plain_len, std::uint8_t *out, std::size_t out_cap, std::size_t *out_len, AesBlockFn encrypt, void *ctx) noexcept
RFC 3394 wrap. plain_len must be 8*n with n >= 2.
Definition se050_rfc3394.hpp:108
Error(*)(const std::uint8_t in[16], std::uint8_t out[16], void *ctx) AesBlockFn
AES-ECB encrypt or decrypt of one 16-byte block (KEK size is the oracle's).
Definition se050_rfc3394.hpp:28
void StoreBe64(std::uint8_t *p, std::uint64_t v) noexcept
Definition se050_rfc3394.hpp:37
constexpr std::size_t kAes256WrappedLen
Definition se050_rfc3394.hpp:25
Error
Definition se050_types.hpp:14
Shared types, limits, and error codes for the HF-SE050 driver.