PKCS5_PBKDF2_HMAC_SHA1的返回值是什么意思? [英] What does PKCS5_PBKDF2_HMAC_SHA1 return value mean?

查看:2473
本文介绍了PKCS5_PBKDF2_HMAC_SHA1的返回值是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用OpenSSL的 PKCS5_PBKDF2_HMAC_SHA1 方法。我收集,如果成功,它返回0,否则其他值。我的问题是,非零回报值是什么意思?内存错误?使用错误?我的程序应该如何处理它(重试,退出?)?



编辑:一个必然的问题是,除了方法本身的逆向工程之外,是否有任何办法?

解决方案


除了逆向工程之外,还有什么办法解决这个问题吗? / p>

PKCS5_PBKDF2_HMAC_SHA1 看起来像其中一个未记录的函数,因为我找不到在 OpenSSL文档中。 OpenSSL有很多,所以如果你要使用图书馆,你应该准备学习资料。







我收集,如果成功,它返回0,否则其他值。


其实,它的逆转。这是我如何知道...

  $ grep -R PKCS5_PBKDF2_HMAC_SHA1 * 
crypto / evp / evp.h:int PKCS5_PBKDF2_HMAC_SHA1(const char * pass,int passlen,
crypto / evp / p5_crpt2.c:int PKCS5_PBKDF2_HMAC_SHA1(const char * pass,int passlen,
...

所以,你在 crypto / evp / p5_crpt2.c 中发现函数的实现: p>

  int PKCS5_PBKDF2_HMAC_SHA1(const char * pass,int passlen,
const unsigned char * salt,int saltlen,int iter,
int keylen,unsigned char * out)
{
返回PKCS5_PBKDF2_HMAC(pass,passlen,salt,saltlen,iter,
EVP_sha1(),keylen,out);
以下 PKCS5_PBKDF2_HMAC

  $ grep -R PKCS5_PBKDF2_HMAC * 
...
crypto / evp / evp.h:int PKCS5_PBKDF2_HMAC(const char * pass,int passlen,
crypto / evp /p5_crpt2.c:int PKCS5_PBKDF2_HMAC(const char * pass,int passlen,
...

再次,从 crypto / evp / p5_crpt2.c

  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)
{
unsigned char digtmp [EVP_MAX_MD_SIZE],* p,itmp [4];
int cplen,j,k,tkeylen,mdlen;
unsigned long i = 1;
HMAC_CTX hctx_tpl,hctx;

mdlen = EVP_MD_size(摘要);
if(mdlen< 0)
return 0;

HMAC_CTX_init(& hctx_tpl);
p = out;
tkeylen = keylen;
if(!pass)
passlen = 0;
else if(passlen == -1)
passlen = strlen(pass);
if(!HMAC_Init_ex(& hctx_tpl,pass,passlen,digest,NULL))
{
HMAC_CTX_cleanup(& hctx_tpl);
return 0;
}
while(tkeylen)
{
if(tkeylen> mdlen)
cplen = mdlen;
else
cplen = tkeylen;
/ *我们不太可能使用超过256个块(5120位!)
*,但只是为了... ...
* /
itmp [0] =(无符号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_cleanup(& hctx_tpl);
return 0;
}
如果(!HMAC_Update(& hctx,salt,saltlen)
||!HMAC_Update(& hctx,itmp,4)
||!HMAC_Final(& hctx,digtmp,NULL))
{
HMAC_CTX_cleanup(& hctx_tpl);
HMAC_CTX_cleanup(& hctx);
return 0;
}
HMAC_CTX_cleanup(& hctx);
memcpy(p,digtmp,cplen); (j = 1; j< iter; j ++)
{
if(!HMAC_CTX_copy(& hctx,& hctx_tpl))
{
HMAC_CTX_cleanup (安培; hctx_tpl);
return 0;
}
如果(!HMAC_Update(& hctx,digtmp,mdlen)
||!HMAC_Final(& hctx,digtmp,NULL))
{
HMAC_CTX_cleanup (安培; hctx_tpl);
HMAC_CTX_cleanup(& hctx);
return 0;
}
HMAC_CTX_cleanup(& hctx); (k = 0; k
p [k] ^ = digtmp [k];
}
tkeylen- = cplen;
i ++;
p + = cplen;
}
HMAC_CTX_cleanup(& hctx_tpl);

return 1;
}

所以看起来像 0 失败,并且 1 成功。您不应该看到其他值。如果你得到一个 0 ,那么所有的 OUT 参数是垃圾。







内存错误?使用错误?


嗯,有时你可以调用 ERR_get_error 。如果你调用它,它是有意义的,那么错误代码是好的。如果错误代码没有意义,那么它可能不太好。



可惜的是,这是我处理它的方式,因为库与设置错误代码不一致。例如,这里是加载 RDRAND 引擎的库代码。



注意代码清除错误代码失败如果它的第三代常春藤桥(这是被测试的能力),并且不清除或设置错误否则!!!

  void ENGINE_load_rdrand(void)
{
extern unsigned int OPENSSL_ia32cap_P [];

if(OPENSSL_ia32cap_P [1]&(1<(62-32)))
{
ENGINE * toadd = ENGINE_rdrand();
if(!toadd)return;
ENGINE_add(toadd);
ENGINE_free(toadd);
ERR_clear_error();
}
}







我的程序应该如何处理它(重试,退出?)?


它看起来像一个硬故障。






最后,这正是我在这种情况下导航的原因。如果你不喜欢 grep ,你可以尝试 ctags 或其他源代码浏览器。


I'm attempting to use OpenSSL's PKCS5_PBKDF2_HMAC_SHA1 method. I gather that it returns 0 if it succeeds, and some other value otherwise. My question is, what does a non-zero return value mean? Memory error? Usage error? How should my program handle it (retry, quit?)?

Edit: A corollary question is, is there any way to figure this out besides reverse-engineering the method itself?

解决方案

is there any way to figure this out besides reverse-engineering the method itself?

PKCS5_PBKDF2_HMAC_SHA1 looks like one of those undocumented functions because I can't find it in the OpenSSL docs. OpenSSL has a lot of them, so you should be prepared to study the sources if you are going to use the library.


I gather that it returns 0 if it succeeds, and some other value otherwise.

Actually, its reversed. Here's how I know...

$ grep -R PKCS5_PBKDF2_HMAC_SHA1 *
crypto/evp/evp.h:int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
crypto/evp/p5_crpt2.c:int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
...

So, you find the function's implementation in crypto/evp/p5_crpt2.c:

int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
                           const unsigned char *salt, int saltlen, int iter,
                           int keylen, unsigned char *out)
    {
        return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter,
                                 EVP_sha1(), keylen, out);
    }

Following PKCS5_PBKDF2_HMAC:

$ grep -R PKCS5_PBKDF2_HMAC *
...
crypto/evp/evp.h:int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
crypto/evp/p5_crpt2.c:int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
...

And again, from crypto/evp/p5_crpt2.c:

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)
{
    unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
    int cplen, j, k, tkeylen, mdlen;
    unsigned long i = 1;
    HMAC_CTX hctx_tpl, hctx;

    mdlen = EVP_MD_size(digest);
    if (mdlen < 0)
        return 0;

    HMAC_CTX_init(&hctx_tpl);
    p = out;
    tkeylen = keylen;
    if(!pass)
        passlen = 0;
    else if(passlen == -1)
        passlen = strlen(pass);
    if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL))
    {
        HMAC_CTX_cleanup(&hctx_tpl);
        return 0;
    }
    while(tkeylen)
    {
        if(tkeylen > mdlen)
            cplen = mdlen;
        else
            cplen = tkeylen;
        /* We are unlikely to ever use more than 256 blocks (5120 bits!)
         * but just in case...
         */
        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_cleanup(&hctx_tpl);
            return 0;
        }
        if (!HMAC_Update(&hctx, salt, saltlen)
            || !HMAC_Update(&hctx, itmp, 4)
            || !HMAC_Final(&hctx, digtmp, NULL))
        {
            HMAC_CTX_cleanup(&hctx_tpl);
            HMAC_CTX_cleanup(&hctx);
            return 0;
        }
        HMAC_CTX_cleanup(&hctx);
        memcpy(p, digtmp, cplen);
        for(j = 1; j < iter; j++)
        {
            if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
            {
                HMAC_CTX_cleanup(&hctx_tpl);
                return 0;
            }
            if (!HMAC_Update(&hctx, digtmp, mdlen)
                || !HMAC_Final(&hctx, digtmp, NULL))
            {
                HMAC_CTX_cleanup(&hctx_tpl);
                HMAC_CTX_cleanup(&hctx);
                return 0;
            }
            HMAC_CTX_cleanup(&hctx);
            for(k = 0; k < cplen; k++)
                p[k] ^= digtmp[k];
        }
        tkeylen-= cplen;
        i++;
        p+= cplen;
    }
    HMAC_CTX_cleanup(&hctx_tpl);

    return 1;
}

So it looks like 0 on failure, and 1 on success. You should not see other values. And if you get a 0, then all the OUT parameters are junk.


Memory error? Usage error?

Well, sometimes you can call ERR_get_error. If you call it and it makes sense, then the error code is good. If the error code makes no sense, then its probably not good.

Sadly, that's the way I handle it because the library is not consistent with setting error codes. For example, here's the library code to load the RDRAND engine.

Notice the code clears the error code on failure if its a 3rd generation Ivy Bridge (that's the capability being tested), and does not clear or set an error otherwise!!!

void ENGINE_load_rdrand (void)
{
    extern unsigned int OPENSSL_ia32cap_P[];

    if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
    {
        ENGINE *toadd = ENGINE_rdrand();
        if(!toadd) return;
        ENGINE_add(toadd);
        ENGINE_free(toadd);
        ERR_clear_error();
    }
}


How should my program handle it (retry, quit?)?

It looks like a hard failure.


Finally, that's exactly how I navigate the sources in this situation. If you don't like grep you can try ctags or another source code browser.

这篇关于PKCS5_PBKDF2_HMAC_SHA1的返回值是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆