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))
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;
EVP_CIPHER_CTX_set_padding(cipher, 0);
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'.
*/