crypto/aes.cpp¶
Namespaces¶
| Name |
|---|
| rlpx |
| rlpx::crypto |
Source code¶
// Copyright 2025 GeniusVentures
// SPDX-License-Identifier: Apache-2.0
#include <rlpx/crypto/aes.hpp>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <cstring>
namespace rlpx::crypto {
CryptoResult<ByteBuffer> Aes::encrypt_ctr(
gsl::span<const uint8_t, kAesKeySize> key,
gsl::span<const uint8_t, kAesBlockSize> iv,
ByteView plaintext
) noexcept {
ByteBuffer ciphertext(plaintext.size());
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if ( !ctx ) {
return CryptoError::kAesEncryptFailed;
}
// Initialize encryption with AES-256-CTR
if ( EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr, key.data(), iv.data()) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesEncryptFailed;
}
int len = 0;
int ciphertext_len = 0;
// Encrypt plaintext
if ( EVP_EncryptUpdate(ctx, ciphertext.data(), &len, plaintext.data(),
static_cast<int>(plaintext.size())) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesEncryptFailed;
}
ciphertext_len = len;
// Finalize encryption (CTR mode doesn't add padding)
if ( EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesEncryptFailed;
}
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx);
ciphertext.resize(ciphertext_len);
return ciphertext;
}
CryptoResult<ByteBuffer> Aes::decrypt_ctr(
gsl::span<const uint8_t, kAesKeySize> key,
gsl::span<const uint8_t, kAesBlockSize> iv,
ByteView ciphertext
) noexcept {
ByteBuffer plaintext(ciphertext.size());
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if ( !ctx ) {
return CryptoError::kAesDecryptFailed;
}
// Initialize decryption with AES-256-CTR
if ( EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr, key.data(), iv.data()) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesDecryptFailed;
}
int len = 0;
int plaintext_len = 0;
// Decrypt ciphertext
if ( EVP_DecryptUpdate(ctx, plaintext.data(), &len, ciphertext.data(),
static_cast<int>(ciphertext.size())) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesDecryptFailed;
}
plaintext_len = len;
// Finalize decryption
if ( EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesDecryptFailed;
}
plaintext_len += len;
EVP_CIPHER_CTX_free(ctx);
plaintext.resize(plaintext_len);
return plaintext;
}
CryptoResult<void> Aes::encrypt_ctr_inplace(
gsl::span<const uint8_t, kAesKeySize> key,
gsl::span<const uint8_t, kAesBlockSize> iv,
MutableByteView data
) noexcept {
if ( data.empty() ) {
return outcome::success();
}
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if ( !ctx ) {
return CryptoError::kAesEncryptFailed;
}
// Initialize encryption
if ( EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr, key.data(), iv.data()) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesEncryptFailed;
}
int len = 0;
// Encrypt in place
if ( EVP_EncryptUpdate(ctx, data.data(), &len, data.data(),
static_cast<int>(data.size())) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesEncryptFailed;
}
// Finalize
if ( EVP_EncryptFinal_ex(ctx, data.data() + len, &len) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesEncryptFailed;
}
EVP_CIPHER_CTX_free(ctx);
return outcome::success();
}
CryptoResult<void> Aes::decrypt_ctr_inplace(
gsl::span<const uint8_t, kAesKeySize> key,
gsl::span<const uint8_t, kAesBlockSize> iv,
MutableByteView data
) noexcept {
if ( data.empty() ) {
return outcome::success();
}
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if ( !ctx ) {
return CryptoError::kAesDecryptFailed;
}
// Initialize decryption
if ( EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr, key.data(), iv.data()) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesDecryptFailed;
}
int len = 0;
// Decrypt in place
if ( EVP_DecryptUpdate(ctx, data.data(), &len, data.data(),
static_cast<int>(data.size())) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesDecryptFailed;
}
// Finalize
if ( EVP_DecryptFinal_ex(ctx, data.data() + len, &len) != 1 ) {
EVP_CIPHER_CTX_free(ctx);
return CryptoError::kAesDecryptFailed;
}
EVP_CIPHER_CTX_free(ctx);
return outcome::success();
}
} // namespace rlpx::crypto
Updated on 2026-04-13 at 23:22:46 -0700