1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_PKEY)
18
19 #include <stdbool.h>
20 #include <securec.h>
21 #include "bsl_sal.h"
22 #include "crypt_eal_pkey.h"
23 #include "crypt_errno.h"
24 #include "eal_pkey_local.h"
25 #include "crypt_algid.h"
26 #include "bsl_err_internal.h"
27 #include "eal_common.h"
28
CRYPT_EAL_PkeyEncrypt(const CRYPT_EAL_PkeyCtx * pkey,const uint8_t * data,uint32_t dataLen,uint8_t * out,uint32_t * outLen)29 int32_t CRYPT_EAL_PkeyEncrypt(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *data, uint32_t dataLen,
30 uint8_t *out, uint32_t *outLen)
31 {
32 if (pkey == NULL) {
33 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT);
34 return CRYPT_NULL_INPUT;
35 }
36 if (pkey->method == NULL || pkey->method->encrypt == NULL) {
37 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT);
38 return CRYPT_EAL_ALG_NOT_SUPPORT;
39 }
40
41 return pkey->method->encrypt(pkey->key, data, dataLen, out, outLen);
42 }
43
CRYPT_EAL_PkeyDecrypt(const CRYPT_EAL_PkeyCtx * pkey,const uint8_t * data,uint32_t dataLen,uint8_t * out,uint32_t * outLen)44 int32_t CRYPT_EAL_PkeyDecrypt(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *data, uint32_t dataLen,
45 uint8_t *out, uint32_t *outLen)
46 {
47 if (pkey == NULL) {
48 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT);
49 return CRYPT_NULL_INPUT;
50 }
51 if (pkey->method == NULL || pkey->method->decrypt == NULL) {
52 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, pkey->id, CRYPT_EAL_ALG_NOT_SUPPORT);
53 return CRYPT_EAL_ALG_NOT_SUPPORT;
54 }
55
56 return pkey->method->decrypt(pkey->key, data, dataLen, out, outLen);
57 }
58
59 #ifdef HITLS_CRYPTO_RSA
CryptRsaEmsaPairSet(CRYPT_EAL_PkeyCtx * pubKey,CRYPT_EAL_PkeyCtx * prvKey,CRYPT_MD_AlgId hashId)60 static int32_t CryptRsaEmsaPairSet(CRYPT_EAL_PkeyCtx *pubKey, CRYPT_EAL_PkeyCtx *prvKey, CRYPT_MD_AlgId hashId)
61 {
62 int32_t mdId = hashId;
63 int32_t ret = CRYPT_EAL_PkeyCtrl(pubKey, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &mdId, sizeof(mdId));
64 if (ret != CRYPT_SUCCESS) {
65 return ret;
66 }
67 return CRYPT_EAL_PkeyCtrl(prvKey, CRYPT_CTRL_SET_RSA_EMSA_PKCSV15, &mdId, sizeof(mdId));
68 }
69 #endif
70
71 #ifdef HITLS_CRYPTO_SM2
CryptSm2PairSet(CRYPT_EAL_PkeyCtx * pubKey,CRYPT_EAL_PkeyCtx * prvKey)72 static int32_t CryptSm2PairSet(CRYPT_EAL_PkeyCtx *pubKey, CRYPT_EAL_PkeyCtx *prvKey)
73 {
74 char *userId = "1234567812345678";
75 int32_t ret = CRYPT_EAL_PkeyCtrl(pubKey, CRYPT_CTRL_SET_SM2_USER_ID, (void *)userId, strlen(userId));
76 if (ret != CRYPT_SUCCESS) {
77 return ret;
78 }
79 return CRYPT_EAL_PkeyCtrl(prvKey, CRYPT_CTRL_SET_SM2_USER_ID, (void *)userId, strlen(userId));
80 }
81 #endif
82
83 #if defined(HITLS_CRYPTO_DSA) || defined(HITLS_CRYPTO_ECDSA) || defined(HITLS_CRYPTO_RSA)
GetSupportedHashId(void)84 static int32_t GetSupportedHashId(void)
85 {
86 #ifdef HITLS_CRYPTO_SHA512
87 return CRYPT_MD_SHA512; // Priority use sha512
88 #elif defined(HITLS_CRYPTO_SHA256)
89 return CRYPT_MD_SHA256;
90 #elif defined(HITLS_CRYPTO_SHA1)
91 return CRYPT_MD_SHA1;
92 #elif defined(HITLS_CRYPTO_SM3)
93 return CRYPT_MD_SM3;
94 #elif defined(HITLS_CRYPTO_MD5)
95 return CRYPT_MD_MD5;
96 #endif
97 return CRYPT_MD_MAX;
98 }
99 #endif
100
CryptSetSignParams(CRYPT_EAL_PkeyCtx * pubKey,CRYPT_EAL_PkeyCtx * privKey,CRYPT_MD_AlgId * hashId)101 static int32_t CryptSetSignParams(CRYPT_EAL_PkeyCtx *pubKey, CRYPT_EAL_PkeyCtx *privKey, CRYPT_MD_AlgId *hashId)
102 {
103 #if !defined(HITLS_CRYPTO_RSA) && !defined(HITLS_CRYPTO_SM2)
104 (void)privKey;
105 #endif
106
107 *hashId = CRYPT_MD_SHA512;
108 switch (CRYPT_EAL_PkeyGetId(pubKey)) {
109 #ifdef HITLS_CRYPTO_ED25519
110 case CRYPT_PKEY_ED25519:
111 return CRYPT_SUCCESS;
112 #endif
113 #if defined(HITLS_CRYPTO_DSA) || defined(HITLS_CRYPTO_ECDSA)
114 case CRYPT_PKEY_DSA:
115 case CRYPT_PKEY_ECDSA:
116 *hashId = GetSupportedHashId();
117 return CRYPT_SUCCESS;
118 #endif
119 #ifdef HITLS_CRYPTO_RSA
120 case CRYPT_PKEY_RSA:
121 *hashId = GetSupportedHashId();
122 return CryptRsaEmsaPairSet(pubKey, privKey, *hashId);
123 #endif
124 #ifdef HITLS_CRYPTO_SM2
125 case CRYPT_PKEY_SM2:
126 *hashId = CRYPT_MD_SM3;
127 return CryptSm2PairSet(pubKey, privKey);
128 #endif
129 default:
130 return CRYPT_SUCCESS;
131 }
132 }
133
CRYPT_EAL_PkeyPairCheck(CRYPT_EAL_PkeyCtx * pubKey,CRYPT_EAL_PkeyCtx * prvKey)134 int32_t CRYPT_EAL_PkeyPairCheck(CRYPT_EAL_PkeyCtx *pubKey, CRYPT_EAL_PkeyCtx *prvKey)
135 {
136 if ((pubKey == NULL) || (prvKey == NULL)) {
137 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_PKEY, CRYPT_PKEY_MAX, CRYPT_NULL_INPUT);
138 return CRYPT_NULL_INPUT;
139 }
140 int32_t ret = CRYPT_SUCCESS;
141 uint8_t *signedData = NULL;
142 uint32_t signedLen;
143 CRYPT_MD_AlgId hashId;
144 uint8_t toBeSig[] = {1};
145 CRYPT_EAL_PkeyCtx *tempPubKey = CRYPT_EAL_PkeyDupCtx(pubKey);
146 CRYPT_EAL_PkeyCtx *tempPrivKey = CRYPT_EAL_PkeyDupCtx(prvKey);
147 if (tempPubKey == NULL || tempPrivKey == NULL) {
148 ret = CRYPT_MEM_ALLOC_FAIL;
149 goto EXIT;
150 }
151 ret = CryptSetSignParams(tempPubKey, tempPrivKey, &hashId);
152 if (ret != CRYPT_SUCCESS) {
153 goto EXIT;
154 }
155 signedLen = CRYPT_EAL_PkeyGetSignLen(tempPrivKey);
156 if (signedLen == 0) {
157 signedLen = CRYPT_EAL_PkeyGetSignLen(tempPubKey);
158 if (signedLen == 0) {
159 ret = CRYPT_ECC_PKEY_ERR_SIGN_LEN;
160 goto EXIT;
161 }
162 }
163 signedData = BSL_SAL_Malloc(signedLen);
164 if (signedData == NULL) {
165 ret = CRYPT_MEM_ALLOC_FAIL;
166 goto EXIT;
167 }
168 ret = CRYPT_EAL_PkeySign(tempPrivKey, hashId, toBeSig, sizeof(toBeSig), signedData, &signedLen);
169 if (ret != CRYPT_SUCCESS) {
170 goto EXIT;
171 }
172 ret = CRYPT_EAL_PkeyVerify(tempPubKey, hashId, toBeSig, sizeof(toBeSig), signedData, signedLen);
173 EXIT:
174 BSL_SAL_FREE(signedData);
175 CRYPT_EAL_PkeyFreeCtx(tempPubKey);
176 CRYPT_EAL_PkeyFreeCtx(tempPrivKey);
177 return ret;
178 }
179 #endif
180