blob: 121467437a01d61b73008b5780c99afc3db4dd41 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
4 * Copyright (C) 2001-2003 Christophe Devine
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9#ifndef USE_HOSTCC
10#include <common.h>
11#endif /* USE_HOSTCC */
12#include <watchdog.h>
13#include <linux/string.h>
14#include <sha256.h>
15
16asmlinkage int neon_en_check(void);
17asmlinkage void neon_enable(void);
18asmlinkage void neon_disable(void);
19asmlinkage void sha256_transform_neon(u32 *digest, const void *data,
20 unsigned int num_blks);
21
22/*
23 * 32-bit integer manipulation macros (big endian)
24 */
25#ifndef PUT_UINT32_BE
26#define PUT_UINT32_BE(n,b,i) { \
27 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
28 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
29 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
30 (b)[(i) + 3] = (unsigned char) ( (n) ); \
31}
32#endif
33
34void sha256_starts_neon(sha256_context * ctx)
35{
36 ctx->total[0] = 0;
37 ctx->total[1] = 0;
38
39 ctx->state[0] = 0x6A09E667;
40 ctx->state[1] = 0xBB67AE85;
41 ctx->state[2] = 0x3C6EF372;
42 ctx->state[3] = 0xA54FF53A;
43 ctx->state[4] = 0x510E527F;
44 ctx->state[5] = 0x9B05688C;
45 ctx->state[6] = 0x1F83D9AB;
46 ctx->state[7] = 0x5BE0CD19;
47}
48
49static inline void sha256_process(sha256_context *ctx,
50 const uint8_t *data, uint32_t blks)
51{
52 int neon_en = neon_en_check();
53
54 if (!neon_en)
55 neon_enable();
56
57 sha256_transform_neon(ctx->state, data, blks);
58
59 if (!neon_en)
60 neon_disable();
61}
62
63void sha256_update_neon(sha256_context *ctx, const uint8_t *input, uint32_t length)
64{
65 uint32_t left, fill;
66 uint32_t blks;
67
68 if (!length)
69 return;
70
71 left = ctx->total[0] & 0x3F;
72 fill = 64 - left;
73
74 ctx->total[0] += length;
75 ctx->total[0] &= 0xFFFFFFFF;
76
77 if (ctx->total[0] < length)
78 ctx->total[1]++;
79
80 if (left && length >= fill) {
81 memcpy((void *) (ctx->buffer + left), (void *) input, fill);
82 sha256_process(ctx, ctx->buffer, 1);
83 length -= fill;
84 input += fill;
85 left = 0;
86 }
87
88 blks = length / 64;
89 while (length >= 64) {
90 sha256_process(ctx, input, blks);
91 length -= 64 * blks;
92 input += 64 * blks;
93 }
94
95 if (length)
96 memcpy((void *) (ctx->buffer + left), (void *) input, length);
97}
98
99static uint8_t sha256_padding[64] = {
100 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
104};
105
106void sha256_finish_neon(sha256_context * ctx, uint8_t digest[32])
107{
108 uint32_t last, padn;
109 uint32_t high, low;
110 uint8_t msglen[8];
111
112 high = ((ctx->total[0] >> 29)
113 | (ctx->total[1] << 3));
114 low = (ctx->total[0] << 3);
115
116 PUT_UINT32_BE(high, msglen, 0);
117 PUT_UINT32_BE(low, msglen, 4);
118
119 last = ctx->total[0] & 0x3F;
120 padn = (last < 56) ? (56 - last) : (120 - last);
121
122 sha256_update(ctx, sha256_padding, padn);
123 sha256_update(ctx, msglen, 8);
124
125 PUT_UINT32_BE(ctx->state[0], digest, 0);
126 PUT_UINT32_BE(ctx->state[1], digest, 4);
127 PUT_UINT32_BE(ctx->state[2], digest, 8);
128 PUT_UINT32_BE(ctx->state[3], digest, 12);
129 PUT_UINT32_BE(ctx->state[4], digest, 16);
130 PUT_UINT32_BE(ctx->state[5], digest, 20);
131 PUT_UINT32_BE(ctx->state[6], digest, 24);
132 PUT_UINT32_BE(ctx->state[7], digest, 28);
133}