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-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 "crypto_mbedtls.h"
48#include "otime.h"
49#include "misc.h"
50
51#include <psa/crypto.h>
52#include <psa/crypto_config.h>
53#include <mbedtls/constant_time.h>
54#include <mbedtls/error.h>
55#include <mbedtls/pem.h>
56
57/*
58 *
59 * Hardware engine support. Allows loading/unloading of engines.
60 *
61 */
62
63void
64crypto_init_lib_engine(const char *engine_name)
65{
66 msg(M_WARN, "Note: mbed TLS hardware crypto engine functionality is not "
67 "available");
68}
69
71crypto_load_provider(const char *provider)
72{
73 if (provider)
74 {
75 msg(M_WARN, "Note: mbed TLS provider functionality is not available");
76 }
77 return NULL;
78}
79
80void
81crypto_unload_provider(const char *provname, provider_t *provider)
82{
83}
84
85/* The library doesn't support looking up algorithms by string anymore, so here
86 * is a lookup table. */
87static const cipher_info_t cipher_info_table[] = {
88/* TODO: Complete the table. */
89
90/* AES */
91#if PSA_WANT_KEY_TYPE_AES
92#if PSA_WANT_ALG_GCM
93 { "AES-128-GCM", PSA_KEY_TYPE_AES, PSA_ALG_GCM, 128 / 8, 96 / 8, 128 / 8 },
94 { "AES-192-GCM", PSA_KEY_TYPE_AES, PSA_ALG_GCM, 192 / 8, 96 / 8, 128 / 8 },
95 { "AES-256-GCM", PSA_KEY_TYPE_AES, PSA_ALG_GCM, 256 / 8, 96 / 8, 128 / 8 },
96#endif /* PSA_WANT_ALG_GCM */
97#if PSA_WANT_ALG_CBC_PKCS7
98 { "AES-128-CBC", PSA_KEY_TYPE_AES, PSA_ALG_CBC_PKCS7, 128 / 8, 128 / 8, 128 / 8 },
99 { "AES-192-CBC", PSA_KEY_TYPE_AES, PSA_ALG_CBC_PKCS7, 192 / 8, 128 / 8, 128 / 8 },
100 { "AES-256-CBC", PSA_KEY_TYPE_AES, PSA_ALG_CBC_PKCS7, 256 / 8, 128 / 8, 128 / 8 },
101#endif /* PSA_WANT_ALG_CBC_PKCS7 */
102#if PSA_WANT_ALG_CTR
103 { "AES-128-CTR", PSA_KEY_TYPE_AES, PSA_ALG_CTR, 128 / 8, 128 / 8, 128 / 8 },
104 { "AES-192-CTR", PSA_KEY_TYPE_AES, PSA_ALG_CTR, 192 / 8, 128 / 8, 128 / 8 },
105 { "AES-256-CTR", PSA_KEY_TYPE_AES, PSA_ALG_CTR, 256 / 8, 128 / 8, 128 / 8 },
106#endif /* PSA_WANT_ALG_CTR */
107#endif /* PSA_WANT_KEY_TYPE_AES */
108
109/* Chacha-Poly */
110#if PSA_WANT_KEY_TYPE_CHACHA20 && PSA_WANT_ALG_CHACHA20_POLY1305
111 { "CHACHA20-POLY1305", PSA_KEY_TYPE_CHACHA20, PSA_ALG_CHACHA20_POLY1305, 256 / 8, 96 / 8, 1 },
112#endif
113};
114static const size_t cipher_info_table_entries = sizeof(cipher_info_table) / sizeof(cipher_info_t);
115
116static const cipher_info_t *
117cipher_get(const char *ciphername)
118{
119 for (size_t i = 0; i < cipher_info_table_entries; i++)
120 {
121 if (strcmp(ciphername, cipher_info_table[i].name) == 0)
122 {
123 return &cipher_info_table[i];
124 }
125 }
126 return NULL;
127}
128
129/* Because Mbed TLS 4 doesn't support looking up algorithms by string, there's
130 * nothing to translate. */
134
135int
136rand_bytes(uint8_t *output, int len)
137{
138 if (len < 0)
139 {
140 return 0;
141 }
142 psa_status_t result = psa_generate_random(output, (size_t)len);
143 return result == PSA_SUCCESS;
144}
145
146bool
147cipher_valid_reason(const char *ciphername, const char **reason)
148{
149 ASSERT(reason);
150
151 const cipher_info_t *cipher_info = cipher_get(ciphername);
152
153 if (cipher_info == NULL)
154 {
155 msg(D_LOW, "Cipher algorithm '%s' not found", ciphername);
156 *reason = "disabled because unknown";
157 return false;
158 }
159
161 {
162 msg(D_LOW,
163 "Cipher algorithm '%s' uses a default key size (%d bytes) "
164 "which is larger than " PACKAGE_NAME "'s current maximum key size "
165 "(%d bytes)",
167 *reason = "disabled due to key size too large";
168 return false;
169 }
170
171 *reason = NULL;
172 return true;
173}
174
175const char *
176cipher_kt_name(const char *ciphername)
177{
178 const cipher_info_t *cipher_info = cipher_get(ciphername);
179 if (cipher_info == NULL)
180 {
181 return "[null-cipher]";
182 }
183 return cipher_info->name;
184}
185
186int
187cipher_kt_key_size(const char *ciphername)
188{
189 const cipher_info_t *cipher_info = cipher_get(ciphername);
190 if (cipher_info == NULL)
191 {
192 return 0;
193 }
194 return cipher_info->key_bytes;
195}
196
197int
198cipher_kt_iv_size(const char *ciphername)
199{
200 const cipher_info_t *cipher_info = cipher_get(ciphername);
201
202 if (cipher_info == NULL)
203 {
204 return 0;
205 }
206 return cipher_info->iv_bytes;
207}
208
209int
210cipher_kt_block_size(const char *ciphername)
211{
212 const cipher_info_t *cipher_info = cipher_get(ciphername);
213 if (cipher_info == NULL)
214 {
215 return 0;
216 }
217 return cipher_info->block_size;
218}
219
220int
221cipher_kt_tag_size(const char *ciphername)
222{
223 if (cipher_kt_mode_aead(ciphername))
224 {
226 }
227 return 0;
228}
229
230bool
231cipher_kt_insecure(const char *ciphername)
232{
233 const cipher_info_t *cipher_info = cipher_get(ciphername);
234 if (cipher_info == NULL)
235 {
236 return true;
237 }
238
239 return !(cipher_info->block_size >= 128 / 8
240 || cipher_info->psa_alg == PSA_ALG_CHACHA20_POLY1305);
241}
242
243bool
244cipher_kt_mode_cbc(const char *ciphername)
245{
246 const cipher_info_t *cipher_info = cipher_get(ciphername);
247 if (cipher_info == NULL)
248 {
249 return false;
250 }
251 return cipher_info->psa_alg == PSA_ALG_CBC_PKCS7;
252}
253
254bool
255cipher_kt_mode_ofb_cfb(const char *ciphername)
256{
257 const cipher_info_t *cipher_info = cipher_get(ciphername);
258 if (cipher_info == NULL)
259 {
260 return false;
261 }
262 return cipher_info->psa_alg == PSA_ALG_OFB || cipher_info->psa_alg == PSA_ALG_CFB;
263}
264
265bool
266cipher_kt_mode_aead(const char *ciphername)
267{
268 const cipher_info_t *cipher_info = cipher_get(ciphername);
269 if (cipher_info == NULL)
270 {
271 return false;
272 }
273 return cipher_info->psa_alg == PSA_ALG_GCM || cipher_info->psa_alg == PSA_ALG_CHACHA20_POLY1305;
274}
275
277cipher_ctx_new(void)
278{
279 cipher_ctx_t *ctx;
280 /* Initializing the object with zeros ensures that it is always safe to call
281 * cipher_ctx_free. */
283 return ctx;
284}
285
286void
288{
289 if (cipher_ctx_mode_aead(ctx))
290 {
291 ASSERT(psa_aead_abort(&ctx->operation.aead) == PSA_SUCCESS);
292 }
293 else
294 {
295 ASSERT(psa_cipher_abort(&ctx->operation.cipher) == PSA_SUCCESS);
296 }
297 ASSERT(psa_destroy_key(ctx->key) == PSA_SUCCESS);
298 free(ctx);
299}
300
301void
302cipher_ctx_init(cipher_ctx_t *ctx, const uint8_t *key, const char *ciphername,
304{
305 ASSERT(ciphername != NULL && ctx != NULL);
306 CLEAR(*ctx);
307
308 ctx->cipher_info = cipher_get(ciphername);
309 ASSERT(ctx->cipher_info != NULL);
310
311 psa_set_key_type(&ctx->key_attributes, ctx->cipher_info->psa_key_type);
312 psa_set_key_algorithm(&ctx->key_attributes, ctx->cipher_info->psa_alg);
313 psa_set_key_bits(&ctx->key_attributes, (size_t)ctx->cipher_info->key_bytes * 8);
314 psa_set_key_usage_flags(&ctx->key_attributes,
315 enc == OPENVPN_OP_ENCRYPT ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT);
316
317 if (psa_import_key(&ctx->key_attributes, key, (size_t)ctx->cipher_info->key_bytes, &ctx->key) != PSA_SUCCESS)
318 {
319 msg(M_FATAL, "psa_import_key failed");
320 }
321
322 /* make sure we used a big enough key */
323 ASSERT(psa_get_key_bits(&ctx->key_attributes) == (size_t)(8 * ctx->cipher_info->key_bytes));
324}
325
326int
328{
329 return ctx->cipher_info->iv_bytes;
330}
331
332int
333cipher_ctx_get_tag(cipher_ctx_t *ctx, uint8_t *tag, int tag_len)
334{
335 if (!ctx->aead_finished || tag_len < OPENVPN_AEAD_TAG_LENGTH)
336 {
337 return 0;
338 }
339
340 memcpy(tag, ctx->tag, OPENVPN_AEAD_TAG_LENGTH);
341 return 1;
342}
343
344int
346{
347 return ctx->cipher_info->block_size;
348}
349
350int
352{
353 ASSERT(ctx != NULL);
354 return (int)psa_get_key_algorithm(&ctx->key_attributes);
355}
356
357bool
359{
360 return ctx != NULL && cipher_ctx_mode(ctx) == OPENVPN_MODE_CBC;
361}
362
363bool
365{
366 if (ctx == NULL)
367 {
368 return false;
369 }
370 int mode = cipher_ctx_mode(ctx);
371 return mode == OPENVPN_MODE_OFB || mode == OPENVPN_MODE_CFB;
372}
373
374bool
376{
377 if (ctx == NULL)
378 {
379 return false;
380 }
381 int mode = cipher_ctx_mode(ctx);
382 return mode == (int)PSA_ALG_GCM || mode == (int)PSA_ALG_CHACHA20_POLY1305;
383}
384
385static int
386cipher_ctx_direction(const cipher_ctx_t *ctx)
387{
388 psa_key_usage_t key_usage = psa_get_key_usage_flags(&ctx->key_attributes);
389 if (key_usage & PSA_KEY_USAGE_ENCRYPT)
390 {
391 return OPENVPN_OP_ENCRYPT;
392 }
393 else if (key_usage & PSA_KEY_USAGE_DECRYPT)
394 {
395 return OPENVPN_OP_DECRYPT;
396 }
397 else
398 {
399 return -1;
400 }
401}
402
403int
404cipher_ctx_reset(cipher_ctx_t *ctx, const uint8_t *iv_buf)
405{
406 psa_status_t status = 0;
407
408 if (cipher_ctx_mode_aead(ctx))
409 {
410 if (psa_aead_abort(&ctx->operation.aead) != PSA_SUCCESS)
411 {
412 return 0;
413 }
414
415 if (cipher_ctx_direction(ctx) == OPENVPN_OP_ENCRYPT)
416 {
417 status = psa_aead_encrypt_setup(&ctx->operation.aead, ctx->key, ctx->cipher_info->psa_alg);
418 }
419 else if (cipher_ctx_direction(ctx) == OPENVPN_OP_DECRYPT)
420 {
421 status = psa_aead_decrypt_setup(&ctx->operation.aead, ctx->key, ctx->cipher_info->psa_alg);
422 }
423 else
424 {
425 return 0;
426 }
427
428 if (status != PSA_SUCCESS)
429 {
430 return 0;
431 }
432
433 status = psa_aead_set_nonce(&ctx->operation.aead, iv_buf, ctx->cipher_info->iv_bytes);
434 if (status != PSA_SUCCESS)
435 {
436 return 0;
437 }
438 }
439 else
440 {
441 if (psa_cipher_abort(&ctx->operation.cipher) != PSA_SUCCESS)
442 {
443 return 0;
444 }
445
446 if (cipher_ctx_direction(ctx) == OPENVPN_OP_ENCRYPT)
447 {
448 status = psa_cipher_encrypt_setup(&ctx->operation.cipher, ctx->key, ctx->cipher_info->psa_alg);
449 }
450 else if (cipher_ctx_direction(ctx) == OPENVPN_OP_DECRYPT)
451 {
452 status = psa_cipher_decrypt_setup(&ctx->operation.cipher, ctx->key, ctx->cipher_info->psa_alg);
453 }
454 else
455 {
456 return 0;
457 }
458
459 if (status != PSA_SUCCESS)
460 {
461 return 0;
462 }
463
464 status = psa_cipher_set_iv(&ctx->operation.cipher, iv_buf, ctx->cipher_info->iv_bytes);
465 if (status != PSA_SUCCESS)
466 {
467 return 0;
468 }
469 }
470
471 return 1;
472}
473
474/* We rely on the caller to ensure that the destination buffer has enough room,
475 * but Mbed TLS always wants a size for the destination buffer. This function
476 * calculates the minimum necessary size for a given cipher and input length.
477 *
478 * This funcion assumes that src_len has been checked to be >= 0. */
479static size_t
480needed_dst_size(const cipher_ctx_t *ctx, int src_len)
481{
482 int mode = cipher_ctx_mode(ctx);
483 if (mode == PSA_ALG_CTR || mode == PSA_ALG_GCM || mode == PSA_ALG_CHACHA20_POLY1305)
484 {
485 /* These algorithms are based on a keystream, so the input and output
486 * length are always equal. */
487 return (size_t)src_len;
488 }
489 else
490 {
491 /* These algorithms are block-based. The number of output blocks that are
492 * produced is at most 1 + src_len / block_size. */
493 size_t block_size = (size_t)cipher_ctx_block_size(ctx);
494 size_t max_blocks = 1 + (size_t)src_len / block_size;
495 return max_blocks * block_size;
496 }
497}
498
499int
500cipher_ctx_update_ad(cipher_ctx_t *ctx, const uint8_t *src, int src_len)
501{
502 if (src_len < 0 || !cipher_ctx_mode_aead(ctx))
503 {
504 return 0;
505 }
506
507 if (psa_aead_update_ad(&ctx->operation.aead, src, (size_t)src_len) != PSA_SUCCESS)
508 {
509 return 0;
510 }
511 return 1;
512}
513
514int
515cipher_ctx_update(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len)
516{
517 if (src_len < 0)
518 {
519 return 0;
520 }
521
522 size_t dst_size = needed_dst_size(ctx, src_len);
523 size_t psa_output_len = 0;
524 psa_status_t status = 0;
525
526 if (cipher_ctx_mode_aead(ctx))
527 {
528 status = psa_aead_update(&ctx->operation.aead, src, (size_t)src_len, dst, dst_size, &psa_output_len);
529 }
530 else
531 {
532 status = psa_cipher_update(&ctx->operation.cipher, src, (size_t)src_len, dst, dst_size, &psa_output_len);
533 }
534
535 if (status != PSA_SUCCESS)
536 {
537 return 0;
538 }
539
540 if (psa_output_len > INT_MAX)
541 {
542 return 0;
543 }
544 *dst_len = (int)psa_output_len;
545
546 return 1;
547}
548
549int
550cipher_ctx_final(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len)
551{
552 size_t dst_size = needed_dst_size(ctx, 0);
553 size_t psa_output_len = 0;
554 psa_status_t status = 0;
555
556 if (cipher_ctx_mode_aead(ctx))
557 {
558 size_t actual_tag_size = 0;
559 status = psa_aead_finish(&ctx->operation.aead,
560 dst,
561 dst_size,
562 &psa_output_len,
563 ctx->tag,
565 &actual_tag_size);
566 if (status != PSA_SUCCESS || psa_output_len > (size_t)INT_MAX || actual_tag_size != (size_t)OPENVPN_AEAD_TAG_LENGTH)
567 {
568 return 0;
569 }
570 ctx->aead_finished = true;
571 }
572 else
573 {
574 status = psa_cipher_finish(&ctx->operation.cipher, dst, dst_size, &psa_output_len);
575 if (status != PSA_SUCCESS || psa_output_len > (size_t)INT_MAX)
576 {
577 return 0;
578 }
579 }
580
581 *dst_len = (int)psa_output_len;
582
583 return 1;
584}
585
586int
587cipher_ctx_final_check_tag(cipher_ctx_t *ctx, uint8_t *dst, int *dst_len, uint8_t *tag, size_t tag_len)
588{
589 if (cipher_ctx_direction(ctx) != OPENVPN_OP_DECRYPT || !cipher_ctx_mode_aead(ctx))
590 {
591 return 0;
592 }
593
594 size_t psa_output_len = 0;
595 psa_status_t status = 0;
596
597 status = psa_aead_verify(&ctx->operation.aead, dst, 0, &psa_output_len, tag, tag_len);
598 if (status != PSA_SUCCESS || psa_output_len > (size_t)INT_MAX)
599 {
600 return 0;
601 }
602 *dst_len = (int)psa_output_len;
603
604 return 1;
605}
606
607static const md_info_t md_info_table[] = {
608#if defined(PSA_WANT_ALG_MD5)
609 { "MD5", PSA_ALG_MD5 },
610#endif
611#if defined(PSA_WANT_ALG_SHA_1)
612 { "SHA1", PSA_ALG_SHA_1 },
613#endif
614#if defined(PSA_WANT_ALG_SHA_224)
615 { "SHA224", PSA_ALG_SHA_224 },
616#endif
617#if defined(PSA_WANT_ALG_SHA_256)
618 { "SHA256", PSA_ALG_SHA_256 },
619#endif
620#if defined(PSA_WANT_ALG_SHA_384)
621 { "SHA384", PSA_ALG_SHA_384 },
622#endif
623#if defined(PSA_WANT_ALG_SHA_512)
624 { "SHA512", PSA_ALG_SHA_512 },
625#endif
626#if defined(PSA_WANT_ALG_SHA3_224)
627 { "SHA3-224", PSA_ALG_SHA3_224 },
628#endif
629#if defined(PSA_WANT_ALG_SHA3_256)
630 { "SHA3-256", PSA_ALG_SHA3_256 },
631#endif
632#if defined(PSA_WANT_ALG_SHA3_384)
633 { "SHA3-384", PSA_ALG_SHA3_384 },
634#endif
635#if defined(PSA_WANT_ALG_SHA3_512)
636 { "SHA3-512", PSA_ALG_SHA3_512 },
637#endif
638};
639const size_t md_info_table_entries = sizeof(md_info_table) / sizeof(md_info_t);
640
641static const md_info_t *
642md_get(const char *digest_name)
643{
644 for (size_t i = 0; i < md_info_table_entries; i++)
645 {
646 if (strcmp(digest_name, md_info_table[i].name) == 0)
647 {
648 return &md_info_table[i];
649 }
650 }
651 return NULL;
652}
653
654bool
655md_valid(const char *digest)
656{
657 const md_info_t *md = md_get(digest);
658 return md != NULL;
659}
660
661const char *
662md_kt_name(const char *mdname)
663{
664 if (strcmp("none", mdname) == 0)
665 {
666 return "[null-digest]";
667 }
668 const md_info_t *md = md_get(mdname);
669 if (md == NULL)
670 {
671 return NULL;
672 }
673 return md->name;
674}
675
676unsigned char
677md_kt_size(const char *mdname)
678{
679 if (strcmp("none", mdname) == 0)
680 {
681 return 0;
682 }
683 const md_info_t *md_info = md_get(mdname);
684 if (md_info == NULL)
685 {
686 return 0;
687 }
688 return (unsigned char)PSA_HASH_LENGTH(md_info->psa_alg);
689}
690
691md_ctx_t *
692md_ctx_new(void)
693{
694 md_ctx_t *ctx;
696 return ctx;
697}
698
699int
700md_full(const char *mdname, const uint8_t *src, int src_len, uint8_t *dst)
701{
702 const md_info_t *md = md_get(mdname);
703 if (md == NULL || src_len < 0)
704 {
705 return 0;
706 }
707
708 /* We depend on the caller to ensure that dst has enough room for the hash,
709 * so we just tell PSA that it can hold the appropriate amount of bytes. */
710 size_t dst_size = PSA_HASH_LENGTH(md->psa_alg);
711 size_t hash_length = 0;
712
713 psa_status_t status = psa_hash_compute(md->psa_alg, src, (size_t)src_len, dst, dst_size, &hash_length);
714 if (status != PSA_SUCCESS || hash_length != dst_size)
715 {
716 return 0;
717 }
718 return 1;
719}
720
721void
723{
724 free(ctx);
725}
726
727void
728md_ctx_init(md_ctx_t *ctx, const char *mdname)
729{
730 const md_info_t *md_info = md_get(mdname);
731 ASSERT(ctx != NULL && md_info != NULL);
732
733 ctx->md_info = md_info;
734 ASSERT(psa_hash_setup(&ctx->operation, md_info->psa_alg) == PSA_SUCCESS);
735}
736
737void
739{
740 ASSERT(psa_hash_abort(&ctx->operation) == PSA_SUCCESS);
741}
742
743int
744md_ctx_size(const md_ctx_t *ctx)
745{
746 if (ctx == NULL)
747 {
748 return 0;
749 }
750 return (int)PSA_HASH_LENGTH(ctx->md_info->psa_alg);
751}
752
753void
754md_ctx_update(md_ctx_t *ctx, const uint8_t *src, size_t src_len)
755{
756 ASSERT(psa_hash_update(&ctx->operation, src, src_len) == PSA_SUCCESS);
757}
758
759void
760md_ctx_final(md_ctx_t *ctx, uint8_t *dst)
761{
762 /* We depend on the caller to ensure that dst has enough room for the hash,
763 * so we just tell PSA that it can hold the appropriate amount of bytes. */
764 size_t dst_size = PSA_HASH_LENGTH(ctx->md_info->psa_alg);
765 size_t hash_length = 0;
766
767 ASSERT(psa_hash_finish(&ctx->operation, dst, dst_size, &hash_length) == PSA_SUCCESS);
768 ASSERT(hash_length == dst_size);
769}
770
772hmac_ctx_new(void)
773{
774 hmac_ctx_t *ctx;
776 return ctx;
777}
778
779void
781{
782 free(ctx);
783}
784
785static void
786hmac_ctx_init_with_arbitrary_key_length(hmac_ctx_t *ctx, const uint8_t *key, size_t key_len, const md_info_t *md_info)
787{
788 ctx->md_info = md_info;
789 psa_set_key_type(&ctx->key_attributes, PSA_KEY_TYPE_HMAC);
790 psa_set_key_algorithm(&ctx->key_attributes, PSA_ALG_HMAC(md_info->psa_alg));
791 psa_set_key_usage_flags(&ctx->key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
792
793 if (psa_import_key(&ctx->key_attributes, key, key_len, &ctx->key) != PSA_SUCCESS)
794 {
795 msg(M_FATAL, "psa_import_key failed");
796 }
797
798 ASSERT(psa_mac_sign_setup(&ctx->operation, ctx->key, PSA_ALG_HMAC(md_info->psa_alg)) == PSA_SUCCESS);
799}
800
801void
802hmac_ctx_init(hmac_ctx_t *ctx, const uint8_t *key, const char *mdname)
803{
804 const md_info_t *md_info = md_get(mdname);
805 ASSERT(ctx != NULL && key != NULL && md_info != NULL);
806
807 hmac_ctx_init_with_arbitrary_key_length(ctx, key, PSA_HASH_LENGTH(md_info->psa_alg), md_info);
808}
809
810void
812{
813 ASSERT(psa_mac_abort(&ctx->operation) == PSA_SUCCESS);
814 ASSERT(psa_destroy_key(ctx->key) == PSA_SUCCESS);
815}
816
817int
819{
820 return (int)PSA_HASH_LENGTH(ctx->md_info->psa_alg);
821}
822
823void
825{
826 ASSERT(psa_mac_abort(&ctx->operation) == PSA_SUCCESS);
827 ASSERT(psa_mac_sign_setup(&ctx->operation, ctx->key, PSA_ALG_HMAC(ctx->md_info->psa_alg)) == PSA_SUCCESS);
828}
829
830void
831hmac_ctx_update(hmac_ctx_t *ctx, const uint8_t *src, int src_len)
832{
833 ASSERT(src_len >= 0);
834 ASSERT(psa_mac_update(&ctx->operation, src, (size_t)src_len) == PSA_SUCCESS);
835}
836
837void
838hmac_ctx_final(hmac_ctx_t *ctx, uint8_t *dst)
839{
840 /* We depend on the caller to ensure that dst has enough room for the hash,
841 * so we just tell PSA that it can hold the appropriate amount of bytes. */
842 size_t dst_size = PSA_HASH_LENGTH(ctx->md_info->psa_alg);
843 size_t hmac_length = 0;
844
845 ASSERT(psa_mac_sign_finish(&ctx->operation, dst, dst_size, &hmac_length) == PSA_SUCCESS);
846 ASSERT(hmac_length == dst_size);
847}
848
849/*
850 * Generate the hash required by for the \c tls1_PRF function.
851 *
852 * @param md_kt Message digest to use
853 * @param sec Secret to base the hash on
854 * @param sec_len Length of the secret
855 * @param seed Seed to hash
856 * @param seed_len Length of the seed
857 * @param out Output buffer
858 * @param olen Length of the output buffer
859 */
860static void
861tls1_P_hash(const md_info_t *md_info, const uint8_t *sec, size_t sec_len, const uint8_t *seed,
862 int seed_len, uint8_t *out, size_t olen)
863{
864 struct gc_arena gc = gc_new();
865 uint8_t A1[MAX_HMAC_KEY_LENGTH];
866
867#ifdef ENABLE_DEBUG
868 /* used by the D_SHOW_KEY_SOURCE, guarded with ENABLE_DEBUG to avoid unused
869 * variables warnings if compiled with --enable-small */
870 const size_t olen_orig = olen;
871 const uint8_t *out_orig = out;
872#endif
873
874 hmac_ctx_t *ctx = hmac_ctx_new();
875 hmac_ctx_t *ctx_tmp = hmac_ctx_new();
876
877 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc));
878 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc));
879
880 unsigned int chunk = (unsigned int)PSA_HASH_LENGTH(md_info->psa_alg);
881 unsigned int A1_len = (unsigned int)PSA_HASH_LENGTH(md_info->psa_alg);
882
883 /* This is the only place where we init an HMAC with a key that is not
884 * equal to its size, therefore we init the hmac ctx manually here */
885 hmac_ctx_init_with_arbitrary_key_length(ctx, sec, sec_len, md_info);
886 hmac_ctx_init_with_arbitrary_key_length(ctx_tmp, sec, sec_len, md_info);
887
888 hmac_ctx_update(ctx, seed, seed_len);
889 hmac_ctx_final(ctx, A1);
890
891 for (;;)
892 {
893 hmac_ctx_reset(ctx);
894 hmac_ctx_reset(ctx_tmp);
895 hmac_ctx_update(ctx, A1, A1_len);
896 hmac_ctx_update(ctx_tmp, A1, A1_len);
897 hmac_ctx_update(ctx, seed, (int)seed_len);
898
899 if (olen > chunk)
900 {
901 hmac_ctx_final(ctx, out);
902 out += chunk;
903 olen -= chunk;
904 hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */
905 }
906 else /* last one */
907 {
908 hmac_ctx_final(ctx, A1);
909 memcpy(out, A1, olen);
910 break;
911 }
912 }
913 hmac_ctx_cleanup(ctx);
914 hmac_ctx_free(ctx);
915 hmac_ctx_cleanup(ctx_tmp);
916 hmac_ctx_free(ctx_tmp);
917 secure_memzero(A1, sizeof(A1));
918
919 dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc));
920 gc_free(&gc);
921}
922
923/*
924 * Use the TLS PRF function for generating data channel keys.
925 * This code is based on the OpenSSL library.
926 *
927 * TLS generates keys as such:
928 *
929 * master_secret[48] = PRF(pre_master_secret[48], "master secret",
930 * ClientHello.random[32] + ServerHello.random[32])
931 *
932 * key_block[] = PRF(SecurityParameters.master_secret[48],
933 * "key expansion",
934 * SecurityParameters.server_random[32] +
935 * SecurityParameters.client_random[32]);
936 *
937 * Notes:
938 *
939 * (1) key_block contains a full set of 4 keys.
940 * (2) The pre-master secret is generated by the client.
941 */
942bool
943ssl_tls1_PRF(const uint8_t *label, size_t label_len, const uint8_t *sec, size_t slen, uint8_t *out1,
944 size_t olen)
945{
946 const md_info_t *md5 = md_get("MD5");
947 const md_info_t *sha1 = md_get("SHA1");
948
949 if (label_len > (size_t)INT_MAX)
950 {
951 return false;
952 }
953
954 struct gc_arena gc = gc_new();
955
956 uint8_t *out2 = (uint8_t *)gc_malloc(olen, false, &gc);
957
958 size_t len = slen / 2;
959 const uint8_t *S1 = sec;
960 const uint8_t *S2 = &(sec[len]);
961 len += (slen & 1); /* add for odd, make longer */
962
963 tls1_P_hash(md5, S1, len, label, (int)label_len, out1, olen);
964 tls1_P_hash(sha1, S2, len, label, (int)label_len, out2, olen);
965
966 for (size_t i = 0; i < olen; i++)
967 {
968 out1[i] ^= out2[i];
969 }
970
971 secure_memzero(out2, olen);
972
973 dmsg(D_SHOW_KEY_SOURCE, "tls1_PRF out[%zu]: %s", olen, format_hex(out1, olen, 0, &gc));
974
975 gc_free(&gc);
976 return true;
977}
978
979void
980crypto_init_lib(void)
981{
982}
983
984void
986{
987}
988
989void
991{
992}
993
994bool
995mbed_log_err(unsigned int flags, int errval, const char *prefix)
996{
997 if (0 != errval)
998 {
999 char errstr[256];
1000 mbedtls_strerror(errval, errstr, sizeof(errstr));
1001
1002 if (NULL == prefix)
1003 {
1004 prefix = "mbed TLS error";
1005 }
1006 msg(flags, "%s: %s", prefix, errstr);
1007 }
1008
1009 return 0 == errval;
1010}
1011
1012bool
1013mbed_log_func_line(unsigned int flags, int errval, const char *func, int line)
1014{
1015 char prefix[256];
1016
1017 if (snprintf(prefix, sizeof(prefix), "%s:%d", func, line) >= sizeof(prefix))
1018 {
1019 return mbed_log_err(flags, errval, func);
1020 }
1021
1022 return mbed_log_err(flags, errval, prefix);
1023}
1024
1025int
1026memcmp_constant_time(const void *a, const void *b, size_t size)
1027{
1028 return mbedtls_ct_memcmp(a, b, size);
1029}
1030
1031void
1033{
1034 /* Mbed TLS 4 does not currently have a mechanism to discover available
1035 * ciphers. We instead print out the ciphers from cipher_info_table. */
1036
1037#ifndef ENABLE_SMALL
1038 printf("The following ciphers and cipher modes are available for use\n"
1039 "with " PACKAGE_NAME ". Each cipher shown below may be used as a\n"
1040 "parameter to the --data-ciphers (or --cipher) option. Using a\n"
1041 "GCM or CBC mode is recommended. In static key mode only CBC\n"
1042 "mode is allowed.\n\n");
1043#endif
1044
1045 for (size_t i = 0; i < cipher_info_table_entries; i++)
1046 {
1047 const cipher_info_t *info = &cipher_info_table[i];
1048 const char *name = info->name;
1049 if (!cipher_kt_insecure(name) && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
1050 {
1051 print_cipher(name);
1052 }
1053 }
1054
1055 printf("\nThe following ciphers have a block size of less than 128 bits, \n"
1056 "and are therefore deprecated. Do not use unless you have to.\n\n");
1057 for (size_t i = 0; i < cipher_info_table_entries; i++)
1058 {
1059 const cipher_info_t *info = &cipher_info_table[i];
1060 const char *name = info->name;
1061 if (cipher_kt_insecure(name) && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
1062 {
1063 print_cipher(name);
1064 }
1065 }
1066 printf("\n");
1067}
1068
1069void
1071{
1072 /* Mbed TLS 4 does not currently have a mechanism to discover available
1073 * message digests. We instead print out the digests from md_info_table. */
1074
1075#ifndef ENABLE_SMALL
1076 printf("The following message digests are available for use with\n" PACKAGE_NAME
1077 ". A message digest is used in conjunction with\n"
1078 "the HMAC function, to authenticate received packets.\n"
1079 "You can specify a message digest as parameter to\n"
1080 "the --auth option.\n\n");
1081#endif
1082
1083 for (size_t i = 0; i < md_info_table_entries; i++)
1084 {
1085 const md_info_t *info = &md_info_table[i];
1086 printf("%s %d bit default key\n", info->name,
1087 (unsigned char)PSA_HASH_LENGTH(info->psa_alg) * 8);
1088 }
1089 printf("\n");
1090}
1091
1092void
1094{
1095 printf("Sorry, mbed TLS hardware crypto engine functionality is not "
1096 "available\n");
1097}
1098
1099bool
1100crypto_pem_encode(const char *name, struct buffer *dst, const struct buffer *src,
1101 struct gc_arena *gc)
1102{
1103 /* 1000 chars is the PEM line length limit (+1 for tailing NUL) */
1104 char header[1000 + 1] = { 0 };
1105 char footer[1000 + 1] = { 0 };
1106
1107 if (snprintf(header, sizeof(header), "-----BEGIN %s-----\n", name) >= sizeof(header))
1108 {
1109 return false;
1110 }
1111 if (snprintf(footer, sizeof(footer), "-----END %s-----\n", name) >= sizeof(footer))
1112 {
1113 return false;
1114 }
1115
1116 size_t out_len = 0;
1117 if (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
1118 != mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src), NULL, 0, &out_len))
1119 {
1120 return false;
1121 }
1122
1123 /* We set the size buf to out_len-1 to NOT include the 0 byte that
1124 * mbedtls_pem_write_buffer in its length calculation */
1125 *dst = alloc_buf_gc(out_len, gc);
1126 if (!mbed_ok(mbedtls_pem_write_buffer(header, footer, BPTR(src), BLEN(src), BPTR(dst),
1127 BCAP(dst), &out_len))
1128 || !(out_len < INT_MAX && out_len > 1)
1129 || !buf_inc_len(dst, (int)out_len - 1))
1130 {
1131 CLEAR(*dst);
1132 return false;
1133 }
1134
1135 return true;
1136}
1137
1138bool
1139crypto_pem_decode(const char *name, struct buffer *dst, const struct buffer *src)
1140{
1141 /* 1000 chars is the PEM line length limit (+1 for tailing NUL) */
1142 char header[1000 + 1] = { 0 };
1143 char footer[1000 + 1] = { 0 };
1144
1145 if (snprintf(header, sizeof(header), "-----BEGIN %s-----", name) >= sizeof(header))
1146 {
1147 return false;
1148 }
1149 if (snprintf(footer, sizeof(footer), "-----END %s-----", name) >= sizeof(footer))
1150 {
1151 return false;
1152 }
1153
1154 /* mbed TLS requires the src to be null-terminated */
1155 /* allocate a new buffer to avoid modifying the src buffer */
1156 struct gc_arena gc = gc_new();
1157 struct buffer input = alloc_buf_gc(BLEN(src) + 1, &gc);
1158 buf_copy(&input, src);
1160
1161 size_t use_len = 0;
1162 mbedtls_pem_context ctx = { 0 };
1163 bool ret =
1164 mbed_ok(mbedtls_pem_read_buffer(&ctx, header, footer, BPTR(&input), NULL, 0, &use_len));
1165 size_t buf_size = 0;
1166 const unsigned char *buf = mbedtls_pem_get_buffer(&ctx, &buf_size);
1167 if (ret && !buf_write(dst, buf, buf_size))
1168 {
1169 ret = false;
1170 msg(M_WARN, "PEM decode error: destination buffer too small");
1171 }
1172
1173 mbedtls_pem_free(&ctx);
1174 gc_free(&gc);
1175 return ret;
1176}
1177
1178#endif /* MBEDTLS_VERSION_NUMBER >= 0x04000000 */
1179#endif /* defined(ENABLE_CRYPTO_MBEDTLS) */
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
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
#define PACKAGE_NAME
Definition config.h:492
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.
Data Channel Cryptography backend interface using the TF-PSA-Crypto library part of Mbed TLS 4.
#define OPENVPN_OP_DECRYPT
Cipher should decrypt.
#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_OP_ENCRYPT
Cipher should encrypt.
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.
static evp_cipher_type * cipher_get(const char *ciphername)
static evp_md_type * md_get(const char *digest)
#define D_SHOW_KEY_SOURCE
Definition errlevel.h:121
#define D_LOW
Definition errlevel.h:96
static SERVICE_STATUS status
Definition interactive.c:51
#define CLEAR(x)
Definition basic.h:32
#define M_FATAL
Definition error.h:90
#define dmsg(flags,...)
Definition error.h:172
#define msg(flags,...)
Definition error.h:152
#define ASSERT(x)
Definition error.h:219
#define M_WARN
Definition error.h:92
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
cipher_operation_t operation
uint8_t tag[16]
psa_key_attributes_t key_attributes
mbedtls_svc_key_id_t key
const cipher_info_t * cipher_info
psa_key_type_t psa_key_type
psa_algorithm_t psa_alg
const char * name
Struct used in cipher name translation table.
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
const md_info_t * md_info
psa_mac_operation_t operation
psa_key_attributes_t key_attributes
mbedtls_svc_key_id_t key
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152
const md_info_t * md_info
psa_hash_operation_t operation
psa_algorithm_t psa_alg
const char * name
struct gc_arena gc
Definition test_ssl.c:131
psa_aead_operation_t aead
psa_cipher_operation_t cipher