我的一个朋友正在浏览这个开源SSL代码来处理SHA加密的函数,并注意到这个奇怪的片段:
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]++;
我们无法弄清楚关于此代码的两件事。 首先,它 AND ctx->total[0]
(类型 uint32_t
)与 0xFFFFFFFF
,这不应该做任何事情。 在二进制中,这是所有1
的 AND,它应该产生相同的值。 那么,在我看来,这两行是相同的:
ctx->total[0] &= 0xFFFFFFFF;
ctx->total[0] = ctx->total[0];
如果我是对的,为什么这条线在那里?一些安全原因?如果我错了,如何以及为什么?
其次,我们不明白这种if
什么时候会是真的,假设 AND 什么都不做。 如果 AND 什么都不做,那么if
本质上是:
if (ctx->total[0] < ctx->total[0])
这永远不应该是真的。 我们缺少什么?
如果您想查看头文件以说服自己ctx->total[0]
属于 uint32_t
类型,或者出于任何其他原因,您可以在此处找到它。
另外,我的第一个疯狂猜测是,当我们从size_t
到uint32_t
投ilen
时,发生了一些偷偷摸摸的事情,但我仍然感到困惑和困惑。
第一个问题:
你是对的,32 位不需要这个 &ing,我的猜测是 - 他们试图防止ctx->total[0]
不是 32 位的情况(所以即使有人会更改它或平台即使对于uint32_t类型也会有 64 位),所以有了这段代码,他们是 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]++;
if
基本上是做的:
if (ctx->total[0] + (uint32_t) ilen < (uint32_t) ilen)
ctx->total[1]++;
即,如果向ctx->total[0]
添加ilen
会导致溢出,则碰撞ctx->total[1]
。 换句话说,它正在执行加法的携带。