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