in source/materials.c [88:136]
int aws_cryptosdk_keyring_on_encrypt(
struct aws_cryptosdk_keyring *keyring,
struct aws_allocator *request_alloc,
struct aws_byte_buf *unencrypted_data_key,
struct aws_array_list *keyring_trace,
struct aws_array_list *edks,
const struct aws_hash_table *enc_ctx,
enum aws_cryptosdk_alg_id alg) {
AWS_PRECONDITION(aws_allocator_is_valid(request_alloc));
AWS_PRECONDITION(aws_cryptosdk_keyring_is_valid(keyring) && (keyring->vtable != NULL));
AWS_PRECONDITION(aws_byte_buf_is_valid(unencrypted_data_key));
AWS_PRECONDITION(aws_cryptosdk_keyring_trace_is_valid(keyring_trace));
AWS_PRECONDITION(aws_cryptosdk_edk_list_is_valid(edks) && aws_cryptosdk_edk_list_elements_are_valid(edks));
AWS_PRECONDITION(enc_ctx == NULL || aws_hash_table_is_valid(enc_ctx));
/* Shallow copy of byte buffer: does NOT duplicate key bytes */
const struct aws_byte_buf precall_data_key_buf = *unencrypted_data_key;
/* Precondition: If a data key has not already been generated, there must be no EDKs.
* Generating a new one and then pushing new EDKs on the list would cause the list of
* EDKs to be inconsistent. (i.e., they would decrypt to different data keys.)
*/
if (!precall_data_key_buf.buffer && aws_array_list_length(edks))
return aws_raise_error(AWS_CRYPTOSDK_ERR_BAD_STATE);
AWS_CRYPTOSDK_PRIVATE_VF_CALL(
on_encrypt, keyring, request_alloc, unencrypted_data_key, keyring_trace, edks, enc_ctx, alg);
/* Postcondition: If this keyring generated data key, it must be the right length. */
if (!precall_data_key_buf.buffer && unencrypted_data_key->buffer) {
const struct aws_cryptosdk_alg_properties *props = aws_cryptosdk_alg_props(alg);
if (props == NULL || (unencrypted_data_key->len != props->data_key_len)) {
return aws_raise_error(AWS_CRYPTOSDK_ERR_BAD_STATE);
}
}
/* Postcondition: If data key was generated before call, byte buffer must not have been
* modified.
*
* Note that this only checks the metadata in the byte buffer and not the key
* bytes themselves. Verifying the key bytes were unchanged would require making an extra
* copy of the key bytes, a case of the cure being worse than the disease.
*/
if (precall_data_key_buf.buffer) {
if (memcmp(&precall_data_key_buf, unencrypted_data_key, sizeof(precall_data_key_buf)))
return aws_raise_error(AWS_CRYPTOSDK_ERR_BAD_STATE);
}
return ret;
}