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 "misc.h"
45
46#include <mbedtls/base64.h>
47#include <mbedtls/des.h>
48#include <mbedtls/error.h>
49#include <mbedtls/md5.h>
50#include <mbedtls/cipher.h>
51#include <mbedtls/pem.h>
52
53#include <mbedtls/entropy.h>
54#include <mbedtls/ssl.h>
55
56
57/*
58 *
59 * Hardware engine support. Allows loading/unloading of engines.
60 *
61 */
62
63void
64crypto_init_lib_engine(const char *engine_name)
65{
66 msg(M_WARN, "Note: mbed TLS hardware crypto engine functionality is not "
67 "available");
68}
69
71crypto_load_provider(const char *provider)
72{
73 if (provider)
74 {
75 msg(M_WARN, "Note: mbed TLS provider functionality is not available");
76 }
77 return NULL;
78}
79
80void
81crypto_unload_provider(const char *provname, provider_t *provider)
82{
83}
84
85/*
86 *
87 * Functions related to the core crypto library
88 *
89 */
90
91void
93{
94}
95
96void
98{
99}
100
101void
103{
104}
105
106bool
107mbed_log_err(unsigned int flags, int errval, const char *prefix)
108{
109 if (0 != errval)
110 {
111 char errstr[256];
112 mbedtls_strerror(errval, errstr, sizeof(errstr));
113
114 if (NULL == prefix)
115 {
116 prefix = "mbed TLS error";
117 }
118 msg(flags, "%s: %s", prefix, errstr);
119 }
120
121 return 0 == errval;
122}
123
124bool
125mbed_log_func_line(unsigned int flags, int errval, const char *func, int line)
126{
127 char prefix[256];
128
129 if (snprintf(prefix, sizeof(prefix), "%s:%d", func, line) >= sizeof(prefix))
130 {
131 return mbed_log_err(flags, errval, func);
132 }
133
134 return mbed_log_err(flags, errval, prefix);
135}
136
137
138#ifdef DMALLOC
139void
140crypto_init_dmalloc(void)
141{
142 msg(M_ERR, "Error: dmalloc support is not available for mbed TLS.");
143}
144#endif /* DMALLOC */
145
147 { "BF-CBC", "BLOWFISH-CBC" },
148 { "BF-CFB", "BLOWFISH-CFB64" },
149 { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" },
150 { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" },
151 { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" }
152};
155
156void
158{
159 const int *ciphers = mbedtls_cipher_list();
160
161#ifndef ENABLE_SMALL
162 printf("The following ciphers and cipher modes are available for use\n"
163 "with " PACKAGE_NAME ". Each cipher shown below may be used as a\n"
164 "parameter to the --data-ciphers (or --cipher) option. Using a\n"
165 "GCM or CBC mode is recommended. In static key mode only CBC\n"
166 "mode is allowed.\n\n");
167#endif
168
169 while (*ciphers != 0)
170 {
171 const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
172 const char *name = mbedtls_cipher_info_get_name(info);
173 if (info && name && !cipher_kt_insecure(name)
174 && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
175 {
176 print_cipher(name);
177 }
178 ciphers++;
179 }
180
181 printf("\nThe following ciphers have a block size of less than 128 bits, \n"
182 "and are therefore deprecated. Do not use unless you have to.\n\n");
183 ciphers = mbedtls_cipher_list();
184 while (*ciphers != 0)
185 {
186 const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
187 const char *name = mbedtls_cipher_info_get_name(info);
188 if (info && name && cipher_kt_insecure(name)
189 && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
190 {
191 print_cipher(name);
192 }
193 ciphers++;
194 }
195 printf("\n");
196}
197
198void
200{
201 const int *digests = mbedtls_md_list();
202
203#ifndef ENABLE_SMALL
204 printf("The following message digests are available for use with\n" PACKAGE_NAME
205 ". A message digest is used in conjunction with\n"
206 "the HMAC function, to authenticate received packets.\n"
207 "You can specify a message digest as parameter to\n"
208 "the --auth option.\n\n");
209#endif
210
211 while (*digests != 0)
212 {
213 const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*digests);
214
215 if (info)
216 {
217 printf("%s %d bit default key\n", mbedtls_md_get_name(info),
218 mbedtls_md_get_size(info) * 8);
219 }
220 digests++;
221 }
222 printf("\n");
223}
224
225void
227{
228 printf("Sorry, mbed TLS hardware crypto engine functionality is not "
229 "available\n");
230}
231
232#if defined(__GNUC__) || defined(__clang__)
233#pragma GCC diagnostic push
234#pragma GCC diagnostic ignored "-Wconversion"
235#endif
236
237bool
238crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src,
239 struct gc_arena *gc)
240{
241 /* 1000 chars is the PEM line length limit (+1 for tailing NUL) */
242 char header[1000 + 1] = { 0 };
243 char footer[1000 + 1] = { 0 };
244
245 if (snprintf(header, sizeof(header), "-----BEGIN %s-----\n", name) >= sizeof(header))
246 {
247 return false;
248 }
249 if (snprintf(footer, sizeof(footer), "-----END %s-----\n", name) >= sizeof(footer))
250 {
251 return false;
252 }
253
254 size_t out_len = 0;
255 if (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
256 != mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src), NULL, 0, &out_len))
257 {
258 return false;
259 }
260
261 /* We set the size buf to out_len-1 to NOT include the 0 byte that
262 * mbedtls_pem_write_buffer in its length calculation */
263 *dst = alloc_buf_gc(out_len, gc);
264 if (!mbed_ok(mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src), BPTR(dst),
265 BCAP(dst), &out_len))
266 || !buf_inc_len(dst, out_len - 1))
267 {
268 CLEAR(*dst);
269 return false;
270 }
271
272 return true;
273}
274
275bool
276crypto_pem_decode(const char *name, struct buffer *dst, const struct buffer *src)
277{
278 /* 1000 chars is the PEM line length limit (+1 for tailing NUL) */
279 char header[1000 + 1] = { 0 };
280 char footer[1000 + 1] = { 0 };
281
282 if (snprintf(header, sizeof(header), "-----BEGIN %s-----", name) >= sizeof(header))
283 {
284 return false;
285 }
286 if (snprintf(footer, sizeof(footer), "-----END %s-----", name) >= sizeof(footer))
287 {
288 return false;
289 }
290
291 /* mbed TLS requires the src to be null-terminated */
292 /* allocate a new buffer to avoid modifying the src buffer */
293 struct gc_arena gc = gc_new();
294 struct buffer input = alloc_buf_gc(BLEN(src) + 1, &gc);
295 buf_copy(&input, src);
297
298 size_t use_len = 0;
299 mbedtls_pem_context ctx = { 0 };
300 bool ret =
302 size_t buf_size = 0;
303 const unsigned char *buf = mbedtls_pem_get_buffer(&ctx, &buf_size);
304 if (ret && !buf_write(dst, buf, buf_size))
305 {
306 ret = false;
307 msg(M_WARN, "PEM decode error: destination buffer too small");
308 }
309
310 mbedtls_pem_free(&ctx);
311 gc_free(&gc);
312 return ret;
313}
314
315/*
316 *
317 * Random number functions, used in cases where we want
318 * reasonably strong cryptographic random number generation
319 * without depleting our entropy pool. Used for random
320 * IV values and a number of other miscellaneous tasks.
321 *
322 */
323
324/*
325 * Initialise the given ctr_drbg context, using a personalisation string and an
326 * entropy gathering function.
327 */
329rand_ctx_get(void)
330{
331 static mbedtls_entropy_context ec = { 0 };
332 static mbedtls_ctr_drbg_context cd_ctx = { 0 };
333 static bool rand_initialised = false;
334
335 if (!rand_initialised)
336 {
337 struct gc_arena gc = gc_new();
338 struct buffer pers_string = alloc_buf_gc(100, &gc);
339
340 /*
341 * Personalisation string, should be as unique as possible (see NIST
342 * 800-90 section 8.7.1). We have very little information at this stage.
343 * Include Program Name, memory address of the context and PID.
344 */
345 buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx,
346 time_string(0, 0, 0, &gc));
347
348 /* Initialise mbed TLS RNG, and built-in entropy sources */
350
353 BLEN(&pers_string))))
354 {
355 msg(M_FATAL, "Failed to initialize random generator");
356 }
357
358 gc_free(&gc);
359 rand_initialised = true;
360 }
361
362 return &cd_ctx;
363}
364
365#ifdef ENABLE_PREDICTION_RESISTANCE
366void
368{
370
372}
373#endif /* ENABLE_PREDICTION_RESISTANCE */
374
375int
377{
379
380 while (len > 0)
381 {
384 {
385 return 0;
386 }
387
388 output += blen;
389 len -= blen;
390 }
391
392 return 1;
393}
394
395/*
396 *
397 * Generic cipher key type functions
398 *
399 */
400static const mbedtls_cipher_info_t *
401cipher_get(const char *ciphername)
402{
403 ASSERT(ciphername);
404
405 const mbedtls_cipher_info_t *cipher = NULL;
406
407 ciphername = translate_cipher_name_from_openvpn(ciphername);
408 cipher = mbedtls_cipher_info_from_string(ciphername);
409 return cipher;
410}
411
412bool
413cipher_valid_reason(const char *ciphername, const char **reason)
414{
415 ASSERT(reason);
416
417 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
418
419 if (NULL == cipher)
420 {
421 msg(D_LOW, "Cipher algorithm '%s' not found", ciphername);
422 *reason = "disabled because unknown";
423 return false;
424 }
425
426 const size_t key_bytelen = mbedtls_cipher_info_get_key_bitlen(cipher) / 8;
428 {
429 msg(D_LOW,
430 "Cipher algorithm '%s' uses a default key size (%zu bytes) "
431 "which is larger than " PACKAGE_NAME "'s current maximum key size "
432 "(%d bytes)",
434 *reason = "disabled due to key size too large";
435 return false;
436 }
437
438 *reason = NULL;
439 return true;
440}
441
442const char *
443cipher_kt_name(const char *ciphername)
444{
445 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
446 if (NULL == cipher_kt)
447 {
448 return "[null-cipher]";
449 }
450
452}
453
454int
455cipher_kt_key_size(const char *ciphername)
456{
457 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
458
459 if (NULL == cipher_kt)
460 {
461 return 0;
462 }
463
465}
466
467int
468cipher_kt_iv_size(const char *ciphername)
469{
470 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
471
472 if (NULL == cipher_kt)
473 {
474 return 0;
475 }
477}
478
479int
480cipher_kt_block_size(const char *ciphername)
481{
482 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
483 if (NULL == cipher_kt)
484 {
485 return 0;
486 }
488}
489
490int
491cipher_kt_tag_size(const char *ciphername)
492{
493 if (cipher_kt_mode_aead(ciphername))
494 {
496 }
497 return 0;
498}
499
500bool
501cipher_kt_insecure(const char *ciphername)
502{
503 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
504 if (!cipher_kt)
505 {
506 return true;
507 }
508
509 return !(cipher_kt_block_size(ciphername) >= 128 / 8
510#ifdef MBEDTLS_CHACHAPOLY_C
512#endif
513 );
514}
515
518{
521}
522
523bool
524cipher_kt_mode_cbc(const char *ciphername)
525{
526 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
527 return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
528}
529
530bool
531cipher_kt_mode_ofb_cfb(const char *ciphername)
532{
533 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
534 return cipher
535 && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB
536 || cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
537}
538
539bool
540cipher_kt_mode_aead(const char *ciphername)
541{
542 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
543 return cipher
544 && (cipher_kt_mode(cipher) == OPENVPN_MODE_GCM
545#ifdef MBEDTLS_CHACHAPOLY_C
547#endif
548 );
549}
550
551
552/*
553 *
554 * Generic cipher context functions
555 *
556 */
557
559cipher_ctx_new(void)
560{
563 return ctx;
564}
565
566void
568{
570 free(ctx);
571}
572
573void
574cipher_ctx_init(mbedtls_cipher_context_t *ctx, const uint8_t *key, const char *ciphername,
576{
577 ASSERT(NULL != ciphername && NULL != ctx);
578 CLEAR(*ctx);
579
580 const mbedtls_cipher_info_t *kt = cipher_get(ciphername);
581 ASSERT(kt);
583
584 if (!mbed_ok(mbedtls_cipher_setup(ctx, kt)))
585 {
586 msg(M_FATAL, "mbed TLS cipher context init #1");
587 }
588
590 {
591 msg(M_FATAL, "mbed TLS cipher set key");
592 }
593
595 {
597 {
598 msg(M_FATAL, "mbed TLS cipher set padding mode");
599 }
600 }
601
602 /* make sure we used a big enough key */
604}
605
606int
608{
609 return mbedtls_cipher_get_iv_size(ctx);
610}
611
612int
614{
615 if (tag_len > SIZE_MAX)
616 {
617 return 0;
618 }
619
620 if (!mbed_ok(mbedtls_cipher_write_tag(ctx, (unsigned char *)tag, tag_len)))
621 {
622 return 0;
623 }
624
625 return 1;
626}
627
628int
630{
631 return (int)mbedtls_cipher_get_block_size(ctx);
632}
633
634int
636{
637 ASSERT(NULL != ctx);
638
640}
641
642bool
644{
645 return ctx && cipher_ctx_mode(ctx) == OPENVPN_MODE_CBC;
646}
647
648
649bool
651{
652 return ctx
655}
656
657bool
659{
660 return ctx
662#ifdef MBEDTLS_CHACHAPOLY_C
664#endif
665 );
666}
667
668int
670{
671 if (!mbed_ok(mbedtls_cipher_reset(ctx)))
672 {
673 return 0;
674 }
675
677 {
678 return 0;
679 }
680
681 return 1;
682}
683
684int
686{
687 if (src_len > SIZE_MAX)
688 {
689 return 0;
690 }
691
693 {
694 return 0;
695 }
696
697 return 1;
698}
699
700int
702 int src_len)
703{
704 size_t s_dst_len = *dst_len;
705
706 if (!mbed_ok(mbedtls_cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len)))
707 {
708 return 0;
709 }
710
712
713 return 1;
714}
715
716int
718{
719 size_t s_dst_len = *dst_len;
720
722 {
723 return 0;
724 }
725
727
728 return 1;
729}
730
731int
733 size_t tag_len)
734{
735 size_t olen = 0;
736
738 {
739 return 0;
740 }
741
742 if (tag_len > SIZE_MAX)
743 {
744 return 0;
745 }
746
748 {
749 msg(D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__);
750 return 0;
751 }
752
753 if (olen > INT_MAX)
754 {
755 return 0;
756 }
757 *dst_len = olen;
758
759 if (!mbed_ok(mbedtls_cipher_check_tag(ctx, (const unsigned char *)tag, tag_len)))
760 {
761 return 0;
762 }
763
764 return 1;
765}
766
767#if defined(__GNUC__) || defined(__clang__)
768#pragma GCC diagnostic pop
769#endif
770
771/*
772 *
773 * Generic message digest information functions
774 *
775 */
776
777
778static const mbedtls_md_info_t *
779md_get(const char *digest)
780{
781 const mbedtls_md_info_t *md = NULL;
782 ASSERT(digest);
783
785 if (!md)
786 {
787 msg(M_FATAL, "Message hash algorithm '%s' not found", digest);
788 }
790 {
791 msg(M_FATAL,
792 "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME
793 "'s current maximum hash size (%d bytes)",
795 }
796 return md;
797}
798
799bool
800md_valid(const char *digest)
801{
803 return md != NULL;
804}
805
806const char *
807md_kt_name(const char *mdname)
808{
809 if (!strcmp("none", mdname))
810 {
811 return "[null-digest]";
812 }
813 const mbedtls_md_info_t *kt = md_get(mdname);
814 return mbedtls_md_get_name(kt);
815}
816
817unsigned char
818md_kt_size(const char *mdname)
819{
820 if (!strcmp("none", mdname))
821 {
822 return 0;
823 }
824 const mbedtls_md_info_t *kt = md_get(mdname);
825 return mbedtls_md_get_size(kt);
826}
827
828/*
829 *
830 * Generic message digest functions
831 *
832 */
833
834int
835md_full(const char *mdname, const uint8_t *src, int src_len, uint8_t *dst)
836{
837 const mbedtls_md_info_t *kt = md_get(mdname);
838 return 0 == mbedtls_md(kt, src, src_len, dst);
839}
840
842md_ctx_new(void)
843{
846 return ctx;
847}
848
849void
851{
852 free(ctx);
853}
854
855void
856md_ctx_init(mbedtls_md_context_t *ctx, const char *mdname)
857{
858 const mbedtls_md_info_t *kt = md_get(mdname);
859 ASSERT(NULL != ctx && NULL != kt);
860
861 mbedtls_md_init(ctx);
862 ASSERT(0 == mbedtls_md_setup(ctx, kt, 0));
863 ASSERT(0 == mbedtls_md_starts(ctx));
864}
865
866void
868{
869 mbedtls_md_free(ctx);
870}
871
872int
874{
875 if (NULL == ctx)
876 {
877 return 0;
878 }
880}
881
882void
884{
885 ASSERT(0 == mbedtls_md_update(ctx, src, src_len));
886}
887
888void
890{
891 ASSERT(0 == mbedtls_md_finish(ctx, dst));
892 mbedtls_md_free(ctx);
893}
894
895
896/*
897 *
898 * Generic HMAC functions
899 *
900 */
901
902
903/*
904 * TODO: re-enable dmsg for crypto debug
905 */
906
908hmac_ctx_new(void)
909{
912 return ctx;
913}
914
915void
917{
918 free(ctx);
919}
920
921void
922hmac_ctx_init(mbedtls_md_context_t *ctx, const uint8_t *key, const char *mdname)
923{
924 const mbedtls_md_info_t *kt = md_get(mdname);
925 ASSERT(NULL != kt && NULL != ctx);
926
927 mbedtls_md_init(ctx);
929 ASSERT(0 == mbedtls_md_setup(ctx, kt, 1));
931
932 /* make sure we used a big enough key */
934}
935
936void
938{
939 mbedtls_md_free(ctx);
940}
941
942int
944{
945 if (NULL == ctx)
946 {
947 return 0;
948 }
950}
951
952void
954{
955 ASSERT(0 == mbedtls_md_hmac_reset(ctx));
956}
957
958void
960{
962}
963
964void
966{
968}
969
970int
971memcmp_constant_time(const void *a, const void *b, size_t size)
972{
973 /* mbed TLS has a no const time memcmp function that it exposes
974 * via its APIs like OpenSSL does with CRYPTO_memcmp
975 * Adapt the function that mbedtls itself uses in
976 * mbedtls_safer_memcmp as it considers that to be safe */
977 volatile const unsigned char *A = (volatile const unsigned char *)a;
978 volatile const unsigned char *B = (volatile const unsigned char *)b;
979 volatile unsigned char diff = 0;
980
981 for (size_t i = 0; i < size; i++)
982 {
983 unsigned char x = A[i], y = B[i];
984 diff |= x ^ y;
985 }
986
987 return diff;
988}
989
990#if defined(__GNUC__) || defined(__clang__)
991#pragma GCC diagnostic push
992#pragma GCC diagnostic ignored "-Wconversion"
993#endif
994
995/*
996 * Generate the hash required by for the \c tls1_PRF function.
997 *
998 * @param md_kt Message digest to use
999 * @param sec Secret to base the hash on
1000 * @param sec_len Length of the secret
1001 * @param seed Seed to hash
1002 * @param seed_len Length of the seed
1003 * @param out Output buffer
1004 * @param olen Length of the output buffer
1005 */
1006static void
1007tls1_P_hash(const mbedtls_md_info_t *md_kt, const uint8_t *sec, size_t sec_len, const uint8_t *seed,
1008 size_t seed_len, uint8_t *out, size_t olen)
1009{
1010 struct gc_arena gc = gc_new();
1011 uint8_t A1[MAX_HMAC_KEY_LENGTH];
1012
1013#ifdef ENABLE_DEBUG
1014 /* used by the D_SHOW_KEY_SOURCE, guarded with ENABLE_DEBUG to avoid unused
1015 * variables warnings if compiled with --enable-small */
1016 const size_t olen_orig = olen;
1017 const uint8_t *out_orig = out;
1018#endif
1019
1020 hmac_ctx_t *ctx = hmac_ctx_new();
1021 hmac_ctx_t *ctx_tmp = hmac_ctx_new();
1022
1023 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc));
1024 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc));
1025
1026 unsigned int chunk = mbedtls_md_get_size(md_kt);
1027 unsigned int A1_len = mbedtls_md_get_size(md_kt);
1028
1029 /* This is the only place where we init an HMAC with a key that is not
1030 * equal to its size, therefore we init the hmac ctx manually here */
1031 mbedtls_md_init(ctx);
1032 ASSERT(0 == mbedtls_md_setup(ctx, md_kt, 1));
1033 ASSERT(0 == mbedtls_md_hmac_starts(ctx, sec, sec_len));
1034
1035 mbedtls_md_init(ctx_tmp);
1036 ASSERT(0 == mbedtls_md_setup(ctx_tmp, md_kt, 1));
1037 ASSERT(0 == mbedtls_md_hmac_starts(ctx_tmp, sec, sec_len));
1038
1039 hmac_ctx_update(ctx, seed, seed_len);
1040 hmac_ctx_final(ctx, A1);
1041
1042 for (;;)
1043 {
1044 hmac_ctx_reset(ctx);
1045 hmac_ctx_reset(ctx_tmp);
1046 hmac_ctx_update(ctx, A1, A1_len);
1047 hmac_ctx_update(ctx_tmp, A1, A1_len);
1048 hmac_ctx_update(ctx, seed, seed_len);
1049
1050 if (olen > chunk)
1051 {
1052 hmac_ctx_final(ctx, out);
1053 out += chunk;
1054 olen -= chunk;
1055 hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */
1056 }
1057 else /* last one */
1058 {
1059 hmac_ctx_final(ctx, A1);
1060 memcpy(out, A1, olen);
1061 break;
1062 }
1063 }
1064 hmac_ctx_cleanup(ctx);
1065 hmac_ctx_free(ctx);
1066 hmac_ctx_cleanup(ctx_tmp);
1067 hmac_ctx_free(ctx_tmp);
1068 secure_memzero(A1, sizeof(A1));
1069
1070 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc));
1071 gc_free(&gc);
1072}
1073
1074/*
1075 * Use the TLS PRF function for generating data channel keys.
1076 * This code is based on the OpenSSL library.
1077 *
1078 * TLS generates keys as such:
1079 *
1080 * master_secret[48] = PRF(pre_master_secret[48], "master secret",
1081 * ClientHello.random[32] + ServerHello.random[32])
1082 *
1083 * key_block[] = PRF(SecurityParameters.master_secret[48],
1084 * "key expansion",
1085 * SecurityParameters.server_random[32] +
1086 * SecurityParameters.client_random[32]);
1087 *
1088 * Notes:
1089 *
1090 * (1) key_block contains a full set of 4 keys.
1091 * (2) The pre-master secret is generated by the client.
1092 */
1093bool
1094ssl_tls1_PRF(const uint8_t *label, size_t label_len, const uint8_t *sec, size_t slen, uint8_t *out1,
1095 size_t olen)
1096{
1097 struct gc_arena gc = gc_new();
1098 const md_kt_t *md5 = md_get("MD5");
1099 const md_kt_t *sha1 = md_get("SHA1");
1100
1101 uint8_t *out2 = (uint8_t *)gc_malloc(olen, false, &gc);
1102
1103 size_t len = slen / 2;
1104 const uint8_t *S1 = sec;
1105 const uint8_t *S2 = &(sec[len]);
1106 len += (slen & 1); /* add for odd, make longer */
1107
1108 tls1_P_hash(md5, S1, len, label, label_len, out1, olen);
1109 tls1_P_hash(sha1, S2, len, label, label_len, out2, olen);
1110
1111 for (size_t i = 0; i < olen; i++)
1112 {
1113 out1[i] ^= out2[i];
1114 }
1115
1116 secure_memzero(out2, olen);
1117
1118 dmsg(D_SHOW_KEY_SOURCE, "tls1_PRF out[%zu]: %s", olen, format_hex(out1, olen, 0, &gc));
1119
1120 gc_free(&gc);
1121 return true;
1122}
1123
1124#if defined(__GNUC__) || defined(__clang__)
1125#pragma GCC diagnostic pop
1126#endif
1127
1128#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:532
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:1059
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
static char * format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
Definition buffer.h:503
#define BCAP(buf)
Definition buffer.h:129
static void gc_free(struct gc_arena *a)
Definition buffer.h:1025
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1064
static struct gc_arena gc_new(void)
Definition buffer.h:1017
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:1797
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:1810
void print_cipher(const char *ciphername)
Print a cipher list entry.
Definition crypto.c:1748
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)
void md_ctx_update(md_ctx_t *ctx, const uint8_t *src, size_t src_len)
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.
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
#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, tv_usec_t usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:104
unsigned int platform_getpid(void)
Definition platform.c:333
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