in crypto/apr_crypto_openssl.c [1456:1544]
static apr_status_t crypto_digest_init(apr_crypto_digest_t **d,
const apr_crypto_key_t *key, apr_crypto_digest_rec_t *rec, apr_pool_t *p)
{
apr_crypto_config_t *config = key->f->config;
apr_crypto_digest_t *digest = *d;
if (!digest) {
*d = digest = apr_pcalloc(p, sizeof(apr_crypto_digest_t));
if (!digest) {
return APR_ENOMEM;
}
apr_pool_cleanup_register(p, digest, crypto_digest_cleanup_helper,
apr_pool_cleanup_null);
}
else {
crypto_digest_cleanup(digest);
}
digest->f = key->f;
digest->pool = p;
digest->provider = key->provider;
digest->key = key;
digest->rec = rec;
switch (key->rec->ktype) {
case APR_CRYPTO_KTYPE_HASH: {
if (!digest->mdCtx) {
digest->mdCtx = EVP_MD_CTX_new();
if (!digest->mdCtx) {
return APR_ENOMEM;
}
}
if (!EVP_DigestInit_ex(digest->mdCtx, key->md, config->engine)) {
return APR_EINIT;
}
break;
}
case APR_CRYPTO_KTYPE_HMAC:
case APR_CRYPTO_KTYPE_CMAC: {
#if APR_USE_OPENSSL_PRE_3_0_API
if (!digest->mdCtx) {
digest->mdCtx = EVP_MD_CTX_new();
if (!digest->mdCtx) {
return APR_ENOMEM;
}
}
if (!EVP_DigestSignInit(digest->mdCtx, NULL, key->md,
config->engine, key->pkey)) {
return APR_EINIT;
}
#else
OSSL_PARAM params[2];
if (!digest->macCtx) {
digest->macCtx = EVP_MAC_CTX_new(key->mac);
if (!digest->macCtx) {
return APR_ENOMEM;
}
}
if (key->rec->ktype == APR_CRYPTO_KTYPE_HMAC) {
params[0] =
OSSL_PARAM_construct_utf8_string("digest",
(char *)EVP_MD_name(key->md),
0);
}
else {
params[0] =
OSSL_PARAM_construct_utf8_string("cipher",
(char *)EVP_CIPHER_name(key->cipher),
0);
}
params[1] = OSSL_PARAM_construct_end();
if (!EVP_MAC_init(digest->macCtx,
key->rec->k.hmac.secret,
key->rec->k.hmac.secretLen,
params)) {
return APR_EINIT;
}
#endif
break;
}
default: {
return APR_EINVAL;
}
}
return APR_SUCCESS;
}