• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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