41c8317493a7908f2999c15d15be4864af1be776
[akaros.git] / kern / lib / crypto / 2sha1.c
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  */
24 static uint32_t ror27(uint32_t val)
25 {
26         return (val >> 27) | (val << 5);
27 }
28
29 static uint32_t ror2(uint32_t val)
30 {
31         return (val >> 2) | (val << 30);
32 }
33
34 static uint32_t ror31(uint32_t val)
35 {
36         return (val >> 31) | (val << 1);
37 }
38
39 static 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
137 void 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
163 uint8_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
189 static 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
241 void 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
259 void 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
284 void 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 }