Skip to content

Commit

Permalink
AES: Implement GHASH without standard library dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
Sainan committed Dec 1, 2024
1 parent d61175d commit bf5dfd6
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
49 changes: 43 additions & 6 deletions soup/aes.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "aes.hpp"

#include <cstring> // memcpy
#include <vector>

#include "base.hpp"

Expand Down Expand Up @@ -900,11 +901,47 @@ NAMESPACE_SOUP
}
}

void aes::ghash(uint8_t res[16], const uint8_t h[16], const std::vector<uint8_t>& x) noexcept
void aes::rshiftBlock(uint8_t block[16]) noexcept
{
plusaes::detail::gcm::Block bH(h, 16);
auto bRes = plusaes::detail::gcm::ghash(bH, x);
memcpy(res, bRes.data(), 16);
for (int i = 15; i > 0; --i)
{
block[i] = (block[i] >> 1) | (block[i - 1] << 7);
}
block[0] >>= 1;
}

void aes::mulBlocks(uint8_t res[16], const uint8_t x[16], const uint8_t y[16]) noexcept
{
memset(res, 0, 16);
uint8_t v[16];
memcpy(v, y, 16);
for (uint8_t i = 0; i != 128; ++i)
{
if ((x[i / 8] >> (7 - (i % 8))) & 1)
{
xorBlocks(res, v);
}

const bool lsb_set = v[15] & 1;
rshiftBlock(v);
if (lsb_set)
{
v[0] ^= 0xe1;
}
}
}

void aes::ghash(uint8_t res[16], const uint8_t h[16], const uint8_t x[], size_t x_bytes) noexcept
{
memset(res, 0, 16);
const auto x_blocks = (x_bytes / 16);
uint8_t tmp[16];
for (size_t i = 0; i != x_blocks; ++i)
{
xorBlocks(res, &x[i * 16]);
memcpy(tmp, res, 16);
mulBlocks(res, tmp, h);
}
}

void aes::calcH(uint8_t h[16], uint8_t roundKeys[240], const int Nr) noexcept
Expand Down Expand Up @@ -933,7 +970,7 @@ NAMESPACE_SOUP
plusaes::detail::gcm::push_back_zero_bits(ghash_in, s + 64);
plusaes::detail::gcm::push_back(ghash_in, std::bitset<64>(len_iv));

return ghash(j0, h, ghash_in);
return ghash(j0, h, ghash_in.data(), ghash_in.size());
}
}

Expand Down Expand Up @@ -989,7 +1026,7 @@ NAMESPACE_SOUP
plusaes::detail::gcm::push_back_zero_bits(ghash_in, u);
plusaes::detail::gcm::push_back(ghash_in, std::bitset<64>(lenA));
plusaes::detail::gcm::push_back(ghash_in, std::bitset<64>(lenC));
ghash(tag, h, ghash_in);
ghash(tag, h, ghash_in.data(), ghash_in.size());
gctr(tag, 16, roundKeys, Nr, j0);
}
}
5 changes: 3 additions & 2 deletions soup/aes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include <cstdint>
#include <string>
#include <vector>

#include "base.hpp" // SOUP_EXCAL

Expand Down Expand Up @@ -53,7 +52,9 @@ NAMESPACE_SOUP
static SOUP_FORCEINLINE void xorBlocks(uint8_t a[16], const uint8_t b[16]) noexcept;
static SOUP_FORCEINLINE void xorBlocks(uint8_t a[], const uint8_t b[], unsigned int len) noexcept;

static void ghash(uint8_t res[16], const uint8_t h[16], const std::vector<uint8_t>& x) noexcept;
static SOUP_FORCEINLINE void rshiftBlock(uint8_t block[16]) noexcept;
static void mulBlocks(uint8_t res[16], const uint8_t x[16], const uint8_t y[16]) noexcept;
static void ghash(uint8_t res[16], const uint8_t h[16], const uint8_t x[], size_t x_bytes) noexcept;
static void calcH(uint8_t h[16], uint8_t roundKeys[240], const int Nr) noexcept;
static void calcJ0(uint8_t j0[16], const uint8_t h[16], const uint8_t* iv, size_t iv_len) SOUP_EXCAL;
static void inc32(uint8_t block[16]) noexcept;
Expand Down

0 comments on commit bf5dfd6

Please sign in to comment.