sha1.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "os.h"
  2. #include <libsec.h>
  3. static void encode(uchar*, u32int*, ulong);
  4. extern void _sha1block(uchar*, ulong, u32int*);
  5. /*
  6. * we require len to be a multiple of 64 for all but
  7. * the last call. There must be room in the input buffer
  8. * to pad.
  9. */
  10. SHA1state*
  11. sha1(uchar *p, ulong len, uchar *digest, SHA1state *s)
  12. {
  13. uchar buf[128];
  14. u32int x[16];
  15. int i;
  16. uchar *e;
  17. if(s == nil){
  18. s = malloc(sizeof(*s));
  19. if(s == nil)
  20. return nil;
  21. memset(s, 0, sizeof(*s));
  22. s->malloced = 1;
  23. }
  24. if(s->seeded == 0){
  25. /* seed the state, these constants would look nicer big-endian */
  26. s->state[0] = 0x67452301;
  27. s->state[1] = 0xefcdab89;
  28. s->state[2] = 0x98badcfe;
  29. s->state[3] = 0x10325476;
  30. s->state[4] = 0xc3d2e1f0;
  31. s->seeded = 1;
  32. }
  33. /* fill out the partial 64 byte block from previous calls */
  34. if(s->blen){
  35. i = 64 - s->blen;
  36. if(len < i)
  37. i = len;
  38. memmove(s->buf + s->blen, p, i);
  39. len -= i;
  40. s->blen += i;
  41. p += i;
  42. if(s->blen == 64){
  43. _sha1block(s->buf, s->blen, s->state);
  44. s->len += s->blen;
  45. s->blen = 0;
  46. }
  47. }
  48. /* do 64 byte blocks */
  49. i = len & ~0x3f;
  50. if(i){
  51. _sha1block(p, i, s->state);
  52. s->len += i;
  53. len -= i;
  54. p += i;
  55. }
  56. /* save the left overs if not last call */
  57. if(digest == 0){
  58. if(len){
  59. memmove(s->buf, p, len);
  60. s->blen += len;
  61. }
  62. return s;
  63. }
  64. /*
  65. * this is the last time through, pad what's left with 0x80,
  66. * 0's, and the input count to create a multiple of 64 bytes
  67. */
  68. if(s->blen){
  69. p = s->buf;
  70. len = s->blen;
  71. } else {
  72. memmove(buf, p, len);
  73. p = buf;
  74. }
  75. s->len += len;
  76. e = p + len;
  77. if(len < 56)
  78. i = 56 - len;
  79. else
  80. i = 120 - len;
  81. memset(e, 0, i);
  82. *e = 0x80;
  83. len += i;
  84. /* append the count */
  85. x[0] = s->len>>29;
  86. x[1] = s->len<<3;
  87. encode(p+len, x, 8);
  88. /* digest the last part */
  89. _sha1block(p, len+8, s->state);
  90. s->len += len+8;
  91. /* return result and free state */
  92. encode(digest, s->state, SHA1dlen);
  93. if(s->malloced == 1)
  94. free(s);
  95. return nil;
  96. }
  97. /*
  98. * encodes input (ulong) into output (uchar). Assumes len is
  99. * a multiple of 4.
  100. */
  101. static void
  102. encode(uchar *output, u32int *input, ulong len)
  103. {
  104. u32int x;
  105. uchar *e;
  106. for(e = output + len; output < e;) {
  107. x = *input++;
  108. *output++ = x >> 24;
  109. *output++ = x >> 16;
  110. *output++ = x >> 8;
  111. *output++ = x;
  112. }
  113. }
  114. DigestState*
  115. hmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest,
  116. DigestState *s)
  117. {
  118. return hmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen);
  119. }