1 /*
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "softbus_rsa_encrypt.h"
17
18 #include <hks_api.h>
19 #include <hks_param.h>
20 #include <hks_type.h>
21 #include <openssl/aes.h>
22 #include <openssl/bn.h>
23 #include <openssl/ossl_typ.h>
24 #include <openssl/pem.h>
25 #include <openssl/rsa.h>
26 #include <openssl/x509.h>
27 #include <securec.h>
28
29 #include "comm_log.h"
30 #include "softbus_adapter_mem.h"
31 #include "softbus_errcode.h"
32
33 static const uint8_t SOFTBUS_RSA_KEY_ALIAS[] = "DsoftbusRsaKey";
34 static const struct HksBlob g_rsaKeyAlias = { sizeof(SOFTBUS_RSA_KEY_ALIAS), (uint8_t *)SOFTBUS_RSA_KEY_ALIAS };
35 static int32_t ConstructKeyParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramCount);
36 static struct HksParam g_generateParams[] = {
37 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_RSA },
38 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_RSA_KEY_SIZE_2048 },
39 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT},
40 { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 },
41 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_OAEP },
42 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_ECB },
43 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
44 };
45 static struct HksParam g_decryptParams[] = {
46 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_RSA },
47 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
48 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_RSA_KEY_SIZE_2048 },
49 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_OAEP },
50 { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 },
51 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_ECB },
52 { .tag = HKS_TAG_MGF_DIGEST, .uint32Param = HKS_DIGEST_SHA1 },
53 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE},
54 };
55
IsRsaKeyPairExist(struct HksBlob Alias)56 static bool IsRsaKeyPairExist(struct HksBlob Alias)
57 {
58 struct HksParamSet *paramSet = NULL;
59 struct HksParam keyExistparams[] = {
60 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE},
61 };
62 if (ConstructKeyParamSet(¶mSet, keyExistparams, sizeof(keyExistparams) / sizeof(struct HksParam)) !=
63 SOFTBUS_OK) {
64 COMM_LOGE(COMM_UTILS, "rsa keypair ConstructKeyParamSet failed.");
65 return false;
66 }
67 if (HksKeyExist(&Alias, paramSet) == HKS_SUCCESS) {
68 COMM_LOGI(COMM_UTILS, "rsa keypair already exist.");
69 HksFreeParamSet(¶mSet);
70 return true;
71 } else {
72 COMM_LOGE(COMM_UTILS, "rsa keypair do not exist.");
73 HksFreeParamSet(¶mSet);
74 return false;
75 }
76 }
77
ConstructKeyParamSet(struct HksParamSet ** paramSet,const struct HksParam * params,uint32_t paramCount)78 static int32_t ConstructKeyParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramCount)
79 {
80 if (HksInitParamSet(paramSet) != HKS_SUCCESS) {
81 COMM_LOGE(COMM_UTILS, "HksInitParamSet failed.");
82 return SOFTBUS_HUKS_ERR;
83 }
84 if (HksAddParams(*paramSet, params, paramCount) != HKS_SUCCESS) {
85 COMM_LOGE(COMM_UTILS, "HksAddParams failed.");
86 HksFreeParamSet(paramSet);
87 *paramSet = NULL;
88 return SOFTBUS_HUKS_ERR;
89 }
90 if (HksBuildParamSet(paramSet) != HKS_SUCCESS) {
91 COMM_LOGE(COMM_UTILS, "HksBuildParamSet failed.");
92 HksFreeParamSet(paramSet);
93 *paramSet = NULL;
94 return SOFTBUS_HUKS_ERR;
95 }
96 return SOFTBUS_OK;
97 }
98
GenerateRsaKeyPair(void)99 static int32_t GenerateRsaKeyPair(void)
100 {
101 struct HksParamSet *paramSet = NULL;
102 if (ConstructKeyParamSet(¶mSet, g_generateParams, sizeof(g_generateParams) / sizeof(struct HksParam)) !=
103 SOFTBUS_OK) {
104 COMM_LOGE(COMM_UTILS, "ConstructKeyParamSet failed.");
105 return SOFTBUS_HUKS_ERR;
106 }
107 if (HksGenerateKey(&g_rsaKeyAlias, paramSet, NULL) != HKS_SUCCESS) {
108 COMM_LOGE(COMM_UTILS, "HksGenerateKey failed.");
109 HksFreeParamSet(¶mSet);
110 paramSet = NULL;
111 return SOFTBUS_HUKS_ERR;
112 }
113 HksFreeParamSet(¶mSet);
114 paramSet = NULL;
115 return SOFTBUS_OK;
116 }
117
SoftBusGetPublicKey(uint8_t * publicKey,uint32_t publicKeyLen)118 int32_t SoftBusGetPublicKey(uint8_t *publicKey, uint32_t publicKeyLen)
119 {
120 if (publicKey == NULL || publicKeyLen == 0) {
121 COMM_LOGE(COMM_UTILS, "invalid param.");
122 return SOFTBUS_INVALID_PARAM;
123 }
124 if (!IsRsaKeyPairExist(g_rsaKeyAlias)) {
125 if (GenerateRsaKeyPair() != SOFTBUS_OK) {
126 COMM_LOGE(COMM_UTILS, "Generate RsaKeyPair failed");
127 return SOFTBUS_HUKS_ERR;
128 }
129 }
130 // Export public key
131 uint8_t pubKey[HKS_RSA_KEY_SIZE_4096] = { 0 };
132 struct HksBlob publicKeyBlob = { HKS_RSA_KEY_SIZE_4096, pubKey };
133 struct HksParamSet *paramSet = NULL;
134 struct HksParam publicKeyParams[] = {
135 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE},
136 };
137 if (ConstructKeyParamSet(¶mSet, publicKeyParams, sizeof(publicKeyParams) / sizeof(struct HksParam)) !=
138 SOFTBUS_OK) {
139 COMM_LOGE(COMM_UTILS, "public key ConstructKeyParamSet failed.");
140 return SOFTBUS_HUKS_ERR;
141 }
142 if (HksExportPublicKey(&g_rsaKeyAlias, paramSet, &publicKeyBlob) != HKS_SUCCESS) {
143 COMM_LOGE(COMM_UTILS, "HksExportPubKey failed.");
144 HksFreeParamSet(¶mSet);
145 return SOFTBUS_HUKS_ERR;
146 }
147 HksFreeParamSet(¶mSet);
148 COMM_LOGD(COMM_UTILS, "public key is X509, size=%{public}u.", publicKeyBlob.size);
149 if (memcpy_s(publicKey, publicKeyLen, publicKeyBlob.data, publicKeyBlob.size) != EOK) {
150 COMM_LOGE(COMM_UTILS, "publicKey memcpy_s failed.");
151 (void)memset_s(pubKey, sizeof(pubKey), 0, sizeof(pubKey));
152 return SOFTBUS_MEM_ERR;
153 }
154 (void)memset_s(pubKey, sizeof(pubKey), 0, sizeof(pubKey));
155 return SOFTBUS_OK;
156 }
157
GetRsaBigNum(const BIGNUM * modNum,BIGNUM ** base,BIGNUM ** result,uint8_t ** buf,int32_t * bufNum)158 static BN_CTX *GetRsaBigNum(const BIGNUM *modNum, BIGNUM **base, BIGNUM **result, uint8_t **buf, int32_t *bufNum)
159 {
160 if (modNum == NULL || base == NULL || result == NULL || buf == NULL || bufNum == NULL) {
161 COMM_LOGE(COMM_UTILS, "invalid param.");
162 return NULL;
163 }
164 BN_CTX *ctx = BN_CTX_new();
165 if (ctx == NULL) {
166 return NULL;
167 }
168 BN_CTX_start(ctx);
169 *base = BN_CTX_get(ctx);
170 *result = BN_CTX_get(ctx);
171 if (*base == NULL || *result == NULL) {
172 COMM_LOGE(COMM_UTILS, "BN_CTX_get failed.");
173 BN_CTX_end(ctx);
174 BN_CTX_free(ctx);
175 return NULL;
176 }
177 *bufNum = BN_num_bytes(modNum);
178 if (*bufNum == 0) {
179 COMM_LOGE(COMM_UTILS, "BN_num_bytes failed.");
180 BN_CTX_end(ctx);
181 BN_CTX_free(ctx);
182 return NULL;
183 }
184 if (*buf != NULL) {
185 OPENSSL_clear_free(*buf, *bufNum);
186 *buf = NULL;
187 }
188 *buf = OPENSSL_malloc(*bufNum);
189 if (*buf == NULL) {
190 COMM_LOGE(COMM_UTILS, "OPENSSL_malloc failed.");
191 BN_CTX_end(ctx);
192 BN_CTX_free(ctx);
193 OPENSSL_clear_free(*buf, *bufNum);
194 *buf = NULL;
195 return NULL;
196 }
197 return ctx;
198 }
199
EncryptByPublicKey(const uint8_t * src,uint32_t srcLen,const RSA * rsa,uint8_t * out,uint32_t outLen)200 static int32_t EncryptByPublicKey(const uint8_t *src, uint32_t srcLen, const RSA *rsa, uint8_t *out, uint32_t outLen)
201 {
202 if (src == NULL || srcLen == 0 || rsa == NULL || out == NULL || outLen < SOFTBUS_RSA_ENCRYPT_LEN) {
203 COMM_LOGE(COMM_UTILS, "invalid param.");
204 return SOFTBUS_INVALID_PARAM;
205 }
206 int32_t ret = SOFTBUS_ENCRYPT_ERR;
207 uint8_t *buf = NULL;
208 int32_t bufNum = 0;
209 BIGNUM *base = NULL;
210 BIGNUM *result = NULL;
211 BN_CTX *ctx = NULL;
212
213 const BIGNUM *modNum = RSA_get0_n(rsa);
214 const BIGNUM *exp = RSA_get0_e(rsa);
215 if ((BN_num_bits(modNum) > OPENSSL_RSA_MAX_MODULUS_BITS) || (BN_ucmp(modNum, exp) <= 0) ||
216 ((BN_num_bits(modNum) > OPENSSL_RSA_SMALL_MODULUS_BITS) && (BN_num_bits(exp) > OPENSSL_RSA_MAX_PUBEXP_BITS))) {
217 COMM_LOGE(COMM_UTILS, "invalid param rsa.");
218 return SOFTBUS_INVALID_PARAM;
219 }
220 do {
221 ctx = GetRsaBigNum(modNum, &base, &result, &buf, &bufNum);
222 if (ctx == NULL) {
223 COMM_LOGE(COMM_UTILS, "GetRsaBigNum failed.");
224 break;
225 }
226 const EVP_MD *md = EVP_sha256();
227 const EVP_MD *mgf1md = EVP_sha1();
228 ret = RSA_padding_add_PKCS1_OAEP_mgf1(buf, bufNum, src, srcLen, NULL, 0, md, mgf1md);
229 if (ret <= 0 || BN_bin2bn(buf, bufNum, base) == NULL || BN_ucmp(base, modNum) >= 0) {
230 COMM_LOGE(COMM_UTILS, "RSA_padding_add_PKCS1_OAEP_mgf1 failed or invalid BIGNUM param .");
231 break;
232 }
233 BN_mod_exp_mont(result, base, exp, modNum, ctx, NULL);
234 ret = BN_bn2binpad(result, out, bufNum);
235 if (ret < 0) {
236 COMM_LOGE(COMM_UTILS, "BN_bn2binpad failed.");
237 break;
238 }
239 ret = SOFTBUS_OK;
240 } while (0);
241 if (ctx != NULL) {
242 BN_CTX_end(ctx);
243 BN_CTX_free(ctx);
244 }
245 OPENSSL_clear_free(buf, bufNum);
246 buf = NULL;
247 return ret;
248 }
249
DataToPublicKey(const uint8_t * bufKey,int32_t bufKeyLen,RSA ** pubKey)250 static int32_t DataToPublicKey(const uint8_t *bufKey, int32_t bufKeyLen, RSA **pubKey)
251 {
252 int32_t res;
253 BIO *pBio = NULL;
254
255 if (bufKey == NULL || bufKeyLen < 0 || pubKey == NULL) {
256 COMM_LOGE(COMM_UTILS, "invalid param.");
257 return SOFTBUS_INVALID_PARAM;
258 }
259 pBio = BIO_new(BIO_s_mem());
260 if (pBio == NULL) {
261 COMM_LOGE(COMM_UTILS, "Bio data malloc failed.");
262 return SOFTBUS_BIO_ERR;
263 }
264 res = BIO_write(pBio, bufKey, bufKeyLen);
265 if (res <= 0) {
266 COMM_LOGE(COMM_UTILS, "Bio data write failed.");
267 BIO_free(pBio);
268 return SOFTBUS_BIO_ERR;
269 }
270 *pubKey = d2i_RSA_PUBKEY_bio(pBio, NULL);
271 if (*pubKey == NULL) {
272 COMM_LOGE(COMM_UTILS, "Data transfer public key failed.");
273 BIO_free(pBio);
274 return SOFTBUS_BIO_ERR;
275 }
276 BIO_free(pBio);
277 return SOFTBUS_OK;
278 }
279
SoftBusRsaEncrypt(const uint8_t * srcData,uint32_t srcDataLen,PublicKey * publicKey,uint8_t ** encryptedData,uint32_t * encryptedDataLen)280 int32_t SoftBusRsaEncrypt(const uint8_t *srcData, uint32_t srcDataLen, PublicKey *publicKey, uint8_t **encryptedData,
281 uint32_t *encryptedDataLen)
282 {
283 if (srcData == NULL || srcDataLen == 0 || publicKey == NULL || publicKey->key == NULL ||
284 publicKey->len <= RSA_PUB_KEY_LEN_SUBTRACT_ENCRYPT_LEN || encryptedData == NULL || encryptedDataLen == NULL) {
285 COMM_LOGE(COMM_UTILS, "invalid param.");
286 return SOFTBUS_INVALID_PARAM;
287 }
288 RSA *peerPubKey = NULL;
289 if (DataToPublicKey(publicKey->key, publicKey->len, &peerPubKey) != SOFTBUS_OK) {
290 COMM_LOGE(COMM_UTILS, "DataToPublicKey failed.");
291 return SOFTBUS_BIO_ERR;
292 }
293 uint32_t cipherTextLen = publicKey->len - RSA_PUB_KEY_LEN_SUBTRACT_ENCRYPT_LEN;
294 uint8_t *cipherText = (uint8_t *)SoftBusCalloc(cipherTextLen);
295 if (cipherText == NULL) {
296 COMM_LOGE(COMM_UTILS, "cipherText calloc failed.");
297 RSA_free(peerPubKey);
298 return SOFTBUS_MALLOC_ERR;
299 }
300 if (EncryptByPublicKey(srcData, srcDataLen, peerPubKey, cipherText, cipherTextLen) != SOFTBUS_OK) {
301 COMM_LOGE(COMM_UTILS, "EncryptByPublicKey failed.");
302 RSA_free(peerPubKey);
303 SoftBusFree(cipherText);
304 return SOFTBUS_ENCRYPT_ERR;
305 }
306 *encryptedDataLen = cipherTextLen;
307 *encryptedData = (uint8_t *)SoftBusCalloc(cipherTextLen);
308 if (*encryptedData == NULL) {
309 COMM_LOGE(COMM_UTILS, "encryptedData calloc failed.");
310 (void)memset_s(cipherText, cipherTextLen, 0, cipherTextLen);
311 RSA_free(peerPubKey);
312 SoftBusFree(cipherText);
313 return SOFTBUS_MALLOC_ERR;
314 }
315 if (memcpy_s(*encryptedData, cipherTextLen, cipherText, cipherTextLen) != EOK) {
316 COMM_LOGE(COMM_UTILS, "encryptedData memcpy_s failed.");
317 (void)memset_s(cipherText, cipherTextLen, 0, cipherTextLen);
318 RSA_free(peerPubKey);
319 SoftBusFree(cipherText);
320 SoftBusFree(*encryptedData);
321 *encryptedData = NULL;
322 return SOFTBUS_MEM_ERR;
323 }
324 RSA_free(peerPubKey);
325 SoftBusFree(cipherText);
326 return SOFTBUS_OK;
327 }
328
SoftBusRsaDecrypt(const uint8_t * srcData,uint32_t srcDataLen,uint8_t ** decryptedData,uint32_t * decryptedDataLen)329 int32_t SoftBusRsaDecrypt(
330 const uint8_t *srcData, uint32_t srcDataLen, uint8_t **decryptedData, uint32_t *decryptedDataLen)
331 {
332 if (srcData == NULL || srcDataLen == 0 || decryptedData == NULL || decryptedDataLen == NULL) {
333 COMM_LOGE(COMM_UTILS, "invalid param.");
334 return SOFTBUS_INVALID_PARAM;
335 }
336 struct HksBlob encryptedBlob = { srcDataLen, (uint8_t *)srcData };
337 struct HksParamSet *paramSet = NULL;
338 if (ConstructKeyParamSet(¶mSet, g_decryptParams, sizeof(g_decryptParams) / sizeof(struct HksParam)) !=
339 SOFTBUS_OK) {
340 COMM_LOGE(COMM_UTILS, "ConstructKeyParamSet failed.");
341 return SOFTBUS_HUKS_ERR;
342 }
343 struct HksBlob decryptedBlob = { .size = HKS_RSA_KEY_SIZE_4096,
344 .data = (uint8_t *)(SoftBusCalloc(HKS_RSA_KEY_SIZE_4096)) };
345 if (decryptedBlob.data == NULL) {
346 COMM_LOGE(COMM_UTILS, "decryptedBlob.data calloc failed.");
347 HksFreeParamSet(¶mSet);
348 return SOFTBUS_MALLOC_ERR;
349 }
350 if (HksDecrypt(&g_rsaKeyAlias, paramSet, &encryptedBlob, &decryptedBlob) != HKS_SUCCESS) {
351 COMM_LOGE(COMM_UTILS, "HksDecrypt failed.");
352 HksFreeParamSet(¶mSet);
353 SoftBusFree(decryptedBlob.data);
354 return SOFTBUS_DECRYPT_ERR;
355 }
356 COMM_LOGD(COMM_UTILS, "HksDecrypt success.");
357 *decryptedDataLen = decryptedBlob.size;
358 *decryptedData = (uint8_t *)SoftBusCalloc(decryptedBlob.size);
359 if (*decryptedData == NULL) {
360 COMM_LOGE(COMM_UTILS, "decryptedData calloc failed");
361 (void)memset_s(decryptedBlob.data, decryptedBlob.size, 0, decryptedBlob.size);
362 HksFreeParamSet(¶mSet);
363 SoftBusFree(decryptedBlob.data);
364 return SOFTBUS_MALLOC_ERR;
365 }
366 if (memcpy_s(*decryptedData, decryptedBlob.size, decryptedBlob.data, decryptedBlob.size) != EOK) {
367 COMM_LOGE(COMM_UTILS, "decryptedData memcpy_s failed");
368 (void)memset_s(decryptedBlob.data, decryptedBlob.size, 0, decryptedBlob.size);
369 HksFreeParamSet(¶mSet);
370 SoftBusFree(decryptedBlob.data);
371 SoftBusFree(*decryptedData);
372 *decryptedData = NULL;
373 return SOFTBUS_MEM_ERR;
374 }
375 (void)memset_s(decryptedBlob.data, decryptedBlob.size, 0, decryptedBlob.size);
376 HksFreeParamSet(¶mSet);
377 SoftBusFree(decryptedBlob.data);
378 return SOFTBUS_OK;
379 }