Coverage Report

Created: 2026-05-30 06:41

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
94
237
  if (keylen > INT_MAX)
95
0
    goto fail;
96
97
237
  ctx->ctx = EVP_CIPHER_CTX_new();
98
237
  if (!ctx->ctx)
99
0
    goto fail;
100
101
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
102
  EVP_CIPHER* evp = EVP_CIPHER_fetch(NULL, "RC4", override_fips ? "fips=no" : NULL);
103
#else
104
237
  const EVP_CIPHER* evp = EVP_rc4();
105
237
#endif
106
107
237
  if (!evp)
108
0
    goto fail;
109
110
237
  EVP_CIPHER_CTX_reset(ctx->ctx);
111
237
  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
237
  EVP_CIPHER_CTX_set_key_length(ctx->ctx, (int)keylen);
126
237
  if (EVP_EncryptInit_ex(ctx->ctx, nullptr, nullptr, key, nullptr) != 1)
127
0
    goto fail;
128
237
#endif
129
237
  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
237
}
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
237
{
147
237
  return winpr_RC4_New_Internal(key, keylen, FALSE);
148
237
}
149
150
BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const void* input, void* output)
151
237
{
152
237
  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
237
  WINPR_ASSERT(ctx->ctx);
158
237
  int outputLength = 0;
159
237
  if (length > INT_MAX)
160
0
    return FALSE;
161
162
237
  WINPR_ASSERT(ctx);
163
237
  return EVP_CipherUpdate(ctx->ctx, output, &outputLength, input, (int)length) == 1;
164
0
#endif
165
0
  return FALSE;
166
237
}
167
168
void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
169
317
{
170
317
  if (!ctx)
171
80
    return;
172
173
#if defined(WITH_INTERNAL_RC4)
174
  winpr_int_rc4_free(ctx->ictx);
175
#elif defined(WITH_OPENSSL)
176
237
  EVP_CIPHER_CTX_free(ctx->ctx);
177
237
#endif
178
237
  free(ctx);
179
237
}
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
480
{
288
480
  const EVP_CIPHER* evp = nullptr;
289
290
480
  switch (cipher)
291
480
  {
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
480
    case WINPR_CIPHER_AES_128_CBC:
309
480
      evp = EVP_get_cipherbyname("aes-128-cbc");
310
480
      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
480
  }
486
487
480
  return evp;
488
480
}
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
480
{
594
480
  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
480
  WINPR_CIPHER_CTX* ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
602
480
  if (!ctx)
603
0
    return nullptr;
604
605
480
  ctx->cipher = cipher;
606
480
  ctx->op = op;
607
608
480
#if defined(WITH_OPENSSL)
609
480
  const EVP_CIPHER* evp = winpr_openssl_get_evp_cipher(cipher);
610
480
  if (!evp)
611
0
    goto fail;
612
613
480
  ctx->ectx = EVP_CIPHER_CTX_new();
614
480
  if (!ctx->ectx)
615
0
    goto fail;
616
617
480
  {
618
480
    const int operation = (op == WINPR_ENCRYPT) ? 1 : 0;
619
480
    if (EVP_CipherInit_ex(ctx->ectx, evp, nullptr, key, iv, operation) != 1)
620
0
      goto fail;
621
480
  }
622
623
480
  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 (mbedtls_cipher_set_padding_mode(ctx->mctx, MBEDTLS_PADDING_NONE) != 0)
648
    goto fail;
649
650
#endif
651
480
  return ctx;
652
653
0
fail:
654
0
  winpr_Cipher_Free(ctx);
655
0
  return nullptr;
656
480
}
657
658
BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled)
659
0
{
660
0
  WINPR_ASSERT(ctx);
661
662
0
#if defined(WITH_OPENSSL)
663
0
  if (!ctx->ectx)
664
0
    return FALSE;
665
0
  EVP_CIPHER_CTX_set_padding(ctx->ectx, enabled);
666
#elif defined(WITH_MBEDTLS)
667
  mbedtls_cipher_padding_t option = enabled ? MBEDTLS_PADDING_PKCS7 : MBEDTLS_PADDING_NONE;
668
  if (mbedtls_cipher_set_padding_mode((mbedtls_cipher_context_t*)ctx, option) != 0)
669
    return FALSE;
670
#else
671
  return FALSE;
672
#endif
673
0
  return TRUE;
674
0
}
675
676
BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const void* input, size_t ilen, void* output,
677
                         size_t* olen)
678
480
{
679
480
  WINPR_ASSERT(ctx);
680
480
  WINPR_ASSERT(olen);
681
682
480
#if defined(WITH_OPENSSL)
683
480
  int outl = (int)*olen;
684
685
480
  if (ilen > INT_MAX)
686
0
  {
687
0
    WLog_ERR(TAG, "input length %" PRIuz " > %d, abort", ilen, INT_MAX);
688
0
    return FALSE;
689
0
  }
690
691
480
  WINPR_ASSERT(ctx->ectx);
692
480
  if (EVP_CipherUpdate(ctx->ectx, output, &outl, input, (int)ilen) == 1)
693
480
  {
694
480
    *olen = (size_t)outl;
695
480
    return TRUE;
696
480
  }
697
698
#elif defined(WITH_MBEDTLS)
699
  WINPR_ASSERT(ctx->mctx);
700
  if (mbedtls_cipher_update(ctx->mctx, input, ilen, output, olen) == 0)
701
    return TRUE;
702
703
#endif
704
705
0
  WLog_ERR(TAG, "Failed to update the data");
706
0
  return FALSE;
707
480
}
708
709
BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, void* output, size_t* olen)
710
480
{
711
480
  WINPR_ASSERT(ctx);
712
713
480
#if defined(WITH_OPENSSL)
714
480
  int outl = (int)*olen;
715
716
480
  WINPR_ASSERT(ctx->ectx);
717
480
  if (EVP_CipherFinal_ex(ctx->ectx, output, &outl) == 1)
718
282
  {
719
282
    *olen = (size_t)outl;
720
282
    return TRUE;
721
282
  }
722
723
#elif defined(WITH_MBEDTLS)
724
725
  WINPR_ASSERT(ctx->mctx);
726
  if (mbedtls_cipher_finish(ctx->mctx, output, olen) == 0)
727
    return TRUE;
728
729
#endif
730
731
198
  return FALSE;
732
480
}
733
734
void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
735
480
{
736
480
  if (!ctx)
737
0
    return;
738
739
480
#if defined(WITH_OPENSSL)
740
480
  if (ctx->ectx)
741
480
    EVP_CIPHER_CTX_free(ctx->ectx);
742
#elif defined(WITH_MBEDTLS)
743
  if (ctx->mctx)
744
  {
745
    mbedtls_cipher_free(ctx->mctx);
746
    free(ctx->mctx);
747
  }
748
#endif
749
750
480
  free(ctx);
751
480
}
752
753
/**
754
 * Key Generation
755
 */
756
757
int winpr_Cipher_BytesToKey(int cipher, WINPR_MD_TYPE md, const void* salt, const void* data,
758
                            size_t datal, size_t count, void* key, void* iv)
759
0
{
760
  /**
761
   * Key and IV generation compatible with OpenSSL EVP_BytesToKey():
762
   * https://www.openssl.org/docs/manmaster/crypto/EVP_BytesToKey.html
763
   */
764
0
#if defined(WITH_OPENSSL)
765
0
  const EVP_MD* evp_md = nullptr;
766
0
  const EVP_CIPHER* evp_cipher = nullptr;
767
0
  evp_md = winpr_openssl_get_evp_md(md);
768
0
  evp_cipher = winpr_openssl_get_evp_cipher(WINPR_ASSERTING_INT_CAST(WINPR_CIPHER_TYPE, cipher));
769
0
  WINPR_ASSERT(datal <= INT_MAX);
770
0
  WINPR_ASSERT(count <= INT_MAX);
771
0
  return EVP_BytesToKey(evp_cipher, evp_md, salt, data, (int)datal, (int)count, key, iv);
772
#elif defined(WITH_MBEDTLS)
773
  int rv = 0;
774
  BYTE md_buf[64];
775
  int niv, nkey, addmd = 0;
776
  unsigned int mds = 0;
777
  mbedtls_md_context_t ctx;
778
  const mbedtls_md_info_t* md_info;
779
  mbedtls_cipher_type_t cipher_type;
780
  const mbedtls_cipher_info_t* cipher_info;
781
  mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
782
  md_info = mbedtls_md_info_from_type(md_type);
783
  cipher_type = winpr_mbedtls_get_cipher_type(cipher);
784
  cipher_info = mbedtls_cipher_info_from_type(cipher_type);
785
  nkey = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
786
  niv = mbedtls_cipher_info_get_iv_size(cipher_info);
787
788
  if ((nkey > 64) || (niv > 64))
789
    return 0;
790
791
  if (!data)
792
    return nkey;
793
794
  mbedtls_md_init(&ctx);
795
796
  if (mbedtls_md_setup(&ctx, md_info, 0) != 0)
797
    goto err;
798
799
  while (1)
800
  {
801
    if (mbedtls_md_starts(&ctx) != 0)
802
      goto err;
803
804
    if (addmd++)
805
    {
806
      if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
807
        goto err;
808
    }
809
810
    if (mbedtls_md_update(&ctx, data, datal) != 0)
811
      goto err;
812
813
    if (salt)
814
    {
815
      if (mbedtls_md_update(&ctx, salt, 8) != 0)
816
        goto err;
817
    }
818
819
    if (mbedtls_md_finish(&ctx, md_buf) != 0)
820
      goto err;
821
822
    mds = mbedtls_md_get_size(md_info);
823
824
    for (unsigned int i = 1; i < (unsigned int)count; i++)
825
    {
826
      if (mbedtls_md_starts(&ctx) != 0)
827
        goto err;
828
829
      if (mbedtls_md_update(&ctx, md_buf, mds) != 0)
830
        goto err;
831
832
      if (mbedtls_md_finish(&ctx, md_buf) != 0)
833
        goto err;
834
    }
835
836
    unsigned int i = 0;
837
838
    if (nkey)
839
    {
840
      while (1)
841
      {
842
        if (nkey == 0)
843
          break;
844
845
        if (i == mds)
846
          break;
847
848
        if (key)
849
          *(BYTE*)(key++) = md_buf[i];
850
851
        nkey--;
852
        i++;
853
      }
854
    }
855
856
    if (niv && (i != mds))
857
    {
858
      while (1)
859
      {
860
        if (niv == 0)
861
          break;
862
863
        if (i == mds)
864
          break;
865
866
        if (iv)
867
          *(BYTE*)(iv++) = md_buf[i];
868
869
        niv--;
870
        i++;
871
      }
872
    }
873
874
    if ((nkey == 0) && (niv == 0))
875
      break;
876
  }
877
878
  rv = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
879
err:
880
  mbedtls_md_free(&ctx);
881
  SecureZeroMemory(md_buf, 64);
882
  return rv;
883
#else
884
  return 0;
885
#endif
886
0
}