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 (snprintf(prefix, sizeof(prefix), "%s:%d", func, line) >= sizeof(prefix))
134 {
135 return mbed_log_err(flags, errval, func);
136 }
137
138 return mbed_log_err(flags, errval, prefix);
139}
140
141
142#ifdef DMALLOC
143void
144crypto_init_dmalloc(void)
145{
146 msg(M_ERR, "Error: dmalloc support is not available for mbed TLS.");
147}
148#endif /* DMALLOC */
149
151 { "BF-CBC", "BLOWFISH-CBC" },
152 { "BF-CFB", "BLOWFISH-CFB64" },
153 { "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" },
154 { "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" },
155 { "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" }
156};
159
160void
162{
163 const int *ciphers = mbedtls_cipher_list();
164
165#ifndef ENABLE_SMALL
166 printf("The following ciphers and cipher modes are available for use\n"
167 "with " PACKAGE_NAME ". Each cipher shown below may be used as a\n"
168 "parameter to the --data-ciphers (or --cipher) option. Using a\n"
169 "GCM or CBC mode is recommended. In static key mode only CBC\n"
170 "mode is allowed.\n\n");
171#endif
172
173 while (*ciphers != 0)
174 {
175 const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
176 const char *name = mbedtls_cipher_info_get_name(info);
177 if (info && name && !cipher_kt_insecure(name)
178 && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
179 {
180 print_cipher(name);
181 }
182 ciphers++;
183 }
184
185 printf("\nThe following ciphers have a block size of less than 128 bits, \n"
186 "and are therefore deprecated. Do not use unless you have to.\n\n");
187 ciphers = mbedtls_cipher_list();
188 while (*ciphers != 0)
189 {
190 const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
191 const char *name = mbedtls_cipher_info_get_name(info);
192 if (info && name && cipher_kt_insecure(name)
193 && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
194 {
195 print_cipher(name);
196 }
197 ciphers++;
198 }
199 printf("\n");
200}
201
202void
204{
205 const int *digests = mbedtls_md_list();
206
207#ifndef ENABLE_SMALL
208 printf("The following message digests are available for use with\n" PACKAGE_NAME
209 ". A message digest is used in conjunction with\n"
210 "the HMAC function, to authenticate received packets.\n"
211 "You can specify a message digest as parameter to\n"
212 "the --auth option.\n\n");
213#endif
214
215 while (*digests != 0)
216 {
217 const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*digests);
218
219 if (info)
220 {
221 printf("%s %d bit default key\n", mbedtls_md_get_name(info),
222 mbedtls_md_get_size(info) * 8);
223 }
224 digests++;
225 }
226 printf("\n");
227}
228
229void
231{
232 printf("Sorry, mbed TLS hardware crypto engine functionality is not "
233 "available\n");
234}
235
236#if defined(__GNUC__) || defined(__clang__)
237#pragma GCC diagnostic push
238#pragma GCC diagnostic ignored "-Wconversion"
239#endif
240
241bool
242crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src,
243 struct gc_arena *gc)
244{
245 /* 1000 chars is the PEM line length limit (+1 for tailing NUL) */
246 char header[1000 + 1] = { 0 };
247 char footer[1000 + 1] = { 0 };
248
249 if (snprintf(header, sizeof(header), "-----BEGIN %s-----\n", name) >= sizeof(header))
250 {
251 return false;
252 }
253 if (snprintf(footer, sizeof(footer), "-----END %s-----\n", name) >= sizeof(footer))
254 {
255 return false;
256 }
257
258 size_t out_len = 0;
259 if (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
260 != mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src), NULL, 0, &out_len))
261 {
262 return false;
263 }
264
265 /* We set the size buf to out_len-1 to NOT include the 0 byte that
266 * mbedtls_pem_write_buffer in its length calculation */
267 *dst = alloc_buf_gc(out_len, gc);
268 if (!mbed_ok(mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src), BPTR(dst),
269 BCAP(dst), &out_len))
270 || !buf_inc_len(dst, out_len - 1))
271 {
272 CLEAR(*dst);
273 return false;
274 }
275
276 return true;
277}
278
279bool
280crypto_pem_decode(const char *name, struct buffer *dst, const struct buffer *src)
281{
282 /* 1000 chars is the PEM line length limit (+1 for tailing NUL) */
283 char header[1000 + 1] = { 0 };
284 char footer[1000 + 1] = { 0 };
285
286 if (snprintf(header, sizeof(header), "-----BEGIN %s-----", name) >= sizeof(header))
287 {
288 return false;
289 }
290 if (snprintf(footer, sizeof(footer), "-----END %s-----", name) >= sizeof(footer))
291 {
292 return false;
293 }
294
295 /* mbed TLS requires the src to be null-terminated */
296 /* allocate a new buffer to avoid modifying the src buffer */
297 struct gc_arena gc = gc_new();
298 struct buffer input = alloc_buf_gc(BLEN(src) + 1, &gc);
299 buf_copy(&input, src);
301
302 size_t use_len = 0;
303 mbedtls_pem_context ctx = { 0 };
304 bool ret =
306 size_t buf_size = 0;
307 const unsigned char *buf = mbedtls_pem_get_buffer(&ctx, &buf_size);
308 if (ret && !buf_write(dst, buf, buf_size))
309 {
310 ret = false;
311 msg(M_WARN, "PEM decode error: destination buffer too small");
312 }
313
314 mbedtls_pem_free(&ctx);
315 gc_free(&gc);
316 return ret;
317}
318
319/*
320 *
321 * Random number functions, used in cases where we want
322 * reasonably strong cryptographic random number generation
323 * without depleting our entropy pool. Used for random
324 * IV values and a number of other miscellaneous tasks.
325 *
326 */
327
328/*
329 * Initialise the given ctr_drbg context, using a personalisation string and an
330 * entropy gathering function.
331 */
333rand_ctx_get(void)
334{
335 static mbedtls_entropy_context ec = { 0 };
336 static mbedtls_ctr_drbg_context cd_ctx = { 0 };
337 static bool rand_initialised = false;
338
339 if (!rand_initialised)
340 {
341 struct gc_arena gc = gc_new();
342 struct buffer pers_string = alloc_buf_gc(100, &gc);
343
344 /*
345 * Personalisation string, should be as unique as possible (see NIST
346 * 800-90 section 8.7.1). We have very little information at this stage.
347 * Include Program Name, memory address of the context and PID.
348 */
349 buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx,
350 time_string(0, 0, 0, &gc));
351
352 /* Initialise mbed TLS RNG, and built-in entropy sources */
354
357 BLEN(&pers_string))))
358 {
359 msg(M_FATAL, "Failed to initialize random generator");
360 }
361
362 gc_free(&gc);
363 rand_initialised = true;
364 }
365
366 return &cd_ctx;
367}
368
369#ifdef ENABLE_PREDICTION_RESISTANCE
370void
372{
374
376}
377#endif /* ENABLE_PREDICTION_RESISTANCE */
378
379int
381{
383
384 while (len > 0)
385 {
388 {
389 return 0;
390 }
391
392 output += blen;
393 len -= blen;
394 }
395
396 return 1;
397}
398
399/*
400 *
401 * Generic cipher key type functions
402 *
403 */
404static const mbedtls_cipher_info_t *
405cipher_get(const char *ciphername)
406{
407 ASSERT(ciphername);
408
409 const mbedtls_cipher_info_t *cipher = NULL;
410
411 ciphername = translate_cipher_name_from_openvpn(ciphername);
412 cipher = mbedtls_cipher_info_from_string(ciphername);
413 return cipher;
414}
415
416bool
417cipher_valid_reason(const char *ciphername, const char **reason)
418{
419 ASSERT(reason);
420
421 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
422
423 if (NULL == cipher)
424 {
425 msg(D_LOW, "Cipher algorithm '%s' not found", ciphername);
426 *reason = "disabled because unknown";
427 return false;
428 }
429
430 const size_t key_bytelen = mbedtls_cipher_info_get_key_bitlen(cipher) / 8;
432 {
433 msg(D_LOW,
434 "Cipher algorithm '%s' uses a default key size (%zu bytes) "
435 "which is larger than " PACKAGE_NAME "'s current maximum key size "
436 "(%d bytes)",
438 *reason = "disabled due to key size too large";
439 return false;
440 }
441
442 *reason = NULL;
443 return true;
444}
445
446const char *
447cipher_kt_name(const char *ciphername)
448{
449 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
450 if (NULL == cipher_kt)
451 {
452 return "[null-cipher]";
453 }
454
456}
457
458int
459cipher_kt_key_size(const char *ciphername)
460{
461 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
462
463 if (NULL == cipher_kt)
464 {
465 return 0;
466 }
467
469}
470
471int
472cipher_kt_iv_size(const char *ciphername)
473{
474 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
475
476 if (NULL == cipher_kt)
477 {
478 return 0;
479 }
481}
482
483int
484cipher_kt_block_size(const char *ciphername)
485{
486 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
487 if (NULL == cipher_kt)
488 {
489 return 0;
490 }
492}
493
494int
495cipher_kt_tag_size(const char *ciphername)
496{
497 if (cipher_kt_mode_aead(ciphername))
498 {
500 }
501 return 0;
502}
503
504bool
505cipher_kt_insecure(const char *ciphername)
506{
507 const mbedtls_cipher_info_t *cipher_kt = cipher_get(ciphername);
508 if (!cipher_kt)
509 {
510 return true;
511 }
512
513 return !(cipher_kt_block_size(ciphername) >= 128 / 8
514#ifdef MBEDTLS_CHACHAPOLY_C
516#endif
517 );
518}
519
522{
525}
526
527bool
528cipher_kt_mode_cbc(const char *ciphername)
529{
530 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
531 return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC;
532}
533
534bool
535cipher_kt_mode_ofb_cfb(const char *ciphername)
536{
537 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
538 return cipher
539 && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB
540 || cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
541}
542
543bool
544cipher_kt_mode_aead(const char *ciphername)
545{
546 const mbedtls_cipher_info_t *cipher = cipher_get(ciphername);
547 return cipher
548 && (cipher_kt_mode(cipher) == OPENVPN_MODE_GCM
549#ifdef MBEDTLS_CHACHAPOLY_C
551#endif
552 );
553}
554
555
556/*
557 *
558 * Generic cipher context functions
559 *
560 */
561
563cipher_ctx_new(void)
564{
567 return ctx;
568}
569
570void
572{
574 free(ctx);
575}
576
577void
578cipher_ctx_init(mbedtls_cipher_context_t *ctx, const uint8_t *key, const char *ciphername,
580{
581 ASSERT(NULL != ciphername && NULL != ctx);
582 CLEAR(*ctx);
583
584 const mbedtls_cipher_info_t *kt = cipher_get(ciphername);
585 ASSERT(kt);
587
588 if (!mbed_ok(mbedtls_cipher_setup(ctx, kt)))
589 {
590 msg(M_FATAL, "mbed TLS cipher context init #1");
591 }
592
594 {
595 msg(M_FATAL, "mbed TLS cipher set key");
596 }
597
599 {
601 {
602 msg(M_FATAL, "mbed TLS cipher set padding mode");
603 }
604 }
605
606 /* make sure we used a big enough key */
608}
609
610int
612{
613 return mbedtls_cipher_get_iv_size(ctx);
614}
615
616int
618{
619 if (tag_len > SIZE_MAX)
620 {
621 return 0;
622 }
623
624 if (!mbed_ok(mbedtls_cipher_write_tag(ctx, (unsigned char *)tag, tag_len)))
625 {
626 return 0;
627 }
628
629 return 1;
630}
631
632int
634{
635 return (int)mbedtls_cipher_get_block_size(ctx);
636}
637
638int
640{
641 ASSERT(NULL != ctx);
642
644}
645
646bool
648{
649 return ctx && cipher_ctx_mode(ctx) == OPENVPN_MODE_CBC;
650}
651
652
653bool
655{
656 return ctx
659}
660
661bool
663{
664 return ctx
666#ifdef MBEDTLS_CHACHAPOLY_C
668#endif
669 );
670}
671
672int
674{
675 if (!mbed_ok(mbedtls_cipher_reset(ctx)))
676 {
677 return 0;
678 }
679
681 {
682 return 0;
683 }
684
685 return 1;
686}
687
688int
690{
691 if (src_len > SIZE_MAX)
692 {
693 return 0;
694 }
695
697 {
698 return 0;
699 }
700
701 return 1;
702}
703
704int
706 int src_len)
707{
708 size_t s_dst_len = *dst_len;
709
710 if (!mbed_ok(mbedtls_cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len)))
711 {
712 return 0;
713 }
714
716
717 return 1;
718}
719
720int
722{
723 size_t s_dst_len = *dst_len;
724
726 {
727 return 0;
728 }
729
731
732 return 1;
733}
734
735int
737 size_t tag_len)
738{
739 size_t olen = 0;
740
742 {
743 return 0;
744 }
745
746 if (tag_len > SIZE_MAX)
747 {
748 return 0;
749 }
750
752 {
753 msg(D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__);
754 return 0;
755 }
756
757 if (olen > INT_MAX)
758 {
759 return 0;
760 }
761 *dst_len = olen;
762
763 if (!mbed_ok(mbedtls_cipher_check_tag(ctx, (const unsigned char *)tag, tag_len)))
764 {
765 return 0;
766 }
767
768 return 1;
769}
770
771#if defined(__GNUC__) || defined(__clang__)
772#pragma GCC diagnostic pop
773#endif
774
775/*
776 *
777 * Generic message digest information functions
778 *
779 */
780
781
782static const mbedtls_md_info_t *
783md_get(const char *digest)
784{
785 const mbedtls_md_info_t *md = NULL;
786 ASSERT(digest);
787
789 if (!md)
790 {
791 msg(M_FATAL, "Message hash algorithm '%s' not found", digest);
792 }
794 {
795 msg(M_FATAL,
796 "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME
797 "'s current maximum hash size (%d bytes)",
799 }
800 return md;
801}
802
803bool
804md_valid(const char *digest)
805{
807 return md != NULL;
808}
809
810const char *
811md_kt_name(const char *mdname)
812{
813 if (!strcmp("none", mdname))
814 {
815 return "[null-digest]";
816 }
817 const mbedtls_md_info_t *kt = md_get(mdname);
818 return mbedtls_md_get_name(kt);
819}
820
821unsigned char
822md_kt_size(const char *mdname)
823{
824 if (!strcmp("none", mdname))
825 {
826 return 0;
827 }
828 const mbedtls_md_info_t *kt = md_get(mdname);
829 return mbedtls_md_get_size(kt);
830}
831
832/*
833 *
834 * Generic message digest functions
835 *
836 */
837
838int
839md_full(const char *mdname, const uint8_t *src, int src_len, uint8_t *dst)
840{
841 const mbedtls_md_info_t *kt = md_get(mdname);
842 return 0 == mbedtls_md(kt, src, src_len, dst);
843}
844
846md_ctx_new(void)
847{
850 return ctx;
851}
852
853void
855{
856 free(ctx);
857}
858
859void
860md_ctx_init(mbedtls_md_context_t *ctx, const char *mdname)
861{
862 const mbedtls_md_info_t *kt = md_get(mdname);
863 ASSERT(NULL != ctx && NULL != kt);
864
865 mbedtls_md_init(ctx);
866 ASSERT(0 == mbedtls_md_setup(ctx, kt, 0));
867 ASSERT(0 == mbedtls_md_starts(ctx));
868}
869
870void
872{
873 mbedtls_md_free(ctx);
874}
875
876int
878{
879 if (NULL == ctx)
880 {
881 return 0;
882 }
884}
885
886void
888{
889 ASSERT(0 == mbedtls_md_update(ctx, src, src_len));
890}
891
892void
894{
895 ASSERT(0 == mbedtls_md_finish(ctx, dst));
896 mbedtls_md_free(ctx);
897}
898
899
900/*
901 *
902 * Generic HMAC functions
903 *
904 */
905
906
907/*
908 * TODO: re-enable dmsg for crypto debug
909 */
910
912hmac_ctx_new(void)
913{
916 return ctx;
917}
918
919void
921{
922 free(ctx);
923}
924
925void
926hmac_ctx_init(mbedtls_md_context_t *ctx, const uint8_t *key, const char *mdname)
927{
928 const mbedtls_md_info_t *kt = md_get(mdname);
929 ASSERT(NULL != kt && NULL != ctx);
930
931 mbedtls_md_init(ctx);
933 ASSERT(0 == mbedtls_md_setup(ctx, kt, 1));
935
936 /* make sure we used a big enough key */
938}
939
940void
942{
943 mbedtls_md_free(ctx);
944}
945
946int
948{
949 if (NULL == ctx)
950 {
951 return 0;
952 }
954}
955
956void
958{
959 ASSERT(0 == mbedtls_md_hmac_reset(ctx));
960}
961
962void
964{
966}
967
968void
970{
972}
973
974int
975memcmp_constant_time(const void *a, const void *b, size_t size)
976{
977 /* mbed TLS has a no const time memcmp function that it exposes
978 * via its APIs like OpenSSL does with CRYPTO_memcmp
979 * Adapt the function that mbedtls itself uses in
980 * mbedtls_safer_memcmp as it considers that to be safe */
981 volatile const unsigned char *A = (volatile const unsigned char *)a;
982 volatile const unsigned char *B = (volatile const unsigned char *)b;
983 volatile unsigned char diff = 0;
984
985 for (size_t i = 0; i < size; i++)
986 {
987 unsigned char x = A[i], y = B[i];
988 diff |= x ^ y;
989 }
990
991 return diff;
992}
993
994#if defined(__GNUC__) || defined(__clang__)
995#pragma GCC diagnostic push
996#pragma GCC diagnostic ignored "-Wconversion"
997#endif
998
999/*
1000 * Generate the hash required by for the \c tls1_PRF function.
1001 *
1002 * @param md_kt Message digest to use
1003 * @param sec Secret to base the hash on
1004 * @param sec_len Length of the secret
1005 * @param seed Seed to hash
1006 * @param seed_len Length of the seed
1007 * @param out Output buffer
1008 * @param olen Length of the output buffer
1009 */
1010static void
1011tls1_P_hash(const mbedtls_md_info_t *md_kt, const uint8_t *sec, size_t sec_len, const uint8_t *seed,
1012 size_t seed_len, uint8_t *out, size_t olen)
1013{
1014 struct gc_arena gc = gc_new();
1015 uint8_t A1[MAX_HMAC_KEY_LENGTH];
1016
1017#ifdef ENABLE_DEBUG
1018 /* used by the D_SHOW_KEY_SOURCE, guarded with ENABLE_DEBUG to avoid unused
1019 * variables warnings if compiled with --enable-small */
1020 const size_t olen_orig = olen;
1021 const uint8_t *out_orig = out;
1022#endif
1023
1024 hmac_ctx_t *ctx = hmac_ctx_new();
1025 hmac_ctx_t *ctx_tmp = hmac_ctx_new();
1026
1027 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc));
1028 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc));
1029
1030 unsigned int chunk = mbedtls_md_get_size(md_kt);
1031 unsigned int A1_len = mbedtls_md_get_size(md_kt);
1032
1033 /* This is the only place where we init an HMAC with a key that is not
1034 * equal to its size, therefore we init the hmac ctx manually here */
1035 mbedtls_md_init(ctx);
1036 ASSERT(0 == mbedtls_md_setup(ctx, md_kt, 1));
1037 ASSERT(0 == mbedtls_md_hmac_starts(ctx, sec, sec_len));
1038
1039 mbedtls_md_init(ctx_tmp);
1040 ASSERT(0 == mbedtls_md_setup(ctx_tmp, md_kt, 1));
1041 ASSERT(0 == mbedtls_md_hmac_starts(ctx_tmp, sec, sec_len));
1042
1043 hmac_ctx_update(ctx, seed, seed_len);
1044 hmac_ctx_final(ctx, A1);
1045
1046 for (;;)
1047 {
1048 hmac_ctx_reset(ctx);
1049 hmac_ctx_reset(ctx_tmp);
1050 hmac_ctx_update(ctx, A1, A1_len);
1051 hmac_ctx_update(ctx_tmp, A1, A1_len);
1052 hmac_ctx_update(ctx, seed, seed_len);
1053
1054 if (olen > chunk)
1055 {
1056 hmac_ctx_final(ctx, out);
1057 out += chunk;
1058 olen -= chunk;
1059 hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */
1060 }
1061 else /* last one */
1062 {
1063 hmac_ctx_final(ctx, A1);
1064 memcpy(out, A1, olen);
1065 break;
1066 }
1067 }
1068 hmac_ctx_cleanup(ctx);
1069 hmac_ctx_free(ctx);
1070 hmac_ctx_cleanup(ctx_tmp);
1071 hmac_ctx_free(ctx_tmp);
1072 secure_memzero(A1, sizeof(A1));
1073
1074 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc));
1075 gc_free(&gc);
1076}
1077
1078/*
1079 * Use the TLS PRF function for generating data channel keys.
1080 * This code is based on the OpenSSL library.
1081 *
1082 * TLS generates keys as such:
1083 *
1084 * master_secret[48] = PRF(pre_master_secret[48], "master secret",
1085 * ClientHello.random[32] + ServerHello.random[32])
1086 *
1087 * key_block[] = PRF(SecurityParameters.master_secret[48],
1088 * "key expansion",
1089 * SecurityParameters.server_random[32] +
1090 * SecurityParameters.client_random[32]);
1091 *
1092 * Notes:
1093 *
1094 * (1) key_block contains a full set of 4 keys.
1095 * (2) The pre-master secret is generated by the client.
1096 */
1097bool
1098ssl_tls1_PRF(const uint8_t *label, size_t label_len, const uint8_t *sec, size_t slen, uint8_t *out1,
1099 size_t olen)
1100{
1101 struct gc_arena gc = gc_new();
1102 const md_kt_t *md5 = md_get("MD5");
1103 const md_kt_t *sha1 = md_get("SHA1");
1104
1105 uint8_t *out2 = (uint8_t *)gc_malloc(olen, false, &gc);
1106
1107 size_t len = slen / 2;
1108 const uint8_t *S1 = sec;
1109 const uint8_t *S2 = &(sec[len]);
1110 len += (slen & 1); /* add for odd, make longer */
1111
1112 tls1_P_hash(md5, S1, len, label, label_len, out1, olen);
1113 tls1_P_hash(sha1, S2, len, label, label_len, out2, olen);
1114
1115 for (size_t i = 0; i < olen; i++)
1116 {
1117 out1[i] ^= out2[i];
1118 }
1119
1120 secure_memzero(out2, olen);
1121
1122 dmsg(D_SHOW_KEY_SOURCE, "tls1_PRF out[%zu]: %s", olen, format_hex(out1, olen, 0, &gc));
1123
1124 gc_free(&gc);
1125 return true;
1126}
1127
1128#if defined(__GNUC__) || defined(__clang__)
1129#pragma GCC diagnostic pop
1130#endif
1131
1132#endif /* MBEDTLS_VERSION_NUMBER < 0x040000 */
1133#endif /* ENABLE_CRYPTO_MBEDTLS */
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
void buf_null_terminate(struct buffer *buf)
Definition buffer.c:532
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:336
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:89
#define ALLOC_OBJ(dptr, type)
Definition buffer.h:1059
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Definition buffer.h:704
#define BPTR(buf)
Definition buffer.h:123
static bool buf_inc_len(struct buffer *buf, int inc)
Definition buffer.h:588
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition buffer.h:414
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:660
#define BLEN(buf)
Definition buffer.h:126
static char * format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
Definition buffer.h:503
#define BCAP(buf)
Definition buffer.h:129
static void gc_free(struct gc_arena *a)
Definition buffer.h:1025
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1064
static struct gc_arena gc_new(void)
Definition buffer.h:1017
const char * translate_cipher_name_from_openvpn(const char *cipher_name)
Translate an OpenVPN cipher name to a crypto library cipher name.
Definition crypto.c:1797
const char * translate_cipher_name_to_openvpn(const char *cipher_name)
Translate a crypto library cipher name to an OpenVPN cipher name.
Definition crypto.c:1810
void print_cipher(const char *ciphername)
Print a cipher list entry.
Definition crypto.c:1748
Data Channel Cryptography Module.
int memcmp_constant_time(const void *a, const void *b, size_t size)
As memcmp(), but constant-time.
Data Channel Cryptography SSL library-specific backend interface.
int cipher_ctx_update(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len)
Updates the given cipher context, encrypting data in the source buffer, and placing any complete bloc...
bool ssl_tls1_PRF(const uint8_t *seed, size_t seed_len, const uint8_t *secret, size_t secret_len, uint8_t *output, size_t output_len)
Calculates the TLS 1.0-1.1 PRF function.
void hmac_ctx_update(hmac_ctx_t *ctx, const uint8_t *src, int src_len)
hmac_ctx_t * hmac_ctx_new(void)
int md_full(const char *mdname, const uint8_t *src, int src_len, uint8_t *dst)
Calculates the message digest for the given buffer.
void hmac_ctx_reset(hmac_ctx_t *ctx)
int cipher_ctx_block_size(const cipher_ctx_t *ctx)
Returns the block size of the cipher, in bytes.
bool cipher_kt_mode_cbc(const char *ciphername)
Check if the supplied cipher is a supported CBC mode cipher.
void show_available_engines(void)
void hmac_ctx_init(hmac_ctx_t *ctx, const uint8_t *key, const char *mdname)
md_ctx_t * md_ctx_new(void)
void hmac_ctx_final(hmac_ctx_t *ctx, uint8_t *dst)
void md_ctx_update(md_ctx_t *ctx, const uint8_t *src, size_t src_len)
int cipher_ctx_iv_length(const cipher_ctx_t *ctx)
Returns the size of the IV used by the cipher, in bytes, or 0 if no IV is used.
void crypto_unload_provider(const char *provname, provider_t *provider)
Unloads the given (OpenSSL) provider.
void crypto_uninit_lib(void)
int cipher_kt_block_size(const char *ciphername)
Returns the block size of the cipher, in bytes.
bool cipher_kt_mode_aead(const char *ciphername)
Check if the supplied cipher is a supported AEAD mode cipher.
int md_ctx_size(const md_ctx_t *ctx)
void show_available_ciphers(void)
bool md_valid(const char *digest)
Return if a message digest parameters is valid given the name of the digest.
bool cipher_ctx_mode_cbc(const cipher_ctx_t *ctx)
Check if the supplied cipher is a supported CBC mode cipher.
void crypto_init_lib(void)
cipher_ctx_t * cipher_ctx_new(void)
Generic cipher functions.
bool cipher_kt_mode_ofb_cfb(const char *ciphername)
Check if the supplied cipher is a supported OFB or CFB mode cipher.
const char * md_kt_name(const char *mdname)
Retrieve a string describing the digest digest (e.g.
int hmac_ctx_size(hmac_ctx_t *ctx)
bool cipher_kt_insecure(const char *ciphername)
Returns true if we consider this cipher to be insecure.
#define MAX_CIPHER_KEY_LENGTH
void crypto_clear_error(void)
bool crypto_pem_decode(const char *name, struct buffer *dst, const struct buffer *src)
Decode a PEM buffer to binary data.
provider_t * crypto_load_provider(const char *provider)
Load the given (OpenSSL) providers.
void cipher_ctx_free(cipher_ctx_t *ctx)
Cleanup and free a cipher context.
int cipher_ctx_mode(const cipher_ctx_t *ctx)
Returns the mode that the cipher runs in.
bool cipher_ctx_mode_ofb_cfb(const cipher_ctx_t *ctx)
Check if the supplied cipher is a supported OFB or CFB mode cipher.
bool cipher_ctx_mode_aead(const cipher_ctx_t *ctx)
Check if the supplied cipher is a supported AEAD mode cipher.
void hmac_ctx_free(hmac_ctx_t *ctx)
int cipher_kt_iv_size(const char *ciphername)
Returns the size of the IV used by the cipher, in bytes, or 0 if no IV is used.
int cipher_kt_tag_size(const char *ciphername)
Returns the MAC tag size of the cipher, in bytes.
int cipher_ctx_update_ad(cipher_ctx_t *ctx, const uint8_t *src, int src_len)
Updates the given cipher context, providing additional data (AD) for authenticated encryption with ad...
int rand_bytes(uint8_t *output, int len)
Wrapper for secure random number generator.
const size_t cipher_name_translation_table_count
const char * cipher_kt_name(const char *ciphername)
Retrieve a normalised string describing the cipher (e.g.
#define MAX_HMAC_KEY_LENGTH
#define OPENVPN_AEAD_TAG_LENGTH
void cipher_ctx_init(cipher_ctx_t *ctx, const uint8_t *key, const char *ciphername, crypto_operation_t enc)
Initialise a cipher context, based on the given key and key type.
int cipher_ctx_get_tag(cipher_ctx_t *ctx, uint8_t *tag, int tag_len)
Gets the computed message authenticated code (MAC) tag for this cipher.
int cipher_kt_key_size(const char *ciphername)
Returns the size of keys used by the cipher, in bytes.
void crypto_init_lib_engine(const char *engine_name)
void hmac_ctx_cleanup(hmac_ctx_t *ctx)
int cipher_ctx_reset(cipher_ctx_t *ctx, const uint8_t *iv_buf)
Resets the given cipher context, setting the IV to the specified value.
const cipher_name_pair cipher_name_translation_table[]
Cipher name translation table.
void md_ctx_cleanup(md_ctx_t *ctx)
int cipher_ctx_final(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len)
Pads the final cipher block using PKCS padding, and output to the destination buffer.
void md_ctx_final(md_ctx_t *ctx, uint8_t *dst)
unsigned char md_kt_size(const char *mdname)
Returns the size of the message digest, in bytes.
void show_available_digests(void)
bool cipher_valid_reason(const char *ciphername, const char **reason)
Returns if the cipher is valid, based on the given cipher name and provides a reason if invalid.
int cipher_ctx_final_check_tag(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len, uint8_t *tag, size_t tag_len)
Like cipher_ctx_final, but check the computed authentication tag against the supplied (expected) tag.
void md_ctx_init(md_ctx_t *ctx, const char *mdname)
Initialises the given message digest context.
void md_ctx_free(md_ctx_t *ctx)
bool crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src, struct gc_arena *gc)
Encode binary data as PEM.
#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.
int cipher_kt_mode(const EVP_CIPHER *cipher_kt)
static evp_cipher_type * cipher_get(const char *ciphername)
static evp_md_type * md_get(const char *digest)
#define D_CRYPT_ERRORS
Definition errlevel.h:57
#define D_SHOW_KEY_SOURCE
Definition errlevel.h:121
#define D_LOW
Definition errlevel.h:96
static int min_int(int x, int y)
Definition integer.h:105
#define CLEAR(x)
Definition basic.h:32
#define M_FATAL
Definition error.h:90
#define dmsg(flags,...)
Definition error.h:172
#define M_ERR
Definition error.h:106
#define msg(flags,...)
Definition error.h:152
#define ASSERT(x)
Definition error.h:219
#define M_WARN
Definition error.h:92
const char * time_string(time_t t, tv_usec_t usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:104
unsigned int platform_getpid(void)
Definition platform.c:333
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
Struct used in cipher name translation table.
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152
struct gc_arena gc
Definition test_ssl.c:131