Skip to content

Commit

Permalink
Remove heap allocations from aes::calcGcmTag
Browse files Browse the repository at this point in the history
This was the last step needed for AES-GCM to be liberated of heap allocations & plusaes.
  • Loading branch information
Sainan committed Dec 1, 2024
1 parent 67b7781 commit f24e409
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 1,339 deletions.
1 change: 0 additions & 1 deletion soup/Soup.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,6 @@
<ClInclude Include="pch.hpp" />
<ClInclude Include="Percentage.hpp" />
<ClInclude Include="plist.hpp" />
<ClInclude Include="plusaes.hpp" />
<ClInclude Include="PointerAndBool.hpp" />
<ClInclude Include="ProcessHandle.hpp" />
<ClInclude Include="Ps2Scancode.hpp" />
Expand Down
3 changes: 0 additions & 3 deletions soup/Soup.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1244,9 +1244,6 @@
<ClInclude Include="ecc.hpp">
<Filter>crypto</Filter>
</ClInclude>
<ClInclude Include="plusaes.hpp">
<Filter>crypto</Filter>
</ClInclude>
<ClInclude Include="compiletime.hpp">
<Filter>util</Filter>
</ClInclude>
Expand Down
40 changes: 21 additions & 19 deletions soup/aes.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "aes.hpp"

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

#include "base.hpp"

Expand All @@ -17,7 +17,6 @@
#endif

#include "Endian.hpp"
#include "plusaes.hpp"

/*
Original source: https://github.com/SergeyBel/AES
Expand All @@ -44,6 +43,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

// https://github.com/kkAyataka/plusaes was also used a reference for AES-GCM

#if SOUP_X86
#define IS_AES_INTRIN_AVAILBLE CpuInfo::get().supportsAESNI()
#else
Expand Down Expand Up @@ -435,7 +436,7 @@ NAMESPACE_SOUP
}
}

void aes::gcmEncrypt(uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t* key, size_t key_len, const uint8_t* iv, size_t iv_len, uint8_t tag[16]) SOUP_EXCAL
void aes::gcmEncrypt(uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t* key, size_t key_len, const uint8_t* iv, size_t iv_len, uint8_t tag[16]) noexcept
{
const auto Nr = getNrFromKeyLen(key_len);
alignas(16) uint8_t roundKeys[240];
Expand All @@ -459,7 +460,7 @@ NAMESPACE_SOUP
calcGcmTag(tag, data, data_len, aadata, aadata_len, roundKeys, Nr, h, j0);
}

bool aes::gcmDecrypt(uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t* key, size_t key_len, const uint8_t* iv, size_t iv_len, const uint8_t tag[16]) SOUP_EXCAL
bool aes::gcmDecrypt(uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t* key, size_t key_len, const uint8_t* iv, size_t iv_len, const uint8_t tag[16]) noexcept
{
const auto Nr = getNrFromKeyLen(key_len);
alignas(16) uint8_t roundKeys[240];
Expand Down Expand Up @@ -1017,22 +1018,23 @@ NAMESPACE_SOUP
}
}

void aes::calcGcmTag(uint8_t tag[16], uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t roundKeys[16], const int Nr, const uint8_t h[16], const uint8_t j0[16]) SOUP_EXCAL
void aes::calcGcmTag(uint8_t tag[16], uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t roundKeys[16], const int Nr, const uint8_t h[16], const uint8_t j0[16]) noexcept
{
const auto lenC = data_len * 8;
const auto lenA = aadata_len * 8;
const std::size_t u = 128 * plusaes::detail::gcm::ceil(lenC / 128.0) - lenC;
const std::size_t v = 128 * plusaes::detail::gcm::ceil(lenA / 128.0) - lenA;

std::vector<unsigned char> ghash_in;
ghash_in.reserve((aadata_len + v / 8) + (data_len + u / 8) + 8 + 8);
plusaes::detail::gcm::push_back(ghash_in, aadata, aadata_len);
plusaes::detail::gcm::push_back_zero_bits(ghash_in, v);
plusaes::detail::gcm::push_back(ghash_in, data, data_len);
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.data(), ghash_in.size());
const uint64_t lenC = data_len * 8;
const uint64_t lenA = aadata_len * 8;
auto u = (128 * static_cast<unsigned long>(std::ceil(lenC / 128.0) + 0.5) - lenC) / 8;
auto v = (128 * static_cast<unsigned long>(std::ceil(lenA / 128.0) + 0.5) - lenA) / 8;
uint8_t z[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };

GhashState state(tag, h);
state.append(aadata, aadata_len);
while (v--) { state.appendByte(0); }
state.append(data, data_len);
while (u--) { state.appendByte(0); }
*reinterpret_cast<uint64_t*>(z) = Endianness::invert(lenA); state.append(z, 8); static_assert(ENDIAN_NATIVE == ENDIAN_LITTLE);
*reinterpret_cast<uint64_t*>(z) = Endianness::invert(lenC); state.append(z, 8); static_assert(ENDIAN_NATIVE == ENDIAN_LITTLE);
SOUP_DEBUG_ASSERT(state.buffer_counter == 0);

gctr(tag, 16, roundKeys, Nr, j0);
}

Expand Down
6 changes: 3 additions & 3 deletions soup/aes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ NAMESPACE_SOUP
static void cfbDecrypt(uint8_t* data, size_t data_len, const uint8_t* key, size_t key_len, const uint8_t iv[16]) noexcept;
static void ecbEncrypt(uint8_t* data, size_t data_len, const uint8_t* key, size_t key_len) noexcept;
static void ecbDecrypt(uint8_t* data, size_t data_len, const uint8_t* key, size_t key_len) noexcept;
static void gcmEncrypt(uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t* key, size_t key_len, const uint8_t* iv, size_t iv_len, uint8_t tag[16]) SOUP_EXCAL;
static bool gcmDecrypt(uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t* key, size_t key_len, const uint8_t* iv, size_t iv_len, const uint8_t tag[16]) SOUP_EXCAL;
static void gcmEncrypt(uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t* key, size_t key_len, const uint8_t* iv, size_t iv_len, uint8_t tag[16]) noexcept;
static bool gcmDecrypt(uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t* key, size_t key_len, const uint8_t* iv, size_t iv_len, const uint8_t tag[16]) noexcept;


static void expandKey(uint8_t w[240], const uint8_t* key, size_t key_len) noexcept;
Expand Down Expand Up @@ -58,7 +58,7 @@ NAMESPACE_SOUP
static void calcJ0(uint8_t j0[16], const uint8_t h[16], const uint8_t* iv, size_t iv_len) noexcept;
static void inc32(uint8_t block[16]) noexcept;
static void gctr(uint8_t* data, size_t data_len, const uint8_t roundKeys[240], const int Nr, const uint8_t icb[8]) noexcept;
static void calcGcmTag(uint8_t tag[16], uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t roundKeys[16], const int Nr, const uint8_t h[16], const uint8_t j0[16]) SOUP_EXCAL;
static void calcGcmTag(uint8_t tag[16], uint8_t* data, size_t data_len, const uint8_t* aadata, size_t aadata_len, const uint8_t roundKeys[16], const int Nr, const uint8_t h[16], const uint8_t j0[16]) noexcept;

struct GhashState
{
Expand Down
Loading

0 comments on commit f24e409

Please sign in to comment.