1b8e80941Smrg/* $OpenBSD: sha1.c,v 1.26 2015/09/11 09:18:27 guenther Exp $ */ 2b8e80941Smrg 3b8e80941Smrg/* 4b8e80941Smrg * SHA-1 in C 5b8e80941Smrg * By Steve Reid <steve@edmweb.com> 6b8e80941Smrg * 100% Public Domain 7b8e80941Smrg * 8b8e80941Smrg * Test Vectors (from FIPS PUB 180-1) 9b8e80941Smrg * "abc" 10b8e80941Smrg * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 11b8e80941Smrg * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 12b8e80941Smrg * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 13b8e80941Smrg * A million repetitions of "a" 14b8e80941Smrg * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 15b8e80941Smrg */ 16b8e80941Smrg 17b8e80941Smrg#include <stdint.h> 18b8e80941Smrg#include <string.h> 19b8e80941Smrg#include "u_endian.h" 20b8e80941Smrg#include "sha1.h" 21b8e80941Smrg 22b8e80941Smrg#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 23b8e80941Smrg 24b8e80941Smrg/* 25b8e80941Smrg * blk0() and blk() perform the initial expand. 26b8e80941Smrg * I got the idea of expanding during the round function from SSLeay 27b8e80941Smrg */ 28b8e80941Smrg#ifdef PIPE_ARCH_LITTLE_ENDIAN 29b8e80941Smrg# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ 30b8e80941Smrg |(rol(block->l[i],8)&0x00FF00FF)) 31b8e80941Smrg#else 32b8e80941Smrg# define blk0(i) block->l[i] 33b8e80941Smrg#endif 34b8e80941Smrg#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 35b8e80941Smrg ^block->l[(i+2)&15]^block->l[i&15],1)) 36b8e80941Smrg 37b8e80941Smrg/* 38b8e80941Smrg * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 39b8e80941Smrg */ 40b8e80941Smrg#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 41b8e80941Smrg#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 42b8e80941Smrg#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 43b8e80941Smrg#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 44b8e80941Smrg#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 45b8e80941Smrg 46b8e80941Smrgtypedef union { 47b8e80941Smrg uint8_t c[64]; 48b8e80941Smrg uint32_t l[16]; 49b8e80941Smrg} CHAR64LONG16; 50b8e80941Smrg 51b8e80941Smrg/* 52b8e80941Smrg * Hash a single 512-bit block. This is the core of the algorithm. 53b8e80941Smrg */ 54b8e80941Smrgvoid 55b8e80941SmrgSHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_LENGTH]) 56b8e80941Smrg{ 57b8e80941Smrg uint32_t a, b, c, d, e; 58b8e80941Smrg uint8_t workspace[SHA1_BLOCK_LENGTH]; 59b8e80941Smrg CHAR64LONG16 *block = (CHAR64LONG16 *)workspace; 60b8e80941Smrg 61b8e80941Smrg (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH); 62b8e80941Smrg 63b8e80941Smrg /* Copy context->state[] to working vars */ 64b8e80941Smrg a = state[0]; 65b8e80941Smrg b = state[1]; 66b8e80941Smrg c = state[2]; 67b8e80941Smrg d = state[3]; 68b8e80941Smrg e = state[4]; 69b8e80941Smrg 70b8e80941Smrg /* 4 rounds of 20 operations each. Loop unrolled. */ 71b8e80941Smrg 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); 72b8e80941Smrg 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); 73b8e80941Smrg 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); 74b8e80941Smrg 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); 75b8e80941Smrg 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); 76b8e80941Smrg 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); 77b8e80941Smrg 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); 78b8e80941Smrg 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); 79b8e80941Smrg 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); 80b8e80941Smrg 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); 81b8e80941Smrg 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); 82b8e80941Smrg 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); 83b8e80941Smrg 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); 84b8e80941Smrg 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); 85b8e80941Smrg 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); 86b8e80941Smrg 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); 87b8e80941Smrg 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); 88b8e80941Smrg 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); 89b8e80941Smrg 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); 90b8e80941Smrg 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); 91b8e80941Smrg 92b8e80941Smrg /* Add the working vars back into context.state[] */ 93b8e80941Smrg state[0] += a; 94b8e80941Smrg state[1] += b; 95b8e80941Smrg state[2] += c; 96b8e80941Smrg state[3] += d; 97b8e80941Smrg state[4] += e; 98b8e80941Smrg 99b8e80941Smrg /* Wipe variables */ 100b8e80941Smrg a = b = c = d = e = 0; 101b8e80941Smrg} 102b8e80941Smrg 103b8e80941Smrg 104b8e80941Smrg/* 105b8e80941Smrg * SHA1Init - Initialize new context 106b8e80941Smrg */ 107b8e80941Smrgvoid 108b8e80941SmrgSHA1Init(SHA1_CTX *context) 109b8e80941Smrg{ 110b8e80941Smrg 111b8e80941Smrg /* SHA1 initialization constants */ 112b8e80941Smrg context->count = 0; 113b8e80941Smrg context->state[0] = 0x67452301; 114b8e80941Smrg context->state[1] = 0xEFCDAB89; 115b8e80941Smrg context->state[2] = 0x98BADCFE; 116b8e80941Smrg context->state[3] = 0x10325476; 117b8e80941Smrg context->state[4] = 0xC3D2E1F0; 118b8e80941Smrg} 119b8e80941Smrg 120b8e80941Smrg 121b8e80941Smrg/* 122b8e80941Smrg * Run your data through this. 123b8e80941Smrg */ 124b8e80941Smrgvoid 125b8e80941SmrgSHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len) 126b8e80941Smrg{ 127b8e80941Smrg size_t i, j; 128b8e80941Smrg 129b8e80941Smrg j = (size_t)((context->count >> 3) & 63); 130b8e80941Smrg context->count += (len << 3); 131b8e80941Smrg if ((j + len) > 63) { 132b8e80941Smrg (void)memcpy(&context->buffer[j], data, (i = 64-j)); 133b8e80941Smrg SHA1Transform(context->state, context->buffer); 134b8e80941Smrg for ( ; i + 63 < len; i += 64) 135b8e80941Smrg SHA1Transform(context->state, (uint8_t *)&data[i]); 136b8e80941Smrg j = 0; 137b8e80941Smrg } else { 138b8e80941Smrg i = 0; 139b8e80941Smrg } 140b8e80941Smrg (void)memcpy(&context->buffer[j], &data[i], len - i); 141b8e80941Smrg} 142b8e80941Smrg 143b8e80941Smrg 144b8e80941Smrg/* 145b8e80941Smrg * Add padding and return the message digest. 146b8e80941Smrg */ 147b8e80941Smrgvoid 148b8e80941SmrgSHA1Pad(SHA1_CTX *context) 149b8e80941Smrg{ 150b8e80941Smrg uint8_t finalcount[8]; 151b8e80941Smrg uint32_t i; 152b8e80941Smrg 153b8e80941Smrg for (i = 0; i < 8; i++) { 154b8e80941Smrg finalcount[i] = (uint8_t)((context->count >> 155b8e80941Smrg ((7 - (i & 7)) * 8)) & 255); /* Endian independent */ 156b8e80941Smrg } 157b8e80941Smrg SHA1Update(context, (uint8_t *)"\200", 1); 158b8e80941Smrg while ((context->count & 504) != 448) 159b8e80941Smrg SHA1Update(context, (uint8_t *)"\0", 1); 160b8e80941Smrg SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ 161b8e80941Smrg} 162b8e80941Smrg 163b8e80941Smrgvoid 164b8e80941SmrgSHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) 165b8e80941Smrg{ 166b8e80941Smrg uint32_t i; 167b8e80941Smrg 168b8e80941Smrg SHA1Pad(context); 169b8e80941Smrg for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { 170b8e80941Smrg digest[i] = (uint8_t) 171b8e80941Smrg ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); 172b8e80941Smrg } 173b8e80941Smrg memset(context, 0, sizeof(*context)); 174b8e80941Smrg} 175