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-2024 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, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include "syshead.h"
35
36#if defined(ENABLE_CRYPTO_MBEDTLS)
37
38#include "errlevel.h"
39#include "basic.h"
40#include "buffer.h"
41#include "crypto.h"
42#include "integer.h"
43#include "crypto_backend.h"
44#include "otime.h"
45#include "mbedtls_compat.h"
46#include "misc.h"
47
48#include <mbedtls/base64.h>
49#include <mbedtls/des.h>
50#include <mbedtls/error.h>
51#include <mbedtls/md5.h>
52#include <mbedtls/cipher.h>
53#include <mbedtls/pem.h>
54
55#include <mbedtls/entropy.h>
56#include <mbedtls/ssl.h>
57
58
59/*
60 *
61 * Hardware engine support. Allows loading/unloading of engines.
62 *
63 */
64
65void
66crypto_init_lib_engine(const char *engine_name)
67{
68 msg(M_WARN, "Note: mbed TLS hardware crypto engine functionality is not "
69 "available");
70}
71
73crypto_load_provider(const char *provider)
74{
75 if (provider)
76 {
77 msg(M_WARN, "Note: mbed TLS provider functionality is not available");
78 }
79 return NULL;
80}
81
82void
83crypto_unload_provider(const char *provname, provider_t *provider)
84{
85}
86
87/*
88 *
89 * Functions related to the core crypto library
90 *
91 */
92
93void
95{
96}
97
98void
100{
101}
102
103void
105{
106}
107
108bool
109mbed_log_err(unsigned int flags, int errval, const char *prefix)
110{
111 if (0 != errval)
112 {
113 char errstr[256];
114 mbedtls_strerror(errval, errstr, sizeof(errstr));
115
116 if (NULL == prefix)
117 {
118 prefix = "mbed TLS error";
119 }
120 msg(flags, "%s: %s", prefix, errstr);
121 }
122
123 return 0 == errval;
124}
125
126bool
127mbed_log_func_line(unsigned int flags, int errval, const char *func,
128 int line)
129{
130 char prefix[256];
131
132 if (!snprintf(prefix, sizeof(prefix), "%s:%d", func, line))
133 {
134 return mbed_log_err(flags, errval, func);
135 }
136
137 return mbed_log_err(flags, errval, prefix);
138}
139
140
141#ifdef DMALLOC
142void
143crypto_init_dmalloc(void)
144{
145 msg(M_ERR, "Error: dmalloc support is not available for mbed TLS.");
146}
147#endif /* DMALLOC */
148
150 { "BF-CBC", "BLOWFISH-CBC" },
151 { "BF-CFB", "BLOWFISH-CFB64" },
152 { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" },
153 { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" },
154 { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" }
155};
158
159void
161{
162 const int *ciphers = mbedtls_cipher_list();
163
164#ifndef ENABLE_SMALL
165 printf("The following ciphers and cipher modes are available for use\n"
166 "with " PACKAGE_NAME ". Each cipher shown below may be used as a\n"
167 "parameter to the --data-ciphers (or --cipher) option. Using a\n"
168 "GCM or CBC mode is recommended. In static key mode only CBC\n"
169 "mode is allowed.\n\n");
170#endif
171
172 while (*ciphers != 0)
173 {
174 const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
175 const char *name = mbedtls_cipher_info_get_name(info);
176 if (info && name && !cipher_kt_insecure(name)
177 && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
178 {
179 print_cipher(name);
180 }
181 ciphers++;
182 }
183
184 printf("\nThe following ciphers have a block size of less than 128 bits, \n"
185 "and are therefore deprecated. Do not use unless you have to.\n\n");
186 ciphers = mbedtls_cipher_list();
187 while (*ciphers != 0)
188 {
189 const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
190 const char *name = mbedtls_cipher_info_get_name(info);
191 if (info && name && cipher_kt_insecure(name)
192 && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
193 {
194 print_cipher(name);
195 }
196 ciphers++;
197 }
198 printf("\n");
199}
200
201void
203{
204 const int *digests = mbedtls_md_list();
205
206#ifndef ENABLE_SMALL
207 printf("The following message digests are available for use with\n"
208 PACKAGE_NAME ". A message digest is used in conjunction with\n"
209 "the HMAC function, to authenticate received packets.\n"
210 "You can specify a message digest as parameter to\n"
211 "the --auth option.\n\n");
212#endif
213
214 while (*digests != 0)
215 {
216 const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*digests);
217
218 if (info)
219 {
220 printf("%s %d bit default key\n", mbedtls_md_get_name(info),
221 mbedtls_md_get_size(info) * 8);
222 }
223 digests++;
224 }
225 printf("\n");
226}
227
228void
230{
231 printf("Sorry, mbed TLS hardware crypto engine functionality is not "
232 "available\n");
233}
234
235bool
236crypto_pem_encode(const char *name, struct buffer *dst,
237 const struct buffer *src, struct gc_arena *gc)
238{
239 /* 1000 chars is the PEM line length limit (+1 for tailing NUL) */
240 char header[1000+1] = { 0 };
241 char footer[1000+1] = { 0 };
242
243 if (!snprintf(header, sizeof(header), "-----BEGIN %s-----\n", name))
244 {
245 return false;
246 }
247 if (!snprintf(footer, sizeof(footer), "-----END %s-----\n", name))
248 {
249 return false;
250 }
251
252 size_t out_len = 0;
253 if (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL !=
254 mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src),
255 NULL, 0, &out_len))
256 {
257 return false;
258 }
259
260 /* We set the size buf to out_len-1 to NOT include the 0 byte that
261 * mbedtls_pem_write_buffer in its length calculation */
262 *dst = alloc_buf_gc(out_len, gc);
263 if (!mbed_ok(mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src),
264 BPTR(dst), BCAP(dst), &out_len))
265 || !buf_inc_len(dst, out_len-1))
266 {
267 CLEAR(*dst);
268 return false;
269 }
270
271 return true;
272}
273
274bool
275crypto_pem_decode(const char *name, struct buffer *dst,
276 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))
283 {
284 return false;
285 }
286 if (!snprintf(footer, sizeof(footer), "-----END %s-----", name))
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 = mbed_ok(mbedtls_pem_read_buffer(&ctx, header, footer, BPTR(&input),
301 NULL, 0, &use_len));
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, time_string(0, 0, 0, &gc));
346
347 /* Initialise mbed TLS RNG, and built-in entropy sources */
349
353 {
354 msg(M_FATAL, "Failed to initialize random generator");
355 }
356
357 gc_free(&gc);
358 rand_initialised = true;
359 }
360
361 return &cd_ctx;
362}
363
364#ifdef ENABLE_PREDICTION_RESISTANCE
365void
367{
369
371}
372#endif /* ENABLE_PREDICTION_RESISTANCE */
373
374int
376{
378
379 while (len > 0)
380 {
383 {
384 return 0;
385 }
386
387 output += blen;
388 len -= blen;
389 }
390
391 return 1;
392}
393
394/*
395 *
396 * Generic cipher key type functions
397 *
398 */
399static const mbedtls_cipher_info_t *
400cipher_get(const char *ciphername)
401{
402 ASSERT(ciphername);
403
404 const mbedtls_cipher_info_t *cipher = NULL;
405
406 ciphername = translate_cipher_name_from_openvpn(ciphername);
407 cipher = mbedtls_cipher_info_from_string(ciphername);
408 return cipher;
409}
410
411bool
412cipher_valid_reason(const char *ciphername, const char **reason)
413{
414 ASSERT(reason);
415
416 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
417
418 if (NULL == cipher)
419 {
420 msg(D_LOW, "Cipher algorithm '%s' not found", ciphername);
421 *reason = "disabled because unknown";
422 return false;
423 }
424
425 const size_t key_bytelen = mbedtls_cipher_info_get_key_bitlen(cipher)/8;
427 {
428 msg(D_LOW, "Cipher algorithm '%s' uses a default key size (%zu bytes) "
429 "which is larger than " PACKAGE_NAME "'s current maximum key size "
430 "(%d bytes)", ciphername, key_bytelen, MAX_CIPHER_KEY_LENGTH);
431 *reason = "disabled due to key size too large";
432 return false;
433 }
434
435 *reason = NULL;
436 return true;
437}
438
439const char *
440cipher_kt_name(const char *ciphername)
441{
442 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
443 if (NULL == cipher_kt)
444 {
445 return "[null-cipher]";
446 }
447
449}
450
451int
452cipher_kt_key_size(const char *ciphername)
453{
454 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
455
456 if (NULL == cipher_kt)
457 {
458 return 0;
459 }
460
462}
463
464int
465cipher_kt_iv_size(const char *ciphername)
466{
467 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
468
469 if (NULL == cipher_kt)
470 {
471 return 0;
472 }
474}
475
476int
477cipher_kt_block_size(const char *ciphername)
478{
479 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
480 if (NULL == cipher_kt)
481 {
482 return 0;
483 }
485}
486
487int
488cipher_kt_tag_size(const char *ciphername)
489{
490 if (cipher_kt_mode_aead(ciphername))
491 {
493 }
494 return 0;
495}
496
497bool
498cipher_kt_insecure(const char *ciphername)
499{
500 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
501 if (!cipher_kt)
502 {
503 return true;
504 }
505
506 return !(cipher_kt_block_size(ciphername) >= 128 / 8
507#ifdef MBEDTLS_CHACHAPOLY_C
509#endif
510 );
511}
512
515{
518}
519
520bool
521cipher_kt_mode_cbc(const char *ciphername)
522{
523 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
524 return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
525}
526
527bool
528cipher_kt_mode_ofb_cfb(const char *ciphername)
529{
530 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
531 return cipher && (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 && (cipher_kt_mode(cipher) == OPENVPN_MODE_GCM
540#ifdef MBEDTLS_CHACHAPOLY_C
542#endif
543 );
544}
545
546
547/*
548 *
549 * Generic cipher context functions
550 *
551 */
552
554cipher_ctx_new(void)
555{
558 return ctx;
559}
560
561void
563{
565 free(ctx);
566}
567
568void
570 const char *ciphername, crypto_operation_t enc)
571{
572 ASSERT(NULL != ciphername && NULL != ctx);
573 CLEAR(*ctx);
574
575 const mbedtls_cipher_info_t *kt = cipher_get(ciphername);
576 ASSERT(kt);
578
579 if (!mbed_ok(mbedtls_cipher_setup(ctx, kt)))
580 {
581 msg(M_FATAL, "mbed TLS cipher context init #1");
582 }
583
585 {
586 msg(M_FATAL, "mbed TLS cipher set key");
587 }
588
590 {
592 {
593 msg(M_FATAL, "mbed TLS cipher set padding mode");
594 }
595 }
596
597 /* make sure we used a big enough key */
599}
600
601int
603{
604 return mbedtls_cipher_get_iv_size(ctx);
605}
606
607int
609{
610 if (tag_len > SIZE_MAX)
611 {
612 return 0;
613 }
614
615 if (!mbed_ok(mbedtls_cipher_write_tag(ctx, (unsigned char *) tag, tag_len)))
616 {
617 return 0;
618 }
619
620 return 1;
621}
622
623int
625{
626 return (int)mbedtls_cipher_get_block_size(ctx);
627}
628
629int
631{
632 ASSERT(NULL != ctx);
633
635}
636
637bool
639{
640 return ctx && cipher_ctx_mode(ctx) == OPENVPN_MODE_CBC;
641}
642
643
644bool
646{
647 return ctx && (cipher_ctx_mode(ctx) == OPENVPN_MODE_OFB
649}
650
651bool
653{
654 return ctx && (cipher_ctx_mode(ctx) == OPENVPN_MODE_GCM
655#ifdef MBEDTLS_CHACHAPOLY_C
657#endif
658 );
659}
660
661int
663{
664 if (!mbed_ok(mbedtls_cipher_reset(ctx)))
665 {
666 return 0;
667 }
668
670 {
671 return 0;
672 }
673
674 return 1;
675}
676
677int
679{
680 if (src_len > SIZE_MAX)
681 {
682 return 0;
683 }
684
686 {
687 return 0;
688 }
689
690 return 1;
691}
692
693int
695 int *dst_len, uint8_t *src, int src_len)
696{
697 size_t s_dst_len = *dst_len;
698
699 if (!mbed_ok(mbedtls_cipher_update(ctx, src, (size_t) src_len, dst,
700 &s_dst_len)))
701 {
702 return 0;
703 }
704
706
707 return 1;
708}
709
710int
712{
713 size_t s_dst_len = *dst_len;
714
716 {
717 return 0;
718 }
719
721
722 return 1;
723}
724
725int
727 int *dst_len, uint8_t *tag, size_t tag_len)
728{
729 size_t olen = 0;
730
732 {
733 return 0;
734 }
735
736 if (tag_len > SIZE_MAX)
737 {
738 return 0;
739 }
740
742 {
743 msg(D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__);
744 return 0;
745 }
746
747 if (olen > INT_MAX)
748 {
749 return 0;
750 }
751 *dst_len = olen;
752
753 if (!mbed_ok(mbedtls_cipher_check_tag(ctx, (const unsigned char *) tag,
754 tag_len)))
755 {
756 return 0;
757 }
758
759 return 1;
760}
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, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)",
785 digest,
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 HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1)
985bool
986ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
988{
991 output_len));
992}
993#else /* HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */
994/*
995 * Generate the hash required by for the \c tls1_PRF function.
996 *
997 * @param md_kt Message digest to use
998 * @param sec Secret to base the hash on
999 * @param sec_len Length of the secret
1000 * @param seed Seed to hash
1001 * @param seed_len Length of the seed
1002 * @param out Output buffer
1003 * @param olen Length of the output buffer
1004 */
1005static void
1007 const uint8_t *seed, int seed_len, uint8_t *out, int olen)
1008{
1009 struct gc_arena gc = gc_new();
1010 uint8_t A1[MAX_HMAC_KEY_LENGTH];
1011
1012#ifdef ENABLE_DEBUG
1013 /* used by the D_SHOW_KEY_SOURCE, guarded with ENABLE_DEBUG to avoid unused
1014 * variables warnings if compiled with --enable-small */
1015 const int olen_orig = olen;
1016 const uint8_t *out_orig = out;
1017#endif
1018
1019 hmac_ctx_t *ctx = hmac_ctx_new();
1020 hmac_ctx_t *ctx_tmp = hmac_ctx_new();
1021
1022 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc));
1023 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc));
1024
1025 int chunk = mbedtls_md_get_size(md_kt);
1026 unsigned int A1_len = mbedtls_md_get_size(md_kt);
1027
1028 /* This is the only place where we init an HMAC with a key that is not
1029 * equal to its size, therefore we init the hmac ctx manually here */
1030 mbedtls_md_init(ctx);
1031 ASSERT(0 == mbedtls_md_setup(ctx, md_kt, 1));
1032 ASSERT(0 == mbedtls_md_hmac_starts(ctx, sec, sec_len));
1033
1034 mbedtls_md_init(ctx_tmp);
1035 ASSERT(0 == mbedtls_md_setup(ctx_tmp, md_kt, 1));
1036 ASSERT(0 == mbedtls_md_hmac_starts(ctx_tmp, sec, sec_len));
1037
1038 hmac_ctx_update(ctx, seed, seed_len);
1039 hmac_ctx_final(ctx, A1);
1040
1041 for (;; )
1042 {
1043 hmac_ctx_reset(ctx);
1044 hmac_ctx_reset(ctx_tmp);
1045 hmac_ctx_update(ctx, A1, A1_len);
1046 hmac_ctx_update(ctx_tmp, A1, A1_len);
1047 hmac_ctx_update(ctx, seed, seed_len);
1048
1049 if (olen > chunk)
1050 {
1051 hmac_ctx_final(ctx, out);
1052 out += chunk;
1053 olen -= chunk;
1054 hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */
1055 }
1056 else /* last one */
1057 {
1058 hmac_ctx_final(ctx, A1);
1059 memcpy(out, A1, olen);
1060 break;
1061 }
1062 }
1063 hmac_ctx_cleanup(ctx);
1064 hmac_ctx_free(ctx);
1065 hmac_ctx_cleanup(ctx_tmp);
1066 hmac_ctx_free(ctx_tmp);
1067 secure_memzero(A1, sizeof(A1));
1068
1069 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc));
1070 gc_free(&gc);
1071}
1072
1073/*
1074 * Use the TLS PRF function for generating data channel keys.
1075 * This code is based on the OpenSSL library.
1076 *
1077 * TLS generates keys as such:
1078 *
1079 * master_secret[48] = PRF(pre_master_secret[48], "master secret",
1080 * ClientHello.random[32] + ServerHello.random[32])
1081 *
1082 * key_block[] = PRF(SecurityParameters.master_secret[48],
1083 * "key expansion",
1084 * SecurityParameters.server_random[32] +
1085 * SecurityParameters.client_random[32]);
1086 *
1087 * Notes:
1088 *
1089 * (1) key_block contains a full set of 4 keys.
1090 * (2) The pre-master secret is generated by the client.
1091 */
1092bool
1093ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec,
1094 int slen, uint8_t *out1, int olen)
1095{
1096 struct gc_arena gc = gc_new();
1097 const md_kt_t *md5 = md_get("MD5");
1098 const md_kt_t *sha1 = md_get("SHA1");
1099
1100 uint8_t *out2 = (uint8_t *)gc_malloc(olen, false, &gc);
1101
1102 int len = slen/2;
1103 const uint8_t *S1 = sec;
1104 const uint8_t *S2 = &(sec[len]);
1105 len += (slen&1); /* add for odd, make longer */
1106
1107 tls1_P_hash(md5, S1, len, label, label_len, out1, olen);
1108 tls1_P_hash(sha1, S2, len, label, label_len, out2, olen);
1109
1110 for (int i = 0; i<olen; i++)
1111 {
1112 out1[i] ^= out2[i];
1113 }
1114
1115 secure_memzero(out2, olen);
1116
1117 dmsg(D_SHOW_KEY_SOURCE, "tls1_PRF out[%d]: %s", olen, format_hex(out1, olen, 0, &gc));
1118
1119 gc_free(&gc);
1120 return true;
1121}
1122#endif /* HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */
1123#endif /* ENABLE_CRYPTO_MBEDTLS */
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
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:88
#define ALLOC_OBJ(dptr, type)
Definition buffer.h:1055
static char * format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
Definition buffer.h:505
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Definition buffer.h:712
#define BPTR(buf)
Definition buffer.h:124
static bool buf_inc_len(struct buffer *buf, int inc)
Definition buffer.h:590
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:668
#define BLEN(buf)
Definition buffer.h:127
#define BCAP(buf)
Definition buffer.h:130
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1060
static struct gc_arena gc_new(void)
Definition buffer.h:1025
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:1820
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:1833
void print_cipher(const char *ciphername)
Print a cipher list entry.
Definition crypto.c:1769
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...
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)
bool ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret, int secret_len, uint8_t *output, int output_len)
Calculates the TLS 1.0-1.1 PRF function.
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:58
#define D_SHOW_KEY_SOURCE
Definition errlevel.h:122
#define D_LOW
Definition errlevel.h:97
static int min_int(int x, int y)
Definition integer.h:102
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:33
#define M_FATAL
Definition error.h:89
#define dmsg(flags,...)
Definition error.h:148
#define M_ERR
Definition error.h:105
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
const char * time_string(time_t t, long usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:108
unsigned int platform_getpid(void)
Definition platform.c:333
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
Struct used in cipher name translation table.
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152
struct gc_arena gc
Definition test_ssl.c:155