Coverage Report

Created: 2023-09-25 06:56

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