Coverage Report

Created: 2026-01-09 06:43

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
245
{
80
245
  if (!key || (keylen == 0))
81
0
    return NULL;
82
83
245
  WINPR_RC4_CTX* ctx = (WINPR_RC4_CTX*)calloc(1, sizeof(WINPR_RC4_CTX));
84
245
  if (!ctx)
85
0
    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
245
  const EVP_CIPHER* evp = NULL;
94
95
245
  if (keylen > INT_MAX)
96
0
    goto fail;
97
98
245
  ctx->ctx = EVP_CIPHER_CTX_new();
99
245
  if (!ctx->ctx)
100
0
    goto fail;
101
102
245
  evp = EVP_rc4();
103
104
245
  if (!evp)
105
0
    goto fail;
106
107
245
  EVP_CIPHER_CTX_reset(ctx->ctx);
108
245
  if (EVP_EncryptInit_ex(ctx->ctx, evp, NULL, NULL, NULL) != 1)
109
0
    goto fail;
110
111
  /* EVP_CIPH_FLAG_NON_FIPS_ALLOW does not exist before openssl 1.0.1 */
112
245
#if !(OPENSSL_VERSION_NUMBER < 0x10001000L)
113
114
245
  if (override_fips == TRUE)
115
0
    EVP_CIPHER_CTX_set_flags(ctx->ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
116
117
245
#endif
118
245
  EVP_CIPHER_CTX_set_key_length(ctx->ctx, (int)keylen);
119
245
  if (EVP_EncryptInit_ex(ctx->ctx, NULL, NULL, key, NULL) != 1)
120
0
    goto fail;
121
245
#endif
122
245
  return ctx;
123
124
0
fail:
125
0
  WINPR_PRAGMA_DIAG_PUSH
126
0
  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
127
128
0
  winpr_RC4_Free(ctx);
129
0
  WINPR_PRAGMA_DIAG_POP
130
0
  return NULL;
131
245
}
132
133
WINPR_RC4_CTX* winpr_RC4_New_Allow_FIPS(const void* key, size_t keylen)
134
0
{
135
0
  return winpr_RC4_New_Internal(key, keylen, TRUE);
136
0
}
137
138
WINPR_RC4_CTX* winpr_RC4_New(const void* key, size_t keylen)
139
245
{
140
245
  return winpr_RC4_New_Internal(key, keylen, FALSE);
141
245
}
142
143
BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const void* input, void* output)
144
245
{
145
245
  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
245
  WINPR_ASSERT(ctx->ctx);
151
245
  int outputLength = 0;
152
245
  if (length > INT_MAX)
153
0
    return FALSE;
154
155
245
  WINPR_ASSERT(ctx);
156
245
  if (EVP_CipherUpdate(ctx->ctx, output, &outputLength, input, (int)length) != 1)
157
0
    return FALSE;
158
245
  return TRUE;
159
0
#endif
160
0
  return FALSE;
161
245
}
162
163
void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
164
324
{
165
324
  if (!ctx)
166
79
    return;
167
168
#if defined(WITH_INTERNAL_RC4)
169
  winpr_int_rc4_free(ctx->ictx);
170
#elif defined(WITH_OPENSSL)
171
245
  EVP_CIPHER_CTX_free(ctx->ctx);
172
245
#endif
173
245
  free(ctx);
174
245
}
175
176
/**
177
 * Generic Cipher API
178
 */
179
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
0
{
247
0
  const WINPR_CIPHER_TYPE* cipher = a;
248
0
  const struct cipher_map* map = b;
249
0
  if (*cipher == map->md)
250
0
    return 0;
251
0
  return *cipher > map->md ? 1 : -1;
252
0
}
253
254
const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE md)
255
0
{
256
0
  WINPR_CIPHER_TYPE lc = md;
257
0
  const struct cipher_map* ret = bsearch(&lc, s_cipher_map, ARRAYSIZE(s_cipher_map),
258
0
                                         sizeof(struct cipher_map), cipher_compare);
259
0
  if (!ret)
260
0
    return "unknown";
261
0
  return ret->name;
262
0
}
263
264
static int cipher_string_compare(const void* a, const void* b)
265
0
{
266
0
  const char* cipher = a;
267
0
  const struct cipher_map* map = b;
268
0
  return strcmp(cipher, map->name);
269
0
}
270
271
WINPR_CIPHER_TYPE winpr_cipher_type_from_string(const char* name)
272
0
{
273
0
  const struct cipher_map* ret = bsearch(name, s_cipher_map, ARRAYSIZE(s_cipher_map),
274
0
                                         sizeof(struct cipher_map), cipher_string_compare);
275
0
  if (!ret)
276
0
    return WINPR_CIPHER_NONE;
277
0
  return ret->md;
278
0
}
279
280
#if defined(WITH_OPENSSL)
281
static const EVP_CIPHER* winpr_openssl_get_evp_cipher(WINPR_CIPHER_TYPE cipher)
282
470
{
283
470
  const EVP_CIPHER* evp = NULL;
284
285
470
  switch (cipher)
286
470
  {
287
0
    case WINPR_CIPHER_NULL:
288
0
      evp = EVP_enc_null();
289
0
      break;
290
291
0
    case WINPR_CIPHER_AES_128_ECB:
292
0
      evp = EVP_get_cipherbyname("aes-128-ecb");
293
0
      break;
294
295
0
    case WINPR_CIPHER_AES_192_ECB:
296
0
      evp = EVP_get_cipherbyname("aes-192-ecb");
297
0
      break;
298
299
0
    case WINPR_CIPHER_AES_256_ECB:
300
0
      evp = EVP_get_cipherbyname("aes-256-ecb");
301
0
      break;
302
303
470
    case WINPR_CIPHER_AES_128_CBC:
304
470
      evp = EVP_get_cipherbyname("aes-128-cbc");
305
470
      break;
306
307
0
    case WINPR_CIPHER_AES_192_CBC:
308
0
      evp = EVP_get_cipherbyname("aes-192-cbc");
309
0
      break;
310
311
0
    case WINPR_CIPHER_AES_256_CBC:
312
0
      evp = EVP_get_cipherbyname("aes-256-cbc");
313
0
      break;
314
315
0
    case WINPR_CIPHER_AES_128_CFB128:
316
0
      evp = EVP_get_cipherbyname("aes-128-cfb128");
317
0
      break;
318
319
0
    case WINPR_CIPHER_AES_192_CFB128:
320
0
      evp = EVP_get_cipherbyname("aes-192-cfb128");
321
0
      break;
322
323
0
    case WINPR_CIPHER_AES_256_CFB128:
324
0
      evp = EVP_get_cipherbyname("aes-256-cfb128");
325
0
      break;
326
327
0
    case WINPR_CIPHER_AES_128_CTR:
328
0
      evp = EVP_get_cipherbyname("aes-128-ctr");
329
0
      break;
330
331
0
    case WINPR_CIPHER_AES_192_CTR:
332
0
      evp = EVP_get_cipherbyname("aes-192-ctr");
333
0
      break;
334
335
0
    case WINPR_CIPHER_AES_256_CTR:
336
0
      evp = EVP_get_cipherbyname("aes-256-ctr");
337
0
      break;
338
339
0
    case WINPR_CIPHER_AES_128_GCM:
340
0
      evp = EVP_get_cipherbyname("aes-128-gcm");
341
0
      break;
342
343
0
    case WINPR_CIPHER_AES_192_GCM:
344
0
      evp = EVP_get_cipherbyname("aes-192-gcm");
345
0
      break;
346
347
0
    case WINPR_CIPHER_AES_256_GCM:
348
0
      evp = EVP_get_cipherbyname("aes-256-gcm");
349
0
      break;
350
351
0
    case WINPR_CIPHER_AES_128_CCM:
352
0
      evp = EVP_get_cipherbyname("aes-128-ccm");
353
0
      break;
354
355
0
    case WINPR_CIPHER_AES_192_CCM:
356
0
      evp = EVP_get_cipherbyname("aes-192-ccm");
357
0
      break;
358
359
0
    case WINPR_CIPHER_AES_256_CCM:
360
0
      evp = EVP_get_cipherbyname("aes-256-ccm");
361
0
      break;
362
363
0
    case WINPR_CIPHER_CAMELLIA_128_ECB:
364
0
      evp = EVP_get_cipherbyname("camellia-128-ecb");
365
0
      break;
366
367
0
    case WINPR_CIPHER_CAMELLIA_192_ECB:
368
0
      evp = EVP_get_cipherbyname("camellia-192-ecb");
369
0
      break;
370
371
0
    case WINPR_CIPHER_CAMELLIA_256_ECB:
372
0
      evp = EVP_get_cipherbyname("camellia-256-ecb");
373
0
      break;
374
375
0
    case WINPR_CIPHER_CAMELLIA_128_CBC:
376
0
      evp = EVP_get_cipherbyname("camellia-128-cbc");
377
0
      break;
378
379
0
    case WINPR_CIPHER_CAMELLIA_192_CBC:
380
0
      evp = EVP_get_cipherbyname("camellia-192-cbc");
381
0
      break;
382
383
0
    case WINPR_CIPHER_CAMELLIA_256_CBC:
384
0
      evp = EVP_get_cipherbyname("camellia-256-cbc");
385
0
      break;
386
387
0
    case WINPR_CIPHER_CAMELLIA_128_CFB128:
388
0
      evp = EVP_get_cipherbyname("camellia-128-cfb128");
389
0
      break;
390
391
0
    case WINPR_CIPHER_CAMELLIA_192_CFB128:
392
0
      evp = EVP_get_cipherbyname("camellia-192-cfb128");
393
0
      break;
394
395
0
    case WINPR_CIPHER_CAMELLIA_256_CFB128:
396
0
      evp = EVP_get_cipherbyname("camellia-256-cfb128");
397
0
      break;
398
399
0
    case WINPR_CIPHER_CAMELLIA_128_CTR:
400
0
      evp = EVP_get_cipherbyname("camellia-128-ctr");
401
0
      break;
402
403
0
    case WINPR_CIPHER_CAMELLIA_192_CTR:
404
0
      evp = EVP_get_cipherbyname("camellia-192-ctr");
405
0
      break;
406
407
0
    case WINPR_CIPHER_CAMELLIA_256_CTR:
408
0
      evp = EVP_get_cipherbyname("camellia-256-ctr");
409
0
      break;
410
411
0
    case WINPR_CIPHER_CAMELLIA_128_GCM:
412
0
      evp = EVP_get_cipherbyname("camellia-128-gcm");
413
0
      break;
414
415
0
    case WINPR_CIPHER_CAMELLIA_192_GCM:
416
0
      evp = EVP_get_cipherbyname("camellia-192-gcm");
417
0
      break;
418
419
0
    case WINPR_CIPHER_CAMELLIA_256_GCM:
420
0
      evp = EVP_get_cipherbyname("camellia-256-gcm");
421
0
      break;
422
423
0
    case WINPR_CIPHER_CAMELLIA_128_CCM:
424
0
      evp = EVP_get_cipherbyname("camellia-128-ccm");
425
0
      break;
426
427
0
    case WINPR_CIPHER_CAMELLIA_192_CCM:
428
0
      evp = EVP_get_cipherbyname("camellia-192-ccm");
429
0
      break;
430
431
0
    case WINPR_CIPHER_CAMELLIA_256_CCM:
432
0
      evp = EVP_get_cipherbyname("camellia-256-ccm");
433
0
      break;
434
435
0
    case WINPR_CIPHER_DES_ECB:
436
0
      evp = EVP_get_cipherbyname("des-ecb");
437
0
      break;
438
439
0
    case WINPR_CIPHER_DES_CBC:
440
0
      evp = EVP_get_cipherbyname("des-cbc");
441
0
      break;
442
443
0
    case WINPR_CIPHER_DES_EDE_ECB:
444
0
      evp = EVP_get_cipherbyname("des-ede-ecb");
445
0
      break;
446
447
0
    case WINPR_CIPHER_DES_EDE_CBC:
448
0
      evp = EVP_get_cipherbyname("des-ede-cbc");
449
0
      break;
450
451
0
    case WINPR_CIPHER_DES_EDE3_ECB:
452
0
      evp = EVP_get_cipherbyname("des-ede3-ecb");
453
0
      break;
454
455
0
    case WINPR_CIPHER_DES_EDE3_CBC:
456
0
      evp = EVP_get_cipherbyname("des-ede3-cbc");
457
0
      break;
458
459
0
    case WINPR_CIPHER_ARC4_128:
460
0
      evp = EVP_get_cipherbyname("rc4");
461
0
      break;
462
463
0
    case WINPR_CIPHER_BLOWFISH_ECB:
464
0
      evp = EVP_get_cipherbyname("blowfish-ecb");
465
0
      break;
466
467
0
    case WINPR_CIPHER_BLOWFISH_CBC:
468
0
      evp = EVP_get_cipherbyname("blowfish-cbc");
469
0
      break;
470
471
0
    case WINPR_CIPHER_BLOWFISH_CFB64:
472
0
      evp = EVP_get_cipherbyname("blowfish-cfb64");
473
0
      break;
474
475
0
    case WINPR_CIPHER_BLOWFISH_CTR:
476
0
      evp = EVP_get_cipherbyname("blowfish-ctr");
477
0
      break;
478
0
    default:
479
0
      break;
480
470
  }
481
482
470
  return evp;
483
470
}
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
#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
578
WINPR_CIPHER_CTX* winpr_Cipher_New(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op,
579
                                   const void* key, const void* iv)
580
0
{
581
0
  return winpr_Cipher_NewEx(cipher, op, key, 0, iv, 0);
582
0
}
583
#endif
584
585
WINPR_API WINPR_CIPHER_CTX* winpr_Cipher_NewEx(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op,
586
                                               const void* key, WINPR_ATTR_UNUSED size_t keylen,
587
                                               const void* iv, WINPR_ATTR_UNUSED size_t ivlen)
588
470
{
589
470
  if (cipher == WINPR_CIPHER_ARC4_128)
590
0
  {
591
0
    WLog_ERR(TAG,
592
0
             "WINPR_CIPHER_ARC4_128 (RC4) cipher not supported, use winpr_RC4_new instead");
593
0
    return NULL;
594
0
  }
595
596
470
  WINPR_CIPHER_CTX* ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
597
470
  if (!ctx)
598
0
    return NULL;
599
600
470
  ctx->cipher = cipher;
601
470
  ctx->op = op;
602
603
470
#if defined(WITH_OPENSSL)
604
470
  const EVP_CIPHER* evp = winpr_openssl_get_evp_cipher(cipher);
605
470
  if (!evp)
606
0
    goto fail;
607
608
470
  ctx->ectx = EVP_CIPHER_CTX_new();
609
470
  if (!ctx->ectx)
610
0
    goto fail;
611
612
470
  {
613
470
    const int operation = (op == WINPR_ENCRYPT) ? 1 : 0;
614
470
    if (EVP_CipherInit_ex(ctx->ectx, evp, NULL, key, iv, operation) != 1)
615
0
      goto fail;
616
470
  }
617
618
470
  EVP_CIPHER_CTX_set_padding(ctx->ectx, 0);
619
620
#elif defined(WITH_MBEDTLS)
621
  mbedtls_cipher_type_t cipher_type = winpr_mbedtls_get_cipher_type(cipher);
622
  const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(cipher_type);
623
624
  if (!cipher_info)
625
    goto fail;
626
627
  ctx->mctx = calloc(1, sizeof(mbedtls_cipher_context_t));
628
  if (!ctx->mctx)
629
    goto fail;
630
631
  const mbedtls_operation_t operation = (op == WINPR_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT;
632
  mbedtls_cipher_init(ctx->mctx);
633
634
  if (mbedtls_cipher_setup(ctx->mctx, cipher_info) != 0)
635
    goto fail;
636
637
  const int key_bitlen = mbedtls_cipher_get_key_bitlen(ctx->mctx);
638
639
  if (mbedtls_cipher_setkey(ctx->mctx, key, key_bitlen, operation) != 0)
640
    goto fail;
641
642
  if (mbedtls_cipher_set_padding_mode(ctx->mctx, MBEDTLS_PADDING_NONE) != 0)
643
    goto fail;
644
645
#endif
646
470
  return ctx;
647
648
0
fail:
649
0
  winpr_Cipher_Free(ctx);
650
0
  return NULL;
651
470
}
652
653
BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled)
654
0
{
655
0
  WINPR_ASSERT(ctx);
656
657
0
#if defined(WITH_OPENSSL)
658
0
  if (!ctx->ectx)
659
0
    return FALSE;
660
0
  EVP_CIPHER_CTX_set_padding(ctx->ectx, enabled);
661
#elif defined(WITH_MBEDTLS)
662
  mbedtls_cipher_padding_t option = enabled ? MBEDTLS_PADDING_PKCS7 : MBEDTLS_PADDING_NONE;
663
  if (mbedtls_cipher_set_padding_mode((mbedtls_cipher_context_t*)ctx, option) != 0)
664
    return FALSE;
665
#else
666
  return FALSE;
667
#endif
668
0
  return TRUE;
669
0
}
670
671
BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const void* input, size_t ilen, void* output,
672
                         size_t* olen)
673
470
{
674
470
  WINPR_ASSERT(ctx);
675
470
  WINPR_ASSERT(olen);
676
677
470
#if defined(WITH_OPENSSL)
678
470
  int outl = (int)*olen;
679
680
470
  if (ilen > INT_MAX)
681
0
  {
682
0
    WLog_ERR(TAG, "input length %" PRIuz " > %d, abort", ilen, INT_MAX);
683
0
    return FALSE;
684
0
  }
685
686
470
  WINPR_ASSERT(ctx->ectx);
687
470
  if (EVP_CipherUpdate(ctx->ectx, output, &outl, input, (int)ilen) == 1)
688
470
  {
689
470
    *olen = (size_t)outl;
690
470
    return TRUE;
691
470
  }
692
693
#elif defined(WITH_MBEDTLS)
694
  WINPR_ASSERT(ctx->mctx);
695
  if (mbedtls_cipher_update(ctx->mctx, input, ilen, output, olen) == 0)
696
    return TRUE;
697
698
#endif
699
700
0
  WLog_ERR(TAG, "Failed to update the data");
701
0
  return FALSE;
702
470
}
703
704
BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, void* output, size_t* olen)
705
470
{
706
470
  WINPR_ASSERT(ctx);
707
708
470
#if defined(WITH_OPENSSL)
709
470
  int outl = (int)*olen;
710
711
470
  WINPR_ASSERT(ctx->ectx);
712
470
  if (EVP_CipherFinal_ex(ctx->ectx, output, &outl) == 1)
713
260
  {
714
260
    *olen = (size_t)outl;
715
260
    return TRUE;
716
260
  }
717
718
#elif defined(WITH_MBEDTLS)
719
720
  WINPR_ASSERT(ctx->mctx);
721
  if (mbedtls_cipher_finish(ctx->mctx, output, olen) == 0)
722
    return TRUE;
723
724
#endif
725
726
210
  return FALSE;
727
470
}
728
729
void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
730
470
{
731
470
  if (!ctx)
732
0
    return;
733
734
470
#if defined(WITH_OPENSSL)
735
470
  if (ctx->ectx)
736
470
    EVP_CIPHER_CTX_free(ctx->ectx);
737
#elif defined(WITH_MBEDTLS)
738
  if (ctx->mctx)
739
  {
740
    mbedtls_cipher_free(ctx->mctx);
741
    free(ctx->mctx);
742
  }
743
#endif
744
745
470
  free(ctx);
746
470
}
747
748
/**
749
 * Key Generation
750
 */
751
752
int winpr_Cipher_BytesToKey(int cipher, WINPR_MD_TYPE md, const void* salt, const void* data,
753
                            size_t datal, size_t count, void* key, void* iv)
754
0
{
755
  /**
756
   * Key and IV generation compatible with OpenSSL EVP_BytesToKey():
757
   * https://www.openssl.org/docs/manmaster/crypto/EVP_BytesToKey.html
758
   */
759
0
#if defined(WITH_OPENSSL)
760
0
  const EVP_MD* evp_md = NULL;
761
0
  const EVP_CIPHER* evp_cipher = NULL;
762
0
  evp_md = winpr_openssl_get_evp_md(md);
763
0
  evp_cipher = winpr_openssl_get_evp_cipher(WINPR_ASSERTING_INT_CAST(WINPR_CIPHER_TYPE, cipher));
764
0
  WINPR_ASSERT(datal <= INT_MAX);
765
0
  WINPR_ASSERT(count <= INT_MAX);
766
0
  return EVP_BytesToKey(evp_cipher, evp_md, salt, data, (int)datal, (int)count, key, iv);
767
#elif defined(WITH_MBEDTLS)
768
  int rv = 0;
769
  BYTE md_buf[64];
770
  int niv, nkey, addmd = 0;
771
  unsigned int mds = 0;
772
  mbedtls_md_context_t ctx;
773
  const mbedtls_md_info_t* md_info;
774
  mbedtls_cipher_type_t cipher_type;
775
  const mbedtls_cipher_info_t* cipher_info;
776
  mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
777
  md_info = mbedtls_md_info_from_type(md_type);
778
  cipher_type = winpr_mbedtls_get_cipher_type(cipher);
779
  cipher_info = mbedtls_cipher_info_from_type(cipher_type);
780
  nkey = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
781
  niv = mbedtls_cipher_info_get_iv_size(cipher_info);
782
783
  if ((nkey > 64) || (niv > 64))
784
    return 0;
785
786
  if (!data)
787
    return nkey;
788
789
  mbedtls_md_init(&ctx);
790
791
  if (mbedtls_md_setup(&ctx, md_info, 0) != 0)
792
    goto err;
793
794
  while (1)
795
  {
796
    if (mbedtls_md_starts(&ctx) != 0)
797
      goto err;
798
799
    if (addmd++)
800
    {
801
      if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
802
        goto err;
803
    }
804
805
    if (mbedtls_md_update(&ctx, data, datal) != 0)
806
      goto err;
807
808
    if (salt)
809
    {
810
      if (mbedtls_md_update(&ctx, salt, 8) != 0)
811
        goto err;
812
    }
813
814
    if (mbedtls_md_finish(&ctx, md_buf) != 0)
815
      goto err;
816
817
    mds = mbedtls_md_get_size(md_info);
818
819
    for (unsigned int i = 1; i < (unsigned int)count; i++)
820
    {
821
      if (mbedtls_md_starts(&ctx) != 0)
822
        goto err;
823
824
      if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
825
        goto err;
826
827
      if (mbedtls_md_finish(&ctx, md_buf) != 0)
828
        goto err;
829
    }
830
831
    unsigned int i = 0;
832
833
    if (nkey)
834
    {
835
      while (1)
836
      {
837
        if (nkey == 0)
838
          break;
839
840
        if (i == mds)
841
          break;
842
843
        if (key)
844
          *(BYTE*)(key++) = md_buf[i];
845
846
        nkey--;
847
        i++;
848
      }
849
    }
850
851
    if (niv && (i != mds))
852
    {
853
      while (1)
854
      {
855
        if (niv == 0)
856
          break;
857
858
        if (i == mds)
859
          break;
860
861
        if (iv)
862
          *(BYTE*)(iv++) = md_buf[i];
863
864
        niv--;
865
        i++;
866
      }
867
    }
868
869
    if ((nkey == 0) && (niv == 0))
870
      break;
871
  }
872
873
  rv = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
874
err:
875
  mbedtls_md_free(&ctx);
876
  SecureZeroMemory(md_buf, 64);
877
  return rv;
878
#else
879
  return 0;
880
#endif
881
0
}