• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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