blob: 19891134aae146abbec8d82030a618dc018d57c6 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/* sha.c
2**
3** Copyright 2008, The Android Open Source Project
4**
5** Redistribution and use in source and binary forms, with or without
6** modification, are permitted provided that the following conditions are met:
7** * Redistributions of source code must retain the above copyright
8** notice, this list of conditions and the following disclaimer.
9** * Redistributions in binary form must reproduce the above copyright
10** notice, this list of conditions and the following disclaimer in the
11** documentation and/or other materials provided with the distribution.
12** * Neither the name of Google Inc. nor the names of its contributors may
13** be used to endorse or promote products derived from this software
14** without specific prior written permission.
15**
16** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
17** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#include "sha.h"
29
30
31#include <errno.h>
32#include <fcntl.h>
33#include <unistd.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include "mtk_device_wrap.h"
39
40// Some machines lack byteswap.h and endian.h. These have to use the
41// slower code, even if they're little-endian.
42
43#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
44
45#include <byteswap.h>
46#include <memory.h>
47
48
49
50// This version is about 28% faster than the generic version below,
51// but assumes little-endianness.
52
53static inline uint32_t ror27(uint32_t val) {
54 return (val >> 27) | (val << 5);
55}
56static inline uint32_t ror2(uint32_t val) {
57 return (val >> 2) | (val << 30);
58}
59static inline uint32_t ror31(uint32_t val) {
60 return (val >> 31) | (val << 1);
61}
62
63static void SHA1_Transform(SHA_CTX* ctx) {
64 uint32_t W[80];
65 register uint32_t A, B, C, D, E;
66 int t;
67
68 A = ctx->state[0];
69 B = ctx->state[1];
70 C = ctx->state[2];
71 D = ctx->state[3];
72 E = ctx->state[4];
73
74#define SHA_F1(A,B,C,D,E,t) \
75 E += ror27(A) + \
76 (W[t] = bswap_32(ctx->buf.w[t])) + \
77 (D^(B&(C^D))) + 0x5A827999; \
78 B = ror2(B);
79
80 for (t = 0; t < 15; t += 5) {
81 SHA_F1(A,B,C,D,E,t + 0);
82 SHA_F1(E,A,B,C,D,t + 1);
83 SHA_F1(D,E,A,B,C,t + 2);
84 SHA_F1(C,D,E,A,B,t + 3);
85 SHA_F1(B,C,D,E,A,t + 4);
86 }
87 SHA_F1(A,B,C,D,E,t + 0); // 16th one, t == 15
88
89#undef SHA_F1
90
91#define SHA_F1(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 (D^(B&(C^D))) + 0x5A827999; \
95 B = ror2(B);
96
97 SHA_F1(E,A,B,C,D,t + 1);
98 SHA_F1(D,E,A,B,C,t + 2);
99 SHA_F1(C,D,E,A,B,t + 3);
100 SHA_F1(B,C,D,E,A,t + 4);
101
102#undef SHA_F1
103
104#define SHA_F2(A,B,C,D,E,t) \
105 E += ror27(A) + \
106 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
107 (B^C^D) + 0x6ED9EBA1; \
108 B = ror2(B);
109
110 for (t = 20; t < 40; t += 5) {
111 SHA_F2(A,B,C,D,E,t + 0);
112 SHA_F2(E,A,B,C,D,t + 1);
113 SHA_F2(D,E,A,B,C,t + 2);
114 SHA_F2(C,D,E,A,B,t + 3);
115 SHA_F2(B,C,D,E,A,t + 4);
116 }
117
118#undef SHA_F2
119
120#define SHA_F3(A,B,C,D,E,t) \
121 E += ror27(A) + \
122 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
123 ((B&C)|(D&(B|C))) + 0x8F1BBCDC; \
124 B = ror2(B);
125
126 for (; t < 60; t += 5) {
127 SHA_F3(A,B,C,D,E,t + 0);
128 SHA_F3(E,A,B,C,D,t + 1);
129 SHA_F3(D,E,A,B,C,t + 2);
130 SHA_F3(C,D,E,A,B,t + 3);
131 SHA_F3(B,C,D,E,A,t + 4);
132 }
133
134#undef SHA_F3
135
136#define SHA_F4(A,B,C,D,E,t) \
137 E += ror27(A) + \
138 (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
139 (B^C^D) + 0xCA62C1D6; \
140 B = ror2(B);
141
142 for (; t < 80; t += 5) {
143 SHA_F4(A,B,C,D,E,t + 0);
144 SHA_F4(E,A,B,C,D,t + 1);
145 SHA_F4(D,E,A,B,C,t + 2);
146 SHA_F4(C,D,E,A,B,t + 3);
147 SHA_F4(B,C,D,E,A,t + 4);
148 }
149
150#undef SHA_F4
151
152 ctx->state[0] += A;
153 ctx->state[1] += B;
154 ctx->state[2] += C;
155 ctx->state[3] += D;
156 ctx->state[4] += E;
157}
158
159void SHA_update(SHA_CTX* ctx, const void* data, int len) {
160 int i = ctx->count % sizeof(ctx->buf);
161 const uint8_t* p = (const uint8_t*)data;
162
163 ctx->count += len;
164
165 while (len > sizeof(ctx->buf) - i) {
166 memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i);
167 len -= sizeof(ctx->buf) - i;
168 p += sizeof(ctx->buf) - i;
169 SHA1_Transform(ctx);
170 i = 0;
171 }
172
173 while (len--) {
174 ctx->buf.b[i++] = *p++;
175 if (i == sizeof(ctx->buf)) {
176 SHA1_Transform(ctx);
177 i = 0;
178 }
179 }
180}
181
182
183const uint8_t* SHA_final(SHA_CTX* ctx) {
184 uint64_t cnt = ctx->count * 8;
185 int i;
186
187 SHA_update(ctx, (uint8_t*)"\x80", 1);
188 while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
189 SHA_update(ctx, (uint8_t*)"\0", 1);
190 }
191 for (i = 0; i < 8; ++i) {
192 uint8_t tmp = cnt >> ((7 - i) * 8);
193 SHA_update(ctx, &tmp, 1);
194 }
195
196 for (i = 0; i < 5; i++) {
197 ctx->buf.w[i] = bswap_32(ctx->state[i]);
198 }
199
200 return ctx->buf.b;
201}
202
203#else // #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
204
205#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
206
207static void SHA1_transform(SHA_CTX *ctx) {
208 uint32_t W[80];
209 uint32_t A, B, C, D, E;
210 uint8_t *p = ctx->buf;
211 int t;
212
213 for(t = 0; t < 16; ++t) {
214 uint32_t tmp = *p++ << 24;
215 tmp |= *p++ << 16;
216 tmp |= *p++ << 8;
217 tmp |= *p++;
218 W[t] = tmp;
219 }
220
221 for(; t < 80; t++) {
222 W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
223 }
224
225 A = ctx->state[0];
226 B = ctx->state[1];
227 C = ctx->state[2];
228 D = ctx->state[3];
229 E = ctx->state[4];
230
231 for(t = 0; t < 80; t++) {
232 uint32_t tmp = rol(5,A) + E + W[t];
233
234 if (t < 20)
235 tmp += (D^(B&(C^D))) + 0x5A827999;
236 else if ( t < 40)
237 tmp += (B^C^D) + 0x6ED9EBA1;
238 else if ( t < 60)
239 tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
240 else
241 tmp += (B^C^D) + 0xCA62C1D6;
242
243 E = D;
244 D = C;
245 C = rol(30,B);
246 B = A;
247 A = tmp;
248 }
249
250 ctx->state[0] += A;
251 ctx->state[1] += B;
252 ctx->state[2] += C;
253 ctx->state[3] += D;
254 ctx->state[4] += E;
255}
256
257void SHA_update(SHA_CTX *ctx, const void *data, int len) {
258 int i = ctx->count % sizeof(ctx->buf);
259 const uint8_t* p = (const uint8_t*)data;
260
261 ctx->count += len;
262
263 while (len--) {
264 ctx->buf[i++] = *p++;
265 if (i == sizeof(ctx->buf)) {
266 SHA1_transform(ctx);
267 i = 0;
268 }
269 }
270}
271const uint8_t *SHA_final(SHA_CTX *ctx) {
272 uint8_t *p = ctx->buf;
273 uint64_t cnt = ctx->count * 8;
274 int i;
275
276 SHA_update(ctx, (uint8_t*)"\x80", 1);
277 while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
278 SHA_update(ctx, (uint8_t*)"\0", 1);
279 }
280 for (i = 0; i < 8; ++i) {
281 uint8_t tmp = cnt >> ((7 - i) * 8);
282 SHA_update(ctx, &tmp, 1);
283 }
284
285 for (i = 0; i < 5; i++) {
286 uint32_t tmp = ctx->state[i];
287 *p++ = tmp >> 24;
288 *p++ = tmp >> 16;
289 *p++ = tmp >> 8;
290 *p++ = tmp >> 0;
291 }
292
293 return ctx->buf;
294}
295
296#endif // endianness
297
298void SHA_init(SHA_CTX* ctx) {
299 ctx->state[0] = 0x67452301;
300 ctx->state[1] = 0xEFCDAB89;
301 ctx->state[2] = 0x98BADCFE;
302 ctx->state[3] = 0x10325476;
303 ctx->state[4] = 0xC3D2E1F0;
304 ctx->count = 0;
305}
306
307/* Convenience function */
308const uint8_t* SHA(const void *data, int len, uint8_t *digest) {
309 const uint8_t *p;
310 int i;
311
312 SHA_CTX ctx;
313 SHA_init(&ctx);
314 SHA_update(&ctx, data, len);
315 p = SHA_final(&ctx);
316 for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
317 digest[i] = *p++;
318 }
319 return digest;
320}
321
322#define NAND_PAGE_SIZE 2048
323
324const uint8_t* ROCK_SHA_FILE(int fd_sha, int offset,int totle_size, uint8_t *digest) {
325 const uint8_t *p;
326 int i = 0;
327 //int fd_sha;
328 int size = 0;
329 char data[NAND_PAGE_SIZE];
330
331
332 mtk_device_wrap_seek(fd_sha, offset, SEEK_SET);
333 SHA_CTX ctx;
334 SHA_init(&ctx);
335
336 do {
337 size = mtk_device_wrap_read(fd_sha,data,NAND_PAGE_SIZE);
338 SHA_update(&ctx, data, size);
339 totle_size -= NAND_PAGE_SIZE;
340
341 }while(totle_size>0);
342 p = SHA_final(&ctx);
343 for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
344 digest[i] = *p++;
345 }
346
347
348 return digest;
349}
350
351
352
353
354// Take a string 'str' of 40 hex digits and parse it into the 20
355// byte array 'digest'. 'str' may contain only the digest or be of
356// the form "<digest>:<anything>". Return 0 on success, -1 on any
357// error.
358int ParseSha1(const char* str, uint8_t* digest) {
359 int i;
360 const char* ps = str;
361 uint8_t* pd = digest;
362 for (i = 0; i < SHA_DIGEST_SIZE * 2; ++i, ++ps) {
363 int digit;
364 if (*ps >= '0' && *ps <= '9') {
365 digit = *ps - '0';
366 } else if (*ps >= 'a' && *ps <= 'f') {
367 digit = *ps - 'a' + 10;
368 } else if (*ps >= 'A' && *ps <= 'F') {
369 digit = *ps - 'A' + 10;
370 } else {
371 return -1;
372 }
373 if (i % 2 == 0) {
374 *pd = digit << 4;
375 } else {
376 *pd |= digit;
377 ++pd;
378 }
379 }
380 if (*ps != '\0') return -1;
381 return 0;
382}