RFC Errata
RFC 3174, "US Secure Hash Algorithm 1 (SHA1)", September 2001
Note: This RFC has been updated by RFC 4634, RFC 6234
Source of RFC: INDEPENDENTSee Also: RFC 3174 w/ inline errata
Errata ID: 329
Status: Verified
Type: Technical
Publication Format(s) : TEXT
Reported By: Ben Davis
Date Reported: 2006-06-01
Verifier Name: Nevil Brownlee
Date Verified: 2010-04-03
Section 7.2 says:
/* * Initialize the first 16 words in the array W */ for(t = 0; t < 16; t++) { W[t] = context->Message_Block[t * 4] << 24; W[t] |= context->Message_Block[t * 4 + 1] << 16; W[t] |= context->Message_Block[t * 4 + 2] << 8; W[t] |= context->Message_Block[t * 4 + 3]; }
It should say:
/* * Initialize the first 16 words in the array W */ for(t = 0; t < 16; t++) { W[t] = (uint32_t)(context->Message_Block[t * 4]) << 24; W[t] |= (uint32_t)(context->Message_Block[t * 4 + 1]) << 16; W[t] |= context->Message_Block[t * 4 + 2] << 8; W[t] |= context->Message_Block[t * 4 + 3]; }
Notes:
Note that Message_Block is an array of "integers of >= 16 bits" as described in "sha1.h" but W[] is an array of unsigned 32-bit integers.
While this works fine in many compilers, some compilers (e.g. Dynamic C v9.25) processing the line:
W[t] = context->Message_Block[t * 4] << 24;
will take the 16 bit integer "context->Message_Block[t * 4]" and shift it left 24 bits, and then assign the resulting (still) 16 bit integer to the 32 bit integer W[t].
This will lead to a different (and undesired) result than the intended behavior of first promoting the 16 bit integer "context->Message_Block[t * 4]" to a 32 bit integer, and *then* shifting that 32 bit integer left 24 times, and storing the result in W[t].
The solution is to use an explicit cast. The last two lines of code in the for loop can remain as they are, as they will not suffer from the above problem and do not need the explicit cast.