Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/platform/vboot_reference/crypto/sha1.c

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

Powered by Google App Engine
This is Rietveld 408576698