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 return;
168 }
169
FillpSha256Set(FillpSha256Ctx ctx[1])170 void FillpSha256Set(FillpSha256Ctx ctx[1])
171 {
172 ctx->count[0] = 0;
173 ctx->count[1] = 0;
174 FillpErrorType err = memcpy_s(ctx->hash, sizeof(ctx->hash), g_i256, sizeof(g_i256));
175 if (err != EOK) {
176 FILLP_LOGERR("FillpSha256Set memcpy_s hash failed : %d", err);
177 }
178
179 return;
180 }
181
182
FillpSha256Upd(FillpSha256Ctx ctx[1],const FILLP_UINT8 data[],size_t len)183 void FillpSha256Upd(FillpSha256Ctx ctx[1], const FILLP_UINT8 data[], size_t len)
184 {
185 FILLP_UINT32 offset = (FILLP_UINT32)(ctx->count[0] & FILLP_SHA256_MASK);
186 FILLP_UINT32 freeSize = FILLP_SHA256_BLOCK_SIZE - offset;
187 const FILLP_UINT8 *dataPtr = data;
188 FillpErrorType err;
189
190 if ((ctx->count[0] += (FILLP_UINT32)len) < len) {
191 ++(ctx->count[1]);
192 }
193
194 while (len >= (size_t)freeSize) {
195 err = memcpy_s(((FILLP_UINT8 *)ctx->wbuf) + offset, freeSize, dataPtr, freeSize);
196 if (err != EOK) {
197 FILLP_LOGERR("FillpSha256Upd memcpy_s 1 failed : %d, freeSize = %u", err, freeSize);
198 return;
199 }
200
201 dataPtr += freeSize;
202 len -= freeSize;
203 freeSize = FILLP_SHA256_BLOCK_SIZE;
204 offset = 0;
205 FILLP_SWAP_32_ARRAY(ctx->wbuf, FILLP_SHA256_BLOCK_SIZE >> FILLP_SHA_TWO_PAR);
206 FillpSha256Compile(ctx);
207 }
208
209 if (len != 0) {
210 err = memcpy_s(((FILLP_UINT8 *)ctx->wbuf) + offset, freeSize, dataPtr, (FILLP_UINT32)len);
211 if (err != EOK) {
212 FILLP_LOGERR("FillpSha256Upd memcpy_s 2 failed : %d, freeSize = %u, len = %zu", err, freeSize, len);
213 }
214 }
215
216 return;
217 }
218
FillpSha256Fin(FillpSha256Ctx ctx[1],FILLP_UINT8 hashVal[],FILLP_UINT32 hashValLen)219 void FillpSha256Fin(FillpSha256Ctx ctx[1], FILLP_UINT8 hashVal[], FILLP_UINT32 hashValLen)
220 {
221 FILLP_UINT32 offset = (FILLP_UINT32)(ctx->count[0] & FILLP_SHA256_MASK);
222 FILLP_UINT32 shfBits;
223
224 /* put bytes in the buffer in big endian */
225 FILLP_SWAP_32_ARRAY(ctx->wbuf, (offset + FILLP_SHA_THREE_PAR) >> FILLP_SHA_TWO_PAR);
226
227 /* mask valid bytes and add the padding, */
228 /* a single 1 bit and as many zero bits as necessary. */
229 shfBits = (FILLP_SHA_EIGHT_PAR * (~offset & FILLP_SHA_THREE_PAR));
230 ctx->wbuf[offset >> FILLP_SHA_TWO_PAR] &= (FILLP_UINT32)0xffffff80 << shfBits;
231 ctx->wbuf[offset >> FILLP_SHA_TWO_PAR] |= (FILLP_UINT32)0x00000080 << shfBits;
232
233 /* need 9 or more empty positions, one for the padding byte */
234 /* (above) and 8 for the length count */
235 if (offset > (FILLP_SHA256_BLOCK_SIZE - FILLP_SHA_NINE_PAR)) {
236 if (offset < FILLP_SHA_60_PAR) {
237 ctx->wbuf[FILLP_SHAWK_ARRAY_SZ_MOD] = 0;
238 }
239
240 FillpSha256Compile(ctx);
241 offset = 0;
242 } else {
243 offset = (offset >> FILLP_SHA_TWO_PAR) + 1; /* compute a word index for the empty buffer positions */
244 }
245
246 while (offset < FILLP_SHA_FOURTEEN_PAR) {
247 /* and zero pad all but last two positions */
248 ctx->wbuf[offset++] = 0;
249 }
250
251 ctx->wbuf[FILLP_SHA_FOURTEEN_PAR] = (ctx->count[1] << FILLP_SHA_THREE_PAR) | (ctx->count[0] >> FILLP_SHA_29_PAR);
252 ctx->wbuf[FILLP_SHA_FIVETEEN_PAR] = ctx->count[0] << FILLP_SHA_THREE_PAR;
253 FillpSha256Compile(ctx);
254
255 for (offset = 0; offset < hashValLen; ++offset) {
256 shfBits = (FILLP_SHA_EIGHT_PAR * (~offset & FILLP_SHA_THREE_PAR));
257 hashVal[offset] = (FILLP_UINT8)(ctx->hash[offset >> FILLP_SHA_TWO_PAR] >> shfBits);
258 }
259
260 return;
261 }
262
263
264 #ifdef __cplusplus
265 }
266 #endif
267
268