1 /*
2 * Copyright (c) 2020-2021 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 #ifdef _CUT_AUTHENTICATE_
23 #undef HKS_SUPPORT_ECDH_C
24 #endif /* _CUT_AUTHENTICATE_ */
25
26 #ifdef HKS_SUPPORT_ECDH_C
27
28 #include "hks_mbedtls_ecdh.h"
29
30 #include <mbedtls/bignum.h>
31 #include <mbedtls/ctr_drbg.h>
32 #include <mbedtls/ecdh.h>
33 #include <mbedtls/ecp.h>
34 #include <mbedtls/entropy.h>
35
36 #include "hks_log.h"
37 #include "hks_mbedtls_common.h"
38 #include "hks_mbedtls_ecc.h"
39 #include "hks_template.h"
40
41 #ifdef HKS_SUPPORT_ECDH_AGREE_KEY
EccKeyMaterialToCtx(const struct HksBlob * nativeKey,const struct HksBlob * pubKey,mbedtls_ecdh_context * ctx)42 static int32_t EccKeyMaterialToCtx(const struct HksBlob *nativeKey,
43 const struct HksBlob *pubKey, mbedtls_ecdh_context *ctx)
44 {
45 int32_t ret = HksEccKeyMaterialToPub(pubKey, &(ctx->MBEDTLS_PRIVATE(Qp)));
46 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Ecc keyMaterial to public key failed! ret = 0x%" LOG_PUBLIC "X", ret)
47
48 ret = HksEccKeyMaterialToPri(nativeKey, &(ctx->MBEDTLS_PRIVATE(d)));
49 HKS_IF_NOT_SUCC_LOGE(ret, "Ecc keyMaterial to private key failed! ret = 0x%" LOG_PUBLIC "X", ret)
50
51 return ret;
52 }
53
HksMbedtlsEcdh(const struct HksBlob * nativeKey,const struct HksBlob * pubKey,const struct HksKeySpec * spec,struct HksBlob * sharedKey)54 int32_t HksMbedtlsEcdh(const struct HksBlob *nativeKey,
55 const struct HksBlob *pubKey, const struct HksKeySpec *spec, struct HksBlob *sharedKey)
56 {
57 int32_t ret = EccKeyCheck(pubKey);
58 HKS_IF_NOT_SUCC_RETURN(ret, ret)
59
60 mbedtls_ecp_group_id mbedtlsCurveNist = MBEDTLS_ECP_DP_NONE;
61 ret = HksMbedtlsEccGetKeyCurveNist((struct KeyMaterialEcc *)(nativeKey->data), &mbedtlsCurveNist);
62 HKS_IF_NOT_SUCC_RETURN(ret, ret)
63
64 mbedtls_ctr_drbg_context ctrDrbg;
65 mbedtls_entropy_context entropy;
66 (void)memset_s(&entropy, sizeof(mbedtls_entropy_context), 0, sizeof(mbedtls_entropy_context));
67 (void)memset_s(&ctrDrbg, sizeof(mbedtls_ctr_drbg_context), 0, sizeof(mbedtls_ctr_drbg_context));
68 ret = HksCtrDrbgSeed(&ctrDrbg, &entropy);
69 HKS_IF_NOT_SUCC_RETURN(ret, ret)
70
71 mbedtls_ecdh_context ctx;
72 (void)memset_s(&ctx, sizeof(mbedtls_ecdh_context), 0, sizeof(mbedtls_ecdh_context));
73 mbedtls_ecdh_init(&ctx);
74
75 do {
76 ret = mbedtls_ecp_group_load(&(ctx.MBEDTLS_PRIVATE(grp)), mbedtlsCurveNist);
77 if (ret != HKS_MBEDTLS_SUCCESS) {
78 HKS_LOG_E("Mbedtls ecdh load group failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
79 break;
80 }
81
82 ret = EccKeyMaterialToCtx(nativeKey, pubKey, &ctx);
83 HKS_IF_NOT_SUCC_BREAK(ret)
84
85 ret = mbedtls_ecdh_compute_shared(&(ctx.MBEDTLS_PRIVATE(grp)), &(ctx.MBEDTLS_PRIVATE(z)),
86 &(ctx.MBEDTLS_PRIVATE(Qp)), &(ctx.MBEDTLS_PRIVATE(d)), mbedtls_ctr_drbg_random, &ctrDrbg);
87 if (ret != HKS_MBEDTLS_SUCCESS) {
88 HKS_LOG_E("Mbedtls ecdh shared key failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
89 break;
90 }
91
92 const uint32_t keyByteLen = HKS_KEY_BYTES(spec->keyLen);
93 ret = mbedtls_mpi_write_binary(&(ctx.MBEDTLS_PRIVATE(z)), sharedKey->data, keyByteLen);
94 if (ret != HKS_MBEDTLS_SUCCESS) {
95 HKS_LOG_E("Mbedtls ecdh mpi write to sharedKey failed! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
96 (void)memset_s(sharedKey->data, sharedKey->size, 0, sharedKey->size);
97 break;
98 }
99 sharedKey->size = keyByteLen;
100 } while (0);
101
102 mbedtls_ecdh_free(&ctx);
103 mbedtls_ctr_drbg_free(&ctrDrbg);
104 mbedtls_entropy_free(&entropy);
105 return ret;
106 }
107 #endif /* HKS_SUPPORT_ECDH_AGREE_KEY */
108 #endif /* HKS_SUPPORT_ECDH_C */
109