FreeRDP
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 
50 struct 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 
67 struct 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 
78 static 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 
124 fail:
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 
133 WINPR_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 
138 WINPR_RC4_CTX* winpr_RC4_New(const void* key, size_t keylen)
139 {
140  return winpr_RC4_New_Internal(key, keylen, FALSE);
141 }
142 
143 BOOL 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 
163 void 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
181 extern const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md);
182 #endif
183 
184 #ifdef WITH_MBEDTLS
185 extern mbedtls_md_type_t winpr_mbedtls_get_md_type(int md);
186 #endif
187 
188 struct cipher_map
189 {
190  WINPR_CIPHER_TYPE md;
191  const char* name;
192 };
193 static 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 
245 static 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 
254 const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE cipher)
255 {
256  WINPR_CIPHER_TYPE lc = cipher;
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 
264 static 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 
271 WINPR_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)
281 static 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)
486 mbedtls_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 WINPR_CIPHER_CTX* winpr_Cipher_New(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op,
578  const void* key, const void* iv)
579 {
580  return winpr_Cipher_NewEx(cipher, op, key, 0, iv, 0);
581 }
582 
583 WINPR_API WINPR_CIPHER_CTX* winpr_Cipher_NewEx(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op,
584  const void* key, size_t keylen, const void* iv,
585  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 NULL;
592  }
593 
594  WINPR_CIPHER_CTX* ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
595  if (!ctx)
596  return NULL;
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 #if 0
611  if (keylen != 0)
612  {
613  WINPR_ASSERT(keylen <= INT32_MAX);
614  const int len = EVP_CIPHER_CTX_key_length(ctx->ectx);
615  if ((len > 0) && (len != keylen))
616  {
617  if (EVP_CIPHER_CTX_set_key_length(ctx->ectx, (int)keylen) != 1)
618  goto fail;
619  }
620  }
621 
622  if (ivlen != 0)
623  {
624  WINPR_ASSERT(ivlen <= INT32_MAX);
625  const int len = EVP_CIPHER_CTX_iv_length(ctx->ectx);
626  if ((len > 0) && (ivlen != len))
627  goto fail;
628  }
629 #endif
630 
631  const int operation = (op == WINPR_ENCRYPT) ? 1 : 0;
632 
633  if (EVP_CipherInit_ex(ctx->ectx, evp, NULL, key, iv, operation) != 1)
634  goto fail;
635 
636  EVP_CIPHER_CTX_set_padding(ctx->ectx, 0);
637 
638 #elif defined(WITH_MBEDTLS)
639  mbedtls_cipher_type_t cipher_type = winpr_mbedtls_get_cipher_type(cipher);
640  const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(cipher_type);
641 
642  if (!cipher_info)
643  goto fail;
644 
645  ctx->mctx = calloc(1, sizeof(mbedtls_cipher_context_t));
646  if (!ctx->mctx)
647  goto fail;
648 
649  const mbedtls_operation_t operation = (op == WINPR_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT;
650  mbedtls_cipher_init(ctx->mctx);
651 
652  if (mbedtls_cipher_setup(ctx->mctx, cipher_info) != 0)
653  goto fail;
654 
655  const int key_bitlen = mbedtls_cipher_get_key_bitlen(ctx->mctx);
656 
657  if (mbedtls_cipher_setkey(ctx->mctx, key, key_bitlen, operation) != 0)
658  goto fail;
659 
660  if (mbedtls_cipher_set_padding_mode(ctx->mctx, MBEDTLS_PADDING_NONE) != 0)
661  goto fail;
662 
663 #endif
664  return ctx;
665 
666 fail:
667  winpr_Cipher_Free(ctx);
668  return NULL;
669 }
670 
671 BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled)
672 {
673  WINPR_ASSERT(ctx);
674 
675 #if defined(WITH_OPENSSL)
676  if (!ctx->ectx)
677  return FALSE;
678  EVP_CIPHER_CTX_set_padding(ctx->ectx, enabled);
679 #elif defined(WITH_MBEDTLS)
680  mbedtls_cipher_padding_t option = enabled ? MBEDTLS_PADDING_PKCS7 : MBEDTLS_PADDING_NONE;
681  if (mbedtls_cipher_set_padding_mode((mbedtls_cipher_context_t*)ctx, option) != 0)
682  return FALSE;
683 #else
684  return FALSE;
685 #endif
686  return TRUE;
687 }
688 
689 BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const void* input, size_t ilen, void* output,
690  size_t* olen)
691 {
692  WINPR_ASSERT(ctx);
693  WINPR_ASSERT(olen);
694 
695 #if defined(WITH_OPENSSL)
696  int outl = (int)*olen;
697 
698  if (ilen > INT_MAX)
699  {
700  WLog_ERR(TAG, "input length %" PRIuz " > %d, abort", ilen, INT_MAX);
701  return FALSE;
702  }
703 
704  WINPR_ASSERT(ctx->ectx);
705  if (EVP_CipherUpdate(ctx->ectx, output, &outl, input, (int)ilen) == 1)
706  {
707  *olen = (size_t)outl;
708  return TRUE;
709  }
710 
711 #elif defined(WITH_MBEDTLS)
712  WINPR_ASSERT(ctx->mctx);
713  if (mbedtls_cipher_update(ctx->mctx, input, ilen, output, olen) == 0)
714  return TRUE;
715 
716 #endif
717 
718  WLog_ERR(TAG, "Failed to update the data");
719  return FALSE;
720 }
721 
722 BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, void* output, size_t* olen)
723 {
724  WINPR_ASSERT(ctx);
725 
726 #if defined(WITH_OPENSSL)
727  int outl = (int)*olen;
728 
729  WINPR_ASSERT(ctx->ectx);
730  if (EVP_CipherFinal_ex(ctx->ectx, output, &outl) == 1)
731  {
732  *olen = (size_t)outl;
733  return TRUE;
734  }
735 
736 #elif defined(WITH_MBEDTLS)
737 
738  WINPR_ASSERT(ctx->mctx);
739  if (mbedtls_cipher_finish(ctx->mctx, output, olen) == 0)
740  return TRUE;
741 
742 #endif
743 
744  return FALSE;
745 }
746 
747 void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
748 {
749  if (!ctx)
750  return;
751 
752 #if defined(WITH_OPENSSL)
753  if (ctx->ectx)
754  EVP_CIPHER_CTX_free(ctx->ectx);
755 #elif defined(WITH_MBEDTLS)
756  if (ctx->mctx)
757  {
758  mbedtls_cipher_free(ctx->mctx);
759  free(ctx->mctx);
760  }
761 #endif
762 
763  free(ctx);
764 }
765 
770 int winpr_Cipher_BytesToKey(int cipher, WINPR_MD_TYPE md, const void* salt, const void* data,
771  size_t datal, size_t count, void* key, void* iv)
772 {
777 #if defined(WITH_OPENSSL)
778  const EVP_MD* evp_md = NULL;
779  const EVP_CIPHER* evp_cipher = NULL;
780  evp_md = winpr_openssl_get_evp_md(md);
781  evp_cipher = winpr_openssl_get_evp_cipher(cipher);
782  WINPR_ASSERT(datal <= INT_MAX);
783  WINPR_ASSERT(count <= INT_MAX);
784  return EVP_BytesToKey(evp_cipher, evp_md, salt, data, (int)datal, (int)count, key, iv);
785 #elif defined(WITH_MBEDTLS)
786  int rv = 0;
787  BYTE md_buf[64];
788  int niv, nkey, addmd = 0;
789  unsigned int mds = 0;
790  mbedtls_md_context_t ctx;
791  const mbedtls_md_info_t* md_info;
792  mbedtls_cipher_type_t cipher_type;
793  const mbedtls_cipher_info_t* cipher_info;
794  mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
795  md_info = mbedtls_md_info_from_type(md_type);
796  cipher_type = winpr_mbedtls_get_cipher_type(cipher);
797  cipher_info = mbedtls_cipher_info_from_type(cipher_type);
798  nkey = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
799  niv = mbedtls_cipher_info_get_iv_size(cipher_info);
800 
801  if ((nkey > 64) || (niv > 64))
802  return 0;
803 
804  if (!data)
805  return nkey;
806 
807  mbedtls_md_init(&ctx);
808 
809  if (mbedtls_md_setup(&ctx, md_info, 0) != 0)
810  goto err;
811 
812  while (1)
813  {
814  if (mbedtls_md_starts(&ctx) != 0)
815  goto err;
816 
817  if (addmd++)
818  {
819  if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
820  goto err;
821  }
822 
823  if (mbedtls_md_update(&ctx, data, datal) != 0)
824  goto err;
825 
826  if (salt)
827  {
828  if (mbedtls_md_update(&ctx, salt, 8) != 0)
829  goto err;
830  }
831 
832  if (mbedtls_md_finish(&ctx, md_buf) != 0)
833  goto err;
834 
835  mds = mbedtls_md_get_size(md_info);
836 
837  for (unsigned int i = 1; i < (unsigned int)count; i++)
838  {
839  if (mbedtls_md_starts(&ctx) != 0)
840  goto err;
841 
842  if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
843  goto err;
844 
845  if (mbedtls_md_finish(&ctx, md_buf) != 0)
846  goto err;
847  }
848 
849  unsigned int i = 0;
850 
851  if (nkey)
852  {
853  while (1)
854  {
855  if (nkey == 0)
856  break;
857 
858  if (i == mds)
859  break;
860 
861  if (key)
862  *(BYTE*)(key++) = md_buf[i];
863 
864  nkey--;
865  i++;
866  }
867  }
868 
869  if (niv && (i != mds))
870  {
871  while (1)
872  {
873  if (niv == 0)
874  break;
875 
876  if (i == mds)
877  break;
878 
879  if (iv)
880  *(BYTE*)(iv++) = md_buf[i];
881 
882  niv--;
883  i++;
884  }
885  }
886 
887  if ((nkey == 0) && (niv == 0))
888  break;
889  }
890 
891  rv = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
892 err:
893  mbedtls_md_free(&ctx);
894  SecureZeroMemory(md_buf, 64);
895  return rv;
896 #else
897  return 0;
898 #endif
899 }