• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 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 "cipher.h"
17 
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "base64.h"
24 #include "cipher_log.h"
25 #include "ctr_drbg.h"
26 #include "entropy.h"
27 #include "md.h"
28 #include "pk.h"
29 #include "rsa.h"
30 #include "securec.h"
31 
32 #define RSA_KEY_BYTE   66
33 #define NUM_FOUR       4
34 #define NUM_THREE      3
35 #define MBEDTLS_RSA_PUBLIC	0 /**< Request private key operation. */
36 #define MBEDTLS_RSA_PRIVATE	1 /**< Request public key operation. */
37 
RsaMallocPrivateKey(const unsigned char * key,size_t * keyLen)38 static char *RsaMallocPrivateKey(const unsigned char *key, size_t *keyLen)
39 {
40     int32_t ret;
41     const char start[] = "-----BEGIN RSA PRIVATE KEY-----\n";
42     const char end[] = "\n-----END RSA PRIVATE KEY-----\n";
43     size_t startLen = strlen(start);
44     size_t endLen = strlen(end);
45     size_t keyFinalLen = *keyLen + startLen + endLen + 1;
46 
47     char *privateKey = malloc(keyFinalLen);
48     if (privateKey == NULL) {
49         return NULL;
50     }
51 
52     (void)memset_s(privateKey, keyFinalLen, 0, keyFinalLen);
53     ret = memcpy_s(privateKey, keyFinalLen, start, startLen);
54     if (ret != EOK) {
55         CIPHER_LOG_E("memcpy failed.");
56         free(privateKey);
57         return NULL;
58     }
59 
60     ret = memcpy_s(privateKey + startLen, keyFinalLen - startLen, key, *keyLen);
61     if (ret != EOK) {
62         CIPHER_LOG_E("memcpy failed.");
63         free(privateKey);
64         return NULL;
65     }
66 
67     ret = memcpy_s(privateKey + startLen + *keyLen, keyFinalLen - startLen - *keyLen, end, endLen);
68     if (ret != EOK) {
69         CIPHER_LOG_E("memcpy failed.");
70         (void)memset_s(privateKey, keyFinalLen, 0, keyFinalLen);
71         free(privateKey);
72         return NULL;
73     }
74 
75     *keyLen = keyFinalLen;
76     return privateKey;
77 }
78 
RsaMallocPublicKey(const unsigned char * key,size_t * keyLen)79 static char *RsaMallocPublicKey(const unsigned char *key, size_t *keyLen)
80 {
81     int32_t ret;
82     const char start[] = "-----BEGIN PUBLIC KEY-----\n";
83     const char end[] = "\n-----END PUBLIC KEY-----\n";
84     size_t startLen = strlen(start);
85     size_t endLen = strlen(end);
86     size_t keyFinalLen = *keyLen + startLen + endLen + 1;
87 
88     char *pubKey = malloc(keyFinalLen);
89     if (pubKey == NULL) {
90         return NULL;
91     }
92 
93     (void)memset_s(pubKey, keyFinalLen, 0, keyFinalLen);
94     ret = memcpy_s(pubKey, keyFinalLen, start, startLen);
95     if (ret != EOK) {
96         CIPHER_LOG_E("memcpy failed.");
97         free(pubKey);
98         return NULL;
99     }
100 
101     ret = memcpy_s(pubKey + startLen, keyFinalLen - startLen, key, *keyLen);
102     if (ret != EOK) {
103         CIPHER_LOG_E("memcpy failed.");
104         free(pubKey);
105         return NULL;
106     }
107 
108     ret = memcpy_s(pubKey + startLen + *keyLen, keyFinalLen - startLen - *keyLen, end, endLen);
109     if (ret != EOK) {
110         CIPHER_LOG_E("memcpy failed.");
111         (void)memset_s(pubKey, keyFinalLen, 0, keyFinalLen);
112         free(pubKey);
113         return NULL;
114     }
115 
116     *keyLen = keyFinalLen;
117     return pubKey;
118 }
119 
RsaInit(mbedtls_ctr_drbg_context * ctrDrbg,mbedtls_entropy_context * entropy)120 static void RsaInit(mbedtls_ctr_drbg_context *ctrDrbg, mbedtls_entropy_context *entropy)
121 {
122     mbedtls_ctr_drbg_init(ctrDrbg);
123     mbedtls_entropy_init(entropy);
124     (void)mbedtls_ctr_drbg_seed(ctrDrbg, mbedtls_entropy_func, entropy, NULL, 0);
125 }
126 
RsaLoadPrivateKey(mbedtls_pk_context * pk,const unsigned char * key,size_t keyLen)127 static int32_t RsaLoadPrivateKey(mbedtls_pk_context *pk, const unsigned char *key, size_t keyLen)
128 {
129     int32_t ret;
130     size_t finalKeyLen = keyLen;
131     mbedtls_rsa_context *rsa = NULL;
132     char *finalKey = RsaMallocPrivateKey(key, &finalKeyLen);
133     if (finalKey == NULL) {
134         CIPHER_LOG_E("malloc private key error, final Key Length:%zu.", finalKeyLen);
135         return ERROR_CODE_GENERAL;
136     }
137 
138     mbedtls_ctr_drbg_context ctrDrbg;
139     mbedtls_entropy_context entropy;
140     RsaInit(&ctrDrbg, &entropy);
141 
142     do {
143         ret = mbedtls_pk_parse_key(pk, (const unsigned char *)finalKey, finalKeyLen, NULL, 0,
144             mbedtls_ctr_drbg_random, &ctrDrbg);
145         if (ret != 0) {
146             CIPHER_LOG_E("parse private key error, ret:%d.", ret);
147             break;
148         }
149 
150         rsa = mbedtls_pk_rsa(*pk);
151         if (rsa == NULL) {
152             CIPHER_LOG_E("rsa error");
153             break;
154         }
155 
156         if (mbedtls_rsa_check_privkey(rsa) != 0) {
157             CIPHER_LOG_E("check private key failed.");
158             break;
159         }
160 
161         /* set padding as OAEPWITHSHA256 */
162         mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
163         (void)memset_s(finalKey, finalKeyLen, 0, finalKeyLen);
164         free(finalKey);
165         return ERROR_SUCCESS;
166     } while (0);
167 
168     (void)memset_s(finalKey, finalKeyLen, 0, finalKeyLen);
169     free(finalKey);
170     mbedtls_ctr_drbg_free(&ctrDrbg);
171     mbedtls_entropy_free(&entropy);
172     return ERROR_CODE_GENERAL;
173 }
174 
RsaLoadPublicKey(mbedtls_pk_context * pk,const unsigned char * key,size_t keyLen)175 static int32_t RsaLoadPublicKey(mbedtls_pk_context *pk, const unsigned char *key, size_t keyLen)
176 {
177     int32_t ret;
178     size_t finalKeyLen = keyLen;
179     mbedtls_rsa_context *rsa = NULL;
180     char* finalKey = RsaMallocPublicKey(key, &finalKeyLen);
181     if (finalKey == NULL) {
182         CIPHER_LOG_E("malloc public key error, final Key Length:%zu.", finalKeyLen);
183         return ERROR_CODE_GENERAL;
184     }
185 
186     do {
187         ret = mbedtls_pk_parse_public_key(pk, (const unsigned char *)finalKey, finalKeyLen);
188         if (ret != 0) {
189             CIPHER_LOG_E("parse public key error, ret:%d.", ret);
190             break;
191         }
192 
193         rsa = mbedtls_pk_rsa(*pk);
194         if (rsa == NULL) {
195             CIPHER_LOG_E("pk rsa error");
196             break;
197         }
198 
199         if (mbedtls_rsa_check_pubkey(rsa)) {
200             CIPHER_LOG_E("check public key failed.");
201             break;
202         }
203         /* set padding as OAEPWITHSHA256 */
204         mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
205         (void)memset_s(finalKey, finalKeyLen, 0, finalKeyLen);
206         free(finalKey);
207         return ERROR_SUCCESS;
208     } while (0);
209 
210     (void)memset_s(finalKey, finalKeyLen, 0, finalKeyLen);
211     free(finalKey);
212     return ERROR_CODE_GENERAL;
213 }
214 
RsaDeinit(mbedtls_ctr_drbg_context * ctrDrbg,mbedtls_entropy_context * entropy)215 static void RsaDeinit(mbedtls_ctr_drbg_context *ctrDrbg, mbedtls_entropy_context *entropy)
216 {
217     mbedtls_ctr_drbg_free(ctrDrbg);
218     mbedtls_entropy_free(entropy);
219 }
220 
RsaEncryptBase64Encode(int32_t cipherTotalLen,char * cipherText,int32_t cipherTextLen)221 static int32_t RsaEncryptBase64Encode(int32_t cipherTotalLen, char *cipherText, int32_t cipherTextLen)
222 {
223     if (cipherTotalLen <= 0) {
224         return ERROR_CODE_GENERAL;
225     }
226 
227     char *tempBuf = malloc(cipherTotalLen);
228     if (tempBuf == NULL) {
229         CIPHER_LOG_E("RsaEncrypt Base64Encode malloc fail.");
230         return ERROR_CODE_GENERAL;
231     }
232 
233     int32_t ret = memcpy_s(tempBuf, cipherTotalLen, cipherText, cipherTotalLen);
234     if (ret != EOK) {
235         CIPHER_LOG_E("memcpy fail.");
236         free(tempBuf);
237         return ERROR_CODE_GENERAL;
238     }
239 
240     (void)memset_s(cipherText, cipherTextLen, 0, cipherTextLen);
241     size_t dataLen = 0;
242     ret = mbedtls_base64_encode(NULL, 0, &dataLen, (const unsigned char *)tempBuf, cipherTotalLen);
243     if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) {
244         CIPHER_LOG_E("base64_encode fail.");
245         free(tempBuf);
246         return ERROR_CODE_GENERAL;
247     }
248 
249     ret = mbedtls_base64_encode((unsigned char *)cipherText, cipherTextLen, &dataLen,
250         (const unsigned char *)tempBuf, cipherTotalLen);
251     if (ret != 0) {
252         CIPHER_LOG_E("base64_encode fail.");
253         free(tempBuf);
254         return ERROR_CODE_GENERAL;
255     }
256     free(tempBuf);
257     return ERROR_SUCCESS;
258 }
259 
RsaEncryptMultipleBlock(mbedtls_rsa_context * rsa,const char * plainText,char * cipherText,int32_t cipherTextLen)260 static int32_t RsaEncryptMultipleBlock(mbedtls_rsa_context *rsa, const char *plainText,
261     char *cipherText, int32_t cipherTextLen)
262 {
263     mbedtls_ctr_drbg_context ctrDrbg;
264     mbedtls_entropy_context entropy;
265     int32_t rsaLen = mbedtls_rsa_get_len(rsa);
266     int32_t rsaContentLen = rsaLen - RSA_KEY_BYTE;
267     if ((rsaContentLen <= 0) || (rsaLen <= 0)) {
268         CIPHER_LOG_E("rsa content len:%d, rsaLen:%d.", rsaContentLen, rsaLen);
269         return ERROR_CODE_GENERAL;
270     }
271     int32_t count = strlen((const char *)(uintptr_t)plainText) / rsaContentLen;
272     int32_t remain = strlen((const char *)(uintptr_t)plainText) % rsaContentLen;
273     int32_t cipherTotalLen = 0;
274     unsigned char *buf = (unsigned char *)malloc(rsaLen);
275     if (buf == NULL) {
276         return ERROR_CODE_GENERAL;
277     }
278     int32_t ret = ERROR_CODE_GENERAL;
279     do {
280         RsaInit(&ctrDrbg, &entropy);
281         bool isBreak = false;
282         for (int32_t i = 0; i < count; i++) {
283             (void)memset_s(buf, rsaLen, 0, rsaLen);
284             if (mbedtls_rsa_pkcs1_encrypt(rsa, mbedtls_ctr_drbg_random, &ctrDrbg,
285                 rsaContentLen, (const unsigned char *)(plainText + i * rsaContentLen), buf)) {
286                 isBreak = true;
287                 break;
288             }
289             if (memcpy_s(cipherText + i * rsaLen, cipherTextLen - i * rsaLen, buf, rsaLen)) {
290                 isBreak = true;
291                 break;
292             }
293             cipherTotalLen += rsaLen;
294         }
295         if (isBreak) {
296             break;
297         }
298         if (remain > 0) {
299             (void)memset_s(buf, rsaLen, 0, rsaLen);
300             if (mbedtls_rsa_pkcs1_encrypt(rsa, mbedtls_ctr_drbg_random, &ctrDrbg,
301                 remain, (const unsigned char *)(plainText + count * rsaContentLen), buf)) {
302                 break;
303             }
304             if (memcpy_s(cipherText + count * rsaLen, cipherTextLen - count * rsaLen, buf, rsaLen)) {
305                 break;
306             }
307             cipherTotalLen += rsaLen;
308         }
309         if (RsaEncryptBase64Encode(cipherTotalLen, cipherText, cipherTextLen)) {
310             break;
311         }
312         ret = ERROR_SUCCESS;
313     } while (0);
314 
315     free(buf);
316     RsaDeinit(&ctrDrbg, &entropy);
317     return ret;
318 }
319 
RsaEncrypt(RsaKeyData * key,const RsaData * plain,RsaData * cipher)320 static int32_t RsaEncrypt(RsaKeyData *key, const RsaData *plain, RsaData *cipher)
321 {
322     if ((key->trans != NULL) && (strcmp(key->trans, "RSA/None/OAEPWithSHA256AndMGF1Padding"))) {
323         return ERROR_CODE_GENERAL;
324     }
325 
326     mbedtls_pk_context pk;
327     mbedtls_pk_init(&pk);
328     if (RsaLoadPublicKey(&pk, (const unsigned char *)key->key, key->keyLen) != 0) {
329         mbedtls_pk_free(&pk);
330         return ERROR_CODE_GENERAL;
331     }
332 
333     mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
334     if (rsa == NULL) {
335         mbedtls_pk_free(&pk);
336         return ERROR_CODE_GENERAL;
337     }
338 
339     int32_t rsaLen = mbedtls_rsa_get_len(rsa);
340     int32_t rsaContentLen = rsaLen - RSA_KEY_BYTE;
341     if (rsaContentLen <= 0) {
342         mbedtls_pk_free(&pk);
343         return ERROR_CODE_GENERAL;
344     }
345 
346     int32_t count = plain->length / rsaContentLen;
347     int32_t remain = plain->length % rsaContentLen;
348     if (cipher->data == NULL) {
349         cipher->length = rsaLen * count + (remain ? rsaLen : 0);
350         cipher->length = (cipher->length / NUM_THREE + 1) * NUM_FOUR + 1;
351         mbedtls_pk_free(&pk);
352         return ERROR_SUCCESS;
353     }
354 
355     if (RsaEncryptMultipleBlock(rsa, plain->data, cipher->data, cipher->length) != 0) {
356         CIPHER_LOG_E("Rsa encrypt block error.");
357         mbedtls_pk_free(&pk);
358         return ERROR_CODE_GENERAL;
359     }
360 
361     mbedtls_pk_free(&pk);
362     return ERROR_SUCCESS;
363 }
364 
CheckParamAndMallocBuf(size_t rsaLen,const RsaData * cipher,unsigned char ** buf,unsigned char ** tembuf)365 static int32_t CheckParamAndMallocBuf(size_t rsaLen, const RsaData *cipher, unsigned char **buf, unsigned char **tembuf)
366 {
367     if ((rsaLen == 0) || (cipher->length == 0)) {
368         return ERROR_CODE_GENERAL;
369     }
370     *buf = (unsigned char*)malloc(rsaLen);
371     if (*buf == NULL) {
372         return ERROR_CODE_GENERAL;
373     }
374     *tembuf = (unsigned char*)malloc(cipher->length);
375     if (*tembuf == NULL) {
376         free(*buf);
377         *buf = NULL;
378         return ERROR_CODE_GENERAL;
379     }
380     return ERROR_SUCCESS;
381 }
382 
RsaPkcs1Decrypt(mbedtls_rsa_context * rsa,size_t rsaLen,RsaData * cipher,RsaData * plain)383 static int32_t RsaPkcs1Decrypt(mbedtls_rsa_context *rsa, size_t rsaLen, RsaData *cipher, RsaData *plain)
384 {
385     size_t plainLen = 0;
386     int32_t totalPlainLen = 0;
387 
388     unsigned char *buf = NULL;
389     unsigned char *tembuf = NULL;
390 
391     int32_t ret = CheckParamAndMallocBuf(rsaLen, cipher, &buf, &tembuf);
392     if (ret != ERROR_SUCCESS) {
393         return ret;
394     }
395 
396     (void)memset_s(tembuf, cipher->length, 0, cipher->length);
397     mbedtls_ctr_drbg_context ctrDrbg;
398     mbedtls_entropy_context entropy;
399     RsaInit(&ctrDrbg, &entropy);
400     size_t dataLen;
401 
402     do {
403         if (mbedtls_base64_decode(tembuf, cipher->length, &dataLen, (const unsigned char *)cipher->data,
404             cipher->length)) {
405             break;
406         }
407         int32_t count = dataLen / rsaLen;
408         bool isBreak = false;
409         for (int32_t i = 0; i < count; i++) {
410             (void)memset_s(buf, rsaLen, 0, rsaLen);
411             if (mbedtls_rsa_pkcs1_decrypt(rsa, mbedtls_ctr_drbg_random, &ctrDrbg,
412                 &plainLen, tembuf + i * rsaLen, buf, rsaLen)) {
413                 isBreak = true;
414                 break;
415             }
416             if (memcpy_s(plain->data + totalPlainLen, plain->length - totalPlainLen, buf, plainLen)) {
417                 isBreak = true;
418                 break;
419             }
420             totalPlainLen += plainLen;
421         }
422         if (isBreak) {
423             break;
424         }
425         plain->length = totalPlainLen;
426         RsaDeinit(&ctrDrbg, &entropy);
427         free(tembuf);
428         free(buf);
429         return ERROR_SUCCESS;
430     } while (0);
431 
432     RsaDeinit(&ctrDrbg, &entropy);
433     free(tembuf);
434     free(buf);
435     return ERROR_CODE_GENERAL;
436 }
437 
RsaDecrypt(RsaKeyData * key,RsaData * cipher,RsaData * plain)438 static int32_t RsaDecrypt(RsaKeyData *key, RsaData *cipher, RsaData *plain)
439 {
440     if ((key->trans != NULL) && (strcmp(key->trans, "RSA/None/OAEPWithSHA256AndMGF1Padding"))) {
441         return ERROR_CODE_GENERAL;
442     }
443 
444     if (plain->data == NULL) {
445         plain->length = cipher->length;
446         return ERROR_SUCCESS;
447     }
448 
449     mbedtls_pk_context pk;
450     mbedtls_pk_init(&pk);
451     if (RsaLoadPrivateKey(&pk, (const unsigned char *)key->key, key->keyLen) != 0) {
452         mbedtls_pk_free(&pk);
453         return ERROR_CODE_GENERAL;
454     }
455 
456     mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
457     size_t rsaLen = mbedtls_rsa_get_len(rsa);
458     int32_t ret = RsaPkcs1Decrypt(rsa, rsaLen, cipher, plain);
459     if (ret != ERROR_SUCCESS) {
460         CIPHER_LOG_E("Rsa pkcs1 decrypt failed.");
461         mbedtls_pk_free(&pk);
462         return ERROR_CODE_GENERAL;
463     }
464 
465     mbedtls_pk_free(&pk);
466     return ERROR_SUCCESS;
467 }
468 
RsaCrypt(RsaKeyData * key,RsaData * inData,RsaData * outData)469 int32_t RsaCrypt(RsaKeyData *key, RsaData *inData, RsaData *outData)
470 {
471     if (key == NULL || inData == NULL || outData == NULL) {
472         return ERROR_CODE_GENERAL;
473     }
474 
475     if ((key->action == NULL) || (key->key == NULL) || (inData->data == NULL)) {
476         return ERROR_CODE_GENERAL;
477     }
478 
479     if (!strcmp(key->action, "encrypt")) {
480         return RsaEncrypt(key, inData, outData);
481     } else if (!strcmp(key->action, "decrypt")) {
482         return RsaDecrypt(key, inData, outData);
483     } else {
484         return ERROR_CODE_GENERAL;
485     }
486 }
487