1 // 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 34 void 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 49 static 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)) 86 #define ROTL(x, n) (SHL((x), (n)) | ((x) >> (32 - (n)))) 87 88 #define P0(x) ((x) ^ ROTL((x), 9) ^ ROTL((x), 17)) 89 #define P1(x) ((x) ^ ROTL((x), 15) ^ ROTL((x), 23)) 90 91 for (j = 16; j < 68; j++) { 92 /* 93 * W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^ 94 * ROTL(W[j - 13],7 ) ^ W[j-6]; 95 */ 96 97 Temp1 = W[j - 16] ^ W[j - 9]; 98 Temp2 = ROTL(W[j - 3], 15); 99 Temp3 = Temp1 ^ Temp2; 100 Temp4 = P1(Temp3); 101 Temp5 = ROTL(W[j - 13], 7) ^ W[j - 6]; 102 W[j] = Temp4 ^ Temp5; 103 } 104 105 for (j = 0; j < 64; j++) 106 W1[j] = W[j] ^ W[j + 4]; 107 108 A = ctx->state[0]; 109 B = ctx->state[1]; 110 C = ctx->state[2]; 111 D = ctx->state[3]; 112 E = ctx->state[4]; 113 F = ctx->state[5]; 114 G = ctx->state[6]; 115 H = ctx->state[7]; 116 117 for (j = 0; j < 16; j++) { 118 SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7); 119 SS2 = SS1 ^ ROTL(A, 12); 120 TT1 = FF0(A, B, C) + D + SS2 + W1[j]; 121 TT2 = GG0(E, F, G) + H + SS1 + W[j]; 122 D = C; 123 C = ROTL(B, 9); 124 B = A; 125 A = TT1; 126 H = G; 127 G = ROTL(F, 19); 128 F = E; 129 E = P0(TT2); 130 } 131 132 for (j = 16; j < 64; j++) { 133 SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7); 134 SS2 = SS1 ^ ROTL(A, 12); 135 TT1 = FF1(A, B, C) + D + SS2 + W1[j]; 136 TT2 = GG1(E, F, G) + H + SS1 + W[j]; 137 D = C; 138 C = ROTL(B, 9); 139 B = A; 140 A = TT1; 141 H = G; 142 G = ROTL(F, 19); 143 F = E; 144 E = P0(TT2); 145 } 146 147 ctx->state[0] ^= A; 148 ctx->state[1] ^= B; 149 ctx->state[2] ^= C; 150 ctx->state[3] ^= D; 151 ctx->state[4] ^= E; 152 ctx->state[5] ^= F; 153 ctx->state[6] ^= G; 154 ctx->state[7] ^= H; 155 } 156 157 void sm3_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen) 158 { 159 size_t fill; 160 size_t left; 161 162 if (!ilen) 163 return; 164 165 left = ctx->total[0] & 0x3F; 166 fill = 64 - left; 167 168 ctx->total[0] += ilen; 169 170 if (ctx->total[0] < ilen) 171 ctx->total[1]++; 172 173 if (left && ilen >= fill) { 174 memcpy(ctx->buffer + left, input, fill); 175 sm3_process(ctx, ctx->buffer); 176 input += fill; 177 ilen -= fill; 178 left = 0; 179 } 180 181 while (ilen >= 64) { 182 sm3_process(ctx, input); 183 input += 64; 184 ilen -= 64; 185 } 186 187 if (ilen > 0) 188 memcpy(ctx->buffer + left, input, ilen); 189 } 190 191 static const uint8_t sm3_padding[64] = { 192 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193 0, 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 }; 197 198 void sm3_final(struct sm3_context *ctx, uint8_t output[32]) 199 { 200 uint32_t last, padn; 201 uint32_t high, low; 202 uint8_t msglen[8]; 203 204 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); 205 low = ctx->total[0] << 3; 206 207 PUT_UINT32_BE(high, msglen, 0); 208 PUT_UINT32_BE(low, msglen, 4); 209 210 last = ctx->total[0] & 0x3F; 211 padn = (last < 56) ? (56 - last) : (120 - last); 212 213 sm3_update(ctx, sm3_padding, padn); 214 sm3_update(ctx, msglen, 8); 215 216 PUT_UINT32_BE(ctx->state[0], output, 0); 217 PUT_UINT32_BE(ctx->state[1], output, 4); 218 PUT_UINT32_BE(ctx->state[2], output, 8); 219 PUT_UINT32_BE(ctx->state[3], output, 12); 220 PUT_UINT32_BE(ctx->state[4], output, 16); 221 PUT_UINT32_BE(ctx->state[5], output, 20); 222 PUT_UINT32_BE(ctx->state[6], output, 24); 223 PUT_UINT32_BE(ctx->state[7], output, 28); 224 } 225 226 void sm3(const uint8_t *input, size_t ilen, uint8_t output[32]) 227 { 228 struct sm3_context ctx = { }; 229 230 sm3_init(&ctx); 231 sm3_update(&ctx, input, ilen); 232 sm3_final(&ctx, output); 233 234 memzero_explicit(&ctx, sizeof(ctx)); 235 } 236 237 void sm3_hmac_init(struct sm3_context *ctx, const uint8_t *key, size_t keylen) 238 { 239 size_t i; 240 uint8_t sum[32]; 241 242 if (keylen > 64) { 243 sm3(key, keylen, sum); 244 keylen = 32; 245 key = sum; 246 } 247 248 memset(ctx->ipad, 0x36, 64); 249 memset(ctx->opad, 0x5C, 64); 250 251 for (i = 0; i < keylen; i++) { 252 ctx->ipad[i] ^= key[i]; 253 ctx->opad[i] ^= key[i]; 254 } 255 256 sm3_init(ctx); 257 sm3_update(ctx, ctx->ipad, 64); 258 259 memzero_explicit(sum, sizeof(sum)); 260 } 261 262 void sm3_hmac_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen) 263 { 264 sm3_update(ctx, input, ilen); 265 } 266 267 void sm3_hmac_final(struct sm3_context *ctx, uint8_t output[32]) 268 { 269 uint8_t tmpbuf[32]; 270 271 sm3_final(ctx, tmpbuf); 272 sm3_init(ctx); 273 sm3_update(ctx, ctx->opad, 64); 274 sm3_update(ctx, tmpbuf, 32); 275 sm3_final(ctx, output); 276 277 memzero_explicit(tmpbuf, sizeof(tmpbuf)); 278 } 279 280 void sm3_hmac(const uint8_t *key, size_t keylen, const uint8_t *input, 281 size_t ilen, uint8_t output[32]) 282 { 283 struct sm3_context ctx; 284 285 sm3_hmac_init(&ctx, key, keylen); 286 sm3_hmac_update(&ctx, input, ilen); 287 sm3_hmac_final(&ctx, output); 288 289 memzero_explicit(&ctx, sizeof(ctx)); 290 } 291