OpenVPN
crypto_mbedtls.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2025 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2010-2021 Sentyron B.V. <openvpn@sentyron.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, see <https://www.gnu.org/licenses/>.
22 */
23
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include "syshead.h"
34
35#if defined(ENABLE_CRYPTO_MBEDTLS)
36
37#include "errlevel.h"
38#include "basic.h"
39#include "buffer.h"
40#include "crypto.h"
41#include "integer.h"
42#include "crypto_backend.h"
43#include "otime.h"
44#include "mbedtls_compat.h"
45#include "misc.h"
46
47#include <mbedtls/base64.h>
48#include <mbedtls/des.h>
49#include <mbedtls/error.h>
50#include <mbedtls/md5.h>
51#include <mbedtls/cipher.h>
52#include <mbedtls/pem.h>
53
54#include <mbedtls/entropy.h>
55#include <mbedtls/ssl.h>
56
57
58/*
59 *
60 * Hardware engine support. Allows loading/unloading of engines.
61 *
62 */
63
64void
65crypto_init_lib_engine(const char *engine_name)
66{
67 msg(M_WARN, "Note: mbed TLS hardware crypto engine functionality is not "
68 "available");
69}
70
72crypto_load_provider(const char *provider)
73{
74 if (provider)
75 {
76 msg(M_WARN, "Note: mbed TLS provider functionality is not available");
77 }
78 return NULL;
79}
80
81void
82crypto_unload_provider(const char *provname, provider_t *provider)
83{
84}
85
86/*
87 *
88 * Functions related to the core crypto library
89 *
90 */
91
92void
94{
95}
96
97void
99{
100}
101
102void
104{
105}
106
107bool
108mbed_log_err(unsigned int flags, int errval, const char *prefix)
109{
110 if (0 != errval)
111 {
112 char errstr[256];
113 mbedtls_strerror(errval, errstr, sizeof(errstr));
114
115 if (NULL == prefix)
116 {
117 prefix = "mbed TLS error";
118 }
119 msg(flags, "%s: %s", prefix, errstr);
120 }
121
122 return 0 == errval;
123}
124
125bool
126mbed_log_func_line(unsigned int flags, int errval, const char *func, int line)
127{
128 char prefix[256];
129
130 if (!snprintf(prefix, sizeof(prefix), "%s:%d", func, line))
131 {
132 return mbed_log_err(flags, errval, func);
133 }
134
135 return mbed_log_err(flags, errval, prefix);
136}
137
138
139#ifdef DMALLOC
140void
141crypto_init_dmalloc(void)
142{
143 msg(M_ERR, "Error: dmalloc support is not available for mbed TLS.");
144}
145#endif /* DMALLOC */
146
148 { "BF-CBC", "BLOWFISH-CBC" },
149 { "BF-CFB", "BLOWFISH-CFB64" },
150 { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" },
151 { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" },
152 { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" }
153};
156
157void
159{
160 const int *ciphers = mbedtls_cipher_list();
161
162#ifndef ENABLE_SMALL
163 printf("The following ciphers and cipher modes are available for use\n"
164 "with " PACKAGE_NAME ". Each cipher shown below may be used as a\n"
165 "parameter to the --data-ciphers (or --cipher) option. Using a\n"
166 "GCM or CBC mode is recommended. In static key mode only CBC\n"
167 "mode is allowed.\n\n");
168#endif
169
170 while (*ciphers != 0)
171 {
172 const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
173 const char *name = mbedtls_cipher_info_get_name(info);
174 if (info && name && !cipher_kt_insecure(name)
175 && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
176 {
177 print_cipher(name);
178 }
179 ciphers++;
180 }
181
182 printf("\nThe following ciphers have a block size of less than 128 bits, \n"
183 "and are therefore deprecated. Do not use unless you have to.\n\n");
184 ciphers = mbedtls_cipher_list();
185 while (*ciphers != 0)
186 {
187 const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
188 const char *name = mbedtls_cipher_info_get_name(info);
189 if (info && name && cipher_kt_insecure(name)
190 && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
191 {
192 print_cipher(name);
193 }
194 ciphers++;
195 }
196 printf("\n");
197}
198
199void
201{
202 const int *digests = mbedtls_md_list();
203
204#ifndef ENABLE_SMALL
205 printf("The following message digests are available for use with\n" PACKAGE_NAME
206 ". A message digest is used in conjunction with\n"
207 "the HMAC function, to authenticate received packets.\n"
208 "You can specify a message digest as parameter to\n"
209 "the --auth option.\n\n");
210#endif
211
212 while (*digests != 0)
213 {
214 const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*digests);
215
216 if (info)
217 {
218 printf("%s %d bit default key\n", mbedtls_md_get_name(info),
219 mbedtls_md_get_size(info) * 8);
220 }
221 digests++;
222 }
223 printf("\n");
224}
225
226void
228{
229 printf("Sorry, mbed TLS hardware crypto engine functionality is not "
230 "available\n");
231}
232
233#if defined(__GNUC__) || defined(__clang__)
234#pragma GCC diagnostic push
235#pragma GCC diagnostic ignored "-Wconversion"
236#endif
237
238bool
239crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src,
240 struct gc_arena *gc)
241{
242 /* 1000 chars is the PEM line length limit (+1 for tailing NUL) */
243 char header[1000 + 1] = { 0 };
244 char footer[1000 + 1] = { 0 };
245
246 if (!snprintf(header, sizeof(header), "-----BEGIN %s-----\n", name))
247 {
248 return false;
249 }
250 if (!snprintf(footer, sizeof(footer), "-----END %s-----\n", name))
251 {
252 return false;
253 }
254
255 size_t out_len = 0;
256 if (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
257 != mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src), NULL, 0, &out_len))
258 {
259 return false;
260 }
261
262 /* We set the size buf to out_len-1 to NOT include the 0 byte that
263 * mbedtls_pem_write_buffer in its length calculation */
264 *dst = alloc_buf_gc(out_len, gc);
265 if (!mbed_ok(mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src), BPTR(dst),
266 BCAP(dst), &out_len))
267 || !buf_inc_len(dst, out_len - 1))
268 {
269 CLEAR(*dst);
270 return false;
271 }
272
273 return true;
274}
275
276bool
277crypto_pem_decode(const char *name, struct buffer *dst, const struct buffer *src)
278{
279 /* 1000 chars is the PEM line length limit (+1 for tailing NUL) */
280 char header[1000 + 1] = { 0 };
281 char footer[1000 + 1] = { 0 };
282
283 if (!snprintf(header, sizeof(header), "-----BEGIN %s-----", name))
284 {
285 return false;
286 }
287 if (!snprintf(footer, sizeof(footer), "-----END %s-----", name))
288 {
289 return false;
290 }
291
292 /* mbed TLS requires the src to be null-terminated */
293 /* allocate a new buffer to avoid modifying the src buffer */
294 struct gc_arena gc = gc_new();
295 struct buffer input = alloc_buf_gc(BLEN(src) + 1, &gc);
296 buf_copy(&input, src);
298
299 size_t use_len = 0;
300 mbedtls_pem_context ctx = { 0 };
301 bool ret =
303 size_t buf_size = 0;
304 const unsigned char *buf = mbedtls_pem_get_buffer(&ctx, &buf_size);
305 if (ret && !buf_write(dst, buf, buf_size))
306 {
307 ret = false;
308 msg(M_WARN, "PEM decode error: destination buffer too small");
309 }
310
311 mbedtls_pem_free(&ctx);
312 gc_free(&gc);
313 return ret;
314}
315
316/*
317 *
318 * Random number functions, used in cases where we want
319 * reasonably strong cryptographic random number generation
320 * without depleting our entropy pool. Used for random
321 * IV values and a number of other miscellaneous tasks.
322 *
323 */
324
325/*
326 * Initialise the given ctr_drbg context, using a personalisation string and an
327 * entropy gathering function.
328 */
330rand_ctx_get(void)
331{
332 static mbedtls_entropy_context ec = { 0 };
333 static mbedtls_ctr_drbg_context cd_ctx = { 0 };
334 static bool rand_initialised = false;
335
336 if (!rand_initialised)
337 {
338 struct gc_arena gc = gc_new();
339 struct buffer pers_string = alloc_buf_gc(100, &gc);
340
341 /*
342 * Personalisation string, should be as unique as possible (see NIST
343 * 800-90 section 8.7.1). We have very little information at this stage.
344 * Include Program Name, memory address of the context and PID.
345 */
346 buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx,
347 time_string(0, 0, 0, &gc));
348
349 /* Initialise mbed TLS RNG, and built-in entropy sources */
351
354 BLEN(&pers_string))))
355 {
356 msg(M_FATAL, "Failed to initialize random generator");
357 }
358
359 gc_free(&gc);
360 rand_initialised = true;
361 }
362
363 return &cd_ctx;
364}
365
366#ifdef ENABLE_PREDICTION_RESISTANCE
367void
369{
371
373}
374#endif /* ENABLE_PREDICTION_RESISTANCE */
375
376int
378{
380
381 while (len > 0)
382 {
385 {
386 return 0;
387 }
388
389 output += blen;
390 len -= blen;
391 }
392
393 return 1;
394}
395
396/*
397 *
398 * Generic cipher key type functions
399 *
400 */
401static const mbedtls_cipher_info_t *
402cipher_get(const char *ciphername)
403{
404 ASSERT(ciphername);
405
406 const mbedtls_cipher_info_t *cipher = NULL;
407
408 ciphername = translate_cipher_name_from_openvpn(ciphername);
409 cipher = mbedtls_cipher_info_from_string(ciphername);
410 return cipher;
411}
412
413bool
414cipher_valid_reason(const char *ciphername, const char **reason)
415{
416 ASSERT(reason);
417
418 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
419
420 if (NULL == cipher)
421 {
422 msg(D_LOW, "Cipher algorithm '%s' not found", ciphername);
423 *reason = "disabled because unknown";
424 return false;
425 }
426
427 const size_t key_bytelen = mbedtls_cipher_info_get_key_bitlen(cipher) / 8;
429 {
430 msg(D_LOW,
431 "Cipher algorithm '%s' uses a default key size (%zu bytes) "
432 "which is larger than " PACKAGE_NAME "'s current maximum key size "
433 "(%d bytes)",
435 *reason = "disabled due to key size too large";
436 return false;
437 }
438
439 *reason = NULL;
440 return true;
441}
442
443const char *
444cipher_kt_name(const char *ciphername)
445{
446 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
447 if (NULL == cipher_kt)
448 {
449 return "[null-cipher]";
450 }
451
453}
454
455int
456cipher_kt_key_size(const char *ciphername)
457{
458 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
459
460 if (NULL == cipher_kt)
461 {
462 return 0;
463 }
464
466}
467
468int
469cipher_kt_iv_size(const char *ciphername)
470{
471 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
472
473 if (NULL == cipher_kt)
474 {
475 return 0;
476 }
478}
479
480int
481cipher_kt_block_size(const char *ciphername)
482{
483 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
484 if (NULL == cipher_kt)
485 {
486 return 0;
487 }
489}
490
491int
492cipher_kt_tag_size(const char *ciphername)
493{
494 if (cipher_kt_mode_aead(ciphername))
495 {
497 }
498 return 0;
499}
500
501bool
502cipher_kt_insecure(const char *ciphername)
503{
504 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
505 if (!cipher_kt)
506 {
507 return true;
508 }
509
510 return !(cipher_kt_block_size(ciphername) >= 128 / 8
511#ifdef MBEDTLS_CHACHAPOLY_C
513#endif
514 );
515}
516
519{
522}
523
524bool
525cipher_kt_mode_cbc(const char *ciphername)
526{
527 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
528 return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
529}
530
531bool
532cipher_kt_mode_ofb_cfb(const char *ciphername)
533{
534 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
535 return cipher
536 && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB
537 || cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
538}
539
540bool
541cipher_kt_mode_aead(const char *ciphername)
542{
543 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
544 return cipher
545 && (cipher_kt_mode(cipher) == OPENVPN_MODE_GCM
546#ifdef MBEDTLS_CHACHAPOLY_C
548#endif
549 );
550}
551
552
553/*
554 *
555 * Generic cipher context functions
556 *
557 */
558
560cipher_ctx_new(void)
561{
564 return ctx;
565}
566
567void
569{
571 free(ctx);
572}
573
574void
575cipher_ctx_init(mbedtls_cipher_context_t *ctx, const uint8_t *key, const char *ciphername,
577{
578 ASSERT(NULL != ciphername && NULL != ctx);
579 CLEAR(*ctx);
580
581 const mbedtls_cipher_info_t *kt = cipher_get(ciphername);
582 ASSERT(kt);
584
585 if (!mbed_ok(mbedtls_cipher_setup(ctx, kt)))
586 {
587 msg(M_FATAL, "mbed TLS cipher context init #1");
588 }
589
591 {
592 msg(M_FATAL, "mbed TLS cipher set key");
593 }
594
596 {
598 {
599 msg(M_FATAL, "mbed TLS cipher set padding mode");
600 }
601 }
602
603 /* make sure we used a big enough key */
605}
606
607int
609{
610 return mbedtls_cipher_get_iv_size(ctx);
611}
612
613int
615{
616 if (tag_len > SIZE_MAX)
617 {
618 return 0;
619 }
620
621 if (!mbed_ok(mbedtls_cipher_write_tag(ctx, (unsigned char *)tag, tag_len)))
622 {
623 return 0;
624 }
625
626 return 1;
627}
628
629int
631{
632 return (int)mbedtls_cipher_get_block_size(ctx);
633}
634
635int
637{
638 ASSERT(NULL != ctx);
639
641}
642
643bool
645{
646 return ctx && cipher_ctx_mode(ctx) == OPENVPN_MODE_CBC;
647}
648
649
650bool
652{
653 return ctx
656}
657
658bool
660{
661 return ctx
663#ifdef MBEDTLS_CHACHAPOLY_C
665#endif
666 );
667}
668
669int
671{
672 if (!mbed_ok(mbedtls_cipher_reset(ctx)))
673 {
674 return 0;
675 }
676
678 {
679 return 0;
680 }
681
682 return 1;
683}
684
685int
687{
688 if (src_len > SIZE_MAX)
689 {
690 return 0;
691 }
692
694 {
695 return 0;
696 }
697
698 return 1;
699}
700
701int
703 int src_len)
704{
705 size_t s_dst_len = *dst_len;
706
707 if (!mbed_ok(mbedtls_cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len)))
708 {
709 return 0;
710 }
711
713
714 return 1;
715}
716
717int
719{
720 size_t s_dst_len = *dst_len;
721
723 {
724 return 0;
725 }
726
728
729 return 1;
730}
731
732int
734 size_t tag_len)
735{
736 size_t olen = 0;
737
739 {
740 return 0;
741 }
742
743 if (tag_len > SIZE_MAX)
744 {
745 return 0;
746 }
747
749 {
750 msg(D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__);
751 return 0;
752 }
753
754 if (olen > INT_MAX)
755 {
756 return 0;
757 }
758 *dst_len = olen;
759
760 if (!mbed_ok(mbedtls_cipher_check_tag(ctx, (const unsigned char *)tag, tag_len)))
761 {
762 return 0;
763 }
764
765 return 1;
766}
767
768/*
769 *
770 * Generic message digest information functions
771 *
772 */
773
774
775static const mbedtls_md_info_t *
776md_get(const char *digest)
777{
778 const mbedtls_md_info_t *md = NULL;
779 ASSERT(digest);
780
782 if (!md)
783 {
784 msg(M_FATAL, "Message hash algorithm '%s' not found", digest);
785 }
787 {
788 msg(M_FATAL,
789 "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME
790 "'s current maximum hash size (%d bytes)",
792 }
793 return md;
794}
795
796bool
797md_valid(const char *digest)
798{
800 return md != NULL;
801}
802
803const char *
804md_kt_name(const char *mdname)
805{
806 if (!strcmp("none", mdname))
807 {
808 return "[null-digest]";
809 }
810 const mbedtls_md_info_t *kt = md_get(mdname);
811 return mbedtls_md_get_name(kt);
812}
813
814unsigned char
815md_kt_size(const char *mdname)
816{
817 if (!strcmp("none", mdname))
818 {
819 return 0;
820 }
821 const mbedtls_md_info_t *kt = md_get(mdname);
822 return mbedtls_md_get_size(kt);
823}
824
825/*
826 *
827 * Generic message digest functions
828 *
829 */
830
831int
832md_full(const char *mdname, const uint8_t *src, int src_len, uint8_t *dst)
833{
834 const mbedtls_md_info_t *kt = md_get(mdname);
835 return 0 == mbedtls_md(kt, src, src_len, dst);
836}
837
839md_ctx_new(void)
840{
843 return ctx;
844}
845
846void
848{
849 free(ctx);
850}
851
852void
853md_ctx_init(mbedtls_md_context_t *ctx, const char *mdname)
854{
855 const mbedtls_md_info_t *kt = md_get(mdname);
856 ASSERT(NULL != ctx && NULL != kt);
857
858 mbedtls_md_init(ctx);
859 ASSERT(0 == mbedtls_md_setup(ctx, kt, 0));
860 ASSERT(0 == mbedtls_md_starts(ctx));
861}
862
863void
865{
866 mbedtls_md_free(ctx);
867}
868
869int
871{
872 if (NULL == ctx)
873 {
874 return 0;
875 }
877}
878
879void
881{
882 ASSERT(0 == mbedtls_md_update(ctx, src, src_len));
883}
884
885void
887{
888 ASSERT(0 == mbedtls_md_finish(ctx, dst));
889 mbedtls_md_free(ctx);
890}
891
892
893/*
894 *
895 * Generic HMAC functions
896 *
897 */
898
899
900/*
901 * TODO: re-enable dmsg for crypto debug
902 */
903
905hmac_ctx_new(void)
906{
909 return ctx;
910}
911
912void
914{
915 free(ctx);
916}
917
918void
919hmac_ctx_init(mbedtls_md_context_t *ctx, const uint8_t *key, const char *mdname)
920{
921 const mbedtls_md_info_t *kt = md_get(mdname);
922 ASSERT(NULL != kt && NULL != ctx);
923
924 mbedtls_md_init(ctx);
926 ASSERT(0 == mbedtls_md_setup(ctx, kt, 1));
928
929 /* make sure we used a big enough key */
931}
932
933void
935{
936 mbedtls_md_free(ctx);
937}
938
939int
941{
942 if (NULL == ctx)
943 {
944 return 0;
945 }
947}
948
949void
951{
952 ASSERT(0 == mbedtls_md_hmac_reset(ctx));
953}
954
955void
957{
959}
960
961void
963{
965}
966
967int
968memcmp_constant_time(const void *a, const void *b, size_t size)
969{
970 /* mbed TLS has a no const time memcmp function that it exposes
971 * via its APIs like OpenSSL does with CRYPTO_memcmp
972 * Adapt the function that mbedtls itself uses in
973 * mbedtls_safer_memcmp as it considers that to be safe */
974 volatile const unsigned char *A = (volatile const unsigned char *)a;
975 volatile const unsigned char *B = (volatile const unsigned char *)b;
976 volatile unsigned char diff = 0;
977
978 for (size_t i = 0; i < size; i++)
979 {
980 unsigned char x = A[i], y = B[i];
981 diff |= x ^ y;
982 }
983
984 return diff;
985}
986/* mbedtls-2.18.0 or newer implements tls_prf, but prf_tls1 is removed
987 * from recent versions, so we use our own implementation if necessary. */
988#if defined(HAVE_MBEDTLS_SSL_TLS_PRF) && defined(MBEDTLS_SSL_TLS_PRF_TLS1)
989bool
990ssl_tls1_PRF(const uint8_t *seed, size_t seed_len, const uint8_t *secret, size_t secret_len,
991 uint8_t *output, size_t output_len)
992{
995}
996#else /* defined(HAVE_MBEDTLS_SSL_TLS_PRF) && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */
997/*
998 * Generate the hash required by for the \c tls1_PRF function.
999 *
1000 * @param md_kt Message digest to use
1001 * @param sec Secret to base the hash on
1002 * @param sec_len Length of the secret
1003 * @param seed Seed to hash
1004 * @param seed_len Length of the seed
1005 * @param out Output buffer
1006 * @param olen Length of the output buffer
1007 */
1008static void
1009tls1_P_hash(const mbedtls_md_info_t *md_kt, const uint8_t *sec, size_t sec_len, const uint8_t *seed,
1010 size_t seed_len, uint8_t *out, size_t olen)
1011{
1012 struct gc_arena gc = gc_new();
1013 uint8_t A1[MAX_HMAC_KEY_LENGTH];
1014
1015#ifdef ENABLE_DEBUG
1016 /* used by the D_SHOW_KEY_SOURCE, guarded with ENABLE_DEBUG to avoid unused
1017 * variables warnings if compiled with --enable-small */
1018 const size_t olen_orig = olen;
1019 const uint8_t *out_orig = out;
1020#endif
1021
1022 hmac_ctx_t *ctx = hmac_ctx_new();
1023 hmac_ctx_t *ctx_tmp = hmac_ctx_new();
1024
1025 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc));
1026 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc));
1027
1028 unsigned int chunk = mbedtls_md_get_size(md_kt);
1029 unsigned int A1_len = mbedtls_md_get_size(md_kt);
1030
1031 /* This is the only place where we init an HMAC with a key that is not
1032 * equal to its size, therefore we init the hmac ctx manually here */
1033 mbedtls_md_init(ctx);
1034 ASSERT(0 == mbedtls_md_setup(ctx, md_kt, 1));
1035 ASSERT(0 == mbedtls_md_hmac_starts(ctx, sec, sec_len));
1036
1037 mbedtls_md_init(ctx_tmp);
1038 ASSERT(0 == mbedtls_md_setup(ctx_tmp, md_kt, 1));
1039 ASSERT(0 == mbedtls_md_hmac_starts(ctx_tmp, sec, sec_len));
1040
1041 hmac_ctx_update(ctx, seed, seed_len);
1042 hmac_ctx_final(ctx, A1);
1043
1044 for (;;)
1045 {
1046 hmac_ctx_reset(ctx);
1047 hmac_ctx_reset(ctx_tmp);
1048 hmac_ctx_update(ctx, A1, A1_len);
1049 hmac_ctx_update(ctx_tmp, A1, A1_len);
1050 hmac_ctx_update(ctx, seed, seed_len);
1051
1052 if (olen > chunk)
1053 {
1054 hmac_ctx_final(ctx, out);
1055 out += chunk;
1056 olen -= chunk;
1057 hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */
1058 }
1059 else /* last one */
1060 {
1061 hmac_ctx_final(ctx, A1);
1062 memcpy(out, A1, olen);
1063 break;
1064 }
1065 }
1066 hmac_ctx_cleanup(ctx);
1067 hmac_ctx_free(ctx);
1068 hmac_ctx_cleanup(ctx_tmp);
1069 hmac_ctx_free(ctx_tmp);
1070 secure_memzero(A1, sizeof(A1));
1071
1072 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc));
1073 gc_free(&gc);
1074}
1075
1076/*
1077 * Use the TLS PRF function for generating data channel keys.
1078 * This code is based on the OpenSSL library.
1079 *
1080 * TLS generates keys as such:
1081 *
1082 * master_secret[48] = PRF(pre_master_secret[48], "master secret",
1083 * ClientHello.random[32] + ServerHello.random[32])
1084 *
1085 * key_block[] = PRF(SecurityParameters.master_secret[48],
1086 * "key expansion",
1087 * SecurityParameters.server_random[32] +
1088 * SecurityParameters.client_random[32]);
1089 *
1090 * Notes:
1091 *
1092 * (1) key_block contains a full set of 4 keys.
1093 * (2) The pre-master secret is generated by the client.
1094 */
1095bool
1096ssl_tls1_PRF(const uint8_t *label, size_t label_len, const uint8_t *sec, size_t slen, uint8_t *out1,
1097 size_t olen)
1098{
1099 struct gc_arena gc = gc_new();
1100 const md_kt_t *md5 = md_get("MD5");
1101 const md_kt_t *sha1 = md_get("SHA1");
1102
1103 uint8_t *out2 = (uint8_t *)gc_malloc(olen, false, &gc);
1104
1105 size_t len = slen / 2;
1106 const uint8_t *S1 = sec;
1107 const uint8_t *S2 = &(sec[len]);
1108 len += (slen & 1); /* add for odd, make longer */
1109
1110 tls1_P_hash(md5, S1, len, label, label_len, out1, olen);
1111 tls1_P_hash(sha1, S2, len, label, label_len, out2, olen);
1112
1113 for (size_t i = 0; i < olen; i++)
1114 {
1115 out1[i] ^= out2[i];
1116 }
1117
1118 secure_memzero(out2, olen);
1119
1120 dmsg(D_SHOW_KEY_SOURCE, "tls1_PRF out[%zu]: %s", olen, format_hex(out1, olen, 0, &gc));
1121
1122 gc_free(&gc);
1123 return true;
1124}
1125#endif /* HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */
1126
1127#if defined(__GNUC__) || defined(__clang__)
1128#pragma GCC diagnostic pop
1129#endif
1130
1131#endif /* ENABLE_CRYPTO_MBEDTLS */
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
void buf_null_terminate(struct buffer *buf)
Definition buffer.c:533
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:336
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:89
#define ALLOC_OBJ(dptr, type)
Definition buffer.h:1037
static char * format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
Definition buffer.h:503
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Definition buffer.h:704
#define BPTR(buf)
Definition buffer.h:123
static bool buf_inc_len(struct buffer *buf, int inc)
Definition buffer.h:588
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition buffer.h:414
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:660
#define BLEN(buf)
Definition buffer.h:126
#define BCAP(buf)
Definition buffer.h:129
static void gc_free(struct gc_arena *a)
Definition buffer.h:1015
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1042
static struct gc_arena gc_new(void)
Definition buffer.h:1007
#define PACKAGE_NAME
Definition config.h:492
const char * translate_cipher_name_from_openvpn(const char *cipher_name)
Translate an OpenVPN cipher name to a crypto library cipher name.
Definition crypto.c:1786
const char * translate_cipher_name_to_openvpn(const char *cipher_name)
Translate a crypto library cipher name to an OpenVPN cipher name.
Definition crypto.c:1799
void print_cipher(const char *ciphername)
Print a cipher list entry.
Definition crypto.c:1737
Data Channel Cryptography Module.
int memcmp_constant_time(const void *a, const void *b, size_t size)
As memcmp(), but constant-time.
Data Channel Cryptography SSL library-specific backend interface.
int cipher_ctx_update(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len)
Updates the given cipher context, encrypting data in the source buffer, and placing any complete bloc...
bool ssl_tls1_PRF(const uint8_t *seed, size_t seed_len, const uint8_t *secret, size_t secret_len, uint8_t *output, size_t output_len)
Calculates the TLS 1.0-1.1 PRF function.
void hmac_ctx_update(hmac_ctx_t *ctx, const uint8_t *src, int src_len)
hmac_ctx_t * hmac_ctx_new(void)
int md_full(const char *mdname, const uint8_t *src, int src_len, uint8_t *dst)
Calculates the message digest for the given buffer.
void hmac_ctx_reset(hmac_ctx_t *ctx)
int cipher_ctx_block_size(const cipher_ctx_t *ctx)
Returns the block size of the cipher, in bytes.
bool cipher_kt_mode_cbc(const char *ciphername)
Check if the supplied cipher is a supported CBC mode cipher.
void show_available_engines(void)
void hmac_ctx_init(hmac_ctx_t *ctx, const uint8_t *key, const char *mdname)
md_ctx_t * md_ctx_new(void)
void hmac_ctx_final(hmac_ctx_t *ctx, uint8_t *dst)
int cipher_ctx_iv_length(const cipher_ctx_t *ctx)
Returns the size of the IV used by the cipher, in bytes, or 0 if no IV is used.
void crypto_unload_provider(const char *provname, provider_t *provider)
Unloads the given (OpenSSL) provider.
void crypto_uninit_lib(void)
int cipher_kt_block_size(const char *ciphername)
Returns the block size of the cipher, in bytes.
void md_ctx_update(md_ctx_t *ctx, const uint8_t *src, int src_len)
bool cipher_kt_mode_aead(const char *ciphername)
Check if the supplied cipher is a supported AEAD mode cipher.
int md_ctx_size(const md_ctx_t *ctx)
void show_available_ciphers(void)
bool md_valid(const char *digest)
Return if a message digest parameters is valid given the name of the digest.
bool cipher_ctx_mode_cbc(const cipher_ctx_t *ctx)
Check if the supplied cipher is a supported CBC mode cipher.
void crypto_init_lib(void)
cipher_ctx_t * cipher_ctx_new(void)
Generic cipher functions.
bool cipher_kt_mode_ofb_cfb(const char *ciphername)
Check if the supplied cipher is a supported OFB or CFB mode cipher.
const char * md_kt_name(const char *mdname)
Retrieve a string describing the digest digest (e.g.
int hmac_ctx_size(hmac_ctx_t *ctx)
bool cipher_kt_insecure(const char *ciphername)
Returns true if we consider this cipher to be insecure.
#define MAX_CIPHER_KEY_LENGTH
void crypto_clear_error(void)
bool crypto_pem_decode(const char *name, struct buffer *dst, const struct buffer *src)
Decode a PEM buffer to binary data.
provider_t * crypto_load_provider(const char *provider)
Load the given (OpenSSL) providers.
void cipher_ctx_free(cipher_ctx_t *ctx)
Cleanup and free a cipher context.
int cipher_ctx_mode(const cipher_ctx_t *ctx)
Returns the mode that the cipher runs in.
bool cipher_ctx_mode_ofb_cfb(const cipher_ctx_t *ctx)
Check if the supplied cipher is a supported OFB or CFB mode cipher.
bool cipher_ctx_mode_aead(const cipher_ctx_t *ctx)
Check if the supplied cipher is a supported AEAD mode cipher.
void hmac_ctx_free(hmac_ctx_t *ctx)
int cipher_kt_iv_size(const char *ciphername)
Returns the size of the IV used by the cipher, in bytes, or 0 if no IV is used.
int cipher_kt_tag_size(const char *ciphername)
Returns the MAC tag size of the cipher, in bytes.
int cipher_ctx_update_ad(cipher_ctx_t *ctx, const uint8_t *src, int src_len)
Updates the given cipher context, providing additional data (AD) for authenticated encryption with ad...
int rand_bytes(uint8_t *output, int len)
Wrapper for secure random number generator.
const size_t cipher_name_translation_table_count
const char * cipher_kt_name(const char *ciphername)
Retrieve a normalised string describing the cipher (e.g.
#define MAX_HMAC_KEY_LENGTH
#define OPENVPN_AEAD_TAG_LENGTH
void cipher_ctx_init(cipher_ctx_t *ctx, const uint8_t *key, const char *ciphername, crypto_operation_t enc)
Initialise a cipher context, based on the given key and key type.
int cipher_ctx_get_tag(cipher_ctx_t *ctx, uint8_t *tag, int tag_len)
Gets the computed message authenticated code (MAC) tag for this cipher.
int cipher_kt_key_size(const char *ciphername)
Returns the size of keys used by the cipher, in bytes.
void crypto_init_lib_engine(const char *engine_name)
void hmac_ctx_cleanup(hmac_ctx_t *ctx)
int cipher_ctx_reset(cipher_ctx_t *ctx, const uint8_t *iv_buf)
Resets the given cipher context, setting the IV to the specified value.
const cipher_name_pair cipher_name_translation_table[]
Cipher name translation table.
void md_ctx_cleanup(md_ctx_t *ctx)
int cipher_ctx_final(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len)
Pads the final cipher block using PKCS padding, and output to the destination buffer.
void md_ctx_final(md_ctx_t *ctx, uint8_t *dst)
unsigned char md_kt_size(const char *mdname)
Returns the size of the message digest, in bytes.
void show_available_digests(void)
bool cipher_valid_reason(const char *ciphername, const char **reason)
Returns if the cipher is valid, based on the given cipher name and provides a reason if invalid.
int cipher_ctx_final_check_tag(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len, uint8_t *tag, size_t tag_len)
Like cipher_ctx_final, but check the computed authentication tag against the supplied (expected) tag.
void md_ctx_init(md_ctx_t *ctx, const char *mdname)
Initialises the given message digest context.
void md_ctx_free(md_ctx_t *ctx)
bool crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src, struct gc_arena *gc)
Encode binary data as PEM.
mbedtls_ctr_drbg_context * rand_ctx_get(void)
Returns a singleton instance of the mbed TLS random number generator.
mbedtls_cipher_context_t cipher_ctx_t
Generic cipher context.
mbedtls_md_context_t hmac_ctx_t
Generic HMAC context.
#define OPENVPN_MODE_OFB
Cipher is in OFB mode.
#define mbed_ok(errval)
Check errval and log on error.
bool mbed_log_err(unsigned int flags, int errval, const char *prefix)
Log the supplied mbed TLS error, prefixed by supplied prefix.
#define OPENVPN_MODE_CFB
Cipher is in CFB mode.
#define OPENVPN_MODE_CBC
Cipher is in CBC mode.
mbedtls_md_info_t md_kt_t
Generic message digest key type context.
void provider_t
mbedtls_operation_t crypto_operation_t
#define OPENVPN_MODE_GCM
Cipher is in GCM mode.
bool mbed_log_func_line(unsigned int flags, int errval, const char *func, int line)
Log the supplied mbed TLS error, prefixed by function name and line number.
int cipher_kt_mode(const EVP_CIPHER *cipher_kt)
static evp_cipher_type * cipher_get(const char *ciphername)
static evp_md_type * md_get(const char *digest)
#define D_CRYPT_ERRORS
Definition errlevel.h:57
#define D_SHOW_KEY_SOURCE
Definition errlevel.h:121
#define D_LOW
Definition errlevel.h:96
static int min_int(int x, int y)
Definition integer.h:105
mbedtls compatibility stub.
static const char * mbedtls_cipher_info_get_name(const mbedtls_cipher_info_t *cipher)
static size_t mbedtls_cipher_info_get_key_bitlen(const mbedtls_cipher_info_t *cipher)
static const mbedtls_md_info_t * mbedtls_md_info_from_ctx(const mbedtls_md_context_t *ctx)
static size_t mbedtls_cipher_info_get_iv_size(const mbedtls_cipher_info_t *cipher)
static mbedtls_cipher_type_t mbedtls_cipher_info_get_type(const mbedtls_cipher_info_t *cipher)
static size_t mbedtls_cipher_info_get_block_size(const mbedtls_cipher_info_t *cipher)
static mbedtls_cipher_mode_t mbedtls_cipher_info_get_mode(const mbedtls_cipher_info_t *cipher)
static const unsigned char * mbedtls_pem_get_buffer(const mbedtls_pem_context *ctx, size_t *buf_size)
#define CLEAR(x)
Definition basic.h:32
#define M_FATAL
Definition error.h:90
#define dmsg(flags,...)
Definition error.h:172
#define M_ERR
Definition error.h:106
#define msg(flags,...)
Definition error.h:152
#define ASSERT(x)
Definition error.h:219
#define M_WARN
Definition error.h:92
const char * time_string(time_t t, long usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:109
unsigned int platform_getpid(void)
Definition platform.c:337
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
Struct used in cipher name translation table.
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152
struct gc_arena gc
Definition test_ssl.c:131