sha1.c (3260B)
1 #include <stdint.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <assert.h> 5 6 #include <arpa/inet.h> 7 8 #include "sha1.h" 9 #include "util.h" 10 11 static inline uint32_t _sha1_rotl32(uint32_t x, uint8_t n) 12 { 13 return x << n | x >> (32 - n); 14 } 15 16 static inline void _sha1_add5(uint32_t *dest, const uint32_t *src) 17 { 18 size_t i; 19 20 for (i = 0; i < 5; i++) 21 dest[i] += src[i]; 22 } 23 24 static inline void _sha1_rotmod5(uint32_t *a, uint32_t f, uint32_t k, uint32_t w) 25 { 26 uint32_t t = _sha1_rotl32(a[0], 5) + f + a[4] + k + w; 27 memmove(a + 1, a, 4 * sizeof(*a)); 28 a[2] = _sha1_rotl32(a[2], 30); 29 a[0] = t; 30 } 31 32 static inline uint32_t _sha1_getnw(uint32_t *w, size_t i) 33 { 34 return w[i & 15] = _sha1_rotl32(w[(i + 13) & 15] ^ w[(i + 8) & 15] ^ w[(i + 2) & 15] ^ w[i & 15], 1); 35 } 36 37 void sha1_init(struct sha1 *s) 38 { 39 memcpy(s->h, (uint32_t[]){ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }, 5 * sizeof(*s->h)); 40 s->len = 0; 41 } 42 43 static inline void _sha1_update(uint32_t *h, const void *data) 44 { 45 const uint32_t k[4] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; 46 const uint32_t *d = data; 47 48 uint32_t w[16]; 49 size_t i; 50 51 uint32_t wr[5]; 52 memcpy(wr, h, sizeof(wr)); 53 54 for (i = 0; i < 16; i++) 55 _sha1_rotmod5(wr, (wr[1] & wr[2]) | (~wr[1] & wr[3]), k[0], w[i] = ntohl(d[i])); 56 for (; i < 20; i++) 57 _sha1_rotmod5(wr, (wr[1] & wr[2]) | (~wr[1] & wr[3]), k[0], _sha1_getnw(w, i)); 58 for (; i < 40; i++) 59 _sha1_rotmod5(wr, wr[1] ^ wr[2] ^ wr[3], k[1], _sha1_getnw(w, i)); 60 for (; i < 60; i++) 61 _sha1_rotmod5(wr, (wr[1] & wr[2]) | (wr[1] & wr[3]) | (wr[2] & wr[3]), k[2], _sha1_getnw(w, i)); 62 for (; i < 80; i++) 63 _sha1_rotmod5(wr, wr[1] ^ wr[2] ^ wr[3], k[3], _sha1_getnw(w, i)); 64 65 _sha1_add5(h, wr); 66 } 67 68 void sha1_update(struct sha1 *s, const void *data, size_t len) 69 { 70 uint8_t *bw = s->buffer + (s->len & (sizeof(s->buffer) - 1)); 71 uint8_t *bend = 1[&s->buffer]; 72 73 if (data == bw) { 74 if (bw + len == bend) 75 _sha1_update(s->h, s->buffer); 76 } else if (bw + len > bend) { 77 const uint8_t *d = data; 78 const uint8_t *dend = d + len; 79 80 if (bw != s->buffer) { 81 memcpy(bw, d, bend - bw); 82 _sha1_update(s->h, s->buffer); 83 d += bend - bw; 84 } 85 86 while ((size_t)(dend - d) > sizeof(s->buffer)) { 87 _sha1_update(s->h, d); 88 d += sizeof(s->buffer); 89 } 90 91 memcpy(s->buffer, d, dend - d); 92 } else { 93 memcpy(bw, data, len); 94 } 95 s->len += len; 96 } 97 98 void sha1_finish(struct sha1 *s) 99 { 100 size_t i; 101 uint8_t *bw = s->buffer + (s->len & (sizeof(s->buffer) - 1)); 102 uint8_t *bend = 1[&s->buffer]; 103 104 *bw++ = 0x80; 105 memset(bw, 0, bend - bw); 106 107 if (bw + sizeof(uint64_t) >= bend) { 108 _sha1_update(s->h, s->buffer); 109 memset(s->buffer, 0, bw - s->buffer); 110 } 111 112 writebeu64(bend - sizeof(uint64_t), s->len << 3); 113 _sha1_update(s->h, s->buffer); 114 115 for (i = 0; i < sizeof(s->h) / sizeof(*s->h); i++) 116 writebeu32(&s->h[i], s->h[i]); 117 } 118 119 void sha1_hmac(const void *key, size_t keylen, 120 const void *data, size_t datalen, 121 void *h) 122 { 123 hmac(key, keylen, 124 data, datalen, 125 (digest_init)sha1_init, 126 (digest_update)sha1_update, 127 (digest_finish)sha1_finish, 128 sizeof(struct sha1), 129 sizeof(((struct sha1 *)0)->buffer), 130 sizeof(((struct sha1 *)0)->h), 131 (ptrdiff_t)&((struct sha1 *)0)->buffer, 132 (ptrdiff_t)&((struct sha1 *)0)->h, 133 h); 134 }