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