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