source: azure_iot_hub/trunk/wolfssl-3.15.7/wolfcrypt/src/wc_encrypt.c@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 16.1 KB
Line 
1/* wc_encrypt.c
2 *
3 * Copyright (C) 2006-2017 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 = NULL;
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#ifndef NO_DES3
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 = NULL;
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 = NULL;
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 = NULL;
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 = NULL;
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#ifndef NO_PWDBASED
276 if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1,
277 info->keySz, hashType)) != 0) {
278#ifdef WOLFSSL_SMALL_STACK
279 XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
280#endif
281 return ret;
282 }
283#endif
284
285#ifndef NO_DES3
286 if (info->cipherType == WC_CIPHER_DES)
287 ret = wc_Des_CbcDecryptWithKey(der, der, derSz, key, info->iv);
288 if (info->cipherType == WC_CIPHER_DES3)
289 ret = wc_Des3_CbcDecryptWithKey(der, der, derSz, key, info->iv);
290#endif /* NO_DES3 */
291#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT)
292 if (info->cipherType == WC_CIPHER_AES_CBC)
293 ret = wc_AesCbcDecryptWithKey(der, der, derSz, key, info->keySz,
294 info->iv);
295#endif /* !NO_AES && HAVE_AES_CBC && HAVE_AES_DECRYPT */
296
297#ifdef WOLFSSL_SMALL_STACK
298 XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
299#endif
300
301 return ret;
302}
303
304int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz,
305 const byte* password, int passwordSz, int hashType)
306{
307 int ret = NOT_COMPILED_IN;
308#ifdef WOLFSSL_SMALL_STACK
309 byte* key = NULL;
310#else
311 byte key[WC_MAX_SYM_KEY_SIZE];
312#endif
313
314 (void)derSz;
315 (void)passwordSz;
316 (void)hashType;
317
318 if (der == NULL || password == NULL || info == NULL || info->keySz == 0 ||
319 info->ivSz < PKCS5_SALT_SZ) {
320 return BAD_FUNC_ARG;
321 }
322
323#ifdef WOLFSSL_SMALL_STACK
324 key = (byte*)XMALLOC(WC_MAX_SYM_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
325 if (key == NULL) {
326 return MEMORY_E;
327 }
328#endif /* WOLFSSL_SMALL_STACK */
329
330#ifndef NO_PWDBASED
331 if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1,
332 info->keySz, hashType)) != 0) {
333#ifdef WOLFSSL_SMALL_STACK
334 XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
335#endif
336 return ret;
337 }
338#endif
339
340#ifndef NO_DES3
341 if (info->cipherType == WC_CIPHER_DES)
342 ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv);
343 if (info->cipherType == WC_CIPHER_DES3)
344 ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv);
345#endif /* NO_DES3 */
346#if !defined(NO_AES) && defined(HAVE_AES_CBC)
347 if (info->cipherType == WC_CIPHER_AES_CBC)
348 ret = wc_AesCbcEncryptWithKey(der, der, derSz, key, info->keySz,
349 info->iv);
350#endif /* !NO_AES && HAVE_AES_CBC */
351
352#ifdef WOLFSSL_SMALL_STACK
353 XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
354#endif
355
356 return ret;
357}
358
359#endif /* WOLFSSL_ENCRYPTED_KEYS */
360
361
362#ifndef NO_PWDBASED
363
364/* Decrypt/Encrypt input in place from parameters based on id
365 *
366 * returns a negative value on fail case
367 */
368int wc_CryptKey(const char* password, int passwordSz, byte* salt,
369 int saltSz, int iterations, int id, byte* input,
370 int length, int version, byte* cbcIv, int enc)
371{
372 int typeH;
373 int derivedLen;
374 int ret = 0;
375#ifdef WOLFSSL_SMALL_STACK
376 byte* key;
377#else
378 byte key[MAX_KEY_SIZE];
379#endif
380
381 (void)input;
382 (void)length;
383 (void)enc;
384
385 WOLFSSL_ENTER("wc_CryptKey");
386
387 switch (id) {
388 #ifndef NO_DES3
389 #ifndef NO_MD5
390 case PBE_MD5_DES:
391 typeH = WC_MD5;
392 derivedLen = 16; /* may need iv for v1.5 */
393 break;
394 #endif
395 #ifndef NO_SHA
396 case PBE_SHA1_DES:
397 typeH = WC_SHA;
398 derivedLen = 16; /* may need iv for v1.5 */
399 break;
400
401 case PBE_SHA1_DES3:
402 typeH = WC_SHA;
403 derivedLen = 32; /* may need iv for v1.5 */
404 break;
405 #endif /* !NO_SHA */
406 #endif /* !NO_DES3 */
407 #if !defined(NO_SHA) && !defined(NO_RC4)
408 case PBE_SHA1_RC4_128:
409 typeH = WC_SHA;
410 derivedLen = 16;
411 break;
412 #endif
413 #ifdef WOLFSSL_AES_256
414 case PBE_AES256_CBC:
415 typeH = WC_SHA256;
416 derivedLen = 32;
417 break;
418 #endif
419 default:
420 WOLFSSL_MSG("Unknown/Unsupported encrypt/decrypt id");
421 return ALGO_ID_E;
422 }
423
424#ifdef WOLFSSL_SMALL_STACK
425 key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
426 if (key == NULL)
427 return MEMORY_E;
428#endif
429
430 if (version == PKCS5v2)
431 ret = wc_PBKDF2(key, (byte*)password, passwordSz,
432 salt, saltSz, iterations, derivedLen, typeH);
433#ifndef NO_SHA
434 else if (version == PKCS5)
435 ret = wc_PBKDF1(key, (byte*)password, passwordSz,
436 salt, saltSz, iterations, derivedLen, typeH);
437#endif
438 else if (version == PKCS12v1) {
439 int i, idx = 0;
440 byte unicodePasswd[MAX_UNICODE_SZ];
441
442 if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
443#ifdef WOLFSSL_SMALL_STACK
444 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
445#endif
446 return UNICODE_SIZE_E;
447 }
448
449 for (i = 0; i < passwordSz; i++) {
450 unicodePasswd[idx++] = 0x00;
451 unicodePasswd[idx++] = (byte)password[i];
452 }
453 /* add trailing NULL */
454 unicodePasswd[idx++] = 0x00;
455 unicodePasswd[idx++] = 0x00;
456
457 ret = wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
458 iterations, derivedLen, typeH, 1);
459 if (id != PBE_SHA1_RC4_128)
460 ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
461 iterations, 8, typeH, 2);
462 }
463 else {
464#ifdef WOLFSSL_SMALL_STACK
465 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
466#endif
467 WOLFSSL_MSG("Unknown/Unsupported PKCS version");
468 return ALGO_ID_E;
469 }
470
471 if (ret != 0) {
472#ifdef WOLFSSL_SMALL_STACK
473 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
474#endif
475 return ret;
476 }
477
478 switch (id) {
479#ifndef NO_DES3
480 #if !defined(NO_SHA) || !defined(NO_MD5)
481 case PBE_MD5_DES:
482 case PBE_SHA1_DES:
483 {
484 Des des;
485 byte* desIv = key + 8;
486
487 if (version == PKCS5v2 || version == PKCS12v1)
488 desIv = cbcIv;
489
490 if (enc) {
491 ret = wc_Des_SetKey(&des, key, desIv, DES_ENCRYPTION);
492 }
493 else {
494 ret = wc_Des_SetKey(&des, key, desIv, DES_DECRYPTION);
495 }
496 if (ret != 0) {
497#ifdef WOLFSSL_SMALL_STACK
498 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
499#endif
500 return ret;
501 }
502
503 if (enc) {
504 wc_Des_CbcEncrypt(&des, input, input, length);
505 }
506 else {
507 wc_Des_CbcDecrypt(&des, input, input, length);
508 }
509 break;
510 }
511 #endif /* !NO_SHA || !NO_MD5 */
512
513 #ifndef NO_SHA
514 case PBE_SHA1_DES3:
515 {
516 Des3 des;
517 byte* desIv = key + 24;
518
519 if (version == PKCS5v2 || version == PKCS12v1)
520 desIv = cbcIv;
521
522 ret = wc_Des3Init(&des, NULL, INVALID_DEVID);
523 if (ret != 0) {
524#ifdef WOLFSSL_SMALL_STACK
525 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
526#endif
527 return ret;
528 }
529 if (enc) {
530 ret = wc_Des3_SetKey(&des, key, desIv, DES_ENCRYPTION);
531 }
532 else {
533 ret = wc_Des3_SetKey(&des, key, desIv, DES_DECRYPTION);
534 }
535 if (ret != 0) {
536#ifdef WOLFSSL_SMALL_STACK
537 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
538#endif
539 return ret;
540 }
541 if (enc) {
542 ret = wc_Des3_CbcEncrypt(&des, input, input, length);
543 }
544 else {
545 ret = wc_Des3_CbcDecrypt(&des, input, input, length);
546 }
547 if (ret != 0) {
548#ifdef WOLFSSL_SMALL_STACK
549 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
550#endif
551 return ret;
552 }
553 break;
554 }
555 #endif /* !NO_SHA */
556#endif
557#if !defined(NO_RC4) && !defined(NO_SHA)
558 case PBE_SHA1_RC4_128:
559 {
560 Arc4 dec;
561
562 wc_Arc4SetKey(&dec, key, derivedLen);
563 wc_Arc4Process(&dec, input, input, length);
564 break;
565 }
566#endif
567#if !defined(NO_AES) && defined(HAVE_AES_CBC)
568 #ifdef WOLFSSL_AES_256
569 case PBE_AES256_CBC:
570 {
571 Aes aes;
572 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
573 if (ret == 0) {
574 if (enc) {
575 ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,
576 AES_ENCRYPTION);
577 }
578 else {
579 ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,
580 AES_DECRYPTION);
581 }
582 }
583 if (ret == 0) {
584 if (enc)
585 ret = wc_AesCbcEncrypt(&aes, input, input, length);
586 else
587 ret = wc_AesCbcDecrypt(&aes, 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 ForceZero(&aes, sizeof(Aes));
596 break;
597 }
598 #endif /* WOLFSSL_AES_256 */
599#endif /* !NO_AES && HAVE_AES_CBC */
600
601 default:
602#ifdef WOLFSSL_SMALL_STACK
603 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
604#endif
605 WOLFSSL_MSG("Unknown/Unsupported encrypt/decryption algorithm");
606 return ALGO_ID_E;
607 }
608
609#ifdef WOLFSSL_SMALL_STACK
610 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
611#endif
612
613 return ret;
614}
615
616#endif /* !NO_PWDBASED */
Note: See TracBrowser for help on using the repository browser.