blob: 0a66d261bba6a9446d1500648b56ec16f4caf27c [file] [log] [blame]
Jerome Forissier47645572019-12-13 10:11:11 +01001// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright (c) 2019 Huawei Technologies Co., Ltd
4 */
5/*
6 * SM3 Hash algorithm
7 * thanks to Xyssl
8 * author:goldboar
9 * email:goldboar@163.com
10 * 2011-10-26
11 */
12
13#include <string.h>
14#include <string_ext.h>
15
16#include "sm3.h"
17
18#define GET_UINT32_BE(n, b, i) \
19 do { \
20 (n) = ((uint32_t)(b)[(i)] << 24) | \
21 ((uint32_t)(b)[(i) + 1] << 16) | \
22 ((uint32_t)(b)[(i) + 2] << 8) | \
23 ((uint32_t)(b)[(i) + 3]); \
24 } while (0)
25
26#define PUT_UINT32_BE(n, b, i) \
27 do { \
28 (b)[(i)] = (uint8_t)((n) >> 24); \
29 (b)[(i) + 1] = (uint8_t)((n) >> 16); \
30 (b)[(i) + 2] = (uint8_t)((n) >> 8); \
31 (b)[(i) + 3] = (uint8_t)((n)); \
32 } while (0)
33
34void sm3_init(struct sm3_context *ctx)
35{
36 ctx->total[0] = 0;
37 ctx->total[1] = 0;
38
39 ctx->state[0] = 0x7380166F;
40 ctx->state[1] = 0x4914B2B9;
41 ctx->state[2] = 0x172442D7;
42 ctx->state[3] = 0xDA8A0600;
43 ctx->state[4] = 0xA96F30BC;
44 ctx->state[5] = 0x163138AA;
45 ctx->state[6] = 0xE38DEE4D;
46 ctx->state[7] = 0xB0FB0E4E;
47}
48
49static void sm3_process(struct sm3_context *ctx, const uint8_t data[64])
50{
51 uint32_t SS1, SS2, TT1, TT2, W[68], W1[64];
52 uint32_t A, B, C, D, E, F, G, H;
53 uint32_t T[64];
54 uint32_t Temp1, Temp2, Temp3, Temp4, Temp5;
55 int j;
56
57 for (j = 0; j < 16; j++)
58 T[j] = 0x79CC4519;
59 for (j = 16; j < 64; j++)
60 T[j] = 0x7A879D8A;
61
62 GET_UINT32_BE(W[0], data, 0);
63 GET_UINT32_BE(W[1], data, 4);
64 GET_UINT32_BE(W[2], data, 8);
65 GET_UINT32_BE(W[3], data, 12);
66 GET_UINT32_BE(W[4], data, 16);
67 GET_UINT32_BE(W[5], data, 20);
68 GET_UINT32_BE(W[6], data, 24);
69 GET_UINT32_BE(W[7], data, 28);
70 GET_UINT32_BE(W[8], data, 32);
71 GET_UINT32_BE(W[9], data, 36);
72 GET_UINT32_BE(W[10], data, 40);
73 GET_UINT32_BE(W[11], data, 44);
74 GET_UINT32_BE(W[12], data, 48);
75 GET_UINT32_BE(W[13], data, 52);
76 GET_UINT32_BE(W[14], data, 56);
77 GET_UINT32_BE(W[15], data, 60);
78
79#define FF0(x, y, z) ((x) ^ (y) ^ (z))
80#define FF1(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
81
82#define GG0(x, y, z) ((x) ^ (y) ^ (z))
83#define GG1(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
84
85#define SHL(x, n) ((x) << (n))
Jens Wiklander959dda92021-05-27 12:36:37 +020086#define SHR(x, n) ((n) > 31 ? 0 : (x) >> (32 - (n)))
87#define ROTL(x, n) (SHL((x), (n) & 0x1F) | SHR((x), (n) & 0x1F))
Jerome Forissier47645572019-12-13 10:11:11 +010088
89#define P0(x) ((x) ^ ROTL((x), 9) ^ ROTL((x), 17))
90#define P1(x) ((x) ^ ROTL((x), 15) ^ ROTL((x), 23))
91
92 for (j = 16; j < 68; j++) {
93 /*
94 * W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^
95 * ROTL(W[j - 13],7 ) ^ W[j-6];
96 */
97
98 Temp1 = W[j - 16] ^ W[j - 9];
99 Temp2 = ROTL(W[j - 3], 15);
100 Temp3 = Temp1 ^ Temp2;
101 Temp4 = P1(Temp3);
102 Temp5 = ROTL(W[j - 13], 7) ^ W[j - 6];
103 W[j] = Temp4 ^ Temp5;
104 }
105
106 for (j = 0; j < 64; j++)
107 W1[j] = W[j] ^ W[j + 4];
108
109 A = ctx->state[0];
110 B = ctx->state[1];
111 C = ctx->state[2];
112 D = ctx->state[3];
113 E = ctx->state[4];
114 F = ctx->state[5];
115 G = ctx->state[6];
116 H = ctx->state[7];
117
118 for (j = 0; j < 16; j++) {
119 SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7);
120 SS2 = SS1 ^ ROTL(A, 12);
121 TT1 = FF0(A, B, C) + D + SS2 + W1[j];
122 TT2 = GG0(E, F, G) + H + SS1 + W[j];
123 D = C;
124 C = ROTL(B, 9);
125 B = A;
126 A = TT1;
127 H = G;
128 G = ROTL(F, 19);
129 F = E;
130 E = P0(TT2);
131 }
132
133 for (j = 16; j < 64; j++) {
134 SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7);
135 SS2 = SS1 ^ ROTL(A, 12);
136 TT1 = FF1(A, B, C) + D + SS2 + W1[j];
137 TT2 = GG1(E, F, G) + H + SS1 + W[j];
138 D = C;
139 C = ROTL(B, 9);
140 B = A;
141 A = TT1;
142 H = G;
143 G = ROTL(F, 19);
144 F = E;
145 E = P0(TT2);
146 }
147
148 ctx->state[0] ^= A;
149 ctx->state[1] ^= B;
150 ctx->state[2] ^= C;
151 ctx->state[3] ^= D;
152 ctx->state[4] ^= E;
153 ctx->state[5] ^= F;
154 ctx->state[6] ^= G;
155 ctx->state[7] ^= H;
156}
157
158void sm3_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen)
159{
160 size_t fill;
161 size_t left;
162
163 if (!ilen)
164 return;
165
166 left = ctx->total[0] & 0x3F;
167 fill = 64 - left;
168
169 ctx->total[0] += ilen;
170
171 if (ctx->total[0] < ilen)
172 ctx->total[1]++;
173
174 if (left && ilen >= fill) {
175 memcpy(ctx->buffer + left, input, fill);
176 sm3_process(ctx, ctx->buffer);
177 input += fill;
178 ilen -= fill;
179 left = 0;
180 }
181
182 while (ilen >= 64) {
183 sm3_process(ctx, input);
184 input += 64;
185 ilen -= 64;
186 }
187
188 if (ilen > 0)
189 memcpy(ctx->buffer + left, input, ilen);
190}
191
192static const uint8_t sm3_padding[64] = {
193 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
195 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
196 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
197};
198
199void sm3_final(struct sm3_context *ctx, uint8_t output[32])
200{
201 uint32_t last, padn;
202 uint32_t high, low;
203 uint8_t msglen[8];
204
205 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
206 low = ctx->total[0] << 3;
207
208 PUT_UINT32_BE(high, msglen, 0);
209 PUT_UINT32_BE(low, msglen, 4);
210
211 last = ctx->total[0] & 0x3F;
212 padn = (last < 56) ? (56 - last) : (120 - last);
213
214 sm3_update(ctx, sm3_padding, padn);
215 sm3_update(ctx, msglen, 8);
216
217 PUT_UINT32_BE(ctx->state[0], output, 0);
218 PUT_UINT32_BE(ctx->state[1], output, 4);
219 PUT_UINT32_BE(ctx->state[2], output, 8);
220 PUT_UINT32_BE(ctx->state[3], output, 12);
221 PUT_UINT32_BE(ctx->state[4], output, 16);
222 PUT_UINT32_BE(ctx->state[5], output, 20);
223 PUT_UINT32_BE(ctx->state[6], output, 24);
224 PUT_UINT32_BE(ctx->state[7], output, 28);
225}
226
227void sm3(const uint8_t *input, size_t ilen, uint8_t output[32])
228{
229 struct sm3_context ctx = { };
230
231 sm3_init(&ctx);
232 sm3_update(&ctx, input, ilen);
233 sm3_final(&ctx, output);
234
235 memzero_explicit(&ctx, sizeof(ctx));
236}
237
238void sm3_hmac_init(struct sm3_context *ctx, const uint8_t *key, size_t keylen)
239{
240 size_t i;
241 uint8_t sum[32];
242
243 if (keylen > 64) {
244 sm3(key, keylen, sum);
245 keylen = 32;
246 key = sum;
247 }
248
249 memset(ctx->ipad, 0x36, 64);
250 memset(ctx->opad, 0x5C, 64);
251
252 for (i = 0; i < keylen; i++) {
253 ctx->ipad[i] ^= key[i];
254 ctx->opad[i] ^= key[i];
255 }
256
257 sm3_init(ctx);
258 sm3_update(ctx, ctx->ipad, 64);
259
260 memzero_explicit(sum, sizeof(sum));
261}
262
263void sm3_hmac_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen)
264{
265 sm3_update(ctx, input, ilen);
266}
267
268void sm3_hmac_final(struct sm3_context *ctx, uint8_t output[32])
269{
270 uint8_t tmpbuf[32];
271
272 sm3_final(ctx, tmpbuf);
273 sm3_init(ctx);
274 sm3_update(ctx, ctx->opad, 64);
275 sm3_update(ctx, tmpbuf, 32);
276 sm3_final(ctx, output);
277
278 memzero_explicit(tmpbuf, sizeof(tmpbuf));
279}
280
281void sm3_hmac(const uint8_t *key, size_t keylen, const uint8_t *input,
282 size_t ilen, uint8_t output[32])
283{
284 struct sm3_context ctx;
285
286 sm3_hmac_init(&ctx, key, keylen);
287 sm3_hmac_update(&ctx, input, ilen);
288 sm3_hmac_final(&ctx, output);
289
290 memzero_explicit(&ctx, sizeof(ctx));
291}