mbedtls: add
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
7aa64cb625
commit
214e307486
219
include/stdex/mbedtls.hpp
Normal file
219
include/stdex/mbedtls.hpp
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
SPDX-License-Identifier: MIT
|
||||||
|
Copyright © 2016-2025 Amebis
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "compat.hpp"
|
||||||
|
#include "exception.hpp"
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdocumentation-deprecated-sync"
|
||||||
|
#endif
|
||||||
|
#include <mbedtls/bignum.h>
|
||||||
|
#include <mbedtls/ctr_drbg.h>
|
||||||
|
#include <mbedtls/entropy.h>
|
||||||
|
#include <mbedtls/error.h>
|
||||||
|
#include <mbedtls/pk.h>
|
||||||
|
#include <mbedtls/x509_crt.h>
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
#ifdef MBEDTLS_USE_PSA_CRYPTO
|
||||||
|
#include <psa/crypto.h>
|
||||||
|
#endif
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace stdex
|
||||||
|
{
|
||||||
|
namespace mbedtls
|
||||||
|
{
|
||||||
|
///
|
||||||
|
/// MbedTLS runtime error
|
||||||
|
///
|
||||||
|
class runtime_error : public stdex::num_runtime_error<int>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Constructs an exception
|
||||||
|
///
|
||||||
|
/// \param[in] num MbedTLS error code
|
||||||
|
///
|
||||||
|
runtime_error(error_type num) : stdex::num_runtime_error<int>(num, message(num))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Constructs an exception
|
||||||
|
///
|
||||||
|
/// \param[in] num MbedTLS error code
|
||||||
|
/// \param[in] msg Error message
|
||||||
|
///
|
||||||
|
runtime_error(error_type num, const std::string &msg) : stdex::num_runtime_error<int>(num, msg + ": " + message(num))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Constructs an exception
|
||||||
|
///
|
||||||
|
/// \param[in] num MbedTLS error code
|
||||||
|
/// \param[in] msg Error message
|
||||||
|
///
|
||||||
|
runtime_error(error_type num, const char *msg) : stdex::num_runtime_error<int>(num, std::string(msg) + ": " + message(num))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///
|
||||||
|
/// Returns a string explaining the meaning of a security result code
|
||||||
|
///
|
||||||
|
/// \sa [mbedtls_strerror function](https://mbed-ce.github.io/mbed-os/group__mbedtls__errors.html#ga8c41c149b77a4807115b19c2af858558)
|
||||||
|
///
|
||||||
|
static std::string message(error_type num)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
mbedtls_strerror(num, buf, sizeof(buf));
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// MbedTLS entropy context
|
||||||
|
///
|
||||||
|
class entropy_context : public mbedtls_entropy_context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Initializes MbedTLS entropy context
|
||||||
|
///
|
||||||
|
/// \sa [mbedtls_entropy_init](https://mbed-ce.github.io/mbed-os/group__mbedtls__entropy__module.html#gaa901e027093c6fe65dee5760db78aced)
|
||||||
|
///
|
||||||
|
entropy_context()
|
||||||
|
{
|
||||||
|
mbedtls_entropy_init(this);
|
||||||
|
#if !defined(_WIN32) && defined(MBEDTLS_FS_IO)
|
||||||
|
int ret = mbedtls_entropy_add_source(this, dev_random_entropy_poll, NULL, 32, MBEDTLS_ENTROPY_SOURCE_STRONG);
|
||||||
|
if (ret != 0)
|
||||||
|
throw runtime_error(ret, "mbedtls_entropy_add_source failed");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Frees MbedTLS entropy context
|
||||||
|
///
|
||||||
|
/// \sa [mbedtls_entropy_free](https://mbed-ce.github.io/mbed-os/group__mbedtls__entropy__module.html#ga06778439f8a0e2daa2d3b444e06ad8dd)
|
||||||
|
///
|
||||||
|
~entropy_context()
|
||||||
|
{
|
||||||
|
mbedtls_entropy_free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
#if !defined(_WIN32) && defined(MBEDTLS_FS_IO)
|
||||||
|
static int dev_random_entropy_poll(void* data, unsigned char* output, size_t len, size_t* olen)
|
||||||
|
{
|
||||||
|
_Unreferenced_(data);
|
||||||
|
*olen = 0;
|
||||||
|
FILE* file = fopen("/dev/random", "rb");
|
||||||
|
if (file == NULL)
|
||||||
|
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||||
|
size_t left = len;
|
||||||
|
unsigned char* p = output;
|
||||||
|
while (left) {
|
||||||
|
// /dev/random can return much less than requested. If so, try again.
|
||||||
|
size_t ret = fread(p, 1, left, file);
|
||||||
|
if (ret == 0 && ferror(file)) {
|
||||||
|
fclose(file);
|
||||||
|
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||||
|
}
|
||||||
|
p += ret;
|
||||||
|
left -= ret;
|
||||||
|
if (!left)
|
||||||
|
break;
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
*olen = len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The MbedTLS CTR_DRBG context structure
|
||||||
|
///
|
||||||
|
struct ctr_drbg_context : public mbedtls_ctr_drbg_context
|
||||||
|
{
|
||||||
|
ctr_drbg_context() { mbedtls_ctr_drbg_init(this); }
|
||||||
|
~ctr_drbg_context() { mbedtls_ctr_drbg_free(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// MbedTLS MPI
|
||||||
|
///
|
||||||
|
struct mpi : public mbedtls_mpi
|
||||||
|
{
|
||||||
|
mpi() { mbedtls_mpi_init(this); }
|
||||||
|
~mpi() { mbedtls_mpi_free(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// MbedTLS public key container
|
||||||
|
///
|
||||||
|
struct pk_context : public mbedtls_pk_context
|
||||||
|
{
|
||||||
|
pk_context() { mbedtls_pk_init(this); }
|
||||||
|
~pk_context() { mbedtls_pk_free(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// MbedTLS container for an X.509 certificate
|
||||||
|
///
|
||||||
|
struct x509_crt : public mbedtls_x509_crt
|
||||||
|
{
|
||||||
|
x509_crt() { mbedtls_x509_crt_init(this); }
|
||||||
|
~x509_crt() { mbedtls_x509_crt_free(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// MbedTLS Container for writing a certificate (CRT)
|
||||||
|
///
|
||||||
|
struct x509write_cert : public mbedtls_x509write_cert
|
||||||
|
{
|
||||||
|
x509write_cert() { mbedtls_x509write_crt_init(this); }
|
||||||
|
~x509write_cert() { mbedtls_x509write_crt_free(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// MbedTLS global initializer
|
||||||
|
///
|
||||||
|
class initializer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Initializes MbedTLS library
|
||||||
|
///
|
||||||
|
initializer()
|
||||||
|
{
|
||||||
|
#ifdef MBEDTLS_USE_PSA_CRYPTO
|
||||||
|
auto status = psa_crypto_init();
|
||||||
|
if (status != PSA_SUCCESS)
|
||||||
|
throw runtime_error("Failed to initialize PSA Crypto implementation");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
~initializer()
|
||||||
|
{
|
||||||
|
#ifdef MBEDTLS_USE_PSA_CRYPTO
|
||||||
|
mbedtls_psa_crypto_free();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user