logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/

sha1.c (3700B)


  1. // SPDX-FileCopyrightText: public domain sha1 implementation based on rfc3174 and libtomcrypt
  2. // SPDX-License-Identifier: 0BSD
  3. #include "sha1.h"
  4. #include <string.h>
  5. static uint32_t
  6. rol(uint32_t n, int k)
  7. {
  8. return (n << k) | (n >> (32 - k));
  9. }
  10. #define F0(b, c, d) (d ^ (b & (c ^ d)))
  11. #define F1(b, c, d) (b ^ c ^ d)
  12. #define F2(b, c, d) ((b & c) | (d & (b | c)))
  13. #define F3(b, c, d) (b ^ c ^ d)
  14. #define G0(a, b, c, d, e, i) \
  15. e += rol(a, 5) + F0(b, c, d) + W[i] + 0x5A827999; \
  16. b = rol(b, 30)
  17. #define G1(a, b, c, d, e, i) \
  18. e += rol(a, 5) + F1(b, c, d) + W[i] + 0x6ED9EBA1; \
  19. b = rol(b, 30)
  20. #define G2(a, b, c, d, e, i) \
  21. e += rol(a, 5) + F2(b, c, d) + W[i] + 0x8F1BBCDC; \
  22. b = rol(b, 30)
  23. #define G3(a, b, c, d, e, i) \
  24. e += rol(a, 5) + F3(b, c, d) + W[i] + 0xCA62C1D6; \
  25. b = rol(b, 30)
  26. static void
  27. processblock(struct sha1 *s, const uint8_t *buf)
  28. {
  29. uint32_t W[80], a, b, c, d, e;
  30. int i;
  31. for(i = 0; i < 16; i++)
  32. {
  33. W[i] = (uint32_t)buf[4 * i] << 24;
  34. W[i] |= (uint32_t)buf[4 * i + 1] << 16;
  35. W[i] |= (uint32_t)buf[4 * i + 2] << 8;
  36. W[i] |= buf[4 * i + 3];
  37. }
  38. for(; i < 80; i++)
  39. W[i] = rol(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
  40. a = s->h[0];
  41. b = s->h[1];
  42. c = s->h[2];
  43. d = s->h[3];
  44. e = s->h[4];
  45. for(i = 0; i < 20;)
  46. {
  47. G0(a, b, c, d, e, i++);
  48. G0(e, a, b, c, d, i++);
  49. G0(d, e, a, b, c, i++);
  50. G0(c, d, e, a, b, i++);
  51. G0(b, c, d, e, a, i++);
  52. }
  53. while(i < 40)
  54. {
  55. G1(a, b, c, d, e, i++);
  56. G1(e, a, b, c, d, i++);
  57. G1(d, e, a, b, c, i++);
  58. G1(c, d, e, a, b, i++);
  59. G1(b, c, d, e, a, i++);
  60. }
  61. while(i < 60)
  62. {
  63. G2(a, b, c, d, e, i++);
  64. G2(e, a, b, c, d, i++);
  65. G2(d, e, a, b, c, i++);
  66. G2(c, d, e, a, b, i++);
  67. G2(b, c, d, e, a, i++);
  68. }
  69. while(i < 80)
  70. {
  71. G3(a, b, c, d, e, i++);
  72. G3(e, a, b, c, d, i++);
  73. G3(d, e, a, b, c, i++);
  74. G3(c, d, e, a, b, i++);
  75. G3(b, c, d, e, a, i++);
  76. }
  77. s->h[0] += a;
  78. s->h[1] += b;
  79. s->h[2] += c;
  80. s->h[3] += d;
  81. s->h[4] += e;
  82. }
  83. static void
  84. pad(struct sha1 *s)
  85. {
  86. unsigned r = s->len % 64;
  87. s->buf[r++] = 0x80;
  88. if(r > 56)
  89. {
  90. memset(s->buf + r, 0, 64 - r);
  91. r = 0;
  92. processblock(s, s->buf);
  93. }
  94. memset(s->buf + r, 0, 56 - r);
  95. s->len *= 8;
  96. s->buf[56] = s->len >> 56;
  97. s->buf[57] = s->len >> 48;
  98. s->buf[58] = s->len >> 40;
  99. s->buf[59] = s->len >> 32;
  100. s->buf[60] = s->len >> 24;
  101. s->buf[61] = s->len >> 16;
  102. s->buf[62] = s->len >> 8;
  103. s->buf[63] = s->len;
  104. processblock(s, s->buf);
  105. }
  106. void
  107. sha1_init(void *ctx)
  108. {
  109. struct sha1 *s = ctx;
  110. s->len = 0;
  111. s->h[0] = 0x67452301;
  112. s->h[1] = 0xEFCDAB89;
  113. s->h[2] = 0x98BADCFE;
  114. s->h[3] = 0x10325476;
  115. s->h[4] = 0xC3D2E1F0;
  116. }
  117. void
  118. sha1_sum(void *ctx, uint8_t md[SHA1_DIGEST_LENGTH])
  119. {
  120. struct sha1 *s = ctx;
  121. int i;
  122. pad(s);
  123. for(i = 0; i < 5; i++)
  124. {
  125. md[4 * i] = s->h[i] >> 24;
  126. md[4 * i + 1] = s->h[i] >> 16;
  127. md[4 * i + 2] = s->h[i] >> 8;
  128. md[4 * i + 3] = s->h[i];
  129. }
  130. }
  131. void
  132. sha1_update(void *ctx, const void *m, unsigned long len)
  133. {
  134. struct sha1 *s = ctx;
  135. const uint8_t *p = m;
  136. unsigned r = s->len % 64;
  137. s->len += len;
  138. if(r)
  139. {
  140. if(len < 64 - r)
  141. {
  142. memcpy(s->buf + r, p, len);
  143. return;
  144. }
  145. memcpy(s->buf + r, p, 64 - r);
  146. len -= 64 - r;
  147. p += 64 - r;
  148. processblock(s, s->buf);
  149. }
  150. for(; len >= 64; len -= 64, p += 64)
  151. processblock(s, p);
  152. memcpy(s->buf, p, len);
  153. }