178acc472SPeter Tyser /*
278acc472SPeter Tyser * Heiko Schocher, DENX Software Engineering, hs@denx.de.
378acc472SPeter Tyser * based on:
478acc472SPeter Tyser * FIPS-180-1 compliant SHA-1 implementation
578acc472SPeter Tyser *
678acc472SPeter Tyser * Copyright (C) 2003-2006 Christophe Devine
778acc472SPeter Tyser *
85b8031ccSTom Rini * SPDX-License-Identifier: LGPL-2.1
978acc472SPeter Tyser */
1078acc472SPeter Tyser /*
1178acc472SPeter Tyser * The SHA-1 standard was published by NIST in 1993.
1278acc472SPeter Tyser *
1378acc472SPeter Tyser * http://www.itl.nist.gov/fipspubs/fip180-1.htm
1478acc472SPeter Tyser */
1578acc472SPeter Tyser
1678acc472SPeter Tyser #ifndef _CRT_SECURE_NO_DEPRECATE
1778acc472SPeter Tyser #define _CRT_SECURE_NO_DEPRECATE 1
1878acc472SPeter Tyser #endif
1978acc472SPeter Tyser
2078acc472SPeter Tyser #ifndef USE_HOSTCC
2178acc472SPeter Tyser #include <common.h>
2278acc472SPeter Tyser #include <linux/string.h>
23*257c8a70SJoseph Chen #include <crypto.h>
2478acc472SPeter Tyser #else
2578acc472SPeter Tyser #include <string.h>
2678acc472SPeter Tyser #endif /* USE_HOSTCC */
2778acc472SPeter Tyser #include <watchdog.h>
282b9912e6SJeroen Hofstee #include <u-boot/sha1.h>
2978acc472SPeter Tyser
3087e494a1SLoic Poulain #include <linux/compiler.h>
3187e494a1SLoic Poulain
3287e494a1SLoic Poulain #ifdef USE_HOSTCC
3387e494a1SLoic Poulain #undef __weak
3487e494a1SLoic Poulain #define __weak
3587e494a1SLoic Poulain #undef __maybe_unused
3687e494a1SLoic Poulain #define __maybe_unused
3787e494a1SLoic Poulain #endif
3887e494a1SLoic Poulain
39da29f299SAndrew Duda const uint8_t sha1_der_prefix[SHA1_DER_LEN] = {
40da29f299SAndrew Duda 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
41da29f299SAndrew Duda 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
42da29f299SAndrew Duda };
43da29f299SAndrew Duda
4478acc472SPeter Tyser /*
4578acc472SPeter Tyser * 32-bit integer manipulation macros (big endian)
4678acc472SPeter Tyser */
4778acc472SPeter Tyser #ifndef GET_UINT32_BE
4878acc472SPeter Tyser #define GET_UINT32_BE(n,b,i) { \
4978acc472SPeter Tyser (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
5078acc472SPeter Tyser | ( (unsigned long) (b)[(i) + 1] << 16 ) \
5178acc472SPeter Tyser | ( (unsigned long) (b)[(i) + 2] << 8 ) \
5278acc472SPeter Tyser | ( (unsigned long) (b)[(i) + 3] ); \
5378acc472SPeter Tyser }
5478acc472SPeter Tyser #endif
5578acc472SPeter Tyser #ifndef PUT_UINT32_BE
5678acc472SPeter Tyser #define PUT_UINT32_BE(n,b,i) { \
5778acc472SPeter Tyser (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
5878acc472SPeter Tyser (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
5978acc472SPeter Tyser (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
6078acc472SPeter Tyser (b)[(i) + 3] = (unsigned char) ( (n) ); \
6178acc472SPeter Tyser }
6278acc472SPeter Tyser #endif
6378acc472SPeter Tyser
6478acc472SPeter Tyser /*
6578acc472SPeter Tyser * SHA-1 context setup
6678acc472SPeter Tyser */
sha1_starts(sha1_context * ctx)6778acc472SPeter Tyser void sha1_starts (sha1_context * ctx)
6878acc472SPeter Tyser {
69*257c8a70SJoseph Chen #if !defined(USE_HOSTCC)
70*257c8a70SJoseph Chen #if !CONFIG_IS_ENABLED(ARMV8_CE_SHA1) && CONFIG_IS_ENABLED(DM_CRYPTO)
71*257c8a70SJoseph Chen sha_context cctx;
72*257c8a70SJoseph Chen u32 algo = CRYPTO_SHA1;
73*257c8a70SJoseph Chen
74*257c8a70SJoseph Chen ctx->cdev = NULL;
75*257c8a70SJoseph Chen if (ctx->length) {
76*257c8a70SJoseph Chen ctx->cdev = crypto_get_device(algo);
77*257c8a70SJoseph Chen if (ctx->cdev) {
78*257c8a70SJoseph Chen cctx.algo = algo;
79*257c8a70SJoseph Chen cctx.length = ctx->length;
80*257c8a70SJoseph Chen crypto_sha_init(ctx->cdev, &cctx);
81*257c8a70SJoseph Chen return;
82*257c8a70SJoseph Chen }
83*257c8a70SJoseph Chen }
84*257c8a70SJoseph Chen #endif
85*257c8a70SJoseph Chen #endif
8678acc472SPeter Tyser ctx->total[0] = 0;
8778acc472SPeter Tyser ctx->total[1] = 0;
8878acc472SPeter Tyser
8978acc472SPeter Tyser ctx->state[0] = 0x67452301;
9078acc472SPeter Tyser ctx->state[1] = 0xEFCDAB89;
9178acc472SPeter Tyser ctx->state[2] = 0x98BADCFE;
9278acc472SPeter Tyser ctx->state[3] = 0x10325476;
9378acc472SPeter Tyser ctx->state[4] = 0xC3D2E1F0;
9478acc472SPeter Tyser }
9578acc472SPeter Tyser
sha1_process_one(sha1_context * ctx,const unsigned char data[64])9687e494a1SLoic Poulain static void __maybe_unused sha1_process_one(sha1_context *ctx, const unsigned char data[64])
9778acc472SPeter Tyser {
9878acc472SPeter Tyser unsigned long temp, W[16], A, B, C, D, E;
9978acc472SPeter Tyser
10078acc472SPeter Tyser GET_UINT32_BE (W[0], data, 0);
10178acc472SPeter Tyser GET_UINT32_BE (W[1], data, 4);
10278acc472SPeter Tyser GET_UINT32_BE (W[2], data, 8);
10378acc472SPeter Tyser GET_UINT32_BE (W[3], data, 12);
10478acc472SPeter Tyser GET_UINT32_BE (W[4], data, 16);
10578acc472SPeter Tyser GET_UINT32_BE (W[5], data, 20);
10678acc472SPeter Tyser GET_UINT32_BE (W[6], data, 24);
10778acc472SPeter Tyser GET_UINT32_BE (W[7], data, 28);
10878acc472SPeter Tyser GET_UINT32_BE (W[8], data, 32);
10978acc472SPeter Tyser GET_UINT32_BE (W[9], data, 36);
11078acc472SPeter Tyser GET_UINT32_BE (W[10], data, 40);
11178acc472SPeter Tyser GET_UINT32_BE (W[11], data, 44);
11278acc472SPeter Tyser GET_UINT32_BE (W[12], data, 48);
11378acc472SPeter Tyser GET_UINT32_BE (W[13], data, 52);
11478acc472SPeter Tyser GET_UINT32_BE (W[14], data, 56);
11578acc472SPeter Tyser GET_UINT32_BE (W[15], data, 60);
11678acc472SPeter Tyser
11778acc472SPeter Tyser #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
11878acc472SPeter Tyser
11978acc472SPeter Tyser #define R(t) ( \
12078acc472SPeter Tyser temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
12178acc472SPeter Tyser W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
12278acc472SPeter Tyser ( W[t & 0x0F] = S(temp,1) ) \
12378acc472SPeter Tyser )
12478acc472SPeter Tyser
12578acc472SPeter Tyser #define P(a,b,c,d,e,x) { \
12678acc472SPeter Tyser e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
12778acc472SPeter Tyser }
12878acc472SPeter Tyser
12978acc472SPeter Tyser A = ctx->state[0];
13078acc472SPeter Tyser B = ctx->state[1];
13178acc472SPeter Tyser C = ctx->state[2];
13278acc472SPeter Tyser D = ctx->state[3];
13378acc472SPeter Tyser E = ctx->state[4];
13478acc472SPeter Tyser
13578acc472SPeter Tyser #define F(x,y,z) (z ^ (x & (y ^ z)))
13678acc472SPeter Tyser #define K 0x5A827999
13778acc472SPeter Tyser
13878acc472SPeter Tyser P (A, B, C, D, E, W[0]);
13978acc472SPeter Tyser P (E, A, B, C, D, W[1]);
14078acc472SPeter Tyser P (D, E, A, B, C, W[2]);
14178acc472SPeter Tyser P (C, D, E, A, B, W[3]);
14278acc472SPeter Tyser P (B, C, D, E, A, W[4]);
14378acc472SPeter Tyser P (A, B, C, D, E, W[5]);
14478acc472SPeter Tyser P (E, A, B, C, D, W[6]);
14578acc472SPeter Tyser P (D, E, A, B, C, W[7]);
14678acc472SPeter Tyser P (C, D, E, A, B, W[8]);
14778acc472SPeter Tyser P (B, C, D, E, A, W[9]);
14878acc472SPeter Tyser P (A, B, C, D, E, W[10]);
14978acc472SPeter Tyser P (E, A, B, C, D, W[11]);
15078acc472SPeter Tyser P (D, E, A, B, C, W[12]);
15178acc472SPeter Tyser P (C, D, E, A, B, W[13]);
15278acc472SPeter Tyser P (B, C, D, E, A, W[14]);
15378acc472SPeter Tyser P (A, B, C, D, E, W[15]);
15478acc472SPeter Tyser P (E, A, B, C, D, R (16));
15578acc472SPeter Tyser P (D, E, A, B, C, R (17));
15678acc472SPeter Tyser P (C, D, E, A, B, R (18));
15778acc472SPeter Tyser P (B, C, D, E, A, R (19));
15878acc472SPeter Tyser
15978acc472SPeter Tyser #undef K
16078acc472SPeter Tyser #undef F
16178acc472SPeter Tyser
16278acc472SPeter Tyser #define F(x,y,z) (x ^ y ^ z)
16378acc472SPeter Tyser #define K 0x6ED9EBA1
16478acc472SPeter Tyser
16578acc472SPeter Tyser P (A, B, C, D, E, R (20));
16678acc472SPeter Tyser P (E, A, B, C, D, R (21));
16778acc472SPeter Tyser P (D, E, A, B, C, R (22));
16878acc472SPeter Tyser P (C, D, E, A, B, R (23));
16978acc472SPeter Tyser P (B, C, D, E, A, R (24));
17078acc472SPeter Tyser P (A, B, C, D, E, R (25));
17178acc472SPeter Tyser P (E, A, B, C, D, R (26));
17278acc472SPeter Tyser P (D, E, A, B, C, R (27));
17378acc472SPeter Tyser P (C, D, E, A, B, R (28));
17478acc472SPeter Tyser P (B, C, D, E, A, R (29));
17578acc472SPeter Tyser P (A, B, C, D, E, R (30));
17678acc472SPeter Tyser P (E, A, B, C, D, R (31));
17778acc472SPeter Tyser P (D, E, A, B, C, R (32));
17878acc472SPeter Tyser P (C, D, E, A, B, R (33));
17978acc472SPeter Tyser P (B, C, D, E, A, R (34));
18078acc472SPeter Tyser P (A, B, C, D, E, R (35));
18178acc472SPeter Tyser P (E, A, B, C, D, R (36));
18278acc472SPeter Tyser P (D, E, A, B, C, R (37));
18378acc472SPeter Tyser P (C, D, E, A, B, R (38));
18478acc472SPeter Tyser P (B, C, D, E, A, R (39));
18578acc472SPeter Tyser
18678acc472SPeter Tyser #undef K
18778acc472SPeter Tyser #undef F
18878acc472SPeter Tyser
18978acc472SPeter Tyser #define F(x,y,z) ((x & y) | (z & (x | y)))
19078acc472SPeter Tyser #define K 0x8F1BBCDC
19178acc472SPeter Tyser
19278acc472SPeter Tyser P (A, B, C, D, E, R (40));
19378acc472SPeter Tyser P (E, A, B, C, D, R (41));
19478acc472SPeter Tyser P (D, E, A, B, C, R (42));
19578acc472SPeter Tyser P (C, D, E, A, B, R (43));
19678acc472SPeter Tyser P (B, C, D, E, A, R (44));
19778acc472SPeter Tyser P (A, B, C, D, E, R (45));
19878acc472SPeter Tyser P (E, A, B, C, D, R (46));
19978acc472SPeter Tyser P (D, E, A, B, C, R (47));
20078acc472SPeter Tyser P (C, D, E, A, B, R (48));
20178acc472SPeter Tyser P (B, C, D, E, A, R (49));
20278acc472SPeter Tyser P (A, B, C, D, E, R (50));
20378acc472SPeter Tyser P (E, A, B, C, D, R (51));
20478acc472SPeter Tyser P (D, E, A, B, C, R (52));
20578acc472SPeter Tyser P (C, D, E, A, B, R (53));
20678acc472SPeter Tyser P (B, C, D, E, A, R (54));
20778acc472SPeter Tyser P (A, B, C, D, E, R (55));
20878acc472SPeter Tyser P (E, A, B, C, D, R (56));
20978acc472SPeter Tyser P (D, E, A, B, C, R (57));
21078acc472SPeter Tyser P (C, D, E, A, B, R (58));
21178acc472SPeter Tyser P (B, C, D, E, A, R (59));
21278acc472SPeter Tyser
21378acc472SPeter Tyser #undef K
21478acc472SPeter Tyser #undef F
21578acc472SPeter Tyser
21678acc472SPeter Tyser #define F(x,y,z) (x ^ y ^ z)
21778acc472SPeter Tyser #define K 0xCA62C1D6
21878acc472SPeter Tyser
21978acc472SPeter Tyser P (A, B, C, D, E, R (60));
22078acc472SPeter Tyser P (E, A, B, C, D, R (61));
22178acc472SPeter Tyser P (D, E, A, B, C, R (62));
22278acc472SPeter Tyser P (C, D, E, A, B, R (63));
22378acc472SPeter Tyser P (B, C, D, E, A, R (64));
22478acc472SPeter Tyser P (A, B, C, D, E, R (65));
22578acc472SPeter Tyser P (E, A, B, C, D, R (66));
22678acc472SPeter Tyser P (D, E, A, B, C, R (67));
22778acc472SPeter Tyser P (C, D, E, A, B, R (68));
22878acc472SPeter Tyser P (B, C, D, E, A, R (69));
22978acc472SPeter Tyser P (A, B, C, D, E, R (70));
23078acc472SPeter Tyser P (E, A, B, C, D, R (71));
23178acc472SPeter Tyser P (D, E, A, B, C, R (72));
23278acc472SPeter Tyser P (C, D, E, A, B, R (73));
23378acc472SPeter Tyser P (B, C, D, E, A, R (74));
23478acc472SPeter Tyser P (A, B, C, D, E, R (75));
23578acc472SPeter Tyser P (E, A, B, C, D, R (76));
23678acc472SPeter Tyser P (D, E, A, B, C, R (77));
23778acc472SPeter Tyser P (C, D, E, A, B, R (78));
23878acc472SPeter Tyser P (B, C, D, E, A, R (79));
23978acc472SPeter Tyser
24078acc472SPeter Tyser #undef K
24178acc472SPeter Tyser #undef F
24278acc472SPeter Tyser
24378acc472SPeter Tyser ctx->state[0] += A;
24478acc472SPeter Tyser ctx->state[1] += B;
24578acc472SPeter Tyser ctx->state[2] += C;
24678acc472SPeter Tyser ctx->state[3] += D;
24778acc472SPeter Tyser ctx->state[4] += E;
24878acc472SPeter Tyser }
24978acc472SPeter Tyser
sha1_process(sha1_context * ctx,const unsigned char * data,unsigned int blocks)25087e494a1SLoic Poulain __weak void sha1_process(sha1_context *ctx, const unsigned char *data,
25187e494a1SLoic Poulain unsigned int blocks)
25287e494a1SLoic Poulain {
25387e494a1SLoic Poulain if (!blocks)
25487e494a1SLoic Poulain return;
25587e494a1SLoic Poulain
25687e494a1SLoic Poulain while (blocks--) {
25787e494a1SLoic Poulain sha1_process_one(ctx, data);
25887e494a1SLoic Poulain data += 64;
25987e494a1SLoic Poulain }
26087e494a1SLoic Poulain }
26187e494a1SLoic Poulain
26278acc472SPeter Tyser /*
26378acc472SPeter Tyser * SHA-1 process buffer
26478acc472SPeter Tyser */
sha1_update(sha1_context * ctx,const unsigned char * input,unsigned int ilen)265a7d1d765SSimon Glass void sha1_update(sha1_context *ctx, const unsigned char *input,
266a7d1d765SSimon Glass unsigned int ilen)
26778acc472SPeter Tyser {
26878acc472SPeter Tyser int fill;
26978acc472SPeter Tyser unsigned long left;
27078acc472SPeter Tyser
27178acc472SPeter Tyser if (ilen <= 0)
27278acc472SPeter Tyser return;
273*257c8a70SJoseph Chen #if !defined(USE_HOSTCC)
274*257c8a70SJoseph Chen #if !CONFIG_IS_ENABLED(ARMV8_CE_SHA1) && CONFIG_IS_ENABLED(DM_CRYPTO)
275*257c8a70SJoseph Chen if (ctx->cdev) {
276*257c8a70SJoseph Chen crypto_sha_update(ctx->cdev, (void *)input, ilen);
277*257c8a70SJoseph Chen return;
278*257c8a70SJoseph Chen }
279*257c8a70SJoseph Chen #endif
280*257c8a70SJoseph Chen #endif
28178acc472SPeter Tyser left = ctx->total[0] & 0x3F;
28278acc472SPeter Tyser fill = 64 - left;
28378acc472SPeter Tyser
28478acc472SPeter Tyser ctx->total[0] += ilen;
28578acc472SPeter Tyser ctx->total[0] &= 0xFFFFFFFF;
28678acc472SPeter Tyser
28778acc472SPeter Tyser if (ctx->total[0] < (unsigned long) ilen)
28878acc472SPeter Tyser ctx->total[1]++;
28978acc472SPeter Tyser
29078acc472SPeter Tyser if (left && ilen >= fill) {
29178acc472SPeter Tyser memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
29287e494a1SLoic Poulain sha1_process(ctx, ctx->buffer, 1);
29378acc472SPeter Tyser input += fill;
29478acc472SPeter Tyser ilen -= fill;
29578acc472SPeter Tyser left = 0;
29678acc472SPeter Tyser }
29778acc472SPeter Tyser
29887e494a1SLoic Poulain sha1_process(ctx, input, ilen / 64);
29987e494a1SLoic Poulain input += ilen / 64 * 64;
30087e494a1SLoic Poulain ilen = ilen % 64;
30178acc472SPeter Tyser
30278acc472SPeter Tyser if (ilen > 0) {
30378acc472SPeter Tyser memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
30478acc472SPeter Tyser }
30578acc472SPeter Tyser }
30678acc472SPeter Tyser
30778acc472SPeter Tyser static const unsigned char sha1_padding[64] = {
30878acc472SPeter Tyser 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30978acc472SPeter Tyser 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31078acc472SPeter Tyser 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31178acc472SPeter Tyser 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
31278acc472SPeter Tyser };
31378acc472SPeter Tyser
31478acc472SPeter Tyser /*
31578acc472SPeter Tyser * SHA-1 final digest
31678acc472SPeter Tyser */
sha1_finish(sha1_context * ctx,unsigned char output[20])31778acc472SPeter Tyser void sha1_finish (sha1_context * ctx, unsigned char output[20])
31878acc472SPeter Tyser {
31978acc472SPeter Tyser unsigned long last, padn;
32078acc472SPeter Tyser unsigned long high, low;
32178acc472SPeter Tyser unsigned char msglen[8];
32278acc472SPeter Tyser
323*257c8a70SJoseph Chen #if !defined(USE_HOSTCC)
324*257c8a70SJoseph Chen #if !CONFIG_IS_ENABLED(ARMV8_CE_SHA1) && CONFIG_IS_ENABLED(DM_CRYPTO)
325*257c8a70SJoseph Chen sha_context cctx;
326*257c8a70SJoseph Chen
327*257c8a70SJoseph Chen if (ctx->cdev) {
328*257c8a70SJoseph Chen cctx.algo = CRYPTO_SHA1;
329*257c8a70SJoseph Chen cctx.length = ctx->length;
330*257c8a70SJoseph Chen crypto_sha_final(ctx->cdev, &cctx, output);
331*257c8a70SJoseph Chen return;
332*257c8a70SJoseph Chen }
333*257c8a70SJoseph Chen #endif
334*257c8a70SJoseph Chen #endif
33578acc472SPeter Tyser high = (ctx->total[0] >> 29)
33678acc472SPeter Tyser | (ctx->total[1] << 3);
33778acc472SPeter Tyser low = (ctx->total[0] << 3);
33878acc472SPeter Tyser
33978acc472SPeter Tyser PUT_UINT32_BE (high, msglen, 0);
34078acc472SPeter Tyser PUT_UINT32_BE (low, msglen, 4);
34178acc472SPeter Tyser
34278acc472SPeter Tyser last = ctx->total[0] & 0x3F;
34378acc472SPeter Tyser padn = (last < 56) ? (56 - last) : (120 - last);
34478acc472SPeter Tyser
34578acc472SPeter Tyser sha1_update (ctx, (unsigned char *) sha1_padding, padn);
34678acc472SPeter Tyser sha1_update (ctx, msglen, 8);
34778acc472SPeter Tyser
34878acc472SPeter Tyser PUT_UINT32_BE (ctx->state[0], output, 0);
34978acc472SPeter Tyser PUT_UINT32_BE (ctx->state[1], output, 4);
35078acc472SPeter Tyser PUT_UINT32_BE (ctx->state[2], output, 8);
35178acc472SPeter Tyser PUT_UINT32_BE (ctx->state[3], output, 12);
35278acc472SPeter Tyser PUT_UINT32_BE (ctx->state[4], output, 16);
35378acc472SPeter Tyser }
35478acc472SPeter Tyser
35578acc472SPeter Tyser /*
35678acc472SPeter Tyser * Output = SHA-1( input buffer )
35778acc472SPeter Tyser */
sha1_csum(const unsigned char * input,unsigned int ilen,unsigned char * output)358a7d1d765SSimon Glass void sha1_csum(const unsigned char *input, unsigned int ilen,
359a7d1d765SSimon Glass unsigned char *output)
36078acc472SPeter Tyser {
36178acc472SPeter Tyser sha1_context ctx;
36278acc472SPeter Tyser
363*257c8a70SJoseph Chen #if !defined(USE_HOSTCC)
364*257c8a70SJoseph Chen #if !CONFIG_IS_ENABLED(ARMV8_CE_SHA1) && CONFIG_IS_ENABLED(DM_CRYPTO)
365*257c8a70SJoseph Chen ctx.length = ilen;
366*257c8a70SJoseph Chen #endif
367*257c8a70SJoseph Chen #endif
36878acc472SPeter Tyser sha1_starts (&ctx);
36978acc472SPeter Tyser sha1_update (&ctx, input, ilen);
37078acc472SPeter Tyser sha1_finish (&ctx, output);
37178acc472SPeter Tyser }
37278acc472SPeter Tyser
37378acc472SPeter Tyser /*
37478acc472SPeter Tyser * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
37578acc472SPeter Tyser * bytes of input processed.
37678acc472SPeter Tyser */
sha1_csum_wd(const unsigned char * input,unsigned int ilen,unsigned char * output,unsigned int chunk_sz)377a7d1d765SSimon Glass void sha1_csum_wd(const unsigned char *input, unsigned int ilen,
378a7d1d765SSimon Glass unsigned char *output, unsigned int chunk_sz)
37978acc472SPeter Tyser {
38078acc472SPeter Tyser sha1_context ctx;
38178acc472SPeter Tyser #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
382a7d1d765SSimon Glass const unsigned char *end, *curr;
38378acc472SPeter Tyser int chunk;
38478acc472SPeter Tyser #endif
385*257c8a70SJoseph Chen #if !defined(USE_HOSTCC)
386*257c8a70SJoseph Chen #if !CONFIG_IS_ENABLED(ARMV8_CE_SHA1) && CONFIG_IS_ENABLED(DM_CRYPTO)
387*257c8a70SJoseph Chen ctx.length = ilen;
388*257c8a70SJoseph Chen #endif
389*257c8a70SJoseph Chen #endif
39078acc472SPeter Tyser sha1_starts (&ctx);
39178acc472SPeter Tyser
39278acc472SPeter Tyser #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
39378acc472SPeter Tyser curr = input;
39478acc472SPeter Tyser end = input + ilen;
39578acc472SPeter Tyser while (curr < end) {
39678acc472SPeter Tyser chunk = end - curr;
39778acc472SPeter Tyser if (chunk > chunk_sz)
39878acc472SPeter Tyser chunk = chunk_sz;
39978acc472SPeter Tyser sha1_update (&ctx, curr, chunk);
40078acc472SPeter Tyser curr += chunk;
40178acc472SPeter Tyser WATCHDOG_RESET ();
40278acc472SPeter Tyser }
40378acc472SPeter Tyser #else
40478acc472SPeter Tyser sha1_update (&ctx, input, ilen);
40578acc472SPeter Tyser #endif
40678acc472SPeter Tyser
40778acc472SPeter Tyser sha1_finish (&ctx, output);
40878acc472SPeter Tyser }
40978acc472SPeter Tyser
41078acc472SPeter Tyser /*
41178acc472SPeter Tyser * Output = HMAC-SHA-1( input buffer, hmac key )
41278acc472SPeter Tyser */
sha1_hmac(const unsigned char * key,int keylen,const unsigned char * input,unsigned int ilen,unsigned char * output)413a7d1d765SSimon Glass void sha1_hmac(const unsigned char *key, int keylen,
414a7d1d765SSimon Glass const unsigned char *input, unsigned int ilen,
415a7d1d765SSimon Glass unsigned char *output)
41678acc472SPeter Tyser {
41778acc472SPeter Tyser int i;
41878acc472SPeter Tyser sha1_context ctx;
41978acc472SPeter Tyser unsigned char k_ipad[64];
42078acc472SPeter Tyser unsigned char k_opad[64];
42178acc472SPeter Tyser unsigned char tmpbuf[20];
42278acc472SPeter Tyser
42378acc472SPeter Tyser memset (k_ipad, 0x36, 64);
42478acc472SPeter Tyser memset (k_opad, 0x5C, 64);
42578acc472SPeter Tyser
42678acc472SPeter Tyser for (i = 0; i < keylen; i++) {
42778acc472SPeter Tyser if (i >= 64)
42878acc472SPeter Tyser break;
42978acc472SPeter Tyser
43078acc472SPeter Tyser k_ipad[i] ^= key[i];
43178acc472SPeter Tyser k_opad[i] ^= key[i];
43278acc472SPeter Tyser }
43378acc472SPeter Tyser
434*257c8a70SJoseph Chen #if !defined(USE_HOSTCC)
435*257c8a70SJoseph Chen #if !CONFIG_IS_ENABLED(ARMV8_CE_SHA1) && CONFIG_IS_ENABLED(DM_CRYPTO)
436*257c8a70SJoseph Chen ctx.length = 64 + ilen;
437*257c8a70SJoseph Chen #endif
438*257c8a70SJoseph Chen #endif
43978acc472SPeter Tyser sha1_starts (&ctx);
44078acc472SPeter Tyser sha1_update (&ctx, k_ipad, 64);
44178acc472SPeter Tyser sha1_update (&ctx, input, ilen);
44278acc472SPeter Tyser sha1_finish (&ctx, tmpbuf);
44378acc472SPeter Tyser
444*257c8a70SJoseph Chen #if !defined(USE_HOSTCC)
445*257c8a70SJoseph Chen #if !CONFIG_IS_ENABLED(ARMV8_CE_SHA1) && CONFIG_IS_ENABLED(DM_CRYPTO)
446*257c8a70SJoseph Chen ctx.length = 64 + 20;
447*257c8a70SJoseph Chen #endif
448*257c8a70SJoseph Chen #endif
44978acc472SPeter Tyser sha1_starts (&ctx);
45078acc472SPeter Tyser sha1_update (&ctx, k_opad, 64);
45178acc472SPeter Tyser sha1_update (&ctx, tmpbuf, 20);
45278acc472SPeter Tyser sha1_finish (&ctx, output);
45378acc472SPeter Tyser
45478acc472SPeter Tyser memset (k_ipad, 0, 64);
45578acc472SPeter Tyser memset (k_opad, 0, 64);
45678acc472SPeter Tyser memset (tmpbuf, 0, 20);
45778acc472SPeter Tyser memset (&ctx, 0, sizeof (sha1_context));
45878acc472SPeter Tyser }
45978acc472SPeter Tyser
46078acc472SPeter Tyser #ifdef SELF_TEST
46178acc472SPeter Tyser /*
46278acc472SPeter Tyser * FIPS-180-1 test vectors
46378acc472SPeter Tyser */
46478acc472SPeter Tyser static const char sha1_test_str[3][57] = {
46578acc472SPeter Tyser {"abc"},
46678acc472SPeter Tyser {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
46778acc472SPeter Tyser {""}
46878acc472SPeter Tyser };
46978acc472SPeter Tyser
47078acc472SPeter Tyser static const unsigned char sha1_test_sum[3][20] = {
47178acc472SPeter Tyser {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
47278acc472SPeter Tyser 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
47378acc472SPeter Tyser {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
47478acc472SPeter Tyser 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
47578acc472SPeter Tyser {0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
47678acc472SPeter Tyser 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
47778acc472SPeter Tyser };
47878acc472SPeter Tyser
47978acc472SPeter Tyser /*
48078acc472SPeter Tyser * Checkup routine
48178acc472SPeter Tyser */
sha1_self_test(void)48278acc472SPeter Tyser int sha1_self_test (void)
48378acc472SPeter Tyser {
48478acc472SPeter Tyser int i, j;
48578acc472SPeter Tyser unsigned char buf[1000];
48678acc472SPeter Tyser unsigned char sha1sum[20];
48778acc472SPeter Tyser sha1_context ctx;
48878acc472SPeter Tyser
48978acc472SPeter Tyser for (i = 0; i < 3; i++) {
49078acc472SPeter Tyser printf (" SHA-1 test #%d: ", i + 1);
49178acc472SPeter Tyser
49278acc472SPeter Tyser sha1_starts (&ctx);
49378acc472SPeter Tyser
49478acc472SPeter Tyser if (i < 2)
49578acc472SPeter Tyser sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
49678acc472SPeter Tyser strlen (sha1_test_str[i]));
49778acc472SPeter Tyser else {
49878acc472SPeter Tyser memset (buf, 'a', 1000);
49978acc472SPeter Tyser for (j = 0; j < 1000; j++)
50078acc472SPeter Tyser sha1_update (&ctx, buf, 1000);
50178acc472SPeter Tyser }
50278acc472SPeter Tyser
50378acc472SPeter Tyser sha1_finish (&ctx, sha1sum);
50478acc472SPeter Tyser
50578acc472SPeter Tyser if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
50678acc472SPeter Tyser printf ("failed\n");
50778acc472SPeter Tyser return (1);
50878acc472SPeter Tyser }
50978acc472SPeter Tyser
51078acc472SPeter Tyser printf ("passed\n");
51178acc472SPeter Tyser }
51278acc472SPeter Tyser
51378acc472SPeter Tyser printf ("\n");
51478acc472SPeter Tyser return (0);
51578acc472SPeter Tyser }
51678acc472SPeter Tyser #else
sha1_self_test(void)51778acc472SPeter Tyser int sha1_self_test (void)
51878acc472SPeter Tyser {
51978acc472SPeter Tyser return (0);
52078acc472SPeter Tyser }
52178acc472SPeter Tyser #endif
522