Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why AND a uint32 value with 0xFFFFFFFF?

A friend of mine was looking through this open-source SSL code at the functions for handling SHA encryption, and noticed this odd snippet:

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]++;

We can't figure out two things about this code. First, it ANDs ctx->total[0] (of type uint32_t) with 0xFFFFFFFF, which shouldn't do anything. In binary, that's ANDing with all 1s, which should yield the same value. In my mind, then, these two lines are identical:

ctx->total[0] &= 0xFFFFFFFF;
ctx->total[0] =  ctx->total[0];

If I am right, why is this line there? Some security reason? If I am wrong, how and why?

Second, we don't understand when that if would ever be true, assuming the AND doesn't do anything. If the AND does nothing, then the if is essentially:

if (ctx->total[0] < ctx->total[0])

which should never be true. What are we missing?


If you want to see the header file to convince yourself that ctx->total[0] is of type uint32_t, or for whatever other reason, you can find that here.

Also, my first wild guess is that there's something sneaky happening when we cast ilen from size_t to uint32_t, but I'm still stuck and confused.

like image 939
ravron Avatar asked Oct 21 '13 17:10

ravron


People also ask

What is 0xFFFFFFFF value?

For example, in 32-bit mode, the hexadecimal value 0xFFFFFFFF is equivalent to the decimal value of "-1". In 64-bit mode, however, the decimal equivalent is 4294967295.

What is UInt32 in C?

In C#, UInt32 struct is used to represent 32-bit unsigned integers(also termed as uint data type) starting from range 0 to 4,294,967,295.


1 Answers

First question:

You're right that this &ing is not needed for 32bit, my guess is - they're trying to prevent situations when ctx->total[0] is not 32bit (so even if somebody will change it or platform will have 64bit even for uint32_t type), so with this code they are 100% sure, without 99.99999% :)

Second question is easy:

Check how this code will work for values ctx->total[0] == 0xFFFFFFFF and 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]++;
like image 200
Iłya Bursov Avatar answered Oct 21 '22 07:10

Iłya Bursov