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(&paramSet, 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(&paramSet);
70         return true;
71     } else {
72         COMM_LOGE(COMM_UTILS, "rsa keypair do not exist.");
73         HksFreeParamSet(&paramSet);
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(&paramSet, 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(&paramSet);
110         paramSet = NULL;
111         return SOFTBUS_HUKS_ERR;
112     }
113     HksFreeParamSet(&paramSet);
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(&paramSet, 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(&paramSet);
145         return SOFTBUS_HUKS_ERR;
146     }
147     HksFreeParamSet(&paramSet);
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(&paramSet, 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(&paramSet);
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(&paramSet);
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(&paramSet);
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(&paramSet);
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(&paramSet);
377     SoftBusFree(decryptedBlob.data);
378     return SOFTBUS_OK;
379 }