1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21
22 #include "hks_client_service_adapter.h"
23
24 #include <mbedtls/bignum.h>
25 #include <mbedtls/ecp.h>
26 #include <mbedtls/pk.h>
27 #include <mbedtls/rsa.h>
28
29 #include "hks_log.h"
30 #include "hks_mbedtls_common.h"
31 #include "hks_mbedtls_ecc.h"
32 #include "hks_mem.h"
33 #include "hks_template.h"
34
35 #ifdef _CUT_AUTHENTICATE_
36 #undef HKS_SUPPORT_HASH_C
37 #undef HKS_SUPPORT_RSA_C
38 #undef HKS_SUPPORT_ECC_C
39 #undef HKS_SUPPORT_X25519_C
40 #undef HKS_SUPPORT_ED25519_C
41 #undef HKS_SUPPORT_KDF_PBKDF2
42 #endif /* _CUT_AUTHENTICATE_ */
43
44 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C)
PkCtxToX509(mbedtls_pk_context * ctx,struct HksBlob * x509Key)45 static int32_t PkCtxToX509(mbedtls_pk_context *ctx, struct HksBlob *x509Key)
46 {
47 uint8_t *tmpBuf = (uint8_t *)HksMalloc(MAX_KEY_SIZE);
48 HKS_IF_NULL_RETURN(tmpBuf, HKS_ERROR_MALLOC_FAIL)
49
50 int32_t ret = HKS_SUCCESS;
51 do {
52 int32_t x509Size = mbedtls_pk_write_pubkey_der(ctx, tmpBuf, MAX_KEY_SIZE);
53 if (x509Size < HKS_MBEDTLS_SUCCESS) {
54 HKS_LOG_E("public key to x509 write der failed! mbedtls ret = 0x%" LOG_PUBLIC "X", x509Size);
55 ret = x509Size;
56 break;
57 }
58
59 uint8_t *x509KeyData = (uint8_t *)HksMalloc(x509Size);
60 if (x509KeyData == NULL) {
61 HKS_LOG_E("Malloc x509 key data failed!");
62 ret = HKS_ERROR_MALLOC_FAIL;
63 break;
64 }
65
66 /* mbedtls_pk_write_pubkey_der use little-endian for storage */
67 if (memcpy_s(x509KeyData, x509Size, tmpBuf + MAX_KEY_SIZE - x509Size, x509Size) != EOK) {
68 HKS_LOG_E("public key to x509 memcpy to x509key failed!");
69 HKS_FREE(x509KeyData);
70 ret = HKS_ERROR_INSUFFICIENT_MEMORY;
71 break;
72 }
73
74 x509Key->size = x509Size;
75 x509Key->data = x509KeyData;
76 } while (0);
77
78 HKS_FREE(tmpBuf);
79 return ret;
80 }
81
82 #ifdef HKS_SUPPORT_RSA_C
InitRsaPkCtx(const struct HksBlob * mod,const struct HksBlob * e,mbedtls_pk_context * ctx)83 static int32_t InitRsaPkCtx(const struct HksBlob *mod, const struct HksBlob *e, mbedtls_pk_context *ctx)
84 {
85 int32_t ret = mbedtls_pk_setup(ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
86 if (ret != HKS_MBEDTLS_SUCCESS) {
87 HKS_LOG_E("Mbedtls setup pk context failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
88 return ret;
89 }
90
91 mbedtls_mpi mpiN;
92 mbedtls_mpi mpiE;
93
94 mbedtls_mpi_init(&mpiN);
95 mbedtls_mpi_init(&mpiE);
96
97 do {
98 ret = mbedtls_mpi_read_binary(&mpiN, mod->data, mod->size);
99 if (ret != HKS_MBEDTLS_SUCCESS) {
100 HKS_LOG_E("Hks init rsa pk context read N failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
101 break;
102 }
103
104 ret = mbedtls_mpi_read_binary(&mpiE, e->data, e->size);
105 if (ret != HKS_MBEDTLS_SUCCESS) {
106 HKS_LOG_E("Hks init rsa pk context read E failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
107 break;
108 }
109
110 mbedtls_rsa_context *rsaCtx = mbedtls_pk_rsa(*ctx);
111 ret = mbedtls_rsa_import(rsaCtx, &mpiN, NULL, NULL, NULL, &mpiE);
112 if (ret != HKS_MBEDTLS_SUCCESS) {
113 HKS_LOG_E("Hks init rsa pk context import rsa context failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
114 break;
115 }
116
117 ret = mbedtls_rsa_complete(rsaCtx);
118 if (ret != HKS_MBEDTLS_SUCCESS) {
119 HKS_LOG_E("Hks init rsa pk context complete rsa context failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
120 }
121 } while (0);
122
123 mbedtls_mpi_free(&mpiN);
124 mbedtls_mpi_free(&mpiE);
125 return ret;
126 }
127
RsaToX509PublicKey(const struct HksBlob * mod,const struct HksBlob * e,struct HksBlob * x509Key)128 static int32_t RsaToX509PublicKey(const struct HksBlob *mod, const struct HksBlob *e, struct HksBlob *x509Key)
129 {
130 mbedtls_pk_context ctx;
131 mbedtls_pk_init(&ctx);
132
133 int32_t ret;
134 do {
135 ret = InitRsaPkCtx(mod, e, &ctx);
136 HKS_IF_NOT_SUCC_BREAK(ret)
137
138 ret = PkCtxToX509(&ctx, x509Key);
139 HKS_IF_NOT_SUCC_LOGE(ret, "Pk context to rsa x509 failed! ret = 0x%" LOG_PUBLIC "X", ret)
140 } while (0);
141
142 mbedtls_pk_free(&ctx);
143 return ret;
144 }
145 #endif
146
147 #ifdef HKS_SUPPORT_ECC_C
InitEccPkCtx(uint32_t keySize,const struct HksBlob * x,const struct HksBlob * y,mbedtls_pk_context * ctx)148 static int32_t InitEccPkCtx(uint32_t keySize, const struct HksBlob *x, const struct HksBlob *y,
149 mbedtls_pk_context *ctx)
150 {
151 int32_t ret = mbedtls_pk_setup(ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY));
152 if (ret != HKS_MBEDTLS_SUCCESS) {
153 HKS_LOG_E("Mbedtls setup pk context failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
154 return ret;
155 }
156
157 mbedtls_ecp_group_id grp_id;
158 ret = GetEccGroupId(keySize, &grp_id);
159 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Get ecc group id failed! ret = 0x%" LOG_PUBLIC "X", ret)
160
161 mbedtls_ecp_keypair *pubKey = mbedtls_pk_ec(*ctx);
162 ret = mbedtls_ecp_group_load(&(pubKey->MBEDTLS_PRIVATE(grp)), grp_id);
163 if (ret != HKS_MBEDTLS_SUCCESS) {
164 HKS_LOG_E("Hks init ecc pk context load group failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
165 return ret;
166 }
167
168 ret = mbedtls_mpi_read_binary(&(pubKey->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), x->data, x->size);
169 if (ret != HKS_MBEDTLS_SUCCESS) {
170 HKS_LOG_E("Hks init ecc pk context read X failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
171 return ret;
172 }
173
174 ret = mbedtls_mpi_read_binary(&(pubKey->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), y->data, y->size);
175 if (ret != HKS_MBEDTLS_SUCCESS) {
176 HKS_LOG_E("Hks init ecc pk context read Y failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
177 return ret;
178 }
179
180 /* Z = 1, X and Y are its standard (affine) coordinates */
181 ret = mbedtls_mpi_lset(&(pubKey->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z)), 1);
182 if (ret != HKS_MBEDTLS_SUCCESS) {
183 HKS_LOG_E("Hks init ecc pk context set Z failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
184 return ret;
185 }
186
187 return HKS_SUCCESS;
188 }
189
EccToX509PublicKey(uint32_t keySize,const struct HksBlob * x,const struct HksBlob * y,struct HksBlob * x509Key)190 static int32_t EccToX509PublicKey(uint32_t keySize, const struct HksBlob *x, const struct HksBlob *y,
191 struct HksBlob *x509Key)
192 {
193 mbedtls_pk_context ctx;
194 mbedtls_pk_init(&ctx);
195
196 int32_t ret;
197 do {
198 ret = InitEccPkCtx(keySize, x, y, &ctx);
199 HKS_IF_NOT_SUCC_BREAK(ret)
200
201 ret = PkCtxToX509(&ctx, x509Key);
202 HKS_IF_NOT_SUCC_LOGE(ret, "Pk context to ecc x509 failed! ret = 0x%" LOG_PUBLIC "X", ret)
203 } while (0);
204
205 mbedtls_pk_free(&ctx);
206 return ret;
207 }
208 #endif
209 #endif
210
211 #if defined(HKS_SUPPORT_X25519_C) || defined(HKS_SUPPORT_ED25519_C)
Curve25519ToX509PublicKey(const struct HksBlob * publicKey,struct HksBlob * x509Key)212 static int32_t Curve25519ToX509PublicKey(const struct HksBlob *publicKey, struct HksBlob *x509Key)
213 {
214 if (publicKey->size != HKS_KEY_BYTES(HKS_CURVE25519_KEY_SIZE_256)) {
215 HKS_LOG_E("Invalid public key size! key size = 0x%" LOG_PUBLIC "X", publicKey->size);
216 return HKS_ERROR_INVALID_ARGUMENT;
217 }
218
219 x509Key->data = (uint8_t *)HksMalloc(publicKey->size);
220 HKS_IF_NULL_LOGE_RETURN(x509Key->data, HKS_ERROR_MALLOC_FAIL,
221 "X25519/Ed25519 to x509 public key malloc x509 key data failed!")
222
223 if (memcpy_s(x509Key->data, publicKey->size, publicKey->data, publicKey->size) != EOK) {
224 HKS_LOG_E("X25519/Ed25519 to x509 public key memcpy to x509 key data failed!");
225 HKS_FREE(x509Key->data);
226 return HKS_ERROR_INSUFFICIENT_MEMORY;
227 }
228 x509Key->size = publicKey->size;
229
230 return HKS_SUCCESS;
231 }
232 #endif
233
TranslateToX509PublicKey(const struct HksBlob * publicKey,struct HksBlob * x509Key)234 int32_t TranslateToX509PublicKey(const struct HksBlob *publicKey, struct HksBlob *x509Key)
235 {
236 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C) || defined(HKS_SUPPORT_X25519_C) || \
237 defined(HKS_SUPPORT_ED25519_C)
238 if ((publicKey == NULL) || (publicKey->data == NULL) || (publicKey->size == 0) || (x509Key == NULL)) {
239 HKS_LOG_E("translate to x509 public key invalid args");
240 return HKS_ERROR_INVALID_ARGUMENT;
241 }
242
243 if (publicKey->size < sizeof(struct HksPubKeyInfo)) {
244 HKS_LOG_E("translate to x509 public key invalid publicKey size");
245 return HKS_ERROR_INVALID_ARGUMENT;
246 }
247
248 struct HksPubKeyInfo *publicKeyInfo = (struct HksPubKeyInfo *)publicKey->data;
249 uint32_t offset = sizeof(struct HksPubKeyInfo);
250 if ((publicKey->size - offset) < publicKeyInfo->nOrXSize) {
251 HKS_LOG_E("translate to x509 public key invalid nOrXSize size");
252 return HKS_ERROR_INVALID_ARGUMENT;
253 }
254
255 struct HksBlob material1 = { publicKeyInfo->nOrXSize, publicKey->data + offset };
256 offset += publicKeyInfo->nOrXSize;
257 if ((publicKey->size - offset) < publicKeyInfo->eOrYSize) {
258 HKS_LOG_E("translate to x509 public key invalid eOrYSize size");
259 return HKS_ERROR_INVALID_ARGUMENT;
260 }
261
262 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C)
263 struct HksBlob material2 = { publicKeyInfo->eOrYSize, publicKey->data + offset };
264 #endif
265 switch (publicKeyInfo->keyAlg) {
266 #ifdef HKS_SUPPORT_RSA_C
267 case HKS_ALG_RSA:
268 return RsaToX509PublicKey(&material1, &material2, x509Key);
269 #endif
270 #ifdef HKS_SUPPORT_ECC_C
271 case HKS_ALG_ECC:
272 return EccToX509PublicKey(publicKeyInfo->keySize, &material1, &material2, x509Key);
273 #endif
274 #if defined(HKS_SUPPORT_X25519_C) || defined(HKS_SUPPORT_ED25519_C)
275 case HKS_ALG_X25519:
276 case HKS_ALG_ED25519:
277 return Curve25519ToX509PublicKey(&material1, x509Key);
278 #endif
279 default:
280 HKS_LOG_E("Unsupport alg type! type = 0x%" LOG_PUBLIC "X", publicKeyInfo->keyAlg);
281 return HKS_ERROR_INVALID_ARGUMENT;
282 }
283 #else
284 (void)publicKey;
285 (void)x509Key;
286 return HKS_ERROR_NOT_SUPPORTED;
287 #endif
288 }
289
290 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C)
291 #ifdef HKS_SUPPORT_RSA_C
CheckRsaCtx(const mbedtls_rsa_context * rsaCtx)292 static int32_t CheckRsaCtx(const mbedtls_rsa_context *rsaCtx)
293 {
294 uint32_t maxKeyByteLen = HKS_RSA_KEY_SIZE_4096 / HKS_BITS_PER_BYTE;
295 if (rsaCtx->MBEDTLS_PRIVATE(len) > maxKeyByteLen) {
296 HKS_LOG_E("Invalid mbedtls rsa context's len! len = 0x%" LOG_PUBLIC "zu", rsaCtx->MBEDTLS_PRIVATE(len));
297 return HKS_ERROR_INVALID_ARGUMENT;
298 }
299
300 return HKS_SUCCESS;
301 }
302
X509PublicKeyToRsa(mbedtls_rsa_context * rsaCtx,struct HksBlob * rsaPublicKey)303 static int32_t X509PublicKeyToRsa(mbedtls_rsa_context *rsaCtx, struct HksBlob *rsaPublicKey)
304 {
305 int32_t ret = CheckRsaCtx(rsaCtx);
306 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Check rsa ctx failed! ret = 0x%" LOG_PUBLIC "X", ret)
307
308 uint32_t nSize = rsaCtx->MBEDTLS_PRIVATE(len);
309 uint32_t eSize = rsaCtx->MBEDTLS_PRIVATE(len);
310
311 uint32_t totalSize = sizeof(struct HksPubKeyInfo) + nSize + eSize;
312 uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
313 HKS_IF_NULL_LOGE_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL,
314 "X509 public key to rsa malloc keyBuffer failed!")
315
316 struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)keyBuffer;
317 pubKeyInfo->keyAlg = HKS_ALG_RSA;
318 pubKeyInfo->keySize = rsaCtx->MBEDTLS_PRIVATE(len) * HKS_BITS_PER_BYTE;
319 pubKeyInfo->nOrXSize = nSize;
320 pubKeyInfo->eOrYSize = eSize;
321 pubKeyInfo->placeHolder = 0;
322
323 ret = mbedtls_mpi_write_binary(&rsaCtx->MBEDTLS_PRIVATE(N), keyBuffer + sizeof(struct HksPubKeyInfo), nSize);
324 if (ret != HKS_MBEDTLS_SUCCESS) {
325 HKS_LOG_E("X509 public key to rsa write N failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
326 HKS_FREE(keyBuffer);
327 return ret;
328 }
329
330 ret = mbedtls_mpi_write_binary(&rsaCtx->MBEDTLS_PRIVATE(E),
331 keyBuffer + sizeof(struct HksPubKeyInfo) + nSize, eSize);
332 if (ret != HKS_MBEDTLS_SUCCESS) {
333 HKS_LOG_E("X509 public key to rsa write E failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
334 HKS_FREE(keyBuffer);
335 return ret;
336 }
337
338 rsaPublicKey->data = keyBuffer;
339 rsaPublicKey->size = totalSize;
340
341 return HKS_SUCCESS;
342 }
343 #endif
344
345 #ifdef HKS_SUPPORT_ECC_C
CheckEccXySize(const uint32_t xSize,const uint32_t ySize)346 static int32_t CheckEccXySize(const uint32_t xSize, const uint32_t ySize)
347 {
348 uint32_t maxKeyByteLen = HKS_ECC_KEY_SIZE_521 / HKS_BITS_PER_BYTE;
349 if ((xSize > maxKeyByteLen) || (ySize > maxKeyByteLen)) {
350 HKS_LOG_E("Invalid ecc public key size! xSize = 0x%" LOG_PUBLIC "X, ySize = 0x%" LOG_PUBLIC "X", xSize, ySize);
351 return HKS_ERROR_INVALID_ARGUMENT;
352 }
353
354 return HKS_SUCCESS;
355 }
356
X509PublicKeyToEcc(mbedtls_ecp_keypair * pubKey,struct HksBlob * eccPublicKey)357 static int32_t X509PublicKeyToEcc(mbedtls_ecp_keypair *pubKey, struct HksBlob *eccPublicKey)
358 {
359 /* When converting from X509 to internal format, the first byte needs to be filled with 0 */
360 uint32_t xSize = mbedtls_mpi_size(&(pubKey->MBEDTLS_PRIVATE(grp).P));
361 uint32_t ySize = mbedtls_mpi_size(&(pubKey->MBEDTLS_PRIVATE(grp).P));
362
363 int32_t ret = CheckEccXySize(xSize, ySize);
364 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Check ecc public key size failed! ret = 0x%" LOG_PUBLIC "X", ret)
365
366 uint32_t totalSize = sizeof(struct HksPubKeyInfo) + xSize + ySize;
367 uint8_t *keyBuffer = (uint8_t *)HksMalloc(totalSize);
368 HKS_IF_NULL_LOGE_RETURN(keyBuffer, HKS_ERROR_MALLOC_FAIL,
369 "X509 public key to ecc malloc keyBuffer failed!")
370
371 if (mbedtls_mpi_size(&(pubKey->MBEDTLS_PRIVATE(grp).P)) > UINT32_MAX / HKS_BITS_PER_BYTE) {
372 HKS_FREE(keyBuffer);
373 HKS_LOG_E("invalid param, the size is :%" LOG_PUBLIC "zu", mbedtls_mpi_size(&(pubKey->MBEDTLS_PRIVATE(grp).P)));
374 return HKS_ERROR_INVALID_ARGUMENT;
375 }
376
377 struct HksPubKeyInfo *pubKeyInfo = (struct HksPubKeyInfo *)keyBuffer;
378 pubKeyInfo->keyAlg = HKS_ALG_ECC;
379 pubKeyInfo->keySize = mbedtls_mpi_size(&(pubKey->MBEDTLS_PRIVATE(grp).P)) * HKS_BITS_PER_BYTE;
380 pubKeyInfo->nOrXSize = xSize;
381 pubKeyInfo->eOrYSize = ySize;
382 pubKeyInfo->placeHolder = 0;
383
384 ret = mbedtls_mpi_write_binary(&(pubKey->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)),
385 keyBuffer + sizeof(struct HksPubKeyInfo), xSize);
386 if (ret != HKS_MBEDTLS_SUCCESS) {
387 HKS_LOG_E("X509 public key to ecc write X failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
388 HKS_FREE(keyBuffer);
389 return ret;
390 }
391
392 ret = mbedtls_mpi_write_binary(&(pubKey->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)),
393 keyBuffer + sizeof(struct HksPubKeyInfo) + xSize, ySize);
394 if (ret != HKS_MBEDTLS_SUCCESS) {
395 HKS_LOG_E("X509 public key to ecc write Y failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
396 HKS_FREE(keyBuffer);
397 return ret;
398 }
399
400 eccPublicKey->data = keyBuffer;
401 eccPublicKey->size = totalSize;
402
403 return HKS_SUCCESS;
404 }
405 #endif
406 #endif
407
TranslateFromX509PublicKey(const uint32_t alg,const struct HksBlob * x509Key,struct HksBlob * publicKey)408 int32_t TranslateFromX509PublicKey(const uint32_t alg, const struct HksBlob *x509Key, struct HksBlob *publicKey)
409 {
410 (void)alg;
411 #if defined(HKS_SUPPORT_RSA_C) || defined(HKS_SUPPORT_ECC_C)
412 mbedtls_pk_context ctx;
413 mbedtls_pk_init(&ctx);
414
415 int32_t ret = mbedtls_pk_parse_public_key(&ctx, x509Key->data, x509Key->size);
416 if (ret != HKS_MBEDTLS_SUCCESS) {
417 mbedtls_pk_free(&ctx);
418 return HKS_ERROR_INVALID_ARGUMENT;
419 }
420
421 /* 1: if the context can do operations on the given type. */
422 if (mbedtls_pk_can_do(&ctx, MBEDTLS_PK_RSA) == 1) {
423 #ifdef HKS_SUPPORT_RSA_C
424 ret = X509PublicKeyToRsa(mbedtls_pk_rsa(ctx), publicKey);
425 #else
426 ret = HKS_ERROR_INVALID_ALGORITHM;
427 #endif
428 } else if (mbedtls_pk_can_do(&ctx, MBEDTLS_PK_ECKEY) == 1) {
429 #ifdef HKS_SUPPORT_ECC_C
430 ret = X509PublicKeyToEcc(mbedtls_pk_ec(ctx), publicKey);
431 #else
432 ret = HKS_ERROR_INVALID_ALGORITHM;
433 #endif
434 } else {
435 HKS_LOG_E("Unsupport alg type!");
436 ret = HKS_ERROR_INVALID_ARGUMENT;
437 }
438
439 mbedtls_pk_free(&ctx);
440 return ret;
441 #else
442 (void)publicKey;
443 (void)x509Key;
444 return HKS_ERROR_NOT_SUPPORTED;
445 #endif
446 }
447
448