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 Fox Crypto B.V. <openvpn@foxcrypto.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
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 (!snprintf(header, sizeof(header), "-----BEGIN %s-----\n", name))
242 {
243 return false;
244 }
245 if (!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, BPTR(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, BPTR(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 (!snprintf(header, sizeof(header), "-----BEGIN %s-----", name))
279 {
280 return false;
281 }
282 if (!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
361#ifdef ENABLE_PREDICTION_RESISTANCE
362void
364{
366
368}
369#endif /* ENABLE_PREDICTION_RESISTANCE */
370
371int
373{
375
376 while (len > 0)
377 {
380 {
381 return 0;
382 }
383
384 output += blen;
385 len -= blen;
386 }
387
388 return 1;
389}
390
391/*
392 *
393 * Generic cipher key type functions
394 *
395 */
396static const mbedtls_cipher_info_t *
397cipher_get(const char *ciphername)
398{
399 ASSERT(ciphername);
400
401 const mbedtls_cipher_info_t *cipher = NULL;
402
403 ciphername = translate_cipher_name_from_openvpn(ciphername);
404 cipher = mbedtls_cipher_info_from_string(ciphername);
405 return cipher;
406}
407
408bool
409cipher_valid_reason(const char *ciphername, const char **reason)
410{
411 ASSERT(reason);
412
413 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
414
415 if (NULL == cipher)
416 {
417 msg(D_LOW, "Cipher algorithm '%s' not found", ciphername);
418 *reason = "disabled because unknown";
419 return false;
420 }
421
422 const size_t key_bytelen = mbedtls_cipher_info_get_key_bitlen(cipher) / 8;
424 {
425 msg(D_LOW,
426 "Cipher algorithm '%s' uses a default key size (%zu bytes) "
427 "which is larger than " PACKAGE_NAME "'s current maximum key size "
428 "(%d bytes)",
430 *reason = "disabled due to key size too large";
431 return false;
432 }
433
434 *reason = NULL;
435 return true;
436}
437
438const char *
439cipher_kt_name(const char *ciphername)
440{
441 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
442 if (NULL == cipher_kt)
443 {
444 return "[null-cipher]";
445 }
446
448}
449
450int
451cipher_kt_key_size(const char *ciphername)
452{
453 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
454
455 if (NULL == cipher_kt)
456 {
457 return 0;
458 }
459
461}
462
463int
464cipher_kt_iv_size(const char *ciphername)
465{
466 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
467
468 if (NULL == cipher_kt)
469 {
470 return 0;
471 }
473}
474
475int
476cipher_kt_block_size(const char *ciphername)
477{
478 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
479 if (NULL == cipher_kt)
480 {
481 return 0;
482 }
484}
485
486int
487cipher_kt_tag_size(const char *ciphername)
488{
489 if (cipher_kt_mode_aead(ciphername))
490 {
492 }
493 return 0;
494}
495
496bool
497cipher_kt_insecure(const char *ciphername)
498{
499 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
500 if (!cipher_kt)
501 {
502 return true;
503 }
504
505 return !(cipher_kt_block_size(ciphername) >= 128 / 8
506#ifdef MBEDTLS_CHACHAPOLY_C
508#endif
509 );
510}
511
514{
517}
518
519bool
520cipher_kt_mode_cbc(const char *ciphername)
521{
522 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
523 return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
524}
525
526bool
527cipher_kt_mode_ofb_cfb(const char *ciphername)
528{
529 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
530 return cipher
531 && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB
532 || cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
533}
534
535bool
536cipher_kt_mode_aead(const char *ciphername)
537{
538 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
539 return cipher
540 && (cipher_kt_mode(cipher) == OPENVPN_MODE_GCM
541#ifdef MBEDTLS_CHACHAPOLY_C
543#endif
544 );
545}
546
547
548/*
549 *
550 * Generic cipher context functions
551 *
552 */
553
555cipher_ctx_new(void)
556{
559 return ctx;
560}
561
562void
564{
566 free(ctx);
567}
568
569void
570cipher_ctx_init(mbedtls_cipher_context_t *ctx, const uint8_t *key, const char *ciphername,
572{
573 ASSERT(NULL != ciphername && NULL != ctx);
574 CLEAR(*ctx);
575
576 const mbedtls_cipher_info_t *kt = cipher_get(ciphername);
577 ASSERT(kt);
579
580 if (!mbed_ok(mbedtls_cipher_setup(ctx, kt)))
581 {
582 msg(M_FATAL, "mbed TLS cipher context init #1");
583 }
584
586 {
587 msg(M_FATAL, "mbed TLS cipher set key");
588 }
589
591 {
593 {
594 msg(M_FATAL, "mbed TLS cipher set padding mode");
595 }
596 }
597
598 /* make sure we used a big enough key */
600}
601
602int
604{
605 return mbedtls_cipher_get_iv_size(ctx);
606}
607
608int
610{
611 if (tag_len > SIZE_MAX)
612 {
613 return 0;
614 }
615
616 if (!mbed_ok(mbedtls_cipher_write_tag(ctx, (unsigned char *)tag, tag_len)))
617 {
618 return 0;
619 }
620
621 return 1;
622}
623
624int
626{
627 return (int)mbedtls_cipher_get_block_size(ctx);
628}
629
630int
632{
633 ASSERT(NULL != ctx);
634
636}
637
638bool
640{
641 return ctx && cipher_ctx_mode(ctx) == OPENVPN_MODE_CBC;
642}
643
644
645bool
647{
648 return ctx
651}
652
653bool
655{
656 return ctx
658#ifdef MBEDTLS_CHACHAPOLY_C
660#endif
661 );
662}
663
664int
666{
667 if (!mbed_ok(mbedtls_cipher_reset(ctx)))
668 {
669 return 0;
670 }
671
673 {
674 return 0;
675 }
676
677 return 1;
678}
679
680int
682{
683 if (src_len > SIZE_MAX)
684 {
685 return 0;
686 }
687
689 {
690 return 0;
691 }
692
693 return 1;
694}
695
696int
698 int src_len)
699{
700 size_t s_dst_len = *dst_len;
701
702 if (!mbed_ok(mbedtls_cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len)))
703 {
704 return 0;
705 }
706
708
709 return 1;
710}
711
712int
714{
715 size_t s_dst_len = *dst_len;
716
718 {
719 return 0;
720 }
721
723
724 return 1;
725}
726
727int
729 size_t tag_len)
730{
731 size_t olen = 0;
732
734 {
735 return 0;
736 }
737
738 if (tag_len > SIZE_MAX)
739 {
740 return 0;
741 }
742
744 {
745 msg(D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__);
746 return 0;
747 }
748
749 if (olen > INT_MAX)
750 {
751 return 0;
752 }
753 *dst_len = olen;
754
755 if (!mbed_ok(mbedtls_cipher_check_tag(ctx, (const unsigned char *)tag, tag_len)))
756 {
757 return 0;
758 }
759
760 return 1;
761}
762
763
764/*
765 *
766 * Generic message digest information functions
767 *
768 */
769
770
771static const mbedtls_md_info_t *
772md_get(const char *digest)
773{
774 const mbedtls_md_info_t *md = NULL;
775 ASSERT(digest);
776
778 if (!md)
779 {
780 msg(M_FATAL, "Message hash algorithm '%s' not found", digest);
781 }
783 {
784 msg(M_FATAL,
785 "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME
786 "'s current maximum hash size (%d bytes)",
788 }
789 return md;
790}
791
792bool
793md_valid(const char *digest)
794{
796 return md != NULL;
797}
798
799const char *
800md_kt_name(const char *mdname)
801{
802 if (!strcmp("none", mdname))
803 {
804 return "[null-digest]";
805 }
806 const mbedtls_md_info_t *kt = md_get(mdname);
807 return mbedtls_md_get_name(kt);
808}
809
810unsigned char
811md_kt_size(const char *mdname)
812{
813 if (!strcmp("none", mdname))
814 {
815 return 0;
816 }
817 const mbedtls_md_info_t *kt = md_get(mdname);
818 return mbedtls_md_get_size(kt);
819}
820
821/*
822 *
823 * Generic message digest functions
824 *
825 */
826
827int
828md_full(const char *mdname, const uint8_t *src, int src_len, uint8_t *dst)
829{
830 const mbedtls_md_info_t *kt = md_get(mdname);
831 return 0 == mbedtls_md(kt, src, src_len, dst);
832}
833
835md_ctx_new(void)
836{
839 return ctx;
840}
841
842void
844{
845 free(ctx);
846}
847
848void
849md_ctx_init(mbedtls_md_context_t *ctx, const char *mdname)
850{
851 const mbedtls_md_info_t *kt = md_get(mdname);
852 ASSERT(NULL != ctx && NULL != kt);
853
854 mbedtls_md_init(ctx);
855 ASSERT(0 == mbedtls_md_setup(ctx, kt, 0));
856 ASSERT(0 == mbedtls_md_starts(ctx));
857}
858
859void
861{
862 mbedtls_md_free(ctx);
863}
864
865int
867{
868 if (NULL == ctx)
869 {
870 return 0;
871 }
873}
874
875void
877{
878 ASSERT(0 == mbedtls_md_update(ctx, src, src_len));
879}
880
881void
883{
884 ASSERT(0 == mbedtls_md_finish(ctx, dst));
885 mbedtls_md_free(ctx);
886}
887
888
889/*
890 *
891 * Generic HMAC functions
892 *
893 */
894
895
896/*
897 * TODO: re-enable dmsg for crypto debug
898 */
899
901hmac_ctx_new(void)
902{
905 return ctx;
906}
907
908void
910{
911 free(ctx);
912}
913
914void
915hmac_ctx_init(mbedtls_md_context_t *ctx, const uint8_t *key, const char *mdname)
916{
917 const mbedtls_md_info_t *kt = md_get(mdname);
918 ASSERT(NULL != kt && NULL != ctx);
919
920 mbedtls_md_init(ctx);
922 ASSERT(0 == mbedtls_md_setup(ctx, kt, 1));
924
925 /* make sure we used a big enough key */
927}
928
929void
931{
932 mbedtls_md_free(ctx);
933}
934
935int
937{
938 if (NULL == ctx)
939 {
940 return 0;
941 }
943}
944
945void
947{
948 ASSERT(0 == mbedtls_md_hmac_reset(ctx));
949}
950
951void
953{
955}
956
957void
959{
961}
962
963int
964memcmp_constant_time(const void *a, const void *b, size_t size)
965{
966 /* mbed TLS has a no const time memcmp function that it exposes
967 * via its APIs like OpenSSL does with CRYPTO_memcmp
968 * Adapt the function that mbedtls itself uses in
969 * mbedtls_safer_memcmp as it considers that to be safe */
970 volatile const unsigned char *A = (volatile const unsigned char *)a;
971 volatile const unsigned char *B = (volatile const unsigned char *)b;
972 volatile unsigned char diff = 0;
973
974 for (size_t i = 0; i < size; i++)
975 {
976 unsigned char x = A[i], y = B[i];
977 diff |= x ^ y;
978 }
979
980 return diff;
981}
982/* mbedtls-2.18.0 or newer implements tls_prf, but prf_tls1 is removed
983 * from recent versions, so we use our own implementation if necessary. */
984#if defined(HAVE_MBEDTLS_SSL_TLS_PRF) && defined(MBEDTLS_SSL_TLS_PRF_TLS1)
985bool
986ssl_tls1_PRF(const uint8_t *seed, size_t seed_len, const uint8_t *secret, size_t secret_len,
987 uint8_t *output, size_t output_len)
988{
991}
992#else /* defined(HAVE_MBEDTLS_SSL_TLS_PRF) && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */
993/*
994 * Generate the hash required by for the \c tls1_PRF function.
995 *
996 * @param md_kt Message digest to use
997 * @param sec Secret to base the hash on
998 * @param sec_len Length of the secret
999 * @param seed Seed to hash
1000 * @param seed_len Length of the seed
1001 * @param out Output buffer
1002 * @param olen Length of the output buffer
1003 */
1004static void
1005tls1_P_hash(const mbedtls_md_info_t *md_kt, const uint8_t *sec, size_t sec_len, const uint8_t *seed,
1006 size_t seed_len, uint8_t *out, size_t olen)
1007{
1008 struct gc_arena gc = gc_new();
1009 uint8_t A1[MAX_HMAC_KEY_LENGTH];
1010
1011#ifdef ENABLE_DEBUG
1012 /* used by the D_SHOW_KEY_SOURCE, guarded with ENABLE_DEBUG to avoid unused
1013 * variables warnings if compiled with --enable-small */
1014 const size_t olen_orig = olen;
1015 const uint8_t *out_orig = out;
1016#endif
1017
1018 hmac_ctx_t *ctx = hmac_ctx_new();
1019 hmac_ctx_t *ctx_tmp = hmac_ctx_new();
1020
1021 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc));
1022 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc));
1023
1024 unsigned int chunk = mbedtls_md_get_size(md_kt);
1025 unsigned int A1_len = mbedtls_md_get_size(md_kt);
1026
1027 /* This is the only place where we init an HMAC with a key that is not
1028 * equal to its size, therefore we init the hmac ctx manually here */
1029 mbedtls_md_init(ctx);
1030 ASSERT(0 == mbedtls_md_setup(ctx, md_kt, 1));
1031 ASSERT(0 == mbedtls_md_hmac_starts(ctx, sec, sec_len));
1032
1033 mbedtls_md_init(ctx_tmp);
1034 ASSERT(0 == mbedtls_md_setup(ctx_tmp, md_kt, 1));
1035 ASSERT(0 == mbedtls_md_hmac_starts(ctx_tmp, sec, sec_len));
1036
1037 hmac_ctx_update(ctx, seed, seed_len);
1038 hmac_ctx_final(ctx, A1);
1039
1040 for (;;)
1041 {
1042 hmac_ctx_reset(ctx);
1043 hmac_ctx_reset(ctx_tmp);
1044 hmac_ctx_update(ctx, A1, A1_len);
1045 hmac_ctx_update(ctx_tmp, A1, A1_len);
1046 hmac_ctx_update(ctx, seed, seed_len);
1047
1048 if (olen > chunk)
1049 {
1050 hmac_ctx_final(ctx, out);
1051 out += chunk;
1052 olen -= chunk;
1053 hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */
1054 }
1055 else /* last one */
1056 {
1057 hmac_ctx_final(ctx, A1);
1058 memcpy(out, A1, olen);
1059 break;
1060 }
1061 }
1062 hmac_ctx_cleanup(ctx);
1063 hmac_ctx_free(ctx);
1064 hmac_ctx_cleanup(ctx_tmp);
1065 hmac_ctx_free(ctx_tmp);
1066 secure_memzero(A1, sizeof(A1));
1067
1068 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc));
1069 gc_free(&gc);
1070}
1071
1072/*
1073 * Use the TLS PRF function for generating data channel keys.
1074 * This code is based on the OpenSSL library.
1075 *
1076 * TLS generates keys as such:
1077 *
1078 * master_secret[48] = PRF(pre_master_secret[48], "master secret",
1079 * ClientHello.random[32] + ServerHello.random[32])
1080 *
1081 * key_block[] = PRF(SecurityParameters.master_secret[48],
1082 * "key expansion",
1083 * SecurityParameters.server_random[32] +
1084 * SecurityParameters.client_random[32]);
1085 *
1086 * Notes:
1087 *
1088 * (1) key_block contains a full set of 4 keys.
1089 * (2) The pre-master secret is generated by the client.
1090 */
1091bool
1092ssl_tls1_PRF(const uint8_t *label, size_t label_len, const uint8_t *sec, size_t slen, uint8_t *out1,
1093 size_t olen)
1094{
1095 struct gc_arena gc = gc_new();
1096 const md_kt_t *md5 = md_get("MD5");
1097 const md_kt_t *sha1 = md_get("SHA1");
1098
1099 uint8_t *out2 = (uint8_t *)gc_malloc(olen, false, &gc);
1100
1101 size_t len = slen / 2;
1102 const uint8_t *S1 = sec;
1103 const uint8_t *S2 = &(sec[len]);
1104 len += (slen & 1); /* add for odd, make longer */
1105
1106 tls1_P_hash(md5, S1, len, label, label_len, out1, olen);
1107 tls1_P_hash(sha1, S2, len, label, label_len, out2, olen);
1108
1109 for (size_t i = 0; i < olen; i++)
1110 {
1111 out1[i] ^= out2[i];
1112 }
1113
1114 secure_memzero(out2, olen);
1115
1116 dmsg(D_SHOW_KEY_SOURCE, "tls1_PRF out[%zu]: %s", olen, format_hex(out1, olen, 0, &gc));
1117
1118 gc_free(&gc);
1119 return true;
1120}
1121#endif /* HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */
1122#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
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:1777
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:1790
void print_cipher(const char *ciphername)
Print a cipher list entry.
Definition crypto.c:1728
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:88
#define dmsg(flags,...)
Definition error.h:170
#define M_ERR
Definition error.h:104
#define msg(flags,...)
Definition error.h:150
#define ASSERT(x)
Definition error.h:217
#define M_WARN
Definition error.h:90
const char * time_string(time_t t, long usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:104
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:154