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(nullptr, "RC4", override_fips ? "fips=no" : nullptr);
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 (iv != nullptr)
648 {
649 const size_t ivsize = mbedtls_cipher_get_iv_size(ctx->mctx);
650
651 if (ivsize > 0)
652 {
653 if (ivlen == 0) /* winpr_Cipher_New() passes ivlen = 0 */
654 ivlen = ivsize;
655
656 if (mbedtls_cipher_set_iv(ctx->mctx, iv, ivlen) != 0)
657 goto fail;
658 }
659 }
660
661 if (mbedtls_cipher_set_padding_mode(ctx->mctx, MBEDTLS_PADDING_NONE) != 0)
662 goto fail;
663
664#endif
665 return ctx;
666
667fail:
668 winpr_Cipher_Free(ctx);
669 return nullptr;
670}
671
672BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled)
673{
674 WINPR_ASSERT(ctx);
675
676#if defined(WITH_OPENSSL)
677 if (!ctx->ectx)
678 return FALSE;
679 EVP_CIPHER_CTX_set_padding(ctx->ectx, enabled);
680#elif defined(WITH_MBEDTLS)
681 mbedtls_cipher_padding_t option = enabled ? MBEDTLS_PADDING_PKCS7 : MBEDTLS_PADDING_NONE;
682 if (mbedtls_cipher_set_padding_mode((mbedtls_cipher_context_t*)ctx, option) != 0)
683 return FALSE;
684#else
685 return FALSE;
686#endif
687 return TRUE;
688}
689
690BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const void* input, size_t ilen, void* output,
691 size_t* olen)
692{
693 WINPR_ASSERT(ctx);
694 WINPR_ASSERT(olen);
695
696#if defined(WITH_OPENSSL)
697 int outl = (int)*olen;
698
699 if (ilen > INT_MAX)
700 {
701 WLog_ERR(TAG, "input length %" PRIuz " > %d, abort", ilen, INT_MAX);
702 return FALSE;
703 }
704
705 WINPR_ASSERT(ctx->ectx);
706 if (EVP_CipherUpdate(ctx->ectx, output, &outl, input, (int)ilen) == 1)
707 {
708 *olen = (size_t)outl;
709 return TRUE;
710 }
711
712#elif defined(WITH_MBEDTLS)
713 WINPR_ASSERT(ctx->mctx);
714 if (mbedtls_cipher_update(ctx->mctx, input, ilen, output, olen) == 0)
715 return TRUE;
716
717#endif
718
719 WLog_ERR(TAG, "Failed to update the data");
720 return FALSE;
721}
722
723BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, void* output, size_t* olen)
724{
725 WINPR_ASSERT(ctx);
726
727#if defined(WITH_OPENSSL)
728 int outl = (int)*olen;
729
730 WINPR_ASSERT(ctx->ectx);
731 if (EVP_CipherFinal_ex(ctx->ectx, output, &outl) == 1)
732 {
733 *olen = (size_t)outl;
734 return TRUE;
735 }
736
737#elif defined(WITH_MBEDTLS)
738
739 WINPR_ASSERT(ctx->mctx);
740 if (mbedtls_cipher_finish(ctx->mctx, output, olen) == 0)
741 return TRUE;
742
743#endif
744
745 return FALSE;
746}
747
748void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
749{
750 if (!ctx)
751 return;
752
753#if defined(WITH_OPENSSL)
754 if (ctx->ectx)
755 EVP_CIPHER_CTX_free(ctx->ectx);
756#elif defined(WITH_MBEDTLS)
757 if (ctx->mctx)
758 {
759 mbedtls_cipher_free(ctx->mctx);
760 free(ctx->mctx);
761 }
762#endif
763
764 free(ctx);
765}
766
771int winpr_Cipher_BytesToKey(int cipher, WINPR_MD_TYPE md, const void* salt, const void* data,
772 size_t datal, size_t count, void* key, void* iv)
773{
778#if defined(WITH_OPENSSL)
779 const EVP_MD* evp_md = nullptr;
780 const EVP_CIPHER* evp_cipher = nullptr;
781 evp_md = winpr_openssl_get_evp_md(md);
782 evp_cipher = winpr_openssl_get_evp_cipher(WINPR_ASSERTING_INT_CAST(WINPR_CIPHER_TYPE, cipher));
783 WINPR_ASSERT(datal <= INT_MAX);
784 WINPR_ASSERT(count <= INT_MAX);
785 return EVP_BytesToKey(evp_cipher, evp_md, salt, data, (int)datal, (int)count, key, iv);
786#elif defined(WITH_MBEDTLS)
787 int rv = 0;
788 BYTE md_buf[64];
789 int niv, nkey, addmd = 0;
790 unsigned int mds = 0;
791 mbedtls_md_context_t ctx;
792 const mbedtls_md_info_t* md_info;
793 mbedtls_cipher_type_t cipher_type;
794 const mbedtls_cipher_info_t* cipher_info;
795 mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
796 md_info = mbedtls_md_info_from_type(md_type);
797 cipher_type = winpr_mbedtls_get_cipher_type(cipher);
798 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
799 nkey = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
800 niv = mbedtls_cipher_info_get_iv_size(cipher_info);
801
802 if ((nkey > 64) || (niv > 64))
803 return 0;
804
805 if (!data)
806 return nkey;
807
808 mbedtls_md_init(&ctx);
809
810 if (mbedtls_md_setup(&ctx, md_info, 0) != 0)
811 goto err;
812
813 while (1)
814 {
815 if (mbedtls_md_starts(&ctx) != 0)
816 goto err;
817
818 if (addmd++)
819 {
820 if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
821 goto err;
822 }
823
824 if (mbedtls_md_update(&ctx, data, datal) != 0)
825 goto err;
826
827 if (salt)
828 {
829 if (mbedtls_md_update(&ctx, salt, 8) != 0)
830 goto err;
831 }
832
833 if (mbedtls_md_finish(&ctx, md_buf) != 0)
834 goto err;
835
836 mds = mbedtls_md_get_size(md_info);
837
838 for (unsigned int i = 1; i < (unsigned int)count; i++)
839 {
840 if (mbedtls_md_starts(&ctx) != 0)
841 goto err;
842
843 if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
844 goto err;
845
846 if (mbedtls_md_finish(&ctx, md_buf) != 0)
847 goto err;
848 }
849
850 unsigned int i = 0;
851
852 if (nkey)
853 {
854 while (1)
855 {
856 if (nkey == 0)
857 break;
858
859 if (i == mds)
860 break;
861
862 if (key)
863 *(BYTE*)(key++) = md_buf[i];
864
865 nkey--;
866 i++;
867 }
868 }
869
870 if (niv && (i != mds))
871 {
872 while (1)
873 {
874 if (niv == 0)
875 break;
876
877 if (i == mds)
878 break;
879
880 if (iv)
881 *(BYTE*)(iv++) = md_buf[i];
882
883 niv--;
884 i++;
885 }
886 }
887
888 if ((nkey == 0) && (niv == 0))
889 break;
890 }
891
892 rv = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
893err:
894 mbedtls_md_free(&ctx);
895 SecureZeroMemory(md_buf, 64);
896 return rv;
897#else
898 return 0;
899#endif
900}