1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <string.h>
17 #include "log.h"
18 #include "utils.h"
19 #include "sha256.h"
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 /* right rotate */
26 #define FILLP_ROTR32(_x, _n) (((_x) >> (_n)) | ((_x) << (32 - (_n))))
27 /* byte endian swap */
28 #define FILLP_SWAP32(_x) ((FILLP_ROTR32((_x), 24) & 0x00ff00ff) | (FILLP_ROTR32((_x), 8) & 0xff00ff00))
29
30 #ifdef FILLP_LITTLE_ENDIAN
31 #define FILLP_SWAP_32_ARRAY(_array, _arySize) \
32 do { \
33 FILLP_UINT32 _index = (_arySize); \
34 FILLP_UINT32 *_arrayPtr = (FILLP_UINT32 *)(_array); \
35 while (_index--) { \
36 _arrayPtr[_index] = FILLP_SWAP32(_arrayPtr[_index]); \
37 } \
38 } while (0)
39 #else
40 #define FILLP_SWAP_32_ARRAY(_array, _arySize)
41 #endif
42
43 #define FILLP_SHA256_MASK (FILLP_SHA256_BLOCK_SIZE - 1)
44
45 #define FILLP_CH(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
46 #define FILLP_MAJ(x, y, z) (((x) & (y)) | ((z) & ((x) ^ (y))))
47
48 /* round transforms for SHA256 and SHA512 compression functions */
49 #define FILLP_S_0(x) (FILLP_ROTR32((x), 2) ^ FILLP_ROTR32((x), 13) ^ FILLP_ROTR32((x), 22))
50 #define FILLP_S_1(x) (FILLP_ROTR32((x), 6) ^ FILLP_ROTR32((x), 11) ^ FILLP_ROTR32((x), 25))
51 #define FILLP_G_0(x) (FILLP_ROTR32((x), 7) ^ FILLP_ROTR32((x), 18) ^ ((x) >> 3))
52 #define FILLP_G_1(x) (FILLP_ROTR32((x), 17) ^ FILLP_ROTR32((x), 19) ^ ((x) >> 10))
53
54 #define FILLP_G_K256_ARRAY_SZ 64
55 #define FILLP_HASH_ARRAY_SZ 8
56 #define FILLP_HASH_ARRAY_SZ_MOD 7
57 #define FILLP_SHAWK_ARRAY_SZ 16
58 #define FILLP_SHAWK_ARRAY_SZ_MOD 15
59 #define FILLP_SHA_TWO_PAR 2
60 #define FILLP_SHA_THREE_PAR 3
61 #define FILLP_SHA_FOUR_PAR 4
62 #define FILLP_SHA_FIVE_PAR 5
63 #define FILLP_SHA_SIX_PAR 6
64 #define FILLP_SHA_SEVEN_PAR 7
65 #define FILLP_SHA_EIGHT_PAR 8
66 #define FILLP_SHA_NINE_PAR 9
67 #define FILLP_SHA_FOURTEEN_PAR 14
68 #define FILLP_SHA_FIVETEEN_PAR 15
69 #define FILLP_SHA_29_PAR 29
70 #define FILLP_SHA_60_PAR 60
71 /* SHA256 mixing data, used to mix with data to create SHA256 key. */
72 static const FILLP_UINT32 g_k256[FILLP_G_K256_ARRAY_SZ] = {
73 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
74 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
75 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
76 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
77 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
78 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
79 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
80 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
81 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
82 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
83 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
84 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
85 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
86 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
87 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
88 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
89 };
90
91 /* initial data for SHA256 digest calculation */
92 static const FILLP_UINT32 g_i256[FILLP_HASH_ARRAY_SZ] = {
93 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
94 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
95 };
96
97 /* ===========================================================================*\
98 Function :FillpSha256Compile
99 Description : This function generates the digest value for SHA256.
100 sCompile 64 bytes of hash data into SHA256 digest value
101 Parameters :
102 ctx[1]
103 Note : this routine assumes that the byte order in the
104 ctx->wbuf[] at this point is such that low address bytes in
105 the ORIGINAL byte stream will go into the high end of
106 words on BOTH big and little endian systems.
107 \*=========================================================================== */
FillpSha256Compile(FillpSha256Ctx ctx[1])108 static void FillpSha256Compile(FillpSha256Ctx ctx[1])
109 {
110 FILLP_UINT32 jdex;
111 FILLP_UINT32 index;
112 FILLP_UINT32 key0;
113 FILLP_UINT32 key1;
114 FILLP_UINT32 key2;
115 FILLP_UINT32 key3;
116 FILLP_UINT32 *buf = ctx->wbuf;
117 FILLP_UINT32 hash[FILLP_HASH_ARRAY_SZ];
118
119 FillpErrorType err = memcpy_s(hash, sizeof(hash), ctx->hash, sizeof(ctx->hash));
120 if (err != EOK) {
121 FILLP_LOGERR("FillpSha256Compile memcpy_s hash failed : %d", err);
122 return;
123 }
124
125 for (jdex = 0; jdex < FILLP_G_K256_ARRAY_SZ; jdex += FILLP_SHAWK_ARRAY_SZ) {
126 for (index = 0; index < FILLP_SHAWK_ARRAY_SZ; index++) {
127 if (jdex > 0) {
128 key0 = ((FILLP_UINT32)(index + FILLP_SHA_FOURTEEN_PAR)) & FILLP_SHAWK_ARRAY_SZ_MOD;
129 key1 = ((FILLP_UINT32)(index + FILLP_SHA_NINE_PAR)) & FILLP_SHAWK_ARRAY_SZ_MOD;
130 key2 = ((FILLP_UINT32)(index + 1)) & FILLP_SHAWK_ARRAY_SZ_MOD;
131 key3 = index & FILLP_SHA_FIVETEEN_PAR;
132 buf[key3] += FILLP_G_1(buf[key0]) + buf[key1] + FILLP_G_0(buf[key2]);
133 } else {
134 key3 = index;
135 }
136
137 key0 = ((FILLP_UINT32)(FILLP_SHA_SEVEN_PAR - index)) & FILLP_HASH_ARRAY_SZ_MOD;
138 hash[key0] += buf[key3];
139
140 key1 = index + jdex;
141 hash[key0] += g_k256[key1];
142
143 key1 = ((FILLP_UINT32)(FILLP_SHA_FOUR_PAR - index)) & FILLP_HASH_ARRAY_SZ_MOD;
144 hash[key0] += FILLP_S_1(hash[key1]);
145
146 key2 = ((FILLP_UINT32)(FILLP_SHA_FIVE_PAR - index)) & FILLP_HASH_ARRAY_SZ_MOD;
147 key3 = ((FILLP_UINT32)(FILLP_SHA_SIX_PAR - index)) & FILLP_HASH_ARRAY_SZ_MOD;
148 hash[key0] += FILLP_CH(hash[key1], hash[key2], hash[key3]);
149
150 key1 = ((FILLP_UINT32)(FILLP_SHA_THREE_PAR - index)) & FILLP_HASH_ARRAY_SZ_MOD;
151 hash[key1] += hash[key0];
152
153 key1 = ((FILLP_UINT32)(0 - index)) & FILLP_HASH_ARRAY_SZ_MOD;
154 hash[key0] += FILLP_S_0(hash[key1]);
155
156 key2 = ((FILLP_UINT32)(1 - index)) & FILLP_HASH_ARRAY_SZ_MOD;
157 key3 = ((FILLP_UINT32)(FILLP_SHA_TWO_PAR - index)) & FILLP_HASH_ARRAY_SZ_MOD;
158 hash[key0] += FILLP_MAJ(hash[key1], hash[key2], hash[key3]);
159 }
160 }
161
162 /* update the context */
163 for (jdex = 0; jdex < FILLP_HASH_ARRAY_SZ; jdex++) {
164 ctx->hash[jdex] += hash[jdex];
165 }
166 }
167
FillpSha256Set(FillpSha256Ctx ctx[1])168 void FillpSha256Set(FillpSha256Ctx ctx[1])
169 {
170 ctx->count[0] = 0;
171 ctx->count[1] = 0;
172 FillpErrorType err = memcpy_s(ctx->hash, sizeof(ctx->hash), g_i256, sizeof(g_i256));
173 if (err != EOK) {
174 FILLP_LOGERR("FillpSha256Set memcpy_s hash failed : %d", err);
175 }
176 }
177
178
FillpSha256Upd(FillpSha256Ctx ctx[1],const FILLP_UINT8 data[],size_t len)179 void FillpSha256Upd(FillpSha256Ctx ctx[1], const FILLP_UINT8 data[], size_t len)
180 {
181 FILLP_UINT32 offset = (FILLP_UINT32)(ctx->count[0] & FILLP_SHA256_MASK);
182 FILLP_UINT32 freeSize = FILLP_SHA256_BLOCK_SIZE - offset;
183 const FILLP_UINT8 *dataPtr = data;
184 FillpErrorType err;
185
186 if ((ctx->count[0] += (FILLP_UINT32)len) < len) {
187 ++(ctx->count[1]);
188 }
189
190 while (len >= (size_t)freeSize) {
191 err = memcpy_s(((FILLP_UINT8 *)ctx->wbuf) + offset, freeSize, dataPtr, freeSize);
192 if (err != EOK) {
193 FILLP_LOGERR("FillpSha256Upd memcpy_s 1 failed : %d, freeSize = %u", err, freeSize);
194 return;
195 }
196
197 dataPtr += freeSize;
198 len -= freeSize;
199 freeSize = FILLP_SHA256_BLOCK_SIZE;
200 offset = 0;
201 FILLP_SWAP_32_ARRAY(ctx->wbuf, FILLP_SHA256_BLOCK_SIZE >> FILLP_SHA_TWO_PAR);
202 FillpSha256Compile(ctx);
203 }
204
205 if (len != 0) {
206 err = memcpy_s(((FILLP_UINT8 *)ctx->wbuf) + offset, freeSize, dataPtr, (FILLP_UINT32)len);
207 if (err != EOK) {
208 FILLP_LOGERR("FillpSha256Upd memcpy_s 2 failed : %d, freeSize = %u, len = %zu", err, freeSize, len);
209 }
210 }
211 }
212
FillpSha256Fin(FillpSha256Ctx ctx[1],FILLP_UINT8 hashVal[],FILLP_UINT32 hashValLen)213 void FillpSha256Fin(FillpSha256Ctx ctx[1], FILLP_UINT8 hashVal[], FILLP_UINT32 hashValLen)
214 {
215 FILLP_UINT32 offset = (FILLP_UINT32)(ctx->count[0] & FILLP_SHA256_MASK);
216 FILLP_UINT32 shfBits;
217
218 /* put bytes in the buffer in big endian */
219 FILLP_SWAP_32_ARRAY(ctx->wbuf, (offset + FILLP_SHA_THREE_PAR) >> FILLP_SHA_TWO_PAR);
220
221 /* mask valid bytes and add the padding, */
222 /* a single 1 bit and as many zero bits as necessary. */
223 shfBits = (FILLP_SHA_EIGHT_PAR * (~offset & FILLP_SHA_THREE_PAR));
224 ctx->wbuf[offset >> FILLP_SHA_TWO_PAR] &= (FILLP_UINT32)0xffffff80 << shfBits;
225 ctx->wbuf[offset >> FILLP_SHA_TWO_PAR] |= (FILLP_UINT32)0x00000080 << shfBits;
226
227 /* need 9 or more empty positions, one for the padding byte */
228 /* (above) and 8 for the length count */
229 if (offset > (FILLP_SHA256_BLOCK_SIZE - FILLP_SHA_NINE_PAR)) {
230 if (offset < FILLP_SHA_60_PAR) {
231 ctx->wbuf[FILLP_SHAWK_ARRAY_SZ_MOD] = 0;
232 }
233
234 FillpSha256Compile(ctx);
235 offset = 0;
236 } else {
237 offset = (offset >> FILLP_SHA_TWO_PAR) + 1; /* compute a word index for the empty buffer positions */
238 }
239
240 while (offset < FILLP_SHA_FOURTEEN_PAR) {
241 /* and zero pad all but last two positions */
242 ctx->wbuf[offset++] = 0;
243 }
244
245 ctx->wbuf[FILLP_SHA_FOURTEEN_PAR] = (ctx->count[1] << FILLP_SHA_THREE_PAR) | (ctx->count[0] >> FILLP_SHA_29_PAR);
246 ctx->wbuf[FILLP_SHA_FIVETEEN_PAR] = ctx->count[0] << FILLP_SHA_THREE_PAR;
247 FillpSha256Compile(ctx);
248
249 for (offset = 0; offset < hashValLen; ++offset) {
250 shfBits = (FILLP_SHA_EIGHT_PAR * (~offset & FILLP_SHA_THREE_PAR));
251 hashVal[offset] = (FILLP_UINT8)(ctx->hash[offset >> FILLP_SHA_TWO_PAR] >> shfBits);
252 }
253 }
254
255
256 #ifdef __cplusplus
257 }
258 #endif
259
260