static int aws_cryptosdk_private_derive_key_v2()

in source/cipher.c [352:406]


static int aws_cryptosdk_private_derive_key_v2(
    const struct aws_cryptosdk_alg_properties *props,
    struct content_key *content_key,
    const struct data_key *data_key,
    struct aws_byte_buf *commitment,
    const struct aws_byte_buf *message_id) {
    AWS_PRECONDITION(aws_cryptosdk_alg_properties_is_valid(props));
    AWS_PRECONDITION(aws_cryptosdk_content_key_is_valid(content_key));
    AWS_PRECONDITION(aws_cryptosdk_data_key_is_valid(data_key));
    AWS_PRECONDITION(aws_byte_buf_is_valid(commitment));
    AWS_PRECONDITION(aws_byte_buf_is_valid(message_id));

    if (commitment->capacity < props->commitment_len) {
        return AWS_CRYPTOSDK_ERR_CRYPTO_UNKNOWN;
    }

    if (message_id->len != MSG_ID_LEN_V2) {
        return AWS_CRYPTOSDK_ERR_UNSUPPORTED_FORMAT;
    }

    const struct aws_byte_buf mysalt = aws_byte_buf_from_array(message_id->buffer, message_id->len);
    const struct aws_byte_buf myikm  = aws_byte_buf_from_array(data_key->keybuf, props->data_key_len);

    memset(content_key->keybuf, 0, sizeof(content_key->keybuf));
    if (props->commitment_len) {
        assert(commitment->buffer);
        memset(commitment->buffer, 0, props->commitment_len);
    }

    uint8_t derivekey_info_array[] = "\0\0DERIVEKEY";
    derivekey_info_array[0]        = props->alg_id >> 8;
    derivekey_info_array[1]        = props->alg_id & 0xFF;

    const struct aws_byte_buf derivekey_info =
        aws_byte_buf_from_array(derivekey_info_array, sizeof(derivekey_info_array) - 1);

    static const uint8_t commitkey_info_array[] = "COMMITKEY";
    const struct aws_byte_buf commitkey_info =
        aws_byte_buf_from_array(commitkey_info_array, sizeof(commitkey_info_array) - 1);

    struct aws_byte_buf myokm = aws_byte_buf_from_array(content_key->keybuf, props->content_key_len);

    enum aws_cryptosdk_sha_version which_sha = aws_cryptosdk_which_sha(props->alg_id);
    if (which_sha == AWS_CRYPTOSDK_NOSHA) {
        return AWS_CRYPTOSDK_ERR_UNSUPPORTED_FORMAT;
    }

    commitment->len = props->commitment_len;
    int rv          = aws_cryptosdk_hkdf(commitment, which_sha, &mysalt, &myikm, &commitkey_info);
    if (rv != AWS_ERROR_SUCCESS) {
        return rv;
    }

    return aws_cryptosdk_hkdf(&myokm, which_sha, &mysalt, &myikm, &derivekey_info);
}