aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@google.com>2022-06-27 19:59:54 -0400
committerGravatar Alex Chernyakhovsky <achernya@mit.edu>2022-06-27 14:11:09 -1000
commitdb49808ac33b23763732376bcd54c8a71b8fd7f5 (patch)
treeaa7b7b51fc7c55cf050f45363e063b119c6a5943 /src
parentad85b9050554c75acadcfbff853222f19290046b (diff)
OCB: Heap-allocate keys
The OpenSSL EVP API requires that keys be heap-allocated, so switch _ae_ctx to use pointers to keys and opaque allocation functions. Bug: https://github.com/mobile-shell/mosh/issues/1174
Diffstat (limited to 'src')
-rw-r--r--src/crypto/ocb_internal.cc45
1 files changed, 31 insertions, 14 deletions
diff --git a/src/crypto/ocb_internal.cc b/src/crypto/ocb_internal.cc
index 9de376f..8dd26b4 100644
--- a/src/crypto/ocb_internal.cc
+++ b/src/crypto/ocb_internal.cc
@@ -364,6 +364,10 @@ namespace ocb_aes {
typedef AES_KEY KEY;
+static KEY *KEY_new() { return new KEY; }
+
+static void KEY_delete(KEY *key) { delete key; }
+
static void set_encrypt_key(const unsigned char *user_key, int bits, KEY *key) {
AES_set_encrypt_key(user_key, bits, key);
}
@@ -413,6 +417,10 @@ typedef struct {
uint8_t b[4096];
} KEY;
+static KEY *KEY_new() { return new KEY; }
+
+static void KEY_delete(KEY *key) { delete key; }
+
static void set_encrypt_key(const unsigned char *handle, const int bits, KEY *key)
{
CCCryptorStatus rv = CCCryptorCreateFromData(
@@ -497,6 +505,10 @@ namespace ocb_aes {
typedef struct aes_ctx KEY;
+static KEY *KEY_new() { return new KEY; }
+
+static void KEY_delete(KEY *key) { delete key; }
+
static void set_encrypt_key(const unsigned char *handle, const int bits, KEY *key)
{
nettle_aes_set_encrypt_key(key, bits/8, (const uint8_t *)handle);
@@ -557,8 +569,8 @@ struct _ae_ctx {
uint64_t KtopStr[3]; /* Register correct, each item */
uint32_t ad_blocks_processed;
uint32_t blocks_processed;
- ocb_aes::KEY decrypt_key;
- ocb_aes::KEY encrypt_key;
+ ocb_aes::KEY *decrypt_key;
+ ocb_aes::KEY *encrypt_key;
#if (OCB_TAG_LEN == 0)
unsigned tag_len;
#endif
@@ -600,6 +612,8 @@ static block getL(const ae_ctx *ctx, unsigned tz)
int ae_clear (ae_ctx *ctx) /* Zero ae_ctx and undo initialization */
{
+ ocb_aes::KEY_delete(ctx->encrypt_key);
+ ocb_aes::KEY_delete(ctx->decrypt_key);
memset(ctx, 0, sizeof(ae_ctx));
return AE_SUCCESS;
}
@@ -616,12 +630,15 @@ int ae_init(ae_ctx *ctx, const void *key, int key_len, int nonce_len, int tag_le
if (nonce_len != 12)
return AE_NOT_SUPPORTED;
+ ctx->decrypt_key = ocb_aes::KEY_new();
+ ctx->encrypt_key = ocb_aes::KEY_new();
+
/* Initialize encryption & decryption keys */
#if (OCB_KEY_LEN > 0)
key_len = OCB_KEY_LEN;
#endif
- ocb_aes::set_encrypt_key(reinterpret_cast<const unsigned char *>(key), key_len*8, &ctx->encrypt_key);
- ocb_aes::set_decrypt_key(reinterpret_cast<const unsigned char *>(key), static_cast<int>(key_len*8), &ctx->decrypt_key);
+ ocb_aes::set_encrypt_key(reinterpret_cast<const unsigned char *>(key), key_len*8, ctx->encrypt_key);
+ ocb_aes::set_decrypt_key(reinterpret_cast<const unsigned char *>(key), static_cast<int>(key_len*8), ctx->decrypt_key);
/* Zero things that need zeroing */
ctx->cached_Top = ctx->ad_checksum = zero_block();
@@ -629,7 +646,7 @@ int ae_init(ae_ctx *ctx, const void *key, int key_len, int nonce_len, int tag_le
/* Compute key-dependent values */
ocb_aes::encrypt(reinterpret_cast<unsigned char *>(&ctx->cached_Top),
- reinterpret_cast<unsigned char *>(&ctx->Lstar), &ctx->encrypt_key);
+ reinterpret_cast<unsigned char *>(&ctx->Lstar), ctx->encrypt_key);
tmp_blk = swap_if_le(ctx->Lstar);
tmp_blk = double_block(tmp_blk);
ctx->Ldollar = swap_if_le(tmp_blk);
@@ -666,7 +683,7 @@ static block gen_offset_from_nonce(ae_ctx *ctx, const void *nonce)
tmp.u8[15] = tmp.u8[15] & 0xc0; /* Zero low 6 bits of nonce */
if ( unequal_blocks(tmp.bl,ctx->cached_Top) ) { /* Cached? */
ctx->cached_Top = tmp.bl; /* Update cache, KtopStr */
- ocb_aes::encrypt(tmp.u8, (unsigned char *)&ctx->KtopStr, &ctx->encrypt_key);
+ ocb_aes::encrypt(tmp.u8, (unsigned char *)&ctx->KtopStr, ctx->encrypt_key);
if (little.endian) { /* Make Register Correct */
ctx->KtopStr[0] = bswap64(ctx->KtopStr[0]);
ctx->KtopStr[1] = bswap64(ctx->KtopStr[1]);
@@ -714,7 +731,7 @@ static void process_ad(ae_ctx *ctx, const void *ad, int ad_len, int final)
ad_offset = xor_block(oa[6], getL(ctx, tz));
ta[7] = xor_block(ad_offset, adp[7]);
#endif
- ocb_aes::ecb_encrypt_blks(ta, BPI, &ctx->encrypt_key);
+ ocb_aes::ecb_encrypt_blks(ta, BPI, ctx->encrypt_key);
ad_checksum = xor_block(ad_checksum, ta[0]);
ad_checksum = xor_block(ad_checksum, ta[1]);
ad_checksum = xor_block(ad_checksum, ta[2]);
@@ -775,7 +792,7 @@ static void process_ad(ae_ctx *ctx, const void *ad, int ad_len, int final)
ta[k] = xor_block(ad_offset, tmp.bl);
++k;
}
- ocb_aes::ecb_encrypt_blks(ta, k, &ctx->encrypt_key);
+ ocb_aes::ecb_encrypt_blks(ta, k, ctx->encrypt_key);
switch (k) {
#if (BPI == 8)
case 8: ad_checksum = xor_block(ad_checksum, ta[7]);
@@ -872,7 +889,7 @@ int ae_encrypt(ae_ctx * ctx,
ta[7] = xor_block(oa[7], ptp[7]);
checksum = xor_block(checksum, ptp[7]);
#endif
- ocb_aes::ecb_encrypt_blks(ta, BPI, &ctx->encrypt_key);
+ ocb_aes::ecb_encrypt_blks(ta, BPI, ctx->encrypt_key);
ctp[0] = xor_block(ta[0], oa[0]);
ctp[1] = xor_block(ta[1], oa[1]);
ctp[2] = xor_block(ta[2], oa[2]);
@@ -944,7 +961,7 @@ int ae_encrypt(ae_ctx * ctx,
}
offset = xor_block(offset, ctx->Ldollar); /* Part of tag gen */
ta[k] = xor_block(offset, checksum); /* Part of tag gen */
- ocb_aes::ecb_encrypt_blks(ta, k + 1, &ctx->encrypt_key);
+ ocb_aes::ecb_encrypt_blks(ta, k + 1, ctx->encrypt_key);
offset = xor_block(ta[k], ctx->ad_checksum); /* Part of tag gen */
if (remaining) {
--k;
@@ -1085,7 +1102,7 @@ int ae_decrypt(ae_ctx *ctx,
oa[7] = xor_block(oa[6], getL(ctx, ntz(block_num)));
ta[7] = xor_block(oa[7], ctp[7]);
#endif
- ocb_aes::ecb_decrypt_blks(ta,BPI,&ctx->decrypt_key);
+ ocb_aes::ecb_decrypt_blks(ta,BPI,ctx->decrypt_key);
ptp[0] = xor_block(ta[0], oa[0]);
checksum = xor_block(checksum, ptp[0]);
ptp[1] = xor_block(ta[1], oa[1]);
@@ -1150,7 +1167,7 @@ int ae_decrypt(ae_ctx *ctx,
if (remaining) {
block pad;
offset = xor_block(offset,ctx->Lstar);
- ocb_aes::encrypt(reinterpret_cast<unsigned char *>(&offset), tmp.u8, &ctx->encrypt_key);
+ ocb_aes::encrypt(reinterpret_cast<unsigned char *>(&offset), tmp.u8, ctx->encrypt_key);
pad = tmp.bl;
memcpy(tmp.u8,ctp+k,remaining);
tmp.bl = xor_block(tmp.bl, pad);
@@ -1159,7 +1176,7 @@ int ae_decrypt(ae_ctx *ctx,
checksum = xor_block(checksum, tmp.bl);
}
}
- ocb_aes::ecb_decrypt_blks(ta,k,&ctx->decrypt_key);
+ ocb_aes::ecb_decrypt_blks(ta,k,ctx->decrypt_key);
switch (k) {
#if (BPI == 8)
case 7: ptp[6] = xor_block(ta[6], oa[6]);
@@ -1188,7 +1205,7 @@ int ae_decrypt(ae_ctx *ctx,
/* Calculate expected tag */
offset = xor_block(offset, ctx->Ldollar);
tmp.bl = xor_block(offset, checksum);
- ocb_aes::encrypt(tmp.u8, tmp.u8, &ctx->encrypt_key);
+ ocb_aes::encrypt(tmp.u8, tmp.u8, ctx->encrypt_key);
tmp.bl = xor_block(tmp.bl, ctx->ad_checksum); /* Full tag */
/* Compare with proposed tag, change ct_len if invalid */