int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
                      const unsigned char *salt, int saltlen, int iter,
                      const EVP_MD *digest, int keylen, unsigned char *out)
{
    const char *empty = "";
    unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
    int cplen, j, k, tkeylen, mdlen;
    unsigned long i = 1;
    HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
    mdlen = EVP_MD_size(digest);
    if (mdlen < 0)
        return 0;
    hctx_tpl = HMAC_CTX_new();
    if (hctx_tpl == NULL)
        return 0;
    p = out;
    tkeylen = keylen;
    if (pass == NULL) {
        pass = empty;
        passlen = 0;
    } else if (passlen == -1) {
        passlen = strlen(pass);
    }
    if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) {
        HMAC_CTX_free(hctx_tpl);
        return 0;
    }
    hctx = HMAC_CTX_new();
    if (hctx == NULL) {
        HMAC_CTX_free(hctx_tpl);
        return 0;
    }
    while (tkeylen) {
        if (tkeylen > mdlen)
            cplen = mdlen;
        else
            cplen = tkeylen;
        itmp[0] = (unsigned char)((i >> 24) & 0xff);
        itmp[1] = (unsigned char)((i >> 16) & 0xff);
        itmp[2] = (unsigned char)((i >> 8) & 0xff);
        itmp[3] = (unsigned char)(i & 0xff);
        if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
            HMAC_CTX_free(hctx);
            HMAC_CTX_free(hctx_tpl);
            return 0;
        }
        if (!HMAC_Update(hctx, salt, saltlen)
            || !HMAC_Update(hctx, itmp, 4)
            || !HMAC_Final(hctx, digtmp, NULL)) {
            HMAC_CTX_free(hctx);
            HMAC_CTX_free(hctx_tpl);
            return 0;
        }
        memcpy(p, digtmp, cplen);
        for (j = 1; j < iter; j++) {
            if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
                HMAC_CTX_free(hctx);
                HMAC_CTX_free(hctx_tpl);
                return 0;
            }
            if (!HMAC_Update(hctx, digtmp, mdlen)
                || !HMAC_Final(hctx, digtmp, NULL)) {
                HMAC_CTX_free(hctx);
                HMAC_CTX_free(hctx_tpl);
                return 0;
            }
            for (k = 0; k < cplen; k++)
                p[k] ^= digtmp[k];
        }
        tkeylen -= cplen;
        i++;
        p += cplen;
    }
    HMAC_CTX_free(hctx);
    HMAC_CTX_free(hctx_tpl);
# ifdef OPENSSL_DEBUG_PKCS5V2
    fprintf(stderr, "Password:\n");
    h__dump(pass, passlen);
    fprintf(stderr, "Salt:\n");
    h__dump(salt, saltlen);
    fprintf(stderr, "Iteration count %d\n", iter);
    fprintf(stderr, "Key:\n");
    h__dump(out, keylen);
# endif
    return 1;
}
['int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,\n                             int passlen, ASN1_TYPE *param,\n                             const EVP_CIPHER *c, const EVP_MD *md, int en_de)\n{\n    unsigned char *salt, key[EVP_MAX_KEY_LENGTH];\n    int saltlen, iter;\n    int rv = 0;\n    unsigned int keylen = 0;\n    int prf_nid, hmac_md_nid;\n    PBKDF2PARAM *kdf = NULL;\n    const EVP_MD *prfmd;\n    if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {\n        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET);\n        goto err;\n    }\n    keylen = EVP_CIPHER_CTX_key_length(ctx);\n    OPENSSL_assert(keylen <= sizeof key);\n    kdf = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), param);\n    if (kdf == NULL) {\n        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);\n        goto err;\n    }\n    keylen = EVP_CIPHER_CTX_key_length(ctx);\n    if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) {\n        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH);\n        goto err;\n    }\n    if (kdf->prf)\n        prf_nid = OBJ_obj2nid(kdf->prf->algorithm);\n    else\n        prf_nid = NID_hmacWithSHA1;\n    if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) {\n        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);\n        goto err;\n    }\n    prfmd = EVP_get_digestbynid(hmac_md_nid);\n    if (prfmd == NULL) {\n        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);\n        goto err;\n    }\n    if (kdf->salt->type != V_ASN1_OCTET_STRING) {\n        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE);\n        goto err;\n    }\n    salt = kdf->salt->value.octet_string->data;\n    saltlen = kdf->salt->value.octet_string->length;\n    iter = ASN1_INTEGER_get(kdf->iter);\n    if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,\n                           keylen, key))\n        goto err;\n    rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);\n err:\n    OPENSSL_cleanse(key, keylen);\n    PBKDF2PARAM_free(kdf);\n    return rv;\n}', 'long ASN1_INTEGER_get(const ASN1_INTEGER *a)\n{\n    int i;\n    int64_t r;\n    if (a == NULL)\n        return 0;\n    i = ASN1_INTEGER_get_int64(&r, a);\n    if (i == 0)\n        return -1;\n    if (r > LONG_MAX || r < LONG_MIN)\n        return -1;\n    return (long)r;\n}', 'int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,\n                      const unsigned char *salt, int saltlen, int iter,\n                      const EVP_MD *digest, int keylen, unsigned char *out)\n{\n    const char *empty = "";\n    unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];\n    int cplen, j, k, tkeylen, mdlen;\n    unsigned long i = 1;\n    HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;\n    mdlen = EVP_MD_size(digest);\n    if (mdlen < 0)\n        return 0;\n    hctx_tpl = HMAC_CTX_new();\n    if (hctx_tpl == NULL)\n        return 0;\n    p = out;\n    tkeylen = keylen;\n    if (pass == NULL) {\n        pass = empty;\n        passlen = 0;\n    } else if (passlen == -1) {\n        passlen = strlen(pass);\n    }\n    if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) {\n        HMAC_CTX_free(hctx_tpl);\n        return 0;\n    }\n    hctx = HMAC_CTX_new();\n    if (hctx == NULL) {\n        HMAC_CTX_free(hctx_tpl);\n        return 0;\n    }\n    while (tkeylen) {\n        if (tkeylen > mdlen)\n            cplen = mdlen;\n        else\n            cplen = tkeylen;\n        itmp[0] = (unsigned char)((i >> 24) & 0xff);\n        itmp[1] = (unsigned char)((i >> 16) & 0xff);\n        itmp[2] = (unsigned char)((i >> 8) & 0xff);\n        itmp[3] = (unsigned char)(i & 0xff);\n        if (!HMAC_CTX_copy(hctx, hctx_tpl)) {\n            HMAC_CTX_free(hctx);\n            HMAC_CTX_free(hctx_tpl);\n            return 0;\n        }\n        if (!HMAC_Update(hctx, salt, saltlen)\n            || !HMAC_Update(hctx, itmp, 4)\n            || !HMAC_Final(hctx, digtmp, NULL)) {\n            HMAC_CTX_free(hctx);\n            HMAC_CTX_free(hctx_tpl);\n            return 0;\n        }\n        memcpy(p, digtmp, cplen);\n        for (j = 1; j < iter; j++) {\n            if (!HMAC_CTX_copy(hctx, hctx_tpl)) {\n                HMAC_CTX_free(hctx);\n                HMAC_CTX_free(hctx_tpl);\n                return 0;\n            }\n            if (!HMAC_Update(hctx, digtmp, mdlen)\n                || !HMAC_Final(hctx, digtmp, NULL)) {\n                HMAC_CTX_free(hctx);\n                HMAC_CTX_free(hctx_tpl);\n                return 0;\n            }\n            for (k = 0; k < cplen; k++)\n                p[k] ^= digtmp[k];\n        }\n        tkeylen -= cplen;\n        i++;\n        p += cplen;\n    }\n    HMAC_CTX_free(hctx);\n    HMAC_CTX_free(hctx_tpl);\n# ifdef OPENSSL_DEBUG_PKCS5V2\n    fprintf(stderr, "Password:\\n");\n    h__dump(pass, passlen);\n    fprintf(stderr, "Salt:\\n");\n    h__dump(salt, saltlen);\n    fprintf(stderr, "Iteration count %d\\n", iter);\n    fprintf(stderr, "Key:\\n");\n    h__dump(out, keylen);\n# endif\n    return 1;\n}']