FreeRDP
Loading...
Searching...
No Matches
cipher.c
1
19#include <winpr/config.h>
20
21#include <winpr/crt.h>
22#include <winpr/assert.h>
23#include <winpr/crypto.h>
24
25#include "../log.h"
26#define TAG WINPR_TAG("crypto.cipher")
27
28#if defined(WITH_INTERNAL_RC4)
29#include "rc4.h"
30#endif
31
32#ifdef WITH_OPENSSL
33#include <openssl/aes.h>
34#include <openssl/rc4.h>
35#include <openssl/des.h>
36#include <openssl/evp.h>
37#endif
38
39#ifdef WITH_MBEDTLS
40#include <mbedtls/md.h>
41#include <mbedtls/aes.h>
42#include <mbedtls/des.h>
43#include <mbedtls/cipher.h>
44#if MBEDTLS_VERSION_MAJOR < 3
45#define mbedtls_cipher_info_get_iv_size(_info) (_info->iv_size)
46#define mbedtls_cipher_info_get_key_bitlen(_info) (_info->key_bitlen)
47#endif
48#endif
49
50struct winpr_cipher_ctx_private_st
51{
52 WINPR_CIPHER_TYPE cipher;
53 WINPR_CRYPTO_OPERATION op;
54
55#ifdef WITH_OPENSSL
56 EVP_CIPHER_CTX* ectx;
57#endif
58#ifdef WITH_MBEDTLS
59 mbedtls_cipher_context_t* mctx;
60#endif
61};
62
67struct winpr_rc4_ctx_private_st
68{
69#if defined(WITH_INTERNAL_RC4)
70 winpr_int_RC4_CTX* ictx;
71#else
72#if defined(WITH_OPENSSL)
73 EVP_CIPHER_CTX* ctx;
74#endif
75#endif
76};
77
78static WINPR_RC4_CTX* winpr_RC4_New_Internal(const BYTE* key, size_t keylen, BOOL override_fips)
79{
80 if (!key || (keylen == 0))
81 return NULL;
82
83 WINPR_RC4_CTX* ctx = (WINPR_RC4_CTX*)calloc(1, sizeof(WINPR_RC4_CTX));
84 if (!ctx)
85 return NULL;
86
87#if defined(WITH_INTERNAL_RC4)
88 WINPR_UNUSED(override_fips);
89 ctx->ictx = winpr_int_rc4_new(key, keylen);
90 if (!ctx->ictx)
91 goto fail;
92#elif defined(WITH_OPENSSL)
93 const EVP_CIPHER* evp = NULL;
94
95 if (keylen > INT_MAX)
96 goto fail;
97
98 ctx->ctx = EVP_CIPHER_CTX_new();
99 if (!ctx->ctx)
100 goto fail;
101
102 evp = EVP_rc4();
103
104 if (!evp)
105 goto fail;
106
107 EVP_CIPHER_CTX_reset(ctx->ctx);
108 if (EVP_EncryptInit_ex(ctx->ctx, evp, NULL, NULL, NULL) != 1)
109 goto fail;
110
111 /* EVP_CIPH_FLAG_NON_FIPS_ALLOW does not exist before openssl 1.0.1 */
112#if !(OPENSSL_VERSION_NUMBER < 0x10001000L)
113
114 if (override_fips == TRUE)
115 EVP_CIPHER_CTX_set_flags(ctx->ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
116
117#endif
118 EVP_CIPHER_CTX_set_key_length(ctx->ctx, (int)keylen);
119 if (EVP_EncryptInit_ex(ctx->ctx, NULL, NULL, key, NULL) != 1)
120 goto fail;
121#endif
122 return ctx;
123
124fail:
125 WINPR_PRAGMA_DIAG_PUSH
126 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
127
128 winpr_RC4_Free(ctx);
129 WINPR_PRAGMA_DIAG_POP
130 return NULL;
131}
132
133WINPR_RC4_CTX* winpr_RC4_New_Allow_FIPS(const void* key, size_t keylen)
134{
135 return winpr_RC4_New_Internal(key, keylen, TRUE);
136}
137
138WINPR_RC4_CTX* winpr_RC4_New(const void* key, size_t keylen)
139{
140 return winpr_RC4_New_Internal(key, keylen, FALSE);
141}
142
143BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const void* input, void* output)
144{
145 WINPR_ASSERT(ctx);
146
147#if defined(WITH_INTERNAL_RC4)
148 return winpr_int_rc4_update(ctx->ictx, length, input, output);
149#elif defined(WITH_OPENSSL)
150 WINPR_ASSERT(ctx->ctx);
151 int outputLength = 0;
152 if (length > INT_MAX)
153 return FALSE;
154
155 WINPR_ASSERT(ctx);
156 if (EVP_CipherUpdate(ctx->ctx, output, &outputLength, input, (int)length) != 1)
157 return FALSE;
158 return TRUE;
159#endif
160 return FALSE;
161}
162
163void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
164{
165 if (!ctx)
166 return;
167
168#if defined(WITH_INTERNAL_RC4)
169 winpr_int_rc4_free(ctx->ictx);
170#elif defined(WITH_OPENSSL)
171 EVP_CIPHER_CTX_free(ctx->ctx);
172#endif
173 free(ctx);
174}
175
180#ifdef WITH_OPENSSL
181extern const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md);
182#endif
183
184#ifdef WITH_MBEDTLS
185extern mbedtls_md_type_t winpr_mbedtls_get_md_type(int md);
186#endif
187
188struct cipher_map
189{
190 WINPR_CIPHER_TYPE md;
191 const char* name;
192};
193static const struct cipher_map s_cipher_map[] = {
194 { WINPR_CIPHER_NONE, "none" },
195 { WINPR_CIPHER_NULL, "null" },
196 { WINPR_CIPHER_AES_128_ECB, "aes-128-ecb" },
197 { WINPR_CIPHER_AES_192_ECB, "aes-192-ecb" },
198 { WINPR_CIPHER_AES_256_ECB, "aes-256-ecb" },
199 { WINPR_CIPHER_AES_128_CBC, "aes-128-cbc" },
200 { WINPR_CIPHER_AES_192_CBC, "aes-192-cbc" },
201 { WINPR_CIPHER_AES_256_CBC, "aes-256-cbc" },
202 { WINPR_CIPHER_AES_128_CFB128, "aes-128-cfb128" },
203 { WINPR_CIPHER_AES_192_CFB128, "aes-192-cfb128" },
204 { WINPR_CIPHER_AES_256_CFB128, "aes-256-cfb128" },
205 { WINPR_CIPHER_AES_128_CTR, "aes-128-ctr" },
206 { WINPR_CIPHER_AES_192_CTR, "aes-192-ctr" },
207 { WINPR_CIPHER_AES_256_CTR, "aes-256-ctr" },
208 { WINPR_CIPHER_AES_128_GCM, "aes-128-gcm" },
209 { WINPR_CIPHER_AES_192_GCM, "aes-192-gcm" },
210 { WINPR_CIPHER_AES_256_GCM, "aes-256-gcm" },
211 { WINPR_CIPHER_CAMELLIA_128_ECB, "camellia-128-ecb" },
212 { WINPR_CIPHER_CAMELLIA_192_ECB, "camellia-192-ecb" },
213 { WINPR_CIPHER_CAMELLIA_256_ECB, "camellia-256-ecb" },
214 { WINPR_CIPHER_CAMELLIA_128_CBC, "camellia-128-cbc" },
215 { WINPR_CIPHER_CAMELLIA_192_CBC, "camellia-192-cbc" },
216 { WINPR_CIPHER_CAMELLIA_256_CBC, "camellia-256-cbc" },
217 { WINPR_CIPHER_CAMELLIA_128_CFB128, "camellia-128-cfb128" },
218 { WINPR_CIPHER_CAMELLIA_192_CFB128, "camellia-192-cfb128" },
219 { WINPR_CIPHER_CAMELLIA_256_CFB128, "camellia-256-cfb128" },
220 { WINPR_CIPHER_CAMELLIA_128_CTR, "camellia-128-ctr" },
221 { WINPR_CIPHER_CAMELLIA_192_CTR, "camellia-192-ctr" },
222 { WINPR_CIPHER_CAMELLIA_256_CTR, "camellia-256-ctr" },
223 { WINPR_CIPHER_CAMELLIA_128_GCM, "camellia-128-gcm" },
224 { WINPR_CIPHER_CAMELLIA_192_GCM, "camellia-192-gcm" },
225 { WINPR_CIPHER_CAMELLIA_256_GCM, "camellia-256-gcm" },
226 { WINPR_CIPHER_DES_ECB, "des-ecb" },
227 { WINPR_CIPHER_DES_CBC, "des-cbc" },
228 { WINPR_CIPHER_DES_EDE_ECB, "des-ede-ecb" },
229 { WINPR_CIPHER_DES_EDE_CBC, "des-ede-cbc" },
230 { WINPR_CIPHER_DES_EDE3_ECB, "des-ede3-ecb" },
231 { WINPR_CIPHER_DES_EDE3_CBC, "des-ede3-cbc" },
232 { WINPR_CIPHER_BLOWFISH_ECB, "blowfish-ecb" },
233 { WINPR_CIPHER_BLOWFISH_CBC, "blowfish-cbc" },
234 { WINPR_CIPHER_BLOWFISH_CFB64, "blowfish-cfb64" },
235 { WINPR_CIPHER_BLOWFISH_CTR, "blowfish-ctr" },
236 { WINPR_CIPHER_ARC4_128, "rc4" },
237 { WINPR_CIPHER_AES_128_CCM, "aes-128-ccm" },
238 { WINPR_CIPHER_AES_192_CCM, "aes-192-ccm" },
239 { WINPR_CIPHER_AES_256_CCM, "aes-256-ccm" },
240 { WINPR_CIPHER_CAMELLIA_128_CCM, "camellia-128-ccm" },
241 { WINPR_CIPHER_CAMELLIA_192_CCM, "camellia-192-ccm" },
242 { WINPR_CIPHER_CAMELLIA_256_CCM, "camellia-256-ccm" },
243};
244
245static int cipher_compare(const void* a, const void* b)
246{
247 const WINPR_CIPHER_TYPE* cipher = a;
248 const struct cipher_map* map = b;
249 if (*cipher == map->md)
250 return 0;
251 return *cipher > map->md ? 1 : -1;
252}
253
254const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE md)
255{
256 WINPR_CIPHER_TYPE lc = md;
257 const struct cipher_map* ret = bsearch(&lc, s_cipher_map, ARRAYSIZE(s_cipher_map),
258 sizeof(struct cipher_map), cipher_compare);
259 if (!ret)
260 return "unknown";
261 return ret->name;
262}
263
264static int cipher_string_compare(const void* a, const void* b)
265{
266 const char* cipher = a;
267 const struct cipher_map* map = b;
268 return strcmp(cipher, map->name);
269}
270
271WINPR_CIPHER_TYPE winpr_cipher_type_from_string(const char* name)
272{
273 const struct cipher_map* ret = bsearch(name, s_cipher_map, ARRAYSIZE(s_cipher_map),
274 sizeof(struct cipher_map), cipher_string_compare);
275 if (!ret)
276 return WINPR_CIPHER_NONE;
277 return ret->md;
278}
279
280#if defined(WITH_OPENSSL)
281static const EVP_CIPHER* winpr_openssl_get_evp_cipher(WINPR_CIPHER_TYPE cipher)
282{
283 const EVP_CIPHER* evp = NULL;
284
285 switch (cipher)
286 {
287 case WINPR_CIPHER_NULL:
288 evp = EVP_enc_null();
289 break;
290
291 case WINPR_CIPHER_AES_128_ECB:
292 evp = EVP_get_cipherbyname("aes-128-ecb");
293 break;
294
295 case WINPR_CIPHER_AES_192_ECB:
296 evp = EVP_get_cipherbyname("aes-192-ecb");
297 break;
298
299 case WINPR_CIPHER_AES_256_ECB:
300 evp = EVP_get_cipherbyname("aes-256-ecb");
301 break;
302
303 case WINPR_CIPHER_AES_128_CBC:
304 evp = EVP_get_cipherbyname("aes-128-cbc");
305 break;
306
307 case WINPR_CIPHER_AES_192_CBC:
308 evp = EVP_get_cipherbyname("aes-192-cbc");
309 break;
310
311 case WINPR_CIPHER_AES_256_CBC:
312 evp = EVP_get_cipherbyname("aes-256-cbc");
313 break;
314
315 case WINPR_CIPHER_AES_128_CFB128:
316 evp = EVP_get_cipherbyname("aes-128-cfb128");
317 break;
318
319 case WINPR_CIPHER_AES_192_CFB128:
320 evp = EVP_get_cipherbyname("aes-192-cfb128");
321 break;
322
323 case WINPR_CIPHER_AES_256_CFB128:
324 evp = EVP_get_cipherbyname("aes-256-cfb128");
325 break;
326
327 case WINPR_CIPHER_AES_128_CTR:
328 evp = EVP_get_cipherbyname("aes-128-ctr");
329 break;
330
331 case WINPR_CIPHER_AES_192_CTR:
332 evp = EVP_get_cipherbyname("aes-192-ctr");
333 break;
334
335 case WINPR_CIPHER_AES_256_CTR:
336 evp = EVP_get_cipherbyname("aes-256-ctr");
337 break;
338
339 case WINPR_CIPHER_AES_128_GCM:
340 evp = EVP_get_cipherbyname("aes-128-gcm");
341 break;
342
343 case WINPR_CIPHER_AES_192_GCM:
344 evp = EVP_get_cipherbyname("aes-192-gcm");
345 break;
346
347 case WINPR_CIPHER_AES_256_GCM:
348 evp = EVP_get_cipherbyname("aes-256-gcm");
349 break;
350
351 case WINPR_CIPHER_AES_128_CCM:
352 evp = EVP_get_cipherbyname("aes-128-ccm");
353 break;
354
355 case WINPR_CIPHER_AES_192_CCM:
356 evp = EVP_get_cipherbyname("aes-192-ccm");
357 break;
358
359 case WINPR_CIPHER_AES_256_CCM:
360 evp = EVP_get_cipherbyname("aes-256-ccm");
361 break;
362
363 case WINPR_CIPHER_CAMELLIA_128_ECB:
364 evp = EVP_get_cipherbyname("camellia-128-ecb");
365 break;
366
367 case WINPR_CIPHER_CAMELLIA_192_ECB:
368 evp = EVP_get_cipherbyname("camellia-192-ecb");
369 break;
370
371 case WINPR_CIPHER_CAMELLIA_256_ECB:
372 evp = EVP_get_cipherbyname("camellia-256-ecb");
373 break;
374
375 case WINPR_CIPHER_CAMELLIA_128_CBC:
376 evp = EVP_get_cipherbyname("camellia-128-cbc");
377 break;
378
379 case WINPR_CIPHER_CAMELLIA_192_CBC:
380 evp = EVP_get_cipherbyname("camellia-192-cbc");
381 break;
382
383 case WINPR_CIPHER_CAMELLIA_256_CBC:
384 evp = EVP_get_cipherbyname("camellia-256-cbc");
385 break;
386
387 case WINPR_CIPHER_CAMELLIA_128_CFB128:
388 evp = EVP_get_cipherbyname("camellia-128-cfb128");
389 break;
390
391 case WINPR_CIPHER_CAMELLIA_192_CFB128:
392 evp = EVP_get_cipherbyname("camellia-192-cfb128");
393 break;
394
395 case WINPR_CIPHER_CAMELLIA_256_CFB128:
396 evp = EVP_get_cipherbyname("camellia-256-cfb128");
397 break;
398
399 case WINPR_CIPHER_CAMELLIA_128_CTR:
400 evp = EVP_get_cipherbyname("camellia-128-ctr");
401 break;
402
403 case WINPR_CIPHER_CAMELLIA_192_CTR:
404 evp = EVP_get_cipherbyname("camellia-192-ctr");
405 break;
406
407 case WINPR_CIPHER_CAMELLIA_256_CTR:
408 evp = EVP_get_cipherbyname("camellia-256-ctr");
409 break;
410
411 case WINPR_CIPHER_CAMELLIA_128_GCM:
412 evp = EVP_get_cipherbyname("camellia-128-gcm");
413 break;
414
415 case WINPR_CIPHER_CAMELLIA_192_GCM:
416 evp = EVP_get_cipherbyname("camellia-192-gcm");
417 break;
418
419 case WINPR_CIPHER_CAMELLIA_256_GCM:
420 evp = EVP_get_cipherbyname("camellia-256-gcm");
421 break;
422
423 case WINPR_CIPHER_CAMELLIA_128_CCM:
424 evp = EVP_get_cipherbyname("camellia-128-ccm");
425 break;
426
427 case WINPR_CIPHER_CAMELLIA_192_CCM:
428 evp = EVP_get_cipherbyname("camellia-192-ccm");
429 break;
430
431 case WINPR_CIPHER_CAMELLIA_256_CCM:
432 evp = EVP_get_cipherbyname("camellia-256-ccm");
433 break;
434
435 case WINPR_CIPHER_DES_ECB:
436 evp = EVP_get_cipherbyname("des-ecb");
437 break;
438
439 case WINPR_CIPHER_DES_CBC:
440 evp = EVP_get_cipherbyname("des-cbc");
441 break;
442
443 case WINPR_CIPHER_DES_EDE_ECB:
444 evp = EVP_get_cipherbyname("des-ede-ecb");
445 break;
446
447 case WINPR_CIPHER_DES_EDE_CBC:
448 evp = EVP_get_cipherbyname("des-ede-cbc");
449 break;
450
451 case WINPR_CIPHER_DES_EDE3_ECB:
452 evp = EVP_get_cipherbyname("des-ede3-ecb");
453 break;
454
455 case WINPR_CIPHER_DES_EDE3_CBC:
456 evp = EVP_get_cipherbyname("des-ede3-cbc");
457 break;
458
459 case WINPR_CIPHER_ARC4_128:
460 evp = EVP_get_cipherbyname("rc4");
461 break;
462
463 case WINPR_CIPHER_BLOWFISH_ECB:
464 evp = EVP_get_cipherbyname("blowfish-ecb");
465 break;
466
467 case WINPR_CIPHER_BLOWFISH_CBC:
468 evp = EVP_get_cipherbyname("blowfish-cbc");
469 break;
470
471 case WINPR_CIPHER_BLOWFISH_CFB64:
472 evp = EVP_get_cipherbyname("blowfish-cfb64");
473 break;
474
475 case WINPR_CIPHER_BLOWFISH_CTR:
476 evp = EVP_get_cipherbyname("blowfish-ctr");
477 break;
478 default:
479 break;
480 }
481
482 return evp;
483}
484
485#elif defined(WITH_MBEDTLS)
486mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher)
487{
488 mbedtls_cipher_type_t type = MBEDTLS_CIPHER_NONE;
489
490 switch (cipher)
491 {
492 case WINPR_CIPHER_NONE:
493 type = MBEDTLS_CIPHER_NONE;
494 break;
495
496 case WINPR_CIPHER_NULL:
497 type = MBEDTLS_CIPHER_NULL;
498 break;
499
500 case WINPR_CIPHER_AES_128_ECB:
501 type = MBEDTLS_CIPHER_AES_128_ECB;
502 break;
503
504 case WINPR_CIPHER_AES_192_ECB:
505 type = MBEDTLS_CIPHER_AES_192_ECB;
506 break;
507
508 case WINPR_CIPHER_AES_256_ECB:
509 type = MBEDTLS_CIPHER_AES_256_ECB;
510 break;
511
512 case WINPR_CIPHER_AES_128_CBC:
513 type = MBEDTLS_CIPHER_AES_128_CBC;
514 break;
515
516 case WINPR_CIPHER_AES_192_CBC:
517 type = MBEDTLS_CIPHER_AES_192_CBC;
518 break;
519
520 case WINPR_CIPHER_AES_256_CBC:
521 type = MBEDTLS_CIPHER_AES_256_CBC;
522 break;
523
524 case WINPR_CIPHER_AES_128_CFB128:
525 type = MBEDTLS_CIPHER_AES_128_CFB128;
526 break;
527
528 case WINPR_CIPHER_AES_192_CFB128:
529 type = MBEDTLS_CIPHER_AES_192_CFB128;
530 break;
531
532 case WINPR_CIPHER_AES_256_CFB128:
533 type = MBEDTLS_CIPHER_AES_256_CFB128;
534 break;
535
536 case WINPR_CIPHER_AES_128_CTR:
537 type = MBEDTLS_CIPHER_AES_128_CTR;
538 break;
539
540 case WINPR_CIPHER_AES_192_CTR:
541 type = MBEDTLS_CIPHER_AES_192_CTR;
542 break;
543
544 case WINPR_CIPHER_AES_256_CTR:
545 type = MBEDTLS_CIPHER_AES_256_CTR;
546 break;
547
548 case WINPR_CIPHER_AES_128_GCM:
549 type = MBEDTLS_CIPHER_AES_128_GCM;
550 break;
551
552 case WINPR_CIPHER_AES_192_GCM:
553 type = MBEDTLS_CIPHER_AES_192_GCM;
554 break;
555
556 case WINPR_CIPHER_AES_256_GCM:
557 type = MBEDTLS_CIPHER_AES_256_GCM;
558 break;
559
560 case WINPR_CIPHER_AES_128_CCM:
561 type = MBEDTLS_CIPHER_AES_128_CCM;
562 break;
563
564 case WINPR_CIPHER_AES_192_CCM:
565 type = MBEDTLS_CIPHER_AES_192_CCM;
566 break;
567
568 case WINPR_CIPHER_AES_256_CCM:
569 type = MBEDTLS_CIPHER_AES_256_CCM;
570 break;
571 }
572
573 return type;
574}
575#endif
576
577#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
578WINPR_CIPHER_CTX* winpr_Cipher_New(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op,
579 const void* key, const void* iv)
580{
581 return winpr_Cipher_NewEx(cipher, op, key, 0, iv, 0);
582}
583#endif
584
585WINPR_API WINPR_CIPHER_CTX* winpr_Cipher_NewEx(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op,
586 const void* key, WINPR_ATTR_UNUSED size_t keylen,
587 const void* iv, WINPR_ATTR_UNUSED size_t ivlen)
588{
589 if (cipher == WINPR_CIPHER_ARC4_128)
590 {
591 WLog_ERR(TAG,
592 "WINPR_CIPHER_ARC4_128 (RC4) cipher not supported, use winpr_RC4_new instead");
593 return NULL;
594 }
595
596 WINPR_CIPHER_CTX* ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
597 if (!ctx)
598 return NULL;
599
600 ctx->cipher = cipher;
601 ctx->op = op;
602
603#if defined(WITH_OPENSSL)
604 const EVP_CIPHER* evp = winpr_openssl_get_evp_cipher(cipher);
605 if (!evp)
606 goto fail;
607
608 ctx->ectx = EVP_CIPHER_CTX_new();
609 if (!ctx->ectx)
610 goto fail;
611
612 {
613 const int operation = (op == WINPR_ENCRYPT) ? 1 : 0;
614 if (EVP_CipherInit_ex(ctx->ectx, evp, NULL, key, iv, operation) != 1)
615 goto fail;
616 }
617
618 EVP_CIPHER_CTX_set_padding(ctx->ectx, 0);
619
620#elif defined(WITH_MBEDTLS)
621 mbedtls_cipher_type_t cipher_type = winpr_mbedtls_get_cipher_type(cipher);
622 const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(cipher_type);
623
624 if (!cipher_info)
625 goto fail;
626
627 ctx->mctx = calloc(1, sizeof(mbedtls_cipher_context_t));
628 if (!ctx->mctx)
629 goto fail;
630
631 const mbedtls_operation_t operation = (op == WINPR_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT;
632 mbedtls_cipher_init(ctx->mctx);
633
634 if (mbedtls_cipher_setup(ctx->mctx, cipher_info) != 0)
635 goto fail;
636
637 const int key_bitlen = mbedtls_cipher_get_key_bitlen(ctx->mctx);
638
639 if (mbedtls_cipher_setkey(ctx->mctx, key, key_bitlen, operation) != 0)
640 goto fail;
641
642 if (mbedtls_cipher_set_padding_mode(ctx->mctx, MBEDTLS_PADDING_NONE) != 0)
643 goto fail;
644
645#endif
646 return ctx;
647
648fail:
649 winpr_Cipher_Free(ctx);
650 return NULL;
651}
652
653BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled)
654{
655 WINPR_ASSERT(ctx);
656
657#if defined(WITH_OPENSSL)
658 if (!ctx->ectx)
659 return FALSE;
660 EVP_CIPHER_CTX_set_padding(ctx->ectx, enabled);
661#elif defined(WITH_MBEDTLS)
662 mbedtls_cipher_padding_t option = enabled ? MBEDTLS_PADDING_PKCS7 : MBEDTLS_PADDING_NONE;
663 if (mbedtls_cipher_set_padding_mode((mbedtls_cipher_context_t*)ctx, option) != 0)
664 return FALSE;
665#else
666 return FALSE;
667#endif
668 return TRUE;
669}
670
671BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const void* input, size_t ilen, void* output,
672 size_t* olen)
673{
674 WINPR_ASSERT(ctx);
675 WINPR_ASSERT(olen);
676
677#if defined(WITH_OPENSSL)
678 int outl = (int)*olen;
679
680 if (ilen > INT_MAX)
681 {
682 WLog_ERR(TAG, "input length %" PRIuz " > %d, abort", ilen, INT_MAX);
683 return FALSE;
684 }
685
686 WINPR_ASSERT(ctx->ectx);
687 if (EVP_CipherUpdate(ctx->ectx, output, &outl, input, (int)ilen) == 1)
688 {
689 *olen = (size_t)outl;
690 return TRUE;
691 }
692
693#elif defined(WITH_MBEDTLS)
694 WINPR_ASSERT(ctx->mctx);
695 if (mbedtls_cipher_update(ctx->mctx, input, ilen, output, olen) == 0)
696 return TRUE;
697
698#endif
699
700 WLog_ERR(TAG, "Failed to update the data");
701 return FALSE;
702}
703
704BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, void* output, size_t* olen)
705{
706 WINPR_ASSERT(ctx);
707
708#if defined(WITH_OPENSSL)
709 int outl = (int)*olen;
710
711 WINPR_ASSERT(ctx->ectx);
712 if (EVP_CipherFinal_ex(ctx->ectx, output, &outl) == 1)
713 {
714 *olen = (size_t)outl;
715 return TRUE;
716 }
717
718#elif defined(WITH_MBEDTLS)
719
720 WINPR_ASSERT(ctx->mctx);
721 if (mbedtls_cipher_finish(ctx->mctx, output, olen) == 0)
722 return TRUE;
723
724#endif
725
726 return FALSE;
727}
728
729void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
730{
731 if (!ctx)
732 return;
733
734#if defined(WITH_OPENSSL)
735 if (ctx->ectx)
736 EVP_CIPHER_CTX_free(ctx->ectx);
737#elif defined(WITH_MBEDTLS)
738 if (ctx->mctx)
739 {
740 mbedtls_cipher_free(ctx->mctx);
741 free(ctx->mctx);
742 }
743#endif
744
745 free(ctx);
746}
747
752int winpr_Cipher_BytesToKey(int cipher, WINPR_MD_TYPE md, const void* salt, const void* data,
753 size_t datal, size_t count, void* key, void* iv)
754{
759#if defined(WITH_OPENSSL)
760 const EVP_MD* evp_md = NULL;
761 const EVP_CIPHER* evp_cipher = NULL;
762 evp_md = winpr_openssl_get_evp_md(md);
763 evp_cipher = winpr_openssl_get_evp_cipher(WINPR_ASSERTING_INT_CAST(WINPR_CIPHER_TYPE, cipher));
764 WINPR_ASSERT(datal <= INT_MAX);
765 WINPR_ASSERT(count <= INT_MAX);
766 return EVP_BytesToKey(evp_cipher, evp_md, salt, data, (int)datal, (int)count, key, iv);
767#elif defined(WITH_MBEDTLS)
768 int rv = 0;
769 BYTE md_buf[64];
770 int niv, nkey, addmd = 0;
771 unsigned int mds = 0;
772 mbedtls_md_context_t ctx;
773 const mbedtls_md_info_t* md_info;
774 mbedtls_cipher_type_t cipher_type;
775 const mbedtls_cipher_info_t* cipher_info;
776 mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
777 md_info = mbedtls_md_info_from_type(md_type);
778 cipher_type = winpr_mbedtls_get_cipher_type(cipher);
779 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
780 nkey = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
781 niv = mbedtls_cipher_info_get_iv_size(cipher_info);
782
783 if ((nkey > 64) || (niv > 64))
784 return 0;
785
786 if (!data)
787 return nkey;
788
789 mbedtls_md_init(&ctx);
790
791 if (mbedtls_md_setup(&ctx, md_info, 0) != 0)
792 goto err;
793
794 while (1)
795 {
796 if (mbedtls_md_starts(&ctx) != 0)
797 goto err;
798
799 if (addmd++)
800 {
801 if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
802 goto err;
803 }
804
805 if (mbedtls_md_update(&ctx, data, datal) != 0)
806 goto err;
807
808 if (salt)
809 {
810 if (mbedtls_md_update(&ctx, salt, 8) != 0)
811 goto err;
812 }
813
814 if (mbedtls_md_finish(&ctx, md_buf) != 0)
815 goto err;
816
817 mds = mbedtls_md_get_size(md_info);
818
819 for (unsigned int i = 1; i < (unsigned int)count; i++)
820 {
821 if (mbedtls_md_starts(&ctx) != 0)
822 goto err;
823
824 if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
825 goto err;
826
827 if (mbedtls_md_finish(&ctx, md_buf) != 0)
828 goto err;
829 }
830
831 unsigned int i = 0;
832
833 if (nkey)
834 {
835 while (1)
836 {
837 if (nkey == 0)
838 break;
839
840 if (i == mds)
841 break;
842
843 if (key)
844 *(BYTE*)(key++) = md_buf[i];
845
846 nkey--;
847 i++;
848 }
849 }
850
851 if (niv && (i != mds))
852 {
853 while (1)
854 {
855 if (niv == 0)
856 break;
857
858 if (i == mds)
859 break;
860
861 if (iv)
862 *(BYTE*)(iv++) = md_buf[i];
863
864 niv--;
865 i++;
866 }
867 }
868
869 if ((nkey == 0) && (niv == 0))
870 break;
871 }
872
873 rv = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
874err:
875 mbedtls_md_free(&ctx);
876 SecureZeroMemory(md_buf, 64);
877 return rv;
878#else
879 return 0;
880#endif
881}