sha1.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Definitions likely to be helpful to multiple SHA-1 implementations.
  3. */
  4. /*
  5. * The 'extra' structure used by SHA-1 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 sha1_extra_mutable;
  10. struct sha1_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 sha1_extra_mutable *mut;
  16. };
  17. struct sha1_extra_mutable {
  18. bool checked_availability;
  19. bool is_available;
  20. };
  21. static inline bool check_availability(const struct sha1_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-1 vtable together with its 'extra'
  31. * structure.
  32. */
  33. #define SHA1_VTABLE(impl_c, impl_display) \
  34. static struct sha1_extra_mutable sha1_ ## impl_c ## _extra_mut; \
  35. static const struct sha1_extra sha1_ ## impl_c ## _extra = { \
  36. .check_available = sha1_ ## impl_c ## _available, \
  37. .mut = &sha1_ ## impl_c ## _extra_mut, \
  38. }; \
  39. const ssh_hashalg ssh_sha1_ ## impl_c = { \
  40. .new = sha1_ ## impl_c ## _new, \
  41. .reset = sha1_ ## impl_c ## _reset, \
  42. .copyfrom = sha1_ ## impl_c ## _copyfrom, \
  43. .digest = sha1_ ## impl_c ## _digest, \
  44. .free = sha1_ ## impl_c ## _free, \
  45. .hlen = 20, \
  46. .blocklen = 64, \
  47. HASHALG_NAMES_ANNOTATED("SHA-1", impl_display), \
  48. .extra = &sha1_ ## impl_c ## _extra, \
  49. }
  50. extern const uint32_t sha1_initial_state[5];
  51. #define SHA1_ROUNDS_PER_STAGE 20
  52. #define SHA1_STAGE0_CONSTANT 0x5a827999
  53. #define SHA1_STAGE1_CONSTANT 0x6ed9eba1
  54. #define SHA1_STAGE2_CONSTANT 0x8f1bbcdc
  55. #define SHA1_STAGE3_CONSTANT 0xca62c1d6
  56. #define SHA1_ROUNDS (4 * SHA1_ROUNDS_PER_STAGE)
  57. typedef struct sha1_block sha1_block;
  58. struct sha1_block {
  59. uint8_t block[64];
  60. size_t used;
  61. uint64_t len;
  62. };
  63. static inline void sha1_block_setup(sha1_block *blk)
  64. {
  65. blk->used = 0;
  66. blk->len = 0;
  67. }
  68. static inline bool sha1_block_write(
  69. sha1_block *blk, const void **vdata, size_t *len)
  70. {
  71. size_t blkleft = sizeof(blk->block) - blk->used;
  72. size_t chunk = *len < blkleft ? *len : blkleft;
  73. const uint8_t *p = *vdata;
  74. memcpy(blk->block + blk->used, p, chunk);
  75. *vdata = p + chunk;
  76. *len -= chunk;
  77. blk->used += chunk;
  78. blk->len += chunk;
  79. if (blk->used == sizeof(blk->block)) {
  80. blk->used = 0;
  81. return true;
  82. }
  83. return false;
  84. }
  85. static inline void sha1_block_pad(sha1_block *blk, BinarySink *bs)
  86. {
  87. uint64_t final_len = blk->len << 3;
  88. size_t pad = 1 + (63 & (55 - blk->used));
  89. put_byte(bs, 0x80);
  90. for (size_t i = 1; i < pad; i++)
  91. put_byte(bs, 0);
  92. put_uint64(bs, final_len);
  93. assert(blk->used == 0 && "Should have exactly hit a block boundary");
  94. }