Coverage Report

Created: 2026-10-28 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/winpr/libwinpr/crypto/cipher.c
Line
Count
Source
1
/**
2
 * WinPR: Windows Portable Runtime
3
 *
4
 * Copyright 2015 Marc-Andre Moreau <marcandre.moreau@gmail.com>
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
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
63
/**
64
 * RC4
65
 */
66
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
244
{
80
244
  if (!key || (keylen == 0))
81
0
    return nullptr;
82
83
244
  WINPR_RC4_CTX* ctx = (WINPR_RC4_CTX*)calloc(1, sizeof(WINPR_RC4_CTX));
84
244
  if (!ctx)
85
0
    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
244
  if (keylen > INT_MAX)
95
0
    goto fail;
96
97
244
  ctx->ctx = EVP_CIPHER_CTX_new();
98
244
  if (!ctx->ctx)
99
0
    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
244
  const EVP_CIPHER* evp = EVP_rc4();
105
244
#endif
106
107
244
  if (!evp)
108
0
    goto fail;
109
110
244
  EVP_CIPHER_CTX_reset(ctx->ctx);
111
244
  if (EVP_EncryptInit_ex(ctx->ctx, evp, nullptr, nullptr, nullptr) != 1)
112
0
    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
244
  EVP_CIPHER_CTX_set_key_length(ctx->ctx, (int)keylen);
126
244
  if (EVP_EncryptInit_ex(ctx->ctx, nullptr, nullptr, key, nullptr) != 1)
127
0
    goto fail;
128
244
#endif
129
244
  return ctx;
130
131
0
fail:
132
0
  WINPR_PRAGMA_DIAG_PUSH
133
0
  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
134
135
0
  winpr_RC4_Free(ctx);
136
0
  WINPR_PRAGMA_DIAG_POP
137
0
  return nullptr;
138
244
}
139
140
WINPR_RC4_CTX* winpr_RC4_New_Allow_FIPS(const void* key, size_t keylen)
141
0
{
142
0
  return winpr_RC4_New_Internal(key, keylen, TRUE);
143
0
}
144
145
WINPR_RC4_CTX* winpr_RC4_New(const void* key, size_t keylen)
146
244
{
147
244
  return winpr_RC4_New_Internal(key, keylen, FALSE);
148
244
}
149
150
BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const void* input, void* output)
151
244
{
152
244
  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
244
  WINPR_ASSERT(ctx->ctx);
158
244
  int outputLength = 0;
159
244
  if (length > INT_MAX)
160
0
    return FALSE;
161
162
244
  WINPR_ASSERT(ctx);
163
244
  return EVP_CipherUpdate(ctx->ctx, output, &outputLength, input, (int)length) == 1;
164
0
#endif
165
0
  return FALSE;
166
244
}
167
168
void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
169
322
{
170
322
  if (!ctx)
171
78
    return;
172
173
#if defined(WITH_INTERNAL_RC4)
174
  winpr_int_rc4_free(ctx->ictx);
175
#elif defined(WITH_OPENSSL)
176
244
  EVP_CIPHER_CTX_free(ctx->ctx);
177
244
#endif
178
244
  free(ctx);
179
244
}
180
181
/**
182
 * Generic Cipher API
183
 */
184
185
#ifdef WITH_OPENSSL
186
extern const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md);
187
#endif
188
189
#ifdef WITH_MBEDTLS
190
extern mbedtls_md_type_t winpr_mbedtls_get_md_type(int md);
191
#endif
192
193
struct cipher_map
194
{
195
  WINPR_CIPHER_TYPE md;
196
  const char* name;
197
};
198
static 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
250
static int cipher_compare(const void* a, const void* b)
251
0
{
252
0
  const WINPR_CIPHER_TYPE* cipher = a;
253
0
  const struct cipher_map* map = b;
254
0
  if (*cipher == map->md)
255
0
    return 0;
256
0
  return *cipher > map->md ? 1 : -1;
257
0
}
258
259
const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE md)
260
0
{
261
0
  WINPR_CIPHER_TYPE lc = md;
262
0
  const struct cipher_map* ret = bsearch(&lc, s_cipher_map, ARRAYSIZE(s_cipher_map),
263
0
                                         sizeof(struct cipher_map), cipher_compare);
264
0
  if (!ret)
265
0
    return "unknown";
266
0
  return ret->name;
267
0
}
268
269
static int cipher_string_compare(const void* a, const void* b)
270
0
{
271
0
  const char* cipher = a;
272
0
  const struct cipher_map* map = b;
273
0
  return strcmp(cipher, map->name);
274
0
}
275
276
WINPR_CIPHER_TYPE winpr_cipher_type_from_string(const char* name)
277
0
{
278
0
  const struct cipher_map* ret = bsearch(name, s_cipher_map, ARRAYSIZE(s_cipher_map),
279
0
                                         sizeof(struct cipher_map), cipher_string_compare);
280
0
  if (!ret)
281
0
    return WINPR_CIPHER_NONE;
282
0
  return ret->md;
283
0
}
284
285
#if defined(WITH_OPENSSL)
286
static const EVP_CIPHER* winpr_openssl_get_evp_cipher(WINPR_CIPHER_TYPE cipher)
287
453
{
288
453
  const EVP_CIPHER* evp = nullptr;
289
290
453
  switch (cipher)
291
453
  {
292
0
    case WINPR_CIPHER_NULL:
293
0
      evp = EVP_enc_null();
294
0
      break;
295
296
0
    case WINPR_CIPHER_AES_128_ECB:
297
0
      evp = EVP_get_cipherbyname("aes-128-ecb");
298
0
      break;
299
300
0
    case WINPR_CIPHER_AES_192_ECB:
301
0
      evp = EVP_get_cipherbyname("aes-192-ecb");
302
0
      break;
303
304
0
    case WINPR_CIPHER_AES_256_ECB:
305
0
      evp = EVP_get_cipherbyname("aes-256-ecb");
306
0
      break;
307
308
453
    case WINPR_CIPHER_AES_128_CBC:
309
453
      evp = EVP_get_cipherbyname("aes-128-cbc");
310
453
      break;
311
312
0
    case WINPR_CIPHER_AES_192_CBC:
313
0
      evp = EVP_get_cipherbyname("aes-192-cbc");
314
0
      break;
315
316
0
    case WINPR_CIPHER_AES_256_CBC:
317
0
      evp = EVP_get_cipherbyname("aes-256-cbc");
318
0
      break;
319
320
0
    case WINPR_CIPHER_AES_128_CFB128:
321
0
      evp = EVP_get_cipherbyname("aes-128-cfb128");
322
0
      break;
323
324
0
    case WINPR_CIPHER_AES_192_CFB128:
325
0
      evp = EVP_get_cipherbyname("aes-192-cfb128");
326
0
      break;
327
328
0
    case WINPR_CIPHER_AES_256_CFB128:
329
0
      evp = EVP_get_cipherbyname("aes-256-cfb128");
330
0
      break;
331
332
0
    case WINPR_CIPHER_AES_128_CTR:
333
0
      evp = EVP_get_cipherbyname("aes-128-ctr");
334
0
      break;
335
336
0
    case WINPR_CIPHER_AES_192_CTR:
337
0
      evp = EVP_get_cipherbyname("aes-192-ctr");
338
0
      break;
339
340
0
    case WINPR_CIPHER_AES_256_CTR:
341
0
      evp = EVP_get_cipherbyname("aes-256-ctr");
342
0
      break;
343
344
0
    case WINPR_CIPHER_AES_128_GCM:
345
0
      evp = EVP_get_cipherbyname("aes-128-gcm");
346
0
      break;
347
348
0
    case WINPR_CIPHER_AES_192_GCM:
349
0
      evp = EVP_get_cipherbyname("aes-192-gcm");
350
0
      break;
351
352
0
    case WINPR_CIPHER_AES_256_GCM:
353
0
      evp = EVP_get_cipherbyname("aes-256-gcm");
354
0
      break;
355
356
0
    case WINPR_CIPHER_AES_128_CCM:
357
0
      evp = EVP_get_cipherbyname("aes-128-ccm");
358
0
      break;
359
360
0
    case WINPR_CIPHER_AES_192_CCM:
361
0
      evp = EVP_get_cipherbyname("aes-192-ccm");
362
0
      break;
363
364
0
    case WINPR_CIPHER_AES_256_CCM:
365
0
      evp = EVP_get_cipherbyname("aes-256-ccm");
366
0
      break;
367
368
0
    case WINPR_CIPHER_CAMELLIA_128_ECB:
369
0
      evp = EVP_get_cipherbyname("camellia-128-ecb");
370
0
      break;
371
372
0
    case WINPR_CIPHER_CAMELLIA_192_ECB:
373
0
      evp = EVP_get_cipherbyname("camellia-192-ecb");
374
0
      break;
375
376
0
    case WINPR_CIPHER_CAMELLIA_256_ECB:
377
0
      evp = EVP_get_cipherbyname("camellia-256-ecb");
378
0
      break;
379
380
0
    case WINPR_CIPHER_CAMELLIA_128_CBC:
381
0
      evp = EVP_get_cipherbyname("camellia-128-cbc");
382
0
      break;
383
384
0
    case WINPR_CIPHER_CAMELLIA_192_CBC:
385
0
      evp = EVP_get_cipherbyname("camellia-192-cbc");
386
0
      break;
387
388
0
    case WINPR_CIPHER_CAMELLIA_256_CBC:
389
0
      evp = EVP_get_cipherbyname("camellia-256-cbc");
390
0
      break;
391
392
0
    case WINPR_CIPHER_CAMELLIA_128_CFB128:
393
0
      evp = EVP_get_cipherbyname("camellia-128-cfb128");
394
0
      break;
395
396
0
    case WINPR_CIPHER_CAMELLIA_192_CFB128:
397
0
      evp = EVP_get_cipherbyname("camellia-192-cfb128");
398
0
      break;
399
400
0
    case WINPR_CIPHER_CAMELLIA_256_CFB128:
401
0
      evp = EVP_get_cipherbyname("camellia-256-cfb128");
402
0
      break;
403
404
0
    case WINPR_CIPHER_CAMELLIA_128_CTR:
405
0
      evp = EVP_get_cipherbyname("camellia-128-ctr");
406
0
      break;
407
408
0
    case WINPR_CIPHER_CAMELLIA_192_CTR:
409
0
      evp = EVP_get_cipherbyname("camellia-192-ctr");
410
0
      break;
411
412
0
    case WINPR_CIPHER_CAMELLIA_256_CTR:
413
0
      evp = EVP_get_cipherbyname("camellia-256-ctr");
414
0
      break;
415
416
0
    case WINPR_CIPHER_CAMELLIA_128_GCM:
417
0
      evp = EVP_get_cipherbyname("camellia-128-gcm");
418
0
      break;
419
420
0
    case WINPR_CIPHER_CAMELLIA_192_GCM:
421
0
      evp = EVP_get_cipherbyname("camellia-192-gcm");
422
0
      break;
423
424
0
    case WINPR_CIPHER_CAMELLIA_256_GCM:
425
0
      evp = EVP_get_cipherbyname("camellia-256-gcm");
426
0
      break;
427
428
0
    case WINPR_CIPHER_CAMELLIA_128_CCM:
429
0
      evp = EVP_get_cipherbyname("camellia-128-ccm");
430
0
      break;
431
432
0
    case WINPR_CIPHER_CAMELLIA_192_CCM:
433
0
      evp = EVP_get_cipherbyname("camellia-192-ccm");
434
0
      break;
435
436
0
    case WINPR_CIPHER_CAMELLIA_256_CCM:
437
0
      evp = EVP_get_cipherbyname("camellia-256-ccm");
438
0
      break;
439
440
0
    case WINPR_CIPHER_DES_ECB:
441
0
      evp = EVP_get_cipherbyname("des-ecb");
442
0
      break;
443
444
0
    case WINPR_CIPHER_DES_CBC:
445
0
      evp = EVP_get_cipherbyname("des-cbc");
446
0
      break;
447
448
0
    case WINPR_CIPHER_DES_EDE_ECB:
449
0
      evp = EVP_get_cipherbyname("des-ede-ecb");
450
0
      break;
451
452
0
    case WINPR_CIPHER_DES_EDE_CBC:
453
0
      evp = EVP_get_cipherbyname("des-ede-cbc");
454
0
      break;
455
456
0
    case WINPR_CIPHER_DES_EDE3_ECB:
457
0
      evp = EVP_get_cipherbyname("des-ede3-ecb");
458
0
      break;
459
460
0
    case WINPR_CIPHER_DES_EDE3_CBC:
461
0
      evp = EVP_get_cipherbyname("des-ede3-cbc");
462
0
      break;
463
464
0
    case WINPR_CIPHER_ARC4_128:
465
0
      evp = EVP_get_cipherbyname("rc4");
466
0
      break;
467
468
0
    case WINPR_CIPHER_BLOWFISH_ECB:
469
0
      evp = EVP_get_cipherbyname("blowfish-ecb");
470
0
      break;
471
472
0
    case WINPR_CIPHER_BLOWFISH_CBC:
473
0
      evp = EVP_get_cipherbyname("blowfish-cbc");
474
0
      break;
475
476
0
    case WINPR_CIPHER_BLOWFISH_CFB64:
477
0
      evp = EVP_get_cipherbyname("blowfish-cfb64");
478
0
      break;
479
480
0
    case WINPR_CIPHER_BLOWFISH_CTR:
481
0
      evp = EVP_get_cipherbyname("blowfish-ctr");
482
0
      break;
483
0
    default:
484
0
      break;
485
453
  }
486
487
453
  return evp;
488
453
}
489
490
#elif defined(WITH_MBEDTLS)
491
mbedtls_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)
583
WINPR_CIPHER_CTX* winpr_Cipher_New(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op,
584
                                   const void* key, const void* iv)
585
0
{
586
0
  return winpr_Cipher_NewEx(cipher, op, key, 0, iv, 0);
587
0
}
588
#endif
589
590
WINPR_API WINPR_ATTR_NODISCARD WINPR_CIPHER_CTX*
591
winpr_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
453
{
594
453
  if (cipher == WINPR_CIPHER_ARC4_128)
595
0
  {
596
0
    WLog_ERR(TAG,
597
0
             "WINPR_CIPHER_ARC4_128 (RC4) cipher not supported, use winpr_RC4_new instead");
598
0
    return nullptr;
599
0
  }
600
601
453
  WINPR_CIPHER_CTX* ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
602
453
  if (!ctx)
603
0
    return nullptr;
604
605
453
  ctx->cipher = cipher;
606
453
  ctx->op = op;
607
608
453
#if defined(WITH_OPENSSL)
609
453
  const EVP_CIPHER* evp = winpr_openssl_get_evp_cipher(cipher);
610
453
  if (!evp)
611
0
    goto fail;
612
613
453
  ctx->ectx = EVP_CIPHER_CTX_new();
614
453
  if (!ctx->ectx)
615
0
    goto fail;
616
617
453
  {
618
453
    const int operation = (op == WINPR_ENCRYPT) ? 1 : 0;
619
453
    if (EVP_CipherInit_ex(ctx->ectx, evp, nullptr, key, iv, operation) != 1)
620
0
      goto fail;
621
453
  }
622
623
453
  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
453
  return ctx;
666
667
0
fail:
668
0
  winpr_Cipher_Free(ctx);
669
0
  return nullptr;
670
453
}
671
672
BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled)
673
0
{
674
0
  WINPR_ASSERT(ctx);
675
676
0
#if defined(WITH_OPENSSL)
677
0
  if (!ctx->ectx)
678
0
    return FALSE;
679
0
  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
0
  return TRUE;
688
0
}
689
690
BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const void* input, size_t ilen, void* output,
691
                         size_t* olen)
692
453
{
693
453
  WINPR_ASSERT(ctx);
694
453
  WINPR_ASSERT(olen);
695
696
453
#if defined(WITH_OPENSSL)
697
453
  int outl = (int)*olen;
698
699
453
  if (ilen > INT_MAX)
700
0
  {
701
0
    WLog_ERR(TAG, "input length %" PRIuz " > %d, abort", ilen, INT_MAX);
702
0
    return FALSE;
703
0
  }
704
705
453
  WINPR_ASSERT(ctx->ectx);
706
453
  if (EVP_CipherUpdate(ctx->ectx, output, &outl, input, (int)ilen) == 1)
707
453
  {
708
453
    *olen = (size_t)outl;
709
453
    return TRUE;
710
453
  }
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
0
  WLog_ERR(TAG, "Failed to update the data");
720
0
  return FALSE;
721
453
}
722
723
BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, void* output, size_t* olen)
724
453
{
725
453
  WINPR_ASSERT(ctx);
726
727
453
#if defined(WITH_OPENSSL)
728
453
  int outl = (int)*olen;
729
730
453
  WINPR_ASSERT(ctx->ectx);
731
453
  if (EVP_CipherFinal_ex(ctx->ectx, output, &outl) == 1)
732
252
  {
733
252
    *olen = (size_t)outl;
734
252
    return TRUE;
735
252
  }
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
201
  return FALSE;
746
453
}
747
748
void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
749
453
{
750
453
  if (!ctx)
751
0
    return;
752
753
453
#if defined(WITH_OPENSSL)
754
453
  if (ctx->ectx)
755
453
    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
453
  free(ctx);
765
453
}
766
767
/**
768
 * Key Generation
769
 */
770
771
int 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
0
{
774
  /**
775
   * Key and IV generation compatible with OpenSSL EVP_BytesToKey():
776
   * https://www.openssl.org/docs/manmaster/crypto/EVP_BytesToKey.html
777
   */
778
0
#if defined(WITH_OPENSSL)
779
0
  const EVP_MD* evp_md = nullptr;
780
0
  const EVP_CIPHER* evp_cipher = nullptr;
781
0
  evp_md = winpr_openssl_get_evp_md(md);
782
0
  evp_cipher = winpr_openssl_get_evp_cipher(WINPR_ASSERTING_INT_CAST(WINPR_CIPHER_TYPE, cipher));
783
0
  WINPR_ASSERT(datal <= INT_MAX);
784
0
  WINPR_ASSERT(count <= INT_MAX);
785
0
  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;
893
err:
894
  mbedtls_md_free(&ctx);
895
  SecureZeroMemory(md_buf, 64);
896
  return rv;
897
#else
898
  return 0;
899
#endif
900
0
}