tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit 83b9f63b860efab0473bcfa41c8c12912af2aeca
parent 2f0b83a64d475a7c5572d6bc93c2b41b93dd4e2e
Author: Nick Mathewson <nickm@torproject.org>
Date:   Sun, 20 Apr 2025 18:49:40 -0400

aes: Support for replacing an AES key without free+alloc

Diffstat:
Msrc/lib/crypt_ops/aes.h | 2++
Msrc/lib/crypt_ops/aes_nss.c | 9+++++++++
Msrc/lib/crypt_ops/aes_openssl.c | 24++++++++++++++++++++++++
3 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/src/lib/crypt_ops/aes.h b/src/lib/crypt_ops/aes.h @@ -33,6 +33,8 @@ int evaluate_ctr_for_aes(void); typedef struct aes_raw_t aes_raw_t; aes_raw_t *aes_raw_new(const uint8_t *key, int key_bits, bool encrypt); +void aes_raw_set_key(aes_raw_t **cipher, const uint8_t *key, + int key_bits, bool encrypt); void aes_raw_free_(aes_raw_t *cipher); #define aes_raw_free(cipher) \ FREE_AND_NULL(aes_raw_t, aes_raw_free_, (cipher)) diff --git a/src/lib/crypt_ops/aes_nss.c b/src/lib/crypt_ops/aes_nss.c @@ -162,6 +162,15 @@ aes_raw_free_(aes_raw_t *cipher_) PK11_DestroyContext(ctx, PR_TRUE); } void +aes_raw_set_key(aes_raw_t **cipher, const uint8_t *key, + int key_bits, bool encrypt) +{ + // For NSS, I could not find a method to change the key + // of an existing context. + aes_raw_free(*cipher); + *cipher = aes_raw_new(key, key_bits, encrypt); +} +void aes_raw_encrypt(const aes_raw_t *cipher, uint8_t *block) { SECStatus s; diff --git a/src/lib/crypt_ops/aes_openssl.c b/src/lib/crypt_ops/aes_openssl.c @@ -422,6 +422,30 @@ aes_raw_new(const uint8_t *key, int key_bits, bool encrypt) return (aes_raw_t *)cipher; } /** + * Replace the key on an existing aes_raw_t. + * + * This may be faster than freeing and reallocating. + */ +void +aes_raw_set_key(aes_raw_t **cipher_, const uint8_t *key, + int key_bits, bool encrypt) +{ + const EVP_CIPHER *c = *(EVP_CIPHER**) cipher_; + switch (key_bits) { + case 128: c = EVP_aes_128_ecb(); break; + case 192: c = EVP_aes_192_ecb(); break; + case 256: c = EVP_aes_256_ecb(); break; + default: tor_assert_unreached(); + } + aes_raw_t *cipherp = *cipher_; + EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *)cipherp; + EVP_CIPHER_CTX_reset(cipher); + int r = EVP_CipherInit(cipher, c, key, NULL, encrypt); + tor_assert(r == 1); + EVP_CIPHER_CTX_set_padding(cipher, 0); +} + +/** * Release storage held by 'cipher'. */ void