1285031Sdes/*	$OpenBSD: sha1.c,v 1.23 2014/01/08 06:14:57 tedu Exp $	*/
2285031Sdes
3285031Sdes/*
4285031Sdes * SHA-1 in C
5285031Sdes * By Steve Reid <steve@edmweb.com>
6285031Sdes * 100% Public Domain
7285031Sdes *
8285031Sdes * Test Vectors (from FIPS PUB 180-1)
9285031Sdes * "abc"
10285031Sdes *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
11285031Sdes * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
12285031Sdes *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
13285031Sdes * A million repetitions of "a"
14285031Sdes *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
15285031Sdes */
16285031Sdes
17285031Sdes#include "includes.h"
18285031Sdes
19285031Sdes#ifndef WITH_OPENSSL
20285031Sdes
21285031Sdes#include <sys/param.h>
22285031Sdes#include <string.h>
23285031Sdes
24285031Sdes#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
25285031Sdes
26285031Sdes/*
27285031Sdes * blk0() and blk() perform the initial expand.
28285031Sdes * I got the idea of expanding during the round function from SSLeay
29285031Sdes */
30285031Sdes#if BYTE_ORDER == LITTLE_ENDIAN
31285031Sdes# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
32285031Sdes    |(rol(block->l[i],8)&0x00FF00FF))
33285031Sdes#else
34285031Sdes# define blk0(i) block->l[i]
35285031Sdes#endif
36285031Sdes#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
37285031Sdes    ^block->l[(i+2)&15]^block->l[i&15],1))
38285031Sdes
39285031Sdes/*
40285031Sdes * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
41285031Sdes */
42285031Sdes#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
43285031Sdes#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
44285031Sdes#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
45285031Sdes#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
46285031Sdes#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
47285031Sdes
48285031Sdestypedef union {
49285031Sdes	u_int8_t c[64];
50285031Sdes	u_int32_t l[16];
51285031Sdes} CHAR64LONG16;
52285031Sdes
53285031Sdes/*
54285031Sdes * Hash a single 512-bit block. This is the core of the algorithm.
55285031Sdes */
56285031Sdesvoid
57285031SdesSHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH])
58285031Sdes{
59285031Sdes	u_int32_t a, b, c, d, e;
60285031Sdes	u_int8_t workspace[SHA1_BLOCK_LENGTH];
61285031Sdes	CHAR64LONG16 *block = (CHAR64LONG16 *)workspace;
62285031Sdes
63285031Sdes	(void)memcpy(block, buffer, SHA1_BLOCK_LENGTH);
64285031Sdes
65285031Sdes	/* Copy context->state[] to working vars */
66285031Sdes	a = state[0];
67285031Sdes	b = state[1];
68285031Sdes	c = state[2];
69285031Sdes	d = state[3];
70285031Sdes	e = state[4];
71285031Sdes
72285031Sdes	/* 4 rounds of 20 operations each. Loop unrolled. */
73285031Sdes	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);
74285031Sdes	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);
75285031Sdes	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);
76285031Sdes	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);
77285031Sdes	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);
78285031Sdes	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);
79285031Sdes	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);
80285031Sdes	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);
81285031Sdes	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);
82285031Sdes	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);
83285031Sdes	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);
84285031Sdes	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);
85285031Sdes	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);
86285031Sdes	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);
87285031Sdes	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);
88285031Sdes	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);
89285031Sdes	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);
90285031Sdes	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);
91285031Sdes	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);
92285031Sdes	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);
93285031Sdes
94285031Sdes	/* Add the working vars back into context.state[] */
95285031Sdes	state[0] += a;
96285031Sdes	state[1] += b;
97285031Sdes	state[2] += c;
98285031Sdes	state[3] += d;
99285031Sdes	state[4] += e;
100285031Sdes
101285031Sdes	/* Wipe variables */
102285031Sdes	a = b = c = d = e = 0;
103285031Sdes}
104285031Sdes
105285031Sdes
106285031Sdes/*
107285031Sdes * SHA1Init - Initialize new context
108285031Sdes */
109285031Sdesvoid
110285031SdesSHA1Init(SHA1_CTX *context)
111285031Sdes{
112285031Sdes
113285031Sdes	/* SHA1 initialization constants */
114285031Sdes	context->count = 0;
115285031Sdes	context->state[0] = 0x67452301;
116285031Sdes	context->state[1] = 0xEFCDAB89;
117285031Sdes	context->state[2] = 0x98BADCFE;
118285031Sdes	context->state[3] = 0x10325476;
119285031Sdes	context->state[4] = 0xC3D2E1F0;
120285031Sdes}
121285031Sdes
122285031Sdes
123285031Sdes/*
124285031Sdes * Run your data through this.
125285031Sdes */
126285031Sdesvoid
127285031SdesSHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len)
128285031Sdes{
129285031Sdes	size_t i, j;
130285031Sdes
131285031Sdes	j = (size_t)((context->count >> 3) & 63);
132285031Sdes	context->count += (len << 3);
133285031Sdes	if ((j + len) > 63) {
134285031Sdes		(void)memcpy(&context->buffer[j], data, (i = 64-j));
135285031Sdes		SHA1Transform(context->state, context->buffer);
136285031Sdes		for ( ; i + 63 < len; i += 64)
137285031Sdes			SHA1Transform(context->state, (u_int8_t *)&data[i]);
138285031Sdes		j = 0;
139285031Sdes	} else {
140285031Sdes		i = 0;
141285031Sdes	}
142285031Sdes	(void)memcpy(&context->buffer[j], &data[i], len - i);
143285031Sdes}
144285031Sdes
145285031Sdes
146285031Sdes/*
147285031Sdes * Add padding and return the message digest.
148285031Sdes */
149285031Sdesvoid
150285031SdesSHA1Pad(SHA1_CTX *context)
151285031Sdes{
152285031Sdes	u_int8_t finalcount[8];
153285031Sdes	u_int i;
154285031Sdes
155285031Sdes	for (i = 0; i < 8; i++) {
156285031Sdes		finalcount[i] = (u_int8_t)((context->count >>
157285031Sdes		    ((7 - (i & 7)) * 8)) & 255);	/* Endian independent */
158285031Sdes	}
159285031Sdes	SHA1Update(context, (u_int8_t *)"\200", 1);
160285031Sdes	while ((context->count & 504) != 448)
161285031Sdes		SHA1Update(context, (u_int8_t *)"\0", 1);
162285031Sdes	SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
163285031Sdes}
164285031Sdes
165285031Sdesvoid
166285031SdesSHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
167285031Sdes{
168285031Sdes	u_int i;
169285031Sdes
170285031Sdes	SHA1Pad(context);
171285031Sdes	for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
172285031Sdes		digest[i] = (u_int8_t)
173285031Sdes		   ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
174285031Sdes	}
175285031Sdes	memset(context, 0, sizeof(*context));
176285031Sdes}
177285031Sdes#endif /* !WITH_OPENSSL */
178