19 #include <winpr/config.h>
21 #include <winpr/crt.h>
22 #include <winpr/assert.h>
23 #include <winpr/crypto.h>
26 #define TAG WINPR_TAG("crypto.cipher")
28 #if defined(WITH_INTERNAL_RC4)
33 #include <openssl/aes.h>
34 #include <openssl/rc4.h>
35 #include <openssl/des.h>
36 #include <openssl/evp.h>
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)
50 struct winpr_cipher_ctx_private_st
52 WINPR_CIPHER_TYPE cipher;
53 WINPR_CRYPTO_OPERATION op;
59 mbedtls_cipher_context_t* mctx;
67 struct winpr_rc4_ctx_private_st
69 #if defined(WITH_INTERNAL_RC4)
70 winpr_int_RC4_CTX* ictx;
72 #if defined(WITH_OPENSSL)
78 static WINPR_RC4_CTX* winpr_RC4_New_Internal(
const BYTE* key,
size_t keylen, BOOL override_fips)
80 if (!key || (keylen == 0))
83 WINPR_RC4_CTX* ctx = (WINPR_RC4_CTX*)calloc(1,
sizeof(WINPR_RC4_CTX));
87 #if defined(WITH_INTERNAL_RC4)
88 WINPR_UNUSED(override_fips);
89 ctx->ictx = winpr_int_rc4_new(key, keylen);
92 #elif defined(WITH_OPENSSL)
93 const EVP_CIPHER* evp = NULL;
98 ctx->ctx = EVP_CIPHER_CTX_new();
107 EVP_CIPHER_CTX_reset(ctx->ctx);
108 if (EVP_EncryptInit_ex(ctx->ctx, evp, NULL, NULL, NULL) != 1)
112 #if !(OPENSSL_VERSION_NUMBER < 0x10001000L)
114 if (override_fips == TRUE)
115 EVP_CIPHER_CTX_set_flags(ctx->ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
118 EVP_CIPHER_CTX_set_key_length(ctx->ctx, (
int)keylen);
119 if (EVP_EncryptInit_ex(ctx->ctx, NULL, NULL, key, NULL) != 1)
125 WINPR_PRAGMA_DIAG_PUSH
126 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
129 WINPR_PRAGMA_DIAG_POP
133 WINPR_RC4_CTX* winpr_RC4_New_Allow_FIPS(
const void* key,
size_t keylen)
135 return winpr_RC4_New_Internal(key, keylen, TRUE);
138 WINPR_RC4_CTX* winpr_RC4_New(
const void* key,
size_t keylen)
140 return winpr_RC4_New_Internal(key, keylen, FALSE);
143 BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx,
size_t length,
const void* input,
void* output)
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)
156 if (EVP_CipherUpdate(ctx->ctx, output, &outputLength, input, (
int)length) != 1)
163 void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
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);
181 extern const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md);
185 extern mbedtls_md_type_t winpr_mbedtls_get_md_type(
int md);
190 WINPR_CIPHER_TYPE md;
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" },
245 static int cipher_compare(
const void* a,
const void* b)
247 const WINPR_CIPHER_TYPE* cipher = a;
248 const struct cipher_map* map = b;
249 if (*cipher == map->md)
251 return *cipher > map->md ? 1 : -1;
254 const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE cipher)
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);
264 static int cipher_string_compare(
const void* a,
const void* b)
266 const char* cipher = a;
267 const struct cipher_map* map = b;
268 return strcmp(cipher, map->name);
271 WINPR_CIPHER_TYPE winpr_cipher_type_from_string(
const char* name)
273 const struct cipher_map* ret = bsearch(name, s_cipher_map, ARRAYSIZE(s_cipher_map),
274 sizeof(
struct cipher_map), cipher_string_compare);
276 return WINPR_CIPHER_NONE;
280 #if defined(WITH_OPENSSL)
281 static const EVP_CIPHER* winpr_openssl_get_evp_cipher(WINPR_CIPHER_TYPE cipher)
283 const EVP_CIPHER* evp = NULL;
287 case WINPR_CIPHER_NULL:
288 evp = EVP_enc_null();
291 case WINPR_CIPHER_AES_128_ECB:
292 evp = EVP_get_cipherbyname(
"aes-128-ecb");
295 case WINPR_CIPHER_AES_192_ECB:
296 evp = EVP_get_cipherbyname(
"aes-192-ecb");
299 case WINPR_CIPHER_AES_256_ECB:
300 evp = EVP_get_cipherbyname(
"aes-256-ecb");
303 case WINPR_CIPHER_AES_128_CBC:
304 evp = EVP_get_cipherbyname(
"aes-128-cbc");
307 case WINPR_CIPHER_AES_192_CBC:
308 evp = EVP_get_cipherbyname(
"aes-192-cbc");
311 case WINPR_CIPHER_AES_256_CBC:
312 evp = EVP_get_cipherbyname(
"aes-256-cbc");
315 case WINPR_CIPHER_AES_128_CFB128:
316 evp = EVP_get_cipherbyname(
"aes-128-cfb128");
319 case WINPR_CIPHER_AES_192_CFB128:
320 evp = EVP_get_cipherbyname(
"aes-192-cfb128");
323 case WINPR_CIPHER_AES_256_CFB128:
324 evp = EVP_get_cipherbyname(
"aes-256-cfb128");
327 case WINPR_CIPHER_AES_128_CTR:
328 evp = EVP_get_cipherbyname(
"aes-128-ctr");
331 case WINPR_CIPHER_AES_192_CTR:
332 evp = EVP_get_cipherbyname(
"aes-192-ctr");
335 case WINPR_CIPHER_AES_256_CTR:
336 evp = EVP_get_cipherbyname(
"aes-256-ctr");
339 case WINPR_CIPHER_AES_128_GCM:
340 evp = EVP_get_cipherbyname(
"aes-128-gcm");
343 case WINPR_CIPHER_AES_192_GCM:
344 evp = EVP_get_cipherbyname(
"aes-192-gcm");
347 case WINPR_CIPHER_AES_256_GCM:
348 evp = EVP_get_cipherbyname(
"aes-256-gcm");
351 case WINPR_CIPHER_AES_128_CCM:
352 evp = EVP_get_cipherbyname(
"aes-128-ccm");
355 case WINPR_CIPHER_AES_192_CCM:
356 evp = EVP_get_cipherbyname(
"aes-192-ccm");
359 case WINPR_CIPHER_AES_256_CCM:
360 evp = EVP_get_cipherbyname(
"aes-256-ccm");
363 case WINPR_CIPHER_CAMELLIA_128_ECB:
364 evp = EVP_get_cipherbyname(
"camellia-128-ecb");
367 case WINPR_CIPHER_CAMELLIA_192_ECB:
368 evp = EVP_get_cipherbyname(
"camellia-192-ecb");
371 case WINPR_CIPHER_CAMELLIA_256_ECB:
372 evp = EVP_get_cipherbyname(
"camellia-256-ecb");
375 case WINPR_CIPHER_CAMELLIA_128_CBC:
376 evp = EVP_get_cipherbyname(
"camellia-128-cbc");
379 case WINPR_CIPHER_CAMELLIA_192_CBC:
380 evp = EVP_get_cipherbyname(
"camellia-192-cbc");
383 case WINPR_CIPHER_CAMELLIA_256_CBC:
384 evp = EVP_get_cipherbyname(
"camellia-256-cbc");
387 case WINPR_CIPHER_CAMELLIA_128_CFB128:
388 evp = EVP_get_cipherbyname(
"camellia-128-cfb128");
391 case WINPR_CIPHER_CAMELLIA_192_CFB128:
392 evp = EVP_get_cipherbyname(
"camellia-192-cfb128");
395 case WINPR_CIPHER_CAMELLIA_256_CFB128:
396 evp = EVP_get_cipherbyname(
"camellia-256-cfb128");
399 case WINPR_CIPHER_CAMELLIA_128_CTR:
400 evp = EVP_get_cipherbyname(
"camellia-128-ctr");
403 case WINPR_CIPHER_CAMELLIA_192_CTR:
404 evp = EVP_get_cipherbyname(
"camellia-192-ctr");
407 case WINPR_CIPHER_CAMELLIA_256_CTR:
408 evp = EVP_get_cipherbyname(
"camellia-256-ctr");
411 case WINPR_CIPHER_CAMELLIA_128_GCM:
412 evp = EVP_get_cipherbyname(
"camellia-128-gcm");
415 case WINPR_CIPHER_CAMELLIA_192_GCM:
416 evp = EVP_get_cipherbyname(
"camellia-192-gcm");
419 case WINPR_CIPHER_CAMELLIA_256_GCM:
420 evp = EVP_get_cipherbyname(
"camellia-256-gcm");
423 case WINPR_CIPHER_CAMELLIA_128_CCM:
424 evp = EVP_get_cipherbyname(
"camellia-128-ccm");
427 case WINPR_CIPHER_CAMELLIA_192_CCM:
428 evp = EVP_get_cipherbyname(
"camellia-192-ccm");
431 case WINPR_CIPHER_CAMELLIA_256_CCM:
432 evp = EVP_get_cipherbyname(
"camellia-256-ccm");
435 case WINPR_CIPHER_DES_ECB:
436 evp = EVP_get_cipherbyname(
"des-ecb");
439 case WINPR_CIPHER_DES_CBC:
440 evp = EVP_get_cipherbyname(
"des-cbc");
443 case WINPR_CIPHER_DES_EDE_ECB:
444 evp = EVP_get_cipherbyname(
"des-ede-ecb");
447 case WINPR_CIPHER_DES_EDE_CBC:
448 evp = EVP_get_cipherbyname(
"des-ede-cbc");
451 case WINPR_CIPHER_DES_EDE3_ECB:
452 evp = EVP_get_cipherbyname(
"des-ede3-ecb");
455 case WINPR_CIPHER_DES_EDE3_CBC:
456 evp = EVP_get_cipherbyname(
"des-ede3-cbc");
459 case WINPR_CIPHER_ARC4_128:
460 evp = EVP_get_cipherbyname(
"rc4");
463 case WINPR_CIPHER_BLOWFISH_ECB:
464 evp = EVP_get_cipherbyname(
"blowfish-ecb");
467 case WINPR_CIPHER_BLOWFISH_CBC:
468 evp = EVP_get_cipherbyname(
"blowfish-cbc");
471 case WINPR_CIPHER_BLOWFISH_CFB64:
472 evp = EVP_get_cipherbyname(
"blowfish-cfb64");
475 case WINPR_CIPHER_BLOWFISH_CTR:
476 evp = EVP_get_cipherbyname(
"blowfish-ctr");
485 #elif defined(WITH_MBEDTLS)
486 mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(
int cipher)
488 mbedtls_cipher_type_t type = MBEDTLS_CIPHER_NONE;
492 case WINPR_CIPHER_NONE:
493 type = MBEDTLS_CIPHER_NONE;
496 case WINPR_CIPHER_NULL:
497 type = MBEDTLS_CIPHER_NULL;
500 case WINPR_CIPHER_AES_128_ECB:
501 type = MBEDTLS_CIPHER_AES_128_ECB;
504 case WINPR_CIPHER_AES_192_ECB:
505 type = MBEDTLS_CIPHER_AES_192_ECB;
508 case WINPR_CIPHER_AES_256_ECB:
509 type = MBEDTLS_CIPHER_AES_256_ECB;
512 case WINPR_CIPHER_AES_128_CBC:
513 type = MBEDTLS_CIPHER_AES_128_CBC;
516 case WINPR_CIPHER_AES_192_CBC:
517 type = MBEDTLS_CIPHER_AES_192_CBC;
520 case WINPR_CIPHER_AES_256_CBC:
521 type = MBEDTLS_CIPHER_AES_256_CBC;
524 case WINPR_CIPHER_AES_128_CFB128:
525 type = MBEDTLS_CIPHER_AES_128_CFB128;
528 case WINPR_CIPHER_AES_192_CFB128:
529 type = MBEDTLS_CIPHER_AES_192_CFB128;
532 case WINPR_CIPHER_AES_256_CFB128:
533 type = MBEDTLS_CIPHER_AES_256_CFB128;
536 case WINPR_CIPHER_AES_128_CTR:
537 type = MBEDTLS_CIPHER_AES_128_CTR;
540 case WINPR_CIPHER_AES_192_CTR:
541 type = MBEDTLS_CIPHER_AES_192_CTR;
544 case WINPR_CIPHER_AES_256_CTR:
545 type = MBEDTLS_CIPHER_AES_256_CTR;
548 case WINPR_CIPHER_AES_128_GCM:
549 type = MBEDTLS_CIPHER_AES_128_GCM;
552 case WINPR_CIPHER_AES_192_GCM:
553 type = MBEDTLS_CIPHER_AES_192_GCM;
556 case WINPR_CIPHER_AES_256_GCM:
557 type = MBEDTLS_CIPHER_AES_256_GCM;
560 case WINPR_CIPHER_AES_128_CCM:
561 type = MBEDTLS_CIPHER_AES_128_CCM;
564 case WINPR_CIPHER_AES_192_CCM:
565 type = MBEDTLS_CIPHER_AES_192_CCM;
568 case WINPR_CIPHER_AES_256_CCM:
569 type = MBEDTLS_CIPHER_AES_256_CCM;
577 WINPR_CIPHER_CTX* winpr_Cipher_New(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op,
578 const void* key,
const void* iv)
580 return winpr_Cipher_NewEx(cipher, op, key, 0, iv, 0);
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,
587 if (cipher == WINPR_CIPHER_ARC4_128)
590 "WINPR_CIPHER_ARC4_128 (RC4) cipher not supported, use winpr_RC4_new instead");
594 WINPR_CIPHER_CTX* ctx = calloc(1,
sizeof(WINPR_CIPHER_CTX));
598 ctx->cipher = cipher;
601 #if defined(WITH_OPENSSL)
602 const EVP_CIPHER* evp = winpr_openssl_get_evp_cipher(cipher);
606 ctx->ectx = EVP_CIPHER_CTX_new();
613 WINPR_ASSERT(keylen <= INT32_MAX);
614 const int len = EVP_CIPHER_CTX_key_length(ctx->ectx);
615 if ((len > 0) && (len != keylen))
617 if (EVP_CIPHER_CTX_set_key_length(ctx->ectx, (
int)keylen) != 1)
624 WINPR_ASSERT(ivlen <= INT32_MAX);
625 const int len = EVP_CIPHER_CTX_iv_length(ctx->ectx);
626 if ((len > 0) && (ivlen != len))
631 const int operation = (op == WINPR_ENCRYPT) ? 1 : 0;
633 if (EVP_CipherInit_ex(ctx->ectx, evp, NULL, key, iv, operation) != 1)
636 EVP_CIPHER_CTX_set_padding(ctx->ectx, 0);
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);
645 ctx->mctx = calloc(1,
sizeof(mbedtls_cipher_context_t));
649 const mbedtls_operation_t operation = (op == WINPR_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT;
650 mbedtls_cipher_init(ctx->mctx);
652 if (mbedtls_cipher_setup(ctx->mctx, cipher_info) != 0)
655 const int key_bitlen = mbedtls_cipher_get_key_bitlen(ctx->mctx);
657 if (mbedtls_cipher_setkey(ctx->mctx, key, key_bitlen, operation) != 0)
660 if (mbedtls_cipher_set_padding_mode(ctx->mctx, MBEDTLS_PADDING_NONE) != 0)
667 winpr_Cipher_Free(ctx);
671 BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled)
675 #if defined(WITH_OPENSSL)
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)
689 BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx,
const void* input,
size_t ilen,
void* output,
695 #if defined(WITH_OPENSSL)
696 int outl = (int)*olen;
700 WLog_ERR(TAG,
"input length %" PRIuz
" > %d, abort", ilen, INT_MAX);
704 WINPR_ASSERT(ctx->ectx);
705 if (EVP_CipherUpdate(ctx->ectx, output, &outl, input, (
int)ilen) == 1)
707 *olen = (size_t)outl;
711 #elif defined(WITH_MBEDTLS)
712 WINPR_ASSERT(ctx->mctx);
713 if (mbedtls_cipher_update(ctx->mctx, input, ilen, output, olen) == 0)
718 WLog_ERR(TAG,
"Failed to update the data");
722 BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx,
void* output,
size_t* olen)
726 #if defined(WITH_OPENSSL)
727 int outl = (int)*olen;
729 WINPR_ASSERT(ctx->ectx);
730 if (EVP_CipherFinal_ex(ctx->ectx, output, &outl) == 1)
732 *olen = (size_t)outl;
736 #elif defined(WITH_MBEDTLS)
738 WINPR_ASSERT(ctx->mctx);
739 if (mbedtls_cipher_finish(ctx->mctx, output, olen) == 0)
747 void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
752 #if defined(WITH_OPENSSL)
754 EVP_CIPHER_CTX_free(ctx->ectx);
755 #elif defined(WITH_MBEDTLS)
758 mbedtls_cipher_free(ctx->mctx);
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)
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)
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);
801 if ((nkey > 64) || (niv > 64))
807 mbedtls_md_init(&ctx);
809 if (mbedtls_md_setup(&ctx, md_info, 0) != 0)
814 if (mbedtls_md_starts(&ctx) != 0)
819 if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
823 if (mbedtls_md_update(&ctx, data, datal) != 0)
828 if (mbedtls_md_update(&ctx, salt, 8) != 0)
832 if (mbedtls_md_finish(&ctx, md_buf) != 0)
835 mds = mbedtls_md_get_size(md_info);
837 for (
unsigned int i = 1; i < (
unsigned int)count; i++)
839 if (mbedtls_md_starts(&ctx) != 0)
842 if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
845 if (mbedtls_md_finish(&ctx, md_buf) != 0)
862 *(BYTE*)(key++) = md_buf[i];
869 if (niv && (i != mds))
880 *(BYTE*)(iv++) = md_buf[i];
887 if ((nkey == 0) && (niv == 0))
891 rv = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
893 mbedtls_md_free(&ctx);
894 SecureZeroMemory(md_buf, 64);