1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include "soft_hmac.h"
13 #include <openssl/hmac.h>
14 #ifdef OPENSSL_ENABLE
15 #include <crypto/siphash.h>
16 #include <siphash/siphash_local.h>
17 #elif defined OPENSSL3_ENABLE
18 #include <crypto/siphash.h>
19 #endif
20 #include <tee_log.h>
21 #include "soft_gmssl.h"
22 #include "soft_common_api.h"
23 #include "soft_err.h"
24 #include "crypto_inner_defines.h"
25
26 static const uint32_t g_algorithm_hmac[] = {
27 CRYPTO_TYPE_HMAC_MD5,
28 CRYPTO_TYPE_HMAC_SHA1,
29 CRYPTO_TYPE_HMAC_SHA224,
30 CRYPTO_TYPE_HMAC_SHA256,
31 CRYPTO_TYPE_HMAC_SHA384,
32 CRYPTO_TYPE_HMAC_SHA512,
33 CRYPTO_TYPE_HMAC_SM3,
34 CRYPTO_TYPE_SIP_HASH,
35 };
36
37 struct hamc_evp {
38 uint32_t algorithm;
39 const EVP_MD *(*hmac_api)(void);
40 };
get_hmac_evp(uint32_t algorithm)41 static const EVP_MD *get_hmac_evp(uint32_t algorithm)
42 {
43 struct hamc_evp g_hmac_config[] = {
44 { CRYPTO_TYPE_HMAC_MD5, EVP_md5 },
45 { CRYPTO_TYPE_HMAC_SHA1, EVP_sha1 },
46 { CRYPTO_TYPE_HMAC_SHA224, EVP_sha224 },
47 { CRYPTO_TYPE_HMAC_SHA256, EVP_sha256 },
48 { CRYPTO_TYPE_HMAC_SHA384, EVP_sha384 },
49 { CRYPTO_TYPE_HMAC_SHA512, EVP_sha512 },
50 };
51
52 for (size_t i = 0; i < sizeof(g_hmac_config) / sizeof(g_hmac_config[0]); i++) {
53 if (algorithm == g_hmac_config[i].algorithm)
54 return g_hmac_config[i].hmac_api();
55 }
56
57 return NULL;
58 }
59
sip_hash_mac_init(struct ctx_handle_t * ctx,const struct symmerit_key_t * key)60 static int32_t sip_hash_mac_init(struct ctx_handle_t *ctx, const struct symmerit_key_t *key)
61 {
62 if (key->key_size != SIPHASH_KEY_SIZE) {
63 tloge("key_size error! key_size = %d", key->key_size);
64 return CRYPTO_BAD_PARAMETERS;
65 }
66
67 SIPHASH *siphash_ctx = TEE_Malloc(sizeof(*siphash_ctx), 0);
68 if (siphash_ctx == NULL) {
69 tloge("siphash_ctx malloc failed!");
70 return CRYPTO_ERROR_SECURITY;
71 }
72
73 int ret = SipHash_set_hash_size(siphash_ctx, SIP_HASH_OUTPUT_LEN);
74 if (ret != BORINGSSL_OK) {
75 tloge("hash size invalid! hash size = %d", SIP_HASH_OUTPUT_LEN);
76 TEE_Free((void *)siphash_ctx);
77 return CRYPTO_BAD_PARAMETERS;
78 }
79
80 ret = SipHash_Init(siphash_ctx, (const uint8_t *)(uintptr_t)(key->key_buffer), 0, 0);
81 if (ret != BORINGSSL_OK) {
82 tloge("sip hash initialize failed!");
83 TEE_Free((void *)siphash_ctx);
84 return get_soft_crypto_error(CRYPTO_BAD_STATE);
85 }
86 ctx->ctx_buffer = (uint64_t)(uintptr_t)siphash_ctx;
87 ctx->ctx_size = sizeof(*siphash_ctx);
88
89 return CRYPTO_SUCCESS;
90 }
91
soft_crypto_hmac_init(struct ctx_handle_t * ctx,const struct symmerit_key_t * key)92 int32_t soft_crypto_hmac_init(struct ctx_handle_t *ctx, const struct symmerit_key_t *key)
93 {
94 bool check = (ctx == NULL || key == NULL || key->key_buffer == 0 || key->key_size == 0);
95 if (check) {
96 tloge("invalid params");
97 return CRYPTO_BAD_PARAMETERS;
98 }
99
100 if (ctx->alg_type == CRYPTO_TYPE_HMAC_SM3)
101 return sm3_mac_init(ctx, key);
102
103 if (ctx->alg_type == CRYPTO_TYPE_SIP_HASH)
104 return sip_hash_mac_init(ctx, key);
105
106 int32_t rc = check_valid_algorithm(ctx->alg_type, g_algorithm_hmac, ARRAY_NUM(g_algorithm_hmac));
107 if (rc != CRYPTO_SUCCESS) {
108 tloge("algorithm 0x%x is incorrect", ctx->alg_type);
109 return rc;
110 }
111
112 const EVP_MD *md = get_hmac_evp(ctx->alg_type);
113 if (md == NULL) {
114 tloge("hmac md is NULL");
115 return CRYPTO_BAD_PARAMETERS;
116 }
117
118 void *hmac_ctx = HMAC_CTX_new();
119 if (hmac_ctx == NULL) {
120 tloge("hmac ctx is NULL");
121 return CRYPTO_BAD_PARAMETERS;
122 }
123
124 uint8_t *key_buffer = (uint8_t *)(uintptr_t)key->key_buffer;
125 rc = HMAC_Init(hmac_ctx, key_buffer, key->key_size, md);
126 if (rc != BORINGSSL_OK) {
127 tloge("hmac init failed! ret = %d\n", rc);
128 HMAC_CTX_free(hmac_ctx);
129 return get_soft_crypto_error(CRYPTO_MAC_INVALID);
130 }
131
132 ctx->ctx_buffer = (uint64_t)(uintptr_t)hmac_ctx;
133 ctx->free_context = free_hmac_context;
134 return CRYPTO_SUCCESS;
135 }
136
sip_hash_mac_update(struct ctx_handle_t * ctx,const struct memref_t * data_in)137 static int32_t sip_hash_mac_update(struct ctx_handle_t *ctx, const struct memref_t *data_in)
138 {
139 if (data_in->size == 0) {
140 tloge("invalid params. data_in size is 0");
141 TEE_Free((void *)(uintptr_t)ctx->ctx_buffer);
142 ctx->ctx_buffer = 0;
143 return CRYPTO_BAD_PARAMETERS;
144 }
145
146 SipHash_Update((SIPHASH *)(uintptr_t)ctx->ctx_buffer, (const uint8_t *)(uintptr_t)data_in->buffer, data_in->size);
147
148 return CRYPTO_SUCCESS;
149 }
150
soft_crypto_hmac_update(struct ctx_handle_t * ctx,const struct memref_t * data_in)151 int32_t soft_crypto_hmac_update(struct ctx_handle_t *ctx, const struct memref_t *data_in)
152 {
153 bool check = (ctx == NULL || ctx->ctx_buffer == 0 || data_in == NULL || data_in->buffer == 0);
154 if (check) {
155 tloge("invalid params");
156 return CRYPTO_BAD_PARAMETERS;
157 }
158
159 if (ctx->alg_type == CRYPTO_TYPE_HMAC_SM3)
160 return sm3_mac_update(ctx, data_in);
161
162 if (ctx->alg_type == CRYPTO_TYPE_SIP_HASH)
163 return sip_hash_mac_update(ctx, data_in);
164
165 uint8_t *in_buffer = (uint8_t *)(uintptr_t)data_in->buffer;
166 int32_t rc = HMAC_Update((HMAC_CTX *)(uintptr_t)(ctx->ctx_buffer), in_buffer, data_in->size);
167 if (rc != BORINGSSL_OK) {
168 tloge("HMAC_Update failed!");
169 return CRYPTO_BAD_PARAMETERS;
170 }
171 return CRYPTO_SUCCESS;
172 }
173
sip_hash_mac_computefinal(struct ctx_handle_t * ctx,struct memref_t * data_out)174 static int32_t sip_hash_mac_computefinal(struct ctx_handle_t *ctx, struct memref_t *data_out)
175 {
176 if (data_out->size < SIP_HASH_OUTPUT_LEN) {
177 tloge("data out size is too short");
178 TEE_Free((void *)(uintptr_t)ctx->ctx_buffer);
179 ctx->ctx_buffer = 0;
180 return CRYPTO_BAD_PARAMETERS;
181 }
182
183 SIPHASH *siphash_ctx = (SIPHASH *)(uintptr_t)ctx->ctx_buffer;
184 uint8_t *out_buffer = (uint8_t *)(uintptr_t)data_out->buffer;
185 uint32_t mac_len_temp = SIP_HASH_OUTPUT_LEN;
186
187 int32_t rc = SipHash_Final(siphash_ctx, out_buffer, mac_len_temp);
188 if (rc != BORINGSSL_OK) {
189 tloge("sip hash mac final failed!");
190 TEE_Free((void *)(uintptr_t)ctx->ctx_buffer);
191 ctx->ctx_buffer = 0;
192 return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
193 }
194
195 data_out->size = mac_len_temp;
196 TEE_Free((void *)(uintptr_t)ctx->ctx_buffer);
197 ctx->ctx_buffer = 0;
198 return CRYPTO_SUCCESS;
199 }
200
soft_crypto_hmac_dofinal(struct ctx_handle_t * ctx,struct memref_t * data_out)201 int32_t soft_crypto_hmac_dofinal(struct ctx_handle_t *ctx, struct memref_t *data_out)
202 {
203 bool check = (ctx == NULL || ctx->ctx_buffer == 0);
204 if (check) {
205 tloge("invalid params");
206 return CRYPTO_BAD_PARAMETERS;
207 }
208
209 check = (data_out == NULL || data_out->buffer == 0);
210 if (check) {
211 tloge("invalid params");
212 free_hmac_context(&(ctx->ctx_buffer));
213 return CRYPTO_BAD_PARAMETERS;
214 }
215
216 if (ctx->alg_type == CRYPTO_TYPE_HMAC_SM3)
217 return sm3_mac_computefinal(ctx, data_out);
218
219 if (ctx->alg_type == CRYPTO_TYPE_SIP_HASH)
220 return sip_hash_mac_computefinal(ctx, data_out);
221
222 uint32_t mac_len_temp = data_out->size;
223 uint8_t *out_buffer = (uint8_t *)(uintptr_t)data_out->buffer;
224
225 int32_t rc = HMAC_Final((HMAC_CTX *)(uintptr_t)(ctx->ctx_buffer), out_buffer, &mac_len_temp);
226 if (rc != BORINGSSL_OK) {
227 tloge("hmac final failed!");
228 free_hmac_context(&(ctx->ctx_buffer));
229 return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
230 }
231
232 data_out->size = mac_len_temp;
233 free_hmac_context(&(ctx->ctx_buffer));
234 return CRYPTO_SUCCESS;
235 }
236
soft_crypto_hmac(uint32_t alg_type,const struct symmerit_key_t * key,const struct memref_t * data_in,struct memref_t * data_out)237 int32_t soft_crypto_hmac(uint32_t alg_type, const struct symmerit_key_t *key,
238 const struct memref_t *data_in, struct memref_t *data_out)
239 {
240 if (alg_type == CRYPTO_TYPE_HMAC_SM3)
241 return crypto_sm3_hmac(key, data_in, data_out);
242
243 bool check = (key == NULL || data_in == NULL || data_out == NULL || data_in->buffer == 0 || data_out->buffer == 0);
244 if (check) {
245 tloge("param is Invalid");
246 return CRYPTO_BAD_PARAMETERS;
247 }
248
249 uint32_t out_len = data_out->size;
250 const EVP_MD *md = get_hmac_evp(alg_type);
251 uint8_t *in_buffer = (uint8_t *)(uintptr_t)data_in->buffer;
252 uint8_t *out_buffer = (uint8_t *)(uintptr_t)data_out->buffer;
253 uint8_t *key_buffer = (uint8_t *)(uintptr_t)key->key_buffer;
254
255 out_buffer = HMAC(md, key_buffer, key->key_size, in_buffer,
256 data_in->size, out_buffer, &out_len);
257 if (data_out->buffer == 0) {
258 tloge("hmac failed");
259 return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
260 }
261 data_out->size = out_len;
262 return CRYPTO_SUCCESS;
263 }
264