rav*_*ron 6 c bit-manipulation
我的一个朋友在处理SHA加密的函数中查看了这个开源SSL代码,并注意到这个奇怪的片段:
ctx->total[0] += (uint32_t) ilen; // ilen is of type size_t
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
Run Code Online (Sandbox Code Playgroud)
我们无法弄清楚这个代码的两个方面.首先,ANDs ctx->total[0](类型uint32_t)与0xFFFFFFFF,不应做任何事情.在二进制中,这与所有1s进行AND运算,它应该产生相同的值.在我看来,这两行是相同的:
ctx->total[0] &= 0xFFFFFFFF;
ctx->total[0] = ctx->total[0];
Run Code Online (Sandbox Code Playgroud)
如果我是对的,为什么这条线呢?一些安全原因?如果我错了,怎么和为什么?
其次,if假设AND没有做任何事情,我们不明白什么时候会成真.如果AND什么都不做,那么if基本上是:
if (ctx->total[0] < ctx->total[0])
Run Code Online (Sandbox Code Playgroud)
这永远不应该是真的.我们缺少什么?
如果你想看到头文件来说服自己ctx->total[0]是类型uint32_t,或者出于其他原因,你可以在这里找到它.
另外,我的第一个野生的猜测是,有一些偷偷摸摸的事情发生时,我们投ilen自size_t到uint32_t,但我仍然停留和困惑.
第一个问题:
你是对的,32bit不需要这个,我的猜测是 - 他们试图防止ctx->total[0]不是32位的情况(所以即使有人会改变它,平台也会有64位甚至uint32_t类型),所以这个代码他们100%肯定,没有99.99999%:)
第二个问题很简单:
检查此代码如何适用于值ctx->total[0] == 0xFFFFFFFF和ilen == 1
ctx->total[0] += (uint32_t) ilen; // this will overflow and total[0] now 0
if( ctx->total[0] < (uint32_t) ilen ) // 0<1 true
ctx->total[1]++;
Run Code Online (Sandbox Code Playgroud)