static apr_status_t crypto_digest_init()

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;

}