18dbcf02cSchristos /*
28dbcf02cSchristos * SHA1 hash implementation and interface functions
38dbcf02cSchristos * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
48dbcf02cSchristos *
5e604d861Schristos * This software may be distributed under the terms of the BSD license.
6e604d861Schristos * See README for more details.
78dbcf02cSchristos */
88dbcf02cSchristos
98dbcf02cSchristos #include "includes.h"
108dbcf02cSchristos
118dbcf02cSchristos #include "common.h"
128dbcf02cSchristos #include "sha1.h"
138dbcf02cSchristos #include "sha1_i.h"
148dbcf02cSchristos #include "md5.h"
158dbcf02cSchristos #include "crypto.h"
168dbcf02cSchristos
178dbcf02cSchristos typedef struct SHA1Context SHA1_CTX;
188dbcf02cSchristos
198dbcf02cSchristos void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
208dbcf02cSchristos
218dbcf02cSchristos
223c260e60Schristos #ifdef CONFIG_CRYPTO_INTERNAL
238dbcf02cSchristos /**
248dbcf02cSchristos * sha1_vector - SHA-1 hash for data vector
258dbcf02cSchristos * @num_elem: Number of elements in the data vector
268dbcf02cSchristos * @addr: Pointers to the data areas
278dbcf02cSchristos * @len: Lengths of the data blocks
288dbcf02cSchristos * @mac: Buffer for the hash
298dbcf02cSchristos * Returns: 0 on success, -1 of failure
308dbcf02cSchristos */
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)318dbcf02cSchristos int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
328dbcf02cSchristos {
338dbcf02cSchristos SHA1_CTX ctx;
348dbcf02cSchristos size_t i;
358dbcf02cSchristos
3636ebd06eSchristos if (TEST_FAIL())
3736ebd06eSchristos return -1;
3836ebd06eSchristos
398dbcf02cSchristos SHA1Init(&ctx);
408dbcf02cSchristos for (i = 0; i < num_elem; i++)
418dbcf02cSchristos SHA1Update(&ctx, addr[i], len[i]);
428dbcf02cSchristos SHA1Final(mac, &ctx);
438dbcf02cSchristos return 0;
448dbcf02cSchristos }
453c260e60Schristos #endif /* CONFIG_CRYPTO_INTERNAL */
468dbcf02cSchristos
478dbcf02cSchristos
488dbcf02cSchristos /* ===== start - public domain SHA1 implementation ===== */
498dbcf02cSchristos
508dbcf02cSchristos /*
518dbcf02cSchristos SHA-1 in C
528dbcf02cSchristos By Steve Reid <sreid@sea-to-sky.net>
538dbcf02cSchristos 100% Public Domain
548dbcf02cSchristos
558dbcf02cSchristos -----------------
568dbcf02cSchristos Modified 7/98
578dbcf02cSchristos By James H. Brown <jbrown@burgoyne.com>
588dbcf02cSchristos Still 100% Public Domain
598dbcf02cSchristos
608dbcf02cSchristos Corrected a problem which generated improper hash values on 16 bit machines
618dbcf02cSchristos Routine SHA1Update changed from
628dbcf02cSchristos void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
638dbcf02cSchristos len)
648dbcf02cSchristos to
658dbcf02cSchristos void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
668dbcf02cSchristos long len)
678dbcf02cSchristos
688dbcf02cSchristos The 'len' parameter was declared an int which works fine on 32 bit machines.
698dbcf02cSchristos However, on 16 bit machines an int is too small for the shifts being done
708dbcf02cSchristos against
718dbcf02cSchristos it. This caused the hash function to generate incorrect values if len was
728dbcf02cSchristos greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
738dbcf02cSchristos
748dbcf02cSchristos Since the file IO in main() reads 16K at a time, any file 8K or larger would
758dbcf02cSchristos be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
768dbcf02cSchristos "a"s).
778dbcf02cSchristos
788dbcf02cSchristos I also changed the declaration of variables i & j in SHA1Update to
798dbcf02cSchristos unsigned long from unsigned int for the same reason.
808dbcf02cSchristos
818dbcf02cSchristos These changes should make no difference to any 32 bit implementations since
828dbcf02cSchristos an
838dbcf02cSchristos int and a long are the same size in those environments.
848dbcf02cSchristos
858dbcf02cSchristos --
868dbcf02cSchristos I also corrected a few compiler warnings generated by Borland C.
878dbcf02cSchristos 1. Added #include <process.h> for exit() prototype
888dbcf02cSchristos 2. Removed unused variable 'j' in SHA1Final
898dbcf02cSchristos 3. Changed exit(0) to return(0) at end of main.
908dbcf02cSchristos
918dbcf02cSchristos ALL changes I made can be located by searching for comments containing 'JHB'
928dbcf02cSchristos -----------------
938dbcf02cSchristos Modified 8/98
948dbcf02cSchristos By Steve Reid <sreid@sea-to-sky.net>
958dbcf02cSchristos Still 100% public domain
968dbcf02cSchristos
978dbcf02cSchristos 1- Removed #include <process.h> and used return() instead of exit()
988dbcf02cSchristos 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
998dbcf02cSchristos 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
1008dbcf02cSchristos
1018dbcf02cSchristos -----------------
1028dbcf02cSchristos Modified 4/01
1038dbcf02cSchristos By Saul Kravitz <Saul.Kravitz@celera.com>
1048dbcf02cSchristos Still 100% PD
1058dbcf02cSchristos Modified to run on Compaq Alpha hardware.
1068dbcf02cSchristos
1078dbcf02cSchristos -----------------
1088dbcf02cSchristos Modified 4/01
1098dbcf02cSchristos By Jouni Malinen <j@w1.fi>
1108dbcf02cSchristos Minor changes to match the coding style used in Dynamics.
1118dbcf02cSchristos
1128dbcf02cSchristos Modified September 24, 2004
1138dbcf02cSchristos By Jouni Malinen <j@w1.fi>
1148dbcf02cSchristos Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
1158dbcf02cSchristos
1168dbcf02cSchristos */
1178dbcf02cSchristos
1188dbcf02cSchristos /*
1198dbcf02cSchristos Test Vectors (from FIPS PUB 180-1)
1208dbcf02cSchristos "abc"
1218dbcf02cSchristos A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
1228dbcf02cSchristos "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
1238dbcf02cSchristos 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
1248dbcf02cSchristos A million repetitions of "a"
1258dbcf02cSchristos 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
1268dbcf02cSchristos */
1278dbcf02cSchristos
1288dbcf02cSchristos #define SHA1HANDSOFF
1298dbcf02cSchristos
1308dbcf02cSchristos #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
1318dbcf02cSchristos
1328dbcf02cSchristos /* blk0() and blk() perform the initial expand. */
1338dbcf02cSchristos /* I got the idea of expanding during the round function from SSLeay */
1348dbcf02cSchristos #ifndef WORDS_BIGENDIAN
1358dbcf02cSchristos #define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
1368dbcf02cSchristos (rol(block->l[i], 8) & 0x00FF00FF))
1378dbcf02cSchristos #else
1388dbcf02cSchristos #define blk0(i) block->l[i]
1398dbcf02cSchristos #endif
1408dbcf02cSchristos #define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
1418dbcf02cSchristos block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
1428dbcf02cSchristos
1438dbcf02cSchristos /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
1448dbcf02cSchristos #define R0(v,w,x,y,z,i) \
1458dbcf02cSchristos z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
1468dbcf02cSchristos w = rol(w, 30);
1478dbcf02cSchristos #define R1(v,w,x,y,z,i) \
1488dbcf02cSchristos z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
1498dbcf02cSchristos w = rol(w, 30);
1508dbcf02cSchristos #define R2(v,w,x,y,z,i) \
1518dbcf02cSchristos z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
1528dbcf02cSchristos #define R3(v,w,x,y,z,i) \
1538dbcf02cSchristos z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
1548dbcf02cSchristos w = rol(w, 30);
1558dbcf02cSchristos #define R4(v,w,x,y,z,i) \
1568dbcf02cSchristos z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
1578dbcf02cSchristos w=rol(w, 30);
1588dbcf02cSchristos
1598dbcf02cSchristos
1608dbcf02cSchristos #ifdef VERBOSE /* SAK */
SHAPrintContext(SHA1_CTX * context,char * msg)1618dbcf02cSchristos void SHAPrintContext(SHA1_CTX *context, char *msg)
1628dbcf02cSchristos {
1638dbcf02cSchristos printf("%s (%d,%d) %x %x %x %x %x\n",
1648dbcf02cSchristos msg,
1658dbcf02cSchristos context->count[0], context->count[1],
1668dbcf02cSchristos context->state[0],
1678dbcf02cSchristos context->state[1],
1688dbcf02cSchristos context->state[2],
1698dbcf02cSchristos context->state[3],
1708dbcf02cSchristos context->state[4]);
1718dbcf02cSchristos }
1728dbcf02cSchristos #endif
1738dbcf02cSchristos
1748dbcf02cSchristos /* Hash a single 512-bit block. This is the core of the algorithm. */
1758dbcf02cSchristos
SHA1Transform(u32 state[5],const unsigned char buffer[64])1768dbcf02cSchristos void SHA1Transform(u32 state[5], const unsigned char buffer[64])
1778dbcf02cSchristos {
1788dbcf02cSchristos u32 a, b, c, d, e;
1798dbcf02cSchristos typedef union {
1808dbcf02cSchristos unsigned char c[64];
1818dbcf02cSchristos u32 l[16];
1828dbcf02cSchristos } CHAR64LONG16;
1838dbcf02cSchristos CHAR64LONG16* block;
1848dbcf02cSchristos #ifdef SHA1HANDSOFF
1858dbcf02cSchristos CHAR64LONG16 workspace;
1868dbcf02cSchristos block = &workspace;
1878dbcf02cSchristos os_memcpy(block, buffer, 64);
1888dbcf02cSchristos #else
1898dbcf02cSchristos block = (CHAR64LONG16 *) buffer;
1908dbcf02cSchristos #endif
1918dbcf02cSchristos /* Copy context->state[] to working vars */
1928dbcf02cSchristos a = state[0];
1938dbcf02cSchristos b = state[1];
1948dbcf02cSchristos c = state[2];
1958dbcf02cSchristos d = state[3];
1968dbcf02cSchristos e = state[4];
1978dbcf02cSchristos /* 4 rounds of 20 operations each. Loop unrolled. */
1988dbcf02cSchristos 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);
1998dbcf02cSchristos 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);
2008dbcf02cSchristos 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);
2018dbcf02cSchristos 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);
2028dbcf02cSchristos 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);
2038dbcf02cSchristos 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);
2048dbcf02cSchristos 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);
2058dbcf02cSchristos 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);
2068dbcf02cSchristos 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);
2078dbcf02cSchristos 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);
2088dbcf02cSchristos 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);
2098dbcf02cSchristos 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);
2108dbcf02cSchristos 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);
2118dbcf02cSchristos 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);
2128dbcf02cSchristos 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);
2138dbcf02cSchristos 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);
2148dbcf02cSchristos 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);
2158dbcf02cSchristos 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);
2168dbcf02cSchristos 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);
2178dbcf02cSchristos 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);
2188dbcf02cSchristos /* Add the working vars back into context.state[] */
2198dbcf02cSchristos state[0] += a;
2208dbcf02cSchristos state[1] += b;
2218dbcf02cSchristos state[2] += c;
2228dbcf02cSchristos state[3] += d;
2238dbcf02cSchristos state[4] += e;
2248dbcf02cSchristos /* Wipe variables */
2258dbcf02cSchristos a = b = c = d = e = 0;
2268dbcf02cSchristos #ifdef SHA1HANDSOFF
227*3d6c0713Schristos forced_memzero(block, 64);
2288dbcf02cSchristos #endif
2298dbcf02cSchristos }
2308dbcf02cSchristos
2318dbcf02cSchristos
2328dbcf02cSchristos /* SHA1Init - Initialize new context */
2338dbcf02cSchristos
SHA1Init(SHA1_CTX * context)2348dbcf02cSchristos void SHA1Init(SHA1_CTX* context)
2358dbcf02cSchristos {
2368dbcf02cSchristos /* SHA1 initialization constants */
2378dbcf02cSchristos context->state[0] = 0x67452301;
2388dbcf02cSchristos context->state[1] = 0xEFCDAB89;
2398dbcf02cSchristos context->state[2] = 0x98BADCFE;
2408dbcf02cSchristos context->state[3] = 0x10325476;
2418dbcf02cSchristos context->state[4] = 0xC3D2E1F0;
2428dbcf02cSchristos context->count[0] = context->count[1] = 0;
2438dbcf02cSchristos }
2448dbcf02cSchristos
2458dbcf02cSchristos
2468dbcf02cSchristos /* Run your data through this. */
2478dbcf02cSchristos
SHA1Update(SHA1_CTX * context,const void * _data,u32 len)2488dbcf02cSchristos void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
2498dbcf02cSchristos {
2508dbcf02cSchristos u32 i, j;
2518dbcf02cSchristos const unsigned char *data = _data;
2528dbcf02cSchristos
2538dbcf02cSchristos #ifdef VERBOSE
2548dbcf02cSchristos SHAPrintContext(context, "before");
2558dbcf02cSchristos #endif
2568dbcf02cSchristos j = (context->count[0] >> 3) & 63;
2578dbcf02cSchristos if ((context->count[0] += len << 3) < (len << 3))
2588dbcf02cSchristos context->count[1]++;
2598dbcf02cSchristos context->count[1] += (len >> 29);
2608dbcf02cSchristos if ((j + len) > 63) {
2618dbcf02cSchristos os_memcpy(&context->buffer[j], data, (i = 64-j));
2628dbcf02cSchristos SHA1Transform(context->state, context->buffer);
2638dbcf02cSchristos for ( ; i + 63 < len; i += 64) {
2648dbcf02cSchristos SHA1Transform(context->state, &data[i]);
2658dbcf02cSchristos }
2668dbcf02cSchristos j = 0;
2678dbcf02cSchristos }
2688dbcf02cSchristos else i = 0;
2698dbcf02cSchristos os_memcpy(&context->buffer[j], &data[i], len - i);
2708dbcf02cSchristos #ifdef VERBOSE
2718dbcf02cSchristos SHAPrintContext(context, "after ");
2728dbcf02cSchristos #endif
2738dbcf02cSchristos }
2748dbcf02cSchristos
2758dbcf02cSchristos
2768dbcf02cSchristos /* Add padding and return the message digest. */
2778dbcf02cSchristos
SHA1Final(unsigned char digest[20],SHA1_CTX * context)2788dbcf02cSchristos void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
2798dbcf02cSchristos {
2808dbcf02cSchristos u32 i;
2818dbcf02cSchristos unsigned char finalcount[8];
2828dbcf02cSchristos
2838dbcf02cSchristos for (i = 0; i < 8; i++) {
2848dbcf02cSchristos finalcount[i] = (unsigned char)
2858dbcf02cSchristos ((context->count[(i >= 4 ? 0 : 1)] >>
2868dbcf02cSchristos ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
2878dbcf02cSchristos }
2888dbcf02cSchristos SHA1Update(context, (unsigned char *) "\200", 1);
2898dbcf02cSchristos while ((context->count[0] & 504) != 448) {
2908dbcf02cSchristos SHA1Update(context, (unsigned char *) "\0", 1);
2918dbcf02cSchristos }
2928dbcf02cSchristos SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform()
2938dbcf02cSchristos */
2948dbcf02cSchristos for (i = 0; i < 20; i++) {
2958dbcf02cSchristos digest[i] = (unsigned char)
2968dbcf02cSchristos ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
2978dbcf02cSchristos 255);
2988dbcf02cSchristos }
2998dbcf02cSchristos /* Wipe variables */
3008dbcf02cSchristos os_memset(context->buffer, 0, 64);
3018dbcf02cSchristos os_memset(context->state, 0, 20);
3028dbcf02cSchristos os_memset(context->count, 0, 8);
303*3d6c0713Schristos forced_memzero(finalcount, sizeof(finalcount));
3048dbcf02cSchristos }
3058dbcf02cSchristos
3068dbcf02cSchristos /* ===== end - public domain SHA1 implementation ===== */
307