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