18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * SHA-1 in C 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * By Steve Reid <steve@edmweb.com> 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 100% Public Domain 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Test Vectors (from FIPS PUB 180-1) 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * "abc" 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * A million repetitions of "a" 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* #define SHA1HANDSOFF * Copies data before messing with it. */ 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h> 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netinet/in.h> /* htonl() */ 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "sha1.h" 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectSHA1_Transform(u_int32_t[5], const unsigned char[64]); 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* blk0() and blk() perform the initial expand. */ 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* I got the idea of expanding during the round function from SSLeay */ 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define blk0(i) (block->l[i] = htonl(block->l[i])) 318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ^block->l[(i+2)&15]^block->l[i&15],1)) 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Hash a single 512-bit block. This is the core of the algorithm. */ 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectSHA1_Transform(u_int32_t state[5], const unsigned char buffer[64]) 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_int32_t a, b, c, d, e; 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project typedef union { 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char c[64]; 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_int32_t l[16]; 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } CHAR64LONG16; 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CHAR64LONG16 *block; 538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SHA1HANDSOFF 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project static unsigned char workspace[64]; 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project block = (CHAR64LONG16 *) workspace; 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(block, buffer, 64); 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project block = (CHAR64LONG16 *) buffer; 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Copy context->state[] to working vars */ 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project a = state[0]; 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project b = state[1]; 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project c = state[2]; 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project d = state[3]; 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project e = state[4]; 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 4 rounds of 20 operations each. Loop unrolled. */ 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 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); 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Add the working vars back into context.state[] */ 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project state[0] += a; 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project state[1] += b; 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project state[2] += c; 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project state[3] += d; 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project state[4] += e; 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Wipe variables */ 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project a = b = c = d = e = 0; 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* SHA1Init - Initialize new context */ 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectSHA1_Init(SHA1_CTX *context) 1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* SHA1 initialization constants */ 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project context->state[0] = 0x67452301; 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project context->state[1] = 0xEFCDAB89; 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project context->state[2] = 0x98BADCFE; 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project context->state[3] = 0x10325476; 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project context->state[4] = 0xC3D2E1F0; 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project context->count[0] = context->count[1] = 0; 1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Run your data through this. */ 1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectSHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) 1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned int i, j; 1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project j = (context->count[0] >> 3) & 63; 1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; 1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project context->count[1] += (len >> 29); 1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((j + len) > 63) { 1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(&context->buffer[j], data, (i = 64-j)); 1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SHA1_Transform(context->state, context->buffer); 1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for ( ; i + 63 < len; i += 64) { 1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SHA1_Transform(context->state, &data[i]); 1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project j = 0; 1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project i = 0; 1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(&context->buffer[j], &data[i], len - i); 1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Add padding and return the message digest. */ 1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectSHA1_Final(unsigned char digest[20], SHA1_CTX *context) 1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_int32_t i, j; 1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char finalcount[8]; 1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < 8; i++) { 1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] 1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ 1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SHA1_Update(context, (unsigned char *) "\200", 1); 1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while ((context->count[0] & 504) != 448) { 1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SHA1_Update(context, (unsigned char *) "\0", 1); 1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ 1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < 20; i++) { 1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project digest[i] = (unsigned char) 1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); 1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Wipe variables */ 1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project i = j = 0; 1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(context->buffer, 0, 64); 1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(context->state, 0, 20); 1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(context->count, 0, 8); 1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(&finalcount, 0, 8); 1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ 1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SHA1Transform(context->state, context->buffer); 1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 171