int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
{
    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
    unsigned char md[EVP_MAX_MD_SIZE];
    unsigned int mdlen;
    int r = 0;
    CMS_DigestedData *dd;
    if (mctx == NULL) {
        CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    dd = cms->d.digestedData;
    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm))
        goto err;
    if (EVP_DigestFinal_ex(mctx, md, &mdlen) <= 0)
        goto err;
    if (verify) {
        if (mdlen != (unsigned int)dd->digest->length) {
            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
                   CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
            goto err;
        }
        if (memcmp(md, dd->digest->data, mdlen))
            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
                   CMS_R_VERIFICATION_FAILURE);
        else
            r = 1;
    } else {
        if (!ASN1_STRING_set(dd->digest, md, mdlen))
            goto err;
        r = 1;
    }
 err:
    EVP_MD_CTX_free(mctx);
    return r;
}
['int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)\n{\n    EVP_MD_CTX *mctx = EVP_MD_CTX_new();\n    unsigned char md[EVP_MAX_MD_SIZE];\n    unsigned int mdlen;\n    int r = 0;\n    CMS_DigestedData *dd;\n    if (mctx == NULL) {\n        CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    dd = cms->d.digestedData;\n    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm))\n        goto err;\n    if (EVP_DigestFinal_ex(mctx, md, &mdlen) <= 0)\n        goto err;\n    if (verify) {\n        if (mdlen != (unsigned int)dd->digest->length) {\n            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,\n                   CMS_R_MESSAGEDIGEST_WRONG_LENGTH);\n            goto err;\n        }\n        if (memcmp(md, dd->digest->data, mdlen))\n            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,\n                   CMS_R_VERIFICATION_FAILURE);\n        else\n            r = 1;\n    } else {\n        if (!ASN1_STRING_set(dd->digest, md, mdlen))\n            goto err;\n        r = 1;\n    }\n err:\n    EVP_MD_CTX_free(mctx);\n    return r;\n}', 'EVP_MD_CTX *EVP_MD_CTX_new(void)\n{\n    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));\n}', 'void *CRYPTO_zalloc(size_t num, const char *file, int line)\n{\n    void *ret = CRYPTO_malloc(num, file, line);\n    FAILTEST();\n    if (ret != NULL)\n        memset(ret, 0, num);\n    return ret;\n}', 'void *CRYPTO_malloc(size_t num, const char *file, int line)\n{\n    void *ret = NULL;\n    if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)\n        return malloc_impl(num, file, line);\n    if (num == 0)\n        return NULL;\n    FAILTEST();\n    allow_customize = 0;\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);\n        ret = malloc(num);\n        CRYPTO_mem_debug_malloc(ret, num, 1, file, line);\n    } else {\n        ret = malloc(num);\n    }\n#else\n    osslargused(file); osslargused(line);\n    ret = malloc(num);\n#endif\n    return ret;\n}', 'int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,\n                                 X509_ALGOR *mdalg)\n{\n    int nid;\n    const ASN1_OBJECT *mdoid;\n    X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);\n    nid = OBJ_obj2nid(mdoid);\n    for (;;) {\n        EVP_MD_CTX *mtmp;\n        chain = BIO_find_type(chain, BIO_TYPE_MD);\n        if (chain == NULL) {\n            CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,\n                   CMS_R_NO_MATCHING_DIGEST);\n            return 0;\n        }\n        BIO_get_md_ctx(chain, &mtmp);\n        if (EVP_MD_CTX_type(mtmp) == nid\n            || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)\n            return EVP_MD_CTX_copy_ex(mctx, mtmp);\n        chain = BIO_next(chain);\n    }\n}', 'void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,\n                     const void **ppval, const X509_ALGOR *algor)\n{\n    if (paobj)\n        *paobj = algor->algorithm;\n    if (pptype) {\n        if (algor->parameter == NULL) {\n            *pptype = V_ASN1_UNDEF;\n            return;\n        } else\n            *pptype = algor->parameter->type;\n        if (ppval)\n            *ppval = algor->parameter->value.ptr;\n    }\n}', 'int OBJ_obj2nid(const ASN1_OBJECT *a)\n{\n    const unsigned int *op;\n    ADDED_OBJ ad, *adp;\n    if (a == NULL)\n        return NID_undef;\n    if (a->nid != 0)\n        return a->nid;\n    if (a->length == 0)\n        return NID_undef;\n    if (added != NULL) {\n        ad.type = ADDED_DATA;\n        ad.obj = (ASN1_OBJECT *)a;\n        adp = lh_ADDED_OBJ_retrieve(added, &ad);\n        if (adp != NULL)\n            return adp->obj->nid;\n    }\n    op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);\n    if (op == NULL)\n        return NID_undef;\n    return nid_objs[*op].nid;\n}', 'DEFINE_LHASH_OF(ADDED_OBJ)', 'void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data)\n{\n    unsigned long hash;\n    OPENSSL_LH_NODE **rn;\n    void *ret;\n    int scratch;\n    lh->error = 0;\n    rn = getrn(lh, data, &hash);\n    if (*rn == NULL) {\n        CRYPTO_atomic_add(&lh->num_retrieve_miss, 1, &scratch, lh->retrieve_stats_lock);\n        return NULL;\n    } else {\n        ret = (*rn)->data;\n        CRYPTO_atomic_add(&lh->num_retrieve, 1, &scratch, lh->retrieve_stats_lock);\n    }\n    return ret;\n}', 'int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)\n{\n# if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL)\n    if (__atomic_is_lock_free(sizeof(*val), val)) {\n        *ret = __atomic_add_fetch(val, amount, __ATOMIC_ACQ_REL);\n        return 1;\n    }\n# endif\n    if (!CRYPTO_THREAD_write_lock(lock))\n        return 0;\n    *val += amount;\n    *ret  = *val;\n    if (!CRYPTO_THREAD_unlock(lock))\n        return 0;\n    return 1;\n}', 'int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)\n{\n# ifdef USE_RWLOCK\n    if (pthread_rwlock_wrlock(lock) != 0)\n        return 0;\n# else\n    if (pthread_mutex_lock(lock) != 0)\n        return 0;\n# endif\n    return 1;\n}', 'void EVP_MD_CTX_free(EVP_MD_CTX *ctx)\n{\n    EVP_MD_CTX_reset(ctx);\n    OPENSSL_free(ctx);\n}', 'void CRYPTO_free(void *str, const char *file, int line)\n{\n    if (free_impl != NULL && free_impl != &CRYPTO_free) {\n        free_impl(str, file, line);\n        return;\n    }\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_free(str, 0, file, line);\n        free(str);\n        CRYPTO_mem_debug_free(str, 1, file, line);\n    } else {\n        free(str);\n    }\n#else\n    free(str);\n#endif\n}']