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