147645577SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 247645577SJerome Forissier /* 347645577SJerome Forissier * Copyright (c) 2019 Huawei Technologies Co., Ltd 447645577SJerome Forissier */ 547645577SJerome Forissier /* 647645577SJerome Forissier * SM3 Hash algorithm 747645577SJerome Forissier * thanks to Xyssl 847645577SJerome Forissier * author:goldboar 947645577SJerome Forissier * email:goldboar@163.com 1047645577SJerome Forissier * 2011-10-26 1147645577SJerome Forissier */ 1247645577SJerome Forissier 1347645577SJerome Forissier #include <string.h> 1447645577SJerome Forissier #include <string_ext.h> 1547645577SJerome Forissier 1647645577SJerome Forissier #include "sm3.h" 1747645577SJerome Forissier 1847645577SJerome Forissier #define GET_UINT32_BE(n, b, i) \ 1947645577SJerome Forissier do { \ 2047645577SJerome Forissier (n) = ((uint32_t)(b)[(i)] << 24) | \ 2147645577SJerome Forissier ((uint32_t)(b)[(i) + 1] << 16) | \ 2247645577SJerome Forissier ((uint32_t)(b)[(i) + 2] << 8) | \ 2347645577SJerome Forissier ((uint32_t)(b)[(i) + 3]); \ 2447645577SJerome Forissier } while (0) 2547645577SJerome Forissier 2647645577SJerome Forissier #define PUT_UINT32_BE(n, b, i) \ 2747645577SJerome Forissier do { \ 2847645577SJerome Forissier (b)[(i)] = (uint8_t)((n) >> 24); \ 2947645577SJerome Forissier (b)[(i) + 1] = (uint8_t)((n) >> 16); \ 3047645577SJerome Forissier (b)[(i) + 2] = (uint8_t)((n) >> 8); \ 3147645577SJerome Forissier (b)[(i) + 3] = (uint8_t)((n)); \ 3247645577SJerome Forissier } while (0) 3347645577SJerome Forissier 3447645577SJerome Forissier void sm3_init(struct sm3_context *ctx) 3547645577SJerome Forissier { 3647645577SJerome Forissier ctx->total[0] = 0; 3747645577SJerome Forissier ctx->total[1] = 0; 3847645577SJerome Forissier 3947645577SJerome Forissier ctx->state[0] = 0x7380166F; 4047645577SJerome Forissier ctx->state[1] = 0x4914B2B9; 4147645577SJerome Forissier ctx->state[2] = 0x172442D7; 4247645577SJerome Forissier ctx->state[3] = 0xDA8A0600; 4347645577SJerome Forissier ctx->state[4] = 0xA96F30BC; 4447645577SJerome Forissier ctx->state[5] = 0x163138AA; 4547645577SJerome Forissier ctx->state[6] = 0xE38DEE4D; 4647645577SJerome Forissier ctx->state[7] = 0xB0FB0E4E; 4747645577SJerome Forissier } 4847645577SJerome Forissier 4947645577SJerome Forissier static void sm3_process(struct sm3_context *ctx, const uint8_t data[64]) 5047645577SJerome Forissier { 5147645577SJerome Forissier uint32_t SS1, SS2, TT1, TT2, W[68], W1[64]; 5247645577SJerome Forissier uint32_t A, B, C, D, E, F, G, H; 5347645577SJerome Forissier uint32_t T[64]; 5447645577SJerome Forissier uint32_t Temp1, Temp2, Temp3, Temp4, Temp5; 5547645577SJerome Forissier int j; 5647645577SJerome Forissier 5747645577SJerome Forissier for (j = 0; j < 16; j++) 5847645577SJerome Forissier T[j] = 0x79CC4519; 5947645577SJerome Forissier for (j = 16; j < 64; j++) 6047645577SJerome Forissier T[j] = 0x7A879D8A; 6147645577SJerome Forissier 6247645577SJerome Forissier GET_UINT32_BE(W[0], data, 0); 6347645577SJerome Forissier GET_UINT32_BE(W[1], data, 4); 6447645577SJerome Forissier GET_UINT32_BE(W[2], data, 8); 6547645577SJerome Forissier GET_UINT32_BE(W[3], data, 12); 6647645577SJerome Forissier GET_UINT32_BE(W[4], data, 16); 6747645577SJerome Forissier GET_UINT32_BE(W[5], data, 20); 6847645577SJerome Forissier GET_UINT32_BE(W[6], data, 24); 6947645577SJerome Forissier GET_UINT32_BE(W[7], data, 28); 7047645577SJerome Forissier GET_UINT32_BE(W[8], data, 32); 7147645577SJerome Forissier GET_UINT32_BE(W[9], data, 36); 7247645577SJerome Forissier GET_UINT32_BE(W[10], data, 40); 7347645577SJerome Forissier GET_UINT32_BE(W[11], data, 44); 7447645577SJerome Forissier GET_UINT32_BE(W[12], data, 48); 7547645577SJerome Forissier GET_UINT32_BE(W[13], data, 52); 7647645577SJerome Forissier GET_UINT32_BE(W[14], data, 56); 7747645577SJerome Forissier GET_UINT32_BE(W[15], data, 60); 7847645577SJerome Forissier 7947645577SJerome Forissier #define FF0(x, y, z) ((x) ^ (y) ^ (z)) 8047645577SJerome Forissier #define FF1(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 8147645577SJerome Forissier 8247645577SJerome Forissier #define GG0(x, y, z) ((x) ^ (y) ^ (z)) 8347645577SJerome Forissier #define GG1(x, y, z) (((x) & (y)) | ((~(x)) & (z))) 8447645577SJerome Forissier 8547645577SJerome Forissier #define SHL(x, n) ((x) << (n)) 86*f0ead748SJerome Forissier #define ROTL(x, n) (SHL((x), (n) & 0x1F) | ((x) >> (32 - ((n) & 0x1F)))) 8747645577SJerome Forissier 8847645577SJerome Forissier #define P0(x) ((x) ^ ROTL((x), 9) ^ ROTL((x), 17)) 8947645577SJerome Forissier #define P1(x) ((x) ^ ROTL((x), 15) ^ ROTL((x), 23)) 9047645577SJerome Forissier 9147645577SJerome Forissier for (j = 16; j < 68; j++) { 9247645577SJerome Forissier /* 9347645577SJerome Forissier * W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^ 9447645577SJerome Forissier * ROTL(W[j - 13],7 ) ^ W[j-6]; 9547645577SJerome Forissier */ 9647645577SJerome Forissier 9747645577SJerome Forissier Temp1 = W[j - 16] ^ W[j - 9]; 9847645577SJerome Forissier Temp2 = ROTL(W[j - 3], 15); 9947645577SJerome Forissier Temp3 = Temp1 ^ Temp2; 10047645577SJerome Forissier Temp4 = P1(Temp3); 10147645577SJerome Forissier Temp5 = ROTL(W[j - 13], 7) ^ W[j - 6]; 10247645577SJerome Forissier W[j] = Temp4 ^ Temp5; 10347645577SJerome Forissier } 10447645577SJerome Forissier 10547645577SJerome Forissier for (j = 0; j < 64; j++) 10647645577SJerome Forissier W1[j] = W[j] ^ W[j + 4]; 10747645577SJerome Forissier 10847645577SJerome Forissier A = ctx->state[0]; 10947645577SJerome Forissier B = ctx->state[1]; 11047645577SJerome Forissier C = ctx->state[2]; 11147645577SJerome Forissier D = ctx->state[3]; 11247645577SJerome Forissier E = ctx->state[4]; 11347645577SJerome Forissier F = ctx->state[5]; 11447645577SJerome Forissier G = ctx->state[6]; 11547645577SJerome Forissier H = ctx->state[7]; 11647645577SJerome Forissier 11747645577SJerome Forissier for (j = 0; j < 16; j++) { 11847645577SJerome Forissier SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7); 11947645577SJerome Forissier SS2 = SS1 ^ ROTL(A, 12); 12047645577SJerome Forissier TT1 = FF0(A, B, C) + D + SS2 + W1[j]; 12147645577SJerome Forissier TT2 = GG0(E, F, G) + H + SS1 + W[j]; 12247645577SJerome Forissier D = C; 12347645577SJerome Forissier C = ROTL(B, 9); 12447645577SJerome Forissier B = A; 12547645577SJerome Forissier A = TT1; 12647645577SJerome Forissier H = G; 12747645577SJerome Forissier G = ROTL(F, 19); 12847645577SJerome Forissier F = E; 12947645577SJerome Forissier E = P0(TT2); 13047645577SJerome Forissier } 13147645577SJerome Forissier 13247645577SJerome Forissier for (j = 16; j < 64; j++) { 13347645577SJerome Forissier SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[j], j), 7); 13447645577SJerome Forissier SS2 = SS1 ^ ROTL(A, 12); 13547645577SJerome Forissier TT1 = FF1(A, B, C) + D + SS2 + W1[j]; 13647645577SJerome Forissier TT2 = GG1(E, F, G) + H + SS1 + W[j]; 13747645577SJerome Forissier D = C; 13847645577SJerome Forissier C = ROTL(B, 9); 13947645577SJerome Forissier B = A; 14047645577SJerome Forissier A = TT1; 14147645577SJerome Forissier H = G; 14247645577SJerome Forissier G = ROTL(F, 19); 14347645577SJerome Forissier F = E; 14447645577SJerome Forissier E = P0(TT2); 14547645577SJerome Forissier } 14647645577SJerome Forissier 14747645577SJerome Forissier ctx->state[0] ^= A; 14847645577SJerome Forissier ctx->state[1] ^= B; 14947645577SJerome Forissier ctx->state[2] ^= C; 15047645577SJerome Forissier ctx->state[3] ^= D; 15147645577SJerome Forissier ctx->state[4] ^= E; 15247645577SJerome Forissier ctx->state[5] ^= F; 15347645577SJerome Forissier ctx->state[6] ^= G; 15447645577SJerome Forissier ctx->state[7] ^= H; 15547645577SJerome Forissier } 15647645577SJerome Forissier 15747645577SJerome Forissier void sm3_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen) 15847645577SJerome Forissier { 15947645577SJerome Forissier size_t fill; 16047645577SJerome Forissier size_t left; 16147645577SJerome Forissier 16247645577SJerome Forissier if (!ilen) 16347645577SJerome Forissier return; 16447645577SJerome Forissier 16547645577SJerome Forissier left = ctx->total[0] & 0x3F; 16647645577SJerome Forissier fill = 64 - left; 16747645577SJerome Forissier 16847645577SJerome Forissier ctx->total[0] += ilen; 16947645577SJerome Forissier 17047645577SJerome Forissier if (ctx->total[0] < ilen) 17147645577SJerome Forissier ctx->total[1]++; 17247645577SJerome Forissier 17347645577SJerome Forissier if (left && ilen >= fill) { 17447645577SJerome Forissier memcpy(ctx->buffer + left, input, fill); 17547645577SJerome Forissier sm3_process(ctx, ctx->buffer); 17647645577SJerome Forissier input += fill; 17747645577SJerome Forissier ilen -= fill; 17847645577SJerome Forissier left = 0; 17947645577SJerome Forissier } 18047645577SJerome Forissier 18147645577SJerome Forissier while (ilen >= 64) { 18247645577SJerome Forissier sm3_process(ctx, input); 18347645577SJerome Forissier input += 64; 18447645577SJerome Forissier ilen -= 64; 18547645577SJerome Forissier } 18647645577SJerome Forissier 18747645577SJerome Forissier if (ilen > 0) 18847645577SJerome Forissier memcpy(ctx->buffer + left, input, ilen); 18947645577SJerome Forissier } 19047645577SJerome Forissier 19147645577SJerome Forissier static const uint8_t sm3_padding[64] = { 19247645577SJerome Forissier 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19347645577SJerome Forissier 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19447645577SJerome Forissier 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19547645577SJerome Forissier 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 19647645577SJerome Forissier }; 19747645577SJerome Forissier 19847645577SJerome Forissier void sm3_final(struct sm3_context *ctx, uint8_t output[32]) 19947645577SJerome Forissier { 20047645577SJerome Forissier uint32_t last, padn; 20147645577SJerome Forissier uint32_t high, low; 20247645577SJerome Forissier uint8_t msglen[8]; 20347645577SJerome Forissier 20447645577SJerome Forissier high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); 20547645577SJerome Forissier low = ctx->total[0] << 3; 20647645577SJerome Forissier 20747645577SJerome Forissier PUT_UINT32_BE(high, msglen, 0); 20847645577SJerome Forissier PUT_UINT32_BE(low, msglen, 4); 20947645577SJerome Forissier 21047645577SJerome Forissier last = ctx->total[0] & 0x3F; 21147645577SJerome Forissier padn = (last < 56) ? (56 - last) : (120 - last); 21247645577SJerome Forissier 21347645577SJerome Forissier sm3_update(ctx, sm3_padding, padn); 21447645577SJerome Forissier sm3_update(ctx, msglen, 8); 21547645577SJerome Forissier 21647645577SJerome Forissier PUT_UINT32_BE(ctx->state[0], output, 0); 21747645577SJerome Forissier PUT_UINT32_BE(ctx->state[1], output, 4); 21847645577SJerome Forissier PUT_UINT32_BE(ctx->state[2], output, 8); 21947645577SJerome Forissier PUT_UINT32_BE(ctx->state[3], output, 12); 22047645577SJerome Forissier PUT_UINT32_BE(ctx->state[4], output, 16); 22147645577SJerome Forissier PUT_UINT32_BE(ctx->state[5], output, 20); 22247645577SJerome Forissier PUT_UINT32_BE(ctx->state[6], output, 24); 22347645577SJerome Forissier PUT_UINT32_BE(ctx->state[7], output, 28); 22447645577SJerome Forissier } 22547645577SJerome Forissier 22647645577SJerome Forissier void sm3(const uint8_t *input, size_t ilen, uint8_t output[32]) 22747645577SJerome Forissier { 22847645577SJerome Forissier struct sm3_context ctx = { }; 22947645577SJerome Forissier 23047645577SJerome Forissier sm3_init(&ctx); 23147645577SJerome Forissier sm3_update(&ctx, input, ilen); 23247645577SJerome Forissier sm3_final(&ctx, output); 23347645577SJerome Forissier 23447645577SJerome Forissier memzero_explicit(&ctx, sizeof(ctx)); 23547645577SJerome Forissier } 23647645577SJerome Forissier 23747645577SJerome Forissier void sm3_hmac_init(struct sm3_context *ctx, const uint8_t *key, size_t keylen) 23847645577SJerome Forissier { 23947645577SJerome Forissier size_t i; 24047645577SJerome Forissier uint8_t sum[32]; 24147645577SJerome Forissier 24247645577SJerome Forissier if (keylen > 64) { 24347645577SJerome Forissier sm3(key, keylen, sum); 24447645577SJerome Forissier keylen = 32; 24547645577SJerome Forissier key = sum; 24647645577SJerome Forissier } 24747645577SJerome Forissier 24847645577SJerome Forissier memset(ctx->ipad, 0x36, 64); 24947645577SJerome Forissier memset(ctx->opad, 0x5C, 64); 25047645577SJerome Forissier 25147645577SJerome Forissier for (i = 0; i < keylen; i++) { 25247645577SJerome Forissier ctx->ipad[i] ^= key[i]; 25347645577SJerome Forissier ctx->opad[i] ^= key[i]; 25447645577SJerome Forissier } 25547645577SJerome Forissier 25647645577SJerome Forissier sm3_init(ctx); 25747645577SJerome Forissier sm3_update(ctx, ctx->ipad, 64); 25847645577SJerome Forissier 25947645577SJerome Forissier memzero_explicit(sum, sizeof(sum)); 26047645577SJerome Forissier } 26147645577SJerome Forissier 26247645577SJerome Forissier void sm3_hmac_update(struct sm3_context *ctx, const uint8_t *input, size_t ilen) 26347645577SJerome Forissier { 26447645577SJerome Forissier sm3_update(ctx, input, ilen); 26547645577SJerome Forissier } 26647645577SJerome Forissier 26747645577SJerome Forissier void sm3_hmac_final(struct sm3_context *ctx, uint8_t output[32]) 26847645577SJerome Forissier { 26947645577SJerome Forissier uint8_t tmpbuf[32]; 27047645577SJerome Forissier 27147645577SJerome Forissier sm3_final(ctx, tmpbuf); 27247645577SJerome Forissier sm3_init(ctx); 27347645577SJerome Forissier sm3_update(ctx, ctx->opad, 64); 27447645577SJerome Forissier sm3_update(ctx, tmpbuf, 32); 27547645577SJerome Forissier sm3_final(ctx, output); 27647645577SJerome Forissier 27747645577SJerome Forissier memzero_explicit(tmpbuf, sizeof(tmpbuf)); 27847645577SJerome Forissier } 27947645577SJerome Forissier 28047645577SJerome Forissier void sm3_hmac(const uint8_t *key, size_t keylen, const uint8_t *input, 28147645577SJerome Forissier size_t ilen, uint8_t output[32]) 28247645577SJerome Forissier { 28347645577SJerome Forissier struct sm3_context ctx; 28447645577SJerome Forissier 28547645577SJerome Forissier sm3_hmac_init(&ctx, key, keylen); 28647645577SJerome Forissier sm3_hmac_update(&ctx, input, ilen); 28747645577SJerome Forissier sm3_hmac_final(&ctx, output); 28847645577SJerome Forissier 28947645577SJerome Forissier memzero_explicit(&ctx, sizeof(ctx)); 29047645577SJerome Forissier } 291