crypto: Use `secure_allocator` for `AES256_ctx`
What changed, and why it matters
This change makes Bitcoin Core store sensitive AES encryption/decryption context data in locked, non-swappable memory instead of ordinary memory. The goal is to reduce the chance that encryption keys or key-derived data leak into swap files or core dumps. It is a defensive hardening patch, not a fix for an actively exploitable bug.
Treat as a low-risk hardening improvement. Review secure_allocator's zeroization and locking behavior on the target platforms, and ensure the pointer lifetime and exception safety are correct. No urgent deployment is required, but include in normal release cadence.
Security signals we found
Use of secure_allocator for cryptographic context
Removal of manual memset zeroization in destructor
Memory-locking hardening for AES key schedule data
Defensive mitigation against swap/core-dump leakage
Evidence from the diff
The commit replaces stack/heap-embedded AES256_ctx objects with dynamically allocated instances using secure_allocator. secure_allocator typically uses mlock/VirtualLock-backed memory and zeroes memory before deallocation. The destructor no longer manually memsets the context; deallocation is delegated to the allocator. This reduces the window where key schedule material resides in ordinary pageable memory and may be swapped or captured in crash dumps.
Changed components
src/crypto/aes.cppsrc/crypto/aes.hAES256EncryptAES256DecryptInspect captured patch +14 / −8
diff --git a/src/crypto/aes.cpp b/src/crypto/aes.cpp
index 40df5690..207a8e8a 100644
--- a/src/crypto/aes.cpp
+++ b/src/crypto/aes.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <crypto/aes.h>
+#include <support/allocators/secure.h>
#include <cstring>
@@ -12,32 +13,34 @@ extern "C" {
AES256Encrypt::AES256Encrypt(const unsigned char key[32])
{
- AES256_init(&ctx, key);
+ ctx = allocator.allocate(1);
+ AES256_init(ctx, key);
}
AES256Encrypt::~AES256Encrypt()
{
- memset(&ctx, 0, sizeof(ctx));
+ allocator.deallocate(ctx, 1);
}
void AES256Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const
{
- AES256_encrypt(&ctx, 1, ciphertext, plaintext);
+ AES256_encrypt(ctx, 1, ciphertext, plaintext);
}
AES256Decrypt::AES256Decrypt(const unsigned char key[32])
{
- AES256_init(&ctx, key);
+ ctx = allocator.allocate(1);
+ AES256_init(ctx, key);
}
AES256Decrypt::~AES256Decrypt()
{
- memset(&ctx, 0, sizeof(ctx));
+ allocator.deallocate(ctx, 1);
}
void AES256Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const
{
- AES256_decrypt(&ctx, 1, plaintext, ciphertext);
+ AES256_decrypt(ctx, 1, plaintext, ciphertext);
}
diff --git a/src/crypto/aes.h b/src/crypto/aes.h
index 4eae9a3b..191cffd9 100644
--- a/src/crypto/aes.h
+++ b/src/crypto/aes.h
@@ -7,6 +7,7 @@
#ifndef BITCOIN_CRYPTO_AES_H
#define BITCOIN_CRYPTO_AES_H
+#include <support/allocators/secure.h>
extern "C" {
#include <crypto/ctaes/ctaes.h>
}
@@ -18,7 +19,8 @@ static const int AES256_KEYSIZE = 32;
class AES256Encrypt
{
private:
- AES256_ctx ctx;
+ secure_allocator<AES256_ctx> allocator;
+ AES256_ctx *ctx;
public:
explicit AES256Encrypt(const unsigned char key[32]);
@@ -30,7 +32,8 @@ public:
class AES256Decrypt
{
private:
- AES256_ctx ctx;
+ secure_allocator<AES256_ctx> allocator;
+ AES256_ctx *ctx;
public:
explicit AES256Decrypt(const unsigned char key[32]);
Why this scored 43/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.