1 /*
2 * Copyright (c) 2020-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 #ifdef _CUT_AUTHENTICATE_
23 #undef HKS_SUPPORT_ECDSA_C
24 #endif /* _CUT_AUTHENTICATE_ */
25
26 #ifdef HKS_SUPPORT_ECDSA_C
27
28 #include "hks_mbedtls_ecdsa.h"
29
30 #include <mbedtls/ctr_drbg.h>
31 #include <mbedtls/ecdsa.h>
32 #include <mbedtls/ecp.h>
33 #include <mbedtls/entropy.h>
34
35 #include "hks_log.h"
36 #include "hks_mbedtls_common.h"
37 #include "hks_mbedtls_ecc.h"
38 #include "hks_template.h"
39
40 #ifdef HKS_SUPPORT_ECDSA_SIGN_VERIFY
41 /* users must ensure the input params not null */
HksMbedtlsEcdsaSign(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * signature)42 int32_t HksMbedtlsEcdsaSign(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
43 const struct HksBlob *message, struct HksBlob *signature)
44 {
45 int32_t ret = EccKeyCheck(key);
46 HKS_IF_NOT_SUCC_RETURN(ret, ret)
47
48 mbedtls_ecp_group_id curveNist = MBEDTLS_ECP_DP_NONE;
49 ret = HksMbedtlsEccGetKeyCurveNist((struct KeyMaterialEcc *)(key->data), &curveNist);
50 HKS_IF_NOT_SUCC_RETURN(ret, ret)
51
52 mbedtls_ctr_drbg_context ctrDrbg;
53 mbedtls_entropy_context entropy;
54 (void)memset_s(&entropy, sizeof(mbedtls_entropy_context), 0, sizeof(mbedtls_entropy_context));
55 (void)memset_s(&ctrDrbg, sizeof(mbedtls_ctr_drbg_context), 0, sizeof(mbedtls_ctr_drbg_context));
56 ret = HksCtrDrbgSeed(&ctrDrbg, &entropy);
57 HKS_IF_NOT_SUCC_RETURN(ret, ret)
58
59 mbedtls_ecdsa_context ctx;
60 (void)memset_s(&ctx, sizeof(mbedtls_ecdsa_context), 0, sizeof(mbedtls_ecdsa_context));
61 mbedtls_ecdsa_init(&ctx);
62
63 do {
64 ret = mbedtls_ecp_group_load(&(ctx.MBEDTLS_PRIVATE(grp)), curveNist);
65 if (ret != HKS_MBEDTLS_SUCCESS) {
66 HKS_LOG_E("Mbedtls ecp group load fail! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
67 break;
68 }
69
70 ret = HksEccKeyMaterialToPri(key, &(ctx.MBEDTLS_PRIVATE(d)));
71 HKS_IF_NOT_SUCC_BREAK(ret)
72
73 mbedtls_md_type_t mbedtlsAlg;
74 uint32_t digest = (usageSpec->digest == HKS_DIGEST_NONE) ? HKS_DIGEST_SHA256 : usageSpec->digest;
75 ret = HksToMbedtlsDigestAlg(digest, &mbedtlsAlg);
76 HKS_IF_NOT_SUCC_BREAK(ret)
77 size_t keyLen = (size_t)(signature->size);
78 ret = mbedtls_ecdsa_write_signature(&ctx, (mbedtls_md_type_t)mbedtlsAlg, message->data, (size_t)message->size,
79 signature->data, keyLen, &keyLen, mbedtls_ctr_drbg_random, &ctrDrbg);
80 signature->size = (uint32_t)keyLen;
81 if (ret != HKS_MBEDTLS_SUCCESS || keyLen != (size_t)(signature->size)) {
82 HKS_LOG_E("Ecc mbedtls sign fail! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
83 (void)memset_s(signature->data, signature->size, 0, signature->size);
84 ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
85 }
86 } while (0);
87
88 mbedtls_ctr_drbg_free(&ctrDrbg);
89 mbedtls_entropy_free(&entropy);
90 mbedtls_ecdsa_free(&ctx);
91 return ret;
92 }
93
94 /* users must ensure the input params not null */
HksMbedtlsEcdsaVerify(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const struct HksBlob * signature)95 int32_t HksMbedtlsEcdsaVerify(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
96 const struct HksBlob *message, const struct HksBlob *signature)
97 {
98 (void)usageSpec;
99 int32_t ret = EccKeyCheck(key);
100 HKS_IF_NOT_SUCC_RETURN(ret, ret)
101
102 mbedtls_ecp_group_id curveNist = MBEDTLS_ECP_DP_NONE;
103 ret = HksMbedtlsEccGetKeyCurveNist((struct KeyMaterialEcc *)(key->data), &curveNist);
104 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Get ecc KeyCureNist fail! ret = 0x%" LOG_PUBLIC "X", ret)
105
106 mbedtls_ecdsa_context ctx;
107 (void)memset_s(&ctx, sizeof(mbedtls_ecdsa_context), 0, sizeof(mbedtls_ecdsa_context));
108 mbedtls_ecdsa_init(&ctx);
109
110 do {
111 ret = mbedtls_ecp_group_load(&(ctx.MBEDTLS_PRIVATE(grp)), curveNist);
112 if (ret != HKS_MBEDTLS_SUCCESS) {
113 HKS_LOG_E("Mbedtls ecp group load fail! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
114 break;
115 }
116
117 ret = HksEccKeyMaterialToPub(key, &(ctx.MBEDTLS_PRIVATE(Q)));
118 HKS_IF_NOT_SUCC_BREAK(ret)
119
120 ret = mbedtls_ecdsa_read_signature(&ctx,
121 message->data, message->size, signature->data, signature->size);
122 if (ret != HKS_MBEDTLS_SUCCESS) {
123 HKS_LOG_E("Ecc mbedtls verify fail! mbedtls ret = 0x%" LOG_PUBLIC "X", ret);
124 ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
125 }
126 } while (0);
127
128 mbedtls_ecdsa_free(&ctx);
129 return ret;
130 }
131 #endif /* HKS_SUPPORT_ECDSA_SIGN_VERIFY */
132 #endif /* HKS_SUPPORT_ECDSA_C */
133