Coverage Report

Created: 2025-07-01 06:46

/src/FreeRDP/winpr/libwinpr/crypto/cipher.c
Line
Count
Source (jump to first uncovered line)
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
0
{
80
0
  if (!key || (keylen == 0))
81
0
    return NULL;
82
83
0
  WINPR_RC4_CTX* ctx = (WINPR_RC4_CTX*)calloc(1, sizeof(WINPR_RC4_CTX));
84
0
  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
0
  const EVP_CIPHER* evp = NULL;
94
95
0
  if (keylen > INT_MAX)
96
0
    goto fail;
97
98
0
  ctx->ctx = EVP_CIPHER_CTX_new();
99
0
  if (!ctx->ctx)
100
0
    goto fail;
101
102
0
  evp = EVP_rc4();
103
104
0
  if (!evp)
105
0
    goto fail;
106
107
0
  EVP_CIPHER_CTX_reset(ctx->ctx);
108
0
  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
0
#if !(OPENSSL_VERSION_NUMBER < 0x10001000L)
113
114
0
  if (override_fips == TRUE)
115
0
    EVP_CIPHER_CTX_set_flags(ctx->ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
116
117
0
#endif
118
0
  EVP_CIPHER_CTX_set_key_length(ctx->ctx, (int)keylen);
119
0
  if (EVP_EncryptInit_ex(ctx->ctx, NULL, NULL, key, NULL) != 1)
120
0
    goto fail;
121
0
#endif
122
0
  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
0
}
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
0
{
140
0
  return winpr_RC4_New_Internal(key, keylen, FALSE);
141
0
}
142
143
BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const void* input, void* output)
144
0
{
145
0
  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
0
  WINPR_ASSERT(ctx->ctx);
151
0
  int outputLength = 0;
152
0
  if (length > INT_MAX)
153
0
    return FALSE;
154
155
0
  WINPR_ASSERT(ctx);
156
0
  if (EVP_CipherUpdate(ctx->ctx, output, &outputLength, input, (int)length) != 1)
157
0
    return FALSE;
158
0
  return TRUE;
159
0
#endif
160
0
  return FALSE;
161
0
}
162
163
void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
164
0
{
165
0
  if (!ctx)
166
0
    return;
167
168
#if defined(WITH_INTERNAL_RC4)
169
  winpr_int_rc4_free(ctx->ictx);
170
#elif defined(WITH_OPENSSL)
171
0
  EVP_CIPHER_CTX_free(ctx->ctx);
172
0
#endif
173
0
  free(ctx);
174
0
}
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
0
{
283
0
  const EVP_CIPHER* evp = NULL;
284
285
0
  switch (cipher)
286
0
  {
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
0
    case WINPR_CIPHER_AES_128_CBC:
304
0
      evp = EVP_get_cipherbyname("aes-128-cbc");
305
0
      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
0
  }
481
482
0
  return evp;
483
0
}
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
0
{
589
0
  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
0
  WINPR_CIPHER_CTX* ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
597
0
  if (!ctx)
598
0
    return NULL;
599
600
0
  ctx->cipher = cipher;
601
0
  ctx->op = op;
602
603
0
#if defined(WITH_OPENSSL)
604
0
  const EVP_CIPHER* evp = winpr_openssl_get_evp_cipher(cipher);
605
0
  if (!evp)
606
0
    goto fail;
607
608
0
  ctx->ectx = EVP_CIPHER_CTX_new();
609
0
  if (!ctx->ectx)
610
0
    goto fail;
611
612
0
  const int operation = (op == WINPR_ENCRYPT) ? 1 : 0;
613
614
0
  if (EVP_CipherInit_ex(ctx->ectx, evp, NULL, key, iv, operation) != 1)
615
0
    goto fail;
616
617
0
  EVP_CIPHER_CTX_set_padding(ctx->ectx, 0);
618
619
#elif defined(WITH_MBEDTLS)
620
  mbedtls_cipher_type_t cipher_type = winpr_mbedtls_get_cipher_type(cipher);
621
  const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(cipher_type);
622
623
  if (!cipher_info)
624
    goto fail;
625
626
  ctx->mctx = calloc(1, sizeof(mbedtls_cipher_context_t));
627
  if (!ctx->mctx)
628
    goto fail;
629
630
  const mbedtls_operation_t operation = (op == WINPR_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT;
631
  mbedtls_cipher_init(ctx->mctx);
632
633
  if (mbedtls_cipher_setup(ctx->mctx, cipher_info) != 0)
634
    goto fail;
635
636
  const int key_bitlen = mbedtls_cipher_get_key_bitlen(ctx->mctx);
637
638
  if (mbedtls_cipher_setkey(ctx->mctx, key, key_bitlen, operation) != 0)
639
    goto fail;
640
641
  if (mbedtls_cipher_set_padding_mode(ctx->mctx, MBEDTLS_PADDING_NONE) != 0)
642
    goto fail;
643
644
#endif
645
0
  return ctx;
646
647
0
fail:
648
0
  winpr_Cipher_Free(ctx);
649
0
  return NULL;
650
0
}
651
652
BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled)
653
0
{
654
0
  WINPR_ASSERT(ctx);
655
656
0
#if defined(WITH_OPENSSL)
657
0
  if (!ctx->ectx)
658
0
    return FALSE;
659
0
  EVP_CIPHER_CTX_set_padding(ctx->ectx, enabled);
660
#elif defined(WITH_MBEDTLS)
661
  mbedtls_cipher_padding_t option = enabled ? MBEDTLS_PADDING_PKCS7 : MBEDTLS_PADDING_NONE;
662
  if (mbedtls_cipher_set_padding_mode((mbedtls_cipher_context_t*)ctx, option) != 0)
663
    return FALSE;
664
#else
665
  return FALSE;
666
#endif
667
0
  return TRUE;
668
0
}
669
670
BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const void* input, size_t ilen, void* output,
671
                         size_t* olen)
672
0
{
673
0
  WINPR_ASSERT(ctx);
674
0
  WINPR_ASSERT(olen);
675
676
0
#if defined(WITH_OPENSSL)
677
0
  int outl = (int)*olen;
678
679
0
  if (ilen > INT_MAX)
680
0
  {
681
0
    WLog_ERR(TAG, "input length %" PRIuz " > %d, abort", ilen, INT_MAX);
682
0
    return FALSE;
683
0
  }
684
685
0
  WINPR_ASSERT(ctx->ectx);
686
0
  if (EVP_CipherUpdate(ctx->ectx, output, &outl, input, (int)ilen) == 1)
687
0
  {
688
0
    *olen = (size_t)outl;
689
0
    return TRUE;
690
0
  }
691
692
#elif defined(WITH_MBEDTLS)
693
  WINPR_ASSERT(ctx->mctx);
694
  if (mbedtls_cipher_update(ctx->mctx, input, ilen, output, olen) == 0)
695
    return TRUE;
696
697
#endif
698
699
0
  WLog_ERR(TAG, "Failed to update the data");
700
0
  return FALSE;
701
0
}
702
703
BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, void* output, size_t* olen)
704
0
{
705
0
  WINPR_ASSERT(ctx);
706
707
0
#if defined(WITH_OPENSSL)
708
0
  int outl = (int)*olen;
709
710
0
  WINPR_ASSERT(ctx->ectx);
711
0
  if (EVP_CipherFinal_ex(ctx->ectx, output, &outl) == 1)
712
0
  {
713
0
    *olen = (size_t)outl;
714
0
    return TRUE;
715
0
  }
716
717
#elif defined(WITH_MBEDTLS)
718
719
  WINPR_ASSERT(ctx->mctx);
720
  if (mbedtls_cipher_finish(ctx->mctx, output, olen) == 0)
721
    return TRUE;
722
723
#endif
724
725
0
  return FALSE;
726
0
}
727
728
void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
729
0
{
730
0
  if (!ctx)
731
0
    return;
732
733
0
#if defined(WITH_OPENSSL)
734
0
  if (ctx->ectx)
735
0
    EVP_CIPHER_CTX_free(ctx->ectx);
736
#elif defined(WITH_MBEDTLS)
737
  if (ctx->mctx)
738
  {
739
    mbedtls_cipher_free(ctx->mctx);
740
    free(ctx->mctx);
741
  }
742
#endif
743
744
0
  free(ctx);
745
0
}
746
747
/**
748
 * Key Generation
749
 */
750
751
int winpr_Cipher_BytesToKey(int cipher, WINPR_MD_TYPE md, const void* salt, const void* data,
752
                            size_t datal, size_t count, void* key, void* iv)
753
0
{
754
  /**
755
   * Key and IV generation compatible with OpenSSL EVP_BytesToKey():
756
   * https://www.openssl.org/docs/manmaster/crypto/EVP_BytesToKey.html
757
   */
758
0
#if defined(WITH_OPENSSL)
759
0
  const EVP_MD* evp_md = NULL;
760
0
  const EVP_CIPHER* evp_cipher = NULL;
761
0
  evp_md = winpr_openssl_get_evp_md(md);
762
0
  evp_cipher = winpr_openssl_get_evp_cipher(WINPR_ASSERTING_INT_CAST(WINPR_CIPHER_TYPE, cipher));
763
0
  WINPR_ASSERT(datal <= INT_MAX);
764
0
  WINPR_ASSERT(count <= INT_MAX);
765
0
  return EVP_BytesToKey(evp_cipher, evp_md, salt, data, (int)datal, (int)count, key, iv);
766
#elif defined(WITH_MBEDTLS)
767
  int rv = 0;
768
  BYTE md_buf[64];
769
  int niv, nkey, addmd = 0;
770
  unsigned int mds = 0;
771
  mbedtls_md_context_t ctx;
772
  const mbedtls_md_info_t* md_info;
773
  mbedtls_cipher_type_t cipher_type;
774
  const mbedtls_cipher_info_t* cipher_info;
775
  mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
776
  md_info = mbedtls_md_info_from_type(md_type);
777
  cipher_type = winpr_mbedtls_get_cipher_type(cipher);
778
  cipher_info = mbedtls_cipher_info_from_type(cipher_type);
779
  nkey = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
780
  niv = mbedtls_cipher_info_get_iv_size(cipher_info);
781
782
  if ((nkey > 64) || (niv > 64))
783
    return 0;
784
785
  if (!data)
786
    return nkey;
787
788
  mbedtls_md_init(&ctx);
789
790
  if (mbedtls_md_setup(&ctx, md_info, 0) != 0)
791
    goto err;
792
793
  while (1)
794
  {
795
    if (mbedtls_md_starts(&ctx) != 0)
796
      goto err;
797
798
    if (addmd++)
799
    {
800
      if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
801
        goto err;
802
    }
803
804
    if (mbedtls_md_update(&ctx, data, datal) != 0)
805
      goto err;
806
807
    if (salt)
808
    {
809
      if (mbedtls_md_update(&ctx, salt, 8) != 0)
810
        goto err;
811
    }
812
813
    if (mbedtls_md_finish(&ctx, md_buf) != 0)
814
      goto err;
815
816
    mds = mbedtls_md_get_size(md_info);
817
818
    for (unsigned int i = 1; i < (unsigned int)count; i++)
819
    {
820
      if (mbedtls_md_starts(&ctx) != 0)
821
        goto err;
822
823
      if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
824
        goto err;
825
826
      if (mbedtls_md_finish(&ctx, md_buf) != 0)
827
        goto err;
828
    }
829
830
    unsigned int i = 0;
831
832
    if (nkey)
833
    {
834
      while (1)
835
      {
836
        if (nkey == 0)
837
          break;
838
839
        if (i == mds)
840
          break;
841
842
        if (key)
843
          *(BYTE*)(key++) = md_buf[i];
844
845
        nkey--;
846
        i++;
847
      }
848
    }
849
850
    if (niv && (i != mds))
851
    {
852
      while (1)
853
      {
854
        if (niv == 0)
855
          break;
856
857
        if (i == mds)
858
          break;
859
860
        if (iv)
861
          *(BYTE*)(iv++) = md_buf[i];
862
863
        niv--;
864
        i++;
865
      }
866
    }
867
868
    if ((nkey == 0) && (niv == 0))
869
      break;
870
  }
871
872
  rv = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
873
err:
874
  mbedtls_md_free(&ctx);
875
  SecureZeroMemory(md_buf, 64);
876
  return rv;
877
#else
878
  return 0;
879
#endif
880
0
}