int aws_cryptosdk_keyring_on_encrypt()

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;
}