sha1.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. // WINSCP Restore use of impl_display, once we have HW-accelerated variant
  34. #define SHA1_VTABLE(impl_c, impl_display) \
  35. static struct sha1_extra_mutable sha1_ ## impl_c ## _extra_mut; \
  36. static const struct sha1_extra sha1_ ## impl_c ## _extra = { \
  37. /* WINSCP */ \
  38. /*.check_available =*/ sha1_ ## impl_c ## _available, \
  39. /*.mut =*/ &sha1_ ## impl_c ## _extra_mut, \
  40. }; \
  41. const ssh_hashalg ssh_sha1_ ## impl_c = { \
  42. /* WINSCP */ \
  43. /*.new =*/ sha1_ ## impl_c ## _new, \
  44. /*.reset =*/ sha1_ ## impl_c ## _reset, \
  45. /*.copyfrom =*/ sha1_ ## impl_c ## _copyfrom, \
  46. /*.digest =*/ sha1_ ## impl_c ## _digest, \
  47. /*.free =*/ sha1_ ## impl_c ## _free, \
  48. /*.hlen =*/ 20, \
  49. /*.blocklen =*/ 64, \
  50. HASHALG_NAMES_BARE("SHA-1"), \
  51. /*.extra =*/ &sha1_ ## impl_c ## _extra, \
  52. }
  53. extern const uint32_t sha1_initial_state[5];
  54. #define SHA1_ROUNDS_PER_STAGE 20
  55. #define SHA1_STAGE0_CONSTANT 0x5a827999
  56. #define SHA1_STAGE1_CONSTANT 0x6ed9eba1
  57. #define SHA1_STAGE2_CONSTANT 0x8f1bbcdc
  58. #define SHA1_STAGE3_CONSTANT 0xca62c1d6
  59. #define SHA1_ROUNDS (4 * SHA1_ROUNDS_PER_STAGE)
  60. typedef struct sha1_block sha1_block;
  61. struct sha1_block {
  62. uint8_t block[64];
  63. size_t used;
  64. uint64_t len;
  65. };
  66. static inline void sha1_block_setup(sha1_block *blk)
  67. {
  68. blk->used = 0;
  69. blk->len = 0;
  70. }
  71. static inline bool sha1_block_write(
  72. sha1_block *blk, const void **vdata, size_t *len)
  73. {
  74. size_t blkleft = sizeof(blk->block) - blk->used;
  75. size_t chunk = *len < blkleft ? *len : blkleft;
  76. const uint8_t *p = *vdata;
  77. memcpy(blk->block + blk->used, p, chunk);
  78. *vdata = p + chunk;
  79. *len -= chunk;
  80. blk->used += chunk;
  81. blk->len += chunk;
  82. if (blk->used == sizeof(blk->block)) {
  83. blk->used = 0;
  84. return true;
  85. }
  86. return false;
  87. }
  88. static inline void sha1_block_pad(sha1_block *blk, BinarySink *bs)
  89. {
  90. uint64_t final_len = blk->len << 3;
  91. size_t pad = 1 + (63 & (55 - blk->used));
  92. put_byte(bs, 0x80);
  93. { // WINSCP
  94. size_t i;
  95. for (i = 1; i < pad; i++)
  96. put_byte(bs, 0);
  97. put_uint64(bs, final_len);
  98. assert(blk->used == 0 && "Should have exactly hit a block boundary");
  99. } // WINSCP
  100. }