1214501Srpaulo/* 2214501Srpaulo * SHA1 hash implementation and interface functions 3214501Srpaulo * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> 4214501Srpaulo * 5214501Srpaulo * This program is free software; you can redistribute it and/or modify 6214501Srpaulo * it under the terms of the GNU General Public License version 2 as 7214501Srpaulo * published by the Free Software Foundation. 8214501Srpaulo * 9214501Srpaulo * Alternatively, this software may be distributed under the terms of BSD 10214501Srpaulo * license. 11214501Srpaulo * 12214501Srpaulo * See README and COPYING for more details. 13214501Srpaulo */ 14214501Srpaulo 15214501Srpaulo#include "includes.h" 16214501Srpaulo 17214501Srpaulo#include "common.h" 18214501Srpaulo#include "sha1.h" 19214501Srpaulo#include "sha1_i.h" 20214501Srpaulo#include "md5.h" 21214501Srpaulo#include "crypto.h" 22214501Srpaulo 23214501Srpaulotypedef struct SHA1Context SHA1_CTX; 24214501Srpaulo 25214501Srpaulovoid SHA1Transform(u32 state[5], const unsigned char buffer[64]); 26214501Srpaulo 27214501Srpaulo 28214501Srpaulo/** 29214501Srpaulo * sha1_vector - SHA-1 hash for data vector 30214501Srpaulo * @num_elem: Number of elements in the data vector 31214501Srpaulo * @addr: Pointers to the data areas 32214501Srpaulo * @len: Lengths of the data blocks 33214501Srpaulo * @mac: Buffer for the hash 34214501Srpaulo * Returns: 0 on success, -1 of failure 35214501Srpaulo */ 36214501Srpauloint sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 37214501Srpaulo{ 38214501Srpaulo SHA1_CTX ctx; 39214501Srpaulo size_t i; 40214501Srpaulo 41214501Srpaulo SHA1Init(&ctx); 42214501Srpaulo for (i = 0; i < num_elem; i++) 43214501Srpaulo SHA1Update(&ctx, addr[i], len[i]); 44214501Srpaulo SHA1Final(mac, &ctx); 45214501Srpaulo return 0; 46214501Srpaulo} 47214501Srpaulo 48214501Srpaulo 49214501Srpaulo/* ===== start - public domain SHA1 implementation ===== */ 50214501Srpaulo 51214501Srpaulo/* 52214501SrpauloSHA-1 in C 53214501SrpauloBy Steve Reid <sreid@sea-to-sky.net> 54214501Srpaulo100% Public Domain 55214501Srpaulo 56214501Srpaulo----------------- 57214501SrpauloModified 7/98 58214501SrpauloBy James H. Brown <jbrown@burgoyne.com> 59214501SrpauloStill 100% Public Domain 60214501Srpaulo 61214501SrpauloCorrected a problem which generated improper hash values on 16 bit machines 62214501SrpauloRoutine SHA1Update changed from 63214501Srpaulo void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int 64214501Srpaulolen) 65214501Srpauloto 66214501Srpaulo void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned 67214501Srpaulolong len) 68214501Srpaulo 69214501SrpauloThe 'len' parameter was declared an int which works fine on 32 bit machines. 70214501SrpauloHowever, on 16 bit machines an int is too small for the shifts being done 71214501Srpauloagainst 72214501Srpauloit. This caused the hash function to generate incorrect values if len was 73214501Srpaulogreater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). 74214501Srpaulo 75214501SrpauloSince the file IO in main() reads 16K at a time, any file 8K or larger would 76214501Srpaulobe guaranteed to generate the wrong hash (e.g. Test Vector #3, a million 77214501Srpaulo"a"s). 78214501Srpaulo 79214501SrpauloI also changed the declaration of variables i & j in SHA1Update to 80214501Srpaulounsigned long from unsigned int for the same reason. 81214501Srpaulo 82214501SrpauloThese changes should make no difference to any 32 bit implementations since 83214501Srpauloan 84214501Srpauloint and a long are the same size in those environments. 85214501Srpaulo 86214501Srpaulo-- 87214501SrpauloI also corrected a few compiler warnings generated by Borland C. 88214501Srpaulo1. Added #include <process.h> for exit() prototype 89214501Srpaulo2. Removed unused variable 'j' in SHA1Final 90214501Srpaulo3. Changed exit(0) to return(0) at end of main. 91214501Srpaulo 92214501SrpauloALL changes I made can be located by searching for comments containing 'JHB' 93214501Srpaulo----------------- 94214501SrpauloModified 8/98 95214501SrpauloBy Steve Reid <sreid@sea-to-sky.net> 96214501SrpauloStill 100% public domain 97214501Srpaulo 98214501Srpaulo1- Removed #include <process.h> and used return() instead of exit() 99214501Srpaulo2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) 100214501Srpaulo3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net 101214501Srpaulo 102214501Srpaulo----------------- 103214501SrpauloModified 4/01 104214501SrpauloBy Saul Kravitz <Saul.Kravitz@celera.com> 105214501SrpauloStill 100% PD 106214501SrpauloModified to run on Compaq Alpha hardware. 107214501Srpaulo 108214501Srpaulo----------------- 109214501SrpauloModified 4/01 110214501SrpauloBy Jouni Malinen <j@w1.fi> 111214501SrpauloMinor changes to match the coding style used in Dynamics. 112214501Srpaulo 113214501SrpauloModified September 24, 2004 114214501SrpauloBy Jouni Malinen <j@w1.fi> 115214501SrpauloFixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined. 116214501Srpaulo 117214501Srpaulo*/ 118214501Srpaulo 119214501Srpaulo/* 120214501SrpauloTest Vectors (from FIPS PUB 180-1) 121214501Srpaulo"abc" 122214501Srpaulo A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 123214501Srpaulo"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 124214501Srpaulo 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 125214501SrpauloA million repetitions of "a" 126214501Srpaulo 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 127214501Srpaulo*/ 128214501Srpaulo 129214501Srpaulo#define SHA1HANDSOFF 130214501Srpaulo 131214501Srpaulo#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 132214501Srpaulo 133214501Srpaulo/* blk0() and blk() perform the initial expand. */ 134214501Srpaulo/* I got the idea of expanding during the round function from SSLeay */ 135214501Srpaulo#ifndef WORDS_BIGENDIAN 136214501Srpaulo#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \ 137214501Srpaulo (rol(block->l[i], 8) & 0x00FF00FF)) 138214501Srpaulo#else 139214501Srpaulo#define blk0(i) block->l[i] 140214501Srpaulo#endif 141214501Srpaulo#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \ 142214501Srpaulo block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1)) 143214501Srpaulo 144214501Srpaulo/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 145214501Srpaulo#define R0(v,w,x,y,z,i) \ 146214501Srpaulo z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ 147214501Srpaulo w = rol(w, 30); 148214501Srpaulo#define R1(v,w,x,y,z,i) \ 149214501Srpaulo z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ 150214501Srpaulo w = rol(w, 30); 151214501Srpaulo#define R2(v,w,x,y,z,i) \ 152214501Srpaulo z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30); 153214501Srpaulo#define R3(v,w,x,y,z,i) \ 154214501Srpaulo z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ 155214501Srpaulo w = rol(w, 30); 156214501Srpaulo#define R4(v,w,x,y,z,i) \ 157214501Srpaulo z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ 158214501Srpaulo w=rol(w, 30); 159214501Srpaulo 160214501Srpaulo 161214501Srpaulo#ifdef VERBOSE /* SAK */ 162214501Srpaulovoid SHAPrintContext(SHA1_CTX *context, char *msg) 163214501Srpaulo{ 164214501Srpaulo printf("%s (%d,%d) %x %x %x %x %x\n", 165214501Srpaulo msg, 166214501Srpaulo context->count[0], context->count[1], 167214501Srpaulo context->state[0], 168214501Srpaulo context->state[1], 169214501Srpaulo context->state[2], 170214501Srpaulo context->state[3], 171214501Srpaulo context->state[4]); 172214501Srpaulo} 173214501Srpaulo#endif 174214501Srpaulo 175214501Srpaulo/* Hash a single 512-bit block. This is the core of the algorithm. */ 176214501Srpaulo 177214501Srpaulovoid SHA1Transform(u32 state[5], const unsigned char buffer[64]) 178214501Srpaulo{ 179214501Srpaulo u32 a, b, c, d, e; 180214501Srpaulo typedef union { 181214501Srpaulo unsigned char c[64]; 182214501Srpaulo u32 l[16]; 183214501Srpaulo } CHAR64LONG16; 184214501Srpaulo CHAR64LONG16* block; 185214501Srpaulo#ifdef SHA1HANDSOFF 186214501Srpaulo CHAR64LONG16 workspace; 187214501Srpaulo block = &workspace; 188214501Srpaulo os_memcpy(block, buffer, 64); 189214501Srpaulo#else 190214501Srpaulo block = (CHAR64LONG16 *) buffer; 191214501Srpaulo#endif 192214501Srpaulo /* Copy context->state[] to working vars */ 193214501Srpaulo a = state[0]; 194214501Srpaulo b = state[1]; 195214501Srpaulo c = state[2]; 196214501Srpaulo d = state[3]; 197214501Srpaulo e = state[4]; 198214501Srpaulo /* 4 rounds of 20 operations each. Loop unrolled. */ 199214501Srpaulo 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); 200214501Srpaulo 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); 201214501Srpaulo 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); 202214501Srpaulo 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); 203214501Srpaulo 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); 204214501Srpaulo 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); 205214501Srpaulo 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); 206214501Srpaulo 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); 207214501Srpaulo 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); 208214501Srpaulo 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); 209214501Srpaulo 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); 210214501Srpaulo 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); 211214501Srpaulo 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); 212214501Srpaulo 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); 213214501Srpaulo 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); 214214501Srpaulo 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); 215214501Srpaulo 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); 216214501Srpaulo 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); 217214501Srpaulo 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); 218214501Srpaulo 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); 219214501Srpaulo /* Add the working vars back into context.state[] */ 220214501Srpaulo state[0] += a; 221214501Srpaulo state[1] += b; 222214501Srpaulo state[2] += c; 223214501Srpaulo state[3] += d; 224214501Srpaulo state[4] += e; 225214501Srpaulo /* Wipe variables */ 226214501Srpaulo a = b = c = d = e = 0; 227214501Srpaulo#ifdef SHA1HANDSOFF 228214501Srpaulo os_memset(block, 0, 64); 229214501Srpaulo#endif 230214501Srpaulo} 231214501Srpaulo 232214501Srpaulo 233214501Srpaulo/* SHA1Init - Initialize new context */ 234214501Srpaulo 235214501Srpaulovoid SHA1Init(SHA1_CTX* context) 236214501Srpaulo{ 237214501Srpaulo /* SHA1 initialization constants */ 238214501Srpaulo context->state[0] = 0x67452301; 239214501Srpaulo context->state[1] = 0xEFCDAB89; 240214501Srpaulo context->state[2] = 0x98BADCFE; 241214501Srpaulo context->state[3] = 0x10325476; 242214501Srpaulo context->state[4] = 0xC3D2E1F0; 243214501Srpaulo context->count[0] = context->count[1] = 0; 244214501Srpaulo} 245214501Srpaulo 246214501Srpaulo 247214501Srpaulo/* Run your data through this. */ 248214501Srpaulo 249214501Srpaulovoid SHA1Update(SHA1_CTX* context, const void *_data, u32 len) 250214501Srpaulo{ 251214501Srpaulo u32 i, j; 252214501Srpaulo const unsigned char *data = _data; 253214501Srpaulo 254214501Srpaulo#ifdef VERBOSE 255214501Srpaulo SHAPrintContext(context, "before"); 256214501Srpaulo#endif 257214501Srpaulo j = (context->count[0] >> 3) & 63; 258214501Srpaulo if ((context->count[0] += len << 3) < (len << 3)) 259214501Srpaulo context->count[1]++; 260214501Srpaulo context->count[1] += (len >> 29); 261214501Srpaulo if ((j + len) > 63) { 262214501Srpaulo os_memcpy(&context->buffer[j], data, (i = 64-j)); 263214501Srpaulo SHA1Transform(context->state, context->buffer); 264214501Srpaulo for ( ; i + 63 < len; i += 64) { 265214501Srpaulo SHA1Transform(context->state, &data[i]); 266214501Srpaulo } 267214501Srpaulo j = 0; 268214501Srpaulo } 269214501Srpaulo else i = 0; 270214501Srpaulo os_memcpy(&context->buffer[j], &data[i], len - i); 271214501Srpaulo#ifdef VERBOSE 272214501Srpaulo SHAPrintContext(context, "after "); 273214501Srpaulo#endif 274214501Srpaulo} 275214501Srpaulo 276214501Srpaulo 277214501Srpaulo/* Add padding and return the message digest. */ 278214501Srpaulo 279214501Srpaulovoid SHA1Final(unsigned char digest[20], SHA1_CTX* context) 280214501Srpaulo{ 281214501Srpaulo u32 i; 282214501Srpaulo unsigned char finalcount[8]; 283214501Srpaulo 284214501Srpaulo for (i = 0; i < 8; i++) { 285214501Srpaulo finalcount[i] = (unsigned char) 286214501Srpaulo ((context->count[(i >= 4 ? 0 : 1)] >> 287214501Srpaulo ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ 288214501Srpaulo } 289214501Srpaulo SHA1Update(context, (unsigned char *) "\200", 1); 290214501Srpaulo while ((context->count[0] & 504) != 448) { 291214501Srpaulo SHA1Update(context, (unsigned char *) "\0", 1); 292214501Srpaulo } 293214501Srpaulo SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() 294214501Srpaulo */ 295214501Srpaulo for (i = 0; i < 20; i++) { 296214501Srpaulo digest[i] = (unsigned char) 297214501Srpaulo ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 298214501Srpaulo 255); 299214501Srpaulo } 300214501Srpaulo /* Wipe variables */ 301214501Srpaulo i = 0; 302214501Srpaulo os_memset(context->buffer, 0, 64); 303214501Srpaulo os_memset(context->state, 0, 20); 304214501Srpaulo os_memset(context->count, 0, 8); 305214501Srpaulo os_memset(finalcount, 0, 8); 306214501Srpaulo} 307214501Srpaulo 308214501Srpaulo/* ===== end - public domain SHA1 implementation ===== */ 309