109 const uint8_t* data,
size_t size,
110 const uint8_t iv[
IV_SIZE])
const {
112 std::vector<uint8_t> output(size);
113 if (size == 0)
return output;
117 uint32_t initial_counter =
118 (
static_cast<uint32_t
>(iv[12]) << 24) |
119 (
static_cast<uint32_t
>(iv[13]) << 16) |
120 (
static_cast<uint32_t
>(iv[14]) << 8) |
121 (
static_cast<uint32_t
>(iv[15]));
122 uint64_t max_blocks = 0xFFFFFFFFULL -
static_cast<uint64_t
>(initial_counter) + 1;
123 uint64_t max_bytes = max_blocks * 16;
124 if (
static_cast<uint64_t
>(size) > max_bytes)
126 "AES-CTR: data size exceeds 32-bit counter space for this IV"};
130 std::memcpy(counter, iv, 16);
134 while (offset < size) {
136 uint8_t keystream[16];
137 std::memcpy(keystream, counter, 16);
141 size_t block_len = size - offset;
142 if (block_len > 16) block_len = 16;
144 for (
size_t j = 0; j < block_len; ++j) {
145 output[offset + j] = data[offset + j] ^ keystream[j];
151 inc_counter(counter);
163 const uint8_t* data,
size_t size,
164 const uint8_t iv[
IV_SIZE])
const {
165 return process(data, size, iv);
174 const uint8_t* data,
size_t size,
175 const uint8_t iv[
IV_SIZE])
const {
176 return process(data, size, iv);
183 static void inc_counter(uint8_t counter[16]) {
184 for (
int i = 15; i >= 12; --i) {
185 if (++counter[i] != 0)
break;
AES-256 block cipher implementation (FIPS-197).
AES-256 block cipher (FIPS-197).
void encrypt_block(uint8_t block[BLOCK_SIZE]) const
Encrypt a single 16-byte block in-place (FIPS-197 Section 5.1).
AES-256 in Counter Mode (CTR) as specified in NIST SP 800-38A.
AesCtr & operator=(const AesCtr &)=delete
expected< std::vector< uint8_t > > encrypt(const uint8_t *data, size_t size, const uint8_t iv[IV_SIZE]) const
Convenience alias for process() – encrypt data with AES-CTR.
expected< std::vector< uint8_t > > decrypt(const uint8_t *data, size_t size, const uint8_t iv[IV_SIZE]) const
Convenience alias for process() – decrypt data with AES-CTR.
static constexpr size_t KEY_SIZE
AES-256 key size in bytes.
AesCtr(const AesCtr &)=delete
AesCtr(const uint8_t key[KEY_SIZE])
Initialize with a 32-byte key.
expected< std::vector< uint8_t > > process(const uint8_t *data, size_t size, const uint8_t iv[IV_SIZE]) const
Encrypt or decrypt data using AES-CTR.
static constexpr size_t IV_SIZE
Full 128-bit IV/counter size in bytes.
A lightweight result type that holds either a success value of type T or an Error.
@ ENCRYPTION_ERROR
An encryption or decryption operation failed (bad key, tampered ciphertext, PME error).
Lightweight error value carrying an ErrorCode and a human-readable message.