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