• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
ror27(uint32_t val)24 static uint32_t ror27(uint32_t val)
25 {
26 	return (val >> 27) | (val << 5);
27 }
28 
ror2(uint32_t val)29 static uint32_t ror2(uint32_t val)
30 {
31 	return (val >> 2) | (val << 30);
32 }
33 
ror31(uint32_t val)34 static uint32_t ror31(uint32_t val)
35 {
36 	return (val >> 31) | (val << 1);
37 }
38 
sha1_transform(struct vb2_sha1_context * ctx)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 
vb2_sha1_update(struct vb2_sha1_context * ctx,const uint8_t * data,uint32_t size)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 
vb2_sha1_finalize(struct vb2_sha1_context * ctx)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 
sha1_transform(struct vb2_sha1_context * ctx)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 
vb2_sha1_update(struct vb2_sha1_context * ctx,const uint8_t * data,uint32_t size)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 
vb2_sha1_finalize(struct vb2_sha1_context * ctx,uint8_t * digest)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 
vb2_sha1_init(struct vb2_sha1_context * ctx)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 }
293