Annotation of OpenXM/src/ox_ntl/crypt/sha1/sha1.c, Revision 1.5
1.5 ! iwane 1: /* $OpenXM: OpenXM/src/ox_ntl/crypt/sha1/sha1.c,v 1.4 2004/06/20 10:59:01 iwane Exp $ */
1.2 iwane 2: /* RFC 3174 - SHA-1 (US Secure Hash Algorithm 1 (SHA1))*/
1.1 iwane 3:
1.3 iwane 4: #include <stdio.h>
1.5 ! iwane 5: #include <string.h>
1.3 iwane 6:
1.2 iwane 7: #include "sha1.h"
1.1 iwane 8:
1.4 iwane 9: #include <unistd.h>
10: #include <errno.h>
11: #include <sys/stat.h>
12:
1.5 ! iwane 13: #ifdef lint
! 14: #define inline
! 15: #endif
! 16:
! 17:
1.1 iwane 18: /* Global Constant */
1.4 iwane 19: static const uint32_t K[4] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
20: static const uint32_t H[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
1.1 iwane 21:
22: #define BLOCK (512 / 8)
23:
24:
1.4 iwane 25: static inline uint32_t lshift32(uint32_t x, int n)
1.1 iwane 26: {
27: return ((x << n) | (x >> (32 - n)));
1.5 ! iwane 28: }
1.1 iwane 29:
30:
31:
32: /**
33: * sizeof(buf) >= 512 * ((len * 8 + 1) / 64)
34: * len * 8 < 2^64 ==> len < 2^61
35: */
1.4 iwane 36: static uint32_t
37: padding(unsigned char *buf, const unsigned char *msg, size_t length)
1.1 iwane 38: {
39: int n;
40: int i;
1.4 iwane 41: size_t len = length % BLOCK;
1.1 iwane 42:
43: memcpy(buf, msg, len);
44:
45: buf[len++] = 0x80;
46:
47: /* 56 < len % 64 */
48: if (BLOCK - 8 < len % BLOCK) {
49: /* too long */
50: n = BLOCK - (len % BLOCK) + BLOCK - 8;
51: } else {
52: n = BLOCK - 8 - (len % BLOCK);
53: }
54:
55: memset(buf + len, 0x00, n);
56:
57: n += len;
58:
59: for (i = 0; i < 4; i++) {
60: buf[n] = 0x00;
61: buf[n + 4] = ((length * 8) >> (8 * (3 - i))) & 0xff;
62: n++;
63: }
64:
65: return ((n + 4) / BLOCK);
66: }
67:
68:
69:
70:
1.4 iwane 71: static uint32_t
72: f(uint32_t t, uint32_t b, uint32_t c, uint32_t d)
1.1 iwane 73: {
74: if (t < 20) {
75: return ((b & c) | ((~b) & d));
76: }
77: if (t < 40 || t >= 60) {
78: return (b ^ c ^ d);
79: }
80:
81: if (t < 60) {
82: return ((b & c) | (b & d) | (c & d));
83: }
84:
1.2 iwane 85: /* Invalid Parameter. */
1.1 iwane 86: return (0);
87: }
88:
89:
90: /* sizeof(msg) == 512 / 8.
91: * padding.
92: */
1.3 iwane 93: void
1.4 iwane 94: sha1_md(uint32_t *h, const unsigned char *msg)
1.1 iwane 95: {
96: int t;
97: int i;
1.4 iwane 98:
99: uint32_t a, b, c, d, e, temp;
100: uint32_t w[80];
1.1 iwane 101:
1.2 iwane 102: /* ... */
1.1 iwane 103: for (t = 0; t < 16; t++) {
104: w[t] = 0;
105: for (i = 0; i < 4; i++) {
106: w[t] |= (msg[i + 4 * t] & 0xff) << ((3 - i) * 8);
107: }
108: }
109:
110: for (t = 16; t < 80; t++) {
111: w[t] = lshift32(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1);
112: }
113:
114: a = h[0];
115: b = h[1];
116: c = h[2];
117: d = h[3];
118: e = h[4];
119:
120: for (t = 0; t < 80; t++) {
121: temp = lshift32(a, 5) + f(t, b, c, d) + e + w[t] + K[t / 20];
122: e = d;
123: d = c;
124: c = lshift32(b, 30);
125: b = a;
126: a = temp;
127: }
128:
129: h[0] += a;
130: h[1] += b;
131: h[2] += c;
132: h[3] += d;
133: h[4] += e;
134: }
135:
136: int
1.4 iwane 137: sha1_h(unsigned char *Ph, const unsigned char *msg, size_t len, const uint32_t *hp)
1.1 iwane 138: {
1.4 iwane 139: int i, j, cnt;
140: size_t l = len;
1.1 iwane 141: unsigned char buf[1024];
1.4 iwane 142: uint32_t h[sizeof(H) / sizeof(H[0])];
1.2 iwane 143:
1.3 iwane 144: if (hp == NULL)
145: memcpy(h, H, sizeof(H));
146: else
147: memcpy(h, hp, sizeof(h));
1.1 iwane 148:
1.4 iwane 149: while (l >= BLOCK) {
1.3 iwane 150: sha1_md(h, msg);
1.1 iwane 151: msg += BLOCK;
152: l -= BLOCK;
153: }
154:
155: cnt = padding(buf, msg, len);
156: for (i = 0; i < cnt; i++) {
1.3 iwane 157: sha1_md(h, buf + BLOCK * i);
1.1 iwane 158: }
159:
160: memset(Ph, 0x00, sizeof(H));
161: for (i = 0; i < sizeof(H) / sizeof(H[0]); i++) {
162: for (j = 0; j < 32; j++) {
163: Ph[4 * i + j / 8] |= ((h[i] >> (31 - j)) & 1) << (7 - j % 8);
164: }
165: }
166:
167: return (0);
168: }
169:
170:
171: int
1.4 iwane 172: sha1(unsigned char *Ph, const unsigned char *msg, size_t len)
1.1 iwane 173: {
1.3 iwane 174: return (sha1_h(Ph, msg, len, NULL));
1.1 iwane 175: }
176:
177:
178: int
1.4 iwane 179: fsha1_h(unsigned char *Ph, int fd, const uint32_t *hp)
1.1 iwane 180: {
1.4 iwane 181: int i, j, cnt, ret;
1.5 ! iwane 182: int l;
1.4 iwane 183: off_t len;
184: unsigned char buf[1024], *msg, msgbuf[1024];
185: uint32_t h[sizeof(H) / sizeof(H[0])];
186: struct stat stbuf;
187:
188: if (hp == NULL)
189: memcpy(h, H, sizeof(H));
190: else
191: memcpy(h, hp, sizeof(h));
1.1 iwane 192:
1.4 iwane 193: ret = fstat(fd, &stbuf);
1.5 ! iwane 194: if (ret != 0) {
! 195: return (errno);
! 196: }
! 197:
! 198:
! 199: msg = msgbuf;
1.4 iwane 200: len = stbuf.st_size;
201: if (len == 0)
202: goto _PADDING;
203:
204: for (;;) {
205: l = read(fd, msgbuf, sizeof(msgbuf));
206: if (l < 0) {
207: return (errno);
208: }
209: if (l == 0)
210: break;
1.1 iwane 211:
1.4 iwane 212: len -= l;
213: msg = msgbuf;
1.1 iwane 214:
1.4 iwane 215: while (l >= BLOCK) {
216: sha1_md(h, msg);
217: msg += BLOCK;
218: l -= BLOCK;
219: }
1.1 iwane 220:
1.4 iwane 221: if (len == 0) {
222: _PADDING:
1.5 ! iwane 223: cnt = padding(buf, msg, (size_t)(stbuf.st_size % BLOCK));
1.4 iwane 224: for (i = 0; i < cnt; i++) {
225: sha1_md(h, buf + BLOCK * i);
226: }
227: }
1.1 iwane 228: }
229:
230:
1.4 iwane 231: memset(Ph, 0x00, sizeof(H));
232: for (i = 0; i < sizeof(H) / sizeof(H[0]); i++) {
233: for (j = 0; j < 32; j++) {
234: Ph[4 * i + j / 8] |= ((h[i] >> (31 - j)) & 1) << (7 - j % 8);
235: }
236: }
237:
1.1 iwane 238: return (0);
239: }
240:
1.4 iwane 241:
242:
243: int
244: fsha1(unsigned char *Ph, int fd)
245: {
246: return (fsha1_h(Ph, fd, NULL));
247: }
1.1 iwane 248:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>