in source/raw_aes_keyring.c [185:258]
static int raw_aes_keyring_on_decrypt(
struct aws_cryptosdk_keyring *kr,
struct aws_allocator *request_alloc,
struct aws_byte_buf *unencrypted_data_key,
struct aws_array_list *keyring_trace,
const struct aws_array_list *edks,
const struct aws_hash_table *enc_ctx,
enum aws_cryptosdk_alg_id alg) {
struct raw_aes_keyring *self = (struct raw_aes_keyring *)kr;
struct aws_byte_buf aad;
if (serialize_aad_init(request_alloc, &aad, enc_ctx)) {
return AWS_OP_ERR;
}
size_t num_edks = aws_array_list_length(edks);
const struct aws_cryptosdk_alg_properties *props = aws_cryptosdk_alg_props(alg);
size_t data_key_len = props->data_key_len;
if (aws_byte_buf_init(unencrypted_data_key, request_alloc, props->data_key_len)) {
aws_byte_buf_clean_up(&aad);
return AWS_OP_ERR;
}
for (size_t edk_idx = 0; edk_idx < num_edks; ++edk_idx) {
const struct aws_cryptosdk_edk *edk;
if (aws_array_list_get_at_ptr(edks, (void **)&edk, edk_idx)) {
aws_byte_buf_clean_up(&aad);
return AWS_OP_ERR;
}
if (!edk->provider_id.len || !edk->provider_info.len || !edk->ciphertext.len) continue;
if (!aws_string_eq_byte_buf(self->key_namespace, &edk->provider_id)) continue;
struct aws_byte_buf iv;
if (!aws_cryptosdk_parse_provider_info(kr, &iv, &edk->provider_info)) continue;
const struct aws_byte_buf *edk_bytes = &edk->ciphertext;
/* Using GCM, so encrypted and unencrypted data key have same length, i.e. data_key_len.
* edk_bytes->buffer holds encrypted data key followed by GCM tag.
*/
if (data_key_len + RAW_AES_KR_TAG_LEN != edk_bytes->len) continue;
if (aws_cryptosdk_aes_gcm_decrypt(
unencrypted_data_key,
aws_byte_cursor_from_array(edk_bytes->buffer, data_key_len),
aws_byte_cursor_from_array(edk_bytes->buffer + data_key_len, RAW_AES_KR_TAG_LEN),
aws_byte_cursor_from_buf(&iv),
aws_byte_cursor_from_buf(&aad),
self->raw_key)) {
/* We are here either because of a ciphertext/tag mismatch (e.g., wrong encryption
* context) or because of an OpenSSL error. In either case, nothing better to do
* than just moving on to next EDK, so clear the error code.
*/
aws_reset_error();
} else {
aws_cryptosdk_keyring_trace_add_record(
request_alloc,
keyring_trace,
self->key_namespace,
self->key_name,
AWS_CRYPTOSDK_WRAPPING_KEY_DECRYPTED_DATA_KEY | AWS_CRYPTOSDK_WRAPPING_KEY_VERIFIED_ENC_CTX);
goto success;
}
}
// None of the EDKs worked, clean up unencrypted data key buffer and return success per materials.h
aws_byte_buf_clean_up(unencrypted_data_key);
success:
aws_byte_buf_clean_up(&aad);
return AWS_OP_SUCCESS;
}