1/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * SHA-1 implementation largely based on libmincrypt in the the Android
6 * Open Source Project (platorm/system/core.git/libmincrypt/sha.c
7 */
8
9#include "2sysincludes.h"
10#include "2common.h"
11#include "2sha.h"
12
13/*
14 * Some machines lack byteswap.h and endian.h. These have to use the
15 * slower code, even if they're little-endian.
16 */
17
18#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
19
20/*
21 * This version is about 28% faster than the generic version below,
22 * but assumes little-endianness.
23 */
24static uint32_t ror27(uint32_t val)
25{
26	return (val >> 27) | (val << 5);
27}
28
29static uint32_t ror2(uint32_t val)
30{
31	return (val >> 2) | (val << 30);
32}
33
34static uint32_t ror31(uint32_t val)
35{
36	return (val >> 31) | (val << 1);
37}
38
39static void sha1_transform(struct vb2_sha1_context *ctx)
40{
41	/* Note that this array uses 80*4=320 bytes of stack */
42	uint32_t W[80];
43	register uint32_t A, B, C, D, E;
44	int t;
45
46	A = ctx->state[0];
47	B = ctx->state[1];
48	C = ctx->state[2];
49	D = ctx->state[3];
50	E = ctx->state[4];
51
52#define SHA_F1(A,B,C,D,E,t)				\
53	E += ror27(A) +					\
54		(W[t] = bswap_32(ctx->buf.w[t])) +	\
55		(D^(B&(C^D))) + 0x5A827999;		\
56	B = ror2(B);
57
58	for (t = 0; t < 15; t += 5) {
59		SHA_F1(A,B,C,D,E,t + 0);
60		SHA_F1(E,A,B,C,D,t + 1);
61		SHA_F1(D,E,A,B,C,t + 2);
62		SHA_F1(C,D,E,A,B,t + 3);
63		SHA_F1(B,C,D,E,A,t + 4);
64	}
65	SHA_F1(A,B,C,D,E,t + 0);  /* 16th one, t == 15 */
66
67#undef SHA_F1
68
69#define SHA_F1(A,B,C,D,E,t)						\
70	E += ror27(A) +							\
71		(W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +	\
72		(D^(B&(C^D))) + 0x5A827999;				\
73	B = ror2(B);
74
75	SHA_F1(E,A,B,C,D,t + 1);
76	SHA_F1(D,E,A,B,C,t + 2);
77	SHA_F1(C,D,E,A,B,t + 3);
78	SHA_F1(B,C,D,E,A,t + 4);
79
80#undef SHA_F1
81
82#define SHA_F2(A,B,C,D,E,t)						\
83	E += ror27(A) +							\
84		(W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +	\
85		(B^C^D) + 0x6ED9EBA1;					\
86	B = ror2(B);
87
88	for (t = 20; t < 40; t += 5) {
89		SHA_F2(A,B,C,D,E,t + 0);
90		SHA_F2(E,A,B,C,D,t + 1);
91		SHA_F2(D,E,A,B,C,t + 2);
92		SHA_F2(C,D,E,A,B,t + 3);
93		SHA_F2(B,C,D,E,A,t + 4);
94	}
95
96#undef SHA_F2
97
98#define SHA_F3(A,B,C,D,E,t)						\
99	E += ror27(A) +							\
100		(W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +	\
101		((B&C)|(D&(B|C))) + 0x8F1BBCDC;				\
102	B = ror2(B);
103
104	for (; t < 60; t += 5) {
105		SHA_F3(A,B,C,D,E,t + 0);
106		SHA_F3(E,A,B,C,D,t + 1);
107		SHA_F3(D,E,A,B,C,t + 2);
108		SHA_F3(C,D,E,A,B,t + 3);
109		SHA_F3(B,C,D,E,A,t + 4);
110	}
111
112#undef SHA_F3
113
114#define SHA_F4(A,B,C,D,E,t)						\
115	E += ror27(A) +							\
116		(W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) +	\
117		(B^C^D) + 0xCA62C1D6;					\
118	B = ror2(B);
119
120	for (; t < 80; t += 5) {
121		SHA_F4(A,B,C,D,E,t + 0);
122		SHA_F4(E,A,B,C,D,t + 1);
123		SHA_F4(D,E,A,B,C,t + 2);
124		SHA_F4(C,D,E,A,B,t + 3);
125		SHA_F4(B,C,D,E,A,t + 4);
126	}
127
128#undef SHA_F4
129
130	ctx->state[0] += A;
131	ctx->state[1] += B;
132	ctx->state[2] += C;
133	ctx->state[3] += D;
134	ctx->state[4] += E;
135}
136
137void vb2_sha1_update(struct vb2_sha1_context *ctx,
138		     const uint8_t *data,
139		     uint32_t size)
140{
141	int i = ctx->count % sizeof(ctx->buf);
142	const uint8_t *p = (const uint8_t*)data;
143
144	ctx->count += size;
145
146	while (size > sizeof(ctx->buf) - i) {
147		memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i);
148		size -= sizeof(ctx->buf) - i;
149		p += sizeof(ctx->buf) - i;
150		sha1_transform(ctx);
151		i = 0;
152	}
153
154	while (size--) {
155		ctx->buf.b[i++] = *p++;
156		if (i == sizeof(ctx->buf)) {
157			sha1_transform(ctx);
158			i = 0;
159		}
160	}
161}
162
163uint8_t *vb2_sha1_finalize(struct vb2_sha1_context *ctx)
164{
165	uint32_t cnt = ctx->count * 8;
166	int i;
167
168	vb2_sha1_update(ctx, (uint8_t*)"\x80", 1);
169	while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
170		vb2_sha1_update(ctx, (uint8_t*)"\0", 1);
171	}
172
173	for (i = 0; i < 8; ++i) {
174		uint8_t tmp = cnt >> ((7 - i) * 8);
175		vb2_sha1_update(ctx, &tmp, 1);
176	}
177
178	for (i = 0; i < 5; i++) {
179		ctx->buf.w[i] = bswap_32(ctx->state[i]);
180	}
181
182	return ctx->buf.b;
183}
184
185#else   /* #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN) */
186
187#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
188
189static void sha1_transform(struct vb2_sha1_context *ctx)
190{
191	/* Note that this array uses 80*4=320 bytes of stack */
192	uint32_t W[80];
193	uint32_t A, B, C, D, E;
194	uint8_t *p = ctx->buf;
195	int t;
196
197	for(t = 0; t < 16; ++t) {
198		uint32_t tmp = *p++ << 24;
199		tmp |= *p++ << 16;
200		tmp |= *p++ << 8;
201		tmp |= *p++;
202		W[t] = tmp;
203	}
204
205	for(; t < 80; t++) {
206		W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
207	}
208
209	A = ctx->state[0];
210	B = ctx->state[1];
211	C = ctx->state[2];
212	D = ctx->state[3];
213	E = ctx->state[4];
214
215	for(t = 0; t < 80; t++) {
216		uint32_t tmp = rol(5,A) + E + W[t];
217
218		if (t < 20)
219			tmp += (D^(B&(C^D))) + 0x5A827999;
220		else if ( t < 40)
221			tmp += (B^C^D) + 0x6ED9EBA1;
222		else if ( t < 60)
223			tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
224		else
225			tmp += (B^C^D) + 0xCA62C1D6;
226
227		E = D;
228		D = C;
229		C = rol(30,B);
230		B = A;
231		A = tmp;
232	}
233
234	ctx->state[0] += A;
235	ctx->state[1] += B;
236	ctx->state[2] += C;
237	ctx->state[3] += D;
238	ctx->state[4] += E;
239}
240
241void vb2_sha1_update(struct vb2_sha1_context *ctx,
242		     const uint8_t *data,
243		     uint32_t size)
244{
245	int i = (int)(ctx->count % sizeof(ctx->buf));
246	const uint8_t* p = (const uint8_t*) data;
247
248	ctx->count += size;
249
250	while (size--) {
251		ctx->buf[i++] = *p++;
252		if (i == sizeof(ctx->buf)) {
253			sha1_transform(ctx);
254			i = 0;
255		}
256	}
257}
258
259void vb2_sha1_finalize(struct vb2_sha1_context *ctx, uint8_t *digest)
260{
261	uint32_t cnt = ctx->count << 3;
262	int i;
263
264	vb2_sha1_update(ctx, (uint8_t*)"\x80", 1);
265	while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
266		vb2_sha1_update(ctx, (uint8_t*)"\0", 1);
267	}
268	for (i = 0; i < 8; ++i) {
269		uint8_t tmp = (uint8_t)((uint64_t)cnt >> ((7 - i) * 8));
270		vb2_sha1_update(ctx, &tmp, 1);
271	}
272
273	for (i = 0; i < 5; i++) {
274		uint32_t tmp = ctx->state[i];
275		*digest++ = (uint8_t)(tmp >> 24);
276		*digest++ = (uint8_t)(tmp >> 16);
277		*digest++ = (uint8_t)(tmp >> 8);
278		*digest++ = (uint8_t)(tmp >> 0);
279	}
280}
281
282#endif /* endianness */
283
284void vb2_sha1_init(struct vb2_sha1_context *ctx)
285{
286	ctx->state[0] = 0x67452301;
287	ctx->state[1] = 0xefcdab89;
288	ctx->state[2] = 0x98badcfe;
289	ctx->state[3] = 0x10325476;
290	ctx->state[4] = 0xc3d2e1f0;
291	ctx->count = 0;
292}
293