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_KEY_DECODE) && defined(HITLS_CRYPTO_RSA)
18 #include "crypt_rsa.h"
19 #include "bsl_asn1.h"
20 #include "bsl_params.h"
21 #include "bsl_errno.h"
22 #include "bsl_err_internal.h"
23 #include "crypt_errno.h"
24 #include "crypt_params_key.h"
25 #include "crypt_encode_decode_local.h"
26 #include "crypt_encode_decode_key.h"
27
ProcRsaPubKey(const BSL_ASN1_Buffer * asn1,CRYPT_RSA_Ctx * rsaKey)28 static int32_t ProcRsaPubKey(const BSL_ASN1_Buffer *asn1, CRYPT_RSA_Ctx *rsaKey)
29 {
30 const BSL_Param param[3] = {
31 {CRYPT_PARAM_RSA_E, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_E_IDX].buff,
32 asn1[CRYPT_RSA_PRV_E_IDX].len, 0},
33 {CRYPT_PARAM_RSA_N, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_N_IDX].buff,
34 asn1[CRYPT_RSA_PRV_N_IDX].len, 0},
35 BSL_PARAM_END
36 };
37 return CRYPT_RSA_SetPubKey(rsaKey, param);
38 }
39
ProcRsaPrivKey(const BSL_ASN1_Buffer * asn1,CRYPT_RSA_Ctx * rsaKey)40 static int32_t ProcRsaPrivKey(const BSL_ASN1_Buffer *asn1, CRYPT_RSA_Ctx *rsaKey)
41 {
42 const BSL_Param param[10] = {
43 {CRYPT_PARAM_RSA_D, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_D_IDX].buff,
44 asn1[CRYPT_RSA_PRV_D_IDX].len, 0},
45 {CRYPT_PARAM_RSA_N, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_N_IDX].buff,
46 asn1[CRYPT_RSA_PRV_N_IDX].len, 0},
47 {CRYPT_PARAM_RSA_E, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_E_IDX].buff,
48 asn1[CRYPT_RSA_PRV_E_IDX].len, 0},
49 {CRYPT_PARAM_RSA_P, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_P_IDX].buff,
50 asn1[CRYPT_RSA_PRV_P_IDX].len, 0},
51 {CRYPT_PARAM_RSA_Q, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_Q_IDX].buff,
52 asn1[CRYPT_RSA_PRV_Q_IDX].len, 0},
53 {CRYPT_PARAM_RSA_DP, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_DP_IDX].buff,
54 asn1[CRYPT_RSA_PRV_DP_IDX].len, 0},
55 {CRYPT_PARAM_RSA_DQ, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_DQ_IDX].buff,
56 asn1[CRYPT_RSA_PRV_DQ_IDX].len, 0},
57 {CRYPT_PARAM_RSA_QINV, BSL_PARAM_TYPE_OCTETS, asn1[CRYPT_RSA_PRV_QINV_IDX].buff,
58 asn1[CRYPT_RSA_PRV_QINV_IDX].len, 0},
59 BSL_PARAM_END
60 };
61 return CRYPT_RSA_SetPrvKey(rsaKey, param);
62 }
63
64
ProcRsaKeyPair(uint8_t * buff,uint32_t buffLen,CRYPT_RSA_Ctx * rsaKey)65 static int32_t ProcRsaKeyPair(uint8_t *buff, uint32_t buffLen, CRYPT_RSA_Ctx *rsaKey)
66 {
67 // decode n and e
68 BSL_ASN1_Buffer asn1[CRYPT_RSA_PRV_OTHER_PRIME_IDX + 1] = {0};
69 int32_t ret = CRYPT_DECODE_RsaPrikeyAsn1Buff(buff, buffLen, asn1, CRYPT_RSA_PRV_OTHER_PRIME_IDX + 1);
70 if (ret != CRYPT_SUCCESS) {
71 BSL_ERR_PUSH_ERROR(ret);
72 return ret;
73 }
74
75 ret = ProcRsaPrivKey(asn1, rsaKey);
76 if (ret != CRYPT_SUCCESS) {
77 BSL_ERR_PUSH_ERROR(ret);
78 return ret;
79 }
80
81 return ProcRsaPubKey(asn1, rsaKey);
82 }
83
ProcRsaPssParam(BSL_ASN1_Buffer * rsaPssParam,CRYPT_RSA_Ctx * rsaPriKey)84 static int32_t ProcRsaPssParam(BSL_ASN1_Buffer *rsaPssParam, CRYPT_RSA_Ctx *rsaPriKey)
85 {
86 CRYPT_RsaPadType padType = CRYPT_EMSA_PSS;
87 int32_t ret = CRYPT_RSA_Ctrl(rsaPriKey, CRYPT_CTRL_SET_RSA_PADDING, &padType, sizeof(CRYPT_RsaPadType));
88 if (ret != CRYPT_SUCCESS) {
89 BSL_ERR_PUSH_ERROR(ret);
90 return ret;
91 }
92 if (rsaPssParam == NULL || rsaPssParam->buff == NULL) {
93 return CRYPT_SUCCESS;
94 }
95
96 CRYPT_RSA_PssPara para = {0};
97 ret = CRYPT_EAL_ParseRsaPssAlgParam(rsaPssParam, ¶);
98 if (ret != CRYPT_SUCCESS) {
99 return ret;
100 }
101 BSL_Param param[4] = {
102 {CRYPT_PARAM_RSA_MD_ID, BSL_PARAM_TYPE_INT32, ¶.mdId, sizeof(para.mdId), 0},
103 {CRYPT_PARAM_RSA_MGF1_ID, BSL_PARAM_TYPE_INT32, ¶.mgfId, sizeof(para.mgfId), 0},
104 {CRYPT_PARAM_RSA_SALTLEN, BSL_PARAM_TYPE_INT32, ¶.saltLen, sizeof(para.saltLen), 0},
105 BSL_PARAM_END};
106 return CRYPT_RSA_Ctrl(rsaPriKey, CRYPT_CTRL_SET_RSA_EMSA_PSS, param, 0);
107 }
108
DecodeRsaPrikeyAsn1Buff(uint8_t * buff,uint32_t buffLen,BSL_ASN1_Buffer * rsaPssParam,BslCid cid,CRYPT_RSA_Ctx ** rsaPriKey)109 static int32_t DecodeRsaPrikeyAsn1Buff(uint8_t *buff, uint32_t buffLen, BSL_ASN1_Buffer *rsaPssParam, BslCid cid,
110 CRYPT_RSA_Ctx **rsaPriKey)
111 {
112 CRYPT_RSA_Ctx *pctx = CRYPT_RSA_NewCtx();
113 if (pctx == NULL) {
114 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
115 return CRYPT_MEM_ALLOC_FAIL;
116 }
117
118 int32_t ret = ProcRsaKeyPair(buff, buffLen, pctx);
119 if (ret != CRYPT_SUCCESS) {
120 CRYPT_RSA_FreeCtx(pctx);
121 BSL_ERR_PUSH_ERROR(ret);
122 return ret;
123 }
124 if (cid != BSL_CID_RSASSAPSS) {
125 *rsaPriKey = pctx;
126 return CRYPT_SUCCESS;
127 }
128
129 ret = ProcRsaPssParam(rsaPssParam, pctx);
130 if (ret != CRYPT_SUCCESS) {
131 CRYPT_RSA_FreeCtx(pctx);
132 return ret;
133 }
134 *rsaPriKey = pctx;
135 return ret;
136 }
137
CRYPT_RSA_ParsePrikeyAsn1Buff(uint8_t * buff,uint32_t buffLen,BSL_ASN1_Buffer * rsaPssParam,CRYPT_RSA_Ctx ** rsaPriKey)138 int32_t CRYPT_RSA_ParsePrikeyAsn1Buff(uint8_t *buff, uint32_t buffLen, BSL_ASN1_Buffer *rsaPssParam,
139 CRYPT_RSA_Ctx **rsaPriKey)
140 {
141 return DecodeRsaPrikeyAsn1Buff(buff, buffLen, rsaPssParam, BSL_CID_UNKNOWN, rsaPriKey);
142 }
143
CRYPT_RSA_ParsePubkeyAsn1Buff(uint8_t * buff,uint32_t buffLen,BSL_ASN1_Buffer * param,CRYPT_RSA_Ctx ** rsaPubKey,BslCid cid)144 int32_t CRYPT_RSA_ParsePubkeyAsn1Buff(uint8_t *buff, uint32_t buffLen, BSL_ASN1_Buffer *param,
145 CRYPT_RSA_Ctx **rsaPubKey, BslCid cid)
146 {
147 // decode n and e
148 BSL_ASN1_Buffer pubAsn1[CRYPT_RSA_PUB_E_IDX + 1] = {0};
149 int32_t ret = CRYPT_DECODE_RsaPubkeyAsn1Buff(buff, buffLen, pubAsn1, CRYPT_RSA_PUB_E_IDX + 1);
150 if (ret != CRYPT_SUCCESS) {
151 return ret;
152 }
153
154 CRYPT_RSA_Ctx *pctx = CRYPT_RSA_NewCtx();
155 if (pctx == NULL) {
156 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
157 return CRYPT_MEM_ALLOC_FAIL;
158 }
159 BSL_Param pubParam[3] = {
160 {CRYPT_PARAM_RSA_E, BSL_PARAM_TYPE_OCTETS, pubAsn1[CRYPT_RSA_PUB_E_IDX].buff,
161 pubAsn1[CRYPT_RSA_PUB_E_IDX].len, 0},
162 {CRYPT_PARAM_RSA_N, BSL_PARAM_TYPE_OCTETS, pubAsn1[CRYPT_RSA_PUB_N_IDX].buff,
163 pubAsn1[CRYPT_RSA_PUB_N_IDX].len, 0},
164 BSL_PARAM_END
165 };
166 ret = CRYPT_RSA_SetPubKey(pctx, pubParam);
167 if (cid != BSL_CID_RSASSAPSS) {
168 *rsaPubKey = pctx;
169 return CRYPT_SUCCESS;
170 }
171
172 ret = ProcRsaPssParam(param, pctx);
173 if (ret != CRYPT_SUCCESS) {
174 CRYPT_RSA_FreeCtx(pctx);
175 BSL_ERR_PUSH_ERROR(ret);
176 return ret;
177 }
178
179 *rsaPubKey = pctx;
180 return ret;
181 }
182
CRYPT_RSA_ParseSubPubkeyAsn1Buff(uint8_t * buff,uint32_t buffLen,CRYPT_RSA_Ctx ** pubKey,bool isComplete)183 int32_t CRYPT_RSA_ParseSubPubkeyAsn1Buff( uint8_t *buff, uint32_t buffLen, CRYPT_RSA_Ctx **pubKey, bool isComplete)
184 {
185 if (pubKey == NULL) {
186 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
187 return CRYPT_NULL_INPUT;
188 }
189 CRYPT_DECODE_SubPubkeyInfo subPubkeyInfo = {0};
190 CRYPT_RSA_Ctx *pctx = NULL;
191 int32_t ret = CRYPT_DECODE_SubPubkey(buff, buffLen, NULL, &subPubkeyInfo, isComplete);
192 if (ret != CRYPT_SUCCESS) {
193 BSL_ERR_PUSH_ERROR(ret);
194 return ret;
195 }
196 if (subPubkeyInfo.keyType != BSL_CID_RSASSAPSS && subPubkeyInfo.keyType != BSL_CID_RSA) {
197 BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH);
198 return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
199 }
200
201 ret = CRYPT_RSA_ParsePubkeyAsn1Buff(subPubkeyInfo.pubKey.buff, subPubkeyInfo.pubKey.len, &subPubkeyInfo.keyParam,
202 &pctx, subPubkeyInfo.keyType);
203 if (ret != CRYPT_SUCCESS) {
204 BSL_ERR_PUSH_ERROR(ret);
205 return ret;
206 }
207
208 *pubKey = pctx;
209 return ret;
210 }
211
CRYPT_RSA_ParsePkcs8Key(uint8_t * buff,uint32_t buffLen,CRYPT_RSA_Ctx ** rsaPriKey)212 int32_t CRYPT_RSA_ParsePkcs8Key(uint8_t *buff, uint32_t buffLen, CRYPT_RSA_Ctx **rsaPriKey)
213 {
214 CRYPT_ENCODE_DECODE_Pk8PrikeyInfo pk8PrikeyInfo = {0};
215 int32_t ret = CRYPT_DECODE_Pkcs8Info(buff, buffLen, NULL, &pk8PrikeyInfo);
216 if (ret != CRYPT_SUCCESS) {
217 BSL_ERR_PUSH_ERROR(ret);
218 return ret;
219 }
220 if (pk8PrikeyInfo.keyType != BSL_CID_RSASSAPSS && pk8PrikeyInfo.keyType != BSL_CID_RSA) {
221 BSL_ERR_PUSH_ERROR(CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH);
222 return CRYPT_DECODE_ERR_KEY_TYPE_NOT_MATCH;
223 }
224 ret = DecodeRsaPrikeyAsn1Buff(pk8PrikeyInfo.pkeyRawKey, pk8PrikeyInfo.pkeyRawKeyLen, &pk8PrikeyInfo.keyParam,
225 pk8PrikeyInfo.keyType, rsaPriKey);
226 if (ret != CRYPT_SUCCESS) {
227 BSL_ERR_PUSH_ERROR(ret);
228 }
229 return ret;
230 }
231 #endif // HITLS_CRYPTO_KEY_DECODE && HITLS_CRYPTO_RSA
232