Coverage Report

Created: 2026-03-04 06:13

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