source: azure_iot_hub_riscv/trunk/wolfssl-4.4.0/wolfcrypt/src/wc_encrypt.c@ 453

Last change on this file since 453 was 453, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 17.4 KB
Line 
1/* wc_encrypt.c
2 *
3 * Copyright (C) 2006-2020 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22
23#ifdef HAVE_CONFIG_H
24 #include <config.h>
25#endif
26
27#include <wolfssl/wolfcrypt/settings.h>
28#include <wolfssl/wolfcrypt/aes.h>
29#include <wolfssl/wolfcrypt/des3.h>
30#include <wolfssl/wolfcrypt/hash.h>
31#include <wolfssl/wolfcrypt/arc4.h>
32#include <wolfssl/wolfcrypt/wc_encrypt.h>
33#include <wolfssl/wolfcrypt/error-crypt.h>
34#include <wolfssl/wolfcrypt/asn.h>
35#include <wolfssl/wolfcrypt/coding.h>
36#include <wolfssl/wolfcrypt/pwdbased.h>
37#include <wolfssl/wolfcrypt/logging.h>
38
39#ifdef NO_INLINE
40 #include <wolfssl/wolfcrypt/misc.h>
41#else
42 #define WOLFSSL_MISC_INCLUDED
43 #include <wolfcrypt/src/misc.c>
44#endif
45
46#if !defined(NO_AES) && defined(HAVE_AES_CBC)
47#ifdef HAVE_AES_DECRYPT
48int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz,
49 const byte* key, word32 keySz, const byte* iv)
50{
51 int ret = 0;
52#ifdef WOLFSSL_SMALL_STACK
53 Aes* aes = NULL;
54#else
55 Aes aes[1];
56#endif
57
58 if (out == NULL || in == NULL || key == NULL || iv == NULL) {
59 return BAD_FUNC_ARG;
60 }
61
62#ifdef WOLFSSL_SMALL_STACK
63 aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER);
64 if (aes == NULL)
65 return MEMORY_E;
66#endif
67
68 ret = wc_AesInit(aes, NULL, INVALID_DEVID);
69 if (ret == 0) {
70 ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
71 if (ret == 0)
72 ret = wc_AesCbcDecrypt(aes, out, in, inSz);
73
74 wc_AesFree(aes);
75 }
76
77#ifdef WOLFSSL_SMALL_STACK
78 XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER);
79#endif
80
81 return ret;
82}
83#endif /* HAVE_AES_DECRYPT */
84
85int wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz,
86 const byte* key, word32 keySz, const byte* iv)
87{
88 int ret = 0;
89#ifdef WOLFSSL_SMALL_STACK
90 Aes* aes;
91#else
92 Aes aes[1];
93#endif
94
95#ifdef WOLFSSL_SMALL_STACK
96 aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER);
97 if (aes == NULL)
98 return MEMORY_E;
99#endif
100
101 ret = wc_AesInit(aes, NULL, INVALID_DEVID);
102 if (ret == 0) {
103 ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
104 if (ret == 0)
105 ret = wc_AesCbcEncrypt(aes, out, in, inSz);
106
107 wc_AesFree(aes);
108 }
109
110#ifdef WOLFSSL_SMALL_STACK
111 XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER);
112#endif
113
114 return ret;
115}
116#endif /* !NO_AES && HAVE_AES_CBC */
117
118
119#if !defined(NO_DES3) && !defined(WOLFSSL_TI_CRYPT)
120int wc_Des_CbcEncryptWithKey(byte* out, const byte* in, word32 sz,
121 const byte* key, const byte* iv)
122{
123 int ret = 0;
124#ifdef WOLFSSL_SMALL_STACK
125 Des* des;
126#else
127 Des des[1];
128#endif
129
130#ifdef WOLFSSL_SMALL_STACK
131 des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER);
132 if (des == NULL)
133 return MEMORY_E;
134#endif
135
136 ret = wc_Des_SetKey(des, key, iv, DES_ENCRYPTION);
137 if (ret == 0)
138 ret = wc_Des_CbcEncrypt(des, out, in, sz);
139
140#ifdef WOLFSSL_SMALL_STACK
141 XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER);
142#endif
143
144 return ret;
145}
146
147int wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz,
148 const byte* key, const byte* iv)
149{
150 int ret = 0;
151#ifdef WOLFSSL_SMALL_STACK
152 Des* des;
153#else
154 Des des[1];
155#endif
156
157#ifdef WOLFSSL_SMALL_STACK
158 des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER);
159 if (des == NULL)
160 return MEMORY_E;
161#endif
162
163 ret = wc_Des_SetKey(des, key, iv, DES_DECRYPTION);
164 if (ret == 0)
165 ret = wc_Des_CbcDecrypt(des, out, in, sz);
166
167#ifdef WOLFSSL_SMALL_STACK
168 XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER);
169#endif
170
171 return ret;
172}
173
174
175int wc_Des3_CbcEncryptWithKey(byte* out, const byte* in, word32 sz,
176 const byte* key, const byte* iv)
177{
178 int ret = 0;
179#ifdef WOLFSSL_SMALL_STACK
180 Des3* des3;
181#else
182 Des3 des3[1];
183#endif
184
185#ifdef WOLFSSL_SMALL_STACK
186 des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER);
187 if (des3 == NULL)
188 return MEMORY_E;
189#endif
190
191 ret = wc_Des3Init(des3, NULL, INVALID_DEVID);
192 if (ret == 0) {
193 ret = wc_Des3_SetKey(des3, key, iv, DES_ENCRYPTION);
194 if (ret == 0)
195 ret = wc_Des3_CbcEncrypt(des3, out, in, sz);
196 wc_Des3Free(des3);
197 }
198
199#ifdef WOLFSSL_SMALL_STACK
200 XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER);
201#endif
202
203 return ret;
204}
205
206
207int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz,
208 const byte* key, const byte* iv)
209{
210 int ret = 0;
211#ifdef WOLFSSL_SMALL_STACK
212 Des3* des3;
213#else
214 Des3 des3[1];
215#endif
216
217#ifdef WOLFSSL_SMALL_STACK
218 des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER);
219 if (des3 == NULL)
220 return MEMORY_E;
221#endif
222
223 ret = wc_Des3Init(des3, NULL, INVALID_DEVID);
224 if (ret == 0) {
225 ret = wc_Des3_SetKey(des3, key, iv, DES_DECRYPTION);
226 if (ret == 0)
227 ret = wc_Des3_CbcDecrypt(des3, out, in, sz);
228 wc_Des3Free(des3);
229 }
230
231#ifdef WOLFSSL_SMALL_STACK
232 XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER);
233#endif
234
235 return ret;
236}
237
238#endif /* !NO_DES3 */
239
240
241#ifdef WOLFSSL_ENCRYPTED_KEYS
242
243int wc_BufferKeyDecrypt(EncryptedInfo* info, byte* der, word32 derSz,
244 const byte* password, int passwordSz, int hashType)
245{
246 int ret = NOT_COMPILED_IN;
247#ifdef WOLFSSL_SMALL_STACK
248 byte* key = NULL;
249#else
250 byte key[WC_MAX_SYM_KEY_SIZE];
251#endif
252
253 (void)derSz;
254 (void)passwordSz;
255 (void)hashType;
256
257 if (der == NULL || password == NULL || info == NULL || info->keySz == 0) {
258 return BAD_FUNC_ARG;
259 }
260
261 /* use file's salt for key derivation, hex decode first */
262 if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) {
263 return BUFFER_E;
264 }
265 if (info->ivSz < PKCS5_SALT_SZ)
266 return BUFFER_E;
267
268#ifdef WOLFSSL_SMALL_STACK
269 key = (byte*)XMALLOC(WC_MAX_SYM_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
270 if (key == NULL) {
271 return MEMORY_E;
272 }
273#endif
274
275 (void)XMEMSET(key, 0, WC_MAX_SYM_KEY_SIZE);
276
277#ifndef NO_PWDBASED
278 if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1,
279 info->keySz, hashType)) != 0) {
280#ifdef WOLFSSL_SMALL_STACK
281 XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
282#endif
283 return ret;
284 }
285#endif
286
287#ifndef NO_DES3
288 if (info->cipherType == WC_CIPHER_DES)
289 ret = wc_Des_CbcDecryptWithKey(der, der, derSz, key, info->iv);
290 if (info->cipherType == WC_CIPHER_DES3)
291 ret = wc_Des3_CbcDecryptWithKey(der, der, derSz, key, info->iv);
292#endif /* NO_DES3 */
293#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT)
294 if (info->cipherType == WC_CIPHER_AES_CBC)
295 ret = wc_AesCbcDecryptWithKey(der, der, derSz, key, info->keySz,
296 info->iv);
297#endif /* !NO_AES && HAVE_AES_CBC && HAVE_AES_DECRYPT */
298
299#ifdef WOLFSSL_SMALL_STACK
300 XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
301#endif
302
303 return ret;
304}
305
306int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz,
307 const byte* password, int passwordSz, int hashType)
308{
309 int ret = NOT_COMPILED_IN;
310#ifdef WOLFSSL_SMALL_STACK
311 byte* key = NULL;
312#else
313 byte key[WC_MAX_SYM_KEY_SIZE];
314#endif
315
316 (void)derSz;
317 (void)passwordSz;
318 (void)hashType;
319
320 if (der == NULL || password == NULL || info == NULL || info->keySz == 0 ||
321 info->ivSz < PKCS5_SALT_SZ) {
322 return BAD_FUNC_ARG;
323 }
324
325#ifdef WOLFSSL_SMALL_STACK
326 key = (byte*)XMALLOC(WC_MAX_SYM_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
327 if (key == NULL) {
328 return MEMORY_E;
329 }
330#endif /* WOLFSSL_SMALL_STACK */
331
332 (void)XMEMSET(key, 0, WC_MAX_SYM_KEY_SIZE);
333
334#ifndef NO_PWDBASED
335 if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1,
336 info->keySz, hashType)) != 0) {
337#ifdef WOLFSSL_SMALL_STACK
338 XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
339#endif
340 return ret;
341 }
342#endif
343
344#ifndef NO_DES3
345 if (info->cipherType == WC_CIPHER_DES)
346 ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv);
347 if (info->cipherType == WC_CIPHER_DES3)
348 ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv);
349#endif /* NO_DES3 */
350#if !defined(NO_AES) && defined(HAVE_AES_CBC)
351 if (info->cipherType == WC_CIPHER_AES_CBC)
352 ret = wc_AesCbcEncryptWithKey(der, der, derSz, key, info->keySz,
353 info->iv);
354#endif /* !NO_AES && HAVE_AES_CBC */
355
356#ifdef WOLFSSL_SMALL_STACK
357 XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
358#endif
359
360 return ret;
361}
362
363#endif /* WOLFSSL_ENCRYPTED_KEYS */
364
365
366#if !defined(NO_PWDBASED) && !defined(NO_ASN)
367
368#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
369/* Decrypt/Encrypt input in place from parameters based on id
370 *
371 * returns a negative value on fail case
372 */
373int wc_CryptKey(const char* password, int passwordSz, byte* salt,
374 int saltSz, int iterations, int id, byte* input,
375 int length, int version, byte* cbcIv, int enc, int shaOid)
376{
377 int typeH;
378 int derivedLen = 0;
379 int ret = 0;
380#ifdef WOLFSSL_SMALL_STACK
381 byte* key;
382#else
383 byte key[MAX_KEY_SIZE];
384#endif
385
386 (void)input;
387 (void)length;
388 (void)enc;
389
390 WOLFSSL_ENTER("wc_CryptKey");
391
392 switch (id) {
393 #ifndef NO_DES3
394 #ifndef NO_MD5
395 case PBE_MD5_DES:
396 typeH = WC_MD5;
397 derivedLen = 16; /* may need iv for v1.5 */
398 break;
399 #endif
400 #ifndef NO_SHA
401 case PBE_SHA1_DES:
402 typeH = WC_SHA;
403 derivedLen = 16; /* may need iv for v1.5 */
404 break;
405
406 case PBE_SHA1_DES3:
407 switch(shaOid) {
408 case HMAC_SHA256_OID:
409 typeH = WC_SHA256;
410 derivedLen = 32;
411 break;
412 default:
413 typeH = WC_SHA;
414 derivedLen = 32; /* may need iv for v1.5 */
415 break;
416 }
417 break;
418 #endif /* !NO_SHA */
419 #endif /* !NO_DES3 */
420 #if !defined(NO_SHA) && !defined(NO_RC4)
421 case PBE_SHA1_RC4_128:
422 typeH = WC_SHA;
423 derivedLen = 16;
424 break;
425 #endif
426 #if defined(WOLFSSL_AES_256)
427 case PBE_AES256_CBC:
428 switch(shaOid) {
429 case HMAC_SHA256_OID:
430 typeH = WC_SHA256;
431 derivedLen = 32;
432 break;
433 #ifndef NO_SHA
434 default:
435 typeH = WC_SHA;
436 derivedLen = 32;
437 break;
438 #endif
439 }
440 break;
441 #endif /* WOLFSSL_AES_256 && !NO_SHA */
442 #if defined(WOLFSSL_AES_128)
443 case PBE_AES128_CBC:
444 switch(shaOid) {
445 case HMAC_SHA256_OID:
446 typeH = WC_SHA256;
447 derivedLen = 16;
448 break;
449 #ifndef NO_SHA
450 default:
451 typeH = WC_SHA;
452 derivedLen = 16;
453 break;
454 #endif
455 }
456 break;
457 #endif /* WOLFSSL_AES_128 && !NO_SHA */
458 default:
459 WOLFSSL_MSG("Unknown/Unsupported encrypt/decrypt id");
460 (void)shaOid;
461 return ALGO_ID_E;
462 }
463
464#ifdef WOLFSSL_SMALL_STACK
465 key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
466 if (key == NULL)
467 return MEMORY_E;
468#endif
469
470 if (version == PKCS5v2)
471 ret = wc_PBKDF2(key, (byte*)password, passwordSz,
472 salt, saltSz, iterations, derivedLen, typeH);
473#ifndef NO_SHA
474 else if (version == PKCS5)
475 ret = wc_PBKDF1(key, (byte*)password, passwordSz,
476 salt, saltSz, iterations, derivedLen, typeH);
477#endif
478#ifdef HAVE_PKCS12
479 else if (version == PKCS12v1) {
480 int i, idx = 0;
481 byte unicodePasswd[MAX_UNICODE_SZ];
482
483 if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
484#ifdef WOLFSSL_SMALL_STACK
485 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
486#endif
487 return UNICODE_SIZE_E;
488 }
489
490 for (i = 0; i < passwordSz; i++) {
491 unicodePasswd[idx++] = 0x00;
492 unicodePasswd[idx++] = (byte)password[i];
493 }
494 /* add trailing NULL */
495 unicodePasswd[idx++] = 0x00;
496 unicodePasswd[idx++] = 0x00;
497
498 ret = wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
499 iterations, derivedLen, typeH, 1);
500 if (id != PBE_SHA1_RC4_128)
501 ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
502 iterations, 8, typeH, 2);
503 }
504#endif /* HAVE_PKCS12 */
505 else {
506#ifdef WOLFSSL_SMALL_STACK
507 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
508#endif
509 WOLFSSL_MSG("Unknown/Unsupported PKCS version");
510 return ALGO_ID_E;
511 }
512
513 if (ret != 0) {
514#ifdef WOLFSSL_SMALL_STACK
515 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
516#endif
517 return ret;
518 }
519
520 switch (id) {
521#ifndef NO_DES3
522 #if !defined(NO_SHA) || !defined(NO_MD5)
523 case PBE_MD5_DES:
524 case PBE_SHA1_DES:
525 {
526 Des des;
527 byte* desIv = key + 8;
528
529 if (version == PKCS5v2 || version == PKCS12v1)
530 desIv = cbcIv;
531
532 if (enc) {
533 ret = wc_Des_SetKey(&des, key, desIv, DES_ENCRYPTION);
534 }
535 else {
536 ret = wc_Des_SetKey(&des, key, desIv, DES_DECRYPTION);
537 }
538 if (ret != 0) {
539#ifdef WOLFSSL_SMALL_STACK
540 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
541#endif
542 return ret;
543 }
544
545 if (enc) {
546 wc_Des_CbcEncrypt(&des, input, input, length);
547 }
548 else {
549 wc_Des_CbcDecrypt(&des, input, input, length);
550 }
551 break;
552 }
553 #endif /* !NO_SHA || !NO_MD5 */
554
555 #ifndef NO_SHA
556 case PBE_SHA1_DES3:
557 {
558 Des3 des;
559 byte* desIv = key + 24;
560
561 if (version == PKCS5v2 || version == PKCS12v1)
562 desIv = cbcIv;
563
564 ret = wc_Des3Init(&des, NULL, INVALID_DEVID);
565 if (ret != 0) {
566#ifdef WOLFSSL_SMALL_STACK
567 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
568#endif
569 return ret;
570 }
571 if (enc) {
572 ret = wc_Des3_SetKey(&des, key, desIv, DES_ENCRYPTION);
573 }
574 else {
575 ret = wc_Des3_SetKey(&des, key, desIv, DES_DECRYPTION);
576 }
577 if (ret != 0) {
578#ifdef WOLFSSL_SMALL_STACK
579 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
580#endif
581 return ret;
582 }
583 if (enc) {
584 ret = wc_Des3_CbcEncrypt(&des, input, input, length);
585 }
586 else {
587 ret = wc_Des3_CbcDecrypt(&des, input, input, length);
588 }
589 if (ret != 0) {
590#ifdef WOLFSSL_SMALL_STACK
591 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
592#endif
593 return ret;
594 }
595 break;
596 }
597 #endif /* !NO_SHA */
598#endif
599#if !defined(NO_RC4) && !defined(NO_SHA)
600 case PBE_SHA1_RC4_128:
601 {
602 Arc4 dec;
603
604 wc_Arc4SetKey(&dec, key, derivedLen);
605 wc_Arc4Process(&dec, input, input, length);
606 break;
607 }
608#endif
609#if !defined(NO_AES) && defined(HAVE_AES_CBC)
610 #ifdef WOLFSSL_AES_256
611 case PBE_AES256_CBC:
612 case PBE_AES128_CBC:
613 {
614 Aes aes;
615 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
616 if (ret == 0) {
617 if (enc) {
618 ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,
619 AES_ENCRYPTION);
620 }
621 else {
622 ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,
623 AES_DECRYPTION);
624 }
625 }
626 if (ret == 0) {
627 if (enc)
628 ret = wc_AesCbcEncrypt(&aes, input, input, length);
629 else
630 ret = wc_AesCbcDecrypt(&aes, input, input, length);
631 }
632 if (ret != 0) {
633#ifdef WOLFSSL_SMALL_STACK
634 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
635#endif
636 return ret;
637 }
638 ForceZero(&aes, sizeof(Aes));
639 break;
640 }
641 #endif /* WOLFSSL_AES_256 */
642#endif /* !NO_AES && HAVE_AES_CBC */
643
644 default:
645#ifdef WOLFSSL_SMALL_STACK
646 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
647#endif
648 WOLFSSL_MSG("Unknown/Unsupported encrypt/decryption algorithm");
649 return ALGO_ID_E;
650 }
651
652#ifdef WOLFSSL_SMALL_STACK
653 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
654#endif
655
656 return ret;
657}
658
659#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
660#endif /* !NO_PWDBASED */
Note: See TracBrowser for help on using the repository browser.