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 "securec.h"
17 #include "crypt_eal_pkey.h"
18 #include "crypt_eal_rand.h"
19 #include "auth_params.h"
20 #include "auth_errno.h"
21 #include "bsl_errno.h"
22 #include "bsl_err_internal.h"
23 #include "crypt_eal_md.h"
24 #include "crypt_eal_rand.h"
25 #include "crypt_errno.h"
26 #include "crypt_eal_codecs.h"
27 #include "auth_privpass_token.h"
28 #include "privpass_token.h"
29 #include "bsl_sal.h"
30
PrivPassNewPkeyCtx(void * libCtx,const char * attrName,int32_t algId)31 void *PrivPassNewPkeyCtx(void *libCtx, const char *attrName, int32_t algId)
32 {
33 (void)libCtx;
34 (void)attrName;
35 return CRYPT_EAL_PkeyNewCtx(algId);
36 }
37
PrivPassFreePkeyCtx(void * pkeyCtx)38 void PrivPassFreePkeyCtx(void *pkeyCtx)
39 {
40 CRYPT_EAL_PkeyFreeCtx(pkeyCtx);
41 }
42
PrivPassPubDigest(void * libCtx,const char * attrName,int32_t algId,const uint8_t * input,uint32_t inputLen,uint8_t * digest,uint32_t * digestLen)43 int32_t PrivPassPubDigest(void *libCtx, const char *attrName, int32_t algId, const uint8_t *input, uint32_t inputLen,
44 uint8_t *digest, uint32_t *digestLen)
45 {
46 (void)libCtx;
47 (void)attrName;
48 if (input == NULL || inputLen == 0 || digest == NULL || digestLen == NULL) {
49 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
50 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
51 }
52 uint32_t mdSize = CRYPT_EAL_MdGetDigestSize(algId);
53 if (mdSize == 0) {
54 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
55 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
56 }
57 if (*digestLen < mdSize) {
58 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
59 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
60 }
61 CRYPT_EAL_MdCTX *ctx = CRYPT_EAL_MdNewCtx(algId);
62 if (ctx == NULL) {
63 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
64 return BSL_MALLOC_FAIL;
65 }
66 int32_t ret = CRYPT_EAL_MdInit(ctx);
67 if (ret != CRYPT_SUCCESS) {
68 BSL_ERR_PUSH_ERROR(ret);
69 CRYPT_EAL_MdFreeCtx(ctx);
70 return ret;
71 }
72 ret = CRYPT_EAL_MdUpdate(ctx, input, inputLen);
73 if (ret != CRYPT_SUCCESS) {
74 BSL_ERR_PUSH_ERROR(ret);
75 CRYPT_EAL_MdFreeCtx(ctx);
76 return ret;
77 }
78 ret = CRYPT_EAL_MdFinal(ctx, digest, digestLen);
79 if (ret != CRYPT_SUCCESS) {
80 BSL_ERR_PUSH_ERROR(ret);
81 CRYPT_EAL_MdFreeCtx(ctx);
82 return ret;
83 }
84 CRYPT_EAL_MdFreeCtx(ctx);
85 return CRYPT_SUCCESS;
86 }
87
PrivPassPubBlind(void * pkeyCtx,int32_t algId,const uint8_t * data,uint32_t dataLen,uint8_t * blindedData,uint32_t * blindedDataLen)88 int32_t PrivPassPubBlind(void *pkeyCtx, int32_t algId, const uint8_t *data, uint32_t dataLen, uint8_t *blindedData,
89 uint32_t *blindedDataLen)
90 {
91 if (pkeyCtx == NULL || data == NULL || dataLen == 0 || blindedData == NULL || blindedDataLen == NULL) {
92 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
93 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
94 }
95 CRYPT_EAL_PkeyCtx *ctx = (CRYPT_EAL_PkeyCtx *)pkeyCtx;
96 uint32_t flag = CRYPT_RSA_BSSA;
97 uint32_t padType = 0;
98 int32_t ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_GET_RSA_PADDING, &padType, sizeof(padType));
99 if (ret != CRYPT_SUCCESS) {
100 BSL_ERR_PUSH_ERROR(ret);
101 return ret;
102 }
103 if (padType != CRYPT_EMSA_PSS) {
104 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_ALG);
105 return HITLS_AUTH_PRIVPASS_INVALID_ALG;
106 }
107 ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_FLAG, (void *)&flag, sizeof(uint32_t));
108 if (ret != CRYPT_SUCCESS) {
109 BSL_ERR_PUSH_ERROR(ret);
110 return ret;
111 }
112
113 ret = CRYPT_EAL_PkeyBlind(ctx, algId, data, dataLen, blindedData, blindedDataLen);
114 if (ret != CRYPT_SUCCESS) {
115 BSL_ERR_PUSH_ERROR(ret);
116 }
117 return ret;
118 }
119
PrivPassPubUnBlind(void * pkeyCtx,const uint8_t * blindedData,uint32_t blindedDataLen,uint8_t * data,uint32_t * dataLen)120 int32_t PrivPassPubUnBlind(void *pkeyCtx, const uint8_t *blindedData, uint32_t blindedDataLen, uint8_t *data,
121 uint32_t *dataLen)
122 {
123 if (pkeyCtx == NULL || blindedData == NULL || blindedDataLen == 0 || data == NULL || dataLen == NULL) {
124 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
125 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
126 }
127 CRYPT_EAL_PkeyCtx *ctx = (CRYPT_EAL_PkeyCtx *)pkeyCtx;
128 return CRYPT_EAL_PkeyUnBlind(ctx, blindedData, blindedDataLen, data, dataLen);
129 }
130
PrivPassPubSignData(void * pkeyCtx,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t * signLen)131 int32_t PrivPassPubSignData(void *pkeyCtx, const uint8_t *data, uint32_t dataLen, uint8_t *sign, uint32_t *signLen)
132 {
133 if (pkeyCtx == NULL || data == NULL || dataLen == 0 || sign == NULL || signLen == NULL) {
134 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
135 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
136 }
137 CRYPT_EAL_PkeyCtx *ctx = (CRYPT_EAL_PkeyCtx *)pkeyCtx;
138 uint32_t flag = CRYPT_RSA_BSSA;
139 uint32_t padType = CRYPT_EMSA_PSS;
140 int32_t ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_PADDING, &padType, sizeof(padType));
141 if (ret != CRYPT_SUCCESS) {
142 BSL_ERR_PUSH_ERROR(ret);
143 return ret;
144 }
145 ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_FLAG, (void *)&flag, sizeof(uint32_t));
146 if (ret != CRYPT_SUCCESS) {
147 BSL_ERR_PUSH_ERROR(ret);
148 return ret;
149 }
150 return CRYPT_EAL_PkeySignData(ctx, data, dataLen, sign, signLen);
151 }
152
PrivPassPubVerify(void * pkeyCtx,int32_t algId,const uint8_t * data,uint32_t dataLen,const uint8_t * sign,uint32_t signLen)153 int32_t PrivPassPubVerify(void *pkeyCtx, int32_t algId, const uint8_t *data, uint32_t dataLen, const uint8_t *sign,
154 uint32_t signLen)
155 {
156 if (pkeyCtx == NULL || data == NULL || dataLen == 0 || sign == NULL || signLen == 0) {
157 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
158 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
159 }
160 CRYPT_EAL_PkeyCtx *ctx = (CRYPT_EAL_PkeyCtx *)pkeyCtx;
161 uint32_t flag = CRYPT_RSA_BSSA;
162 uint32_t padType = 0;
163 int32_t ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_GET_RSA_PADDING, &padType, sizeof(padType));
164 if (ret != CRYPT_SUCCESS) {
165 BSL_ERR_PUSH_ERROR(ret);
166 return ret;
167 }
168 if (padType != CRYPT_EMSA_PSS) {
169 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_ALG);
170 return HITLS_AUTH_PRIVPASS_INVALID_ALG;
171 }
172 ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_RSA_FLAG, (void *)&flag, sizeof(uint32_t));
173 if (ret != CRYPT_SUCCESS) {
174 BSL_ERR_PUSH_ERROR(ret);
175 return ret;
176 }
177 return CRYPT_EAL_PkeyVerify(ctx, algId, data, dataLen, sign, signLen);
178 }
179
PubKeyCheck(CRYPT_EAL_PkeyCtx * ctx)180 static int32_t PubKeyCheck(CRYPT_EAL_PkeyCtx *ctx)
181 {
182 uint32_t padType = 0;
183 uint32_t keyBits = 0;
184 CRYPT_MD_AlgId mdType = 0;
185
186 int32_t ret = CRYPT_EAL_PkeyGetId(ctx);
187 if (ret != CRYPT_PKEY_RSA) {
188 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_PUBKEY_TYPE);
189 return HITLS_AUTH_PRIVPASS_INVALID_PUBKEY_TYPE;
190 }
191 ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_GET_RSA_PADDING, &padType, sizeof(padType));
192 if (ret != CRYPT_SUCCESS) {
193 BSL_ERR_PUSH_ERROR(ret);
194 return ret;
195 }
196 if (padType != CRYPT_EMSA_PSS) {
197 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_PUBKEY_PADDING_INFO);
198 return HITLS_AUTH_PRIVPASS_INVALID_PUBKEY_PADDING_INFO;
199 }
200 ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_GET_RSA_MD, &mdType, sizeof(CRYPT_MD_AlgId));
201 if (ret != CRYPT_SUCCESS) {
202 BSL_ERR_PUSH_ERROR(ret);
203 return ret;
204 }
205 if (mdType != CRYPT_MD_SHA384) {
206 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_PUBKEY_PADDING_MD);
207 return HITLS_AUTH_PRIVPASS_INVALID_PUBKEY_PADDING_MD;
208 }
209 keyBits = CRYPT_EAL_PkeyGetKeyBits(ctx);
210 if (keyBits != 2048) { // now only support rsa-2048
211 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_PUBKEY_BITS);
212 return HITLS_AUTH_PRIVPASS_INVALID_PUBKEY_BITS;
213 }
214 return CRYPT_SUCCESS;
215 }
216
PrivPassPubDecodePubKey(void * libCtx,const char * attrName,uint8_t * pubKey,uint32_t pubKeyLen,void ** pkeyCtx)217 int32_t PrivPassPubDecodePubKey(void *libCtx, const char *attrName, uint8_t *pubKey, uint32_t pubKeyLen, void **pkeyCtx)
218 {
219 (void)libCtx;
220 (void)attrName;
221 if (pkeyCtx == NULL || *pkeyCtx != NULL || pubKey == NULL || pubKeyLen == 0) {
222 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
223 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
224 }
225 CRYPT_EAL_PkeyCtx *ctx = NULL;
226 BSL_Buffer encode = {.data = pubKey, .dataLen = pubKeyLen};
227 int32_t ret = CRYPT_EAL_DecodeBuffKey(BSL_FORMAT_ASN1, CRYPT_PUBKEY_SUBKEY, &encode, NULL, 0, &ctx);
228 if (ret != CRYPT_SUCCESS) {
229 BSL_ERR_PUSH_ERROR(ret);
230 return ret;
231 }
232 ret = PubKeyCheck(ctx);
233 if (ret != CRYPT_SUCCESS) {
234 CRYPT_EAL_PkeyFreeCtx(ctx);
235 return ret;
236 }
237 *pkeyCtx = ctx;
238 return CRYPT_SUCCESS;
239 }
240
PrivPassPubDecodePrvKey(void * libCtx,const char * attrName,void * param,uint8_t * prvKey,uint32_t prvKeyLen,void ** pkeyCtx)241 int32_t PrivPassPubDecodePrvKey(void *libCtx, const char *attrName, void *param, uint8_t *prvKey, uint32_t prvKeyLen,
242 void **pkeyCtx)
243 {
244 (void)libCtx;
245 (void)attrName;
246 (void)param;
247 if (pkeyCtx == NULL || *pkeyCtx != NULL || prvKey == NULL || prvKeyLen == 0) {
248 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
249 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
250 }
251 CRYPT_EAL_PkeyCtx *ctx = NULL;
252 uint32_t keyBits = 0;
253 uint8_t *tmpBuff = BSL_SAL_Malloc(prvKeyLen + 1);
254 if (tmpBuff == NULL) {
255 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
256 return BSL_MALLOC_FAIL;
257 }
258 (void)memcpy_s(tmpBuff, prvKeyLen, prvKey, prvKeyLen);
259 tmpBuff[prvKeyLen] = '\0';
260 BSL_Buffer encode = {.data = tmpBuff, .dataLen = prvKeyLen};
261 int32_t ret = CRYPT_EAL_DecodeBuffKey(BSL_FORMAT_PEM, CRYPT_PRIKEY_PKCS8_UNENCRYPT, &encode, NULL, 0, &ctx);
262 (void)memset_s(tmpBuff, prvKeyLen, 0, prvKeyLen);
263 BSL_SAL_Free(tmpBuff);
264 if (ret != CRYPT_SUCCESS) {
265 BSL_ERR_PUSH_ERROR(ret);
266 return ret;
267 }
268 if (CRYPT_EAL_PkeyGetId(ctx) != CRYPT_PKEY_RSA) {
269 CRYPT_EAL_PkeyFreeCtx(ctx);
270 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_PRVKEY_TYPE);
271 return HITLS_AUTH_PRIVPASS_INVALID_PRVKEY_TYPE;
272 }
273 keyBits = CRYPT_EAL_PkeyGetKeyBits(ctx);
274 if (keyBits != 2048) { // now only support rsa-2048
275 CRYPT_EAL_PkeyFreeCtx(ctx);
276 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_PRVKEY_BITS);
277 return HITLS_AUTH_PRIVPASS_INVALID_PRVKEY_BITS;
278 }
279 *pkeyCtx = ctx;
280 return CRYPT_SUCCESS;
281 }
282
PrivPassPubCheckKeyPair(void * pubKeyCtx,void * prvKeyCtx)283 int32_t PrivPassPubCheckKeyPair(void *pubKeyCtx, void *prvKeyCtx)
284 {
285 if (pubKeyCtx == NULL || prvKeyCtx == NULL) {
286 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
287 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
288 }
289 int32_t ret = CRYPT_EAL_PkeyPairCheck(pubKeyCtx, prvKeyCtx);
290 if (ret != CRYPT_SUCCESS) {
291 BSL_ERR_PUSH_ERROR(ret);
292 }
293 return ret;
294 }
295
PrivPassPubRandom(uint8_t * buffer,uint32_t bufferLen)296 int32_t PrivPassPubRandom(uint8_t *buffer, uint32_t bufferLen)
297 {
298 if (buffer == NULL || bufferLen == 0) {
299 BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
300 return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
301 }
302 return CRYPT_EAL_RandbytesEx(NULL, buffer, bufferLen);
303 }
304
PrivPassCryptPubCb(void)305 PrivPassCryptCb PrivPassCryptPubCb(void)
306 {
307 PrivPassCryptCb method = {
308 .newPkeyCtx = PrivPassNewPkeyCtx,
309 .freePkeyCtx = PrivPassFreePkeyCtx,
310 .digest = PrivPassPubDigest,
311 .blind = PrivPassPubBlind,
312 .unBlind = PrivPassPubUnBlind,
313 .signData = PrivPassPubSignData,
314 .verify = PrivPassPubVerify,
315 .decodePubKey = PrivPassPubDecodePubKey,
316 .decodePrvKey = PrivPassPubDecodePrvKey,
317 .checkKeyPair = PrivPassPubCheckKeyPair,
318 .random = PrivPassPubRandom,
319 };
320 return method;
321 }