blob: 41c8317493a7908f2999c15d15be4864af1be776 [file] [log] [blame]
Randall Spanglere166d042014-05-13 09:24:52 -07001/* 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}