sha256.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* Based on linux source code */
  2. /*
  3. * sha256_base.h - core logic for SHA-256 implementations
  4. *
  5. * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #ifdef __cplusplus
  12. extern "C" {
  13. #endif
  14. #include <string.h>
  15. #include "sha256.h"
  16. #define unlikely(x) __builtin_expect(!!(x), 0)
  17. void sha256_block_data_order (uint32_t *ctx, const void *in, size_t num);
  18. int sha256_init(struct sha256_state *sctx)
  19. {
  20. sctx->state[0] = SHA256_H0;
  21. sctx->state[1] = SHA256_H1;
  22. sctx->state[2] = SHA256_H2;
  23. sctx->state[3] = SHA256_H3;
  24. sctx->state[4] = SHA256_H4;
  25. sctx->state[5] = SHA256_H5;
  26. sctx->state[6] = SHA256_H6;
  27. sctx->state[7] = SHA256_H7;
  28. sctx->count = 0;
  29. return 0;
  30. }
  31. int sha256_update(struct sha256_state *sctx,
  32. const void *data,
  33. size_t len)
  34. {
  35. const u8 *data8 = (const u8 *)data;
  36. unsigned int len32 = (unsigned int)len;
  37. unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
  38. sctx->count += len32;
  39. if (unlikely((partial + len32) >= SHA256_BLOCK_SIZE)) {
  40. int blocks;
  41. if (partial) {
  42. int p = SHA256_BLOCK_SIZE - partial;
  43. memcpy(sctx->buf + partial, data8, p);
  44. data8 += p;
  45. len32 -= p;
  46. sha256_block_data_order(sctx->state, sctx->buf, 1);
  47. }
  48. blocks = len32 / SHA256_BLOCK_SIZE;
  49. len32 %= SHA256_BLOCK_SIZE;
  50. if (blocks) {
  51. sha256_block_data_order(sctx->state, data8, blocks);
  52. data8 += blocks * SHA256_BLOCK_SIZE;
  53. }
  54. partial = 0;
  55. }
  56. if (len32)
  57. memcpy(sctx->buf + partial, data8, len32);
  58. return 0;
  59. }
  60. int sha256_finalize(struct sha256_state *sctx)
  61. {
  62. const int bit_offset = SHA256_BLOCK_SIZE - sizeof(u64);
  63. u64 *bits = (u64 *)(sctx->buf + bit_offset);
  64. unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
  65. sctx->buf[partial++] = 0x80;
  66. if (partial > bit_offset) {
  67. memset(sctx->buf + partial, 0x0, SHA256_BLOCK_SIZE - partial);
  68. partial = 0;
  69. sha256_block_data_order(sctx->state, sctx->buf, 1);
  70. }
  71. memset(sctx->buf + partial, 0x0, bit_offset - partial);
  72. *bits = __builtin_bswap64(sctx->count << 3);
  73. sha256_block_data_order(sctx->state, sctx->buf, 1);
  74. return 0;
  75. }
  76. int sha256_finish(struct sha256_state *sctx, void *out)
  77. {
  78. unsigned int digest_size = 32;
  79. u32 *digest = (u32 *)out;
  80. int i;
  81. // Switch: misalignment shouldn't be a problem here...
  82. for (i = 0; digest_size > 0; i++, digest_size -= sizeof(u32))
  83. *digest++ = __builtin_bswap32(sctx->state[i]);
  84. *sctx = (struct sha256_state){};
  85. return 0;
  86. }
  87. #ifdef __cplusplus
  88. }
  89. #endif