From e59236fc17d2b404946a17d4af213c491294a81c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sat, 27 Jan 2018 23:32:46 +0100 Subject: [PATCH] Add PSA crypto module New module psa_crypto.c (MBEDTLS_PSA_CRYPTO_C): Platform Security Architecture compatibility layer on top of libmedcrypto. Implement psa_crypto_init function which sets up a RNG. Add a mbedtls_psa_crypto_free function which deinitializes the library. Define a first batch of error codes. --- include/mbedtls/check_config.h | 6 ++ include/mbedtls/config.h | 14 ++- include/psa/crypto.h | 90 +++++++++++++++++++ include/psa/crypto_extra.h | 46 ++++++++++ include/psa/crypto_platform.h | 39 +++++++++ library/CMakeLists.txt | 1 + library/Makefile | 1 + library/psa_crypto.c | 97 +++++++++++++++++++++ library/version_features.c | 3 + tests/suites/test_suite_psa_crypto.data | 2 + tests/suites/test_suite_psa_crypto.function | 24 +++++ visualc/VS2010/mbedTLS.vcxproj | 4 + 12 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 include/psa/crypto.h create mode 100644 include/psa/crypto_extra.h create mode 100644 include/psa/crypto_platform.h create mode 100644 library/psa_crypto.c create mode 100644 tests/suites/test_suite_psa_crypto.data create mode 100644 tests/suites/test_suite_psa_crypto.function diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 9e6bb8a46..41c3f2458 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -486,6 +486,12 @@ #error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" #endif +#if defined(MBEDTLS_PSA_CRYPTO_C) && \ + !( defined(MBEDTLS_CTR_DRBG_C) && \ + defined(MBEDTLS_ENTROPY_C) ) +#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ !defined(MBEDTLS_OID_C) ) #error "MBEDTLS_RSA_C defined, but not all prerequisites" diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 052aed0d3..dc112a91d 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -2013,7 +2013,7 @@ * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C * */ -//#define MBEDTLS_CMAC_C +#define MBEDTLS_CMAC_C /** * \def MBEDTLS_CTR_DRBG_C @@ -2555,6 +2555,18 @@ */ #define MBEDTLS_POLY1305_C +/** +* \def MBEDTLS_PSA_CRYPTO_C + * + * Enable the Platform Security Architecture cryptography API. + * + * Module: library/psa_crypto.c + * + * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C + * + */ +#define MBEDTLS_PSA_CRYPTO_C + /** * \def MBEDTLS_RIPEMD160_C * diff --git a/include/psa/crypto.h b/include/psa/crypto.h new file mode 100644 index 000000000..fc299af39 --- /dev/null +++ b/include/psa/crypto.h @@ -0,0 +1,90 @@ +/** + * \file psa/crypto.h + * \brief Platform Security Architecture cryptography module + */ + +#ifndef PSA_CRYPTO_H +#define PSA_CRYPTO_H + +#include "crypto_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup basic Basic definitions + * @{ + */ + +/** + * \brief Function return status. + * + * Zero indicates success, anything else indicates an error. + */ +typedef enum { + /** The action was completed successfully. */ + PSA_SUCCESS = 0, + /** The requested operation or a parameter is not supported + by this implementation. */ + PSA_ERROR_NOT_SUPPORTED, + /** The requested action is denied by a policy. */ + PSA_ERROR_NOT_PERMITTED, + /** An output buffer is too small. */ + PSA_ERROR_BUFFER_TOO_SMALL, + /** A slot is occupied, but must be empty to carry out the + requested action. */ + PSA_ERROR_OCCUPIED_SLOT, + /** A slot is empty, but must be occupied to carry out the + requested action. */ + PSA_ERROR_EMPTY_SLOT, + /** The requested action cannot be performed in the current state. */ + PSA_ERROR_BAD_STATE, + /** The parameters passed to the function are invalid. */ + PSA_ERROR_INVALID_ARGUMENT, + /** There is not enough runtime memory. */ + PSA_ERROR_INSUFFICIENT_MEMORY, + /** There is not enough persistent storage. */ + PSA_ERROR_INSUFFICIENT_STORAGE, + /** There was a communication failure inside the implementation. */ + PSA_ERROR_COMMUNICATION_FAILURE, + /** A hardware failure was detected. */ + PSA_ERROR_HARDWARE_FAILURE, + /** A tampering attempt was detected. */ + PSA_ERROR_TAMPERING_DETECTED, + /** There is not enough entropy to generate random data needed + for the requested action. */ + PSA_ERROR_INSUFFICIENT_ENTROPY, + /** The signature or MAC is incorrect. */ + PSA_ERROR_INVALID_SIGNATURE, + /** An error occurred that does not correspond to any defined + failure cause. */ + PSA_ERROR_UNKNOWN_ERROR, +} psa_status_t; + +/** + * \brief Library initialization. + * + * Applications must call this function before calling any other + * function in this module. + * + * Applications may call this function more than once. Once a call + * succeeds, subsequent calls are guaranteed to succeed. + * + * \return * \c PSA_SUCCESS: success. + * * \c PSA_ERROR_INSUFFICIENT_MEMORY + * * \c PSA_ERROR_COMMUNICATION_FAILURE + * * \c PSA_ERROR_HARDWARE_FAILURE + * * \c PSA_ERROR_TAMPERING_DETECTED + * * \c PSA_ERROR_INSUFFICIENT_ENTROPY + */ +psa_status_t psa_crypto_init(void); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#include "crypto_extra.h" + +#endif /* PSA_CRYPTO_H */ diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h new file mode 100644 index 000000000..b9e12bb6f --- /dev/null +++ b/include/psa/crypto_extra.h @@ -0,0 +1,46 @@ +/** + * \file psa/crypto_extra.h + * + * \brief PSA cryptography module: Mbed TLS vendor extensions + */ +/* + * Copyright (C) 2018, 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_EXTRA_H +#define PSA_CRYPTO_EXTRA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Library deinitialization. + * + * This function clears all data associated with the PSA layer, + * including the whole key store. + * + * This is an Mbed TLS extension. + */ +void mbedtls_psa_crypto_free( void ); + +#ifdef __cplusplus +} +#endif + +#endif /* PSA_CRYPTO_EXTRA_H */ diff --git a/include/psa/crypto_platform.h b/include/psa/crypto_platform.h new file mode 100644 index 000000000..eafc0b3ea --- /dev/null +++ b/include/psa/crypto_platform.h @@ -0,0 +1,39 @@ +/** + * \file psa/crypto_platform.h + * + * \brief PSA cryptography module: Mbed TLS platfom definitions + */ +/* + * Copyright (C) 2018, 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_PLATFORM_H +#define PSA_CRYPTO_PLATFORM_H + +/* 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.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +/* PSA requires several types which C99 provides in stdint.h. */ +#include + +#endif /* PSA_CRYPTO_PLATFORM_H */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 6a280fe70..07811f9d0 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -53,6 +53,7 @@ set(src_crypto platform.c platform_util.c poly1305.c + psa_crypto.c ripemd160.c rsa.c rsa_internal.c diff --git a/library/Makefile b/library/Makefile index 430c59881..f4b39bdeb 100644 --- a/library/Makefile +++ b/library/Makefile @@ -81,6 +81,7 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \ pk.o pk_wrap.o pkcs12.o \ pkcs5.o pkparse.o pkwrite.o \ platform.o platform_util.o poly1305.o \ + psa_crypto.o \ ripemd160.o rsa_internal.o rsa.o \ sha1.o sha256.o sha512.o \ threading.o timing.o version.o \ diff --git a/library/psa_crypto.c b/library/psa_crypto.c new file mode 100644 index 000000000..ca25bb487 --- /dev/null +++ b/library/psa_crypto.c @@ -0,0 +1,97 @@ +/* + * PSA crypto layer on top of Mbed TLS crypto + */ +/* Copyright (C) 2018, 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_C) + +#include "psa/crypto.h" + +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/entropy.h" + + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) +{ + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +typedef struct { + int initialized; + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; +} psa_global_data_t; + +static psa_global_data_t global_data; + +static psa_status_t mbedtls_to_psa_error( int ret ) +{ + switch( ret ) + { + case 0: + return( PSA_SUCCESS ); + case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED: + case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE: + case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED: + return( PSA_ERROR_INSUFFICIENT_ENTROPY ); + default: + return( PSA_ERROR_UNKNOWN_ERROR ); + } +} + +void mbedtls_psa_crypto_free( void ) +{ + mbedtls_ctr_drbg_free( &global_data.ctr_drbg ); + mbedtls_entropy_free( &global_data.entropy ); + mbedtls_zeroize( &global_data, sizeof( global_data ) ); +} + +psa_status_t psa_crypto_init( void ) +{ + int ret; + const unsigned char drbg_seed[] = "PSA"; + + if( global_data.initialized != 0 ) + return( PSA_SUCCESS ); + + mbedtls_zeroize( &global_data, sizeof( global_data ) ); + mbedtls_entropy_init( &global_data.entropy ); + mbedtls_ctr_drbg_init( &global_data.ctr_drbg ); + + ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg, + mbedtls_entropy_func, + &global_data.entropy, + drbg_seed, sizeof( drbg_seed ) - 1 ); + if( ret != 0 ) + goto exit; + +exit: + if( ret != 0 ) + mbedtls_psa_crypto_free( ); + return( mbedtls_to_psa_error( ret ) ); +} + +#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/version_features.c b/library/version_features.c index 777b6034c..b77bf2658 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -678,6 +678,9 @@ static const char *features[] = { #if defined(MBEDTLS_POLY1305_C) "MBEDTLS_POLY1305_C", #endif /* MBEDTLS_POLY1305_C */ +#if defined(MBEDTLS_PSA_CRYPTO_C) + "MBEDTLS_PSA_CRYPTO_C", +#endif /* MBEDTLS_PSA_CRYPTO_C */ #if defined(MBEDTLS_RIPEMD160_C) "MBEDTLS_RIPEMD160_C", #endif /* MBEDTLS_RIPEMD160_C */ diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data new file mode 100644 index 000000000..3d7689bd2 --- /dev/null +++ b/tests/suites/test_suite_psa_crypto.data @@ -0,0 +1,2 @@ +PSA init/deinit +init_deinit: diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function new file mode 100644 index 000000000..9d9eee47b --- /dev/null +++ b/tests/suites/test_suite_psa_crypto.function @@ -0,0 +1,24 @@ +/* BEGIN_HEADER */ +#include "psa/crypto.h" +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_PSA_CRYPTO_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void init_deinit() +{ + psa_status_t ret; + int i; + for( i = 0; i <= 1; i++ ) + { + ret = psa_crypto_init( ); + TEST_ASSERT( ret == PSA_SUCCESS ); + ret = psa_crypto_init( ); + TEST_ASSERT( ret == PSA_SUCCESS ); + mbedtls_psa_crypto_free( ); + } +} +/* END_CASE */ diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 73c92bda5..2c569e52d 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -224,6 +224,9 @@ + + + @@ -281,6 +284,7 @@ +