19#include <winpr/config.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)
50struct winpr_cipher_ctx_private_st
52 WINPR_CIPHER_TYPE cipher;
53 WINPR_CRYPTO_OPERATION op;
59 mbedtls_cipher_context_t* mctx;
67struct winpr_rc4_ctx_private_st
69#if defined(WITH_INTERNAL_RC4)
70 winpr_int_RC4_CTX* ictx;
72#if defined(WITH_OPENSSL)
78static 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)
97 ctx->ctx = EVP_CIPHER_CTX_new();
101#if OPENSSL_VERSION_NUMBER >= 0x30000000L
102 EVP_CIPHER* evp = EVP_CIPHER_fetch(NULL,
"RC4", override_fips ?
"fips=no" : NULL);
104 const EVP_CIPHER* evp = EVP_rc4();
110 EVP_CIPHER_CTX_reset(ctx->ctx);
111 if (EVP_EncryptInit_ex(ctx->ctx, evp,
nullptr,
nullptr,
nullptr) != 1)
114#if OPENSSL_VERSION_NUMBER >= 0x30000000L
115 EVP_CIPHER_free(evp);
118#if !(OPENSSL_VERSION_NUMBER < 0x10001000L)
120 if (override_fips == TRUE)
121 EVP_CIPHER_CTX_set_flags(ctx->ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
125 EVP_CIPHER_CTX_set_key_length(ctx->ctx, (
int)keylen);
126 if (EVP_EncryptInit_ex(ctx->ctx,
nullptr,
nullptr, key,
nullptr) != 1)
132 WINPR_PRAGMA_DIAG_PUSH
133 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
136 WINPR_PRAGMA_DIAG_POP
140WINPR_RC4_CTX* winpr_RC4_New_Allow_FIPS(
const void* key,
size_t keylen)
142 return winpr_RC4_New_Internal(key, keylen, TRUE);
145WINPR_RC4_CTX* winpr_RC4_New(
const void* key,
size_t keylen)
147 return winpr_RC4_New_Internal(key, keylen, FALSE);
150BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx,
size_t length,
const void* input,
void* output)
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)
163 return EVP_CipherUpdate(ctx->ctx, output, &outputLength, input, (
int)length) == 1;
168void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
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);
186extern const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md);
190extern mbedtls_md_type_t winpr_mbedtls_get_md_type(
int md);
195 WINPR_CIPHER_TYPE md;
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" },
250static int cipher_compare(
const void* a,
const void* b)
252 const WINPR_CIPHER_TYPE* cipher = a;
253 const struct cipher_map* map = b;
254 if (*cipher == map->md)
256 return *cipher > map->md ? 1 : -1;
259const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE md)
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);
269static int cipher_string_compare(
const void* a,
const void* b)
271 const char* cipher = a;
272 const struct cipher_map* map = b;
273 return strcmp(cipher, map->name);
276WINPR_CIPHER_TYPE winpr_cipher_type_from_string(
const char* name)
278 const struct cipher_map* ret = bsearch(name, s_cipher_map, ARRAYSIZE(s_cipher_map),
279 sizeof(
struct cipher_map), cipher_string_compare);
281 return WINPR_CIPHER_NONE;
285#if defined(WITH_OPENSSL)
286static const EVP_CIPHER* winpr_openssl_get_evp_cipher(WINPR_CIPHER_TYPE cipher)
288 const EVP_CIPHER* evp =
nullptr;
292 case WINPR_CIPHER_NULL:
293 evp = EVP_enc_null();
296 case WINPR_CIPHER_AES_128_ECB:
297 evp = EVP_get_cipherbyname(
"aes-128-ecb");
300 case WINPR_CIPHER_AES_192_ECB:
301 evp = EVP_get_cipherbyname(
"aes-192-ecb");
304 case WINPR_CIPHER_AES_256_ECB:
305 evp = EVP_get_cipherbyname(
"aes-256-ecb");
308 case WINPR_CIPHER_AES_128_CBC:
309 evp = EVP_get_cipherbyname(
"aes-128-cbc");
312 case WINPR_CIPHER_AES_192_CBC:
313 evp = EVP_get_cipherbyname(
"aes-192-cbc");
316 case WINPR_CIPHER_AES_256_CBC:
317 evp = EVP_get_cipherbyname(
"aes-256-cbc");
320 case WINPR_CIPHER_AES_128_CFB128:
321 evp = EVP_get_cipherbyname(
"aes-128-cfb128");
324 case WINPR_CIPHER_AES_192_CFB128:
325 evp = EVP_get_cipherbyname(
"aes-192-cfb128");
328 case WINPR_CIPHER_AES_256_CFB128:
329 evp = EVP_get_cipherbyname(
"aes-256-cfb128");
332 case WINPR_CIPHER_AES_128_CTR:
333 evp = EVP_get_cipherbyname(
"aes-128-ctr");
336 case WINPR_CIPHER_AES_192_CTR:
337 evp = EVP_get_cipherbyname(
"aes-192-ctr");
340 case WINPR_CIPHER_AES_256_CTR:
341 evp = EVP_get_cipherbyname(
"aes-256-ctr");
344 case WINPR_CIPHER_AES_128_GCM:
345 evp = EVP_get_cipherbyname(
"aes-128-gcm");
348 case WINPR_CIPHER_AES_192_GCM:
349 evp = EVP_get_cipherbyname(
"aes-192-gcm");
352 case WINPR_CIPHER_AES_256_GCM:
353 evp = EVP_get_cipherbyname(
"aes-256-gcm");
356 case WINPR_CIPHER_AES_128_CCM:
357 evp = EVP_get_cipherbyname(
"aes-128-ccm");
360 case WINPR_CIPHER_AES_192_CCM:
361 evp = EVP_get_cipherbyname(
"aes-192-ccm");
364 case WINPR_CIPHER_AES_256_CCM:
365 evp = EVP_get_cipherbyname(
"aes-256-ccm");
368 case WINPR_CIPHER_CAMELLIA_128_ECB:
369 evp = EVP_get_cipherbyname(
"camellia-128-ecb");
372 case WINPR_CIPHER_CAMELLIA_192_ECB:
373 evp = EVP_get_cipherbyname(
"camellia-192-ecb");
376 case WINPR_CIPHER_CAMELLIA_256_ECB:
377 evp = EVP_get_cipherbyname(
"camellia-256-ecb");
380 case WINPR_CIPHER_CAMELLIA_128_CBC:
381 evp = EVP_get_cipherbyname(
"camellia-128-cbc");
384 case WINPR_CIPHER_CAMELLIA_192_CBC:
385 evp = EVP_get_cipherbyname(
"camellia-192-cbc");
388 case WINPR_CIPHER_CAMELLIA_256_CBC:
389 evp = EVP_get_cipherbyname(
"camellia-256-cbc");
392 case WINPR_CIPHER_CAMELLIA_128_CFB128:
393 evp = EVP_get_cipherbyname(
"camellia-128-cfb128");
396 case WINPR_CIPHER_CAMELLIA_192_CFB128:
397 evp = EVP_get_cipherbyname(
"camellia-192-cfb128");
400 case WINPR_CIPHER_CAMELLIA_256_CFB128:
401 evp = EVP_get_cipherbyname(
"camellia-256-cfb128");
404 case WINPR_CIPHER_CAMELLIA_128_CTR:
405 evp = EVP_get_cipherbyname(
"camellia-128-ctr");
408 case WINPR_CIPHER_CAMELLIA_192_CTR:
409 evp = EVP_get_cipherbyname(
"camellia-192-ctr");
412 case WINPR_CIPHER_CAMELLIA_256_CTR:
413 evp = EVP_get_cipherbyname(
"camellia-256-ctr");
416 case WINPR_CIPHER_CAMELLIA_128_GCM:
417 evp = EVP_get_cipherbyname(
"camellia-128-gcm");
420 case WINPR_CIPHER_CAMELLIA_192_GCM:
421 evp = EVP_get_cipherbyname(
"camellia-192-gcm");
424 case WINPR_CIPHER_CAMELLIA_256_GCM:
425 evp = EVP_get_cipherbyname(
"camellia-256-gcm");
428 case WINPR_CIPHER_CAMELLIA_128_CCM:
429 evp = EVP_get_cipherbyname(
"camellia-128-ccm");
432 case WINPR_CIPHER_CAMELLIA_192_CCM:
433 evp = EVP_get_cipherbyname(
"camellia-192-ccm");
436 case WINPR_CIPHER_CAMELLIA_256_CCM:
437 evp = EVP_get_cipherbyname(
"camellia-256-ccm");
440 case WINPR_CIPHER_DES_ECB:
441 evp = EVP_get_cipherbyname(
"des-ecb");
444 case WINPR_CIPHER_DES_CBC:
445 evp = EVP_get_cipherbyname(
"des-cbc");
448 case WINPR_CIPHER_DES_EDE_ECB:
449 evp = EVP_get_cipherbyname(
"des-ede-ecb");
452 case WINPR_CIPHER_DES_EDE_CBC:
453 evp = EVP_get_cipherbyname(
"des-ede-cbc");
456 case WINPR_CIPHER_DES_EDE3_ECB:
457 evp = EVP_get_cipherbyname(
"des-ede3-ecb");
460 case WINPR_CIPHER_DES_EDE3_CBC:
461 evp = EVP_get_cipherbyname(
"des-ede3-cbc");
464 case WINPR_CIPHER_ARC4_128:
465 evp = EVP_get_cipherbyname(
"rc4");
468 case WINPR_CIPHER_BLOWFISH_ECB:
469 evp = EVP_get_cipherbyname(
"blowfish-ecb");
472 case WINPR_CIPHER_BLOWFISH_CBC:
473 evp = EVP_get_cipherbyname(
"blowfish-cbc");
476 case WINPR_CIPHER_BLOWFISH_CFB64:
477 evp = EVP_get_cipherbyname(
"blowfish-cfb64");
480 case WINPR_CIPHER_BLOWFISH_CTR:
481 evp = EVP_get_cipherbyname(
"blowfish-ctr");
490#elif defined(WITH_MBEDTLS)
491mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(
int cipher)
493 mbedtls_cipher_type_t type = MBEDTLS_CIPHER_NONE;
497 case WINPR_CIPHER_NONE:
498 type = MBEDTLS_CIPHER_NONE;
501 case WINPR_CIPHER_NULL:
502 type = MBEDTLS_CIPHER_NULL;
505 case WINPR_CIPHER_AES_128_ECB:
506 type = MBEDTLS_CIPHER_AES_128_ECB;
509 case WINPR_CIPHER_AES_192_ECB:
510 type = MBEDTLS_CIPHER_AES_192_ECB;
513 case WINPR_CIPHER_AES_256_ECB:
514 type = MBEDTLS_CIPHER_AES_256_ECB;
517 case WINPR_CIPHER_AES_128_CBC:
518 type = MBEDTLS_CIPHER_AES_128_CBC;
521 case WINPR_CIPHER_AES_192_CBC:
522 type = MBEDTLS_CIPHER_AES_192_CBC;
525 case WINPR_CIPHER_AES_256_CBC:
526 type = MBEDTLS_CIPHER_AES_256_CBC;
529 case WINPR_CIPHER_AES_128_CFB128:
530 type = MBEDTLS_CIPHER_AES_128_CFB128;
533 case WINPR_CIPHER_AES_192_CFB128:
534 type = MBEDTLS_CIPHER_AES_192_CFB128;
537 case WINPR_CIPHER_AES_256_CFB128:
538 type = MBEDTLS_CIPHER_AES_256_CFB128;
541 case WINPR_CIPHER_AES_128_CTR:
542 type = MBEDTLS_CIPHER_AES_128_CTR;
545 case WINPR_CIPHER_AES_192_CTR:
546 type = MBEDTLS_CIPHER_AES_192_CTR;
549 case WINPR_CIPHER_AES_256_CTR:
550 type = MBEDTLS_CIPHER_AES_256_CTR;
553 case WINPR_CIPHER_AES_128_GCM:
554 type = MBEDTLS_CIPHER_AES_128_GCM;
557 case WINPR_CIPHER_AES_192_GCM:
558 type = MBEDTLS_CIPHER_AES_192_GCM;
561 case WINPR_CIPHER_AES_256_GCM:
562 type = MBEDTLS_CIPHER_AES_256_GCM;
565 case WINPR_CIPHER_AES_128_CCM:
566 type = MBEDTLS_CIPHER_AES_128_CCM;
569 case WINPR_CIPHER_AES_192_CCM:
570 type = MBEDTLS_CIPHER_AES_192_CCM;
573 case WINPR_CIPHER_AES_256_CCM:
574 type = MBEDTLS_CIPHER_AES_256_CCM;
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)
586 return winpr_Cipher_NewEx(cipher, op, key, 0, iv, 0);
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)
594 if (cipher == WINPR_CIPHER_ARC4_128)
597 "WINPR_CIPHER_ARC4_128 (RC4) cipher not supported, use winpr_RC4_new instead");
601 WINPR_CIPHER_CTX* ctx = calloc(1,
sizeof(WINPR_CIPHER_CTX));
605 ctx->cipher = cipher;
608#if defined(WITH_OPENSSL)
609 const EVP_CIPHER* evp = winpr_openssl_get_evp_cipher(cipher);
613 ctx->ectx = EVP_CIPHER_CTX_new();
618 const int operation = (op == WINPR_ENCRYPT) ? 1 : 0;
619 if (EVP_CipherInit_ex(ctx->ectx, evp,
nullptr, key, iv, operation) != 1)
623 EVP_CIPHER_CTX_set_padding(ctx->ectx, 0);
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);
632 ctx->mctx = calloc(1,
sizeof(mbedtls_cipher_context_t));
636 const mbedtls_operation_t operation = (op == WINPR_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT;
637 mbedtls_cipher_init(ctx->mctx);
639 if (mbedtls_cipher_setup(ctx->mctx, cipher_info) != 0)
642 const int key_bitlen = mbedtls_cipher_get_key_bitlen(ctx->mctx);
644 if (mbedtls_cipher_setkey(ctx->mctx, key, key_bitlen, operation) != 0)
647 if (mbedtls_cipher_set_padding_mode(ctx->mctx, MBEDTLS_PADDING_NONE) != 0)
654 winpr_Cipher_Free(ctx);
658BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled)
662#if defined(WITH_OPENSSL)
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)
676BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx,
const void* input,
size_t ilen,
void* output,
682#if defined(WITH_OPENSSL)
683 int outl = (int)*olen;
687 WLog_ERR(TAG,
"input length %" PRIuz
" > %d, abort", ilen, INT_MAX);
691 WINPR_ASSERT(ctx->ectx);
692 if (EVP_CipherUpdate(ctx->ectx, output, &outl, input, (
int)ilen) == 1)
694 *olen = (size_t)outl;
698#elif defined(WITH_MBEDTLS)
699 WINPR_ASSERT(ctx->mctx);
700 if (mbedtls_cipher_update(ctx->mctx, input, ilen, output, olen) == 0)
705 WLog_ERR(TAG,
"Failed to update the data");
709BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx,
void* output,
size_t* olen)
713#if defined(WITH_OPENSSL)
714 int outl = (int)*olen;
716 WINPR_ASSERT(ctx->ectx);
717 if (EVP_CipherFinal_ex(ctx->ectx, output, &outl) == 1)
719 *olen = (size_t)outl;
723#elif defined(WITH_MBEDTLS)
725 WINPR_ASSERT(ctx->mctx);
726 if (mbedtls_cipher_finish(ctx->mctx, output, olen) == 0)
734void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
739#if defined(WITH_OPENSSL)
741 EVP_CIPHER_CTX_free(ctx->ectx);
742#elif defined(WITH_MBEDTLS)
745 mbedtls_cipher_free(ctx->mctx);
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)
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)
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);
788 if ((nkey > 64) || (niv > 64))
794 mbedtls_md_init(&ctx);
796 if (mbedtls_md_setup(&ctx, md_info, 0) != 0)
801 if (mbedtls_md_starts(&ctx) != 0)
806 if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
810 if (mbedtls_md_update(&ctx, data, datal) != 0)
815 if (mbedtls_md_update(&ctx, salt, 8) != 0)
819 if (mbedtls_md_finish(&ctx, md_buf) != 0)
822 mds = mbedtls_md_get_size(md_info);
824 for (
unsigned int i = 1; i < (
unsigned int)count; i++)
826 if (mbedtls_md_starts(&ctx) != 0)
829 if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
832 if (mbedtls_md_finish(&ctx, md_buf) != 0)
849 *(BYTE*)(key++) = md_buf[i];
856 if (niv && (i != mds))
867 *(BYTE*)(iv++) = md_buf[i];
874 if ((nkey == 0) && (niv == 0))
878 rv = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
880 mbedtls_md_free(&ctx);
881 SecureZeroMemory(md_buf, 64);