sha256-sw.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Software implementation of SHA-256.
  3. */
  4. #include "ssh.h"
  5. #include "sha256.h"
  6. #ifndef WINSCP_VS
  7. static bool sha256_sw_available(void)
  8. {
  9. /* Software SHA-256 is always available */
  10. return true;
  11. }
  12. #endif // WINSCP_VS
  13. #ifdef WINSCP_VS
  14. static inline uint32_t ror(uint32_t x, unsigned y)
  15. {
  16. return (x << (31 & /*WINSCP*/(uint32_t)(-(int32_t)y))) | (x >> (31 & y));
  17. }
  18. static inline uint32_t Ch(uint32_t ctrl, uint32_t if1, uint32_t if0)
  19. {
  20. return if0 ^ (ctrl & (if1 ^ if0));
  21. }
  22. static inline uint32_t Maj(uint32_t x, uint32_t y, uint32_t z)
  23. {
  24. return (x & y) | (z & (x | y));
  25. }
  26. static inline uint32_t Sigma_0(uint32_t x)
  27. {
  28. return ror(x,2) ^ ror(x,13) ^ ror(x,22);
  29. }
  30. static inline uint32_t Sigma_1(uint32_t x)
  31. {
  32. return ror(x,6) ^ ror(x,11) ^ ror(x,25);
  33. }
  34. static inline uint32_t sigma_0(uint32_t x)
  35. {
  36. return ror(x,7) ^ ror(x,18) ^ (x >> 3);
  37. }
  38. static inline uint32_t sigma_1(uint32_t x)
  39. {
  40. return ror(x,17) ^ ror(x,19) ^ (x >> 10);
  41. }
  42. static inline void sha256_sw_round(
  43. unsigned round_index, const uint32_t *schedule,
  44. uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d,
  45. uint32_t *e, uint32_t *f, uint32_t *g, uint32_t *h)
  46. {
  47. uint32_t t1 = *h + Sigma_1(*e) + Ch(*e,*f,*g) +
  48. sha256_round_constants[round_index] + schedule[round_index];
  49. uint32_t t2 = Sigma_0(*a) + Maj(*a,*b,*c);
  50. *d += t1;
  51. *h = t1 + t2;
  52. }
  53. /*WINSCP static*/ void sha256_sw_block(uint32_t *core, const uint8_t *block)
  54. {
  55. uint32_t w[SHA256_ROUNDS];
  56. uint32_t a,b,c,d,e,f,g,h;
  57. for (size_t t = 0; t < 16; t++)
  58. w[t] = GET_32BIT_MSB_FIRST(block + 4*t);
  59. for (size_t t = 16; t < SHA256_ROUNDS; t++)
  60. w[t] = sigma_1(w[t-2]) + w[t-7] + sigma_0(w[t-15]) + w[t-16];
  61. a = core[0]; b = core[1]; c = core[2]; d = core[3];
  62. e = core[4]; f = core[5]; g = core[6]; h = core[7];
  63. for (size_t t = 0; t < SHA256_ROUNDS; t += 8) {
  64. sha256_sw_round(t+0, w, &a,&b,&c,&d,&e,&f,&g,&h);
  65. sha256_sw_round(t+1, w, &h,&a,&b,&c,&d,&e,&f,&g);
  66. sha256_sw_round(t+2, w, &g,&h,&a,&b,&c,&d,&e,&f);
  67. sha256_sw_round(t+3, w, &f,&g,&h,&a,&b,&c,&d,&e);
  68. sha256_sw_round(t+4, w, &e,&f,&g,&h,&a,&b,&c,&d);
  69. sha256_sw_round(t+5, w, &d,&e,&f,&g,&h,&a,&b,&c);
  70. sha256_sw_round(t+6, w, &c,&d,&e,&f,&g,&h,&a,&b);
  71. sha256_sw_round(t+7, w, &b,&c,&d,&e,&f,&g,&h,&a);
  72. }
  73. core[0] += a; core[1] += b; core[2] += c; core[3] += d;
  74. core[4] += e; core[5] += f; core[6] += g; core[7] += h;
  75. smemclr(w, sizeof(w));
  76. }
  77. #else // WINSCP_VS
  78. typedef struct sha256_sw {
  79. uint32_t core[8];
  80. sha256_block blk;
  81. BinarySink_IMPLEMENTATION;
  82. ssh_hash hash;
  83. } sha256_sw;
  84. static void sha256_sw_write(BinarySink *bs, const void *vp, size_t len);
  85. static ssh_hash *sha256_sw_new(const ssh_hashalg *alg)
  86. {
  87. sha256_sw *s = snew(sha256_sw);
  88. s->hash.vt = alg;
  89. BinarySink_INIT(s, sha256_sw_write);
  90. BinarySink_DELEGATE_INIT(&s->hash, s);
  91. return &s->hash;
  92. }
  93. static void sha256_sw_reset(ssh_hash *hash)
  94. {
  95. sha256_sw *s = container_of(hash, sha256_sw, hash);
  96. memcpy(s->core, sha256_initial_state, sizeof(s->core));
  97. sha256_block_setup(&s->blk);
  98. }
  99. static void sha256_sw_copyfrom(ssh_hash *hcopy, ssh_hash *horig)
  100. {
  101. sha256_sw *copy = container_of(hcopy, sha256_sw, hash);
  102. sha256_sw *orig = container_of(horig, sha256_sw, hash);
  103. memcpy(copy, orig, sizeof(*copy));
  104. BinarySink_COPIED(copy);
  105. BinarySink_DELEGATE_INIT(&copy->hash, copy);
  106. }
  107. static void sha256_sw_free(ssh_hash *hash)
  108. {
  109. sha256_sw *s = container_of(hash, sha256_sw, hash);
  110. smemclr(s, sizeof(*s));
  111. sfree(s);
  112. }
  113. static void sha256_sw_write(BinarySink *bs, const void *vp, size_t len)
  114. {
  115. sha256_sw *s = BinarySink_DOWNCAST(bs, sha256_sw);
  116. while (len > 0)
  117. if (sha256_block_write(&s->blk, &vp, &len))
  118. sha256_sw_block(s->core, s->blk.block);
  119. }
  120. static void sha256_sw_digest(ssh_hash *hash, uint8_t *digest)
  121. {
  122. sha256_sw *s = container_of(hash, sha256_sw, hash);
  123. sha256_block_pad(&s->blk, BinarySink_UPCAST(s));
  124. { // WINSCP
  125. size_t i;
  126. for (i = 0; i < 8; i++)
  127. PUT_32BIT_MSB_FIRST(digest + 4*i, s->core[i]);
  128. } // WINSCP
  129. }
  130. SHA256_VTABLE(sw, "unaccelerated");
  131. #endif // WINSCP_VS