• 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 "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 }