• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * 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 "sysincludes.h"
10 
11 #include "cryptolib.h"
12 #include "utility.h"
13 
14 
15 /* Some machines lack byteswap.h and endian.h. These have to use the
16  * slower code, even if they're little-endian.
17  */
18 
19 #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
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   return (val >> 27) | (val << 5);
26 }
ror2(uint32_t val)27 static uint32_t ror2(uint32_t val) {
28   return (val >> 2) | (val << 30);
29 }
ror31(uint32_t val)30 static uint32_t ror31(uint32_t val) {
31   return (val >> 31) | (val << 1);
32 }
33 
SHA1_Transform(SHA1_CTX * ctx)34 static void SHA1_Transform(SHA1_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 
SHA1_update(SHA1_CTX * ctx,const uint8_t * data,uint64_t len)130 void SHA1_update(SHA1_CTX* ctx, const uint8_t* data, uint64_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 
SHA1_final(SHA1_CTX * ctx)154 uint8_t* SHA1_final(SHA1_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 
SHA1_transform(SHA1_CTX * ctx)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 
SHA1_update(SHA1_CTX * ctx,const uint8_t * data,uint64_t len)228 void SHA1_update(SHA1_CTX *ctx, const uint8_t *data, uint64_t len) {
229   int i = (int)(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 }
SHA1_final(SHA1_CTX * ctx)242 uint8_t* SHA1_final(SHA1_CTX *ctx) {
243   uint8_t *p = ctx->buf;
244   uint64_t cnt = ctx->count << 3;
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 = (uint8_t)((uint64_t)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++ = (uint8_t)(tmp >> 24);
259     *p++ = (uint8_t)(tmp >> 16);
260     *p++ = (uint8_t)(tmp >> 8);
261     *p++ = (uint8_t)(tmp >> 0);
262   }
263 
264   return ctx->buf;
265 }
266 
267 #endif /* endianness */
268 
SHA1_init(SHA1_CTX * ctx)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 
internal_SHA1(const uint8_t * data,uint64_t len,uint8_t * digest)278 uint8_t* internal_SHA1(const uint8_t *data, uint64_t 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 }
290