1 /*
2 * Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License); you may
5 * not use this file except in compliance with the License.
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 */
9
10
11
12 #include <string.h>
13 #include <gmssl/sm3.h>
14 #include <gmssl/error.h>
15
16 /**
17 * HMAC_k(m) = H((k ^ opad) || H((k ^ ipad) || m))
18 * pseudo-code:
19 * function hmac(key, message)
20 * opad = [0x5c * blocksize]
21 * ipad = [0x36 * blocksize]
22 * if (length(key) > blocksize) then
23 * key = hash(key)
24 * end if
25 * for i from 0 to length(key) - 1 step 1
26 * ipad[i] = ipad[i] XOR key[i]
27 * opad[i] = opad[i] XOR key[i]
28 * end for
29 * return hash(opad || hash(ipad || message))
30 * end function
31 */
32
33
34 #define IPAD 0x36
35 #define OPAD 0x5C
36
sm3_hmac_init(SM3_HMAC_CTX * ctx,const uint8_t * key,size_t key_len)37 void sm3_hmac_init(SM3_HMAC_CTX *ctx, const uint8_t *key, size_t key_len)
38 {
39 int i;
40
41 if (key_len <= SM3_BLOCK_SIZE) {
42 memcpy(ctx->key, key, key_len);
43 memset(ctx->key + key_len, 0, SM3_BLOCK_SIZE - key_len);
44 } else {
45 sm3_init(&ctx->sm3_ctx);
46 sm3_update(&ctx->sm3_ctx, key, key_len);
47 sm3_finish(&ctx->sm3_ctx, ctx->key);
48 memset(ctx->key + SM3_DIGEST_SIZE, 0,
49 SM3_BLOCK_SIZE - SM3_DIGEST_SIZE);
50 }
51 for (i = 0; i < SM3_BLOCK_SIZE; i++) {
52 ctx->key[i] ^= IPAD;
53 }
54
55 sm3_init(&ctx->sm3_ctx);
56 sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE);
57 }
58
sm3_hmac_update(SM3_HMAC_CTX * ctx,const uint8_t * data,size_t data_len)59 void sm3_hmac_update(SM3_HMAC_CTX *ctx, const uint8_t *data, size_t data_len)
60 {
61 sm3_update(&ctx->sm3_ctx, data, data_len);
62 }
63
sm3_hmac_finish(SM3_HMAC_CTX * ctx,uint8_t mac[SM3_HMAC_SIZE])64 void sm3_hmac_finish(SM3_HMAC_CTX *ctx, uint8_t mac[SM3_HMAC_SIZE])
65 {
66 int i;
67 for (i = 0; i < SM3_BLOCK_SIZE; i++) {
68 ctx->key[i] ^= (IPAD ^ OPAD);
69 }
70 sm3_finish(&ctx->sm3_ctx, mac);
71 sm3_init(&ctx->sm3_ctx);
72 sm3_update(&ctx->sm3_ctx, ctx->key, SM3_BLOCK_SIZE);
73 sm3_update(&ctx->sm3_ctx, mac, SM3_DIGEST_SIZE);
74 sm3_finish(&ctx->sm3_ctx, mac);
75 memset(ctx, 0, sizeof(*ctx));
76 }
77
sm3_hmac(const uint8_t * key,size_t key_len,const uint8_t * data,size_t data_len,uint8_t mac[SM3_HMAC_SIZE])78 void sm3_hmac(const uint8_t *key, size_t key_len,
79 const uint8_t *data, size_t data_len,
80 uint8_t mac[SM3_HMAC_SIZE])
81 {
82 SM3_HMAC_CTX ctx;
83 sm3_hmac_init(&ctx, key, key_len);
84 sm3_hmac_update(&ctx, data, data_len);
85 sm3_hmac_finish(&ctx, mac);
86 }
87