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