int aws_cryptosdk_raw_aes_keyring_encrypt_data_key_with_iv()

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