[BACK]Return to sha1.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_ntl / crypt / sha1

Annotation of OpenXM/src/ox_ntl/crypt/sha1/sha1.c, Revision 1.6

1.6     ! iwane       1: /* $OpenXM: OpenXM/src/ox_ntl/crypt/sha1/sha1.c,v 1.5 2004/07/04 02:31:51 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));
1.6     ! iwane     161:        for (i = 0; i < (int)(sizeof(H) / sizeof(H[0])); i++) {
1.1       iwane     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));
1.6     ! iwane     232:        for (i = 0; i < (int)(sizeof(H) / sizeof(H[0])); i++) {
1.4       iwane     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>