sha256.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /* Copyright 2018 Canaan Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include <string.h>
  16. #include "sha256.h"
  17. #include "sysctl.h"
  18. #include "utils.h"
  19. #define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
  20. #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
  21. #define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | (ROTL((x), 8) & 0x00ff00ffL))
  22. #define BYTESWAP64(x) byteswap64(x)
  23. volatile sha256_t *const sha256 = (volatile sha256_t *)SHA256_BASE_ADDR;
  24. static const uint8_t padding[64] =
  25. {
  26. 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  27. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  28. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  29. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  30. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  31. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  32. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  33. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  34. static inline uint64_t byteswap64(uint64_t x)
  35. {
  36. uint32_t a = (uint32_t)(x >> 32);
  37. uint32_t b = (uint32_t)x;
  38. return ((uint64_t)BYTESWAP(b) << 32) | (uint64_t)BYTESWAP(a);
  39. }
  40. void sha256_init(sha256_context_t *context, size_t input_len)
  41. {
  42. sysctl_clock_enable(SYSCTL_CLOCK_SHA);
  43. sysctl_reset(SYSCTL_RESET_SHA);
  44. sha256->sha_num_reg.sha_data_cnt = (uint32_t)((input_len + SHA256_BLOCK_LEN + 8) / SHA256_BLOCK_LEN);
  45. sha256->sha_function_reg_1.dma_en = 0x0;
  46. sha256->sha_function_reg_0.sha_endian = SHA256_BIG_ENDIAN;
  47. sha256->sha_function_reg_0.sha_en = ENABLE_SHA;
  48. context->total_len = 0L;
  49. context->buffer_len = 0L;
  50. }
  51. void sha256_update(sha256_context_t *context, const void *input, size_t input_len)
  52. {
  53. const uint8_t *data = input;
  54. size_t buffer_bytes_left;
  55. size_t bytes_to_copy;
  56. uint32_t i;
  57. while(input_len)
  58. {
  59. buffer_bytes_left = SHA256_BLOCK_LEN - context->buffer_len;
  60. bytes_to_copy = buffer_bytes_left;
  61. if(bytes_to_copy > input_len)
  62. bytes_to_copy = input_len;
  63. memcpy(&context->buffer.bytes[context->buffer_len], data, bytes_to_copy);
  64. context->total_len += bytes_to_copy * 8L;
  65. context->buffer_len += bytes_to_copy;
  66. data += bytes_to_copy;
  67. input_len -= bytes_to_copy;
  68. if(context->buffer_len == SHA256_BLOCK_LEN)
  69. {
  70. for(i = 0; i < 16; i++)
  71. {
  72. while(sha256->sha_function_reg_1.fifo_in_full)
  73. ;
  74. sha256->sha_data_in1 = context->buffer.words[i];
  75. }
  76. context->buffer_len = 0L;
  77. }
  78. }
  79. }
  80. void sha256_final(sha256_context_t *context, uint8_t *output)
  81. {
  82. size_t bytes_to_pad;
  83. size_t length_pad;
  84. uint32_t i;
  85. bytes_to_pad = 120L - context->buffer_len;
  86. if(bytes_to_pad > 64L)
  87. bytes_to_pad -= 64L;
  88. length_pad = BYTESWAP64(context->total_len);
  89. sha256_update(context, padding, bytes_to_pad);
  90. sha256_update(context, &length_pad, 8L);
  91. while(!(sha256->sha_function_reg_0.sha_en))
  92. ;
  93. if(output)
  94. {
  95. for(i = 0; i < SHA256_HASH_WORDS; i++)
  96. {
  97. *((uint32_t *)output) = sha256->sha_result[SHA256_HASH_WORDS - i - 1];
  98. output += 4;
  99. }
  100. }
  101. }
  102. void sha256_hard_calculate(const uint8_t *input, size_t input_len, uint8_t *output)
  103. {
  104. sha256_context_t sha;
  105. sha256_init(&sha, input_len);
  106. sha256_update(&sha, input, input_len);
  107. sha256_final(&sha, output);
  108. }