1*8462SApril.Chin@Sun.COM /*********************************************************************** 2*8462SApril.Chin@Sun.COM * * 3*8462SApril.Chin@Sun.COM * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1996-2008 AT&T Intellectual Property * 5*8462SApril.Chin@Sun.COM * and is licensed under the * 6*8462SApril.Chin@Sun.COM * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 8*8462SApril.Chin@Sun.COM * * 9*8462SApril.Chin@Sun.COM * A copy of the License is available at * 10*8462SApril.Chin@Sun.COM * http://www.opensource.org/licenses/cpl1.0.txt * 11*8462SApril.Chin@Sun.COM * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*8462SApril.Chin@Sun.COM * * 13*8462SApril.Chin@Sun.COM * Information and Software Systems Research * 14*8462SApril.Chin@Sun.COM * AT&T Research * 15*8462SApril.Chin@Sun.COM * Florham Park NJ * 16*8462SApril.Chin@Sun.COM * * 17*8462SApril.Chin@Sun.COM * Glenn Fowler <gsf@research.att.com> * 18*8462SApril.Chin@Sun.COM * * 19*8462SApril.Chin@Sun.COM ***********************************************************************/ 20*8462SApril.Chin@Sun.COM #pragma prototyped 21*8462SApril.Chin@Sun.COM 22*8462SApril.Chin@Sun.COM /* 23*8462SApril.Chin@Sun.COM * SHA-1 in C 24*8462SApril.Chin@Sun.COM * By Steve Reid <steve@edmweb.com> 25*8462SApril.Chin@Sun.COM * 100% Public Domain 26*8462SApril.Chin@Sun.COM * 27*8462SApril.Chin@Sun.COM * Test Vectors (from FIPS PUB 180-1) 28*8462SApril.Chin@Sun.COM * "abc" 29*8462SApril.Chin@Sun.COM * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 30*8462SApril.Chin@Sun.COM * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 31*8462SApril.Chin@Sun.COM * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 32*8462SApril.Chin@Sun.COM * A million repetitions of "a" 33*8462SApril.Chin@Sun.COM * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 34*8462SApril.Chin@Sun.COM */ 35*8462SApril.Chin@Sun.COM 36*8462SApril.Chin@Sun.COM #define sha1_description "FIPS 180-1 SHA-1 secure hash algorithm 1." 37*8462SApril.Chin@Sun.COM #define sha1_options "[+(version)?sha1 (FIPS 180-1) 1996-09-26]\ 38*8462SApril.Chin@Sun.COM [+(author)?Steve Reid <steve@edmweb.com>]" 39*8462SApril.Chin@Sun.COM #define sha1_match "sha1|SHA1|sha-1|SHA-1" 40*8462SApril.Chin@Sun.COM #define sha1_scale 0 41*8462SApril.Chin@Sun.COM 42*8462SApril.Chin@Sun.COM #define sha1_padding md5_pad 43*8462SApril.Chin@Sun.COM 44*8462SApril.Chin@Sun.COM typedef struct Sha1_s 45*8462SApril.Chin@Sun.COM { 46*8462SApril.Chin@Sun.COM _SUM_PUBLIC_ 47*8462SApril.Chin@Sun.COM _SUM_PRIVATE_ 48*8462SApril.Chin@Sun.COM uint32_t count[2]; 49*8462SApril.Chin@Sun.COM uint32_t state[5]; 50*8462SApril.Chin@Sun.COM uint8_t buffer[64]; 51*8462SApril.Chin@Sun.COM uint8_t digest[20]; 52*8462SApril.Chin@Sun.COM uint8_t digest_sum[20]; 53*8462SApril.Chin@Sun.COM } Sha1_t; 54*8462SApril.Chin@Sun.COM 55*8462SApril.Chin@Sun.COM #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 56*8462SApril.Chin@Sun.COM 57*8462SApril.Chin@Sun.COM /* 58*8462SApril.Chin@Sun.COM * blk0() and blk() perform the initial expand. 59*8462SApril.Chin@Sun.COM * I got the idea of expanding during the round function from SSLeay 60*8462SApril.Chin@Sun.COM */ 61*8462SApril.Chin@Sun.COM #if _ast_intswap 62*8462SApril.Chin@Sun.COM # define blk0(i) \ 63*8462SApril.Chin@Sun.COM (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) \ 64*8462SApril.Chin@Sun.COM | (rol(block->l[i], 8) & 0x00FF00FF)) 65*8462SApril.Chin@Sun.COM #else 66*8462SApril.Chin@Sun.COM # define blk0(i) block->l[i] 67*8462SApril.Chin@Sun.COM #endif 68*8462SApril.Chin@Sun.COM #define blk(i) \ 69*8462SApril.Chin@Sun.COM (block->l[i & 15] = rol(block->l[(i + 13) & 15] \ 70*8462SApril.Chin@Sun.COM ^ block->l[(i + 8) & 15] \ 71*8462SApril.Chin@Sun.COM ^ block->l[(i + 2) & 15] \ 72*8462SApril.Chin@Sun.COM ^ block->l[i & 15], 1)) 73*8462SApril.Chin@Sun.COM 74*8462SApril.Chin@Sun.COM /* 75*8462SApril.Chin@Sun.COM * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 76*8462SApril.Chin@Sun.COM */ 77*8462SApril.Chin@Sun.COM #define R0(v,w,x,y,z,i) \ 78*8462SApril.Chin@Sun.COM z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ 79*8462SApril.Chin@Sun.COM w = rol(w, 30); 80*8462SApril.Chin@Sun.COM #define R1(v,w,x,y,z,i) \ 81*8462SApril.Chin@Sun.COM z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ 82*8462SApril.Chin@Sun.COM w = rol(w, 30); 83*8462SApril.Chin@Sun.COM #define R2(v,w,x,y,z,i) \ 84*8462SApril.Chin@Sun.COM z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \ 85*8462SApril.Chin@Sun.COM w = rol(w, 30); 86*8462SApril.Chin@Sun.COM #define R3(v,w,x,y,z,i) \ 87*8462SApril.Chin@Sun.COM z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ 88*8462SApril.Chin@Sun.COM w = rol(w, 30); 89*8462SApril.Chin@Sun.COM #define R4(v,w,x,y,z,i) \ 90*8462SApril.Chin@Sun.COM z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ 91*8462SApril.Chin@Sun.COM w = rol(w, 30); 92*8462SApril.Chin@Sun.COM 93*8462SApril.Chin@Sun.COM typedef union { 94*8462SApril.Chin@Sun.COM unsigned char c[64]; 95*8462SApril.Chin@Sun.COM unsigned int l[16]; 96*8462SApril.Chin@Sun.COM } CHAR64LONG16; 97*8462SApril.Chin@Sun.COM 98*8462SApril.Chin@Sun.COM #ifdef __sparc_v9__ 99*8462SApril.Chin@Sun.COM static void do_R01(uint32_t *a, uint32_t *b, uint32_t *c, 100*8462SApril.Chin@Sun.COM uint32_t *d, uint32_t *e, CHAR64LONG16 *); 101*8462SApril.Chin@Sun.COM static void do_R2(uint32_t *a, uint32_t *b, uint32_t *c, 102*8462SApril.Chin@Sun.COM uint32_t *d, uint32_t *e, CHAR64LONG16 *); 103*8462SApril.Chin@Sun.COM static void do_R3(uint32_t *a, uint32_t *b, uint32_t *c, 104*8462SApril.Chin@Sun.COM uint32_t *d, uint32_t *e, CHAR64LONG16 *); 105*8462SApril.Chin@Sun.COM static void do_R4(uint32_t *a, uint32_t *b, uint32_t *c, 106*8462SApril.Chin@Sun.COM uint32_t *d, uint32_t *e, CHAR64LONG16 *); 107*8462SApril.Chin@Sun.COM 108*8462SApril.Chin@Sun.COM #define nR0(v,w,x,y,z,i) R0(*v,*w,*x,*y,*z,i) 109*8462SApril.Chin@Sun.COM #define nR1(v,w,x,y,z,i) R1(*v,*w,*x,*y,*z,i) 110*8462SApril.Chin@Sun.COM #define nR2(v,w,x,y,z,i) R2(*v,*w,*x,*y,*z,i) 111*8462SApril.Chin@Sun.COM #define nR3(v,w,x,y,z,i) R3(*v,*w,*x,*y,*z,i) 112*8462SApril.Chin@Sun.COM #define nR4(v,w,x,y,z,i) R4(*v,*w,*x,*y,*z,i) 113*8462SApril.Chin@Sun.COM 114*8462SApril.Chin@Sun.COM static void 115*8462SApril.Chin@Sun.COM do_R01(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, 116*8462SApril.Chin@Sun.COM uint32_t *e, CHAR64LONG16 *block) 117*8462SApril.Chin@Sun.COM { 118*8462SApril.Chin@Sun.COM nR0(a,b,c,d,e, 0); nR0(e,a,b,c,d, 1); nR0(d,e,a,b,c, 2); 119*8462SApril.Chin@Sun.COM nR0(c,d,e,a,b, 3); nR0(b,c,d,e,a, 4); nR0(a,b,c,d,e, 5); 120*8462SApril.Chin@Sun.COM nR0(e,a,b,c,d, 6); nR0(d,e,a,b,c, 7); nR0(c,d,e,a,b, 8); 121*8462SApril.Chin@Sun.COM nR0(b,c,d,e,a, 9); nR0(a,b,c,d,e,10); nR0(e,a,b,c,d,11); 122*8462SApril.Chin@Sun.COM nR0(d,e,a,b,c,12); nR0(c,d,e,a,b,13); nR0(b,c,d,e,a,14); 123*8462SApril.Chin@Sun.COM nR0(a,b,c,d,e,15); nR1(e,a,b,c,d,16); nR1(d,e,a,b,c,17); 124*8462SApril.Chin@Sun.COM nR1(c,d,e,a,b,18); nR1(b,c,d,e,a,19); 125*8462SApril.Chin@Sun.COM } 126*8462SApril.Chin@Sun.COM 127*8462SApril.Chin@Sun.COM static void 128*8462SApril.Chin@Sun.COM do_R2(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, 129*8462SApril.Chin@Sun.COM uint32_t *e, CHAR64LONG16 *block) 130*8462SApril.Chin@Sun.COM { 131*8462SApril.Chin@Sun.COM nR2(a,b,c,d,e,20); nR2(e,a,b,c,d,21); nR2(d,e,a,b,c,22); 132*8462SApril.Chin@Sun.COM nR2(c,d,e,a,b,23); nR2(b,c,d,e,a,24); nR2(a,b,c,d,e,25); 133*8462SApril.Chin@Sun.COM nR2(e,a,b,c,d,26); nR2(d,e,a,b,c,27); nR2(c,d,e,a,b,28); 134*8462SApril.Chin@Sun.COM nR2(b,c,d,e,a,29); nR2(a,b,c,d,e,30); nR2(e,a,b,c,d,31); 135*8462SApril.Chin@Sun.COM nR2(d,e,a,b,c,32); nR2(c,d,e,a,b,33); nR2(b,c,d,e,a,34); 136*8462SApril.Chin@Sun.COM nR2(a,b,c,d,e,35); nR2(e,a,b,c,d,36); nR2(d,e,a,b,c,37); 137*8462SApril.Chin@Sun.COM nR2(c,d,e,a,b,38); nR2(b,c,d,e,a,39); 138*8462SApril.Chin@Sun.COM } 139*8462SApril.Chin@Sun.COM 140*8462SApril.Chin@Sun.COM static void 141*8462SApril.Chin@Sun.COM do_R3(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, 142*8462SApril.Chin@Sun.COM uint32_t *e, CHAR64LONG16 *block) 143*8462SApril.Chin@Sun.COM { 144*8462SApril.Chin@Sun.COM nR3(a,b,c,d,e,40); nR3(e,a,b,c,d,41); nR3(d,e,a,b,c,42); 145*8462SApril.Chin@Sun.COM nR3(c,d,e,a,b,43); nR3(b,c,d,e,a,44); nR3(a,b,c,d,e,45); 146*8462SApril.Chin@Sun.COM nR3(e,a,b,c,d,46); nR3(d,e,a,b,c,47); nR3(c,d,e,a,b,48); 147*8462SApril.Chin@Sun.COM nR3(b,c,d,e,a,49); nR3(a,b,c,d,e,50); nR3(e,a,b,c,d,51); 148*8462SApril.Chin@Sun.COM nR3(d,e,a,b,c,52); nR3(c,d,e,a,b,53); nR3(b,c,d,e,a,54); 149*8462SApril.Chin@Sun.COM nR3(a,b,c,d,e,55); nR3(e,a,b,c,d,56); nR3(d,e,a,b,c,57); 150*8462SApril.Chin@Sun.COM nR3(c,d,e,a,b,58); nR3(b,c,d,e,a,59); 151*8462SApril.Chin@Sun.COM } 152*8462SApril.Chin@Sun.COM 153*8462SApril.Chin@Sun.COM static void 154*8462SApril.Chin@Sun.COM do_R4(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, 155*8462SApril.Chin@Sun.COM uint32_t *e, CHAR64LONG16 *block) 156*8462SApril.Chin@Sun.COM { 157*8462SApril.Chin@Sun.COM nR4(a,b,c,d,e,60); nR4(e,a,b,c,d,61); nR4(d,e,a,b,c,62); 158*8462SApril.Chin@Sun.COM nR4(c,d,e,a,b,63); nR4(b,c,d,e,a,64); nR4(a,b,c,d,e,65); 159*8462SApril.Chin@Sun.COM nR4(e,a,b,c,d,66); nR4(d,e,a,b,c,67); nR4(c,d,e,a,b,68); 160*8462SApril.Chin@Sun.COM nR4(b,c,d,e,a,69); nR4(a,b,c,d,e,70); nR4(e,a,b,c,d,71); 161*8462SApril.Chin@Sun.COM nR4(d,e,a,b,c,72); nR4(c,d,e,a,b,73); nR4(b,c,d,e,a,74); 162*8462SApril.Chin@Sun.COM nR4(a,b,c,d,e,75); nR4(e,a,b,c,d,76); nR4(d,e,a,b,c,77); 163*8462SApril.Chin@Sun.COM nR4(c,d,e,a,b,78); nR4(b,c,d,e,a,79); 164*8462SApril.Chin@Sun.COM } 165*8462SApril.Chin@Sun.COM #endif 166*8462SApril.Chin@Sun.COM 167*8462SApril.Chin@Sun.COM /* 168*8462SApril.Chin@Sun.COM * Hash a single 512-bit block. This is the core of the algorithm. 169*8462SApril.Chin@Sun.COM */ 170*8462SApril.Chin@Sun.COM static void 171*8462SApril.Chin@Sun.COM sha1_transform(uint32_t state[5], const unsigned char buffer[64]) { 172*8462SApril.Chin@Sun.COM uint32_t a, b, c, d, e; 173*8462SApril.Chin@Sun.COM CHAR64LONG16 *block; 174*8462SApril.Chin@Sun.COM CHAR64LONG16 workspace; 175*8462SApril.Chin@Sun.COM 176*8462SApril.Chin@Sun.COM block = &workspace; 177*8462SApril.Chin@Sun.COM (void)memcpy(block, buffer, 64); 178*8462SApril.Chin@Sun.COM 179*8462SApril.Chin@Sun.COM /* Copy sha->state[] to working vars */ 180*8462SApril.Chin@Sun.COM a = state[0]; 181*8462SApril.Chin@Sun.COM b = state[1]; 182*8462SApril.Chin@Sun.COM c = state[2]; 183*8462SApril.Chin@Sun.COM d = state[3]; 184*8462SApril.Chin@Sun.COM e = state[4]; 185*8462SApril.Chin@Sun.COM 186*8462SApril.Chin@Sun.COM #ifdef __sparc_v9__ 187*8462SApril.Chin@Sun.COM do_R01(&a, &b, &c, &d, &e, block); 188*8462SApril.Chin@Sun.COM do_R2(&a, &b, &c, &d, &e, block); 189*8462SApril.Chin@Sun.COM do_R3(&a, &b, &c, &d, &e, block); 190*8462SApril.Chin@Sun.COM do_R4(&a, &b, &c, &d, &e, block); 191*8462SApril.Chin@Sun.COM #else 192*8462SApril.Chin@Sun.COM /* 4 rounds of 20 operations each. Loop unrolled. */ 193*8462SApril.Chin@Sun.COM R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 194*8462SApril.Chin@Sun.COM R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 195*8462SApril.Chin@Sun.COM R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 196*8462SApril.Chin@Sun.COM R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 197*8462SApril.Chin@Sun.COM R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 198*8462SApril.Chin@Sun.COM R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 199*8462SApril.Chin@Sun.COM R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 200*8462SApril.Chin@Sun.COM R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 201*8462SApril.Chin@Sun.COM R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 202*8462SApril.Chin@Sun.COM R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 203*8462SApril.Chin@Sun.COM R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 204*8462SApril.Chin@Sun.COM R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 205*8462SApril.Chin@Sun.COM R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 206*8462SApril.Chin@Sun.COM R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 207*8462SApril.Chin@Sun.COM R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 208*8462SApril.Chin@Sun.COM R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 209*8462SApril.Chin@Sun.COM R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 210*8462SApril.Chin@Sun.COM R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 211*8462SApril.Chin@Sun.COM R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 212*8462SApril.Chin@Sun.COM R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 213*8462SApril.Chin@Sun.COM #endif 214*8462SApril.Chin@Sun.COM 215*8462SApril.Chin@Sun.COM /* Add the working vars back into context.state[] */ 216*8462SApril.Chin@Sun.COM state[0] += a; 217*8462SApril.Chin@Sun.COM state[1] += b; 218*8462SApril.Chin@Sun.COM state[2] += c; 219*8462SApril.Chin@Sun.COM state[3] += d; 220*8462SApril.Chin@Sun.COM state[4] += e; 221*8462SApril.Chin@Sun.COM 222*8462SApril.Chin@Sun.COM /* Wipe variables */ 223*8462SApril.Chin@Sun.COM a = b = c = d = e = 0; 224*8462SApril.Chin@Sun.COM } 225*8462SApril.Chin@Sun.COM 226*8462SApril.Chin@Sun.COM static int 227*8462SApril.Chin@Sun.COM sha1_block(register Sum_t* p, const void* s, size_t len) 228*8462SApril.Chin@Sun.COM { 229*8462SApril.Chin@Sun.COM Sha1_t* sha = (Sha1_t*)p; 230*8462SApril.Chin@Sun.COM uint8_t* data = (uint8_t*)s; 231*8462SApril.Chin@Sun.COM unsigned int i, j; 232*8462SApril.Chin@Sun.COM 233*8462SApril.Chin@Sun.COM if (len) { 234*8462SApril.Chin@Sun.COM j = sha->count[0]; 235*8462SApril.Chin@Sun.COM if ((sha->count[0] += len << 3) < j) 236*8462SApril.Chin@Sun.COM sha->count[1] += (len >> 29) + 1; 237*8462SApril.Chin@Sun.COM j = (j >> 3) & 63; 238*8462SApril.Chin@Sun.COM if ((j + len) > 63) { 239*8462SApril.Chin@Sun.COM (void)memcpy(&sha->buffer[j], data, (i = 64 - j)); 240*8462SApril.Chin@Sun.COM sha1_transform(sha->state, sha->buffer); 241*8462SApril.Chin@Sun.COM for ( ; i + 63 < len; i += 64) 242*8462SApril.Chin@Sun.COM sha1_transform(sha->state, &data[i]); 243*8462SApril.Chin@Sun.COM j = 0; 244*8462SApril.Chin@Sun.COM } else { 245*8462SApril.Chin@Sun.COM i = 0; 246*8462SApril.Chin@Sun.COM } 247*8462SApril.Chin@Sun.COM 248*8462SApril.Chin@Sun.COM (void)memcpy(&sha->buffer[j], &data[i], len - i); 249*8462SApril.Chin@Sun.COM } 250*8462SApril.Chin@Sun.COM return 0; 251*8462SApril.Chin@Sun.COM } 252*8462SApril.Chin@Sun.COM 253*8462SApril.Chin@Sun.COM static int 254*8462SApril.Chin@Sun.COM sha1_init(Sum_t* p) 255*8462SApril.Chin@Sun.COM { 256*8462SApril.Chin@Sun.COM register Sha1_t* sha = (Sha1_t*)p; 257*8462SApril.Chin@Sun.COM 258*8462SApril.Chin@Sun.COM sha->count[0] = sha->count[1] = 0; 259*8462SApril.Chin@Sun.COM sha->state[0] = 0x67452301; 260*8462SApril.Chin@Sun.COM sha->state[1] = 0xEFCDAB89; 261*8462SApril.Chin@Sun.COM sha->state[2] = 0x98BADCFE; 262*8462SApril.Chin@Sun.COM sha->state[3] = 0x10325476; 263*8462SApril.Chin@Sun.COM sha->state[4] = 0xC3D2E1F0; 264*8462SApril.Chin@Sun.COM 265*8462SApril.Chin@Sun.COM return 0; 266*8462SApril.Chin@Sun.COM } 267*8462SApril.Chin@Sun.COM 268*8462SApril.Chin@Sun.COM static Sum_t* 269*8462SApril.Chin@Sun.COM sha1_open(const Method_t* method, const char* name) 270*8462SApril.Chin@Sun.COM { 271*8462SApril.Chin@Sun.COM Sha1_t* sha; 272*8462SApril.Chin@Sun.COM 273*8462SApril.Chin@Sun.COM if (sha = newof(0, Sha1_t, 1, 0)) 274*8462SApril.Chin@Sun.COM { 275*8462SApril.Chin@Sun.COM sha->method = (Method_t*)method; 276*8462SApril.Chin@Sun.COM sha->name = name; 277*8462SApril.Chin@Sun.COM sha1_init((Sum_t*)sha); 278*8462SApril.Chin@Sun.COM } 279*8462SApril.Chin@Sun.COM return (Sum_t*)sha; 280*8462SApril.Chin@Sun.COM } 281*8462SApril.Chin@Sun.COM 282*8462SApril.Chin@Sun.COM /* 283*8462SApril.Chin@Sun.COM * Add padding and return the message digest. 284*8462SApril.Chin@Sun.COM */ 285*8462SApril.Chin@Sun.COM 286*8462SApril.Chin@Sun.COM static const unsigned char final_200 = 128; 287*8462SApril.Chin@Sun.COM static const unsigned char final_0 = 0; 288*8462SApril.Chin@Sun.COM 289*8462SApril.Chin@Sun.COM static int 290*8462SApril.Chin@Sun.COM sha1_done(Sum_t* p) 291*8462SApril.Chin@Sun.COM { 292*8462SApril.Chin@Sun.COM Sha1_t* sha = (Sha1_t*)p; 293*8462SApril.Chin@Sun.COM unsigned int i; 294*8462SApril.Chin@Sun.COM unsigned char finalcount[8]; 295*8462SApril.Chin@Sun.COM 296*8462SApril.Chin@Sun.COM for (i = 0; i < 8; i++) { 297*8462SApril.Chin@Sun.COM /* Endian independent */ 298*8462SApril.Chin@Sun.COM finalcount[i] = (unsigned char) 299*8462SApril.Chin@Sun.COM ((sha->count[(i >= 4 ? 0 : 1)] 300*8462SApril.Chin@Sun.COM >> ((3 - (i & 3)) * 8)) & 255); 301*8462SApril.Chin@Sun.COM } 302*8462SApril.Chin@Sun.COM 303*8462SApril.Chin@Sun.COM sha1_block(p, &final_200, 1); 304*8462SApril.Chin@Sun.COM while ((sha->count[0] & 504) != 448) 305*8462SApril.Chin@Sun.COM sha1_block(p, &final_0, 1); 306*8462SApril.Chin@Sun.COM /* The next Update should cause a sha1_transform() */ 307*8462SApril.Chin@Sun.COM sha1_block(p, finalcount, 8); 308*8462SApril.Chin@Sun.COM 309*8462SApril.Chin@Sun.COM for (i = 0; i < elementsof(sha->digest); i++) 310*8462SApril.Chin@Sun.COM { 311*8462SApril.Chin@Sun.COM sha->digest[i] = (unsigned char)((sha->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); 312*8462SApril.Chin@Sun.COM sha->digest_sum[i] ^= sha->digest[i]; 313*8462SApril.Chin@Sun.COM } 314*8462SApril.Chin@Sun.COM memset(sha->count, 0, sizeof(sha->count)); 315*8462SApril.Chin@Sun.COM memset(sha->state, 0, sizeof(sha->state)); 316*8462SApril.Chin@Sun.COM memset(sha->buffer, 0, sizeof(sha->buffer)); 317*8462SApril.Chin@Sun.COM return 0; 318*8462SApril.Chin@Sun.COM } 319*8462SApril.Chin@Sun.COM 320*8462SApril.Chin@Sun.COM static int 321*8462SApril.Chin@Sun.COM sha1_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale) 322*8462SApril.Chin@Sun.COM { 323*8462SApril.Chin@Sun.COM register Sha1_t* sha = (Sha1_t*)p; 324*8462SApril.Chin@Sun.COM register unsigned char* d; 325*8462SApril.Chin@Sun.COM register int n; 326*8462SApril.Chin@Sun.COM 327*8462SApril.Chin@Sun.COM d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest; 328*8462SApril.Chin@Sun.COM for (n = 0; n < elementsof(sha->digest); n++) 329*8462SApril.Chin@Sun.COM sfprintf(sp, "%02x", d[n]); 330*8462SApril.Chin@Sun.COM return 0; 331*8462SApril.Chin@Sun.COM } 332*8462SApril.Chin@Sun.COM 333*8462SApril.Chin@Sun.COM static int 334*8462SApril.Chin@Sun.COM sha1_data(Sum_t* p, Sumdata_t* data) 335*8462SApril.Chin@Sun.COM { 336*8462SApril.Chin@Sun.COM register Sha1_t* sha = (Sha1_t*)p; 337*8462SApril.Chin@Sun.COM 338*8462SApril.Chin@Sun.COM data->size = elementsof(sha->digest); 339*8462SApril.Chin@Sun.COM data->num = 0; 340*8462SApril.Chin@Sun.COM data->buf = sha->digest; 341*8462SApril.Chin@Sun.COM return 0; 342*8462SApril.Chin@Sun.COM } 343