sha256.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Definitions likely to be helpful to multiple SHA-256 implementations.
  3. */
  4. /*
  5. * The 'extra' structure used by SHA-256 implementations is used to
  6. * include information about how to check if a given implementation is
  7. * available at run time, and whether we've already checked.
  8. */
  9. struct sha256_extra_mutable;
  10. struct sha256_extra {
  11. /* Function to check availability. Might be expensive, so we don't
  12. * want to call it more than once. */
  13. bool (*check_available)(void);
  14. /* Point to a writable substructure. */
  15. struct sha256_extra_mutable *mut;
  16. };
  17. struct sha256_extra_mutable {
  18. bool checked_availability;
  19. bool is_available;
  20. };
  21. static inline bool check_availability(const struct sha256_extra *extra)
  22. {
  23. if (!extra->mut->checked_availability) {
  24. extra->mut->is_available = extra->check_available();
  25. extra->mut->checked_availability = true;
  26. }
  27. return extra->mut->is_available;
  28. }
  29. /*
  30. * Macro to define a SHA-256 vtable together with its 'extra'
  31. * structure.
  32. */
  33. #define SHA256_VTABLE(impl_c, impl_display) \
  34. static struct sha256_extra_mutable sha256_ ## impl_c ## _extra_mut; \
  35. static const struct sha256_extra sha256_ ## impl_c ## _extra = { \
  36. .check_available = sha256_ ## impl_c ## _available, \
  37. .mut = &sha256_ ## impl_c ## _extra_mut, \
  38. }; \
  39. const ssh_hashalg ssh_sha256_ ## impl_c = { \
  40. .new = sha256_ ## impl_c ## _new, \
  41. .reset = sha256_ ## impl_c ## _reset, \
  42. .copyfrom = sha256_ ## impl_c ## _copyfrom, \
  43. .digest = sha256_ ## impl_c ## _digest, \
  44. .free = sha256_ ## impl_c ## _free, \
  45. .hlen = 32, \
  46. .blocklen = 64, \
  47. HASHALG_NAMES_ANNOTATED("SHA-256", impl_display), \
  48. .extra = &sha256_ ## impl_c ## _extra, \
  49. }
  50. extern const uint32_t sha256_initial_state[8];
  51. extern const uint32_t sha256_round_constants[64];
  52. #define SHA256_ROUNDS 64
  53. typedef struct sha256_block sha256_block;
  54. struct sha256_block {
  55. uint8_t block[64];
  56. size_t used;
  57. uint64_t len;
  58. };
  59. static inline void sha256_block_setup(sha256_block *blk)
  60. {
  61. blk->used = 0;
  62. blk->len = 0;
  63. }
  64. static inline bool sha256_block_write(
  65. sha256_block *blk, const void **vdata, size_t *len)
  66. {
  67. size_t blkleft = sizeof(blk->block) - blk->used;
  68. size_t chunk = *len < blkleft ? *len : blkleft;
  69. const uint8_t *p = *vdata;
  70. memcpy(blk->block + blk->used, p, chunk);
  71. *vdata = p + chunk;
  72. *len -= chunk;
  73. blk->used += chunk;
  74. blk->len += chunk;
  75. if (blk->used == sizeof(blk->block)) {
  76. blk->used = 0;
  77. return true;
  78. }
  79. return false;
  80. }
  81. static inline void sha256_block_pad(sha256_block *blk, BinarySink *bs)
  82. {
  83. uint64_t final_len = blk->len << 3;
  84. size_t pad = 1 + (63 & (55 - blk->used));
  85. put_byte(bs, 0x80);
  86. for (size_t i = 1; i < pad; i++)
  87. put_byte(bs, 0);
  88. put_uint64(bs, final_len);
  89. assert(blk->used == 0 && "Should have exactly hit a block boundary");
  90. }