sha256.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*++
  2. Copyright (c) 2015 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. sha256.c
  5. Abstract:
  6. This module implements the SHA-256 hashing function.
  7. Author:
  8. Evan Green 13-Jan-2015
  9. Environment:
  10. Any
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include "cryptop.h"
  16. //
  17. // --------------------------------------------------------------------- Macros
  18. //
  19. #define SHA256_ROTATE_LEFT(_Value, _Count) \
  20. (((_Value) << (_Count)) | ((_Value) >> (32 - (_Count))))
  21. #define SHA256_ROTATE_RIGHT(_Value, _Count) \
  22. (((_Value) >> (_Count)) | ((_Value) << (32 - (_Count))))
  23. #define SHA256_CH(_ValueX, _ValueY, _ValueZ) \
  24. (((_ValueX) & (_ValueY)) ^ (~(_ValueX) & (_ValueZ)))
  25. #define SHA256_MAJ(_ValueX, _ValueY, _ValueZ) \
  26. (((_ValueX) & (_ValueY)) ^ ((_ValueX) & (_ValueZ)) ^ \
  27. ((_ValueY) & (_ValueZ)))
  28. #define SHA256_EP0(_Value) \
  29. (SHA256_ROTATE_RIGHT(_Value, 2) ^ \
  30. SHA256_ROTATE_RIGHT(_Value, 13) ^ \
  31. SHA256_ROTATE_RIGHT(_Value, 22))
  32. #define SHA256_EP1(_Value) \
  33. (SHA256_ROTATE_RIGHT(_Value, 6) ^ \
  34. SHA256_ROTATE_RIGHT(_Value, 11) ^ \
  35. SHA256_ROTATE_RIGHT(_Value, 25))
  36. #define SHA256_SIG0(_Value) \
  37. (SHA256_ROTATE_RIGHT(_Value, 7) ^ \
  38. SHA256_ROTATE_RIGHT(_Value, 18) ^ \
  39. ((_Value) >> 3))
  40. #define SHA256_SIG1(_Value) \
  41. (SHA256_ROTATE_RIGHT(_Value, 17) ^ \
  42. SHA256_ROTATE_RIGHT(_Value, 19) ^ \
  43. ((_Value) >> 10))
  44. //
  45. // ---------------------------------------------------------------- Definitions
  46. //
  47. //
  48. // ------------------------------------------------------ Data Type Definitions
  49. //
  50. //
  51. // ----------------------------------------------- Internal Function Prototypes
  52. //
  53. VOID
  54. CypSha256ProcessMessage (
  55. PSHA256_CONTEXT Context
  56. );
  57. VOID
  58. CypSha256PadMessage (
  59. PSHA256_CONTEXT Context
  60. );
  61. //
  62. // -------------------------------------------------------------------- Globals
  63. //
  64. const ULONG CySha256KConstants[64] = {
  65. 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1,
  66. 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
  67. 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786,
  68. 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
  69. 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147,
  70. 0x06CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
  71. 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B,
  72. 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
  73. 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A,
  74. 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
  75. 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
  76. };
  77. //
  78. // ------------------------------------------------------------------ Functions
  79. //
  80. CRYPTO_API
  81. VOID
  82. CySha256Initialize (
  83. PSHA256_CONTEXT Context
  84. )
  85. /*++
  86. Routine Description:
  87. This routine initializes a SHA-256 context structure, preparing it to
  88. accept and hash data.
  89. Arguments:
  90. Context - Supplies a pointer to the context to initialize.
  91. Return Value:
  92. None.
  93. --*/
  94. {
  95. Context->Length = 0;
  96. Context->BlockIndex = 0;
  97. Context->IntermediateHash[0] = 0x6A09E667;
  98. Context->IntermediateHash[1] = 0xBB67AE85;
  99. Context->IntermediateHash[2] = 0x3C6EF372;
  100. Context->IntermediateHash[3] = 0xA54FF53A;
  101. Context->IntermediateHash[4] = 0x510E527F;
  102. Context->IntermediateHash[5] = 0x9B05688C;
  103. Context->IntermediateHash[6] = 0x1F83D9AB;
  104. Context->IntermediateHash[7] = 0x5BE0CD19;
  105. return;
  106. }
  107. CRYPTO_API
  108. VOID
  109. CySha256AddContent (
  110. PSHA256_CONTEXT Context,
  111. PVOID Message,
  112. UINTN Length
  113. )
  114. /*++
  115. Routine Description:
  116. This routine adds data to a SHA-256 digest.
  117. Arguments:
  118. Context - Supplies a pointer to the initialized SHA-256 context.
  119. Message - Supplies a pointer to the buffer containing the bytes.
  120. Length - Supplies the length of the message buffer, in bytes.
  121. Return Value:
  122. None.
  123. --*/
  124. {
  125. PUCHAR Bytes;
  126. Bytes = Message;
  127. while (Length != 0) {
  128. Context->MessageBlock[Context->BlockIndex] = *Bytes;
  129. Context->BlockIndex += 1;
  130. if (Context->BlockIndex == sizeof(Context->MessageBlock)) {
  131. CypSha256ProcessMessage(Context);
  132. Context->Length += sizeof(Context->MessageBlock) * BITS_PER_BYTE;
  133. Context->BlockIndex = 0;
  134. }
  135. Bytes += 1;
  136. Length -= 1;
  137. }
  138. return;
  139. }
  140. CRYPTO_API
  141. VOID
  142. CySha256GetHash (
  143. PSHA256_CONTEXT Context,
  144. UCHAR Hash[SHA256_HASH_SIZE]
  145. )
  146. /*++
  147. Routine Description:
  148. This routine computes and returns the final SHA-256 hash value for the
  149. messages that have been previously entered.
  150. Arguments:
  151. Context - Supplies a pointer to the initialized SHA-256 context.
  152. Hash - Supplies a pointer where the final hash value will be returned. This
  153. buffer must be SHA256_HASH_SIZE length in bytes.
  154. Return Value:
  155. None.
  156. --*/
  157. {
  158. INT DigestIndex;
  159. INT ShiftAmount;
  160. CypSha256PadMessage(Context);
  161. Context->Length = 0;
  162. //
  163. // Copy the key and convert to big endian at the same time.
  164. //
  165. for (DigestIndex = 0; DigestIndex < SHA256_HASH_SIZE; DigestIndex += 1) {
  166. ShiftAmount = (sizeof(ULONG) - 1 - (DigestIndex % sizeof(ULONG))) *
  167. BITS_PER_BYTE;
  168. Hash[DigestIndex] =
  169. Context->IntermediateHash[DigestIndex / sizeof(ULONG)] >>
  170. ShiftAmount;
  171. }
  172. return;
  173. }
  174. //
  175. // --------------------------------------------------------- Internal Functions
  176. //
  177. VOID
  178. CypSha256ProcessMessage (
  179. PSHA256_CONTEXT Context
  180. )
  181. /*++
  182. Routine Description:
  183. This routine processes the 512 bits in the current message block and adds
  184. them to the digest.
  185. Arguments:
  186. Context - Supplies a pointer to the initialized SHA-256 context with a full
  187. message block.
  188. Return Value:
  189. None.
  190. --*/
  191. {
  192. ULONG Block[64];
  193. ULONG BlockA;
  194. ULONG BlockB;
  195. ULONG BlockC;
  196. ULONG BlockD;
  197. ULONG BlockE;
  198. ULONG BlockF;
  199. ULONG BlockG;
  200. ULONG BlockH;
  201. UINTN BlockIndex;
  202. UINTN ByteIndex;
  203. ULONG Working1;
  204. ULONG Working2;
  205. ByteIndex = 0;
  206. for (BlockIndex = 0; BlockIndex < 16; BlockIndex += 1) {
  207. Block[BlockIndex] = (Context->MessageBlock[ByteIndex] << 24) |
  208. (Context->MessageBlock[ByteIndex + 1] << 16) |
  209. (Context->MessageBlock[ByteIndex + 2] << 8) |
  210. Context->MessageBlock[ByteIndex + 3];
  211. ByteIndex += 4;
  212. }
  213. while (BlockIndex < 64) {
  214. Block[BlockIndex] = SHA256_SIG1(Block[BlockIndex - 2]) +
  215. Block[BlockIndex - 7] +
  216. SHA256_SIG0(Block[BlockIndex - 15]) +
  217. Block[BlockIndex - 16];
  218. BlockIndex += 1;
  219. }
  220. BlockA = Context->IntermediateHash[0];
  221. BlockB = Context->IntermediateHash[1];
  222. BlockC = Context->IntermediateHash[2];
  223. BlockD = Context->IntermediateHash[3];
  224. BlockE = Context->IntermediateHash[4];
  225. BlockF = Context->IntermediateHash[5];
  226. BlockG = Context->IntermediateHash[6];
  227. BlockH = Context->IntermediateHash[7];
  228. for (BlockIndex = 0; BlockIndex < 64; BlockIndex += 1) {
  229. Working1 = BlockH +
  230. SHA256_EP1(BlockE) +
  231. SHA256_CH(BlockE, BlockF, BlockG) +
  232. CySha256KConstants[BlockIndex] +
  233. Block[BlockIndex];
  234. Working2 = SHA256_EP0(BlockA) + SHA256_MAJ(BlockA, BlockB, BlockC);
  235. BlockH = BlockG;
  236. BlockG = BlockF;
  237. BlockF = BlockE;
  238. BlockE = BlockD + Working1;
  239. BlockD = BlockC;
  240. BlockC = BlockB;
  241. BlockB = BlockA;
  242. BlockA = Working1 + Working2;
  243. }
  244. Context->IntermediateHash[0] += BlockA;
  245. Context->IntermediateHash[1] += BlockB;
  246. Context->IntermediateHash[2] += BlockC;
  247. Context->IntermediateHash[3] += BlockD;
  248. Context->IntermediateHash[4] += BlockE;
  249. Context->IntermediateHash[5] += BlockF;
  250. Context->IntermediateHash[6] += BlockG;
  251. Context->IntermediateHash[7] += BlockH;
  252. return;
  253. }
  254. VOID
  255. CypSha256PadMessage (
  256. PSHA256_CONTEXT Context
  257. )
  258. /*++
  259. Routine Description:
  260. This routine pads the message out to an even multiple of 512 bits.
  261. The standard specifies that the first padding bit must be a 1, and then the
  262. last 64 bits represent the length of the original message.
  263. Arguments:
  264. Context - Supplies a pointer to the initialized SHA-256 context with a full
  265. message block.
  266. Return Value:
  267. None.
  268. --*/
  269. {
  270. UINTN Index;
  271. //
  272. // Check to see if the current message block is too small to hold the
  273. // initial padding bits and length. If so, process the block, then continue
  274. // padding onto a second block.
  275. //
  276. Index = Context->BlockIndex;
  277. if (Index < 56) {
  278. Context->MessageBlock[Index] = 0x80;
  279. Index += 1;
  280. while (Index < 56) {
  281. Context->MessageBlock[Index] = 0;
  282. Index += 1;
  283. }
  284. } else {
  285. Context->MessageBlock[Index] = 0x80;
  286. Index += 1;
  287. while (Index < sizeof(Context->MessageBlock)) {
  288. Context->MessageBlock[Index] = 0;
  289. Index += 1;
  290. }
  291. CypSha256ProcessMessage(Context);
  292. RtlZeroMemory(Context->MessageBlock, 56);
  293. }
  294. Context->Length += Context->BlockIndex * BITS_PER_BYTE;
  295. //
  296. // Store the message length in the last 8 octets.
  297. //
  298. Context->MessageBlock[56] = (UCHAR)(Context->Length >> (32 + 24));
  299. Context->MessageBlock[57] = (UCHAR)(Context->Length >> (32 + 16));
  300. Context->MessageBlock[58] = (UCHAR)(Context->Length >> (32 + 8));
  301. Context->MessageBlock[59] = (UCHAR)(Context->Length >> 32);
  302. Context->MessageBlock[60] = (UCHAR)(Context->Length >> 24);
  303. Context->MessageBlock[61] = (UCHAR)(Context->Length >> 16);
  304. Context->MessageBlock[62] = (UCHAR)(Context->Length >> 8);
  305. Context->MessageBlock[63] = (UCHAR)(Context->Length);
  306. CypSha256ProcessMessage(Context);
  307. return;
  308. }