sha_block.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /*
  2. * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "soc/soc_caps.h"
  10. #if SOC_SHA_SUPPORTED
  11. #include "soc/periph_defs.h"
  12. #include "esp_private/periph_ctrl.h"
  13. #include "hal/sha_hal.h"
  14. #include "hal/clk_gate_ll.h"
  15. #include "sha_block.h"
  16. #if defined(SOC_SHA_SUPPORT_SHA1)
  17. static void sha1_update_block(sha1_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen)
  18. {
  19. size_t fill;
  20. uint32_t left, local_len = 0;
  21. left = ctx->total[0] & 0x3F;
  22. fill = 64 - left;
  23. ctx->total[0] += (uint32_t) ilen;
  24. ctx->total[0] &= 0xFFFFFFFF;
  25. if ( ctx->total[0] < (uint32_t) ilen ) {
  26. ctx->total[1]++;
  27. }
  28. if ( left && ilen >= fill ) {
  29. memcpy( (void *) (ctx->buffer + left), input, fill );
  30. input += fill;
  31. ilen -= fill;
  32. left = 0;
  33. local_len = 64;
  34. }
  35. if ( (ilen >= 64) || local_len) {
  36. /* Enable peripheral module */
  37. periph_ll_enable_clk_clear_rst(PERIPH_SHA_MODULE);
  38. if (ctx->first_block == 0) {
  39. /* Writes the message digest to the SHA engine */
  40. sha_hal_write_digest(sha_type, ctx->state);
  41. }
  42. /* First process buffered block, if any */
  43. if ( local_len ) {
  44. /* Hash a single block */
  45. sha_hal_hash_block(sha_type, ctx->buffer, block_length(sha_type)/4, ctx->first_block);
  46. if (ctx->first_block == 1) {
  47. ctx->first_block = 0;
  48. }
  49. }
  50. while ( ilen >= 64 ) {
  51. sha_hal_hash_block(sha_type, input, block_length(sha_type)/4, ctx->first_block);
  52. if (ctx->first_block == 1) {
  53. ctx->first_block = 0;
  54. }
  55. input += 64;
  56. ilen -= 64;
  57. }
  58. /* Reads the current message digest from the SHA engine */
  59. sha_hal_read_digest(sha_type, ctx->state);
  60. /* Disable peripheral module */
  61. periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE);
  62. }
  63. if ( ilen > 0 ) {
  64. memcpy( (void *) (ctx->buffer + left), input, ilen);
  65. }
  66. }
  67. void sha1_block(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
  68. {
  69. sha1_ctx ctx;
  70. memset(&ctx, 0, sizeof(sha1_ctx));
  71. ctx.first_block = 1;
  72. sha1_update_block(&ctx, sha_type, input, ilen);
  73. uint32_t last, padn;
  74. uint32_t high, low;
  75. unsigned char msglen[8];
  76. high = ( ctx.total[0] >> 29 )
  77. | ( ctx.total[1] << 3 );
  78. low = ( ctx.total[0] << 3 );
  79. PUT_UINT32_BE( high, msglen, 0 );
  80. PUT_UINT32_BE( low, msglen, 4 );
  81. last = ctx.total[0] & 0x3F;
  82. padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
  83. sha1_update_block(&ctx, sha_type, sha1_padding, padn);
  84. sha1_update_block(&ctx, sha_type, msglen, 8);
  85. memcpy(output, ctx.state, 20);
  86. }
  87. #endif /* defined(SOC_SHA_SUPPORT_SHA1) */
  88. #if defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256)
  89. static void sha256_update_block(sha256_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen)
  90. {
  91. size_t fill;
  92. uint32_t left, local_len = 0;
  93. left = ctx->total[0] & 0x3F;
  94. fill = 64 - left;
  95. ctx->total[0] += (uint32_t) ilen;
  96. ctx->total[0] &= 0xFFFFFFFF;
  97. if ( ctx->total[0] < (uint32_t) ilen ) {
  98. ctx->total[1]++;
  99. }
  100. if ( left && ilen >= fill ) {
  101. memcpy( (void *) (ctx->buffer + left), input, fill );
  102. input += fill;
  103. ilen -= fill;
  104. left = 0;
  105. local_len = 64;
  106. }
  107. if ( (ilen >= 64) || local_len) {
  108. /* Enable peripheral module */
  109. periph_ll_enable_clk_clear_rst(PERIPH_SHA_MODULE);
  110. if (ctx->first_block == 0) {
  111. /* Writes the message digest to the SHA engine */
  112. sha_hal_write_digest(sha_type, ctx->state);
  113. }
  114. /* First process buffered block, if any */
  115. if ( local_len ) {
  116. /* Hash a single block */
  117. sha_hal_hash_block(sha_type, ctx->buffer, block_length(sha_type)/4, ctx->first_block);
  118. if (ctx->first_block == 1) {
  119. ctx->first_block = 0;
  120. }
  121. }
  122. while ( ilen >= 64 ) {
  123. sha_hal_hash_block(sha_type, input, block_length(sha_type)/4, ctx->first_block);
  124. if (ctx->first_block == 1) {
  125. ctx->first_block = 0;
  126. }
  127. input += 64;
  128. ilen -= 64;
  129. }
  130. /* Reads the current message digest from the SHA engine */
  131. sha_hal_read_digest(sha_type, ctx->state);
  132. /* Disable peripheral module */
  133. periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE);
  134. }
  135. if ( ilen > 0 ) {
  136. memcpy( (void *) (ctx->buffer + left), input, ilen);
  137. }
  138. }
  139. void sha256_block(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
  140. {
  141. sha256_ctx ctx;
  142. memset(&ctx, 0, sizeof(sha256_ctx));
  143. ctx.first_block = 1;
  144. sha256_update_block(&ctx, sha_type, input, ilen);
  145. uint32_t last, padn;
  146. uint32_t high, low;
  147. unsigned char msglen[8];
  148. high = ( ctx.total[0] >> 29 )
  149. | ( ctx.total[1] << 3 );
  150. low = ( ctx.total[0] << 3 );
  151. PUT_UINT32_BE( high, msglen, 0 );
  152. PUT_UINT32_BE( low, msglen, 4 );
  153. last = ctx.total[0] & 0x3F;
  154. padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
  155. sha256_update_block(&ctx, sha_type, sha256_padding, padn);
  156. sha256_update_block(&ctx, sha_type, msglen, 8);
  157. if (sha_type == SHA2_256) {
  158. memcpy(output, ctx.state, 32);
  159. } else if (sha_type == SHA2_224) {
  160. memcpy(output, ctx.state, 28);
  161. }
  162. }
  163. #endif /* defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256) */
  164. #if defined(SOC_SHA_SUPPORT_SHA384) || defined(SOC_SHA_SUPPORT_SHA512)
  165. #if SOC_SHA_SUPPORT_SHA512_T
  166. int sha_512_t_init_hash_block(uint16_t t)
  167. {
  168. uint32_t t_string = 0;
  169. uint8_t t0, t1, t2, t_len;
  170. if (t == 384) {
  171. return -1;
  172. }
  173. if (t <= 9) {
  174. t_string = (uint32_t)((1 << 23) | ((0x30 + t) << 24));
  175. t_len = 0x48;
  176. } else if (t <= 99) {
  177. t0 = t % 10;
  178. t1 = (t / 10) % 10;
  179. t_string = (uint32_t)((1 << 15) | ((0x30 + t0) << 16) |
  180. (((0x30 + t1) << 24)));
  181. t_len = 0x50;
  182. } else if (t <= 512) {
  183. t0 = t % 10;
  184. t1 = (t / 10) % 10;
  185. t2 = t / 100;
  186. t_string = (uint32_t)((1 << 7) | ((0x30 + t0) << 8) |
  187. (((0x30 + t1) << 16) + ((0x30 + t2) << 24)));
  188. t_len = 0x58;
  189. } else {
  190. return -1;
  191. }
  192. /* Calculates and sets the initial digiest for SHA512_t */
  193. sha_hal_sha512_init_hash(t_string, t_len);
  194. return 0;
  195. }
  196. #endif //SOC_SHA_SUPPORT_SHA512_T
  197. static void sha512_update_block(sha512_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen)
  198. {
  199. size_t fill;
  200. unsigned int left, local_len = 0;
  201. left = (unsigned int) (ctx->total[0] & 0x7F);
  202. fill = 128 - left;
  203. ctx->total[0] += (uint64_t) ilen;
  204. if ( ctx->total[0] < (uint64_t) ilen ) {
  205. ctx->total[1]++;
  206. }
  207. if ( left && ilen >= fill ) {
  208. memcpy( (void *) (ctx->buffer + left), input, fill );
  209. input += fill;
  210. ilen -= fill;
  211. left = 0;
  212. local_len = 128;
  213. }
  214. if ( (ilen >= 128) || local_len) {
  215. /* Enable peripheral module */
  216. periph_ll_enable_clk_clear_rst(PERIPH_SHA_MODULE);
  217. if (ctx->first_block && sha_type == SHA2_512T){
  218. sha_512_t_init_hash_block(ctx->t_val);
  219. ctx->first_block = 0;
  220. }
  221. else if (ctx->first_block == 0) {
  222. /* Writes the message digest to the SHA engine */
  223. sha_hal_write_digest(sha_type, ctx->state);
  224. }
  225. /* First process buffered block, if any */
  226. if ( local_len ) {
  227. /* Hash a single block */
  228. sha_hal_hash_block(sha_type, ctx->buffer, block_length(sha_type)/4, ctx->first_block);
  229. if (ctx->first_block == 1) {
  230. ctx->first_block = 0;
  231. }
  232. }
  233. while ( ilen >= 128 ) {
  234. sha_hal_hash_block(sha_type, input, block_length(sha_type)/4, ctx->first_block);
  235. if (ctx->first_block == 1) {
  236. ctx->first_block = 0;
  237. }
  238. input += 128;
  239. ilen -= 128;
  240. }
  241. /* Reads the current message digest from the SHA engine */
  242. sha_hal_read_digest(sha_type, ctx->state);
  243. /* Disable peripheral module */
  244. periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE);
  245. }
  246. if ( ilen > 0 ) {
  247. memcpy( (void *) (ctx->buffer + left), input, ilen);
  248. }
  249. }
  250. void sha512_block(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
  251. {
  252. sha512_ctx ctx;
  253. memset(&ctx, 0, sizeof(sha512_ctx));
  254. ctx.first_block = 1;
  255. sha512_update_block(&ctx, sha_type, input, ilen);
  256. size_t last, padn;
  257. uint64_t high, low;
  258. unsigned char msglen[16];
  259. high = ( ctx.total[0] >> 61 )
  260. | ( ctx.total[1] << 3 );
  261. low = ( ctx.total[0] << 3 );
  262. PUT_UINT64_BE( high, msglen, 0 );
  263. PUT_UINT64_BE( low, msglen, 8 );
  264. last = (size_t)( ctx.total[0] & 0x7F );
  265. padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
  266. sha512_update_block( &ctx, sha_type, sha512_padding, padn );
  267. sha512_update_block( &ctx, sha_type, msglen, 16 );
  268. if (sha_type == SHA2_384) {
  269. memcpy(output, ctx.state, 48);
  270. } else {
  271. memcpy(output, ctx.state, 64);
  272. }
  273. }
  274. #endif /* defined(SOC_SHA_SUPPORT_SHA384) || defined(SOC_SHA_SUPPORT_SHA512) */
  275. #if SOC_SHA_SUPPORT_SHA512_T
  276. void sha512t_block(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output, uint32_t t_val)
  277. {
  278. sha512_ctx ctx;
  279. memset(&ctx, 0, sizeof(sha512_ctx));
  280. ctx.first_block = 1;
  281. ctx.t_val = t_val;
  282. sha512_update_block(&ctx, sha_type, input, ilen);
  283. size_t last, padn;
  284. uint64_t high, low;
  285. unsigned char msglen[16];
  286. high = ( ctx.total[0] >> 61 )
  287. | ( ctx.total[1] << 3 );
  288. low = ( ctx.total[0] << 3 );
  289. PUT_UINT64_BE( high, msglen, 0 );
  290. PUT_UINT64_BE( low, msglen, 8 );
  291. last = (size_t)( ctx.total[0] & 0x7F );
  292. padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
  293. sha512_update_block( &ctx, sha_type, sha512_padding, padn );
  294. sha512_update_block( &ctx, sha_type, msglen, 16 );
  295. if (sha_type == SHA2_384) {
  296. memcpy(output, ctx.state, 48);
  297. } else {
  298. memcpy(output, ctx.state, 64);
  299. }
  300. }
  301. #endif /*SOC_SHA_SUPPORT_SHA512_T*/
  302. #endif /*SOC_SHA_SUPPORTED*/