[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.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>