C version of OpenSSL EVP_BytesToKey method

大城市里の小女人 提交于 2019-12-12 05:48:47

问题


I'm looking for C implementation of the OpenSSL EVP_BytesToKey function.

This is pseudo-code explanation of the EVP_BytesToKey method (in /doc/ssleay.txt of the OpenSSL source):

/* M[] is an array of message digests
 * MD() is the message digest function */
M[0]=MD(data . salt);
for (i=1; i<count; i++) M[0]=MD(M[0]);

i=1
while (data still needed for key and iv)
{
    M[i]=MD(M[i-1] . data . salt);
    for (i=1; i<count; i++) M[i]=MD(M[i]);
    i++;
}

If the salt is NULL, it is not used.
The digests are concatenated together.
M = M[0] . M[1] . M[2] .......

this is my code(MD() is sha512. And i need the key is 32 bytes and the iv is 16 bytes):

int main()
{
    unsigned long long out[8]; 
    unsigned char key[9] = {0x4b,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c};
    int len, i;

    len = sizeof(key);
    sha512(out, key, len);

    unsigned char a[sizeof(out)];
    for (i = 0; i < count; i++) 
    {
        long2char(out, a); // unsigned long long to unsigned char;
        sha512(out, a, sizeof(out));
    }

    return 0;
}

After count times sha512(), the out is 64 bytes, so I think I don't need the rest of that pseudo-code. But the result is not correct, I don't know what went wrong.

I wish you can help me to figure it out. thanks!


回答1:


I'm looking for C implementation of the OpenSSL EVP_BytesToKey function...

Perhaps you should just use the one OpenSSL provides? You know, the one called EVP_BytesToKey in evp_key.c (shown below).

OpenSSL 1.1.0c changed the digest algorithm used in some internal components. Formerly, MD5 was used, and 1.1.0 switched to SHA256. Be careful the change is not affecting you in both EVP_BytesToKey and commands like openssl enc


int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
                   const unsigned char *salt, const unsigned char *data,
                   int datal, int count, unsigned char *key,
                   unsigned char *iv)
{
    EVP_MD_CTX *c;
    unsigned char md_buf[EVP_MAX_MD_SIZE];
    int niv, nkey, addmd = 0;
    unsigned int mds = 0, i;
    int rv = 0;
    nkey = EVP_CIPHER_key_length(type);
    niv = EVP_CIPHER_iv_length(type);
    OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
    OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);

    if (data == NULL)
        return nkey;

    c = EVP_MD_CTX_new();
    if (c == NULL)
        goto err;
    for (;;) {
        if (!EVP_DigestInit_ex(c, md, NULL))
            goto err;
        if (addmd++)
            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
                goto err;
        if (!EVP_DigestUpdate(c, data, datal))
            goto err;
        if (salt != NULL)
            if (!EVP_DigestUpdate(c, salt, PKCS5_SALT_LEN))
                goto err;
        if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
            goto err;

        for (i = 1; i < (unsigned int)count; i++) {
            if (!EVP_DigestInit_ex(c, md, NULL))
                goto err;
            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
                goto err;
            if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
                goto err;
        }
        i = 0;
        if (nkey) {
            for (;;) {
                if (nkey == 0)
                    break;
                if (i == mds)
                    break;
                if (key != NULL)
                    *(key++) = md_buf[i];
                nkey--;
                i++;
            }
        }
        if (niv && (i != mds)) {
            for (;;) {
                if (niv == 0)
                    break;
                if (i == mds)
                    break;
                if (iv != NULL)
                    *(iv++) = md_buf[i];
                niv--;
                i++;
            }
        }
        if ((nkey == 0) && (niv == 0))
            break;
    }
    rv = EVP_CIPHER_key_length(type);
 err:
    EVP_MD_CTX_free(c);
    OPENSSL_cleanse(md_buf, sizeof(md_buf));
    return rv;
}


来源:https://stackoverflow.com/questions/29534656/c-version-of-openssl-evp-bytestokey-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!