mbedtls: Update Mbed TLS and Mbed Crypto

Update Mbed TLS to 2.19.0d0 and Mbed Crypto to 2.0.0d1.
pull/11315/head
Jaeden Amero 2019-08-21 13:53:23 +01:00
parent 6dfd515dd6
commit ea17d58b49
123 changed files with 11766 additions and 3822 deletions

View File

@ -1 +1 @@
mbedtls-2.18.1
mbedtls-2.19.0d0

View File

@ -27,7 +27,7 @@
#
# Set the mbed TLS release to import (this can/should be edited before import)
MBED_TLS_RELEASE ?= mbedtls-2.18.1
MBED_TLS_RELEASE ?= mbedtls-2.19.0d0
MBED_TLS_REPO_URL ?= git@github.com:ARMmbed/mbedtls-restricted.git
# Translate between mbed TLS namespace and mbed namespace

View File

@ -25,7 +25,7 @@
#define MBEDTLS_CERTS_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -36,68 +36,214 @@
extern "C" {
#endif
/* List of all PEM-encoded CA certificates, terminated by NULL;
* PEM encoded if MBEDTLS_PEM_PARSE_C is enabled, DER encoded
* otherwise. */
extern const char * mbedtls_test_cas[];
extern const size_t mbedtls_test_cas_len[];
/* List of all DER-encoded CA certificates, terminated by NULL */
extern const unsigned char * mbedtls_test_cas_der[];
extern const size_t mbedtls_test_cas_der_len[];
#if defined(MBEDTLS_PEM_PARSE_C)
/* Concatenation of all CA certificates in PEM format if available */
extern const char mbedtls_test_cas_pem[];
extern const size_t mbedtls_test_cas_pem_len;
#endif
/* List of all CA certificates, terminated by NULL */
extern const char * mbedtls_test_cas[];
extern const size_t mbedtls_test_cas_len[];
#endif /* MBEDTLS_PEM_PARSE_C */
/*
* Convenience for users who just want a certificate:
* RSA by default, or ECDSA if RSA is not available
* CA test certificates
*/
extern const char * mbedtls_test_ca_crt;
extern const size_t mbedtls_test_ca_crt_len;
extern const char * mbedtls_test_ca_key;
extern const size_t mbedtls_test_ca_key_len;
extern const char * mbedtls_test_ca_pwd;
extern const size_t mbedtls_test_ca_pwd_len;
extern const char * mbedtls_test_srv_crt;
extern const size_t mbedtls_test_srv_crt_len;
extern const char * mbedtls_test_srv_key;
extern const size_t mbedtls_test_srv_key_len;
extern const char * mbedtls_test_cli_crt;
extern const size_t mbedtls_test_cli_crt_len;
extern const char * mbedtls_test_cli_key;
extern const size_t mbedtls_test_cli_key_len;
#if defined(MBEDTLS_ECDSA_C)
extern const char mbedtls_test_ca_crt_ec[];
extern const char mbedtls_test_ca_crt_ec_pem[];
extern const char mbedtls_test_ca_key_ec_pem[];
extern const char mbedtls_test_ca_pwd_ec_pem[];
extern const char mbedtls_test_ca_key_rsa_pem[];
extern const char mbedtls_test_ca_pwd_rsa_pem[];
extern const char mbedtls_test_ca_crt_rsa_sha1_pem[];
extern const char mbedtls_test_ca_crt_rsa_sha256_pem[];
extern const unsigned char mbedtls_test_ca_crt_ec_der[];
extern const unsigned char mbedtls_test_ca_key_ec_der[];
extern const unsigned char mbedtls_test_ca_key_rsa_der[];
extern const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[];
extern const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[];
extern const size_t mbedtls_test_ca_crt_ec_pem_len;
extern const size_t mbedtls_test_ca_key_ec_pem_len;
extern const size_t mbedtls_test_ca_pwd_ec_pem_len;
extern const size_t mbedtls_test_ca_key_rsa_pem_len;
extern const size_t mbedtls_test_ca_pwd_rsa_pem_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len;
extern const size_t mbedtls_test_ca_crt_ec_der_len;
extern const size_t mbedtls_test_ca_key_ec_der_len;
extern const size_t mbedtls_test_ca_pwd_ec_der_len;
extern const size_t mbedtls_test_ca_key_rsa_der_len;
extern const size_t mbedtls_test_ca_pwd_rsa_der_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha1_der_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha256_der_len;
/* Config-dependent dispatch between PEM and DER encoding
* (PEM if enabled, otherwise DER) */
extern const char mbedtls_test_ca_crt_ec[];
extern const char mbedtls_test_ca_key_ec[];
extern const char mbedtls_test_ca_pwd_ec[];
extern const char mbedtls_test_ca_key_rsa[];
extern const char mbedtls_test_ca_pwd_rsa[];
extern const char mbedtls_test_ca_crt_rsa_sha1[];
extern const char mbedtls_test_ca_crt_rsa_sha256[];
extern const size_t mbedtls_test_ca_crt_ec_len;
extern const char mbedtls_test_ca_key_ec[];
extern const size_t mbedtls_test_ca_key_ec_len;
extern const char mbedtls_test_ca_pwd_ec[];
extern const size_t mbedtls_test_ca_pwd_ec_len;
extern const char mbedtls_test_srv_crt_ec[];
extern const size_t mbedtls_test_srv_crt_ec_len;
extern const char mbedtls_test_srv_key_ec[];
extern const size_t mbedtls_test_srv_key_ec_len;
extern const char mbedtls_test_cli_crt_ec[];
extern const size_t mbedtls_test_cli_crt_ec_len;
extern const char mbedtls_test_cli_key_ec[];
extern const size_t mbedtls_test_cli_key_ec_len;
#endif
#if defined(MBEDTLS_RSA_C)
extern const char mbedtls_test_ca_crt_rsa[];
extern const size_t mbedtls_test_ca_crt_rsa_len;
extern const char mbedtls_test_ca_key_rsa[];
extern const size_t mbedtls_test_ca_key_rsa_len;
extern const char mbedtls_test_ca_pwd_rsa[];
extern const size_t mbedtls_test_ca_pwd_rsa_len;
extern const char mbedtls_test_srv_crt_rsa[];
extern const size_t mbedtls_test_srv_crt_rsa_len;
extern const char mbedtls_test_srv_key_rsa[];
extern const size_t mbedtls_test_ca_crt_rsa_sha1_len;
extern const size_t mbedtls_test_ca_crt_rsa_sha256_len;
/* Config-dependent dispatch between SHA-1 and SHA-256
* (SHA-256 if enabled, otherwise SHA-1) */
extern const char mbedtls_test_ca_crt_rsa[];
extern const size_t mbedtls_test_ca_crt_rsa_len;
/* Config-dependent dispatch between EC and RSA
* (RSA if enabled, otherwise EC) */
extern const char * mbedtls_test_ca_crt;
extern const char * mbedtls_test_ca_key;
extern const char * mbedtls_test_ca_pwd;
extern const size_t mbedtls_test_ca_crt_len;
extern const size_t mbedtls_test_ca_key_len;
extern const size_t mbedtls_test_ca_pwd_len;
/*
* Server test certificates
*/
extern const char mbedtls_test_srv_crt_ec_pem[];
extern const char mbedtls_test_srv_key_ec_pem[];
extern const char mbedtls_test_srv_pwd_ec_pem[];
extern const char mbedtls_test_srv_key_rsa_pem[];
extern const char mbedtls_test_srv_pwd_rsa_pem[];
extern const char mbedtls_test_srv_crt_rsa_sha1_pem[];
extern const char mbedtls_test_srv_crt_rsa_sha256_pem[];
extern const unsigned char mbedtls_test_srv_crt_ec_der[];
extern const unsigned char mbedtls_test_srv_key_ec_der[];
extern const unsigned char mbedtls_test_srv_key_rsa_der[];
extern const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[];
extern const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[];
extern const size_t mbedtls_test_srv_crt_ec_pem_len;
extern const size_t mbedtls_test_srv_key_ec_pem_len;
extern const size_t mbedtls_test_srv_pwd_ec_pem_len;
extern const size_t mbedtls_test_srv_key_rsa_pem_len;
extern const size_t mbedtls_test_srv_pwd_rsa_pem_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len;
extern const size_t mbedtls_test_srv_crt_ec_der_len;
extern const size_t mbedtls_test_srv_key_ec_der_len;
extern const size_t mbedtls_test_srv_pwd_ec_der_len;
extern const size_t mbedtls_test_srv_key_rsa_der_len;
extern const size_t mbedtls_test_srv_pwd_rsa_der_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha1_der_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha256_der_len;
/* Config-dependent dispatch between PEM and DER encoding
* (PEM if enabled, otherwise DER) */
extern const char mbedtls_test_srv_crt_ec[];
extern const char mbedtls_test_srv_key_ec[];
extern const char mbedtls_test_srv_pwd_ec[];
extern const char mbedtls_test_srv_key_rsa[];
extern const char mbedtls_test_srv_pwd_rsa[];
extern const char mbedtls_test_srv_crt_rsa_sha1[];
extern const char mbedtls_test_srv_crt_rsa_sha256[];
extern const size_t mbedtls_test_srv_crt_ec_len;
extern const size_t mbedtls_test_srv_key_ec_len;
extern const size_t mbedtls_test_srv_pwd_ec_len;
extern const size_t mbedtls_test_srv_key_rsa_len;
extern const char mbedtls_test_cli_crt_rsa[];
extern const size_t mbedtls_test_cli_crt_rsa_len;
extern const char mbedtls_test_cli_key_rsa[];
extern const size_t mbedtls_test_srv_pwd_rsa_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha1_len;
extern const size_t mbedtls_test_srv_crt_rsa_sha256_len;
/* Config-dependent dispatch between SHA-1 and SHA-256
* (SHA-256 if enabled, otherwise SHA-1) */
extern const char mbedtls_test_srv_crt_rsa[];
extern const size_t mbedtls_test_srv_crt_rsa_len;
/* Config-dependent dispatch between EC and RSA
* (RSA if enabled, otherwise EC) */
extern const char * mbedtls_test_srv_crt;
extern const char * mbedtls_test_srv_key;
extern const char * mbedtls_test_srv_pwd;
extern const size_t mbedtls_test_srv_crt_len;
extern const size_t mbedtls_test_srv_key_len;
extern const size_t mbedtls_test_srv_pwd_len;
/*
* Client test certificates
*/
extern const char mbedtls_test_cli_crt_ec_pem[];
extern const char mbedtls_test_cli_key_ec_pem[];
extern const char mbedtls_test_cli_pwd_ec_pem[];
extern const char mbedtls_test_cli_key_rsa_pem[];
extern const char mbedtls_test_cli_pwd_rsa_pem[];
extern const char mbedtls_test_cli_crt_rsa_pem[];
extern const unsigned char mbedtls_test_cli_crt_ec_der[];
extern const unsigned char mbedtls_test_cli_key_ec_der[];
extern const unsigned char mbedtls_test_cli_key_rsa_der[];
extern const unsigned char mbedtls_test_cli_crt_rsa_der[];
extern const size_t mbedtls_test_cli_crt_ec_pem_len;
extern const size_t mbedtls_test_cli_key_ec_pem_len;
extern const size_t mbedtls_test_cli_pwd_ec_pem_len;
extern const size_t mbedtls_test_cli_key_rsa_pem_len;
extern const size_t mbedtls_test_cli_pwd_rsa_pem_len;
extern const size_t mbedtls_test_cli_crt_rsa_pem_len;
extern const size_t mbedtls_test_cli_crt_ec_der_len;
extern const size_t mbedtls_test_cli_key_ec_der_len;
extern const size_t mbedtls_test_cli_key_rsa_der_len;
extern const size_t mbedtls_test_cli_crt_rsa_der_len;
/* Config-dependent dispatch between PEM and DER encoding
* (PEM if enabled, otherwise DER) */
extern const char mbedtls_test_cli_crt_ec[];
extern const char mbedtls_test_cli_key_ec[];
extern const char mbedtls_test_cli_pwd_ec[];
extern const char mbedtls_test_cli_key_rsa[];
extern const char mbedtls_test_cli_pwd_rsa[];
extern const char mbedtls_test_cli_crt_rsa[];
extern const size_t mbedtls_test_cli_crt_ec_len;
extern const size_t mbedtls_test_cli_key_ec_len;
extern const size_t mbedtls_test_cli_pwd_ec_len;
extern const size_t mbedtls_test_cli_key_rsa_len;
#endif
extern const size_t mbedtls_test_cli_pwd_rsa_len;
extern const size_t mbedtls_test_cli_crt_rsa_len;
/* Config-dependent dispatch between EC and RSA
* (RSA if enabled, otherwise EC) */
extern const char * mbedtls_test_cli_crt;
extern const char * mbedtls_test_cli_key;
extern const char * mbedtls_test_cli_pwd;
extern const size_t mbedtls_test_cli_crt_len;
extern const size_t mbedtls_test_cli_key_len;
extern const size_t mbedtls_test_cli_pwd_len;
#ifdef __cplusplus
}

View File

@ -26,7 +26,7 @@
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -293,28 +293,52 @@
* For example, when a function accepts as input a pointer to a buffer that may
* contain untrusted data, and its documentation mentions that this pointer
* must not be NULL:
* - the pointer is checked to be non-NULL only if this option is enabled
* - the content of the buffer is always validated
* - The pointer is checked to be non-NULL only if this option is enabled.
* - The content of the buffer is always validated.
*
* When this flag is defined, if a library function receives a parameter that
* is invalid, it will:
* - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a
* call to the function mbedtls_param_failed()
* - immediately return (with a specific error code unless the function
* returns void and can't communicate an error).
* is invalid:
* 1. The function will invoke the macro MBEDTLS_PARAM_FAILED().
* 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function
* will immediately return. If the function returns an Mbed TLS error code,
* the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA.
*
* When defining this flag, you also need to:
* - either provide a definition of the function mbedtls_param_failed() in
* your application (see platform_util.h for its prototype) as the library
* calls that function, but does not provide a default definition for it,
* - or provide a different definition of the macro MBEDTLS_PARAM_FAILED()
* below if the above mechanism is not flexible enough to suit your needs.
* See the documentation of this macro later in this file.
* When defining this flag, you also need to arrange a definition for
* MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods:
* - By default, the library defines MBEDTLS_PARAM_FAILED() to call a
* function mbedtls_param_failed(), but the library does not define this
* function. If you do not make any other arrangements, you must provide
* the function mbedtls_param_failed() in your application.
* See `platform_util.h` for its prototype.
* - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the
* library defines MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`.
* You can still supply an alternative definition of
* MBEDTLS_PARAM_FAILED(), which may call `assert`.
* - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h`
* or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`,
* the library will call the macro that you defined and will not supply
* its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`,
* you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source
* files include `<assert.h>`.
*
* Uncomment to enable validation of application-controlled parameters.
*/
//#define MBEDTLS_CHECK_PARAMS
/**
* \def MBEDTLS_CHECK_PARAMS_ASSERT
*
* Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to
* `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined.
*
* If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to
* calling a function mbedtls_param_failed(). See the documentation of
* #MBEDTLS_CHECK_PARAMS for details.
*
* Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`.
*/
//#define MBEDTLS_CHECK_PARAMS_ASSERT
/* \} name SECTION: System support */
/**
@ -1342,6 +1366,20 @@
*/
#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
/**
* \def MBEDTLS_SSL_RECORD_CHECKING
*
* Enable the function mbedtls_ssl_check_record() which can be used to check
* the validity and authenticity of an incoming record, to verify that it has
* not been seen before. These checks are performed without modifying the
* externally visible state of the SSL context.
*
* See mbedtls_ssl_check_record() for more information.
*
* Uncomment to enable support for record checking.
*/
#define MBEDTLS_SSL_RECORD_CHECKING
/**
* \def MBEDTLS_SSL_DTLS_CONNECTION_ID
*
@ -1381,6 +1419,33 @@
*/
//#define MBEDTLS_SSL_ASYNC_PRIVATE
/**
* \def MBEDTLS_SSL_CONTEXT_SERIALIZATION
*
* Enable serialization of the TLS context structures, through use of the
* functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load().
*
* This pair of functions allows one side of a connection to serialize the
* context associated with the connection, then free or re-use that context
* while the serialized state is persisted elsewhere, and finally deserialize
* that state to a live context for resuming read/write operations on the
* connection. From a protocol perspective, the state of the connection is
* unaffected, in particular this is entirely transparent to the peer.
*
* Note: this is distinct from TLS session resumption, which is part of the
* protocol and fully visible by the peer. TLS session resumption enables
* establishing new connections associated to a saved session with shorter,
* lighter handshakes, while context serialization is a local optimization in
* handling a single, potentially long-lived connection.
*
* Enabling these APIs makes some SSL structures larger, as 64 extra bytes are
* saved after the handshake to allow for more efficient serialization, so if
* you don't need this feature you'll save RAM by disabling it.
*
* Comment to disable the context serialization APIs.
*/
#define MBEDTLS_SSL_CONTEXT_SERIALIZATION
/**
* \def MBEDTLS_SSL_DEBUG_ALL
*
@ -3272,13 +3337,16 @@
/**
* \brief This macro is invoked by the library when an invalid parameter
* is detected that is only checked with MBEDTLS_CHECK_PARAMS
* is detected that is only checked with #MBEDTLS_CHECK_PARAMS
* (see the documentation of that option for context).
*
* When you leave this undefined here, a default definition is
* provided that invokes the function mbedtls_param_failed(),
* which is declared in platform_util.h for the benefit of the
* library, but that you need to define in your application.
* When you leave this undefined here, the library provides
* a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT
* is defined, the default definition is `assert(cond)`,
* otherwise the default definition calls a function
* mbedtls_param_failed(). This function is declared in
* `platform_util.h` for the benefit of the library, but
* you need to define in your application.
*
* When you define this here, this replaces the default
* definition in platform_util.h (which no longer declares the
@ -3287,6 +3355,9 @@
* particular, that all the necessary declarations are visible
* from within the library - you can ensure that by providing
* them in this file next to the macro definition).
* If you define this macro to call `assert`, also define
* #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files
* include `<assert.h>`.
*
* Note that you may define this macro to expand to nothing, in
* which case you don't have to worry about declarations or
@ -3532,7 +3603,7 @@
#include MBEDTLS_USER_CONFIG_FILE
#endif
#include "check_config.h"
#include "mbedtls/check_config.h"
#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !MBEDTLS_TEST_NULL_ENTROPY && !MBEDTLS_ENTROPY_NV_SEED */

View File

@ -25,15 +25,15 @@
#define MBEDTLS_DEBUG_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ssl.h"
#include "mbedtls/ssl.h"
#if defined(MBEDTLS_ECP_C)
#include "ecp.h"
#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_DEBUG_C)

View File

@ -25,7 +25,7 @@
#define MBEDTLS_ERROR_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -100,6 +100,7 @@
* ECP 4 10 (Started from top)
* MD 5 5
* HKDF 5 1 (Started from top)
* SSL 5 1 (Started from 0x5F00)
* CIPHER 6 8 (Started from 0x6080)
* SSL 6 24 (Started from top, plus 0x6000)
* SSL 7 32

View File

@ -24,13 +24,13 @@
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#include "net_sockets.h"
#include "mbedtls/net_sockets.h"
#if defined(MBEDTLS_DEPRECATED_WARNING)
#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
#endif /* MBEDTLS_DEPRECATED_WARNING */

View File

@ -41,12 +41,12 @@
#define MBEDTLS_NET_SOCKETS_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ssl.h"
#include "mbedtls/ssl.h"
#include <stddef.h>
#include <stdint.h>

View File

@ -27,14 +27,14 @@
#define MBEDTLS_PKCS11_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PKCS11_C)
#include "x509_crt.h"
#include "mbedtls/x509_crt.h"
#include <pkcs11-helper-1.0/pkcs11h-certificate.h>

View File

@ -25,27 +25,27 @@
#define MBEDTLS_SSL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "bignum.h"
#include "ecp.h"
#include "mbedtls/bignum.h"
#include "mbedtls/ecp.h"
#include "ssl_ciphersuites.h"
#include "mbedtls/ssl_ciphersuites.h"
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "x509_crt.h"
#include "x509_crl.h"
#include "mbedtls/x509_crt.h"
#include "mbedtls/x509_crl.h"
#endif
#if defined(MBEDTLS_DHM_C)
#include "dhm.h"
#include "mbedtls/dhm.h"
#endif
#if defined(MBEDTLS_ECDH_C)
#include "ecdh.h"
#include "mbedtls/ecdh.h"
#endif
#if defined(MBEDTLS_ZLIB_SUPPORT)
@ -62,7 +62,7 @@
#endif
#if defined(MBEDTLS_HAVE_TIME)
#include "platform_time.h"
#include "mbedtls/platform_time.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -127,6 +127,7 @@
#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */
#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */
#define MBEDTLS_ERR_SSL_UNEXPECTED_CID -0x6000 /**< An encrypted DTLS-frame with an unexpected CID was received. */
#define MBEDTLS_ERR_SSL_VERSION_MISMATCH -0x5F00 /**< An operation failed due to an unexpected version or configuration. */
#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */
/*
@ -845,6 +846,14 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
/*
* This structure is used for storing current session data.
*
* Note: when changing this definition, we need to check and update:
* - in tests/suites/test_suite_ssl.function:
* ssl_populate_session() and ssl_serialize_session_save_load()
* - in library/ssl_tls.c:
* mbedtls_ssl_session_init() and mbedtls_ssl_session_free()
* mbedtls_ssl_session_save() and ssl_session_load()
* ssl_session_copy()
*/
struct mbedtls_ssl_session
{
@ -1756,6 +1765,56 @@ void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
*/
void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout );
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
/**
* \brief Check whether a buffer contains a valid and authentic record
* that has not been seen before. (DTLS only).
*
* This function does not change the user-visible state
* of the SSL context. Its sole purpose is to provide
* an indication of the legitimacy of an incoming record.
*
* This can be useful e.g. in distributed server environments
* using the DTLS Connection ID feature, in which connections
* might need to be passed between service instances on a change
* of peer address, but where such disruptive operations should
* only happen after the validity of incoming records has been
* confirmed.
*
* \param ssl The SSL context to use.
* \param buf The address of the buffer holding the record to be checked.
* This must be a read/write buffer of length \p buflen Bytes.
* \param buflen The length of \p buf in Bytes.
*
* \note This routine only checks whether the provided buffer begins
* with a valid and authentic record that has not been seen
* before, but does not check potential data following the
* initial record. In particular, it is possible to pass DTLS
* datagrams containing multiple records, in which case only
* the first record is checked.
*
* \note This function modifies the input buffer \p buf. If you need
* to preserve the original record, you have to maintain a copy.
*
* \return \c 0 if the record is valid and authentic and has not been
* seen before.
* \return MBEDTLS_ERR_SSL_INVALID_MAC if the check completed
* successfully but the record was found to be not authentic.
* \return MBEDTLS_ERR_SSL_INVALID_RECORD if the check completed
* successfully but the record was found to be invalid for
* a reason different from authenticity checking.
* \return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD if the check completed
* successfully but the record was found to be unexpected
* in the state of the SSL context, including replayed records.
* \return Another negative error code on different kinds of failure.
* In this case, the SSL context becomes unusable and needs
* to be freed or reset before reuse.
*/
int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl,
unsigned char *buf,
size_t buflen );
#endif /* MBEDTLS_SSL_RECORD_CHECKING */
/**
* \brief Set the timer callbacks (Mandatory for DTLS.)
*
@ -2298,6 +2357,90 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session );
#endif /* MBEDTLS_SSL_CLI_C */
/**
* \brief Load serialized session data into a session structure.
* On client, this can be used for loading saved sessions
* before resuming them with mbedstls_ssl_set_session().
* On server, this can be used for alternative implementations
* of session cache or session tickets.
*
* \warning If a peer certificate chain is associated with the session,
* the serialized state will only contain the peer's
* end-entity certificate and the result of the chain
* verification (unless verification was disabled), but not
* the rest of the chain.
*
* \see mbedtls_ssl_session_save()
* \see mbedtls_ssl_set_session()
*
* \param session The session structure to be populated. It must have been
* initialised with mbedtls_ssl_session_init() but not
* populated yet.
* \param buf The buffer holding the serialized session data. It must be a
* readable buffer of at least \p len bytes.
* \param len The size of the serialized data in bytes.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
* \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data
* was generated in a different version or configuration of
* Mbed TLS.
* \return Another negative value for other kinds of errors (for
* example, unsupported features in the embedded certificate).
*/
int mbedtls_ssl_session_load( mbedtls_ssl_session *session,
const unsigned char *buf,
size_t len );
/**
* \brief Save session structure as serialized data in a buffer.
* On client, this can be used for saving session data,
* potentially in non-volatile storage, for resuming later.
* On server, this can be used for alternative implementations
* of session cache or session tickets.
*
* \see mbedtls_ssl_session_load()
* \see mbedtls_ssl_get_session_pointer()
*
* \param session The session structure to be saved.
* \param buf The buffer to write the serialized data to. It must be a
* writeable buffer of at least \p len bytes, or may be \c
* NULL if \p len is \c 0.
* \param buf_len The number of bytes available for writing in \p buf.
* \param olen The size in bytes of the data that has been or would have
* been written. It must point to a valid \c size_t.
*
* \note \p olen is updated to the correct value regardless of
* whether \p buf_len was large enough. This makes it possible
* to determine the necessary size by calling this function
* with \p buf set to \c NULL and \p buf_len to \c 0.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
*/
int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
unsigned char *buf,
size_t buf_len,
size_t *olen );
/**
* \brief Get a pointer to the current session structure, for example
* to serialize it.
*
* \warning Ownership of the session remains with the SSL context, and
* the returned pointer is only guaranteed to be valid until
* the next API call operating on the same \p ssl context.
*
* \see mbedtls_ssl_session_save()
*
* \param ssl The SSL context.
*
* \return A pointer to the current session if successful.
* \return \c NULL if no session is active.
*/
const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl );
/**
* \brief Set the list of allowed ciphersuites and the preference
* order. First in the list has the highest preference.
@ -3736,6 +3879,130 @@ int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl );
*/
void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
/**
* \brief Save an active connection as serialized data in a buffer.
* This allows the freeing or re-using of the SSL context
* while still picking up the connection later in a way that
* it entirely transparent to the peer.
*
* \see mbedtls_ssl_context_load()
*
* \note This feature is currently only available under certain
* conditions, see the documentation of the return value
* #MBEDTLS_ERR_SSL_BAD_INPUT_DATA for details.
*
* \note When this function succeeds, it calls
* mbedtls_ssl_session_reset() on \p ssl which as a result is
* no longer associated with the connection that has been
* serialized. This avoids creating copies of the connection
* state. You're then free to either re-use the context
* structure for a different connection, or call
* mbedtls_ssl_free() on it. See the documentation of
* mbedtls_ssl_session_reset() for more details.
*
* \param ssl The SSL context to save. On success, it is no longer
* associated with the connection that has been serialized.
* \param buf The buffer to write the serialized data to. It must be a
* writeable buffer of at least \p buf_len bytes, or may be \c
* NULL if \p buf_len is \c 0.
* \param buf_len The number of bytes available for writing in \p buf.
* \param olen The size in bytes of the data that has been or would have
* been written. It must point to a valid \c size_t.
*
* \note \p olen is updated to the correct value regardless of
* whether \p buf_len was large enough. This makes it possible
* to determine the necessary size by calling this function
* with \p buf set to \c NULL and \p buf_len to \c 0. However,
* the value of \p olen is only guaranteed to be correct when
* the function returns #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL or
* \c 0. If the return value is different, then the value of
* \p olen is undefined.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
* \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed
* while reseting the context.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if a handshake is in
* progress, or there is pending data for reading or sending,
* or the connection does not use DTLS 1.2 with an AEAD
* ciphersuite, or renegotiation is enabled.
*/
int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t buf_len,
size_t *olen );
/**
* \brief Load serialized connection data to an SSL context.
*
* \see mbedtls_ssl_context_save()
*
* \warning The same serialized data must never be loaded into more
* that one context. In order to ensure that, after
* successfully loading serialized data to an SSL context, you
* should immediately destroy or invalidate all copies of the
* serialized data that was loaded. Loading the same data in
* more than one context would cause severe security failures
* including but not limited to loss of confidentiality.
*
* \note Before calling this function, the SSL context must be
* prepared in one of the two following ways. The first way is
* to take a context freshly initialised with
* mbedtls_ssl_init() and call mbedtls_ssl_setup() on it with
* the same ::mbedtls_ssl_config structure that was used in
* the original connection. The second way is to
* call mbedtls_ssl_session_reset() on a context that was
* previously prepared as above but used in the meantime.
* Either way, you must not use the context to perform a
* handshake between calling mbedtls_ssl_setup() or
* mbedtls_ssl_session_reset() and calling this function. You
* may however call other setter functions in that time frame
* as indicated in the note below.
*
* \note Before or after calling this function successfully, you
* also need to configure some connection-specific callbacks
* and settings before you can use the connection again
* (unless they were already set before calling
* mbedtls_ssl_session_reset() and the values are suitable for
* the present connection). Specifically, you want to call
* at least mbedtls_ssl_set_bio() and
* mbedtls_ssl_set_timer_cb(). All other SSL setter functions
* are not necessary to call, either because they're only used
* in handshakes, or because the setting is already saved. You
* might choose to call them anyway, for example in order to
* share code between the cases of establishing a new
* connection and the case of loading an already-established
* connection.
*
* \note If you have new information about the path MTU, you want to
* call mbedtls_ssl_set_mtu() after calling this function, as
* otherwise this function would overwrite your
* newly-configured value with the value that was active when
* the context was saved.
*
* \note When this function returns an error code, it calls
* mbedtls_ssl_free() on \p ssl. In this case, you need to
* prepare the context with the usual sequence starting with a
* call to mbedtls_ssl_init() if you want to use it again.
*
* \param ssl The SSL context structure to be populated. It must have
* been prepared as described in the note above.
* \param buf The buffer holding the serialized connection data. It must
* be a readable buffer of at least \p len bytes.
* \param len The size of the serialized data in bytes.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed.
* \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data
* comes from a different Mbed TLS version or build.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
*/
int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len );
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
/**
* \brief Initialize an SSL configuration context
* Just makes the context ready for

View File

@ -25,15 +25,15 @@
#define MBEDTLS_SSL_CACHE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ssl.h"
#include "mbedtls/ssl.h"
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#include "mbedtls/threading.h"
#endif
/**

View File

@ -25,14 +25,14 @@
#define MBEDTLS_SSL_CIPHERSUITES_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "pk.h"
#include "cipher.h"
#include "md.h"
#include "mbedtls/pk.h"
#include "mbedtls/cipher.h"
#include "mbedtls/md.h"
#ifdef __cplusplus
extern "C" {

View File

@ -25,15 +25,15 @@
#define MBEDTLS_SSL_COOKIE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ssl.h"
#include "mbedtls/ssl.h"
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#include "mbedtls/threading.h"
#endif
/**

View File

@ -25,41 +25,41 @@
#define MBEDTLS_SSL_INTERNAL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ssl.h"
#include "cipher.h"
#include "mbedtls/ssl.h"
#include "mbedtls/cipher.h"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#endif
#if defined(MBEDTLS_MD5_C)
#include "md5.h"
#include "mbedtls/md5.h"
#endif
#if defined(MBEDTLS_SHA1_C)
#include "sha1.h"
#include "mbedtls/sha1.h"
#endif
#if defined(MBEDTLS_SHA256_C)
#include "sha256.h"
#include "mbedtls/sha256.h"
#endif
#if defined(MBEDTLS_SHA512_C)
#include "sha512.h"
#include "mbedtls/sha512.h"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#include "ecjpake.h"
#include "mbedtls/ecjpake.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "psa_util.h"
#include "mbedtls/psa_util.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
@ -458,7 +458,7 @@ struct mbedtls_ssl_handshake_params
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
void (*calc_verify)(mbedtls_ssl_context *, unsigned char *);
void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *);
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
mbedtls_ssl_tls_prf_cb *tls_prf;
@ -642,8 +642,29 @@ struct mbedtls_ssl_transform
z_stream ctx_deflate; /*!< compression context */
z_stream ctx_inflate; /*!< decompression context */
#endif
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
/* We need the Hello random bytes in order to re-derive keys from the
* Master Secret and other session info, see ssl_populate_transform() */
unsigned char randbytes[64]; /*!< ServerHello.random+ClientHello.random */
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
};
/*
* Return 1 if the transform uses an AEAD cipher, 0 otherwise.
* Equivalently, return 0 if a separate MAC is used, 1 otherwise.
*/
static inline int mbedtls_ssl_transform_uses_aead(
const mbedtls_ssl_transform *transform )
{
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
return( transform->maclen == 0 && transform->taglen != 0 );
#else
(void) transform;
return( 1 );
#endif
}
/*
* Internal representation of record frames
*
@ -672,18 +693,29 @@ struct mbedtls_ssl_transform
typedef struct
{
uint8_t ctr[8]; /* Record sequence number */
uint8_t type; /* Record type */
uint8_t ver[2]; /* SSL/TLS version */
uint8_t ctr[8]; /* In TLS: The implicit record sequence number.
* In DTLS: The 2-byte epoch followed by
* the 6-byte sequence number.
* This is stored as a raw big endian byte array
* as opposed to a uint64_t because we rarely
* need to perform arithmetic on this, but do
* need it as a Byte array for the purpose of
* MAC computations. */
uint8_t type; /* The record content type. */
uint8_t ver[2]; /* SSL/TLS version as present on the wire.
* Convert to internal presentation of versions
* using mbedtls_ssl_read_version() and
* mbedtls_ssl_write_version().
* Keep wire-format for MAC computations. */
unsigned char *buf; /* Memory buffer enclosing the record content */
size_t buf_len; /* Buffer length */
size_t data_offset; /* Offset of record content */
size_t data_len; /* Length of record content */
unsigned char *buf; /* Memory buffer enclosing the record content */
size_t buf_len; /* Buffer length */
size_t data_offset; /* Offset of record content */
size_t data_len; /* Length of record content */
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
uint8_t cid_len; /* Length of the CID (0 if not present) */
unsigned char cid[ MBEDTLS_SSL_CID_LEN_MAX ]; /* The CID */
uint8_t cid_len; /* Length of the CID (0 if not present) */
unsigned char cid[ MBEDTLS_SSL_CID_LEN_MAX ]; /* The CID */
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
} mbedtls_record;
@ -930,7 +962,20 @@ void mbedtls_ssl_read_version( int *major, int *minor, int transport,
static inline size_t mbedtls_ssl_in_hdr_len( const mbedtls_ssl_context *ssl )
{
return( (size_t) ( ssl->in_iv - ssl->in_hdr ) );
#if !defined(MBEDTLS_SSL_PROTO_DTLS)
((void) ssl);
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
return( 13 );
}
else
#endif /* MBEDTLS_SSL_PROTO_DTLS */
{
return( 5 );
}
}
static inline size_t mbedtls_ssl_out_hdr_len( const mbedtls_ssl_context *ssl )
@ -958,7 +1003,7 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl );
/* Visible for testing purposes only */
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl );
int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl );
void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl );
#endif
@ -1013,7 +1058,7 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
mbedtls_record *rec,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl,
int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
mbedtls_ssl_transform *transform,
mbedtls_record *rec );

View File

@ -25,7 +25,7 @@
#define MBEDTLS_SSL_TICKET_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -36,11 +36,11 @@
* secrecy, when MBEDTLS_HAVE_TIME is defined.
*/
#include "ssl.h"
#include "cipher.h"
#include "mbedtls/ssl.h"
#include "mbedtls/cipher.h"
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#include "mbedtls/threading.h"
#endif
#ifdef __cplusplus

View File

@ -29,7 +29,7 @@
#define MBEDTLS_VERSION_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -25,16 +25,16 @@
#define MBEDTLS_X509_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "asn1.h"
#include "pk.h"
#include "mbedtls/asn1.h"
#include "mbedtls/pk.h"
#if defined(MBEDTLS_RSA_C)
#include "rsa.h"
#include "mbedtls/rsa.h"
#endif
/**

View File

@ -25,12 +25,12 @@
#define MBEDTLS_X509_CRL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "x509.h"
#include "mbedtls/x509.h"
#ifdef __cplusplus
extern "C" {

View File

@ -25,13 +25,14 @@
#define MBEDTLS_X509_CRT_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "x509.h"
#include "x509_crl.h"
#include "mbedtls/x509.h"
#include "mbedtls/x509_crl.h"
#include "mbedtls/bignum.h"
/**
* \addtogroup x509_module

View File

@ -25,12 +25,12 @@
#define MBEDTLS_X509_CSR_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "x509.h"
#include "mbedtls/x509.h"
#ifdef __cplusplus
extern "C" {

View File

@ -1 +1 @@
mbedcrypto-1.1.1
mbedcrypto-2.0.0d1

View File

@ -29,7 +29,7 @@
# Set the Mbed Crypto release to import (this can/should be edited before
# import)
CRYPTO_RELEASE ?= mbedcrypto-1.1.1
CRYPTO_RELEASE ?= mbedcrypto-2.0.0d1
CRYPTO_REPO_URL ?= git@github.com:ARMmbed/mbed-crypto.git
# Translate between Mbed Crypto namespace and Mbed OS namespace

View File

@ -42,7 +42,7 @@
#define MBEDTLS_AES_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -28,12 +28,12 @@
#define MBEDTLS_AESNI_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "aes.h"
#include "mbedtls/aes.h"
#define MBEDTLS_AESNI_AES 0x02000000u
#define MBEDTLS_AESNI_CLMUL 0x00000002u

View File

@ -29,7 +29,7 @@
#define MBEDTLS_ARC4_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -31,7 +31,7 @@
#define MBEDTLS_ARIA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -39,7 +39,7 @@
#include <stddef.h>
#include <stdint.h>
#include "platform_util.h"
#include "mbedtls/platform_util.h"
#define MBEDTLS_ARIA_ENCRYPT 1 /**< ARIA encryption. */
#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */

View File

@ -25,7 +25,7 @@
#define MBEDTLS_ASN1_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -33,7 +33,7 @@
#include <stddef.h>
#if defined(MBEDTLS_BIGNUM_C)
#include "bignum.h"
#include "mbedtls/bignum.h"
#endif
/**
@ -66,7 +66,7 @@
* - 0x02 -- tag indicating INTEGER
* - 0x01 -- length in octets
* - 0x05 -- value
* Such sequences are typically read into \c ::mbedtls_x509_buf.
* Such sequences are typically read into Mbed TLS's \c mbedtls_x509_buf.
* \{
*/
#define MBEDTLS_ASN1_BOOLEAN 0x01

View File

@ -25,12 +25,12 @@
#define MBEDTLS_ASN1_WRITE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "asn1.h"
#include "mbedtls/asn1.h"
#define MBEDTLS_ASN1_CHK_ADD(g, f) \
do \

View File

@ -25,7 +25,7 @@
#define MBEDTLS_BASE64_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -25,7 +25,7 @@
#define MBEDTLS_BIGNUM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -25,7 +25,7 @@
#define MBEDTLS_BLOWFISH_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -33,7 +33,7 @@
#include <stddef.h>
#include <stdint.h>
#include "platform_util.h"
#include "mbedtls/platform_util.h"
#define MBEDTLS_BLOWFISH_ENCRYPT 1
#define MBEDTLS_BLOWFISH_DECRYPT 0

View File

@ -39,12 +39,12 @@
#define MBEDTLS_BN_MUL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "bignum.h"
#include "mbedtls/bignum.h"
#if defined(MBEDTLS_HAVE_ASM)
@ -642,7 +642,8 @@
"r6", "r7", "r8", "r9", "cc" \
);
#elif defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
#elif (__ARM_ARCH >= 6) && \
defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
#define MULADDC_INIT \
asm(

View File

@ -25,7 +25,7 @@
#define MBEDTLS_CAMELLIA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -33,7 +33,7 @@
#include <stddef.h>
#include <stdint.h>
#include "platform_util.h"
#include "mbedtls/platform_util.h"
#define MBEDTLS_CAMELLIA_ENCRYPT 1
#define MBEDTLS_CAMELLIA_DECRYPT 0

View File

@ -50,12 +50,12 @@
#define MBEDTLS_CCM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "cipher.h"
#include "mbedtls/cipher.h"
#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */
#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */

View File

@ -34,7 +34,7 @@
#define MBEDTLS_CHACHA20_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -34,13 +34,13 @@
#define MBEDTLS_CHACHAPOLY_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
/* for shared error codes */
#include "poly1305.h"
#include "mbedtls/poly1305.h"
#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054 /**< The requested operation is not permitted in the current state. */
#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056 /**< Authenticated decryption failed: data was not authentic. */
@ -58,7 +58,7 @@ mbedtls_chachapoly_mode_t;
#if !defined(MBEDTLS_CHACHAPOLY_ALT)
#include "chacha20.h"
#include "mbedtls/chacha20.h"
typedef struct mbedtls_chachapoly_context
{

View File

@ -30,13 +30,13 @@
#define MBEDTLS_CIPHER_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include "platform_util.h"
#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#define MBEDTLS_CIPHER_MODE_AEAD

View File

@ -27,12 +27,12 @@
#define MBEDTLS_CIPHER_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "cipher.h"
#include "mbedtls/cipher.h"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
@ -124,14 +124,13 @@ typedef enum
MBEDTLS_CIPHER_PSA_KEY_UNSET = 0,
MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */
/* use raw key material internally imported */
/* into a allocated key slot, and which */
/* hence need to destroy that key slot */
/* when they are no longer needed. */
/* as a volatile key, and which hence need */
/* to destroy that key when the context is */
/* freed. */
MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */
/* which use a key from a key slot */
/* provided by the user, and which */
/* hence should not be destroyed when */
/* the context is no longer needed. */
/* which use a key provided by the */
/* user, and which hence will not be */
/* destroyed when the context is freed. */
} mbedtls_cipher_psa_key_ownership;
typedef struct

View File

@ -29,12 +29,12 @@
#define MBEDTLS_CMAC_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "cipher.h"
#include "mbedtls/cipher.h"
#ifdef __cplusplus
extern "C" {

View File

@ -37,15 +37,15 @@
#define MBEDTLS_CTR_DRBG_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "aes.h"
#include "mbedtls/aes.h"
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#include "mbedtls/threading.h"
#endif
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */

View File

@ -30,7 +30,7 @@
#define MBEDTLS_DES_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -66,11 +66,11 @@
#define MBEDTLS_DHM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "bignum.h"
#include "mbedtls/bignum.h"
/*
* DHM Error codes
@ -298,7 +298,6 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
#if defined(MBEDTLS_ASN1_PARSE_C)
/** \ingroup x509_module */
/**
* \brief This function parses DHM parameters in PEM or DER format.
*
@ -317,7 +316,6 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
size_t dhminlen );
#if defined(MBEDTLS_FS_IO)
/** \ingroup x509_module */
/**
* \brief This function loads and parses DHM parameters from a file.
*
@ -350,11 +348,10 @@ int mbedtls_dhm_self_test( int verbose );
#endif
/**
* RFC 3526, RFC 5114 and RFC 7919 standardize a number of
* Diffie-Hellman groups, some of which are included here
* for use within the SSL/TLS module and the user's convenience
* when configuring the Diffie-Hellman parameters by hand
* through \c mbedtls_ssl_conf_dh_param.
* RFC 3526, RFC 5114 and RFC 7919 standardize a number of Diffie-Hellman
* groups, some of which are included here for use by Mbed TLS's SSL/TLS module
* and the user's convenience when configuring the Diffie-Hellman parameters by
* hand through Mbed TLS's \c mbedtls_ssl_conf_dh_param.
*
* The following lists the source of the above groups in the standards:
* - RFC 5114 section 2.2: 2048-bit MODP Group with 224-bit Prime Order Subgroup

View File

@ -35,12 +35,12 @@
#define MBEDTLS_ECDH_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ecp.h"
#include "mbedtls/ecp.h"
#ifdef __cplusplus
extern "C" {

View File

@ -33,13 +33,13 @@
#define MBEDTLS_ECDSA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ecp.h"
#include "md.h"
#include "mbedtls/ecp.h"
#include "mbedtls/md.h"
/**
* \brief Maximum ECDSA signature size for a given curve bit size

View File

@ -41,13 +41,13 @@
* also be use outside TLS.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ecp.h"
#include "md.h"
#include "mbedtls/ecp.h"
#include "mbedtls/md.h"
#ifdef __cplusplus
extern "C" {

View File

@ -37,12 +37,12 @@
#define MBEDTLS_ECP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "bignum.h"
#include "mbedtls/bignum.h"
/*
* ECP error codes
@ -375,19 +375,19 @@ mbedtls_ecp_keypair;
* same; they must not be used until the function finally
* returns 0.
*
* This only applies to functions whose documentation
* mentions they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS for functions in the
* SSL module). For functions that accept a "restart context"
* argument, passing NULL disables restart and makes the
* function equivalent to the function with the same name
* This only applies to functions whose documentation mentions
* they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or
* `MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS` for functions in the
* Mbed TLS SSL module). For functions that accept a "restart
* context" argument, passing NULL disables restart and makes
* the function equivalent to the function with the same name
* with \c _restartable removed. For functions in the ECDH
* module, restart is disabled unless the function accepts
* an "ECDH context" argument and
* mbedtls_ecdh_enable_restart() was previously called on
* that context. For function in the SSL module, restart is
* only enabled for specific sides and key exchanges
* (currently only for clients and ECDHE-ECDSA).
* module, restart is disabled unless the function accepts an
* "ECDH context" argument and mbedtls_ecdh_enable_restart()
* was previously called on that context. For function in the
* Mbed TLS SSL module, restart is only enabled for specific
* sides and key exchanges (currently only for clients and
* ECDHE-ECDSA).
*
* \param max_ops Maximum number of basic operations done in a row.
* Default: 0 (unlimited).

View File

@ -62,7 +62,7 @@
#define MBEDTLS_ECP_INTERNAL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -25,7 +25,7 @@
#define MBEDTLS_ENTROPY_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -33,21 +33,21 @@
#include <stddef.h>
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
#include "sha512.h"
#include "mbedtls/sha512.h"
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
#else
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
#include "sha256.h"
#include "mbedtls/sha256.h"
#endif
#endif
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#include "mbedtls/threading.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
#include "havege.h"
#include "mbedtls/havege.h"
#endif
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */

View File

@ -25,7 +25,7 @@
#define MBEDTLS_ENTROPY_POLL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -34,12 +34,12 @@
#define MBEDTLS_GCM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "cipher.h"
#include "mbedtls/cipher.h"
#include <stdint.h>

View File

@ -25,12 +25,13 @@
#define MBEDTLS_HAVEGE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#define MBEDTLS_HAVEGE_COLLECT_SIZE 1024
@ -43,9 +44,9 @@ extern "C" {
*/
typedef struct mbedtls_havege_state
{
int PT1, PT2, offset[2];
int pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
int WALK[8192];
uint32_t PT1, PT2, offset[2];
uint32_t pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
uint32_t WALK[8192];
}
mbedtls_havege_state;

View File

@ -7,33 +7,33 @@
* specified by RFC 5869.
*/
/*
* Copyright (C) 2016-2018, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2018-2019, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_HKDF_H
#define MBEDTLS_HKDF_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "md.h"
#include "mbedtls/md.h"
/**
* \name HKDF Error codes

View File

@ -25,15 +25,15 @@
#define MBEDTLS_HMAC_DRBG_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "md.h"
#include "mbedtls/md.h"
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#include "mbedtls/threading.h"
#endif
/*

View File

@ -30,7 +30,7 @@
#include <stddef.h>
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -30,7 +30,7 @@
#define MBEDTLS_MD2_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -30,7 +30,7 @@
#define MBEDTLS_MD4_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -29,7 +29,7 @@
#define MBEDTLS_MD5_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -29,12 +29,12 @@
#define MBEDTLS_MD_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "md.h"
#include "mbedtls/md.h"
#ifdef __cplusplus
extern "C" {

View File

@ -25,7 +25,7 @@
#define MBEDTLS_MEMORY_BUFFER_ALLOC_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -38,12 +38,12 @@
#define MBEDTLS_NIST_KW_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "cipher.h"
#include "mbedtls/cipher.h"
#ifdef __cplusplus
extern "C" {

View File

@ -25,22 +25,22 @@
#define MBEDTLS_OID_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "asn1.h"
#include "pk.h"
#include "mbedtls/asn1.h"
#include "mbedtls/pk.h"
#include <stddef.h>
#if defined(MBEDTLS_CIPHER_C)
#include "cipher.h"
#include "mbedtls/cipher.h"
#endif
#if defined(MBEDTLS_MD_C)
#include "md.h"
#include "mbedtls/md.h"
#endif
#define MBEDTLS_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */

View File

@ -29,12 +29,12 @@
#define MBEDTLS_PADLOCK_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "aes.h"
#include "mbedtls/aes.h"
#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */

View File

@ -25,7 +25,7 @@
#define MBEDTLS_PEM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -112,17 +112,27 @@ void mbedtls_pem_free( mbedtls_pem_context *ctx );
* \brief Write a buffer of PEM information from a DER encoded
* buffer.
*
* \param header header string to write
* \param footer footer string to write
* \param der_data DER data to write
* \param der_len length of the DER data
* \param buf buffer to write to
* \param buf_len length of output buffer
* \param olen total length written / required (if buf_len is not enough)
* \param header The header string to write.
* \param footer The footer string to write.
* \param der_data The DER data to encode.
* \param der_len The length of the DER data \p der_data in Bytes.
* \param buf The buffer to write to.
* \param buf_len The length of the output buffer \p buf in Bytes.
* \param olen The address at which to store the total length written
* or required (if \p buf_len is not enough).
*
* \return 0 on success, or a specific PEM or BASE64 error code. On
* MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL olen is the required
* size.
* \note You may pass \c NULL for \p buf and \c 0 for \p buf_len
* to request the length of the resulting PEM buffer in
* `*olen`.
*
* \note This function may be called with overlapping \p der_data
* and \p buf buffers.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL if \p buf isn't large
* enough to hold the PEM buffer. In this case, `*olen` holds
* the required minimum size of \p buf.
* \return Another PEM or BASE64 error code on other kinds of failure.
*/
int mbedtls_pem_write_buffer( const char *header, const char *footer,
const unsigned char *der_data, size_t der_len,

View File

@ -26,23 +26,23 @@
#define MBEDTLS_PK_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "md.h"
#include "mbedtls/md.h"
#if defined(MBEDTLS_RSA_C)
#include "rsa.h"
#include "mbedtls/rsa.h"
#endif
#if defined(MBEDTLS_ECP_C)
#include "ecp.h"
#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_ECDSA_C)
#include "ecdsa.h"
#include "mbedtls/ecdsa.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -217,7 +217,7 @@ void mbedtls_pk_init( mbedtls_pk_context *ctx );
*
* \note For contexts that have been set up with
* mbedtls_pk_setup_opaque(), this does not free the underlying
* key slot and you still need to call psa_destroy_key()
* PSA key and you still need to call psa_destroy_key()
* independently if you want to destroy that key.
*/
void mbedtls_pk_free( mbedtls_pk_context *ctx );
@ -259,21 +259,21 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief Initialize a PK context to wrap a PSA key slot.
* \brief Initialize a PK context to wrap a PSA key.
*
* \note This function replaces mbedtls_pk_setup() for contexts
* that wrap a (possibly opaque) PSA key slot instead of
* that wrap a (possibly opaque) PSA key instead of
* storing and manipulating the key material directly.
*
* \param ctx The context to initialize. It must be empty (type NONE).
* \param key The PSA key slot to wrap, which must hold an ECC key pair
* \param key The PSA key to wrap, which must hold an ECC key pair
* (see notes below).
*
* \note The wrapped key slot must remain valid as long as the
* \note The wrapped key must remain valid as long as the
* wrapping PK context is in use, that is at least between
* the point this function is called and the point
* mbedtls_pk_free() is called on this context. The wrapped
* key slot might then be independently used or destroyed.
* key might then be independently used or destroyed.
*
* \note This function is currently only available for ECC key
* pairs (that is, ECC keys containing private key material).
@ -281,7 +281,7 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
* (context already used, invalid key slot).
* (context already used, invalid key handle).
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an
* ECC key pair.
* \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
@ -788,7 +788,7 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief Turn an EC key into an Opaque one
* \brief Turn an EC key into an opaque one.
*
* \warning This is a temporary utility function for tests. It might
* change or be removed at any time without notice.
@ -796,18 +796,19 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
* \note Only ECDSA keys are supported so far. Signing with the
* specified hash is the only allowed use of that key.
*
* \param pk Input: the EC key to transfer to a PSA key slot.
* Output: a PK context wrapping that PSA key slot.
* \param slot Output: the chosen slot for storing the key.
* It's the caller's responsibility to destroy that slot
* after calling mbedtls_pk_free() on the PK context.
* \param pk Input: the EC key to import to a PSA key.
* Output: a PK context wrapping that PSA key.
* \param handle Output: a PSA key handle.
* It's the caller's responsibility to call
* psa_destroy_key() on that handle after calling
* mbedtls_pk_free() on the PK context.
* \param hash_alg The hash algorithm to allow for use with that key.
*
* \return \c 0 if successful.
* \return An Mbed TLS error code otherwise.
*/
int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
psa_key_handle_t *slot,
psa_key_handle_t *handle,
psa_algorithm_t hash_alg );
#endif /* MBEDTLS_USE_PSA_CRYPTO */

View File

@ -26,12 +26,12 @@
#define MBEDTLS_PK_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "pk.h"
#include "mbedtls/pk.h"
struct mbedtls_pk_info_t
{

View File

@ -25,14 +25,14 @@
#define MBEDTLS_PKCS12_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "md.h"
#include "cipher.h"
#include "asn1.h"
#include "mbedtls/md.h"
#include "mbedtls/cipher.h"
#include "mbedtls/asn1.h"
#include <stddef.h>

View File

@ -27,13 +27,13 @@
#define MBEDTLS_PKCS5_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "asn1.h"
#include "md.h"
#include "mbedtls/asn1.h"
#include "mbedtls/md.h"
#include <stddef.h>
#include <stdint.h>

View File

@ -34,13 +34,13 @@
#define MBEDTLS_PLATFORM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_HAVE_TIME)
#include "platform_time.h"
#include "mbedtls/platform_time.h"
#endif
#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */

View File

@ -25,7 +25,7 @@
#define MBEDTLS_PLATFORM_TIME_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -26,14 +26,14 @@
#define MBEDTLS_PLATFORM_UTIL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_HAVE_TIME_DATE)
#include "platform_time.h"
#include "mbedtls/platform_time.h"
#include <time.h>
#endif /* MBEDTLS_HAVE_TIME_DATE */
@ -43,6 +43,12 @@ extern "C" {
#if defined(MBEDTLS_CHECK_PARAMS)
#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert
* (which is what our config.h suggests). */
#include <assert.h>
#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
#if defined(MBEDTLS_PARAM_FAILED)
/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
*
@ -50,6 +56,11 @@ extern "C" {
* MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
*/
#define MBEDTLS_PARAM_FAILED_ALT
#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT)
#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
#define MBEDTLS_PARAM_FAILED_ALT
#else /* MBEDTLS_PARAM_FAILED */
#define MBEDTLS_PARAM_FAILED( cond ) \
mbedtls_param_failed( #cond, __FILE__, __LINE__ )

View File

@ -34,7 +34,7 @@
#define MBEDTLS_POLY1305_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -29,7 +29,7 @@
#define MBEDTLS_PSA_UTIL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -38,10 +38,10 @@
#include "psa/crypto.h"
#include "ecp.h"
#include "md.h"
#include "pk.h"
#include "oid.h"
#include "mbedtls/ecp.h"
#include "mbedtls/md.h"
#include "mbedtls/pk.h"
#include "mbedtls/oid.h"
#include <string.h>
@ -413,7 +413,7 @@ static inline int mbedtls_psa_err_translate_pk( psa_status_t status )
/* All other failures */
case PSA_ERROR_COMMUNICATION_FAILURE:
case PSA_ERROR_HARDWARE_FAILURE:
case PSA_ERROR_TAMPERING_DETECTED:
case PSA_ERROR_CORRUPTION_DETECTED:
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
default: /* We return the same as for the 'other failures',
* but list them separately nonetheless to indicate

View File

@ -25,7 +25,7 @@
#define MBEDTLS_RIPEMD160_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@ -57,7 +57,7 @@ typedef struct mbedtls_ripemd160_context
mbedtls_ripemd160_context;
#else /* MBEDTLS_RIPEMD160_ALT */
#include "ripemd160.h"
#include "ripemd160_alt.h"
#endif /* MBEDTLS_RIPEMD160_ALT */
/**

View File

@ -31,16 +31,16 @@
#define MBEDTLS_RSA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "bignum.h"
#include "md.h"
#include "mbedtls/bignum.h"
#include "mbedtls/md.h"
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#include "mbedtls/threading.h"
#endif
/*

View File

@ -58,12 +58,12 @@
#define MBEDTLS_RSA_INTERNAL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "bignum.h"
#include "mbedtls/bignum.h"
#ifdef __cplusplus
extern "C" {

View File

@ -32,7 +32,7 @@
#define MBEDTLS_SHA1_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -28,7 +28,7 @@
#define MBEDTLS_SHA256_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -27,7 +27,7 @@
#define MBEDTLS_SHA512_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -25,7 +25,7 @@
#define MBEDTLS_THREADING_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -25,7 +25,7 @@
#define MBEDTLS_TIMING_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

View File

@ -25,7 +25,7 @@
#define MBEDTLS_XTEA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

File diff suppressed because it is too large Load Diff

View File

@ -62,21 +62,19 @@ extern "C" {
MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_INSUFFICIENT_DATA )
#endif
/** \addtogroup policy
/** \addtogroup attributes
* @{
*/
/** \brief Set the enrollment algorithm in a key policy.
/** \brief Declare the enrollment algorithm for a key.
*
* An operation on a key may indifferently use the algorithm set with
* psa_key_policy_set_usage() or with this function.
* psa_set_key_algorithm() or with this function.
*
* \param[in,out] policy The key policy to modify. It must have been
* initialized as per the documentation for
* #psa_key_policy_t.
* \param alg2 A second algorithm that the key may be used for,
* in addition to the algorithm set with
* psa_key_policy_set_usage().
* \param[out] attributes The attribute structure to write to.
* \param alg2 A second algorithm that the key may be used
* for, in addition to the algorithm set with
* psa_set_key_algorithm().
*
* \warning Setting an enrollment algorithm is not recommended, because
* using the same key with different algorithms can allow some
@ -87,17 +85,135 @@ extern "C" {
* verified that the usage of the key with multiple algorithms
* is safe.
*/
void psa_key_policy_set_enrollment_algorithm(psa_key_policy_t *policy,
psa_algorithm_t alg2);
static inline void psa_set_key_enrollment_algorithm(
psa_key_attributes_t *attributes,
psa_algorithm_t alg2)
{
attributes->core.policy.alg2 = alg2;
}
/** \brief Retrieve the enrollment algorithm field of a policy structure.
/** Retrieve the enrollment algorithm policy from key attributes.
*
* \param[in] policy The policy object to query.
* \param[in] attributes The key attribute structure to query.
*
* \return The enrollment algorithm for a key with this policy.
* \return The enrollment algorithm stored in the attribute structure.
*/
psa_algorithm_t psa_key_policy_get_enrollment_algorithm(
const psa_key_policy_t *policy);
static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
const psa_key_attributes_t *attributes)
{
return( attributes->core.policy.alg2 );
}
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/** Retrieve the slot number where a key is stored.
*
* A slot number is only defined for keys that are stored in a secure
* element.
*
* This information is only useful if the secure element is not entirely
* managed through the PSA Cryptography API. It is up to the secure
* element driver to decide how PSA slot numbers map to any other interface
* that the secure element may have.
*
* \param[in] attributes The key attribute structure to query.
* \param[out] slot_number On success, the slot number containing the key.
*
* \retval #PSA_SUCCESS
* The key is located in a secure element, and \p *slot_number
* indicates the slot number that contains it.
* \retval #PSA_ERROR_NOT_PERMITTED
* The caller is not permitted to query the slot number.
* Mbed Crypto currently does not return this error.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The key is not located in a secure element.
*/
psa_status_t psa_get_key_slot_number(
const psa_key_attributes_t *attributes,
psa_key_slot_number_t *slot_number );
/** Choose the slot number where a key is stored.
*
* This function declares a slot number in the specified attribute
* structure.
*
* A slot number is only meaningful for keys that are stored in a secure
* element. It is up to the secure element driver to decide how PSA slot
* numbers map to any other interface that the secure element may have.
*
* \note Setting a slot number in key attributes for a key creation can
* cause the following errors when creating the key:
* - #PSA_ERROR_NOT_SUPPORTED if the selected secure element does
* not support choosing a specific slot number.
* - #PSA_ERROR_NOT_PERMITTED if the caller is not permitted to
* choose slot numbers in general or to choose this specific slot.
* - #PSA_ERROR_INVALID_ARGUMENT if the chosen slot number is not
* valid in general or not valid for this specific key.
* - #PSA_ERROR_ALREADY_EXISTS if there is already a key in the
* selected slot.
*
* \param[out] attributes The attribute structure to write to.
* \param slot_number The slot number to set.
*/
static inline void psa_set_key_slot_number(
psa_key_attributes_t *attributes,
psa_key_slot_number_t slot_number )
{
attributes->core.flags |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
attributes->slot_number = slot_number;
}
/** Remove the slot number attribute from a key attribute structure.
*
* This function undoes the action of psa_set_key_slot_number().
*
* \param[out] attributes The attribute structure to write to.
*/
static inline void psa_clear_key_slot_number(
psa_key_attributes_t *attributes )
{
attributes->core.flags &= ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
}
/** Register a key that is already present in a secure element.
*
* The key must be located in a secure element designated by the
* lifetime field in \p attributes, in the slot set with
* psa_set_key_slot_number() in the attribute structure.
* This function makes the key available through the key identifier
* specified in \p attributes.
*
* \param[in] attributes The attributes of the existing key.
*
* \retval #PSA_SUCCESS
* The key was successfully registered.
* Note that depending on the design of the driver, this may or may
* not guarantee that a key actually exists in the designated slot
* and is compatible with the specified attributes.
* \retval #PSA_ERROR_ALREADY_EXISTS
* There is already a key with the identifier specified in
* \p attributes.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p attributes specifies a lifetime which is not located
* in a secure element.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* No slot number is specified in \p attributes,
* or the specified slot number is not valid.
* \retval #PSA_ERROR_NOT_PERMITTED
* The caller is not authorized to register the specified key slot.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
* results in this error code.
*/
psa_status_t mbedtls_psa_register_se_key(
const psa_key_attributes_t *attributes);
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
/**@}*/
@ -111,6 +227,43 @@ psa_algorithm_t psa_key_policy_get_enrollment_algorithm(
*/
void mbedtls_psa_crypto_free( void );
/** \brief Statistics about
* resource consumption related to the PSA keystore.
*
* \note The content of this structure is not part of the stable API and ABI
* of Mbed Crypto and may change arbitrarily from version to version.
*/
typedef struct mbedtls_psa_stats_s
{
/** Number of slots containing key material for a volatile key. */
size_t volatile_slots;
/** Number of slots containing key material for a key which is in
* internal persistent storage. */
size_t persistent_slots;
/** Number of slots containing a reference to a key in a
* secure element. */
size_t external_slots;
/** Number of slots which are occupied, but do not contain
* key material yet. */
size_t half_filled_slots;
/** Number of slots that contain cache data. */
size_t cache_slots;
/** Number of slots that are not used for anything. */
size_t empty_slots;
/** Largest key id value among open keys in internal persistent storage. */
psa_app_key_id_t max_open_internal_key_id;
/** Largest key id value among open keys in secure elements. */
psa_app_key_id_t max_open_external_key_id;
} mbedtls_psa_stats_t;
/** \brief Get statistics about
* resource consumption related to the PSA keystore.
*
* \note When Mbed Crypto is built as part of a service, with isolation
* between the application and the keystore, the service may or
* may not expose this function.
*/
void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats );
/**
* \brief Inject an initial entropy seed for the random generator into
@ -179,9 +332,249 @@ void mbedtls_psa_crypto_free( void );
* The library has already been initialized. It is no longer
* possible to call this function.
*/
psa_status_t mbedtls_psa_inject_entropy(const unsigned char *seed,
psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
size_t seed_size);
/** \addtogroup crypto_types
* @{
*/
/** DSA public key.
*
* The import and export format is the
* representation of the public key `y = g^x mod p` as a big-endian byte
* string. The length of the byte string is the length of the base prime `p`
* in bytes.
*/
#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x60020000)
/** DSA key pair (private and public key).
*
* The import and export format is the
* representation of the private key `x` as a big-endian byte string. The
* length of the byte string is the private key size in bytes (leading zeroes
* are not stripped).
*
* Determinstic DSA key derivation with psa_generate_derived_key follows
* FIPS 186-4 &sect;B.1.2: interpret the byte string as integer
* in big-endian order. Discard it if it is not in the range
* [0, *N* - 2] where *N* is the boundary of the private key domain
* (the prime *p* for Diffie-Hellman, the subprime *q* for DSA,
* or the order of the curve's base point for ECC).
* Add 1 to the resulting integer and use this as the private key *x*.
*
*/
#define PSA_KEY_TYPE_DSA_KEY_PAIR ((psa_key_type_t)0x70020000)
/** Whether a key type is an DSA key (pair or public-only). */
#define PSA_KEY_TYPE_IS_DSA(type) \
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)
#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000)
/** DSA signature with hashing.
*
* This is the signature scheme defined by FIPS 186-4,
* with a random per-message secret number (*k*).
*
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
* This includes #PSA_ALG_ANY_HASH
* when specifying the algorithm in a usage policy.
*
* \return The corresponding DSA signature algorithm.
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_DSA(hash_alg) \
(PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000)
#define PSA_ALG_DSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000)
/** Deterministic DSA signature with hashing.
*
* This is the deterministic variant defined by RFC 6979 of
* the signature scheme defined by FIPS 186-4.
*
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
* This includes #PSA_ALG_ANY_HASH
* when specifying the algorithm in a usage policy.
*
* \return The corresponding DSA signature algorithm.
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \
(PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
#define PSA_ALG_IS_DSA(alg) \
(((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \
PSA_ALG_DSA_BASE)
#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \
(((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \
(PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \
(PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
/* We need to expand the sample definition of this macro from
* the API definition. */
#undef PSA_ALG_IS_HASH_AND_SIGN
#define PSA_ALG_IS_HASH_AND_SIGN(alg) \
(PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \
PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg))
/**@}*/
/** \addtogroup attributes
* @{
*/
/** Custom Diffie-Hellman group.
*
* For keys of type #PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_GROUP_CUSTOM) or
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_GROUP_CUSTOM), the group data comes
* from domain parameters set by psa_set_key_domain_parameters().
*/
/* This value is reserved for private use in the TLS named group registry. */
#define PSA_DH_GROUP_CUSTOM ((psa_dh_group_t) 0x01fc)
/**
* \brief Set domain parameters for a key.
*
* Some key types require additional domain parameters in addition to
* the key type identifier and the key size. Use this function instead
* of psa_set_key_type() when you need to specify domain parameters.
*
* The format for the required domain parameters varies based on the key type.
*
* - For RSA keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY or #PSA_KEY_TYPE_RSA_KEY_PAIR),
* the domain parameter data consists of the public exponent,
* represented as a big-endian integer with no leading zeros.
* This information is used when generating an RSA key pair.
* When importing a key, the public exponent is read from the imported
* key data and the exponent recorded in the attribute structure is ignored.
* As an exception, the public exponent 65537 is represented by an empty
* byte string.
* - For DSA keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY or #PSA_KEY_TYPE_DSA_KEY_PAIR),
* the `Dss-Parms` format as defined by RFC 3279 &sect;2.3.2.
* ```
* Dss-Parms ::= SEQUENCE {
* p INTEGER,
* q INTEGER,
* g INTEGER
* }
* ```
* - For Diffie-Hellman key exchange keys
* (#PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_GROUP_CUSTOM) or
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_GROUP_CUSTOM)), the
* `DomainParameters` format as defined by RFC 3279 &sect;2.3.3.
* ```
* DomainParameters ::= SEQUENCE {
* p INTEGER, -- odd prime, p=jq +1
* g INTEGER, -- generator, g
* q INTEGER, -- factor of p-1
* j INTEGER OPTIONAL, -- subgroup factor
* validationParms ValidationParms OPTIONAL
* }
* ValidationParms ::= SEQUENCE {
* seed BIT STRING,
* pgenCounter INTEGER
* }
* ```
*
* \note This function may allocate memory or other resources.
* Once you have called this function on an attribute structure,
* you must call psa_reset_key_attributes() to free these resources.
*
* \note This is an experimental extension to the interface. It may change
* in future versions of the library.
*
* \param[in,out] attributes Attribute structure where the specified domain
* parameters will be stored.
* If this function fails, the content of
* \p attributes is not modified.
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
* \param[in] data Buffer containing the key domain parameters.
* The content of this buffer is interpreted
* according to \p type as described above.
* \param data_length Size of the \p data buffer in bytes.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
*/
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
psa_key_type_t type,
const uint8_t *data,
size_t data_length);
/**
* \brief Get domain parameters for a key.
*
* Get the domain parameters for a key with this function, if any. The format
* of the domain parameters written to \p data is specified in the
* documentation for psa_set_key_domain_parameters().
*
* \note This is an experimental extension to the interface. It may change
* in future versions of the library.
*
* \param[in] attributes The key attribute structure to query.
* \param[out] data On success, the key domain parameters.
* \param data_size Size of the \p data buffer in bytes.
* The buffer is guaranteed to be large
* enough if its size in bytes is at least
* the value given by
* PSA_KEY_DOMAIN_PARAMETERS_SIZE().
* \param[out] data_length On success, the number of bytes
* that make up the key domain parameters data.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
*/
psa_status_t psa_get_key_domain_parameters(
const psa_key_attributes_t *attributes,
uint8_t *data,
size_t data_size,
size_t *data_length);
/** Safe output buffer size for psa_get_key_domain_parameters().
*
* This macro returns a compile-time constant if its arguments are
* compile-time constants.
*
* \warning This function may call its arguments multiple times or
* zero times, so you should not pass arguments that contain
* side effects.
*
* \note This is an experimental extension to the interface. It may change
* in future versions of the library.
*
* \param key_type A supported key type.
* \param key_bits The size of the key in bits.
*
* \return If the parameters are valid and supported, return
* a buffer size in bytes that guarantees that
* psa_get_key_domain_parameters() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
#define PSA_KEY_DOMAIN_PARAMETERS_SIZE(key_type, key_bits) \
(PSA_KEY_TYPE_IS_RSA(key_type) ? sizeof(int) : \
PSA_KEY_TYPE_IS_DH(key_type) ? PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
PSA_KEY_TYPE_IS_DSA(key_type) ? PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
0)
#define PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 3 /*without optional parts*/)
#define PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 2 /*p, g*/ + 34 /*q*/)
/**@}*/
#ifdef __cplusplus
}

View File

@ -89,6 +89,7 @@ typedef struct
* `psa_key_file_id_t` argument. As a workaround, make `psa_key_id_t` an
* alias for `psa_key_file_id_t` when building for a multi-client service. */
typedef psa_key_file_id_t psa_key_id_t;
#define PSA_KEY_ID_INIT {0, 0}
#else /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */

View File

@ -8,11 +8,11 @@
* space in which the PSA Crypto implementation runs, typically secure
* elements (SEs).
*
* This file is part of the PSA Crypto Driver Model, containing functions for
* driver developers to implement to enable hardware to be called in a
* standardized way by a PSA Cryptographic API implementation. The functions
* comprising the driver model, which driver authors implement, are not
* intended to be called by application developers.
* This file is part of the PSA Crypto Driver HAL (hardware abstraction layer),
* containing functions for driver developers to implement to enable hardware
* to be called in a standardized way by a PSA Cryptography API
* implementation. The functions comprising the driver HAL, which driver
* authors implement, are not intended to be called by application developers.
*/
/*
@ -40,10 +40,113 @@
extern "C" {
#endif
/** \defgroup se_init Secure element driver initialization
*/
/**@{*/
/** \brief Driver context structure
*
* Driver functions receive a pointer to this structure.
* Each registered driver has one instance of this structure.
*
* Implementations must include the fields specified here and
* may include other fields.
*/
typedef struct {
/** A read-only pointer to the driver's persistent data.
*
* Drivers typically use this persistent data to keep track of
* which slot numbers are available. This is only a guideline:
* drivers may use the persistent data for any purpose, keeping
* in mind the restrictions on when the persistent data is saved
* to storage: the persistent data is only saved after calling
* certain functions that receive a writable pointer to the
* persistent data.
*
* The core allocates a memory buffer for the persistent data.
* The pointer is guaranteed to be suitably aligned for any data type,
* like a pointer returned by `malloc` (but the core can use any
* method to allocate the buffer, not necessarily `malloc`).
*
* The size of this buffer is in the \c persistent_data_size field of
* this structure.
*
* Before the driver is initialized for the first time, the content of
* the persistent data is all-bits-zero. After a driver upgrade, if the
* size of the persistent data has increased, the original data is padded
* on the right with zeros; if the size has decreased, the original data
* is truncated to the new size.
*
* This pointer is to read-only data. Only a few driver functions are
* allowed to modify the persistent data. These functions receive a
* writable pointer. These functions are:
* - psa_drv_se_t::p_init
* - psa_drv_se_key_management_t::p_allocate
* - psa_drv_se_key_management_t::p_destroy
*
* The PSA Cryptography core saves the persistent data from one
* session to the next. It does this before returning from API functions
* that call a driver method that is allowed to modify the persistent
* data, specifically:
* - psa_crypto_init() causes a call to psa_drv_se_t::p_init, and may call
* psa_drv_se_key_management_t::p_destroy to complete an action
* that was interrupted by a power failure.
* - Key creation functions cause a call to
* psa_drv_se_key_management_t::p_allocate, and may cause a call to
* psa_drv_se_key_management_t::p_destroy in case an error occurs.
* - psa_destroy_key() causes a call to
* psa_drv_se_key_management_t::p_destroy.
*/
const void *const persistent_data;
/** The size of \c persistent_data in bytes.
*
* This is always equal to the value of the `persistent_data_size` field
* of the ::psa_drv_se_t structure when the driver is registered.
*/
const size_t persistent_data_size;
/** Driver transient data.
*
* The core initializes this value to 0 and does not read or modify it
* afterwards. The driver may store whatever it wants in this field.
*/
uintptr_t transient_data;
} psa_drv_se_context_t;
/** \brief A driver initialization function.
*
* \param[in,out] drv_context The driver context structure.
* \param[in,out] persistent_data A pointer to the persistent data
* that allows writing.
* \param lifetime The lifetime value for which this driver
* is registered.
*
* \retval #PSA_SUCCESS
* The driver is operational.
* The core will update the persistent data in storage.
* \return
* Any other return value prevents the driver from being used in
* this session.
* The core will NOT update the persistent data in storage.
*/
typedef psa_status_t (*psa_drv_se_init_t)(psa_drv_se_context_t *drv_context,
void *persistent_data,
psa_key_lifetime_t lifetime);
#if defined(__DOXYGEN_ONLY__) || !defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* Mbed Crypto with secure element support enabled defines this type in
* crypto_types.h because it is also visible to applications through an
* implementation-specific extension.
* For the PSA Cryptography specification, this type is only visible
* via crypto_se_driver.h. */
/** An internal designation of a key slot between the core part of the
* PSA Crypto implementation and the driver. The meaning of this value
* is driver-dependent. */
typedef uint32_t psa_key_slot_number_t; // Change this to psa_key_slot_t after psa_key_slot_t is removed from Mbed crypto
typedef uint64_t psa_key_slot_number_t;
#endif /* __DOXYGEN_ONLY__ || !MBEDTLS_PSA_CRYPTO_SE_C */
/**@}*/
/** \defgroup se_mac Secure Element Message Authentication Codes
* Generation and authentication of Message Authentication Codes (MACs) using
@ -65,7 +168,8 @@ typedef uint32_t psa_key_slot_number_t; // Change this to psa_key_slot_t after p
/** \brief A function that starts a secure element MAC operation for a PSA
* Crypto Driver implementation
*
* \param[in,out] p_context A structure that will contain the
* \param[in,out] drv_context The driver context structure.
* \param[in,out] op_context A structure that will contain the
* hardware-specific MAC context
* \param[in] key_slot The slot of the key to be used for the
* operation
@ -75,28 +179,29 @@ typedef uint32_t psa_key_slot_number_t; // Change this to psa_key_slot_t after p
* \retval PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_se_mac_setup_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_mac_setup_t)(psa_drv_se_context_t *drv_context,
void *op_context,
psa_key_slot_number_t key_slot,
psa_algorithm_t algorithm);
/** \brief A function that continues a previously started secure element MAC
* operation
*
* \param[in,out] p_context A hardware-specific structure for the
* \param[in,out] op_context A hardware-specific structure for the
* previously-established MAC operation to be
* updated
* \param[in] p_input A buffer containing the message to be appended
* to the MAC operation
* \param[in] input_length The size in bytes of the input message buffer
* \param[in] input_length The size in bytes of the input message buffer
*/
typedef psa_status_t (*psa_drv_se_mac_update_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_mac_update_t)(void *op_context,
const uint8_t *p_input,
size_t input_length);
/** \brief a function that completes a previously started secure element MAC
* operation by returning the resulting MAC.
*
* \param[in,out] p_context A hardware-specific structure for the
* \param[in,out] op_context A hardware-specific structure for the
* previously started MAC operation to be
* finished
* \param[out] p_mac A buffer where the generated MAC will be
@ -109,7 +214,7 @@ typedef psa_status_t (*psa_drv_se_mac_update_t)(void *p_context,
* \retval PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *op_context,
uint8_t *p_mac,
size_t mac_size,
size_t *p_mac_length);
@ -117,11 +222,11 @@ typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *p_context,
/** \brief A function that completes a previously started secure element MAC
* operation by comparing the resulting MAC against a provided value
*
* \param[in,out] p_context A hardware-specific structure for the previously
* started MAC operation to be fiinished
* \param[in] p_mac The MAC value against which the resulting MAC will
* be compared against
* \param[in] mac_length The size in bytes of the value stored in `p_mac`
* \param[in,out] op_context A hardware-specific structure for the previously
* started MAC operation to be fiinished
* \param[in] p_mac The MAC value against which the resulting MAC
* will be compared against
* \param[in] mac_length The size in bytes of the value stored in `p_mac`
*
* \retval PSA_SUCCESS
* The operation completed successfully and the MACs matched each
@ -130,21 +235,22 @@ typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *p_context,
* The operation completed successfully, but the calculated MAC did
* not match the provided MAC
*/
typedef psa_status_t (*psa_drv_se_mac_finish_verify_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_mac_finish_verify_t)(void *op_context,
const uint8_t *p_mac,
size_t mac_length);
/** \brief A function that aborts a previous started secure element MAC
* operation
*
* \param[in,out] p_context A hardware-specific structure for the previously
* started MAC operation to be aborted
* \param[in,out] op_context A hardware-specific structure for the previously
* started MAC operation to be aborted
*/
typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *p_context);
typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *op_context);
/** \brief A function that performs a secure element MAC operation in one
* command and returns the calculated MAC
*
* \param[in,out] drv_context The driver context structure.
* \param[in] p_input A buffer containing the message to be MACed
* \param[in] input_length The size in bytes of `p_input`
* \param[in] key_slot The slot of the key to be used
@ -159,7 +265,8 @@ typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *p_context);
* \retval PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_se_mac_generate_t)(const uint8_t *p_input,
typedef psa_status_t (*psa_drv_se_mac_generate_t)(psa_drv_se_context_t *drv_context,
const uint8_t *p_input,
size_t input_length,
psa_key_slot_number_t key_slot,
psa_algorithm_t alg,
@ -170,6 +277,7 @@ typedef psa_status_t (*psa_drv_se_mac_generate_t)(const uint8_t *p_input,
/** \brief A function that performs a secure element MAC operation in one
* command and compares the resulting MAC against a provided value
*
* \param[in,out] drv_context The driver context structure.
* \param[in] p_input A buffer containing the message to be MACed
* \param[in] input_length The size in bytes of `input`
* \param[in] key_slot The slot of the key to be used
@ -186,7 +294,8 @@ typedef psa_status_t (*psa_drv_se_mac_generate_t)(const uint8_t *p_input,
* The operation completed successfully, but the calculated MAC did
* not match the provided MAC
*/
typedef psa_status_t (*psa_drv_se_mac_verify_t)(const uint8_t *p_input,
typedef psa_status_t (*psa_drv_se_mac_verify_t)(psa_drv_se_context_t *drv_context,
const uint8_t *p_input,
size_t input_length,
psa_key_slot_number_t key_slot,
psa_algorithm_t alg,
@ -263,7 +372,8 @@ typedef struct {
/** \brief A function that provides the cipher setup function for a
* secure element driver
*
* \param[in,out] p_context A structure that will contain the
* \param[in,out] drv_context The driver context structure.
* \param[in,out] op_context A structure that will contain the
* hardware-specific cipher context.
* \param[in] key_slot The slot of the key to be used for the
* operation
@ -275,7 +385,8 @@ typedef struct {
* \retval PSA_SUCCESS
* \retval PSA_ERROR_NOT_SUPPORTED
*/
typedef psa_status_t (*psa_drv_se_cipher_setup_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_context,
void *op_context,
psa_key_slot_number_t key_slot,
psa_algorithm_t algorithm,
psa_encrypt_or_decrypt_t direction);
@ -288,21 +399,21 @@ typedef psa_status_t (*psa_drv_se_cipher_setup_t)(void *p_context,
* generate function is not necessary for the drivers to implement as the PSA
* Crypto implementation can do the generation using its RNG features.
*
* \param[in,out] p_context A structure that contains the previously set up
* \param[in,out] op_context A structure that contains the previously set up
* hardware-specific cipher context
* \param[in] p_iv A buffer containing the initialization vector
* \param[in] iv_length The size (in bytes) of the `p_iv` buffer
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context,
const uint8_t *p_iv,
size_t iv_length);
/** \brief A function that continues a previously started secure element cipher
* operation
*
* \param[in,out] p_context A hardware-specific structure for the
* \param[in,out] op_context A hardware-specific structure for the
* previously started cipher operation
* \param[in] p_input A buffer containing the data to be
* encrypted/decrypted
@ -317,7 +428,7 @@ typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *p_context,
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context,
const uint8_t *p_input,
size_t input_size,
uint8_t *p_output,
@ -327,7 +438,7 @@ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *p_context,
/** \brief A function that completes a previously started secure element cipher
* operation
*
* \param[in,out] p_context A hardware-specific structure for the
* \param[in,out] op_context A hardware-specific structure for the
* previously started cipher operation
* \param[out] p_output The caller-allocated buffer where the output
* will be placed
@ -338,7 +449,7 @@ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *p_context,
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *op_context,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
@ -346,10 +457,10 @@ typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *p_context,
/** \brief A function that aborts a previously started secure element cipher
* operation
*
* \param[in,out] p_context A hardware-specific structure for the
* \param[in,out] op_context A hardware-specific structure for the
* previously started cipher operation
*/
typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *p_context);
typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *op_context);
/** \brief A function that performs the ECB block mode for secure element
* cipher operations
@ -357,23 +468,25 @@ typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *p_context);
* Note: this function should only be used with implementations that do not
* provide a needed higher-level operation.
*
* \param[in] key_slot The slot of the key to be used for the operation
* \param[in] algorithm The algorithm to be used in the cipher operation
* \param[in] direction Indicates whether the operation is an encrypt or
* decrypt
* \param[in] p_input A buffer containing the data to be
* encrypted/decrypted
* \param[in] input_size The size in bytes of the buffer pointed to by
* `p_input`
* \param[out] p_output The caller-allocated buffer where the output will
* be placed
* \param[in] output_size The allocated size in bytes of the `p_output`
* buffer
* \param[in,out] drv_context The driver context structure.
* \param[in] key_slot The slot of the key to be used for the operation
* \param[in] algorithm The algorithm to be used in the cipher operation
* \param[in] direction Indicates whether the operation is an encrypt or
* decrypt
* \param[in] p_input A buffer containing the data to be
* encrypted/decrypted
* \param[in] input_size The size in bytes of the buffer pointed to by
* `p_input`
* \param[out] p_output The caller-allocated buffer where the output
* will be placed
* \param[in] output_size The allocated size in bytes of the `p_output`
* buffer
*
* \retval PSA_SUCCESS
* \retval PSA_ERROR_NOT_SUPPORTED
*/
typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_key_slot_number_t key_slot,
typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
psa_algorithm_t algorithm,
psa_encrypt_or_decrypt_t direction,
const uint8_t *p_input,
@ -427,6 +540,7 @@ typedef struct {
* \brief A function that signs a hash or short message with a private key in
* a secure element
*
* \param[in,out] drv_context The driver context structure.
* \param[in] key_slot Key slot of an asymmetric key pair
* \param[in] alg A signature algorithm that is compatible
* with the type of `key`
@ -439,7 +553,8 @@ typedef struct {
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_key_slot_number_t key_slot,
typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
psa_algorithm_t alg,
const uint8_t *p_hash,
size_t hash_length,
@ -451,6 +566,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_key_slot_number_t key_s
* \brief A function that verifies the signature a hash or short message using
* an asymmetric public key in a secure element
*
* \param[in,out] drv_context The driver context structure.
* \param[in] key_slot Key slot of a public key or an asymmetric key
* pair
* \param[in] alg A signature algorithm that is compatible with
@ -463,7 +579,8 @@ typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_key_slot_number_t key_s
* \retval PSA_SUCCESS
* The signature is valid.
*/
typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_key_slot_number_t key_slot,
typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
psa_algorithm_t alg,
const uint8_t *p_hash,
size_t hash_length,
@ -474,6 +591,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_key_slot_number_t key
* \brief A function that encrypts a short message with an asymmetric public
* key in a secure element
*
* \param[in,out] drv_context The driver context structure.
* \param[in] key_slot Key slot of a public key or an asymmetric key
* pair
* \param[in] alg An asymmetric encryption algorithm that is
@ -499,7 +617,8 @@ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_key_slot_number_t key
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_key_slot_number_t key_slot,
typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
psa_algorithm_t alg,
const uint8_t *p_input,
size_t input_length,
@ -513,6 +632,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_key_slot_number_t ke
* \brief A function that decrypts a short message with an asymmetric private
* key in a secure element.
*
* \param[in,out] drv_context The driver context structure.
* \param[in] key_slot Key slot of an asymmetric key pair
* \param[in] alg An asymmetric encryption algorithm that is
* compatible with the type of `key`
@ -537,7 +657,8 @@ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_key_slot_number_t ke
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_key_slot_number_t key_slot,
typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
psa_algorithm_t alg,
const uint8_t *p_input,
size_t input_length,
@ -581,6 +702,7 @@ typedef struct {
/** \brief A function that performs a secure element authenticated encryption
* operation
*
* \param[in,out] drv_context The driver context structure.
* \param[in] key_slot Slot containing the key to use.
* \param[in] algorithm The AEAD algorithm to compute
* (\c PSA_ALG_XXX value such that
@ -608,7 +730,8 @@ typedef struct {
* \retval #PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_key_slot_number_t key_slot,
typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
psa_algorithm_t algorithm,
const uint8_t *p_nonce,
size_t nonce_length,
@ -622,6 +745,7 @@ typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_key_slot_number_t key_slot
/** A function that peforms a secure element authenticated decryption operation
*
* \param[in,out] drv_context The driver context structure.
* \param[in] key_slot Slot containing the key to use
* \param[in] algorithm The AEAD algorithm to compute
* (\c PSA_ALG_XXX value such that
@ -648,7 +772,8 @@ typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_key_slot_number_t key_slot
* \retval #PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_se_aead_decrypt_t)(psa_key_slot_number_t key_slot,
typedef psa_status_t (*psa_drv_se_aead_decrypt_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
psa_algorithm_t algorithm,
const uint8_t *p_nonce,
size_t nonce_length,
@ -685,31 +810,182 @@ typedef struct {
*/
/**@{*/
/** An enumeration indicating how a key is created.
*/
typedef enum
{
PSA_KEY_CREATION_IMPORT, /**< During psa_import_key() */
PSA_KEY_CREATION_GENERATE, /**< During psa_generate_key() */
PSA_KEY_CREATION_DERIVE, /**< During psa_key_derivation_output_key() */
PSA_KEY_CREATION_COPY, /**< During psa_copy_key() */
#ifndef __DOXYGEN_ONLY__
/** A key is being registered with mbedtls_psa_register_se_key().
*
* The core only passes this value to
* psa_drv_se_key_management_t::p_validate_slot_number, not to
* psa_drv_se_key_management_t::p_allocate. The call to
* `p_validate_slot_number` is not followed by any other call to the
* driver: the key is considered successfully registered if the call to
* `p_validate_slot_number` succeeds, or if `p_validate_slot_number` is
* null.
*
* With this creation method, the driver must return #PSA_SUCCESS if
* the given attributes are compatible with the existing key in the slot,
* and #PSA_ERROR_DOES_NOT_EXIST if the driver can determine that there
* is no key with the specified slot number.
*
* This is an Mbed Crypto extension.
*/
PSA_KEY_CREATION_REGISTER,
#endif
} psa_key_creation_method_t;
/** \brief A function that allocates a slot for a key.
*
* To create a key in a specific slot in a secure element, the core
* first calls this function to determine a valid slot number,
* then calls a function to create the key material in that slot.
* In nominal conditions (that is, if no error occurs),
* the effect of a call to a key creation function in the PSA Cryptography
* API with a lifetime that places the key in a secure element is the
* following:
* -# The core calls psa_drv_se_key_management_t::p_allocate
* (or in some implementations
* psa_drv_se_key_management_t::p_validate_slot_number). The driver
* selects (or validates) a suitable slot number given the key attributes
* and the state of the secure element.
* -# The core calls a key creation function in the driver.
*
* The key creation functions in the PSA Cryptography API are:
* - psa_import_key(), which causes
* a call to `p_allocate` with \p method = #PSA_KEY_CREATION_IMPORT
* then a call to psa_drv_se_key_management_t::p_import.
* - psa_generate_key(), which causes
* a call to `p_allocate` with \p method = #PSA_KEY_CREATION_GENERATE
* then a call to psa_drv_se_key_management_t::p_import.
* - psa_key_derivation_output_key(), which causes
* a call to `p_allocate` with \p method = #PSA_KEY_CREATION_DERIVE
* then a call to psa_drv_se_key_derivation_t::p_derive.
* - psa_copy_key(), which causes
* a call to `p_allocate` with \p method = #PSA_KEY_CREATION_COPY
* then a call to psa_drv_se_key_management_t::p_export.
*
* In case of errors, other behaviors are possible.
* - If the PSA Cryptography subsystem dies after the first step,
* for example because the device has lost power abruptly,
* the second step may never happen, or may happen after a reset
* and re-initialization. Alternatively, after a reset and
* re-initialization, the core may call
* psa_drv_se_key_management_t::p_destroy on the slot number that
* was allocated (or validated) instead of calling a key creation function.
* - If an error occurs, the core may call
* psa_drv_se_key_management_t::p_destroy on the slot number that
* was allocated (or validated) instead of calling a key creation function.
*
* Errors and system resets also have an impact on the driver's persistent
* data. If a reset happens before the overall key creation process is
* completed (before or after the second step above), it is unspecified
* whether the persistent data after the reset is identical to what it
* was before or after the call to `p_allocate` (or `p_validate_slot_number`).
*
* \param[in,out] drv_context The driver context structure.
* \param[in,out] persistent_data A pointer to the persistent data
* that allows writing.
* \param[in] attributes Attributes of the key.
* \param method The way in which the key is being created.
* \param[out] key_slot Slot where the key will be stored.
* This must be a valid slot for a key of the
* chosen type. It must be unoccupied.
*
* \retval #PSA_SUCCESS
* Success.
* The core will record \c *key_slot as the key slot where the key
* is stored and will update the persistent data in storage.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
*/
typedef psa_status_t (*psa_drv_se_allocate_key_t)(
psa_drv_se_context_t *drv_context,
void *persistent_data,
const psa_key_attributes_t *attributes,
psa_key_creation_method_t method,
psa_key_slot_number_t *key_slot);
/** \brief A function that determines whether a slot number is valid
* for a key.
*
* To create a key in a specific slot in a secure element, the core
* first calls this function to validate the choice of slot number,
* then calls a function to create the key material in that slot.
* See the documentation of #psa_drv_se_allocate_key_t for more details.
*
* As of the PSA Cryptography API specification version 1.0, there is no way
* for applications to trigger a call to this function. However some
* implementations offer the capability to create or declare a key in
* a specific slot via implementation-specific means, generally for the
* sake of initial device provisioning or onboarding. Such a mechanism may
* be added to a future version of the PSA Cryptography API specification.
*
* \param[in,out] drv_context The driver context structure.
* \param[in] attributes Attributes of the key.
* \param method The way in which the key is being created.
* \param[in] key_slot Slot where the key is to be stored.
*
* \retval #PSA_SUCCESS
* The given slot number is valid for a key with the given
* attributes.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The given slot number is not valid for a key with the
* given attributes. This includes the case where the slot
* number is not valid at all.
* \retval #PSA_ERROR_ALREADY_EXISTS
* There is already a key with the specified slot number.
* Drivers may choose to return this error from the key
* creation function instead.
*/
typedef psa_status_t (*psa_drv_se_validate_slot_number_t)(
psa_drv_se_context_t *drv_context,
const psa_key_attributes_t *attributes,
psa_key_creation_method_t method,
psa_key_slot_number_t key_slot);
/** \brief A function that imports a key into a secure element in binary format
*
* This function can support any output from psa_export_key(). Refer to the
* documentation of psa_export_key() for the format for each key type.
*
* \param[in] key_slot Slot where the key will be stored
* This must be a valid slot for a key of the chosen
* type. It must be unoccupied.
* \param[in] lifetime The required lifetime of the key storage
* \param[in] type Key type (a \c PSA_KEY_TYPE_XXX value)
* \param[in] algorithm Key algorithm (a \c PSA_ALG_XXX value)
* \param[in] usage The allowed uses of the key
* \param[in] p_data Buffer containing the key data
* \param[in] data_length Size of the `data` buffer in bytes
* \param[in,out] drv_context The driver context structure.
* \param key_slot Slot where the key will be stored.
* This must be a valid slot for a key of the
* chosen type. It must be unoccupied.
* \param[in] attributes The key attributes, including the lifetime,
* the key type and the usage policy.
* Drivers should not access the key size stored
* in the attributes: it may not match the
* data passed in \p data.
* Drivers can call psa_get_key_lifetime(),
* psa_get_key_type(),
* psa_get_key_usage_flags() and
* psa_get_key_algorithm() to access this
* information.
* \param[in] data Buffer containing the key data.
* \param[in] data_length Size of the \p data buffer in bytes.
* \param[out] bits On success, the key size in bits. The driver
* must determine this value after parsing the
* key according to the key type.
* This value is not used if the function fails.
*
* \retval #PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_se_import_key_t)(psa_key_slot_number_t key_slot,
psa_key_lifetime_t lifetime,
psa_key_type_t type,
psa_algorithm_t algorithm,
psa_key_usage_t usage,
const uint8_t *p_data,
size_t data_length);
typedef psa_status_t (*psa_drv_se_import_key_t)(
psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
size_t *bits);
/**
* \brief A function that destroys a secure element key and restore the slot to
@ -721,12 +997,18 @@ typedef psa_status_t (*psa_drv_se_import_key_t)(psa_key_slot_number_t key_slot,
*
* This function returns the specified slot to its default state.
*
* \param[in] key_slot The key slot to erase.
* \param[in,out] drv_context The driver context structure.
* \param[in,out] persistent_data A pointer to the persistent data
* that allows writing.
* \param key_slot The key slot to erase.
*
* \retval #PSA_SUCCESS
* The slot's content, if any, has been erased.
*/
typedef psa_status_t (*psa_drv_se_destroy_key_t)(psa_key_slot_number_t key);
typedef psa_status_t (*psa_drv_se_destroy_key_t)(
psa_drv_se_context_t *drv_context,
void *persistent_data,
psa_key_slot_number_t key_slot);
/**
* \brief A function that exports a secure element key in binary format
@ -743,6 +1025,7 @@ typedef psa_status_t (*psa_drv_se_destroy_key_t)(psa_key_slot_number_t key);
* `psa_export_key()` does. Refer to the
* documentation of `psa_export_key()` for the format for each key type.
*
* \param[in,out] drv_context The driver context structure.
* \param[in] key Slot whose content is to be exported. This must
* be an occupied key slot.
* \param[out] p_data Buffer where the key data is to be written.
@ -756,9 +1039,10 @@ typedef psa_status_t (*psa_drv_se_destroy_key_t)(psa_key_slot_number_t key);
* \retval #PSA_ERROR_NOT_SUPPORTED
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_TAMPERING_DETECTED
* \retval #PSA_ERROR_CORRUPTION_DETECTED
*/
typedef psa_status_t (*psa_drv_se_export_key_t)(psa_key_slot_number_t key,
typedef psa_status_t (*psa_drv_se_export_key_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key,
uint8_t *p_data,
size_t data_size,
size_t *p_data_length);
@ -767,39 +1051,52 @@ typedef psa_status_t (*psa_drv_se_export_key_t)(psa_key_slot_number_t key,
* \brief A function that generates a symmetric or asymmetric key on a secure
* element
*
* If \p type is asymmetric (`#PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) == 1`),
* the public component of the generated key will be placed in `p_pubkey_out`.
* The format of the public key information will match the format specified for
* the psa_export_key() function for the key type.
* If \p type is asymmetric (#PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) = 1),
* the driver may export the public key at the time of generation,
* in the format documented for psa_export_public_key() by writing it
* to the \p pubkey buffer.
* This is optional, intended for secure elements that output the
* public key at generation time and that cannot export the public key
* later. Drivers that do not need this feature should leave
* \p *pubkey_length set to 0 and should
* implement the psa_drv_key_management_t::p_export_public function.
* Some implementations do not support this feature, in which case
* \p pubkey is \c NULL and \p pubkey_size is 0.
*
* \param[in] key_slot Slot where the generated key will be placed
* \param[in] type The type of the key to be generated
* \param[in] usage The prescribed usage of the generated key
* Note: Not all Secure Elements support the same
* restrictions that PSA Crypto does (and vice versa).
* Driver developers should endeavor to match the
* usages as close as possible.
* \param[in] bits The size in bits of the key to be generated.
* \param[in] extra Extra parameters for key generation. The
* interpretation of this parameter should match the
* interpretation in the `extra` parameter is the
* `psa_generate_key` function
* \param[in] extra_size The size in bytes of the \p extra buffer
* \param[out] p_pubkey_out The buffer where the public key information will
* be placed
* \param[in] pubkey_out_size The size in bytes of the `p_pubkey_out` buffer
* \param[out] p_pubkey_length Upon successful completion, will contain the
* size of the data placed in `p_pubkey_out`.
* \param[in,out] drv_context The driver context structure.
* \param key_slot Slot where the key will be stored.
* This must be a valid slot for a key of the
* chosen type. It must be unoccupied.
* \param[in] attributes The key attributes, including the lifetime,
* the key type and size, and the usage policy.
* Drivers can call psa_get_key_lifetime(),
* psa_get_key_type(), psa_get_key_bits(),
* psa_get_key_usage_flags() and
* psa_get_key_algorithm() to access this
* information.
* \param[out] pubkey A buffer where the driver can write the
* public key, when generating an asymmetric
* key pair.
* This is \c NULL when generating a symmetric
* key or if the core does not support
* exporting the public key at generation time.
* \param pubkey_size The size of the `pubkey` buffer in bytes.
* This is 0 when generating a symmetric
* key or if the core does not support
* exporting the public key at generation time.
* \param[out] pubkey_length On entry, this is always 0.
* On success, the number of bytes written to
* \p pubkey. If this is 0 or unchanged on return,
* the core will not read the \p pubkey buffer,
* and will instead call the driver's
* psa_drv_key_management_t::p_export_public
* function to export the public key when needed.
*/
typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_key_slot_number_t key_slot,
psa_key_type_t type,
psa_key_usage_t usage,
size_t bits,
const void *extra,
size_t extra_size,
uint8_t *p_pubkey_out,
size_t pubkey_out_size,
size_t *p_pubkey_length);
typedef psa_status_t (*psa_drv_se_generate_key_t)(
psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
const psa_key_attributes_t *attributes,
uint8_t *pubkey, size_t pubkey_size, size_t *pubkey_length);
/**
* \brief A struct containing all of the function pointers needed to for secure
@ -811,6 +1108,10 @@ typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_key_slot_number_t key_slot
* If one of the functions is not implemented, it should be set to NULL.
*/
typedef struct {
/** Function that allocates a slot for a key. */
psa_drv_se_allocate_key_t p_allocate;
/** Function that checks the validity of a slot for a key. */
psa_drv_se_validate_slot_number_t p_validate_slot_number;
/** Function that performs a key import operation */
psa_drv_se_import_key_t p_import;
/** Function that performs a generation */
@ -819,6 +1120,8 @@ typedef struct {
psa_drv_se_destroy_key_t p_destroy;
/** Function that performs a key export operation */
psa_drv_se_export_key_t p_export;
/** Function that performs a public key export operation */
psa_drv_se_export_key_t p_export_public;
} psa_drv_se_key_management_t;
/**@}*/
@ -875,15 +1178,17 @@ typedef struct {
/** \brief A function that Sets up a secure element key derivation operation by
* specifying the algorithm and the source key sot
*
* \param[in,out] p_context A hardware-specific structure containing any
* context information for the implementation
* \param[in] kdf_alg The algorithm to be used for the key derivation
* \param[in] souce_key The key to be used as the source material for the
* key derivation
* \param[in,out] drv_context The driver context structure.
* \param[in,out] op_context A hardware-specific structure containing any
* context information for the implementation
* \param[in] kdf_alg The algorithm to be used for the key derivation
* \param[in] source_key The key to be used as the source material for
* the key derivation
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t *drv_context,
void *op_context,
psa_algorithm_t kdf_alg,
psa_key_slot_number_t source_key);
@ -894,7 +1199,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(void *p_context,
* expeced that this function may be called multiple times for the same
* operation, each with a different algorithm-specific `collateral_id`
*
* \param[in,out] p_context A hardware-specific structure containing any
* \param[in,out] op_context A hardware-specific structure containing any
* context information for the implementation
* \param[in] collateral_id An ID for the collateral being provided
* \param[in] p_collateral A buffer containing the collateral data
@ -902,7 +1207,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(void *p_context,
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context,
uint32_t collateral_id,
const uint8_t *p_collateral,
size_t collateral_size);
@ -910,14 +1215,14 @@ typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *p_context,
/** \brief A function that performs the final secure element key derivation
* step and place the generated key material in a slot
*
* \param[in,out] p_context A hardware-specific structure containing any
* \param[in,out] op_context A hardware-specific structure containing any
* context information for the implementation
* \param[in] dest_key The slot where the generated key material
* should be placed
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context,
psa_key_slot_number_t dest_key);
/** \brief A function that performs the final step of a secure element key
@ -931,7 +1236,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *p_context,
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *p_context,
typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *op_context,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
@ -961,6 +1266,113 @@ typedef struct {
/**@}*/
/** \defgroup se_registration Secure element driver registration
*/
/**@{*/
/** A structure containing pointers to all the entry points of a
* secure element driver.
*
* Future versions of this specification may add extra substructures at
* the end of this structure.
*/
typedef struct {
/** The version of the driver HAL that this driver implements.
* This is a protection against loading driver binaries built against
* a different version of this specification.
* Use #PSA_DRV_SE_HAL_VERSION.
*/
uint32_t hal_version;
/** The size of the driver's persistent data in bytes.
*
* This can be 0 if the driver does not need persistent data.
*
* See the documentation of psa_drv_se_context_t::persistent_data
* for more information about why and how a driver can use
* persistent data.
*/
size_t persistent_data_size;
/** The driver initialization function.
*
* This function is called once during the initialization of the
* PSA Cryptography subsystem, before any other function of the
* driver is called. If this function returns a failure status,
* the driver will be unusable, at least until the next system reset.
*
* If this field is \c NULL, it is equivalent to a function that does
* nothing and returns #PSA_SUCCESS.
*/
psa_drv_se_init_t p_init;
const psa_drv_se_key_management_t *key_management;
const psa_drv_se_mac_t *mac;
const psa_drv_se_cipher_t *cipher;
const psa_drv_se_aead_t *aead;
const psa_drv_se_asymmetric_t *asymmetric;
const psa_drv_se_key_derivation_t *derivation;
} psa_drv_se_t;
/** The current version of the secure element driver HAL.
*/
/* 0.0.0 patchlevel 5 */
#define PSA_DRV_SE_HAL_VERSION 0x00000005
/** Register an external cryptoprocessor (secure element) driver.
*
* This function is only intended to be used by driver code, not by
* application code. In implementations with separation between the
* PSA cryptography module and applications, this function should
* only be available to callers that run in the same memory space as
* the cryptography module, and should not be exposed to applications
* running in a different memory space.
*
* This function may be called before psa_crypto_init(). It is
* implementation-defined whether this function may be called
* after psa_crypto_init().
*
* \note Implementations store metadata about keys including the lifetime
* value. Therefore, from one instantiation of the PSA Cryptography
* library to the next one, if there is a key in storage with a certain
* lifetime value, you must always register the same driver (or an
* updated version that communicates with the same secure element)
* with the same lifetime value.
*
* \param lifetime The lifetime value through which this driver will
* be exposed to applications.
* The values #PSA_KEY_LIFETIME_VOLATILE and
* #PSA_KEY_LIFETIME_PERSISTENT are reserved and
* may not be used for drivers. Implementations
* may reserve other values.
* \param[in] methods The method table of the driver. This structure must
* remain valid for as long as the cryptography
* module keeps running. It is typically a global
* constant.
*
* \return PSA_SUCCESS
* The driver was successfully registered. Applications can now
* use \p lifetime to access keys through the methods passed to
* this function.
* \return PSA_ERROR_BAD_STATE
* This function was called after the initialization of the
* cryptography module, and this implementation does not support
* driver registration at this stage.
* \return PSA_ERROR_ALREADY_EXISTS
* There is already a registered driver for this value of \p lifetime.
* \return PSA_ERROR_INVALID_ARGUMENT
* \p lifetime is a reserved value.
* \return PSA_ERROR_NOT_SUPPORTED
* `methods->hal_version` is not supported by this implementation.
* \return PSA_ERROR_INSUFFICIENT_MEMORY
* \return PSA_ERROR_NOT_PERMITTED
*/
psa_status_t psa_register_se_driver(
psa_key_lifetime_t lifetime,
const psa_drv_se_t *methods);
/**@}*/
#ifdef __cplusplus
}
#endif

View File

@ -53,6 +53,9 @@
#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
#define PSA_ROUND_UP_TO_MULTIPLE(block_size, length) \
(((length) + (block_size) - 1) / (block_size) * (block_size))
/** The size of the output of psa_hash_finish(), in bytes.
*
* This is also the hash size that psa_hash_verify() expects.
@ -269,7 +272,7 @@
* \param key_type The type of the MAC key.
* \param key_bits The size of the MAC key in bits.
* \param alg A MAC algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_MAC(alg) is true).
* #PSA_ALG_IS_MAC(\p alg) is true).
*
* \return The MAC size for the specified algorithm with
* the specified key parameters.
@ -294,7 +297,7 @@
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(alg) is true).
* #PSA_ALG_IS_AEAD(\p alg) is true).
* \param plaintext_length Size of the plaintext in bytes.
*
* \return The AEAD ciphertext size for the specified
@ -318,7 +321,7 @@
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(alg) is true).
* #PSA_ALG_IS_AEAD(\p alg) is true).
* \param ciphertext_length Size of the plaintext in bytes.
*
* \return The AEAD ciphertext size for the specified
@ -330,7 +333,81 @@
*/
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
(plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
(ciphertext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
0)
/** A sufficient output buffer size for psa_aead_update().
*
* If the size of the output buffer is at least this large, it is
* guaranteed that psa_aead_update() will not fail due to an
* insufficient buffer size. The actual size of the output may be smaller
* in any given call.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
* \param input_length Size of the input in bytes.
*
* \return A sufficient output buffer size for the specified
* algorithm.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
/* For all the AEAD modes defined in this specification, it is possible
* to emit output without delay. However, hardware may not always be
* capable of this. So for modes based on a block cipher, allow the
* implementation to delay the output until it has a full block. */
#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
PSA_ROUND_UP_TO_MULTIPLE(PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE, (input_length)) : \
(input_length))
/** A sufficient ciphertext buffer size for psa_aead_finish().
*
* If the size of the ciphertext buffer is at least this large, it is
* guaranteed that psa_aead_finish() will not fail due to an
* insufficient ciphertext buffer size. The actual size of the output may
* be smaller in any given call.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
*
* \return A sufficient ciphertext buffer size for the
* specified algorithm.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
#define PSA_AEAD_FINISH_OUTPUT_SIZE(alg) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
0)
/** A sufficient plaintext buffer size for psa_aead_verify().
*
* If the size of the plaintext buffer is at least this large, it is
* guaranteed that psa_aead_verify() will not fail due to an
* insufficient plaintext buffer size. The actual size of the output may
* be smaller in any given call.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
*
* \return A sufficient plaintext buffer size for the
* specified algorithm.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
#define PSA_AEAD_VERIFY_OUTPUT_SIZE(alg) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
0)
#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
@ -349,9 +426,9 @@
#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \
(PSA_BITS_TO_BYTES(curve_bits) * 2)
/** Safe signature buffer size for psa_asymmetric_sign().
/** Sufficient signature buffer size for psa_asymmetric_sign().
*
* This macro returns a safe buffer size for a signature using a key
* This macro returns a sufficient buffer size for a signature using a key
* of the specified type and size, with the specified algorithm.
* Note that the actual size of the signature may be smaller
* (some algorithms produce a variable-size signature).
@ -370,7 +447,7 @@
* psa_asymmetric_sign() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro either shall return either a
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
@ -380,9 +457,9 @@
PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \
((void)alg, 0))
/** Safe output buffer size for psa_asymmetric_encrypt().
/** Sufficient output buffer size for psa_asymmetric_encrypt().
*
* This macro returns a safe buffer size for a ciphertext produced using
* This macro returns a sufficient buffer size for a ciphertext produced using
* a key of the specified type and size, with the specified algorithm.
* Note that the actual size of the ciphertext may be smaller, depending
* on the algorithm.
@ -401,7 +478,7 @@
* psa_asymmetric_encrypt() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro either shall return either a
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
@ -411,9 +488,9 @@
((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
0)
/** Safe output buffer size for psa_asymmetric_decrypt().
/** Sufficient output buffer size for psa_asymmetric_decrypt().
*
* This macro returns a safe buffer size for a ciphertext produced using
* This macro returns a sufficient buffer size for a ciphertext produced using
* a key of the specified type and size, with the specified algorithm.
* Note that the actual size of the ciphertext may be smaller, depending
* on the algorithm.
@ -432,7 +509,7 @@
* psa_asymmetric_decrypt() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro either shall return either a
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
@ -491,7 +568,7 @@
* overapproximated as 9 half-size INTEGERS;
* - 7 bytes for the public exponent.
*/
#define PSA_KEY_EXPORT_RSA_KEYPAIR_MAX_SIZE(key_bits) \
#define PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) \
(9 * PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE((key_bits) / 2 + 1) + 14)
/* Maximum size of the export encoding of a DSA public key.
@ -529,7 +606,7 @@
* - 3 full-size INTEGERs (p, g, y);
* - 2 * (1 + 1 + 32) bytes for 2 sub-size INTEGERs (q, x <= 256 bits).
*/
#define PSA_KEY_EXPORT_DSA_KEYPAIR_MAX_SIZE(key_bits) \
#define PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) \
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3 + 75)
/* Maximum size of the export encoding of an ECC public key.
@ -549,10 +626,10 @@
*
* An ECC key pair is represented by the secret value.
*/
#define PSA_KEY_EXPORT_ECC_KEYPAIR_MAX_SIZE(key_bits) \
#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \
(PSA_BITS_TO_BYTES(key_bits))
/** Safe output buffer size for psa_export_key() or psa_export_public_key().
/** Sufficient output buffer size for psa_export_key() or psa_export_public_key().
*
* This macro returns a compile-time constant if its arguments are
* compile-time constants.
@ -564,32 +641,36 @@
* The following code illustrates how to allocate enough memory to export
* a key by querying the key type and size at runtime.
* \code{c}
* psa_key_type_t key_type;
* size_t key_bits;
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* psa_status_t status;
* status = psa_get_key_information(key, &key_type, &key_bits);
* status = psa_get_key_attributes(key, &attributes);
* if (status != PSA_SUCCESS) handle_error(...);
* psa_key_type_t key_type = psa_get_key_type(&attributes);
* size_t key_bits = psa_get_key_bits(&attributes);
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits);
* unsigned char *buffer = malloc(buffer_size);
* if (buffer != NULL) handle_error(...);
* psa_reset_key_attributes(&attributes);
* uint8_t *buffer = malloc(buffer_size);
* if (buffer == NULL) handle_error(...);
* size_t buffer_length;
* status = psa_export_key(key, buffer, buffer_size, &buffer_length);
* if (status != PSA_SUCCESS) handle_error(...);
* \endcode
*
* For psa_export_public_key(), calculate the buffer size from the
* public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR
* public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR
* to convert a key pair type to the corresponding public key type.
* \code{c}
* psa_key_type_t key_type;
* size_t key_bits;
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* psa_status_t status;
* status = psa_get_key_information(key, &key_type, &key_bits);
* status = psa_get_key_attributes(key, &attributes);
* if (status != PSA_SUCCESS) handle_error(...);
* psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(key_type);
* psa_key_type_t key_type = psa_get_key_type(&attributes);
* psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
* size_t key_bits = psa_get_key_bits(&attributes);
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(public_key_type, key_bits);
* unsigned char *buffer = malloc(buffer_size);
* if (buffer != NULL) handle_error(...);
* psa_reset_key_attributes(&attributes);
* uint8_t *buffer = malloc(buffer_size);
* if (buffer == NULL) handle_error(...);
* size_t buffer_length;
* status = psa_export_public_key(key, buffer, buffer_size, &buffer_length);
* if (status != PSA_SUCCESS) handle_error(...);
@ -603,18 +684,18 @@
* psa_asymmetric_sign() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
* If the parameters are a valid combination that is not supported
* by the implementation, this macro either shall return either a
* by the implementation, this macro shall return either a
* sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
#define PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits) \
(PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
(key_type) == PSA_KEY_TYPE_RSA_KEYPAIR ? PSA_KEY_EXPORT_RSA_KEYPAIR_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_DSA_KEYPAIR ? PSA_KEY_EXPORT_DSA_KEYPAIR_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
(key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
PSA_KEY_TYPE_IS_ECC_KEYPAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEYPAIR_MAX_SIZE(key_bits) : \
PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \
PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
0)

View File

@ -45,9 +45,9 @@
* \brief Function return status.
*
* This is either #PSA_SUCCESS (which is zero), indicating success,
* or a nonzero value indicating that an error occurred. Errors are
* encoded as one of the \c PSA_ERROR_xxx values defined here.
* If #PSA_SUCCESS is already defined, it means that #psa_status_t
* or a small negative value indicating that an error occurred. Errors are
* encoded as one of the \c PSA_ERROR_xxx values defined here. */
/* If #PSA_SUCCESS is already defined, it means that #psa_status_t
* is also defined in an external header, so prevent its multiple
* definition.
*/
@ -68,6 +68,9 @@ typedef uint32_t psa_key_type_t;
/** The type of PSA elliptic curve identifiers. */
typedef uint16_t psa_ecc_curve_t;
/** The type of PSA Diffie-Hellman group identifiers. */
typedef uint16_t psa_dh_group_t;
/** \brief Encoding of a cryptographic algorithm.
*
* For algorithms that can be applied to multiple key types, this type
@ -85,10 +88,30 @@ typedef uint32_t psa_algorithm_t;
*/
/** Encoding of key lifetimes.
*
* The lifetime of a key indicates where it is stored and what system actions
* may create and destroy it.
*
* Keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE are automatically
* destroyed when the application terminates or on a power reset.
*
* Keys with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE are said
* to be _persistent_.
* Persistent keys are preserved if the application or the system restarts.
* Persistent keys have a key identifier of type #psa_key_id_t.
* The application can call psa_open_key() to open a persistent key that
* it created previously.
*/
typedef uint32_t psa_key_lifetime_t;
/** Encoding of identifiers of persistent keys.
*
* - Applications may freely choose key identifiers in the range
* #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX.
* - Implementations may define additional key identifiers in the range
* #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX.
* - 0 is reserved as an invalid key identifier.
* - Key identifiers outside these ranges are reserved for future use.
*/
/* Implementation-specific quirk: The Mbed Crypto library can be built as
* part of a multi-client service that exposes the PSA Crypto API in each
@ -97,6 +120,7 @@ typedef uint32_t psa_key_lifetime_t;
* psa_key_id_t in crypto_platform.h instead of here. */
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER)
typedef uint32_t psa_key_id_t;
#define PSA_KEY_ID_INIT 0
#endif
/**@}*/
@ -110,4 +134,137 @@ typedef uint32_t psa_key_usage_t;
/**@}*/
/** \defgroup attributes Key attributes
* @{
*/
/** The type of a structure containing key attributes.
*
* This is an opaque structure that can represent the metadata of a key
* object. Metadata that can be stored in attributes includes:
* - The location of the key in storage, indicated by its key identifier
* and its lifetime.
* - The key's policy, comprising usage flags and a specification of
* the permitted algorithm(s).
* - Information about the key itself: the key type and its size.
* - Implementations may define additional attributes.
*
* The actual key material is not considered an attribute of a key.
* Key attributes do not contain information that is generally considered
* highly confidential.
*
* An attribute structure can be a simple data structure where each function
* `psa_set_key_xxx` sets a field and the corresponding function
* `psa_get_key_xxx` retrieves the value of the corresponding field.
* However, implementations may report values that are equivalent to the
* original one, but have a different encoding. For example, an
* implementation may use a more compact representation for types where
* many bit-patterns are invalid or not supported, and store all values
* that it does not support as a special marker value. In such an
* implementation, after setting an invalid value, the corresponding
* get function returns an invalid value which may not be the one that
* was originally stored.
*
* An attribute structure may contain references to auxiliary resources,
* for example pointers to allocated memory or indirect references to
* pre-calculated values. In order to free such resources, the application
* must call psa_reset_key_attributes(). As an exception, calling
* psa_reset_key_attributes() on an attribute structure is optional if
* the structure has only been modified by the following functions
* since it was initialized or last reset with psa_reset_key_attributes():
* - psa_set_key_id()
* - psa_set_key_lifetime()
* - psa_set_key_type()
* - psa_set_key_bits()
* - psa_set_key_usage_flags()
* - psa_set_key_algorithm()
*
* Before calling any function on a key attribute structure, the application
* must initialize it by any of the following means:
* - Set the structure to all-bits-zero, for example:
* \code
* psa_key_attributes_t attributes;
* memset(&attributes, 0, sizeof(attributes));
* \endcode
* - Initialize the structure to logical zero values, for example:
* \code
* psa_key_attributes_t attributes = {0};
* \endcode
* - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT,
* for example:
* \code
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* \endcode
* - Assign the result of the function psa_key_attributes_init()
* to the structure, for example:
* \code
* psa_key_attributes_t attributes;
* attributes = psa_key_attributes_init();
* \endcode
*
* A freshly initialized attribute structure contains the following
* values:
*
* - lifetime: #PSA_KEY_LIFETIME_VOLATILE.
* - key identifier: unspecified.
* - type: \c 0.
* - key size: \c 0.
* - usage flags: \c 0.
* - algorithm: \c 0.
*
* A typical sequence to create a key is as follows:
* -# Create and initialize an attribute structure.
* -# If the key is persistent, call psa_set_key_id().
* Also call psa_set_key_lifetime() to place the key in a non-default
* location.
* -# Set the key policy with psa_set_key_usage_flags() and
* psa_set_key_algorithm().
* -# Set the key type with psa_set_key_type().
* Skip this step if copying an existing key with psa_copy_key().
* -# When generating a random key with psa_generate_key() or deriving a key
* with psa_key_derivation_output_key(), set the desired key size with
* psa_set_key_bits().
* -# Call a key creation function: psa_import_key(), psa_generate_key(),
* psa_key_derivation_output_key() or psa_copy_key(). This function reads
* the attribute structure, creates a key with these attributes, and
* outputs a handle to the newly created key.
* -# The attribute structure is now no longer necessary.
* You may call psa_reset_key_attributes(), although this is optional
* with the workflow presented here because the attributes currently
* defined in this specification do not require any additional resources
* beyond the structure itself.
*
* A typical sequence to query a key's attributes is as follows:
* -# Call psa_get_key_attributes().
* -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that
* you are interested in.
* -# Call psa_reset_key_attributes() to free any resources that may be
* used by the attribute structure.
*
* Once a key has been created, it is impossible to change its attributes.
*/
typedef struct psa_key_attributes_s psa_key_attributes_t;
#ifndef __DOXYGEN_ONLY__
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* Mbed Crypto defines this type in crypto_types.h because it is also
* visible to applications through an implementation-specific extension.
* For the PSA Cryptography specification, this type is only visible
* via crypto_se_driver.h. */
typedef uint64_t psa_key_slot_number_t;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
#endif /* !__DOXYGEN_ONLY__ */
/**@}*/
/** \defgroup derivation Key derivation
* @{
*/
/** \brief Encoding of the step of a key derivation. */
typedef uint16_t psa_key_derivation_step_t;
/**@}*/
#endif /* PSA_CRYPTO_TYPES_H */

View File

@ -105,9 +105,13 @@
* descriptions for permitted sequencing of functions.
*
* Implementations shall not return this error code to indicate
* that a key slot is occupied when it needs to be free or vice versa,
* but shall return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
* as applicable. */
* that a key either exists or not,
* but shall instead return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
* as applicable.
*
* Implementations shall not return this error code to indicate that a
* key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
* instead. */
#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
/** The parameters passed to the function are invalid.
@ -115,12 +119,7 @@
* Implementations may return this error any time a parameter or
* combination of parameters are recognized as invalid.
*
* Implementations shall not return this error code to indicate
* that a key slot is occupied when it needs to be free or vice versa,
* but shall return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
* as applicable.
*
* Implementation shall not return this error code to indicate that a
* Implementations shall not return this error code to indicate that a
* key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
* instead.
*/
@ -162,7 +161,7 @@
*
* This error indicates that some persistent storage is corrupted.
* It should not be used for a corruption of volatile memory
* (use #PSA_ERROR_TAMPERING_DETECTED), for a communication error
* (use #PSA_ERROR_CORRUPTION_DETECTED), for a communication error
* between the cryptoprocessor and its external storage (use
* #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is
* in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE).
@ -175,7 +174,7 @@
* the global integrity of the keystore. Depending on the global
* integrity guarantees offered by the implementation, access to other
* data may or may not fail even if the data is still readable but
* its integrity canont be guaranteed.
* its integrity cannot be guaranteed.
*
* Implementations should only use this error code to report a
* permanent storage corruption. However application writers should
@ -218,7 +217,7 @@
* This error indicates an attack against the application. Implementations
* shall not return this error code as a consequence of the behavior of
* the application itself. */
#define PSA_ERROR_TAMPERING_DETECTED ((psa_status_t)-151)
#define PSA_ERROR_CORRUPTION_DETECTED ((psa_status_t)-151)
/** There is not enough entropy to generate random data needed
* for the requested action.
@ -269,7 +268,7 @@
* to read from a resource. */
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
/** The key handle is not valid.
/** The key handle is not valid. See also :ref:\`key-handles\`.
*/
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
@ -324,7 +323,7 @@
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
/** Whether a key type is a key pair containing a private part and a public
* part. */
#define PSA_KEY_TYPE_IS_KEYPAIR(type) \
#define PSA_KEY_TYPE_IS_KEY_PAIR(type) \
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR)
/** The key pair type corresponding to a public key type.
*
@ -336,7 +335,7 @@
* If \p type is not a public key or a key pair,
* the return value is undefined.
*/
#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type) \
#define PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY(type) \
((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
/** The public key type corresponding to a key pair type.
*
@ -348,7 +347,7 @@
* If \p type is not a public key or a key pair,
* the return value is undefined.
*/
#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) \
#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) \
((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
/** Raw data.
@ -374,7 +373,7 @@
*/
#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t)0x52000000)
/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
/** Key for a cipher, AEAD or MAC algorithm based on the AES block cipher.
*
* The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
* 32 bytes (AES-256).
@ -392,7 +391,7 @@
*/
#define PSA_KEY_TYPE_DES ((psa_key_type_t)0x40000002)
/** Key for an cipher, AEAD or MAC algorithm based on the
/** Key for a cipher, AEAD or MAC algorithm based on the
* Camellia block cipher. */
#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x40000003)
@ -402,40 +401,41 @@
* legacy protocols. */
#define PSA_KEY_TYPE_ARC4 ((psa_key_type_t)0x40000004)
/** Key for the ChaCha20 stream cipher or the Chacha20-Poly1305 AEAD algorithm.
*
* ChaCha20 and the ChaCha20_Poly1305 construction are defined in RFC 7539.
*
* Implementations must support 12-byte nonces, may support 8-byte nonces,
* and should reject other sizes.
*/
#define PSA_KEY_TYPE_CHACHA20 ((psa_key_type_t)0x40000005)
/** RSA public key. */
#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x60010000)
/** RSA key pair (private and public key). */
#define PSA_KEY_TYPE_RSA_KEYPAIR ((psa_key_type_t)0x70010000)
#define PSA_KEY_TYPE_RSA_KEY_PAIR ((psa_key_type_t)0x70010000)
/** Whether a key type is an RSA key (pair or public-only). */
#define PSA_KEY_TYPE_IS_RSA(type) \
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
/** DSA public key. */
#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x60020000)
/** DSA key pair (private and public key). */
#define PSA_KEY_TYPE_DSA_KEYPAIR ((psa_key_type_t)0x70020000)
/** Whether a key type is an DSA key (pair or public-only). */
#define PSA_KEY_TYPE_IS_DSA(type) \
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x60030000)
#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE ((psa_key_type_t)0x70030000)
#define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t)0x70030000)
#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff)
/** Elliptic curve key pair. */
#define PSA_KEY_TYPE_ECC_KEYPAIR(curve) \
(PSA_KEY_TYPE_ECC_KEYPAIR_BASE | (curve))
#define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \
(PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve))
/** Elliptic curve public key. */
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \
(PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
/** Whether a key type is an elliptic curve key (pair or public-only). */
#define PSA_KEY_TYPE_IS_ECC(type) \
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) & \
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
/** Whether a key type is an elliptic curve key pair. */
#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type) \
#define PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type) \
(((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
PSA_KEY_TYPE_ECC_KEYPAIR_BASE)
PSA_KEY_TYPE_ECC_KEY_PAIR_BASE)
/** Whether a key type is an elliptic curve public key. */
#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) \
(((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
@ -480,9 +480,61 @@
#define PSA_ECC_CURVE_BRAINPOOL_P256R1 ((psa_ecc_curve_t) 0x001a)
#define PSA_ECC_CURVE_BRAINPOOL_P384R1 ((psa_ecc_curve_t) 0x001b)
#define PSA_ECC_CURVE_BRAINPOOL_P512R1 ((psa_ecc_curve_t) 0x001c)
/** Curve25519.
*
* This is the curve defined in Bernstein et al.,
* _Curve25519: new Diffie-Hellman speed records_, LNCS 3958, 2006.
* The algorithm #PSA_ALG_ECDH performs X25519 when used with this curve.
*/
#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x001d)
/** Curve448
*
* This is the curve defined in Hamburg,
* _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015.
* The algorithm #PSA_ALG_ECDH performs X448 when used with this curve.
*/
#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e)
#define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t)0x60040000)
#define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t)0x70040000)
#define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t)0x0000ffff)
/** Diffie-Hellman key pair. */
#define PSA_KEY_TYPE_DH_KEY_PAIR(group) \
(PSA_KEY_TYPE_DH_KEY_PAIR_BASE | (group))
/** Diffie-Hellman public key. */
#define PSA_KEY_TYPE_DH_PUBLIC_KEY(group) \
(PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE | (group))
/** Whether a key type is a Diffie-Hellman key (pair or public-only). */
#define PSA_KEY_TYPE_IS_DH(type) \
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
~PSA_KEY_TYPE_DH_GROUP_MASK) == PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE)
/** Whether a key type is a Diffie-Hellman key pair. */
#define PSA_KEY_TYPE_IS_DH_KEY_PAIR(type) \
(((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \
PSA_KEY_TYPE_DH_KEY_PAIR_BASE)
/** Whether a key type is a Diffie-Hellman public key. */
#define PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) \
(((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \
PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE)
/** Extract the group from a Diffie-Hellman key type. */
#define PSA_KEY_TYPE_GET_GROUP(type) \
((psa_dh_group_t) (PSA_KEY_TYPE_IS_DH(type) ? \
((type) & PSA_KEY_TYPE_DH_GROUP_MASK) : \
0))
/* The encoding of group identifiers is currently aligned with the
* TLS Supported Groups Registry (formerly known as the
* TLS EC Named Curve Registry)
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
* The values are defined by RFC 7919. */
#define PSA_DH_GROUP_FFDHE2048 ((psa_dh_group_t) 0x0100)
#define PSA_DH_GROUP_FFDHE3072 ((psa_dh_group_t) 0x0101)
#define PSA_DH_GROUP_FFDHE4096 ((psa_dh_group_t) 0x0102)
#define PSA_DH_GROUP_FFDHE6144 ((psa_dh_group_t) 0x0103)
#define PSA_DH_GROUP_FFDHE8192 ((psa_dh_group_t) 0x0104)
/** The block size of a block cipher.
*
* \param type A cipher key type (value of type #psa_key_type_t).
@ -517,9 +569,8 @@
#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x06000000)
#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x10000000)
#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000)
#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x22000000)
#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x30000000)
#define PSA_ALG_CATEGORY_KEY_SELECTION ((psa_algorithm_t)0x31000000)
#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x20000000)
#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x30000000)
#define PSA_ALG_IS_VENDOR_DEFINED(alg) \
(((alg) & PSA_ALG_VENDOR_FLAG) != 0)
@ -591,7 +642,6 @@
#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION)
#define PSA_ALG_KEY_SELECTION_FLAG ((psa_algorithm_t)0x01000000)
/** Whether the specified algorithm is a key agreement algorithm.
*
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
@ -601,8 +651,7 @@
* algorithm identifier.
*/
#define PSA_ALG_IS_KEY_AGREEMENT(alg) \
(((alg) & PSA_ALG_CATEGORY_MASK & ~PSA_ALG_KEY_SELECTION_FLAG) == \
PSA_ALG_CATEGORY_KEY_AGREEMENT)
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_AGREEMENT)
/** Whether the specified algorithm is a key derivation algorithm.
*
@ -615,17 +664,6 @@
#define PSA_ALG_IS_KEY_DERIVATION(alg) \
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
/** Whether the specified algorithm is a key selection algorithm.
*
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
*
* \return 1 if \p alg is a key selection algorithm, 0 otherwise.
* This macro may return either 0 or 1 if \p alg is not a supported
* algorithm identifier.
*/
#define PSA_ALG_IS_KEY_SELECTION(alg) \
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_SELECTION)
#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff)
#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001)
@ -663,15 +701,12 @@
*
* That is, suppose that `PSA_xxx_SIGNATURE` is one of the following macros:
* - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS,
* - #PSA_ALG_DSA, #PSA_ALG_DETERMINISTIC_DSA,
* - #PSA_ALG_ECDSA, #PSA_ALG_DETERMINISTIC_ECDSA.
* Then you may create and use a key as follows:
* - Set the key usage field using #PSA_ALG_ANY_HASH, for example:
* ```
* psa_key_policy_set_usage(&policy,
* PSA_KEY_USAGE_SIGN, //or PSA_KEY_USAGE_VERIFY
* PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH));
* psa_set_key_policy(handle, &policy);
* psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN); // or VERIFY
* psa_set_key_algorithm(&attributes, PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH));
* ```
* - Import or generate key material.
* - Call psa_asymmetric_sign() or psa_asymmetric_verify(), passing
@ -685,7 +720,7 @@
*
* This value may not be used to build other algorithms that are
* parametrized over a hash. For any valid use of this macro to build
* an algorithm `\p alg`, #PSA_ALG_IS_HASH_AND_SIGN(\p alg) is true.
* an algorithm \c alg, #PSA_ALG_IS_HASH_AND_SIGN(\c alg) is true.
*
* This value may not be used to build an algorithm specification to
* perform an operation. It is only valid to build policies.
@ -702,7 +737,7 @@
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
*
* \return The corresponding HMAC algorithm.
* \return Unspecified if \p alg is not a supported
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_HMAC(hash_alg) \
@ -802,9 +837,14 @@
(((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET)
#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x02c00000)
/** The CBC-MAC construction over a block cipher
*
* \warning CBC-MAC is insecure in many cases.
* A more secure mode, such as #PSA_ALG_CMAC, is recommended.
*/
#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x02c00001)
/** The CMAC construction over a block cipher */
#define PSA_ALG_CMAC ((psa_algorithm_t)0x02c00002)
#define PSA_ALG_GMAC ((psa_algorithm_t)0x02c00003)
/** Whether the specified algorithm is a MAC algorithm based on a block cipher.
*
@ -841,6 +881,18 @@
*/
#define PSA_ALG_ARC4 ((psa_algorithm_t)0x04800001)
/** The ChaCha20 stream cipher.
*
* ChaCha20 is defined in RFC 7539.
*
* The nonce size for psa_cipher_set_iv() or psa_cipher_generate_iv()
* must be 12.
*
* The initial block counter is always 0.
*
*/
#define PSA_ALG_CHACHA20 ((psa_algorithm_t)0x04800005)
/** The CTR stream cipher mode.
*
* CTR is a stream cipher which is built from a block cipher.
@ -850,8 +902,16 @@
*/
#define PSA_ALG_CTR ((psa_algorithm_t)0x04c00001)
/** The CFB stream cipher mode.
*
* The underlying block cipher is determined by the key type.
*/
#define PSA_ALG_CFB ((psa_algorithm_t)0x04c00002)
/** The OFB stream cipher mode.
*
* The underlying block cipher is determined by the key type.
*/
#define PSA_ALG_OFB ((psa_algorithm_t)0x04c00003)
/** The XTS cipher mode.
@ -879,8 +939,43 @@
*/
#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t)0x04600101)
#define PSA_ALG_CCM ((psa_algorithm_t)0x06001001)
#define PSA_ALG_GCM ((psa_algorithm_t)0x06001002)
#define PSA_ALG_AEAD_FROM_BLOCK_FLAG ((psa_algorithm_t)0x00400000)
/** Whether the specified algorithm is an AEAD mode on a block cipher.
*
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
*
* \return 1 if \p alg is an AEAD algorithm which is an AEAD mode based on
* a block cipher, 0 otherwise.
* This macro may return either 0 or 1 if \p alg is not a supported
* algorithm identifier.
*/
#define PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) \
(((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_AEAD_FROM_BLOCK_FLAG)) == \
(PSA_ALG_CATEGORY_AEAD | PSA_ALG_AEAD_FROM_BLOCK_FLAG))
/** The CCM authenticated encryption algorithm.
*
* The underlying block cipher is determined by the key type.
*/
#define PSA_ALG_CCM ((psa_algorithm_t)0x06401001)
/** The GCM authenticated encryption algorithm.
*
* The underlying block cipher is determined by the key type.
*/
#define PSA_ALG_GCM ((psa_algorithm_t)0x06401002)
/** The Chacha20-Poly1305 AEAD algorithm.
*
* The ChaCha20_Poly1305 construction is defined in RFC 7539.
*
* Implementations must support 12-byte nonces, may support 8-byte nonces,
* and should reject other sizes.
*
* Implementations must support 16-byte tags and should reject other sizes.
*/
#define PSA_ALG_CHACHA20_POLY1305 ((psa_algorithm_t)0x06001005)
/* In the encoding of a AEAD algorithm, the bits corresponding to
* PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag.
@ -920,14 +1015,15 @@
* \return The corresponding AEAD algorithm with the default
* tag length for that algorithm.
*/
#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(aead_alg) \
( \
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, PSA_ALG_CCM) \
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, PSA_ALG_GCM) \
#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(aead_alg) \
( \
PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_CCM) \
PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_GCM) \
PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \
0)
#define PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, ref) \
PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, 0) == \
PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \
#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, ref) \
PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, 0) == \
PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \
ref :
#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x10020000)
@ -943,7 +1039,7 @@
* when specifying the algorithm in a usage policy.
*
* \return The corresponding RSA PKCS#1 v1.5 signature algorithm.
* \return Unspecified if \p alg is not a supported
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg) \
@ -974,7 +1070,7 @@
* when specifying the algorithm in a usage policy.
*
* \return The corresponding RSA PSS signature algorithm.
* \return Unspecified if \p alg is not a supported
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_RSA_PSS(hash_alg) \
@ -982,37 +1078,6 @@
#define PSA_ALG_IS_RSA_PSS(alg) \
(((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000)
/** DSA signature with hashing.
*
* This is the signature scheme defined by FIPS 186-4,
* with a random per-message secret number (*k*).
*
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
* This includes #PSA_ALG_ANY_HASH
* when specifying the algorithm in a usage policy.
*
* \return The corresponding DSA signature algorithm.
* \return Unspecified if \p alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_DSA(hash_alg) \
(PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000)
#define PSA_ALG_DSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000)
#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \
(PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
#define PSA_ALG_IS_DSA(alg) \
(((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \
PSA_ALG_DSA_BASE)
#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \
(((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \
(PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \
(PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x10060000)
/** ECDSA signature with hashing.
*
@ -1031,7 +1096,7 @@
* when specifying the algorithm in a usage policy.
*
* \return The corresponding ECDSA signature algorithm.
* \return Unspecified if \p alg is not a supported
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_ECDSA(hash_alg) \
@ -1066,7 +1131,7 @@
*
* \return The corresponding deterministic ECDSA signature
* algorithm.
* \return Unspecified if \p alg is not a supported
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \
@ -1096,7 +1161,7 @@
*/
#define PSA_ALG_IS_HASH_AND_SIGN(alg) \
(PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \
PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg))
PSA_ALG_IS_ECDSA(alg))
/** Get the hash used by a hash-and-sign signature algorithm.
*
@ -1138,7 +1203,7 @@
* for MGF1.
*
* \return The corresponding RSA OAEP signature algorithm.
* \return Unspecified if \p alg is not a supported
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_RSA_OAEP(hash_alg) \
@ -1150,16 +1215,25 @@
((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \
0)
#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x30000100)
#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x20000100)
/** Macro to build an HKDF algorithm.
*
* For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256.
*
* This key derivation algorithm uses the following inputs:
* - #PSA_KEY_DERIVATION_INPUT_SALT is the salt used in the "extract" step.
* It is optional; if omitted, the derivation uses an empty salt.
* - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key used in the "extract" step.
* - #PSA_KEY_DERIVATION_INPUT_INFO is the info string used in the "expand" step.
* You must pass #PSA_KEY_DERIVATION_INPUT_SALT before #PSA_KEY_DERIVATION_INPUT_SECRET.
* You may pass #PSA_KEY_DERIVATION_INPUT_INFO at any time after steup and before
* starting to generate output.
*
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
*
* \return The corresponding HKDF algorithm.
* \return Unspecified if \p alg is not a supported
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_HKDF(hash_alg) \
@ -1180,18 +1254,22 @@
#define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x30000200)
#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x20000200)
/** Macro to build a TLS-1.2 PRF algorithm.
*
* TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule,
* specified in Section 5 of RFC 5246. It is based on HMAC and can be
* used with either SHA-256 or SHA-384.
*
* For the application to TLS-1.2, the salt and label arguments passed
* to psa_key_derivation() are what's called 'seed' and 'label' in RFC 5246,
* respectively. For example, for TLS key expansion, the salt is the
* This key derivation algorithm uses the following inputs, which must be
* passed in the order given here:
* - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
* - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
* - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
*
* For the application to TLS-1.2 key expansion, the seed is the
* concatenation of ServerHello.Random + ClientHello.Random,
* while the label is "key expansion".
* and the label is "key expansion".
*
* For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA256)` represents the
* TLS 1.2 PRF using HMAC-SHA-256.
@ -1200,7 +1278,7 @@
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
*
* \return The corresponding TLS-1.2 PRF algorithm.
* \return Unspecified if \p alg is not a supported
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_TLS12_PRF(hash_alg) \
@ -1219,7 +1297,7 @@
#define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg) \
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x30000300)
#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x20000300)
/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm.
*
* In a pure-PSK handshake in TLS 1.2, the master secret is derived
@ -1228,10 +1306,16 @@
* The latter is based on HMAC and can be used with either SHA-256
* or SHA-384.
*
* For the application to TLS-1.2, the salt passed to psa_key_derivation()
* (and forwarded to the TLS-1.2 PRF) is the concatenation of the
* ClientHello.Random + ServerHello.Random, while the label is "master secret"
* or "extended master secret".
* This key derivation algorithm uses the following inputs, which must be
* passed in the order given here:
* - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
* - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
* - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
*
* For the application to TLS-1.2, the seed (which is
* forwarded to the TLS-1.2 PRF) is the concatenation of the
* ClientHello.Random + ServerHello.Random,
* and the label is "master secret" or "extended master secret".
*
* For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the
* TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256.
@ -1240,7 +1324,7 @@
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
*
* \return The corresponding TLS-1.2 PSK to MS algorithm.
* \return Unspecified if \p alg is not a supported
* \return Unspecified if \p hash_alg is not a supported
* hash algorithm.
*/
#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg) \
@ -1259,55 +1343,67 @@
#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x010fffff)
#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x0803ffff)
#define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t)0x10fc0000)
/** Use a shared secret as is.
/** Macro to build a combined algorithm that chains a key agreement with
* a key derivation.
*
* Specify this algorithm as the selection component of a key agreement
* to use the raw result of the key agreement as key material.
* \param ka_alg A key agreement algorithm (\c PSA_ALG_XXX value such
* that #PSA_ALG_IS_KEY_AGREEMENT(\p ka_alg) is true).
* \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
* that #PSA_ALG_IS_KEY_DERIVATION(\p kdf_alg) is true).
*
* \warning The raw result of a key agreement algorithm such as finite-field
* Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should
* not be used directly as key material. It can however be used as the secret
* input in a key derivation algorithm.
* \return The corresponding key agreement and derivation
* algorithm.
* \return Unspecified if \p ka_alg is not a supported
* key agreement algorithm or \p kdf_alg is not a
* supported key derivation algorithm.
*/
#define PSA_ALG_SELECT_RAW ((psa_algorithm_t)0x31000001)
#define PSA_ALG_KEY_AGREEMENT(ka_alg, kdf_alg) \
((ka_alg) | (kdf_alg))
#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) \
(((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION)
#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \
((alg) & ~PSA_ALG_KEY_DERIVATION_MASK)
#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \
(((alg) & PSA_ALG_KEY_AGREEMENT_MASK) | PSA_ALG_CATEGORY_KEY_AGREEMENT)
#define PSA_ALG_FFDH_BASE ((psa_algorithm_t)0x22100000)
/** The Diffie-Hellman key agreement algorithm.
/** Whether the specified algorithm is a raw key agreement algorithm.
*
* This algorithm combines the finite-field Diffie-Hellman (DH) key
* agreement, also known as Diffie-Hellman-Merkle (DHM) key agreement,
* to produce a shared secret from a private key and the peer's
* public key, with a key selection or key derivation algorithm to produce
* one or more shared keys and other shared cryptographic material.
* A raw key agreement algorithm is one that does not specify
* a key derivation function.
* Usually, raw key agreement algorithms are constructed directly with
* a \c PSA_ALG_xxx macro while non-raw key agreement algorithms are
* constructed with PSA_ALG_KEY_AGREEMENT().
*
* The shared secret produced by key agreement and passed as input to the
* derivation or selection algorithm \p kdf_alg is the shared secret
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
*
* \return 1 if \p alg is a raw key agreement algorithm, 0 otherwise.
* This macro may return either 0 or 1 if \p alg is not a supported
* algorithm identifier.
*/
#define PSA_ALG_IS_RAW_KEY_AGREEMENT(alg) \
(PSA_ALG_IS_KEY_AGREEMENT(alg) && \
PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) == PSA_ALG_CATEGORY_KEY_DERIVATION)
#define PSA_ALG_IS_KEY_DERIVATION_OR_AGREEMENT(alg) \
((PSA_ALG_IS_KEY_DERIVATION(alg) || PSA_ALG_IS_KEY_AGREEMENT(alg)))
/** The finite-field Diffie-Hellman (DH) key agreement algorithm.
*
* The shared secret produced by key agreement is
* `g^{ab}` in big-endian format.
* It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p`
* in bits.
*
* \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
* that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
* or a key selection algorithm (\c PSA_ALG_XXX value such
* that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
*
* \return The Diffie-Hellman algorithm with the specified
* selection or derivation algorithm.
*/
#define PSA_ALG_FFDH(kdf_alg) \
(PSA_ALG_FFDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
#define PSA_ALG_FFDH ((psa_algorithm_t)0x30100000)
/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm.
*
* This includes every supported key selection or key agreement algorithm
* for the output of the Diffie-Hellman calculation.
* This includes the raw finite field Diffie-Hellman algorithm as well as
* finite-field Diffie-Hellman followed by any supporter key derivation
* algorithm.
*
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
*
@ -1316,18 +1412,11 @@
* key agreement algorithm identifier.
*/
#define PSA_ALG_IS_FFDH(alg) \
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH_BASE)
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH)
#define PSA_ALG_ECDH_BASE ((psa_algorithm_t)0x22200000)
/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm.
*
* This algorithm combines the elliptic curve Diffie-Hellman key
* agreement to produce a shared secret from a private key and the peer's
* public key, with a key selection or key derivation algorithm to produce
* one or more shared keys and other shared cryptographic material.
*
* The shared secret produced by key agreement and passed as input to the
* derivation or selection algorithm \p kdf_alg is the x-coordinate of
* The shared secret produced by key agreement is the x-coordinate of
* the shared secret point. It is always `ceiling(m / 8)` bytes long where
* `m` is the bit size associated with the curve, i.e. the bit size of the
* order of the curve's coordinate field. When `m` is not a multiple of 8,
@ -1349,22 +1438,15 @@
* the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
* in big-endian byte order.
* The bit size is `m` for the field `F_{2^m}`.
*
* \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
* that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
* or a selection algorithm (\c PSA_ALG_XXX value such
* that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
*
* \return The Diffie-Hellman algorithm with the specified
* selection or derivation algorithm.
*/
#define PSA_ALG_ECDH(kdf_alg) \
(PSA_ALG_ECDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
#define PSA_ALG_ECDH ((psa_algorithm_t)0x30200000)
/** Whether the specified algorithm is an elliptic curve Diffie-Hellman
* algorithm.
*
* This includes every supported key selection or key agreement algorithm
* for the output of the Diffie-Hellman calculation.
* This includes the raw elliptic curve Diffie-Hellman algorithm as well as
* elliptic curve Diffie-Hellman followed by any supporter key derivation
* algorithm.
*
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
*
@ -1374,7 +1456,7 @@
* key agreement algorithm identifier.
*/
#define PSA_ALG_IS_ECDH(alg) \
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH_BASE)
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH)
/** Whether the specified algorithm encoding is a wildcard.
*
@ -1419,6 +1501,19 @@
*/
#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001)
/** The minimum value for a key identifier chosen by the application.
*/
#define PSA_KEY_ID_USER_MIN ((psa_app_key_id_t)0x00000001)
/** The maximum value for a key identifier chosen by the application.
*/
#define PSA_KEY_ID_USER_MAX ((psa_app_key_id_t)0x3fffffff)
/** The minimum value for a key identifier chosen by the implementation.
*/
#define PSA_KEY_ID_VENDOR_MIN ((psa_app_key_id_t)0x40000000)
/** The maximum value for a key identifier chosen by the implementation.
*/
#define PSA_KEY_ID_VENDOR_MAX ((psa_app_key_id_t)0x7fffffff)
/**@}*/
/** \defgroup policy Key policies
@ -1438,6 +1533,22 @@
*/
#define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t)0x00000001)
/** Whether the key may be copied.
*
* This flag allows the use of psa_copy_key() to make a copy of the key
* with the same policy or a more restrictive policy.
*
* For lifetimes for which the key is located in a secure element which
* enforce the non-exportability of keys, copying a key outside the secure
* element also requires the usage flag #PSA_KEY_USAGE_EXPORT.
* Copying the key inside the secure element is permitted with just
* #PSA_KEY_USAGE_COPY if the secure element supports it.
* For keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE or
* #PSA_KEY_LIFETIME_PERSISTENT, the usage flag #PSA_KEY_USAGE_COPY
* is sufficient to permit the copy.
*/
#define PSA_KEY_USAGE_COPY ((psa_key_usage_t)0x00000002)
/** Whether the key may be used to encrypt a message.
*
* This flag allows the key to be used for a symmetric encryption operation,
@ -1486,4 +1597,40 @@
/**@}*/
/** \defgroup derivation Key derivation
* @{
*/
/** A secret input for key derivation.
*
* This must be a key of type #PSA_KEY_TYPE_DERIVE.
*/
#define PSA_KEY_DERIVATION_INPUT_SECRET ((psa_key_derivation_step_t)0x0101)
/** A label for key derivation.
*
* This must be a direct input.
*/
#define PSA_KEY_DERIVATION_INPUT_LABEL ((psa_key_derivation_step_t)0x0201)
/** A salt for key derivation.
*
* This must be a direct input.
*/
#define PSA_KEY_DERIVATION_INPUT_SALT ((psa_key_derivation_step_t)0x0202)
/** An information string for key derivation.
*
* This must be a direct input.
*/
#define PSA_KEY_DERIVATION_INPUT_INFO ((psa_key_derivation_step_t)0x0203)
/** A seed for key derivation.
*
* This must be a direct input.
*/
#define PSA_KEY_DERIVATION_INPUT_SEED ((psa_key_derivation_step_t)0x0204)
/**@}*/
#endif /* PSA_CRYPTO_VALUES_H */

View File

@ -12,6 +12,26 @@
* In implementations with isolation between the application and the
* cryptography module, it is expected that the front-end and the back-end
* would have different versions of this file.
*
* <h3>Design notes about multipart operation structures</h3>
*
* Each multipart operation structure contains a `psa_algorithm_t alg`
* field which indicates which specific algorithm the structure is for.
* When the structure is not in use, `alg` is 0. Most of the structure
* consists of a union which is discriminated by `alg`.
*
* Note that when `alg` is 0, the content of other fields is undefined.
* In particular, it is not guaranteed that a freshly-initialized structure
* is all-zero: we initialize structures to something like `{0, 0}`, which
* is only guaranteed to initializes the first member of the union;
* GCC and Clang initialize the whole structure to 0 (at the time of writing),
* but MSVC and CompCert don't.
*
* In Mbed Crypto, multipart operation structures live independently from
* the key. This allows Mbed Crypto to free the key objects when destroying
* a key slot. If a multipart operation needs to remember the key after
* the setup function returns, the operation structure needs to contain a
* copy of the key.
*/
/*
* Copyright (C) 2018, ARM Limited, All Rights Reserved
@ -35,6 +55,10 @@
#ifndef PSA_CRYPTO_STRUCT_H
#define PSA_CRYPTO_STRUCT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Include the Mbed TLS configuration file, the way Mbed TLS does it
* in each of its header files. */
#if !defined(MBEDTLS_CONFIG_FILE)
@ -152,6 +176,27 @@ static inline struct psa_cipher_operation_s psa_cipher_operation_init( void )
return( v );
}
struct psa_aead_operation_s
{
psa_algorithm_t alg;
unsigned int key_set : 1;
unsigned int iv_set : 1;
uint8_t iv_size;
uint8_t block_size;
union
{
unsigned dummy; /* Enable easier initializing of the union. */
mbedtls_cipher_context_t cipher;
} ctx;
};
#define PSA_AEAD_OPERATION_INIT {0, 0, 0, 0, 0, {0}}
static inline struct psa_aead_operation_s psa_aead_operation_init( void )
{
const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT;
return( v );
}
#if defined(MBEDTLS_MD_C)
typedef struct
{
@ -165,62 +210,68 @@ typedef struct
#endif
uint8_t offset_in_block;
uint8_t block_number;
} psa_hkdf_generator_t;
unsigned int state : 2;
unsigned int info_set : 1;
} psa_hkdf_key_derivation_t;
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_MD_C)
typedef struct psa_tls12_prf_generator_s
typedef enum
{
/* The TLS 1.2 PRF uses the key for each HMAC iteration,
* hence we must store it for the lifetime of the generator.
* This is different from HKDF, where the key is only used
* in the extraction phase, but not during expansion. */
unsigned char *key;
size_t key_len;
/* `A(i) + seed` in the notation of RFC 5246, Sect. 5 */
uint8_t *Ai_with_seed;
size_t Ai_with_seed_len;
/* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */
uint8_t output_block[PSA_HASH_MAX_SIZE];
TLS12_PRF_STATE_INIT, /* no input provided */
TLS12_PRF_STATE_SEED_SET, /* seed has been set */
TLS12_PRF_STATE_KEY_SET, /* key has been set */
TLS12_PRF_STATE_LABEL_SET, /* label has been set */
TLS12_PRF_STATE_OUTPUT /* output has been started */
} psa_tls12_prf_key_derivation_state_t;
typedef struct psa_tls12_prf_key_derivation_s
{
#if PSA_HASH_MAX_SIZE > 0xff
#error "PSA_HASH_MAX_SIZE does not fit in uint8_t"
#endif
/* Indicates how many bytes in the current HMAC block have
* already been read by the user. */
uint8_t offset_in_block;
* not yet been read by the user. */
uint8_t left_in_block;
/* The 1-based number of the block. */
uint8_t block_number;
} psa_tls12_prf_generator_t;
psa_tls12_prf_key_derivation_state_t state;
uint8_t *seed;
size_t seed_length;
uint8_t *label;
size_t label_length;
psa_hmac_internal_data hmac;
uint8_t Ai[PSA_HASH_MAX_SIZE];
/* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */
uint8_t output_block[PSA_HASH_MAX_SIZE];
} psa_tls12_prf_key_derivation_t;
#endif /* MBEDTLS_MD_C */
struct psa_crypto_generator_s
struct psa_key_derivation_s
{
psa_algorithm_t alg;
size_t capacity;
union
{
struct
{
uint8_t *data;
size_t size;
} buffer;
/* Make the union non-empty even with no supported algorithms. */
uint8_t dummy;
#if defined(MBEDTLS_MD_C)
psa_hkdf_generator_t hkdf;
psa_tls12_prf_generator_t tls12_prf;
psa_hkdf_key_derivation_t hkdf;
psa_tls12_prf_key_derivation_t tls12_prf;
#endif
} ctx;
};
#define PSA_CRYPTO_GENERATOR_INIT {0, 0, {{0, 0}}}
static inline struct psa_crypto_generator_s psa_crypto_generator_init( void )
/* This only zeroes out the first byte in the union, the rest is unspecified. */
#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, {0}}
static inline struct psa_key_derivation_s psa_key_derivation_operation_init( void )
{
const struct psa_crypto_generator_s v = PSA_CRYPTO_GENERATOR_INIT;
const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT;
return( v );
}
@ -230,6 +281,7 @@ struct psa_key_policy_s
psa_algorithm_t alg;
psa_algorithm_t alg2;
};
typedef struct psa_key_policy_s psa_key_policy_t;
#define PSA_KEY_POLICY_INIT {0, 0, 0}
static inline struct psa_key_policy_s psa_key_policy_init( void )
@ -238,4 +290,183 @@ static inline struct psa_key_policy_s psa_key_policy_init( void )
return( v );
}
/* The type used internally for key sizes.
* Public interfaces use size_t, but internally we use a smaller type. */
typedef uint16_t psa_key_bits_t;
/* The maximum value of the type used to represent bit-sizes.
* This is used to mark an invalid key size. */
#define PSA_KEY_BITS_TOO_LARGE ( (psa_key_bits_t) ( -1 ) )
/* The maximum size of a key in bits.
* Currently defined as the maximum that can be represented, rounded down
* to a whole number of bytes.
* This is an uncast value so that it can be used in preprocessor
* conditionals. */
#define PSA_MAX_KEY_BITS 0xfff8
/** A mask of flags that can be stored in key attributes.
*
* This type is also used internally to store flags in slots. Internal
* flags are defined in library/psa_crypto_core.h. Internal flags may have
* the same value as external flags if they are properly handled during
* key creation and in psa_get_key_attributes.
*/
typedef uint16_t psa_key_attributes_flag_t;
#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \
( (psa_key_attributes_flag_t) 0x0001 )
/* A mask of key attribute flags used externally only.
* Only meant for internal checks inside the library. */
#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \
MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \
0 )
/* A mask of key attribute flags used both internally and externally.
* Currently there aren't any. */
#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \
0 )
typedef struct
{
psa_key_type_t type;
psa_key_lifetime_t lifetime;
psa_key_id_t id;
psa_key_policy_t policy;
psa_key_bits_t bits;
psa_key_attributes_flag_t flags;
} psa_core_key_attributes_t;
#define PSA_CORE_KEY_ATTRIBUTES_INIT {0, 0, PSA_KEY_ID_INIT, PSA_KEY_POLICY_INIT, 0, 0}
struct psa_key_attributes_s
{
psa_core_key_attributes_t core;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
psa_key_slot_number_t slot_number;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
void *domain_parameters;
size_t domain_parameters_size;
};
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, 0, NULL, 0}
#else
#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0}
#endif
static inline struct psa_key_attributes_s psa_key_attributes_init( void )
{
const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;
return( v );
}
static inline void psa_set_key_id(psa_key_attributes_t *attributes,
psa_key_id_t id)
{
attributes->core.id = id;
if( attributes->core.lifetime == PSA_KEY_LIFETIME_VOLATILE )
attributes->core.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
}
static inline psa_key_id_t psa_get_key_id(
const psa_key_attributes_t *attributes)
{
return( attributes->core.id );
}
static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
psa_key_lifetime_t lifetime)
{
attributes->core.lifetime = lifetime;
if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
{
#ifdef MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
attributes->core.id.key_id = 0;
attributes->core.id.owner = 0;
#else
attributes->core.id = 0;
#endif
}
}
static inline psa_key_lifetime_t psa_get_key_lifetime(
const psa_key_attributes_t *attributes)
{
return( attributes->core.lifetime );
}
static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
psa_key_usage_t usage_flags)
{
attributes->core.policy.usage = usage_flags;
}
static inline psa_key_usage_t psa_get_key_usage_flags(
const psa_key_attributes_t *attributes)
{
return( attributes->core.policy.usage );
}
static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
psa_algorithm_t alg)
{
attributes->core.policy.alg = alg;
}
static inline psa_algorithm_t psa_get_key_algorithm(
const psa_key_attributes_t *attributes)
{
return( attributes->core.policy.alg );
}
/* This function is declared in crypto_extra.h, which comes after this
* header file, but we need the function here, so repeat the declaration. */
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
psa_key_type_t type,
const uint8_t *data,
size_t data_length);
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
psa_key_type_t type)
{
if( attributes->domain_parameters == NULL )
{
/* Common case: quick path */
attributes->core.type = type;
}
else
{
/* Call the bigger function to free the old domain paramteres.
* Ignore any errors which may arise due to type requiring
* non-default domain parameters, since this function can't
* report errors. */
(void) psa_set_key_domain_parameters( attributes, type, NULL, 0 );
}
}
static inline psa_key_type_t psa_get_key_type(
const psa_key_attributes_t *attributes)
{
return( attributes->core.type );
}
static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
size_t bits)
{
if( bits > PSA_MAX_KEY_BITS )
attributes->core.bits = PSA_KEY_BITS_TOO_LARGE;
else
attributes->core.bits = (psa_key_bits_t) bits;
}
static inline size_t psa_get_key_bits(
const psa_key_attributes_t *attributes)
{
return( attributes->core.bits );
}
#ifdef __cplusplus
}
#endif
#endif /* PSA_CRYPTO_STRUCT_H */

View File

@ -29,6 +29,7 @@
#endif
#include "psa/crypto.h"
#include "psa/crypto_se_driver.h"
#include "mbedtls/ecp.h"
#include "mbedtls/rsa.h"
@ -38,27 +39,102 @@
*/
typedef struct
{
psa_key_type_t type;
psa_key_policy_t policy;
psa_key_lifetime_t lifetime;
psa_key_file_id_t persistent_storage_id;
unsigned allocated : 1;
psa_core_key_attributes_t attr;
union
{
/* Raw-data key (key_type_is_raw_bytes() in psa_crypto.c) */
struct raw_data
{
uint8_t *data;
size_t bytes;
} raw;
#if defined(MBEDTLS_RSA_C)
/* RSA public key or key pair */
mbedtls_rsa_context *rsa;
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
/* EC public key or key pair */
mbedtls_ecp_keypair *ecp;
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* Any key type in a secure element */
struct se
{
psa_key_slot_number_t slot_number;
} se;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
} data;
} psa_key_slot_t;
/* A mask of key attribute flags used only internally.
* Currently there aren't any. */
#define PSA_KA_MASK_INTERNAL_ONLY ( \
0 )
/** Test whether a key slot is occupied.
*
* A key slot is occupied iff the key type is nonzero. This works because
* no valid key can have 0 as its key type.
*
* \param[in] slot The key slot to test.
*
* \return 1 if the slot is occupied, 0 otherwise.
*/
static inline int psa_is_key_slot_occupied( const psa_key_slot_t *slot )
{
return( slot->attr.type != 0 );
}
/** Retrieve flags from psa_key_slot_t::attr::core::flags.
*
* \param[in] slot The key slot to query.
* \param mask The mask of bits to extract.
*
* \return The key attribute flags in the given slot,
* bitwise-anded with \p mask.
*/
static inline uint16_t psa_key_slot_get_flags( const psa_key_slot_t *slot,
uint16_t mask )
{
return( slot->attr.flags & mask );
}
/** Set flags in psa_key_slot_t::attr::core::flags.
*
* \param[in,out] slot The key slot to modify.
* \param mask The mask of bits to modify.
* \param value The new value of the selected bits.
*/
static inline void psa_key_slot_set_flags( psa_key_slot_t *slot,
uint16_t mask,
uint16_t value )
{
slot->attr.flags = ( ( ~mask & slot->attr.flags ) |
( mask & value ) );
}
/** Turn on flags in psa_key_slot_t::attr::core::flags.
*
* \param[in,out] slot The key slot to modify.
* \param mask The mask of bits to set.
*/
static inline void psa_key_slot_set_bits_in_flags( psa_key_slot_t *slot,
uint16_t mask )
{
slot->attr.flags |= mask;
}
/** Turn off flags in psa_key_slot_t::attr::core::flags.
*
* \param[in,out] slot The key slot to modify.
* \param mask The mask of bits to clear.
*/
static inline void psa_key_slot_clear_bits( psa_key_slot_t *slot,
uint16_t mask )
{
slot->attr.flags &= ~mask;
}
/** Completely wipe a slot in memory, including its policy.
*
* Persistent storage is not affected.
@ -68,7 +144,7 @@ typedef struct
* \retval PSA_SUCCESS
* Success. This includes the case of a key slot that was
* already fully wiped.
* \retval PSA_ERROR_TAMPERING_DETECTED
* \retval PSA_ERROR_CORRUPTION_DETECTED
*/
psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot );

View File

@ -91,6 +91,7 @@ psa_status_t psa_its_set(psa_storage_uid_t uid,
* \param[in] data_offset The starting offset of the data requested
* \param[in] data_length the amount of data requested (and the minimum allocated size of the `p_data` buffer)
* \param[out] p_data The buffer where the data will be placed upon successful completion
* \param[out] p_data_length The amount of data returned in the p_data buffer
*
*
* \return A status indicating the success/failure of the operation
@ -107,7 +108,7 @@ psa_status_t psa_its_get(psa_storage_uid_t uid,
uint32_t data_offset,
uint32_t data_length,
void *p_data,
size_t *p_data_length);
size_t *p_data_length );
/**
* \brief Retrieve the metadata about the provided uid

View File

@ -0,0 +1,356 @@
/*
* PSA crypto support for secure element drivers
*/
/* Copyright (C) 2019, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of Mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "psa/crypto_se_driver.h"
#include "psa_crypto_se.h"
#if defined(MBEDTLS_PSA_ITS_FILE_C)
#include "psa_crypto_its.h"
#else /* Native ITS implementation */
#include "psa/error.h"
#include "psa/internal_trusted_storage.h"
#endif
#include "mbedtls/platform.h"
#if !defined(MBEDTLS_PLATFORM_C)
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
/****************************************************************/
/* Driver lookup */
/****************************************************************/
/* This structure is identical to psa_drv_se_context_t declared in
* `crypto_se_driver.h`, except that some parts are writable here
* (non-const, or pointer to non-const). */
typedef struct
{
void *persistent_data;
size_t persistent_data_size;
uintptr_t transient_data;
} psa_drv_se_internal_context_t;
typedef struct psa_se_drv_table_entry_s
{
psa_key_lifetime_t lifetime;
const psa_drv_se_t *methods;
union
{
psa_drv_se_internal_context_t internal;
psa_drv_se_context_t context;
};
} psa_se_drv_table_entry_t;
static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS];
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
psa_key_lifetime_t lifetime )
{
size_t i;
/* In the driver table, lifetime=0 means an entry that isn't used.
* No driver has a lifetime of 0 because it's a reserved value
* (which designates volatile keys). Make sure we never return
* a driver entry for lifetime 0. */
if( lifetime == 0 )
return( NULL );
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
{
if( driver_table[i].lifetime == lifetime )
return( &driver_table[i] );
}
return( NULL );
}
const psa_drv_se_t *psa_get_se_driver_methods(
const psa_se_drv_table_entry_t *driver )
{
return( driver->methods );
}
psa_drv_se_context_t *psa_get_se_driver_context(
psa_se_drv_table_entry_t *driver )
{
return( &driver->context );
}
int psa_get_se_driver( psa_key_lifetime_t lifetime,
const psa_drv_se_t **p_methods,
psa_drv_se_context_t **p_drv_context)
{
psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
if( p_methods != NULL )
*p_methods = ( driver ? driver->methods : NULL );
if( p_drv_context != NULL )
*p_drv_context = ( driver ? &driver->context : NULL );
return( driver != NULL );
}
/****************************************************************/
/* Persistent data management */
/****************************************************************/
static psa_status_t psa_get_se_driver_its_file_uid(
const psa_se_drv_table_entry_t *driver,
psa_storage_uid_t *uid )
{
if( driver->lifetime > PSA_MAX_SE_LIFETIME )
return( PSA_ERROR_NOT_SUPPORTED );
#if SIZE_MAX > UINT32_MAX
/* ITS file sizes are limited to 32 bits. */
if( driver->internal.persistent_data_size > UINT32_MAX )
return( PSA_ERROR_NOT_SUPPORTED );
#endif
/* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
*uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->lifetime;
return( PSA_SUCCESS );
}
psa_status_t psa_load_se_persistent_data(
const psa_se_drv_table_entry_t *driver )
{
psa_status_t status;
psa_storage_uid_t uid;
size_t length;
status = psa_get_se_driver_its_file_uid( driver, &uid );
if( status != PSA_SUCCESS )
return( status );
/* Read the amount of persistent data that the driver requests.
* If the data in storage is larger, it is truncated. If the data
* in storage is smaller, silently keep what is already at the end
* of the output buffer. */
/* psa_get_se_driver_its_file_uid ensures that the size_t
* persistent_data_size is in range, but compilers don't know that,
* so cast to reassure them. */
return( psa_its_get( uid, 0,
(uint32_t) driver->internal.persistent_data_size,
driver->internal.persistent_data,
&length ) );
}
psa_status_t psa_save_se_persistent_data(
const psa_se_drv_table_entry_t *driver )
{
psa_status_t status;
psa_storage_uid_t uid;
status = psa_get_se_driver_its_file_uid( driver, &uid );
if( status != PSA_SUCCESS )
return( status );
/* psa_get_se_driver_its_file_uid ensures that the size_t
* persistent_data_size is in range, but compilers don't know that,
* so cast to reassure them. */
return( psa_its_set( uid,
(uint32_t) driver->internal.persistent_data_size,
driver->internal.persistent_data,
0 ) );
}
psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime )
{
psa_storage_uid_t uid;
if( lifetime > PSA_MAX_SE_LIFETIME )
return( PSA_ERROR_NOT_SUPPORTED );
uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime;
return( psa_its_remove( uid ) );
}
psa_status_t psa_find_se_slot_for_key(
const psa_key_attributes_t *attributes,
psa_key_creation_method_t method,
psa_se_drv_table_entry_t *driver,
psa_key_slot_number_t *slot_number )
{
psa_status_t status;
/* If the lifetime is wrong, it's a bug in the library. */
if( driver->lifetime != psa_get_key_lifetime( attributes ) )
return( PSA_ERROR_CORRUPTION_DETECTED );
/* If the driver doesn't support key creation in any way, give up now. */
if( driver->methods->key_management == NULL )
return( PSA_ERROR_NOT_SUPPORTED );
if( psa_get_key_slot_number( attributes, slot_number ) == PSA_SUCCESS )
{
/* The application wants to use a specific slot. Allow it if
* the driver supports it. On a system with isolation,
* the crypto service must check that the application is
* permitted to request this slot. */
psa_drv_se_validate_slot_number_t p_validate_slot_number =
driver->methods->key_management->p_validate_slot_number;
if( p_validate_slot_number == NULL )
return( PSA_ERROR_NOT_SUPPORTED );
status = p_validate_slot_number( &driver->context,
attributes, method,
*slot_number );
}
else
{
/* The application didn't tell us which slot to use. Let the driver
* choose. This is the normal case. */
psa_drv_se_allocate_key_t p_allocate =
driver->methods->key_management->p_allocate;
if( p_allocate == NULL )
return( PSA_ERROR_NOT_SUPPORTED );
status = p_allocate( &driver->context,
driver->internal.persistent_data,
attributes, method,
slot_number );
}
return( status );
}
psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
psa_key_slot_number_t slot_number )
{
psa_status_t status;
psa_status_t storage_status;
/* Normally a missing method would mean that the action is not
* supported. But psa_destroy_key() is not supposed to return
* PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should
* be able to destroy it. The only use case for a driver that
* does not have a way to destroy keys at all is if the keys are
* locked in a read-only state: we can use the keys but not
* destroy them. Hence, if the driver doesn't support destroying
* keys, it's really a lack of permission. */
if( driver->methods->key_management == NULL ||
driver->methods->key_management->p_destroy == NULL )
return( PSA_ERROR_NOT_PERMITTED );
status = driver->methods->key_management->p_destroy(
&driver->context,
driver->internal.persistent_data,
slot_number );
storage_status = psa_save_se_persistent_data( driver );
return( status == PSA_SUCCESS ? storage_status : status );
}
/****************************************************************/
/* Driver registration */
/****************************************************************/
psa_status_t psa_register_se_driver(
psa_key_lifetime_t lifetime,
const psa_drv_se_t *methods)
{
size_t i;
psa_status_t status;
if( methods->hal_version != PSA_DRV_SE_HAL_VERSION )
return( PSA_ERROR_NOT_SUPPORTED );
/* Driver table entries are 0-initialized. 0 is not a valid driver
* lifetime because it means a volatile key. */
#if defined(static_assert)
static_assert( PSA_KEY_LIFETIME_VOLATILE == 0,
"Secure element support requires 0 to mean a volatile key" );
#endif
if( lifetime == PSA_KEY_LIFETIME_VOLATILE ||
lifetime == PSA_KEY_LIFETIME_PERSISTENT )
{
return( PSA_ERROR_INVALID_ARGUMENT );
}
if( lifetime > PSA_MAX_SE_LIFETIME )
return( PSA_ERROR_NOT_SUPPORTED );
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
{
if( driver_table[i].lifetime == 0 )
break;
/* Check that lifetime isn't already in use up to the first free
* entry. Since entries are created in order and never deleted,
* there can't be a used entry after the first free entry. */
if( driver_table[i].lifetime == lifetime )
return( PSA_ERROR_ALREADY_EXISTS );
}
if( i == PSA_MAX_SE_DRIVERS )
return( PSA_ERROR_INSUFFICIENT_MEMORY );
driver_table[i].lifetime = lifetime;
driver_table[i].methods = methods;
if( methods->persistent_data_size != 0 )
{
driver_table[i].internal.persistent_data =
mbedtls_calloc( 1, methods->persistent_data_size );
if( driver_table[i].internal.persistent_data == NULL )
{
status = PSA_ERROR_INSUFFICIENT_MEMORY;
goto error;
}
/* Load the driver's persistent data. On first use, the persistent
* data does not exist in storage, and is initialized to
* all-bits-zero by the calloc call just above. */
status = psa_load_se_persistent_data( &driver_table[i] );
if( status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST )
goto error;
}
driver_table[i].internal.persistent_data_size =
methods->persistent_data_size;
return( PSA_SUCCESS );
error:
memset( &driver_table[i], 0, sizeof( driver_table[i] ) );
return( status );
}
void psa_unregister_all_se_drivers( void )
{
size_t i;
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
{
if( driver_table[i].internal.persistent_data != NULL )
mbedtls_free( driver_table[i].internal.persistent_data );
}
memset( driver_table, 0, sizeof( driver_table ) );
}
/****************************************************************/
/* The end */
/****************************************************************/
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */

View File

@ -0,0 +1,184 @@
/*
* PSA crypto support for secure element drivers
*/
/* Copyright (C) 2019, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef PSA_CRYPTO_SE_H
#define PSA_CRYPTO_SE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "psa/crypto.h"
#include "psa/crypto_se_driver.h"
/** The maximum lifetime value that this implementation supports
* for a secure element.
*
* This is not a characteristic that each PSA implementation has, but a
* limitation of the current implementation due to the constraints imposed
* by storage. See #PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE.
*
* The minimum lifetime value for a secure element is 2, like on any
* PSA implementation (0=volatile and 1=internal-storage are taken).
*/
#define PSA_MAX_SE_LIFETIME 255
/** The base of the range of ITS file identifiers for secure element
* driver persistent data.
*
* We use a slice of the implemenation reserved range 0xffff0000..0xffffffff,
* specifically the range 0xfffffe00..0xfffffeff. The length of this range
* drives the value of #PSA_MAX_SE_LIFETIME.
* The identifiers 0xfffffe00 and 0xfffffe01 are actually not used since
* they correspond to #PSA_KEY_LIFETIME_VOLATILE and
* #PSA_KEY_LIFETIME_PERSISTENT which don't have a driver.
*/
#define PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE ( (psa_key_id_t) 0xfffffe00 )
/** The maximum number of registered secure element driver lifetimes. */
#define PSA_MAX_SE_DRIVERS 4
/** Unregister all secure element drivers.
*
* \warning Do not call this function while the library is in the initialized
* state. This function is only intended to be called at the end
* of mbedtls_psa_crypto_free().
*/
void psa_unregister_all_se_drivers( void );
/** A structure that describes a registered secure element driver.
*
* A secure element driver table entry contains a pointer to the
* driver's method table as well as the driver context structure.
*/
typedef struct psa_se_drv_table_entry_s psa_se_drv_table_entry_t;
/** Return the secure element driver information for a lifetime value.
*
* \param lifetime The lifetime value to query.
* \param[out] p_methods On output, if there is a driver,
* \c *methods points to its method table.
* Otherwise \c *methods is \c NULL.
* \param[out] p_drv_context On output, if there is a driver,
* \c *drv_context points to its context
* structure.
* Otherwise \c *drv_context is \c NULL.
*
* \retval 1
* \p lifetime corresponds to a registered driver.
* \retval 0
* \p lifetime does not correspond to a registered driver.
*/
int psa_get_se_driver( psa_key_lifetime_t lifetime,
const psa_drv_se_t **p_methods,
psa_drv_se_context_t **p_drv_context);
/** Return the secure element driver table entry for a lifetime value.
*
* \param lifetime The lifetime value to query.
*
* \return The driver table entry for \p lifetime, or
* \p NULL if \p lifetime does not correspond to a registered driver.
*/
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
psa_key_lifetime_t lifetime );
/** Return the method table for a secure element driver.
*
* \param[in] driver The driver table entry to access, or \c NULL.
*
* \return The driver's method table.
* \c NULL if \p driver is \c NULL.
*/
const psa_drv_se_t *psa_get_se_driver_methods(
const psa_se_drv_table_entry_t *driver );
/** Return the context of a secure element driver.
*
* \param[in] driver The driver table entry to access, or \c NULL.
*
* \return A pointer to the driver context.
* \c NULL if \p driver is \c NULL.
*/
psa_drv_se_context_t *psa_get_se_driver_context(
psa_se_drv_table_entry_t *driver );
/** Find a free slot for a key that is to be created.
*
* This function calls the relevant method in the driver to find a suitable
* slot for a key with the given attributes.
*
* \param[in] attributes Metadata about the key that is about to be created.
* \param[in] driver The driver table entry to query.
* \param[out] slot_number On success, a slot number that is free in this
* secure element.
*/
psa_status_t psa_find_se_slot_for_key(
const psa_key_attributes_t *attributes,
psa_key_creation_method_t method,
psa_se_drv_table_entry_t *driver,
psa_key_slot_number_t *slot_number );
/** Destoy a key in a secure element.
*
* This function calls the relevant driver method to destroy a key
* and updates the driver's persistent data.
*/
psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
psa_key_slot_number_t slot_number );
/** Load the persistent data of a secure element driver.
*
* \param driver The driver table entry containing the persistent
* data to load from storage.
*/
psa_status_t psa_load_se_persistent_data(
const psa_se_drv_table_entry_t *driver );
/** Save the persistent data of a secure element driver.
*
* \param[in] driver The driver table entry containing the persistent
* data to save to storage.
*/
psa_status_t psa_save_se_persistent_data(
const psa_se_drv_table_entry_t *driver );
/** Destroy the persistent data of a secure element driver.
*
* This is currently only used for testing.
*
* \param[in] lifetime The driver lifetime whose persistent data should
* be erased.
*/
psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime );
/** The storage representation of a key whose data is in a secure element.
*/
typedef struct
{
uint8_t slot_number[sizeof( psa_key_slot_number_t )];
uint8_t bits[sizeof( psa_key_bits_t )];
} psa_se_key_data_storage_t;
#endif /* PSA_CRYPTO_SE_H */

View File

@ -33,6 +33,9 @@
#include "psa_crypto_core.h"
#include "psa_crypto_slot_management.h"
#include "psa_crypto_storage.h"
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
#include "psa_crypto_se.h"
#endif
#include <stdlib.h>
#include <string.h>
@ -71,8 +74,8 @@ psa_status_t psa_get_key_slot( psa_key_handle_t handle,
return( PSA_ERROR_INVALID_HANDLE );
slot = &global_data.key_slots[handle - 1];
/* If the slot hasn't been allocated, the handle is invalid. */
if( ! slot->allocated )
/* If the slot isn't occupied, the handle is invalid. */
if( ! psa_is_key_slot_occupied( slot ) )
return( PSA_ERROR_INVALID_HANDLE );
*p_slot = slot;
@ -99,71 +102,55 @@ void psa_wipe_all_key_slots( void )
global_data.key_slots_initialized = 0;
}
/** Find a free key slot and mark it as in use.
*
* \param[out] handle On success, a slot number that is not in use. This
* value can be used as a handle to the slot.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
*/
static psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle )
psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle,
psa_key_slot_t **p_slot )
{
if( ! global_data.key_slots_initialized )
return( PSA_ERROR_BAD_STATE );
for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) )
{
psa_key_slot_t *slot = &global_data.key_slots[*handle - 1];
if( ! slot->allocated )
{
slot->allocated = 1;
*p_slot = &global_data.key_slots[*handle - 1];
if( ! psa_is_key_slot_occupied( *p_slot ) )
return( PSA_SUCCESS );
}
}
*p_slot = NULL;
return( PSA_ERROR_INSUFFICIENT_MEMORY );
}
/** Wipe a key slot and mark it as available.
*
* This does not affect persistent storage.
*
* \param handle The handle to the key slot to release.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_TAMPERING_DETECTED
*/
static psa_status_t psa_internal_release_key_slot( psa_key_handle_t handle )
{
psa_key_slot_t *slot;
psa_status_t status;
status = psa_get_key_slot( handle, &slot );
if( status != PSA_SUCCESS )
return( status );
return( psa_wipe_key_slot( slot ) );
}
psa_status_t psa_allocate_key( psa_key_handle_t *handle )
{
*handle = 0;
return( psa_internal_allocate_key_slot( handle ) );
}
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot )
static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *slot )
{
psa_status_t status = PSA_SUCCESS;
uint8_t *key_data = NULL;
size_t key_data_length = 0;
status = psa_load_persistent_key( p_slot->persistent_storage_id,
&( p_slot )->type,
&( p_slot )->policy, &key_data,
&key_data_length );
status = psa_load_persistent_key( &slot->attr,
&key_data, &key_data_length );
if( status != PSA_SUCCESS )
goto exit;
status = psa_import_key_into_slot( p_slot,
key_data, key_data_length );
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if( psa_key_lifetime_is_external( slot->attr.lifetime ) )
{
psa_se_key_data_storage_t *data;
if( key_data_length != sizeof( *data ) )
{
status = PSA_ERROR_STORAGE_FAILURE;
goto exit;
}
data = (psa_se_key_data_storage_t *) key_data;
memcpy( &slot->data.se.slot_number, &data->slot_number,
sizeof( slot->data.se.slot_number ) );
memcpy( &slot->attr.bits, &data->bits,
sizeof( slot->attr.bits ) );
}
else
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
{
status = psa_import_key_into_slot( slot, key_data, key_data_length );
}
exit:
psa_free_persistent_key_data( key_data, key_data_length );
return( status );
@ -176,120 +163,134 @@ exit:
* is provided.
*
* \param file_id The key identifier to check.
* \param vendor_ok Nonzero to allow key ids in the vendor range.
* 0 to allow only key ids in the application range.
*
* \return 1 if \p file_id is acceptable, otherwise 0.
*/
static int psa_is_key_id_valid( psa_key_file_id_t file_id )
static int psa_is_key_id_valid( psa_key_file_id_t file_id,
int vendor_ok )
{
psa_app_key_id_t key_id = PSA_KEY_FILE_GET_KEY_ID( file_id );
/* Reject id=0 because by general library conventions, 0 is an invalid
* value wherever possible. */
if( key_id == 0 )
if( PSA_KEY_ID_USER_MIN <= key_id && key_id <= PSA_KEY_ID_USER_MAX )
return( 1 );
else if( vendor_ok &&
PSA_KEY_ID_VENDOR_MIN <= key_id &&
key_id <= PSA_KEY_ID_VENDOR_MAX )
return( 1 );
else
return( 0 );
/* Reject high values because the file names are reserved for the
* library's internal use. */
if( key_id > PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
return( 0 );
return( 1 );
}
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
/** Declare a slot as persistent and load it from storage.
*
* This function may only be called immediately after a successful call
* to psa_internal_allocate_key_slot().
*
* \param handle A handle to a key slot freshly allocated with
* psa_internal_allocate_key_slot().
*
* \retval #PSA_SUCCESS
* The slot content was loaded successfully.
* \retval #PSA_ERROR_DOES_NOT_EXIST
* There is no content for this slot in persistent storage.
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p id is not acceptable.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_STORAGE_FAILURE
*/
static psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle,
psa_key_file_id_t id )
psa_status_t psa_validate_persistent_key_parameters(
psa_key_lifetime_t lifetime,
psa_key_file_id_t id,
psa_se_drv_table_entry_t **p_drv,
int creating )
{
if( p_drv != NULL )
*p_drv = NULL;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if( psa_key_lifetime_is_external( lifetime ) )
{
*p_drv = psa_get_se_driver_entry( lifetime );
if( *p_drv == NULL )
return( PSA_ERROR_INVALID_ARGUMENT );
}
else
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
if( lifetime != PSA_KEY_LIFETIME_PERSISTENT )
return( PSA_ERROR_INVALID_ARGUMENT );
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
if( ! psa_is_key_id_valid( id, ! creating ) )
return( PSA_ERROR_INVALID_ARGUMENT );
return( PSA_SUCCESS );
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
(void) id;
(void) creating;
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
}
psa_status_t psa_open_key( psa_key_file_id_t id, psa_key_handle_t *handle )
{
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
psa_key_slot_t *slot;
psa_status_t status;
psa_key_slot_t *slot;
if( ! psa_is_key_id_valid( id ) )
return( PSA_ERROR_INVALID_ARGUMENT );
*handle = 0;
status = psa_validate_persistent_key_parameters(
PSA_KEY_LIFETIME_PERSISTENT, id, NULL, 0 );
if( status != PSA_SUCCESS )
return( status );
status = psa_get_empty_key_slot( handle, &slot );
if( status != PSA_SUCCESS )
return( status );
slot->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
slot->attr.id = id;
status = psa_load_persistent_key_into_slot( slot );
if( status != PSA_SUCCESS )
{
psa_wipe_key_slot( slot );
*handle = 0;
}
return( status );
#else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
(void) id;
*handle = 0;
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
}
psa_status_t psa_close_key( psa_key_handle_t handle )
{
psa_status_t status;
psa_key_slot_t *slot;
status = psa_get_key_slot( handle, &slot );
if( status != PSA_SUCCESS )
return( status );
slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT;
slot->persistent_storage_id = id;
status = psa_load_persistent_key_into_slot( slot );
return( status );
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
(void) handle;
(void) id;
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
return( psa_wipe_key_slot( slot ) );
}
static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime,
psa_key_file_id_t id,
psa_key_handle_t *handle,
psa_status_t wanted_load_status )
void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats )
{
psa_status_t status;
*handle = 0;
if( lifetime != PSA_KEY_LIFETIME_PERSISTENT )
return( PSA_ERROR_INVALID_ARGUMENT );
status = psa_internal_allocate_key_slot( handle );
if( status != PSA_SUCCESS )
return( status );
status = psa_internal_make_key_persistent( *handle, id );
if( status != wanted_load_status )
psa_key_handle_t key;
memset( stats, 0, sizeof( *stats ) );
for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
{
psa_internal_release_key_slot( *handle );
*handle = 0;
const psa_key_slot_t *slot = &global_data.key_slots[key - 1];
if( ! psa_is_key_slot_occupied( slot ) )
{
++stats->empty_slots;
continue;
}
if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE )
++stats->volatile_slots;
else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT )
{
psa_app_key_id_t id = PSA_KEY_FILE_GET_KEY_ID(slot->attr.id);
++stats->persistent_slots;
if( id > stats->max_open_internal_key_id )
stats->max_open_internal_key_id = id;
}
else
{
psa_app_key_id_t id = PSA_KEY_FILE_GET_KEY_ID(slot->attr.id);
++stats->external_slots;
if( id > stats->max_open_external_key_id )
stats->max_open_external_key_id = id;
}
}
return( status );
}
psa_status_t psa_open_key( psa_key_lifetime_t lifetime,
psa_key_file_id_t id,
psa_key_handle_t *handle )
{
return( persistent_key_setup( lifetime, id, handle, PSA_SUCCESS ) );
}
psa_status_t psa_create_key( psa_key_lifetime_t lifetime,
psa_key_file_id_t id,
psa_key_handle_t *handle )
{
psa_status_t status;
status = persistent_key_setup( lifetime, id, handle,
PSA_ERROR_DOES_NOT_EXIST );
switch( status )
{
case PSA_SUCCESS: return( PSA_ERROR_ALREADY_EXISTS );
case PSA_ERROR_DOES_NOT_EXIST: return( PSA_SUCCESS );
default: return( status );
}
}
psa_status_t psa_close_key( psa_key_handle_t handle )
{
return( psa_internal_release_key_slot( handle ) );
}
#endif /* MBEDTLS_PSA_CRYPTO_C */

View File

@ -22,6 +22,9 @@
#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H
#define PSA_CRYPTO_SLOT_MANAGEMENT_H
#include "psa/crypto.h"
#include "psa_crypto_se.h"
/* Number of key slots (plus one because 0 is not used).
* The value is a compile-time constant for now, for simplicity. */
#define PSA_KEY_SLOT_COUNT 32
@ -55,4 +58,72 @@ psa_status_t psa_initialize_key_slots( void );
* This does not affect persistent storage. */
void psa_wipe_all_key_slots( void );
/** Find a free key slot.
*
* This function returns a key slot that is available for use and is in its
* ground state (all-bits-zero).
*
* \param[out] handle On success, a slot number that can be used as a
* handle to the slot.
* \param[out] p_slot On success, a pointer to the slot.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_BAD_STATE
*/
psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle,
psa_key_slot_t **p_slot );
/** Test whether a lifetime designates a key in an external cryptoprocessor.
*
* \param lifetime The lifetime to test.
*
* \retval 1
* The lifetime designates an external key. There should be a
* registered driver for this lifetime, otherwise the key cannot
* be created or manipulated.
* \retval 0
* The lifetime designates a key that is volatile or in internal
* storage.
*/
static inline int psa_key_lifetime_is_external( psa_key_lifetime_t lifetime )
{
return( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
lifetime != PSA_KEY_LIFETIME_PERSISTENT );
}
/** Test whether the given parameters are acceptable for a persistent key.
*
* This function does not access the storage in any way. It only tests
* whether the parameters are meaningful and permitted by general policy.
* It does not test whether the a file by the given id exists or could be
* created.
*
* If the key is in external storage, this function returns the corresponding
* driver.
*
* \param lifetime The lifetime to test.
* \param id The key id to test.
* \param[out] p_drv On output, if \p lifetime designates a key
* in an external processor, \c *p_drv is a pointer
* to the driver table entry fot this lifetime.
* If \p lifetime designates a transparent key,
* \c *p_drv is \c NULL.
* \param creating 0 if attempting to open an existing key.
* Nonzero if attempting to create a key.
*
* \retval PSA_SUCCESS
* The given parameters are valid.
* \retval PSA_ERROR_INVALID_ARGUMENT
* \p lifetime is volatile or is invalid.
* \retval PSA_ERROR_INVALID_ARGUMENT
* \p id is invalid.
*/
psa_status_t psa_validate_persistent_key_parameters(
psa_key_lifetime_t lifetime,
psa_key_file_id_t id,
psa_se_drv_table_entry_t **p_drv,
int creating );
#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */

View File

@ -50,6 +50,12 @@
#define mbedtls_free free
#endif
/****************************************************************/
/* Key storage */
/****************************************************************/
/* Determine a file name (ITS file identifier) for the given key file
* identifier. The file name must be distinct from any file that is used
* for a purpose other than storing a key. Currently, the only such file
@ -95,15 +101,16 @@ static psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key,
{
psa_status_t status;
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot( key );
size_t actual_size;
struct psa_storage_info_t data_identifier_info;
size_t data_length = 0;
status = psa_its_get_info( data_identifier, &data_identifier_info );
if( status != PSA_SUCCESS )
return( status );
status = psa_its_get( data_identifier, 0, (uint32_t) data_size, data, &actual_size );
status = psa_its_get( data_identifier, 0, (uint32_t) data_size, data, &data_length );
if( data_size != data_length )
return( PSA_ERROR_STORAGE_FAILURE );
return( status );
}
@ -223,7 +230,7 @@ static psa_status_t psa_crypto_storage_get_data_length(
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_UINT32_LE
#define GET_UINT32_LE(n,b,i) \
#define GET_UINT32_LE( n, b, i ) \
{ \
(n) = ( (uint32_t) (b)[(i) ] ) \
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
@ -233,7 +240,7 @@ static psa_status_t psa_crypto_storage_get_data_length(
#endif
#ifndef PUT_UINT32_LE
#define PUT_UINT32_LE(n,b,i) \
#define PUT_UINT32_LE( n, b, i ) \
{ \
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
@ -251,6 +258,7 @@ static psa_status_t psa_crypto_storage_get_data_length(
typedef struct {
uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
uint8_t version[4];
uint8_t lifetime[sizeof( psa_key_lifetime_t )];
uint8_t type[sizeof( psa_key_type_t )];
uint8_t policy[sizeof( psa_key_policy_t )];
uint8_t data_len[4];
@ -259,20 +267,20 @@ typedef struct {
void psa_format_key_data_for_storage( const uint8_t *data,
const size_t data_length,
const psa_key_type_t type,
const psa_key_policy_t *policy,
const psa_core_key_attributes_t *attr,
uint8_t *storage_data )
{
psa_persistent_key_storage_format *storage_format =
(psa_persistent_key_storage_format *) storage_data;
memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
PUT_UINT32_LE(0, storage_format->version, 0);
PUT_UINT32_LE(type, storage_format->type, 0);
PUT_UINT32_LE(policy->usage, storage_format->policy, 0);
PUT_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
PUT_UINT32_LE(policy->alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
PUT_UINT32_LE(data_length, storage_format->data_len, 0);
PUT_UINT32_LE( 0, storage_format->version, 0 );
PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
PUT_UINT32_LE( attr->type, storage_format->type, 0 );
PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
PUT_UINT32_LE( data_length, storage_format->data_len, 0 );
memcpy( storage_format->key_data, data, data_length );
}
@ -288,8 +296,7 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
size_t storage_data_length,
uint8_t **key_data,
size_t *key_data_length,
psa_key_type_t *type,
psa_key_policy_t *policy )
psa_core_key_attributes_t *attr )
{
psa_status_t status;
const psa_persistent_key_storage_format *storage_format =
@ -303,32 +310,37 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
if( status != PSA_SUCCESS )
return( status );
GET_UINT32_LE(version, storage_format->version, 0);
GET_UINT32_LE( version, storage_format->version, 0 );
if( version != 0 )
return( PSA_ERROR_STORAGE_FAILURE );
GET_UINT32_LE(*key_data_length, storage_format->data_len, 0);
GET_UINT32_LE( *key_data_length, storage_format->data_len, 0 );
if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) ||
*key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
return( PSA_ERROR_STORAGE_FAILURE );
*key_data = mbedtls_calloc( 1, *key_data_length );
if( *key_data == NULL )
return( PSA_ERROR_INSUFFICIENT_MEMORY );
if( *key_data_length == 0 )
{
*key_data = NULL;
}
else
{
*key_data = mbedtls_calloc( 1, *key_data_length );
if( *key_data == NULL )
return( PSA_ERROR_INSUFFICIENT_MEMORY );
memcpy( *key_data, storage_format->key_data, *key_data_length );
}
GET_UINT32_LE(*type, storage_format->type, 0);
GET_UINT32_LE(policy->usage, storage_format->policy, 0);
GET_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
GET_UINT32_LE(policy->alg2, storage_format->policy, 2 * sizeof( uint32_t ));
memcpy( *key_data, storage_format->key_data, *key_data_length );
GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
GET_UINT32_LE( attr->type, storage_format->type, 0 );
GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
return( PSA_SUCCESS );
}
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
const psa_key_type_t type,
const psa_key_policy_t *policy,
psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr,
const uint8_t *data,
const size_t data_length )
{
@ -344,10 +356,9 @@ psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
if( storage_data == NULL )
return( PSA_ERROR_INSUFFICIENT_MEMORY );
psa_format_key_data_for_storage( data, data_length, type, policy,
storage_data );
psa_format_key_data_for_storage( data, data_length, attr, storage_data );
status = psa_crypto_storage_store( key,
status = psa_crypto_storage_store( attr->id,
storage_data, storage_data_length );
mbedtls_free( storage_data );
@ -364,15 +375,14 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
mbedtls_free( key_data );
}
psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
psa_key_type_t *type,
psa_key_policy_t *policy,
psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr,
uint8_t **data,
size_t *data_length )
{
psa_status_t status = PSA_SUCCESS;
uint8_t *loaded_data;
size_t storage_data_length = 0;
psa_key_id_t key = attr->id;
status = psa_crypto_storage_get_data_length( key, &storage_data_length );
if( status != PSA_SUCCESS )
@ -388,13 +398,74 @@ psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
goto exit;
status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
data, data_length, type, policy );
data, data_length, attr );
exit:
mbedtls_free( loaded_data );
return( status );
}
/****************************************************************/
/* Transactions */
/****************************************************************/
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
psa_crypto_transaction_t psa_crypto_transaction;
psa_status_t psa_crypto_save_transaction( void )
{
struct psa_storage_info_t p_info;
psa_status_t status;
status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
if( status == PSA_SUCCESS )
{
/* This shouldn't happen: we're trying to start a transaction while
* there is still a transaction that hasn't been replayed. */
return( PSA_ERROR_CORRUPTION_DETECTED );
}
else if( status != PSA_ERROR_DOES_NOT_EXIST )
return( status );
return( psa_its_set( PSA_CRYPTO_ITS_TRANSACTION_UID,
sizeof( psa_crypto_transaction ),
&psa_crypto_transaction,
0 ) );
}
psa_status_t psa_crypto_load_transaction( void )
{
psa_status_t status;
size_t length;
status = psa_its_get( PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
sizeof( psa_crypto_transaction ),
&psa_crypto_transaction, &length );
if( status != PSA_SUCCESS )
return( status );
if( length != sizeof( psa_crypto_transaction ) )
return( PSA_ERROR_STORAGE_FAILURE );
return( PSA_SUCCESS );
}
psa_status_t psa_crypto_stop_transaction( void )
{
psa_status_t status = psa_its_remove( PSA_CRYPTO_ITS_TRANSACTION_UID );
/* Whether or not updating the storage succeeded, the transaction is
* finished now. It's too late to go back, so zero out the in-memory
* data. */
memset( &psa_crypto_transaction, 0, sizeof( psa_crypto_transaction ) );
return( status );
}
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
/****************************************************************/
/* Random generator state */
/****************************************************************/
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
size_t seed_size )
@ -417,4 +488,10 @@ psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
}
#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
/****************************************************************/
/* The end */
/****************************************************************/
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */

View File

@ -29,20 +29,20 @@
extern "C" {
#endif
/* Include the Mbed TLS configuration file, the way Mbed TLS does it
* in each of its header files. */
#if defined(MBEDTLS_CONFIG_FILE)
#include MBEDTLS_CONFIG_FILE
#else
#include "mbedtls/config.h"
#endif
#include "psa/crypto.h"
#include <stdint.h>
#include "psa/crypto_se_driver.h"
/* Limit the maximum key size to 30kB (just in case someone tries to
* inadvertently store an obscene amount of data) */
#define PSA_CRYPTO_MAX_STORAGE_SIZE ( 30 * 1024 )
#include <stdint.h>
#include <string.h>
/* Limit the maximum key size in storage. This should have no effect
* since the key size is limited in memory. */
#define PSA_CRYPTO_MAX_STORAGE_SIZE ( PSA_BITS_TO_BYTES( PSA_MAX_KEY_BITS ) )
/* Sanity check: a file size must fit in 32 bits. Allow a generous
* 64kB of metadata. */
#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
#error PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
#endif
/** The maximum permitted persistent slot number.
*
@ -59,7 +59,7 @@ extern "C" {
* This limitation will probably become moot when we implement client
* separation for key storage.
*/
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xfffeffff
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER PSA_KEY_ID_VENDOR_MAX
/**
* \brief Checks if persistent data is stored for the given key slot number
@ -88,12 +88,11 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key );
* already occupied non-persistent key, as well as validating the key data.
*
*
* \param key Persistent identifier of the key to be stored. This
* should be an unoccupied storage location.
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
* \param[in] policy The key policy to save.
* \param[in] data Buffer containing the key data.
* \param data_length The number of bytes that make up the key data.
* \param[in] attr The attributes of the key to save.
* The key identifier field in the attributes
* determines the key's location.
* \param[in] data Buffer containing the key data.
* \param data_length The number of bytes that make up the key data.
*
* \retval PSA_SUCCESS
* \retval PSA_ERROR_INSUFFICIENT_MEMORY
@ -101,9 +100,7 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key );
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_ALREADY_EXISTS
*/
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
const psa_key_type_t type,
const psa_key_policy_t *policy,
psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr,
const uint8_t *data,
const size_t data_length );
@ -119,11 +116,10 @@ psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
* this function to zeroize and free this buffer, regardless of whether this
* function succeeds or fails.
*
* \param key Persistent identifier of the key to be loaded. This
* should be an occupied storage location.
* \param[out] type On success, the key type (a \c PSA_KEY_TYPE_XXX
* value).
* \param[out] policy On success, the key's policy.
* \param[in,out] attr On input, the key identifier field identifies
* the key to load. Other fields are ignored.
* On success, the attribute structure contains
* the key metadata that was loaded from storage.
* \param[out] data Pointer to an allocated key data buffer on return.
* \param[out] data_length The number of bytes that make up the key data.
*
@ -132,9 +128,7 @@ psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_DOES_NOT_EXIST
*/
psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
psa_key_type_t *type,
psa_key_policy_t *policy,
psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr,
uint8_t **data,
size_t *data_length );
@ -166,17 +160,15 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length );
/**
* \brief Formats key data and metadata for persistent storage
*
* \param[in] data Buffer for the key data.
* \param[in] data Buffer containing the key data.
* \param data_length Length of the key data buffer.
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
* \param policy The key policy.
* \param[in] attr The core attributes of the key.
* \param[out] storage_data Output buffer for the formatted data.
*
*/
void psa_format_key_data_for_storage( const uint8_t *data,
const size_t data_length,
const psa_key_type_t type,
const psa_key_policy_t *policy,
const psa_core_key_attributes_t *attr,
uint8_t *storage_data );
/**
@ -188,8 +180,8 @@ void psa_format_key_data_for_storage( const uint8_t *data,
* containing the key data. This must be freed
* using psa_free_persistent_key_data()
* \param[out] key_data_length Length of the key data buffer
* \param[out] type Key type (a \c PSA_KEY_TYPE_XXX value).
* \param[out] policy The key policy.
* \param[out] attr On success, the attribute structure is filled
* with the loaded key metadata.
*
* \retval PSA_SUCCESS
* \retval PSA_ERROR_INSUFFICIENT_STORAGE
@ -200,8 +192,180 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
size_t storage_data_length,
uint8_t **key_data,
size_t *key_data_length,
psa_key_type_t *type,
psa_key_policy_t *policy );
psa_core_key_attributes_t *attr );
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/** This symbol is defined if transaction support is required. */
#define PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS
#endif
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
/** The type of transaction that is in progress.
*/
/* This is an integer type rather than an enum for two reasons: to support
* unknown values when loading a transaction file, and to ensure that the
* type has a known size.
*/
typedef uint16_t psa_crypto_transaction_type_t;
/** No transaction is in progress.
*
* This has the value 0, so zero-initialization sets a transaction's type to
* this value.
*/
#define PSA_CRYPTO_TRANSACTION_NONE ( (psa_crypto_transaction_type_t) 0x0000 )
/** A key creation transaction.
*
* This is only used for keys in an external cryptoprocessor (secure element).
* Keys in RAM or in internal storage are created atomically in storage
* (simple file creation), so they do not need a transaction mechanism.
*/
#define PSA_CRYPTO_TRANSACTION_CREATE_KEY ( (psa_crypto_transaction_type_t) 0x0001 )
/** A key destruction transaction.
*
* This is only used for keys in an external cryptoprocessor (secure element).
* Keys in RAM or in internal storage are destroyed atomically in storage
* (simple file deletion), so they do not need a transaction mechanism.
*/
#define PSA_CRYPTO_TRANSACTION_DESTROY_KEY ( (psa_crypto_transaction_type_t) 0x0002 )
/** Transaction data.
*
* This type is designed to be serialized by writing the memory representation
* and reading it back on the same device.
*
* \note The transaction mechanism is designed for a single active transaction
* at a time. The transaction object is #psa_crypto_transaction.
*
* \note If an API call starts a transaction, it must complete this transaction
* before returning to the application.
*
* The lifetime of a transaction is the following (note that only one
* transaction may be active at a time):
*
* -# Call psa_crypto_prepare_transaction() to initialize the transaction
* object in memory and declare the type of transaction that is starting.
* -# Fill in the type-specific fields of #psa_crypto_transaction.
* -# Call psa_crypto_save_transaction() to start the transaction. This
* saves the transaction data to internal storage.
* -# Perform the work of the transaction by modifying files, contacting
* external entities, or whatever needs doing. Note that the transaction
* may be interrupted by a power failure, so you need to have a way
* recover from interruptions either by undoing what has been done
* so far or by resuming where you left off.
* -# If there are intermediate stages in the transaction, update
* the fields of #psa_crypto_transaction and call
* psa_crypto_save_transaction() again when each stage is reached.
* -# When the transaction is over, call psa_crypto_stop_transaction() to
* remove the transaction data in storage and in memory.
*
* If the system crashes while a transaction is in progress, psa_crypto_init()
* calls psa_crypto_load_transaction() and takes care of completing or
* rewinding the transaction. This is done in psa_crypto_recover_transaction()
* in psa_crypto.c. If you add a new type of transaction, be
* sure to add code for it in psa_crypto_recover_transaction().
*/
typedef union
{
/* Each element of this union must have the following properties
* to facilitate serialization and deserialization:
*
* - The element is a struct.
* - The first field of the struct is `psa_crypto_transaction_type_t type`.
* - Elements of the struct are arranged such a way that there is
* no padding.
*/
struct psa_crypto_transaction_unknown_s
{
psa_crypto_transaction_type_t type;
uint16_t unused1;
uint32_t unused2;
uint64_t unused3;
uint64_t unused4;
} unknown;
/* ::type is #PSA_CRYPTO_TRANSACTION_CREATE_KEY or
* #PSA_CRYPTO_TRANSACTION_DESTROY_KEY. */
struct psa_crypto_transaction_key_s
{
psa_crypto_transaction_type_t type;
uint16_t unused1;
psa_key_lifetime_t lifetime;
psa_key_slot_number_t slot;
psa_key_id_t id;
} key;
} psa_crypto_transaction_t;
/** The single active transaction.
*/
extern psa_crypto_transaction_t psa_crypto_transaction;
/** Prepare for a transaction.
*
* There must not be an ongoing transaction.
*
* \param type The type of transaction to start.
*/
static inline void psa_crypto_prepare_transaction(
psa_crypto_transaction_type_t type )
{
psa_crypto_transaction.unknown.type = type;
}
/** Save the transaction data to storage.
*
* You may call this function multiple times during a transaction to
* atomically update the transaction state.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_STORAGE_FAILURE
*/
psa_status_t psa_crypto_save_transaction( void );
/** Load the transaction data from storage, if any.
*
* This function is meant to be called from psa_crypto_init() to recover
* in case a transaction was interrupted by a system crash.
*
* \retval #PSA_SUCCESS
* The data about the ongoing transaction has been loaded to
* #psa_crypto_transaction.
* \retval #PSA_ERROR_DOES_NOT_EXIST
* There is no ongoing transaction.
* \retval #PSA_ERROR_STORAGE_FAILURE
*/
psa_status_t psa_crypto_load_transaction( void );
/** Indicate that the current transaction is finished.
*
* Call this function at the very end of transaction processing.
* This function does not "commit" or "abort" the transaction: the storage
* subsystem has no concept of "commit" and "abort", just saving and
* removing the transaction information in storage.
*
* This function erases the transaction data in storage (if any) and
* resets the transaction data in memory.
*
* \retval #PSA_SUCCESS
* There was transaction data in storage.
* \retval #PSA_ERROR_DOES_NOT_EXIST
* There was no transaction data in storage.
* \retval #PSA_ERROR_STORAGE_FAILURE
* It was impossible to determine whether there was transaction data
* in storage, or the transaction data could not be erased.
*/
psa_status_t psa_crypto_stop_transaction( void );
/** The ITS file identifier for the transaction data.
*
* 0xffffffNN = special file; 0x74 = 't' for transaction.
*/
#define PSA_CRYPTO_ITS_TRANSACTION_UID ( (psa_key_id_t) 0xffffff74 )
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
/** Backend side of mbedtls_psa_inject_entropy().

View File

@ -44,7 +44,9 @@
#include <stdio.h>
#include <string.h>
#if !defined(PSA_ITS_STORAGE_PREFIX)
#define PSA_ITS_STORAGE_PREFIX ""
#endif
#define PSA_ITS_STORAGE_FILENAME_PATTERN "%08lx%08lx"
#define PSA_ITS_STORAGE_SUFFIX ".psa_its"
@ -173,6 +175,8 @@ psa_status_t psa_its_get( psa_storage_uid_t uid,
if( n != data_length )
goto exit;
status = PSA_SUCCESS;
if( p_data_length != NULL )
*p_data_length = n;
exit:
if( stream != NULL )

Some files were not shown because too many files have changed in this diff Show More