sha1-sw.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Software implementation of SHA-1.
  3. */
  4. #include "ssh.h"
  5. #include "sha1.h"
  6. static bool sha1_sw_available(void)
  7. {
  8. /* Software SHA-1 is always available */
  9. return true;
  10. }
  11. static inline uint32_t rol(uint32_t x, unsigned y)
  12. {
  13. return (x << (31 & y)) | (x >> (31 & (uint32_t)(-(int32_t)y))); // WINSCP
  14. }
  15. static inline uint32_t Ch(uint32_t ctrl, uint32_t if1, uint32_t if0)
  16. {
  17. return if0 ^ (ctrl & (if1 ^ if0));
  18. }
  19. static inline uint32_t Maj(uint32_t x, uint32_t y, uint32_t z)
  20. {
  21. return (x & y) | (z & (x | y));
  22. }
  23. static inline uint32_t Par(uint32_t x, uint32_t y, uint32_t z)
  24. {
  25. return (x ^ y ^ z);
  26. }
  27. static inline void sha1_sw_round(
  28. unsigned round_index, const uint32_t *schedule,
  29. uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e,
  30. uint32_t f, uint32_t constant)
  31. {
  32. *e = rol(*a, 5) + f + *e + schedule[round_index] + constant;
  33. *b = rol(*b, 30);
  34. }
  35. static void sha1_sw_block(uint32_t *core, const uint8_t *block)
  36. {
  37. uint32_t w[SHA1_ROUNDS];
  38. uint32_t a,b,c,d,e;
  39. { // WINSCP
  40. size_t t;
  41. for (t = 0; t < 16; t++)
  42. w[t] = GET_32BIT_MSB_FIRST(block + 4*t);
  43. { // WINSCP
  44. size_t t;
  45. for (t = 16; t < SHA1_ROUNDS; t++)
  46. w[t] = rol(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1);
  47. a = core[0]; b = core[1]; c = core[2]; d = core[3];
  48. e = core[4];
  49. { // WINSCP
  50. size_t t = 0;
  51. size_t u;
  52. for (u = 0; u < SHA1_ROUNDS_PER_STAGE/5; u++) {
  53. sha1_sw_round(t++,w, &a,&b,&c,&d,&e, Ch(b,c,d), SHA1_STAGE0_CONSTANT);
  54. sha1_sw_round(t++,w, &e,&a,&b,&c,&d, Ch(a,b,c), SHA1_STAGE0_CONSTANT);
  55. sha1_sw_round(t++,w, &d,&e,&a,&b,&c, Ch(e,a,b), SHA1_STAGE0_CONSTANT);
  56. sha1_sw_round(t++,w, &c,&d,&e,&a,&b, Ch(d,e,a), SHA1_STAGE0_CONSTANT);
  57. sha1_sw_round(t++,w, &b,&c,&d,&e,&a, Ch(c,d,e), SHA1_STAGE0_CONSTANT);
  58. }
  59. { // WINSCP
  60. size_t u;
  61. for (u = 0; u < SHA1_ROUNDS_PER_STAGE/5; u++) {
  62. sha1_sw_round(t++,w, &a,&b,&c,&d,&e, Par(b,c,d), SHA1_STAGE1_CONSTANT);
  63. sha1_sw_round(t++,w, &e,&a,&b,&c,&d, Par(a,b,c), SHA1_STAGE1_CONSTANT);
  64. sha1_sw_round(t++,w, &d,&e,&a,&b,&c, Par(e,a,b), SHA1_STAGE1_CONSTANT);
  65. sha1_sw_round(t++,w, &c,&d,&e,&a,&b, Par(d,e,a), SHA1_STAGE1_CONSTANT);
  66. sha1_sw_round(t++,w, &b,&c,&d,&e,&a, Par(c,d,e), SHA1_STAGE1_CONSTANT);
  67. }
  68. { // WINSCP
  69. size_t u;
  70. for (u = 0; u < SHA1_ROUNDS_PER_STAGE/5; u++) {
  71. sha1_sw_round(t++,w, &a,&b,&c,&d,&e, Maj(b,c,d), SHA1_STAGE2_CONSTANT);
  72. sha1_sw_round(t++,w, &e,&a,&b,&c,&d, Maj(a,b,c), SHA1_STAGE2_CONSTANT);
  73. sha1_sw_round(t++,w, &d,&e,&a,&b,&c, Maj(e,a,b), SHA1_STAGE2_CONSTANT);
  74. sha1_sw_round(t++,w, &c,&d,&e,&a,&b, Maj(d,e,a), SHA1_STAGE2_CONSTANT);
  75. sha1_sw_round(t++,w, &b,&c,&d,&e,&a, Maj(c,d,e), SHA1_STAGE2_CONSTANT);
  76. }
  77. { // WINSCP
  78. size_t u;
  79. for (u = 0; u < SHA1_ROUNDS_PER_STAGE/5; u++) {
  80. sha1_sw_round(t++,w, &a,&b,&c,&d,&e, Par(b,c,d), SHA1_STAGE3_CONSTANT);
  81. sha1_sw_round(t++,w, &e,&a,&b,&c,&d, Par(a,b,c), SHA1_STAGE3_CONSTANT);
  82. sha1_sw_round(t++,w, &d,&e,&a,&b,&c, Par(e,a,b), SHA1_STAGE3_CONSTANT);
  83. sha1_sw_round(t++,w, &c,&d,&e,&a,&b, Par(d,e,a), SHA1_STAGE3_CONSTANT);
  84. sha1_sw_round(t++,w, &b,&c,&d,&e,&a, Par(c,d,e), SHA1_STAGE3_CONSTANT);
  85. }
  86. core[0] += a; core[1] += b; core[2] += c; core[3] += d; core[4] += e;
  87. smemclr(w, sizeof(w));
  88. } // WINSCP
  89. } // WINSCP
  90. } // WINSCP
  91. } // WINSCP
  92. } // WINSCP
  93. } // WINSCP
  94. }
  95. typedef struct sha1_sw {
  96. uint32_t core[5];
  97. sha1_block blk;
  98. BinarySink_IMPLEMENTATION;
  99. ssh_hash hash;
  100. } sha1_sw;
  101. static void sha1_sw_write(BinarySink *bs, const void *vp, size_t len);
  102. static ssh_hash *sha1_sw_new(const ssh_hashalg *alg)
  103. {
  104. sha1_sw *s = snew(sha1_sw);
  105. s->hash.vt = alg;
  106. BinarySink_INIT(s, sha1_sw_write);
  107. BinarySink_DELEGATE_INIT(&s->hash, s);
  108. return &s->hash;
  109. }
  110. static void sha1_sw_reset(ssh_hash *hash)
  111. {
  112. sha1_sw *s = container_of(hash, sha1_sw, hash);
  113. memcpy(s->core, sha1_initial_state, sizeof(s->core));
  114. sha1_block_setup(&s->blk);
  115. }
  116. static void sha1_sw_copyfrom(ssh_hash *hcopy, ssh_hash *horig)
  117. {
  118. sha1_sw *copy = container_of(hcopy, sha1_sw, hash);
  119. sha1_sw *orig = container_of(horig, sha1_sw, hash);
  120. memcpy(copy, orig, sizeof(*copy));
  121. BinarySink_COPIED(copy);
  122. BinarySink_DELEGATE_INIT(&copy->hash, copy);
  123. }
  124. static void sha1_sw_free(ssh_hash *hash)
  125. {
  126. sha1_sw *s = container_of(hash, sha1_sw, hash);
  127. smemclr(s, sizeof(*s));
  128. sfree(s);
  129. }
  130. static void sha1_sw_write(BinarySink *bs, const void *vp, size_t len)
  131. {
  132. sha1_sw *s = BinarySink_DOWNCAST(bs, sha1_sw);
  133. while (len > 0)
  134. if (sha1_block_write(&s->blk, &vp, &len))
  135. sha1_sw_block(s->core, s->blk.block);
  136. }
  137. static void sha1_sw_digest(ssh_hash *hash, uint8_t *digest)
  138. {
  139. sha1_sw *s = container_of(hash, sha1_sw, hash);
  140. sha1_block_pad(&s->blk, BinarySink_UPCAST(s));
  141. { // WINSCP
  142. size_t i;
  143. for (i = 0; i < 5; i++)
  144. PUT_32BIT_MSB_FIRST(digest + 4*i, s->core[i]);
  145. } // WINSCP
  146. }
  147. SHA1_VTABLE(sw, "unaccelerated");