in source/raw_aes_keyring.c [90:142]
int aws_cryptosdk_raw_aes_keyring_encrypt_data_key_with_iv(
struct aws_cryptosdk_keyring *kr,
struct aws_allocator *request_alloc,
const struct aws_byte_buf *unencrypted_data_key,
struct aws_array_list *edks,
const struct aws_hash_table *enc_ctx,
enum aws_cryptosdk_alg_id alg,
const uint8_t *iv) {
struct raw_aes_keyring *self = (struct raw_aes_keyring *)kr;
const struct aws_cryptosdk_alg_properties *props = aws_cryptosdk_alg_props(alg);
size_t data_key_len = props->data_key_len;
struct aws_byte_buf aad;
if (serialize_aad_init(request_alloc, &aad, enc_ctx)) {
return AWS_OP_ERR;
}
struct aws_cryptosdk_edk edk = { { 0 } };
/* Encrypted data key bytes same length as unencrypted data key in GCM.
* enc_data_key field also includes tag afterward.
*/
if (aws_byte_buf_init(&edk.ciphertext, request_alloc, data_key_len + RAW_AES_KR_TAG_LEN)) {
aws_byte_buf_clean_up(&aad);
return AWS_OP_ERR;
}
struct aws_byte_buf edk_bytes = aws_byte_buf_from_array(edk.ciphertext.buffer, data_key_len);
struct aws_byte_buf tag = aws_byte_buf_from_array(edk.ciphertext.buffer + data_key_len, RAW_AES_KR_TAG_LEN);
if (aws_cryptosdk_aes_gcm_encrypt(
&edk_bytes,
&tag,
aws_byte_cursor_from_buf(unencrypted_data_key),
aws_byte_cursor_from_array(iv, RAW_AES_KR_IV_LEN),
aws_byte_cursor_from_buf(&aad),
self->raw_key))
goto err;
edk.ciphertext.len = edk.ciphertext.capacity;
if (aws_cryptosdk_serialize_provider_info_init(request_alloc, &edk.provider_info, self->key_name, iv)) goto err;
if (aws_byte_buf_init(&edk.provider_id, request_alloc, self->key_namespace->len)) goto err;
if (!aws_byte_buf_write_from_whole_string(&edk.provider_id, self->key_namespace)) goto err;
if (aws_array_list_push_back(edks, &edk)) goto err;
aws_byte_buf_clean_up(&aad);
return AWS_OP_SUCCESS;
err:
aws_cryptosdk_edk_clean_up(&edk);
aws_byte_buf_clean_up(&aad);
return AWS_OP_ERR;
}