hl_sha256.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /*
  2. * hashlib++ - a simple hash library for C++
  3. *
  4. * Copyright (c) 2007-2010 Benjamin Grüdelbach
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1) Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * 2) Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in
  14. * the documentation and/or other materials provided with the
  15. * distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  21. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  24. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. //----------------------------------------------------------------------
  29. /*
  30. * The hashlib++ SHA256 implementation is derivative from the sourcecode
  31. * published by Aaron D. Gifford
  32. *
  33. * Copyright (c) 2000-2001, Aaron D. Gifford
  34. * All rights reserved.
  35. *
  36. * Redistribution and use in source and binary forms, with or without
  37. * modification, are permitted provided that the following conditions
  38. * are met:
  39. * 1. Redistributions of source code must retain the above copyright
  40. * notice, this list of conditions and the following disclaimer.
  41. * 2. Redistributions in binary form must reproduce the above copyright
  42. * notice, this list of conditions and the following disclaimer in the
  43. * documentation and/or other materials provided with the distribution.
  44. * 3. Neither the name of the copyright holder nor the names of contributors
  45. * may be used to endorse or promote products derived from this software
  46. * without specific prior written permission.
  47. *
  48. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
  49. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  50. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  51. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
  52. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  53. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  54. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  55. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  56. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  57. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  58. * SUCH DAMAGE.
  59. *
  60. */
  61. //----------------------------------------------------------------------
  62. /**
  63. * @file hl_sha256.cpp
  64. * @brief This file contains the implementation of the SHA256 class
  65. * @date Di 25 Sep 2007
  66. */
  67. //----------------------------------------------------------------------
  68. //hashlib++ includes
  69. #include "hl_sha256.h"
  70. //----------------------------------------------------------------------
  71. /*
  72. * Standard C includes
  73. */
  74. #include <string.h>
  75. #include <assert.h>
  76. //----------------------------------------------------------------------
  77. #include "hl_sha2mac.h"
  78. //----------------------------------------------------------------------
  79. /*
  80. * Hash constant words K for SHA-256:
  81. */
  82. const static sha2_word32 K256[64] = {
  83. 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
  84. 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
  85. 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
  86. 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
  87. 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
  88. 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
  89. 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
  90. 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
  91. 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
  92. 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
  93. 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
  94. 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
  95. 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
  96. 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
  97. 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
  98. 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
  99. };
  100. /*
  101. * Initial hash value H for SHA-256:
  102. */
  103. const static sha2_word32 sha256_initial_hash_value[8] = {
  104. 0x6a09e667UL,
  105. 0xbb67ae85UL,
  106. 0x3c6ef372UL,
  107. 0xa54ff53aUL,
  108. 0x510e527fUL,
  109. 0x9b05688cUL,
  110. 0x1f83d9abUL,
  111. 0x5be0cd19UL
  112. };
  113. /*
  114. * Constant used by End() functions for converting the
  115. * digest to a readable hexadecimal character string:
  116. */
  117. static const char *sha2_hex_digits = "0123456789abcdef";
  118. /*** SHA-256: *********************************************************/
  119. /**
  120. * @brief Initialize the context
  121. * @param context The context to init.
  122. */
  123. void SHA256::SHA256_Init(HL_SHA256_CTX* context) {
  124. if (context == (HL_SHA256_CTX*)0) {
  125. return;
  126. }
  127. MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
  128. MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
  129. context->bitcount = 0;
  130. }
  131. #ifdef SHA2_UNROLL_TRANSFORM
  132. /* Unrolled SHA-256 round macros: */
  133. #if BYTE_ORDER == LITTLE_ENDIAN
  134. #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
  135. REVERSE32(*data++, W256[j]); \
  136. T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
  137. K256[j] + W256[j]; \
  138. (d) += T1; \
  139. (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
  140. j++
  141. #else /* BYTE_ORDER == LITTLE_ENDIAN */
  142. #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
  143. T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
  144. K256[j] + (W256[j] = *data++); \
  145. (d) += T1; \
  146. (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
  147. j++
  148. #endif /* BYTE_ORDER == LITTLE_ENDIAN */
  149. #define ROUND256(a,b,c,d,e,f,g,h) \
  150. s0 = W256[(j+1)&0x0f]; \
  151. s0 = sigma0_256(s0); \
  152. s1 = W256[(j+14)&0x0f]; \
  153. s1 = sigma1_256(s1); \
  154. T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
  155. (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
  156. (d) += T1; \
  157. (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
  158. j++
  159. /**
  160. * @brief Internal data transformation
  161. * @param context The context to use
  162. * @param data The data to transform
  163. */
  164. void SHA256::SHA256_Transform(HL_SHA256_CTX* context, const sha2_word32* data) {
  165. sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
  166. sha2_word32 T1, *W256;
  167. int j;
  168. W256 = (sha2_word32*)context->buffer;
  169. /* Initialize registers with the prev. intermediate value */
  170. a = context->state[0];
  171. b = context->state[1];
  172. c = context->state[2];
  173. d = context->state[3];
  174. e = context->state[4];
  175. f = context->state[5];
  176. g = context->state[6];
  177. h = context->state[7];
  178. j = 0;
  179. do {
  180. /* Rounds 0 to 15 (unrolled): */
  181. ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
  182. ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
  183. ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
  184. ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
  185. ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
  186. ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
  187. ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
  188. ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
  189. } while (j < 16);
  190. /* Now for the remaining rounds to 64: */
  191. do {
  192. ROUND256(a,b,c,d,e,f,g,h);
  193. ROUND256(h,a,b,c,d,e,f,g);
  194. ROUND256(g,h,a,b,c,d,e,f);
  195. ROUND256(f,g,h,a,b,c,d,e);
  196. ROUND256(e,f,g,h,a,b,c,d);
  197. ROUND256(d,e,f,g,h,a,b,c);
  198. ROUND256(c,d,e,f,g,h,a,b);
  199. ROUND256(b,c,d,e,f,g,h,a);
  200. } while (j < 64);
  201. /* Compute the current intermediate hash value */
  202. context->state[0] += a;
  203. context->state[1] += b;
  204. context->state[2] += c;
  205. context->state[3] += d;
  206. context->state[4] += e;
  207. context->state[5] += f;
  208. context->state[6] += g;
  209. context->state[7] += h;
  210. /* Clean up */
  211. a = b = c = d = e = f = g = h = T1 = 0;
  212. }
  213. #else /* SHA2_UNROLL_TRANSFORM */
  214. /**
  215. * @brief Internal data transformation
  216. * @param context The context to use
  217. * @param data The data to transform
  218. */
  219. void SHA256::SHA256_Transform(HL_SHA256_CTX* context, const sha2_word32* data) {
  220. sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
  221. sha2_word32 T1, T2, *W256;
  222. int j;
  223. W256 = (sha2_word32*)context->buffer;
  224. /* Initialize registers with the prev. intermediate value */
  225. a = context->state[0];
  226. b = context->state[1];
  227. c = context->state[2];
  228. d = context->state[3];
  229. e = context->state[4];
  230. f = context->state[5];
  231. g = context->state[6];
  232. h = context->state[7];
  233. j = 0;
  234. do {
  235. #if BYTE_ORDER == LITTLE_ENDIAN
  236. /* Copy data while converting to host byte order */
  237. REVERSE32(*data++,W256[j]);
  238. /* Apply the SHA-256 compression function to update a..h */
  239. T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
  240. #else /* BYTE_ORDER == LITTLE_ENDIAN */
  241. /* Apply the SHA-256 compression function to update a..h with copy */
  242. T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
  243. #endif /* BYTE_ORDER == LITTLE_ENDIAN */
  244. T2 = Sigma0_256(a) + Maj(a, b, c);
  245. h = g;
  246. g = f;
  247. f = e;
  248. e = d + T1;
  249. d = c;
  250. c = b;
  251. b = a;
  252. a = T1 + T2;
  253. j++;
  254. } while (j < 16);
  255. do {
  256. /* Part of the message block expansion: */
  257. s0 = W256[(j+1)&0x0f];
  258. s0 = sigma0_256(s0);
  259. s1 = W256[(j+14)&0x0f];
  260. s1 = sigma1_256(s1);
  261. /* Apply the SHA-256 compression function to update a..h */
  262. T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
  263. (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
  264. T2 = Sigma0_256(a) + Maj(a, b, c);
  265. h = g;
  266. g = f;
  267. f = e;
  268. e = d + T1;
  269. d = c;
  270. c = b;
  271. b = a;
  272. a = T1 + T2;
  273. j++;
  274. } while (j < 64);
  275. /* Compute the current intermediate hash value */
  276. context->state[0] += a;
  277. context->state[1] += b;
  278. context->state[2] += c;
  279. context->state[3] += d;
  280. context->state[4] += e;
  281. context->state[5] += f;
  282. context->state[6] += g;
  283. context->state[7] += h;
  284. /* Clean up */
  285. a = b = c = d = e = f = g = h = T1 = T2 = 0;
  286. }
  287. #endif /* SHA2_UNROLL_TRANSFORM */
  288. /**
  289. * @brief Updates the context
  290. * @param context The context to update.
  291. * @param data The data for updating the context.
  292. * @param len The length of the given data.
  293. */
  294. void SHA256::SHA256_Update(HL_SHA256_CTX* context, const sha2_byte *data, unsigned int len) {
  295. unsigned int freespace, usedspace;
  296. if (len == 0) {
  297. /* Calling with no data is valid - we do nothing */
  298. return;
  299. }
  300. /* Sanity check: */
  301. assert(context != (HL_SHA256_CTX*)0 && data != (sha2_byte*)0);
  302. usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
  303. if (usedspace > 0) {
  304. /* Calculate how much free space is available in the buffer */
  305. freespace = SHA256_BLOCK_LENGTH - usedspace;
  306. if (len >= freespace) {
  307. /* Fill the buffer completely and process it */
  308. MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
  309. context->bitcount += freespace << 3;
  310. len -= freespace;
  311. data += freespace;
  312. SHA256_Transform(context, (sha2_word32*)context->buffer);
  313. } else {
  314. /* The buffer is not yet full */
  315. MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
  316. context->bitcount += len << 3;
  317. /* Clean up: */
  318. usedspace = freespace = 0;
  319. return;
  320. }
  321. }
  322. while (len >= SHA256_BLOCK_LENGTH) {
  323. /* Process as many complete blocks as we can */
  324. SHA256_Transform(context, (sha2_word32*)data);
  325. context->bitcount += SHA256_BLOCK_LENGTH << 3;
  326. len -= SHA256_BLOCK_LENGTH;
  327. data += SHA256_BLOCK_LENGTH;
  328. }
  329. if (len > 0) {
  330. /* There's left-overs, so save 'em */
  331. MEMCPY_BCOPY(context->buffer, data, len);
  332. context->bitcount += len << 3;
  333. }
  334. /* Clean up: */
  335. usedspace = freespace = 0;
  336. }
  337. /**
  338. * @brief Finalize the sha256 operation
  339. * @param digest The digest to finalize the operation with.
  340. * @param context The context to finalize.
  341. */
  342. void SHA256::SHA256_Final(sha2_byte digest[], HL_SHA256_CTX* context) {
  343. sha2_word32 *d = (sha2_word32*)digest;
  344. unsigned int usedspace;
  345. /* Sanity check: */
  346. assert(context != (HL_SHA256_CTX*)0);
  347. /* If no digest buffer is passed, we don't bother doing this: */
  348. if (digest != (sha2_byte*)0) {
  349. usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
  350. #if BYTE_ORDER == LITTLE_ENDIAN
  351. /* Convert FROM host byte order */
  352. REVERSE64(context->bitcount,context->bitcount);
  353. #endif
  354. if (usedspace > 0) {
  355. /* Begin padding with a 1 bit: */
  356. context->buffer[usedspace++] = 0x80;
  357. if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
  358. /* Set-up for the last transform: */
  359. MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
  360. } else {
  361. if (usedspace < SHA256_BLOCK_LENGTH) {
  362. MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
  363. }
  364. /* Do second-to-last transform: */
  365. SHA256_Transform(context, (sha2_word32*)context->buffer);
  366. /* And set-up for the last transform: */
  367. MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
  368. }
  369. } else {
  370. /* Set-up for the last transform: */
  371. MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
  372. /* Begin padding with a 1 bit: */
  373. *context->buffer = 0x80;
  374. }
  375. /* Set the bit count: */
  376. *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
  377. /* Final transform: */
  378. SHA256_Transform(context, (sha2_word32*)context->buffer);
  379. #if BYTE_ORDER == LITTLE_ENDIAN
  380. {
  381. /* Convert TO host byte order */
  382. int j;
  383. for (j = 0; j < 8; j++) {
  384. REVERSE32(context->state[j],context->state[j]);
  385. *d++ = context->state[j];
  386. }
  387. }
  388. #else
  389. MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
  390. #endif
  391. }
  392. /* Clean up state data: */
  393. MEMSET_BZERO(context, sizeof(context));
  394. usedspace = 0;
  395. }
  396. /**
  397. * @brief Ends the sha256 operation and return the
  398. * created hash in the given buffer.
  399. * @param context The context to end.
  400. * @param buffer This OUT-Parameter contains the created
  401. * hash after ending the operation.
  402. */
  403. char* SHA256::SHA256_End(HL_SHA256_CTX* context, char buffer[]) {
  404. sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
  405. int i;
  406. /* Sanity check: */
  407. assert(context != (HL_SHA256_CTX*)0);
  408. if (buffer != (char*)0) {
  409. SHA256_Final(digest, context);
  410. for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
  411. *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
  412. *buffer++ = sha2_hex_digits[*d & 0x0f];
  413. d++;
  414. }
  415. *buffer = (char)0;
  416. } else {
  417. MEMSET_BZERO(context, sizeof(context));
  418. }
  419. MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
  420. return buffer;
  421. }
  422. //----------------------------------------------------------------------
  423. //EOF