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