static int aws_cryptosdk_openssl_hkdf_version()

in source/hkdf.c [124:159]


static int aws_cryptosdk_openssl_hkdf_version(
    struct aws_byte_buf *okm,
    enum aws_cryptosdk_sha_version which_sha,
    const struct aws_byte_buf *salt,
    const struct aws_byte_buf *ikm,
    const struct aws_byte_buf *info) {
    const EVP_MD *evp_md = aws_cryptosdk_get_evp_md(which_sha);
    if (!evp_md) return aws_raise_error(AWS_CRYPTOSDK_ERR_UNSUPPORTED_FORMAT);
    EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
    if (!pctx) return aws_raise_error(AWS_CRYPTOSDK_ERR_CRYPTO_UNKNOWN);
    static const uint8_t zeroes[EVP_MAX_MD_SIZE] = { 0 };
    const uint8_t *mysalt                        = NULL;
    size_t mysalt_len                            = 0;
    if (salt->len) {
        mysalt     = (uint8_t *)salt->buffer;
        mysalt_len = salt->len;
    } else {
        mysalt     = zeroes;
        mysalt_len = EVP_MD_size(evp_md);
    }

    if (EVP_PKEY_derive_init(pctx) <= 0) goto err;
    if (EVP_PKEY_CTX_set_hkdf_md(pctx, evp_md) <= 0) goto err;
    if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, mysalt, mysalt_len) <= 0) goto err;
    if (EVP_PKEY_CTX_set1_hkdf_key(pctx, ikm->buffer, ikm->len) <= 0) goto err;
    if (EVP_PKEY_CTX_add1_hkdf_info(pctx, info->buffer, info->len) <= 0) goto err;
    if (EVP_PKEY_derive(pctx, okm->buffer, &okm->len) <= 0) goto err;

    EVP_PKEY_CTX_free(pctx);
    return AWS_OP_SUCCESS;

err:
    EVP_PKEY_CTX_free(pctx);
    aws_byte_buf_secure_zero(okm);
    return aws_raise_error(AWS_CRYPTOSDK_ERR_CRYPTO_UNKNOWN);
}