1 /*
2 * Copyright (c) 2022-2023 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 #ifndef __HVB_SM3_H__
16 #define __HVB_SM3_H__
17
18 #include "hvb_sm3.h"
19 #include "hvb_gm_common.h"
20 #include "hvb_sysdeps.h"
21 #include "hvb_util.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #define SM3_PRECAL_W_NUMS 16
26
27 static const uint32_t const_t[] = {
28 0x79cc4519,
29 0xf3988a32,
30 0xe7311465,
31 0xce6228cb,
32 0x9cc45197,
33 0x3988a32f,
34 0x7311465e,
35 0xe6228cbc,
36 0xcc451979,
37 0x988a32f3,
38 0x311465e7,
39 0x6228cbce,
40 0xc451979c,
41 0x88a32f39,
42 0x11465e73,
43 0x228cbce6,
44 0x9d8a7a87,
45 0x3b14f50f,
46 0x7629ea1e,
47 0xec53d43c,
48 0xd8a7a879,
49 0xb14f50f3,
50 0x629ea1e7,
51 0xc53d43ce,
52 0x8a7a879d,
53 0x14f50f3b,
54 0x29ea1e76,
55 0x53d43cec,
56 0xa7a879d8,
57 0x4f50f3b1,
58 0x9ea1e762,
59 0x3d43cec5,
60 0x7a879d8a,
61 0xf50f3b14,
62 0xea1e7629,
63 0xd43cec53,
64 0xa879d8a7,
65 0x50f3b14f,
66 0xa1e7629e,
67 0x43cec53d,
68 0x879d8a7a,
69 0x0f3b14f5,
70 0x1e7629ea,
71 0x3cec53d4,
72 0x79d8a7a8,
73 0xf3b14f50,
74 0xe7629ea1,
75 0xcec53d43,
76 0x9d8a7a87,
77 0x3b14f50f,
78 0x7629ea1e,
79 0xec53d43c,
80 0xd8a7a879,
81 0xb14f50f3,
82 0x629ea1e7,
83 0xc53d43ce,
84 0x8a7a879d,
85 0x14f50f3b,
86 0x29ea1e76,
87 0x53d43cec,
88 0xa7a879d8,
89 0x4f50f3b1,
90 0x9ea1e762,
91 0x3d43cec5,
92 };
93
94 static uint32_t sm3_iv_init[SM3_IV_WORD_SIZE] = {
95 0x7380166F, 0x4914B2B9, 0x172442D7, 0xDA8A0600, 0xA96F30BC, 0x163138AA, 0xE38DEE4D, 0xB0FB0E4E };
96
97 /* x is 32bit */
98 #define rotl(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
99 #define p0(x) ((x) ^ rotl((x), 9) ^ rotl((x), 17))
100 #define p1(x) ((x) ^ rotl((x), 15) ^ rotl((x), 23))
101 #define ff0(x, y, z) ((x) ^ (y) ^ (z))
102 #define ff2(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
103 #define gg0(x, y, z) ((x) ^ (y) ^ (z))
104 #define gg1(x, y, z) (((x) & (y)) | (~(x) & (z)))
105 #define cal_w(w1, w2, w3, w4, w5) \
106 (p1((w1) ^ (w2) ^ rotl((w3), 15)) ^ rotl((w4), 7) ^ (w5))
107
bigend_read_word(const uint8_t * data)108 static uint32_t bigend_read_word(const uint8_t *data)
109 {
110 uint32_t res;
111
112 res = data[0];
113 res = (res << 8) | data[1];
114 res = (res << 8) | data[2];
115 res = (res << 8) | data[3];
116
117 return res;
118 }
119
120 #define sm3_round(A, B, C, D, E, F, G, H, T, FF, GG, Wj, Wi) \
121 do { \
122 uint32_t a12 = rotl((A), 12); \
123 uint32_t ss1 = rotl(a12 + (E) + (T), 7); \
124 uint32_t ss2 = ss1 ^ a12; \
125 uint32_t tt1 = FF((A), (B), (C)) + (D) + ss2 + (Wi); \
126 uint32_t tt2 = GG((E), (F), (G)) + (H) + ss1 + (Wj); \
127 (B) = rotl((B), 9); \
128 (D) = p0(tt2); \
129 (F) = rotl((F), 19); \
130 (H) = tt1; \
131 } while (0)
132
133 #define sm3_round_0_15(A, B, C, D, E, F, G, H, T, Wj, Wi) \
134 sm3_round(A, B, C, D, E, F, G, H, T, ff0, gg0, Wj, Wi)
135
136 #define sm3_round_16_63(A, B, C, D, E, F, G, H, T, Wj, Wi) \
137 sm3_round(A, B, C, D, E, F, G, H, T, ff2, gg1, Wj, Wi)
138
sm3_block_calc(uint32_t regs[8],const uint8_t * data)139 static void sm3_block_calc(uint32_t regs[8], const uint8_t *data)
140 {
141 uint32_t w[SM3_PRECAL_W_NUMS];
142 uint32_t i;
143
144 /* pre store w */
145 for (i = 0; i < SM3_PRECAL_W_NUMS; i++, data += 4)
146 w[i] = bigend_read_word(data);
147
148 sm3_round_0_15(regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7],
149 const_t[0], w[0], w[0] ^ w[4]);
150 sm3_round_0_15(regs[7], regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6],
151 const_t[1], w[1], w[1] ^ w[5]);
152 sm3_round_0_15(regs[6], regs[7], regs[0], regs[1], regs[2], regs[3], regs[4], regs[5],
153 const_t[2], w[2], w[2] ^ w[6]);
154 sm3_round_0_15(regs[5], regs[6], regs[7], regs[0], regs[1], regs[2], regs[3], regs[4],
155 const_t[3], w[3], w[3] ^ w[7]);
156 sm3_round_0_15(regs[4], regs[5], regs[6], regs[7], regs[0], regs[1], regs[2], regs[3],
157 const_t[4], w[4], w[4] ^ w[8]);
158 sm3_round_0_15(regs[3], regs[4], regs[5], regs[6], regs[7], regs[0], regs[1], regs[2],
159 const_t[5], w[5], w[5] ^ w[9]);
160 sm3_round_0_15(regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[0], regs[1],
161 const_t[6], w[6], w[6] ^ w[10]);
162 sm3_round_0_15(regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[0],
163 const_t[7], w[7], w[7] ^ w[11]);
164 sm3_round_0_15(regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7],
165 const_t[8], w[8], w[8] ^ w[12]);
166 sm3_round_0_15(regs[7], regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6],
167 const_t[9], w[9], w[9] ^ w[13]);
168 sm3_round_0_15(regs[6], regs[7], regs[0], regs[1], regs[2], regs[3], regs[4], regs[5],
169 const_t[10], w[10], w[10] ^ w[14]);
170 sm3_round_0_15(regs[5], regs[6], regs[7], regs[0], regs[1], regs[2], regs[3], regs[4],
171 const_t[11], w[11], w[11] ^ w[15]);
172 w[0] = cal_w(w[0], w[7], w[13], w[3], w[10]);
173 sm3_round_0_15(regs[4], regs[5], regs[6], regs[7], regs[0], regs[1], regs[2], regs[3],
174 const_t[12], w[12], w[12] ^ w[0]);
175 w[1] = cal_w(w[1], w[8], w[14], w[4], w[11]);
176 sm3_round_0_15(regs[3], regs[4], regs[5], regs[6], regs[7], regs[0], regs[1], regs[2],
177 const_t[13], w[13], w[13] ^ w[1]);
178 w[2] = cal_w(w[2], w[9], w[15], w[5], w[12]);
179 sm3_round_0_15(regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[0], regs[1],
180 const_t[14], w[14], w[14] ^ w[2]);
181 w[3] = cal_w(w[3], w[10], w[0], w[6], w[13]);
182 sm3_round_0_15(regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[0],
183 const_t[15], w[15], w[15] ^ w[3]);
184
185 for (i = 1; i < 4; i++) {
186 w[4] = cal_w(w[4], w[11], w[1], w[7], w[14]);
187 sm3_round_16_63(regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7],
188 const_t[i * 16 + 0], w[0], w[0] ^ w[4]);
189 w[5] = cal_w(w[5], w[12], w[2], w[8], w[15]);
190 sm3_round_16_63(regs[7], regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6],
191 const_t[i * 16 + 1], w[1], w[1] ^ w[5]);
192 w[6] = cal_w(w[6], w[13], w[3], w[9], w[0]);
193 sm3_round_16_63(regs[6], regs[7], regs[0], regs[1], regs[2], regs[3], regs[4], regs[5],
194 const_t[i * 16 + 2], w[2], w[2] ^ w[6]);
195 w[7] = cal_w(w[7], w[14], w[4], w[10], w[1]);
196 sm3_round_16_63(regs[5], regs[6], regs[7], regs[0], regs[1], regs[2], regs[3], regs[4],
197 const_t[i * 16 + 3], w[3], w[3] ^ w[7]);
198 w[8] = cal_w(w[8], w[15], w[5], w[11], w[2]);
199 sm3_round_16_63(regs[4], regs[5], regs[6], regs[7], regs[0], regs[1], regs[2], regs[3],
200 const_t[i * 16 + 4], w[4], w[4] ^ w[8]);
201 w[9] = cal_w(w[9], w[0], w[6], w[12], w[3]);
202 sm3_round_16_63(regs[3], regs[4], regs[5], regs[6], regs[7], regs[0], regs[1], regs[2],
203 const_t[i * 16 + 5], w[5], w[5] ^ w[9]);
204 w[10] = cal_w(w[10], w[1], w[7], w[13], w[4]);
205 sm3_round_16_63(regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[0], regs[1],
206 const_t[i * 16 + 6], w[6], w[6] ^ w[10]);
207 w[11] = cal_w(w[11], w[2], w[8], w[14], w[5]);
208 sm3_round_16_63(regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[0],
209 const_t[i * 16 + 7], w[7], w[7] ^ w[11]);
210 w[12] = cal_w(w[12], w[3], w[9], w[15], w[6]);
211 sm3_round_16_63(regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7],
212 const_t[i * 16 + 8], w[8], w[8] ^ w[12]);
213 w[13] = cal_w(w[13], w[4], w[10], w[0], w[7]);
214 sm3_round_16_63(regs[7], regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6],
215 const_t[i * 16 + 9], w[9], w[9] ^ w[13]);
216 w[14] = cal_w(w[14], w[5], w[11], w[1], w[8]);
217 sm3_round_16_63(regs[6], regs[7], regs[0], regs[1], regs[2], regs[3], regs[4], regs[5],
218 const_t[i * 16 + 10], w[10], w[10] ^ w[14]);
219 w[15] = cal_w(w[15], w[6], w[12], w[2], w[9]);
220 sm3_round_16_63(regs[5], regs[6], regs[7], regs[0], regs[1], regs[2], regs[3], regs[4],
221 const_t[i * 16 + 11], w[11], w[11] ^ w[15]);
222 w[0] = cal_w(w[0], w[7], w[13], w[3], w[10]);
223 sm3_round_16_63(regs[4], regs[5], regs[6], regs[7], regs[0], regs[1], regs[2], regs[3],
224 const_t[i * 16 + 12], w[12], w[12] ^ w[0]);
225 w[1] = cal_w(w[1], w[8], w[14], w[4], w[11]);
226 sm3_round_16_63(regs[3], regs[4], regs[5], regs[6], regs[7], regs[0], regs[1], regs[2],
227 const_t[i * 16 + 13], w[13], w[13] ^ w[1]);
228 w[2] = cal_w(w[2], w[9], w[15], w[5], w[12]);
229 sm3_round_16_63(regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[0], regs[1],
230 const_t[i * 16 + 14], w[14], w[14] ^ w[2]);
231 w[3] = cal_w(w[3], w[10], w[0], w[6], w[13]);
232 sm3_round_16_63(regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[0],
233 const_t[i * 16 + 15], w[15], w[15] ^ w[3]);
234 }
235 }
236
sm3_data_blk_update(uint32_t * iv,const void * msg,uint32_t len)237 static void sm3_data_blk_update(uint32_t *iv, const void *msg, uint32_t len)
238 {
239 uint32_t regs[8];
240 const uint8_t *pdata = msg;
241 uint32_t i;
242 uint32_t j;
243
244 for (i = 0; i < len / 64; i++, pdata += 64) {
245 for (j = 0; j < 8; j++)
246 regs[j] = iv[j];
247
248 sm3_block_calc(regs, pdata);
249
250 for (j = 0; j < 8; j++)
251 iv[j] ^= regs[j];
252 }
253 }
254
hvb_sm3_init(struct sm3_ctx_t * hash_ctx)255 int hvb_sm3_init(struct sm3_ctx_t *hash_ctx)
256 {
257 if (hvb_check(hash_ctx == NULL))
258 return SM3_POINTER_NULL;
259
260 hash_ctx->buf_len = 0;
261 hash_ctx->total_len = 0;
262
263 if (hvb_check(hvb_memcpy_s(hash_ctx->iv, sizeof(hash_ctx->iv), sm3_iv_init, sizeof(sm3_iv_init)) != 0))
264 return SM3_MEMORY_ERR;
265
266 return SM3_OK;
267 }
268
hvb_sm3_update(struct sm3_ctx_t * hash_ctx,const void * msg,uint32_t msg_len)269 int hvb_sm3_update(struct sm3_ctx_t *hash_ctx, const void *msg, uint32_t msg_len)
270 {
271 uint32_t left_len;
272 uint32_t calc_len;
273 uint8_t *msg_tmp = (uint8_t *)msg;
274
275 if (hvb_check(msg == NULL || hash_ctx == NULL))
276 return SM3_POINTER_NULL;
277
278 if (hvb_check(msg_len == 0))
279 return SM3_MSG_LEN_ERR;
280
281 if (hvb_check(hash_ctx->buf_len >= SM3_BLK_BYTE_SIZE))
282 return SM3_BUF_LEN_ERR;
283
284 hash_ctx->total_len += msg_len;
285 if (hash_ctx->total_len < msg_len)
286 return SM3_OVER_MAX_LEN;
287
288 left_len = SM3_BLK_BYTE_SIZE - hash_ctx->buf_len;
289
290 if (hash_ctx->buf_len != 0 && msg_len >= left_len) {
291 if (hvb_check(hvb_memcpy_s(hash_ctx->blk_buf + hash_ctx->buf_len, sizeof(hash_ctx->blk_buf) - hash_ctx->buf_len,
292 msg_tmp, left_len) != 0))
293 return SM3_MEMORY_ERR;
294 sm3_data_blk_update(hash_ctx->iv, hash_ctx->blk_buf, SM3_BLK_BYTE_SIZE);
295 hash_ctx->buf_len = 0;
296 msg_len -= left_len;
297 msg_tmp += left_len;
298 }
299
300 if (msg_len >= SM3_BLK_BYTE_SIZE) {
301 calc_len = (msg_len / SM3_BLK_BYTE_SIZE) * SM3_BLK_BYTE_SIZE;
302 sm3_data_blk_update(hash_ctx->iv, msg_tmp, calc_len);
303 msg_len -= calc_len;
304 msg_tmp += calc_len;
305 }
306
307 if (msg_len != 0) {
308 if (hvb_check(hvb_memcpy_s(hash_ctx->blk_buf + hash_ctx->buf_len, sizeof(hash_ctx->blk_buf) - hash_ctx->buf_len,
309 msg_tmp, msg_len) != 0))
310 return SM3_MEMORY_ERR;
311 hash_ctx->buf_len += msg_len;
312 }
313
314 return SM3_OK;
315 }
316
317 #define SM3_PAD_BLK_WORD_SIZE (SM3_BLK_WORD_SIZE * 2)
318 #define SM3_PAD_INFO_BYTE_LEN 8
sm3_pad_update(uint32_t * iv,const void * left_msg,uint32_t left_len,uint64_t total_bit_len)319 static int sm3_pad_update(uint32_t *iv, const void *left_msg, uint32_t left_len, uint64_t total_bit_len)
320 {
321 uint32_t pad_word_len;
322 uint32_t sm3_pad[SM3_PAD_BLK_WORD_SIZE];
323 uint8_t *pad_ptr = NULL;
324 uint32_t fill_zero_len;
325 int ret = -1;
326
327 if (left_len != 0) {
328 ret = hvb_memcpy_s(sm3_pad, sizeof(sm3_pad), left_msg, left_len);
329 if (hvb_check(ret != 0)) {
330 return SM3_MEMORY_ERR;
331 }
332 }
333
334 pad_ptr = (uint8_t *)sm3_pad;
335 pad_ptr[left_len] = 0x80; // padding 0x80
336 left_len++;
337
338 if (left_len + SM3_PAD_INFO_BYTE_LEN <= SM3_BLK_BYTE_SIZE)
339 pad_word_len = SM3_BLK_WORD_SIZE;
340 else
341 pad_word_len = SM3_PAD_BLK_WORD_SIZE;
342
343 fill_zero_len = word2byte(pad_word_len) - (uint32_t)left_len - SM3_PAD_INFO_BYTE_LEN;
344 ret = hvb_memset_s(pad_ptr + left_len, sizeof(sm3_pad) - left_len, 0, fill_zero_len);
345 if (hvb_check(ret != 0))
346 return SM3_MEMORY_ERR;
347
348 sm3_pad[pad_word_len - 1] = htobe32((uint32_t)total_bit_len);
349 total_bit_len = total_bit_len >> 32;
350 sm3_pad[pad_word_len - 2] = htobe32((uint32_t)total_bit_len);
351
352 sm3_data_blk_update(iv, pad_ptr, word2byte(pad_word_len));
353 return SM3_OK;
354 }
355
sm3_output_iv(uint32_t * iv,uint8_t * out,uint32_t * out_len)356 static int sm3_output_iv(uint32_t *iv, uint8_t *out, uint32_t *out_len)
357 {
358 if (hvb_check(out == NULL))
359 return SM3_POINTER_NULL;
360
361 if (hvb_check(out_len == NULL))
362 return SM3_POINTER_NULL;
363
364 if (hvb_check(*out_len < SM3_IV_BYTE_SIZE))
365 return SM3_OUTBUF_NOT_ENOUGH;
366
367 *out_len = SM3_IV_BYTE_SIZE;
368 for (uint32_t i = 0; i < SM3_IV_WORD_SIZE; i++)
369 iv[i] = htobe32(iv[i]);
370
371 if (hvb_check(hvb_memcpy_s(out, *out_len, iv, SM3_IV_BYTE_SIZE) != 0))
372 return SM3_MEMORY_ERR;
373
374 return SM3_OK;
375 }
376
hvb_sm3_final(struct sm3_ctx_t * hash_ctx,uint8_t * out,uint32_t * out_len)377 int hvb_sm3_final(struct sm3_ctx_t *hash_ctx, uint8_t *out, uint32_t *out_len)
378 {
379 uint64_t total_bit_len;
380 int ret = -1;
381
382 if (hvb_check(hash_ctx == NULL))
383 return SM3_POINTER_NULL;
384
385 total_bit_len = hash_ctx->total_len * 8;
386 if (hvb_check(total_bit_len <= hash_ctx->total_len))
387 return SM3_OVER_MAX_LEN;
388
389 ret = sm3_pad_update(hash_ctx->iv, hash_ctx->blk_buf, hash_ctx->buf_len, total_bit_len);
390 if (hvb_check(ret != SM3_OK))
391 return ret;
392
393 return sm3_output_iv(hash_ctx->iv, out, out_len);
394 }
395
hvb_sm3_single(const void * msg,uint32_t msg_len,uint8_t * out,uint32_t * out_len)396 int hvb_sm3_single(const void *msg, uint32_t msg_len, uint8_t *out, uint32_t *out_len)
397 {
398 uint32_t data_size;
399 uint64_t total_bit_len;
400 uint32_t iv[SM3_IV_WORD_SIZE];
401 int ret = -1;
402
403 /* 8bit per byte */
404 total_bit_len = (uint64_t)msg_len * 8;
405
406 if (hvb_check(msg == NULL))
407 return SM3_POINTER_NULL;
408
409 if (hvb_check(msg_len == 0))
410 return SM3_MSG_LEN_ERR;
411
412 if (hvb_check(hvb_memcpy_s(iv, sizeof(iv), sm3_iv_init, sizeof(sm3_iv_init)) != 0))
413 return SM3_MEMORY_ERR;
414
415 data_size = (msg_len / SM3_BLK_BYTE_SIZE) * SM3_BLK_BYTE_SIZE;
416
417 if (data_size > 0)
418 sm3_data_blk_update(iv, msg, data_size);
419
420 ret = sm3_pad_update(iv, (uint8_t *)msg + data_size, msg_len - data_size, total_bit_len);
421 if (hvb_check(ret != SM3_OK))
422 return ret;
423
424 return sm3_output_iv(iv, out, out_len);
425 }
426
427 #endif
428