Merge pull request #3501 from stevew817/feature/transparent_drivers_trial

Add partial implementation of accelerator API defined in #3493
This commit is contained in:
Gilles Peskine 2020-09-07 18:02:03 +02:00 committed by GitHub
commit 1ffec8f68f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1336 additions and 69 deletions

View File

@ -261,7 +261,7 @@ add_subdirectory(library)
# to define the test executables.
#
if(ENABLE_TESTING OR ENABLE_PROGRAMS)
file(GLOB MBEDTLS_TEST_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/*.c)
file(GLOB MBEDTLS_TEST_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/*.c ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/drivers/*.c)
add_library(mbedtls_test OBJECT ${MBEDTLS_TEST_FILES})
target_include_directories(mbedtls_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests/include

View File

@ -0,0 +1,4 @@
Features
* Partial implementation of the new PSA Crypto accelerator APIs for
enabling key generation and asymmetric signing/verification through crypto
accelerators. Contributed by Steven Cooreman in #3501.

View File

@ -1329,6 +1329,17 @@
*/
#define MBEDTLS_PKCS1_V21
/** \def MBEDTLS_PSA_CRYPTO_DRIVERS
*
* Enable support for the experimental PSA crypto driver interface.
*
* Requires: MBEDTLS_PSA_CRYPTO_C.
*
* \warning This interface is experimental and may change or be removed
* without notice.
*/
//#define MBEDTLS_PSA_CRYPTO_DRIVERS
/**
* \def MBEDTLS_PSA_CRYPTO_SPM
*

View File

@ -61,6 +61,7 @@ set(src_crypto
platform_util.c
poly1305.c
psa_crypto.c
psa_crypto_driver_wrappers.c
psa_crypto_se.c
psa_crypto_slot_management.c
psa_crypto_storage.c

View File

@ -118,6 +118,7 @@ OBJS_CRYPTO= \
platform_util.o \
poly1305.o \
psa_crypto.o \
psa_crypto_driver_wrappers.o \
psa_crypto_se.o \
psa_crypto_slot_management.o \
psa_crypto_storage.o \

View File

@ -27,6 +27,7 @@
#include "psa_crypto_core.h"
#include "psa_crypto_invasive.h"
#include "psa_crypto_driver_wrappers.h"
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
#include "psa_crypto_se.h"
#endif
@ -124,7 +125,7 @@ static psa_global_data_t global_data;
if( global_data.initialized == 0 ) \
return( PSA_ERROR_BAD_STATE );
static psa_status_t mbedtls_to_psa_error( int ret )
psa_status_t mbedtls_to_psa_error( int ret )
{
/* If there's both a high-level code and low-level code, dispatch on
* the high-level code. */
@ -3637,10 +3638,6 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle,
{
psa_key_slot_t *slot;
psa_status_t status;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
*signature_length = signature_size;
/* Immediately reject a zero-length signature buffer. This guarantees
@ -3659,24 +3656,19 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle,
goto exit;
}
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
{
if( drv->asymmetric == NULL ||
drv->asymmetric->p_sign == NULL )
{
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
status = drv->asymmetric->p_sign( drv_context,
slot->data.se.slot_number,
alg,
hash, hash_length,
signature, signature_size,
signature_length );
}
else
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
/* Try any of the available accelerators first */
status = psa_driver_wrapper_sign_hash( slot,
alg,
hash,
hash_length,
signature,
signature_size,
signature_length );
if( status != PSA_ERROR_NOT_SUPPORTED ||
psa_key_lifetime_is_external( slot->attr.lifetime ) )
goto exit;
/* If the operation was not supported by any accelerator, try fallback. */
#if defined(MBEDTLS_RSA_C)
if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
{
@ -3763,29 +3755,22 @@ psa_status_t psa_verify_hash( psa_key_handle_t handle,
{
psa_key_slot_t *slot;
psa_status_t status;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY_HASH, alg );
if( status != PSA_SUCCESS )
return( status );
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
{
if( drv->asymmetric == NULL ||
drv->asymmetric->p_verify == NULL )
return( PSA_ERROR_NOT_SUPPORTED );
return( drv->asymmetric->p_verify( drv_context,
slot->data.se.slot_number,
alg,
hash, hash_length,
signature, signature_length ) );
}
else
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
/* Try any of the available accelerators first */
status = psa_driver_wrapper_verify_hash( slot,
alg,
hash,
hash_length,
signature,
signature_length );
if( status != PSA_ERROR_NOT_SUPPORTED ||
psa_key_lifetime_is_external( slot->attr.lifetime ) )
return status;
#if defined(MBEDTLS_RSA_C)
if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
{
@ -6004,29 +5989,15 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
if( status != PSA_SUCCESS )
goto exit;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if( driver != NULL )
{
const psa_drv_se_t *drv = psa_get_se_driver_methods( driver );
size_t pubkey_length = 0; /* We don't support this feature yet */
if( drv->key_management == NULL ||
drv->key_management->p_generate == NULL )
{
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
status = drv->key_management->p_generate(
psa_get_se_driver_context( driver ),
slot->data.se.slot_number, attributes,
NULL, 0, &pubkey_length );
}
else
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
{
status = psa_generate_key_internal(
slot, attributes->core.bits,
attributes->domain_parameters, attributes->domain_parameters_size );
}
status = psa_driver_wrapper_generate_key( attributes,
slot );
if( status != PSA_ERROR_NOT_SUPPORTED ||
psa_key_lifetime_is_external( attributes->core.lifetime ) )
goto exit;
status = psa_generate_key_internal(
slot, attributes->core.bits,
attributes->domain_parameters, attributes->domain_parameters_size );
exit:
if( status == PSA_SUCCESS )

View File

@ -161,4 +161,16 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
const uint8_t *data,
size_t data_length );
/** Convert an mbed TLS error code to a PSA error code
*
* \note This function is provided solely for the convenience of
* Mbed TLS and may be removed at any time without notice.
*
* \param ret An mbed TLS-thrown error code
*
* \return The corresponding PSA error code
*/
psa_status_t mbedtls_to_psa_error( int ret );
#endif /* PSA_CRYPTO_CORE_H */

View File

@ -0,0 +1,373 @@
/*
* Functions to delegate cryptographic operations to an available
* and appropriate accelerator.
* Warning: This file will be auto-generated in the future.
*/
/* Copyright The Mbed TLS Contributors
* 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.
*/
#include "psa_crypto_core.h"
#include "psa_crypto_driver_wrappers.h"
#include "mbedtls/platform.h"
#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
/* Include test driver definition when running tests */
#if defined(PSA_CRYPTO_DRIVER_TEST)
#ifndef PSA_CRYPTO_DRIVER_PRESENT
#define PSA_CRYPTO_DRIVER_PRESENT
#endif
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif
#include "test/drivers/test_driver.h"
#endif /* PSA_CRYPTO_DRIVER_TEST */
/* Repeat above block for each JSON-declared driver during autogeneration */
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
/* Support the 'old' SE interface when asked to */
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style
* SE driver is present, to avoid unused argument errors at compile time. */
#ifndef PSA_CRYPTO_DRIVER_PRESENT
#define PSA_CRYPTO_DRIVER_PRESENT
#endif
#include "psa_crypto_se.h"
#endif
/* Start delegation functions */
psa_status_t psa_driver_wrapper_sign_hash( psa_key_slot_t *slot,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length )
{
#if defined(PSA_CRYPTO_DRIVER_PRESENT)
/* Try dynamically-registered SE interface first */
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
{
if( drv->asymmetric == NULL ||
drv->asymmetric->p_sign == NULL )
{
/* Key is defined in SE, but we have no way to exercise it */
return( PSA_ERROR_NOT_SUPPORTED );
}
return( drv->asymmetric->p_sign( drv_context,
slot->data.se.slot_number,
alg,
hash, hash_length,
signature, signature_size,
signature_length ) );
}
#endif /* PSA_CRYPTO_SE_C */
/* Then try accelerator API */
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime);
psa_key_attributes_t attributes = {
.core = slot->attr
};
switch( location )
{
case PSA_KEY_LOCATION_LOCAL_STORAGE:
/* Key is stored in the slot in export representation, so
* cycle through all known transparent accelerators */
#if defined(PSA_CRYPTO_DRIVER_TEST)
status = test_transparent_signature_sign_hash( &attributes,
slot->data.key.data,
slot->data.key.bytes,
alg,
hash,
hash_length,
signature,
signature_size,
signature_length );
/* Declared with fallback == true */
if( status != PSA_ERROR_NOT_SUPPORTED )
return( status );
#endif /* PSA_CRYPTO_DRIVER_TEST */
/* Fell through, meaning no accelerator supports this operation */
return( PSA_ERROR_NOT_SUPPORTED );
/* Add cases for opaque driver here */
#if defined(PSA_CRYPTO_DRIVER_TEST)
case PSA_CRYPTO_TEST_DRIVER_LIFETIME:
return( test_opaque_signature_sign_hash( &attributes,
slot->data.key.data,
slot->data.key.bytes,
alg,
hash,
hash_length,
signature,
signature_size,
signature_length ) );
#endif /* PSA_CRYPTO_DRIVER_TEST */
default:
/* Key is declared with a lifetime not known to us */
return( status );
}
#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
#else /* PSA_CRYPTO_DRIVER_PRESENT */
(void)slot;
(void)alg;
(void)hash;
(void)hash_length;
(void)signature;
(void)signature_size;
(void)signature_length;
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
}
psa_status_t psa_driver_wrapper_verify_hash( psa_key_slot_t *slot,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length )
{
#if defined(PSA_CRYPTO_DRIVER_PRESENT)
/* Try dynamically-registered SE interface first */
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
{
if( drv->asymmetric == NULL ||
drv->asymmetric->p_verify == NULL )
{
/* Key is defined in SE, but we have no way to exercise it */
return( PSA_ERROR_NOT_SUPPORTED );
}
return( drv->asymmetric->p_verify( drv_context,
slot->data.se.slot_number,
alg,
hash, hash_length,
signature, signature_length ) );
}
#endif /* PSA_CRYPTO_SE_C */
/* Then try accelerator API */
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime);
psa_key_attributes_t attributes = {
.core = slot->attr
};
switch( location )
{
case PSA_KEY_LOCATION_LOCAL_STORAGE:
/* Key is stored in the slot in export representation, so
* cycle through all known transparent accelerators */
#if defined(PSA_CRYPTO_DRIVER_TEST)
status = test_transparent_signature_verify_hash( &attributes,
slot->data.key.data,
slot->data.key.bytes,
alg,
hash,
hash_length,
signature,
signature_length );
/* Declared with fallback == true */
if( status != PSA_ERROR_NOT_SUPPORTED )
return( status );
#endif /* PSA_CRYPTO_DRIVER_TEST */
/* Fell through, meaning no accelerator supports this operation */
return( PSA_ERROR_NOT_SUPPORTED );
/* Add cases for opaque driver here */
#if defined(PSA_CRYPTO_DRIVER_TEST)
case PSA_CRYPTO_TEST_DRIVER_LIFETIME:
return( test_opaque_signature_verify_hash( &attributes,
slot->data.key.data,
slot->data.key.bytes,
alg,
hash,
hash_length,
signature,
signature_length ) );
#endif /* PSA_CRYPTO_DRIVER_TEST */
default:
/* Key is declared with a lifetime not known to us */
return( status );
}
#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
#else /* PSA_CRYPTO_DRIVER_PRESENT */
(void)slot;
(void)alg;
(void)hash;
(void)hash_length;
(void)signature;
(void)signature_length;
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
}
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
/** Calculate the size to allocate for buffering a key with given attributes.
*
* This function provides a way to get the expected size for storing a key with
* the given attributes. This will be the size of the export representation for
* cleartext keys, and a driver-defined size for keys stored by opaque drivers.
*
* \param[in] attributes The key attribute structure of the key to store.
* \param[out] expected_size On success, a byte size large enough to contain
* the declared key.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_NOT_SUPPORTED
*/
static psa_status_t get_expected_key_size( const psa_key_attributes_t *attributes,
size_t *expected_size )
{
size_t buffer_size = 0;
if( PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ) == PSA_KEY_LOCATION_LOCAL_STORAGE )
{
buffer_size = PSA_KEY_EXPORT_MAX_SIZE( attributes->core.type,
attributes->core.bits );
if( buffer_size == 0 )
return( PSA_ERROR_NOT_SUPPORTED );
*expected_size = buffer_size;
return( PSA_SUCCESS );
}
else
{
/* TBD: opaque driver support: need to calculate size through a
* driver-defined size function, since the size of an opaque (wrapped)
* key will be different for each implementation. */
return( PSA_ERROR_NOT_SUPPORTED );
}
}
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes,
psa_key_slot_t *slot )
{
#if defined(PSA_CRYPTO_DRIVER_PRESENT)
/* Try dynamically-registered SE interface first */
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
{
size_t pubkey_length = 0; /* We don't support this feature yet */
if( drv->key_management == NULL ||
drv->key_management->p_generate == NULL )
{
/* Key is defined as being in SE, but we have no way to generate it */
return( PSA_ERROR_NOT_SUPPORTED );
}
return( drv->key_management->p_generate(
drv_context,
slot->data.se.slot_number, attributes,
NULL, 0, &pubkey_length ) );
}
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
/* Then try accelerator API */
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime);
size_t export_size = 0;
status = get_expected_key_size( attributes, &export_size );
if( status != PSA_SUCCESS )
return( status );
slot->data.key.data = mbedtls_calloc(1, export_size);
if( slot->data.key.data == NULL )
return( PSA_ERROR_INSUFFICIENT_MEMORY );
slot->data.key.bytes = export_size;
switch( location )
{
case PSA_KEY_LOCATION_LOCAL_STORAGE:
/* Key is stored in the slot in export representation, so
* cycle through all known transparent accelerators */
/* Transparent drivers are limited to generating asymmetric keys */
if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
{
status = PSA_ERROR_NOT_SUPPORTED;
break;
}
#if defined(PSA_CRYPTO_DRIVER_TEST)
status = test_transparent_generate_key( attributes,
slot->data.key.data,
slot->data.key.bytes,
&slot->data.key.bytes );
/* Declared with fallback == true */
if( status != PSA_ERROR_NOT_SUPPORTED )
break;
#endif /* PSA_CRYPTO_DRIVER_TEST */
/* Fell through, meaning no accelerator supports this operation */
status = PSA_ERROR_NOT_SUPPORTED;
break;
/* Add cases for opaque driver here */
#if defined(PSA_CRYPTO_DRIVER_TEST)
case PSA_CRYPTO_TEST_DRIVER_LIFETIME:
status = test_opaque_generate_key( attributes,
slot->data.key.data,
slot->data.key.bytes,
&slot->data.key.bytes );
break;
#endif /* PSA_CRYPTO_DRIVER_TEST */
default:
/* Key is declared with a lifetime not known to us */
status = PSA_ERROR_INVALID_ARGUMENT;
break;
}
if( status != PSA_SUCCESS )
{
/* free allocated buffer */
mbedtls_free( slot->data.key.data );
slot->data.key.data = NULL;
slot->data.key.bytes = 0;
}
return( status );
#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
#else /* PSA_CRYPTO_DRIVER_PRESENT */
(void) attributes;
(void) slot;
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
}
/* End of automatically generated file. */

View File

@ -0,0 +1,48 @@
/*
* Function signatures for functionality that can be provided by
* cryptographic accelerators.
* Warning: This file will be auto-generated in the future.
*/
/* Copyright The Mbed TLS Contributors
* 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.
*/
#ifndef PSA_CRYPTO_DRIVER_WRAPPERS_H
#define PSA_CRYPTO_DRIVER_WRAPPERS_H
#include "psa/crypto.h"
#include "psa/crypto_driver_common.h"
psa_status_t psa_driver_wrapper_sign_hash( psa_key_slot_t *slot,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length );
psa_status_t psa_driver_wrapper_verify_hash( psa_key_slot_t *slot,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length );
psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes,
psa_key_slot_t *slot );
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */
/* End of automatically generated file. */

View File

@ -435,6 +435,9 @@ static const char * const features[] = {
#if defined(MBEDTLS_PKCS1_V21)
"MBEDTLS_PKCS1_V21",
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
"MBEDTLS_PSA_CRYPTO_DRIVERS",
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
"MBEDTLS_PSA_CRYPTO_SPM",
#endif /* MBEDTLS_PSA_CRYPTO_SPM */

View File

@ -8,7 +8,7 @@ WARNING_CXXFLAGS ?= -Wall -Wextra
LDFLAGS ?=
MBEDTLS_TEST_PATH:=../tests/src
MBEDTLS_TEST_OBJS:=$(patsubst %.c,%.o,$(wildcard ${MBEDTLS_TEST_PATH}/*.c))
MBEDTLS_TEST_OBJS:=$(patsubst %.c,%.o,$(wildcard ${MBEDTLS_TEST_PATH}/*.c ${MBEDTLS_TEST_PATH}/drivers/*.c))
LOCAL_CFLAGS = $(WARNING_CFLAGS) -I../tests/include -I../include -D_FILE_OFFSET_BITS=64
LOCAL_CXXFLAGS = $(WARNING_CXXFLAGS) -I../include -D_FILE_OFFSET_BITS=64

View File

@ -1,5 +1,5 @@
MBEDTLS_TEST_PATH:=../../tests/src
MBEDTLS_TEST_OBJS:=$(patsubst %.c,%.o,$(wildcard ${MBEDTLS_TEST_PATH}/*.c))
MBEDTLS_TEST_OBJS:=$(patsubst %.c,%.o,$(wildcard ${MBEDTLS_TEST_PATH}/*.c ${MBEDTLS_TEST_PATH}/drivers/*.c))
LOCAL_CFLAGS = -I../../tests/include -I../../include -D_FILE_OFFSET_BITS=64
LOCAL_LDFLAGS = ${MBEDTLS_TEST_OBJS} \

View File

@ -1216,6 +1216,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
if( strcmp( "MBEDTLS_PSA_CRYPTO_DRIVERS", config ) == 0 )
{
MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_CRYPTO_DRIVERS );
return( 0 );
}
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
if( strcmp( "MBEDTLS_PSA_CRYPTO_SPM", config ) == 0 )
{

View File

@ -39,6 +39,7 @@ my $psa_header_dir = 'include/psa';
my $source_dir = 'library';
my $test_source_dir = 'tests/src';
my $test_header_dir = 'tests/include/test';
my $test_drivers_header_dir = 'tests/include/test/drivers';
my @thirdparty_header_dirs = qw(
3rdparty/everest/include/everest
@ -116,6 +117,7 @@ sub check_dirs {
&& -d $source_dir
&& -d $test_source_dir
&& -d $test_header_dir
&& -d $test_drivers_header_dir
&& -d $programs_dir;
}
@ -262,6 +264,7 @@ sub main {
$mbedtls_header_dir,
$psa_header_dir,
$test_header_dir,
$test_drivers_header_dir,
$source_dir,
@thirdparty_header_dirs,
);

1
tests/.gitignore vendored
View File

@ -11,4 +11,5 @@ data_files/entropy_seed
include/test/instrument_record_status.h
src/*.o
src/drivers/*.o
src/libmbed*

View File

@ -80,7 +80,7 @@ all: $(BINARIES)
$(MBEDLIBS):
$(MAKE) -C ../library
MBEDTLS_TEST_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c))
MBEDTLS_TEST_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c src/drivers/*.c))
mbedtls_test: $(MBEDTLS_TEST_OBJS)
@ -89,6 +89,10 @@ src/%.o : src/%.c
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $<
src/drivers/%.o : src/drivers/%.c
echo " CC $<"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $<
C_FILES := $(addsuffix .c,$(APPS))
# Wildcard target for test code generation:
@ -130,12 +134,13 @@ $(addprefix embedded_,$(filter test_suite_psa_%, $(APPS))): embedded_%: TESTS/mb
clean:
ifndef WINDOWS
rm -rf $(BINARIES) *.c *.datax TESTS
rm -f src/*.o src/libmbed*
rm -f src/*.o src/drivers/*.o src/libmbed*
else
if exist *.c del /Q /F *.c
if exist *.exe del /Q /F *.exe
if exist *.datax del /Q /F *.datax
if exist src/*.o del /Q /F src/*.o
if exist src/drivers/*.o del /Q /F src/drivers/*.o
if exist src/libmbed* del /Q /F src/libmed*
ifneq ($(wildcard TESTS/.*),)
rmdir /Q /S TESTS

View File

@ -0,0 +1,61 @@
/*
* Test driver for generating keys.
*/
/* Copyright The Mbed TLS Contributors
* 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.
*/
#ifndef PSA_CRYPTO_TEST_DRIVERS_KEYGEN_H
#define PSA_CRYPTO_TEST_DRIVERS_KEYGEN_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(PSA_CRYPTO_DRIVER_TEST)
#include <psa/crypto_driver_common.h>
typedef struct {
/* If non-null, on success, copy this to the output. */
void *forced_output;
size_t forced_output_length;
/* If not PSA_SUCCESS, return this error code instead of processing the
* function call. */
psa_status_t forced_status;
/* Count the amount of times one of the keygen driver functions is called. */
unsigned long hits;
} test_driver_keygen_hooks_t;
#define TEST_DRIVER_KEYGEN_INIT { NULL, 0, PSA_ERROR_NOT_SUPPORTED, 0 }
static inline test_driver_keygen_hooks_t test_driver_keygen_hooks_init( void )
{
const test_driver_keygen_hooks_t v = TEST_DRIVER_KEYGEN_INIT;
return( v );
}
extern test_driver_keygen_hooks_t test_driver_keygen_hooks;
psa_status_t test_transparent_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key, size_t key_size, size_t *key_length );
psa_status_t test_opaque_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key, size_t key_size, size_t *key_length );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_TEST_DRIVERS_KEYGEN_H */

View File

@ -0,0 +1,82 @@
/*
* Test driver for signature functions.
*/
/* Copyright The Mbed TLS Contributors
* 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.
*/
#ifndef PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H
#define PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(PSA_CRYPTO_DRIVER_TEST)
#include <psa/crypto_driver_common.h>
typedef struct {
/* If non-null, on success, copy this to the output. */
void *forced_output;
size_t forced_output_length;
/* If not PSA_SUCCESS, return this error code instead of processing the
* function call. */
psa_status_t forced_status;
/* Count the amount of times one of the keygen driver functions is called. */
unsigned long hits;
} test_driver_signature_hooks_t;
#define TEST_DRIVER_SIGNATURE_INIT { NULL, 0, PSA_ERROR_NOT_SUPPORTED, 0 }
static inline test_driver_signature_hooks_t test_driver_signature_hooks_init( void )
{
const test_driver_signature_hooks_t v = TEST_DRIVER_SIGNATURE_INIT;
return( v );
}
extern test_driver_signature_hooks_t test_driver_signature_sign_hooks;
extern test_driver_signature_hooks_t test_driver_signature_verify_hooks;
psa_status_t test_transparent_signature_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
uint8_t *signature, size_t signature_size, size_t *signature_length );
psa_status_t test_opaque_signature_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
uint8_t *signature, size_t signature_size, size_t *signature_length );
psa_status_t test_transparent_signature_verify_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length );
psa_status_t test_opaque_signature_verify_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#endif /* PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H */

View File

@ -0,0 +1,28 @@
/*
* Umbrella include for all of the test driver functionality
*/
/* Copyright The Mbed TLS Contributors
* 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.
*/
#ifndef PSA_CRYPTO_TEST_DRIVER_H
#define PSA_CRYPTO_TEST_DRIVER_H
#define PSA_CRYPTO_TEST_DRIVER_LIFETIME 0x7fffff
#include "test/drivers/signature.h"
#include "test/drivers/keygen.h"
#endif /* PSA_CRYPTO_TEST_DRIVER_H */

View File

@ -1656,6 +1656,16 @@ component_test_se_default () {
make test
}
component_test_psa_crypto_drivers () {
msg "build: MBEDTLS_PSA_CRYPTO_DRIVERS w/ driver hooks"
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
# Need to define the correct symbol and include the test driver header path in order to build with the test driver
make CC=gcc CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -I../tests/include -O2" LDFLAGS="$ASAN_CFLAGS"
msg "test: MBEDTLS_PSA_CRYPTO_DRIVERS, signature"
make test
}
component_test_make_shared () {
msg "build/test: make shared" # ~ 40s
make SHARED=1 all check

125
tests/src/drivers/keygen.c Normal file
View File

@ -0,0 +1,125 @@
/*
* Test driver for generating keys.
* Currently only supports generating ECC keys.
*/
/* Copyright The Mbed TLS Contributors
* 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.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
#include "psa/crypto.h"
#include "psa_crypto_core.h"
#include "mbedtls/ecp.h"
#include "mbedtls/error.h"
#include "test/drivers/keygen.h"
#include "test/random.h"
#include <string.h>
test_driver_keygen_hooks_t test_driver_keygen_hooks = TEST_DRIVER_KEYGEN_INIT;
psa_status_t test_transparent_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key, size_t key_size, size_t *key_length )
{
++test_driver_keygen_hooks.hits;
if( test_driver_keygen_hooks.forced_status != PSA_SUCCESS )
return( test_driver_keygen_hooks.forced_status );
if( test_driver_keygen_hooks.forced_output != NULL )
{
if( test_driver_keygen_hooks.forced_output_length > key_size )
return( PSA_ERROR_BUFFER_TOO_SMALL );
memcpy( key, test_driver_keygen_hooks.forced_output,
test_driver_keygen_hooks.forced_output_length );
*key_length = test_driver_keygen_hooks.forced_output_length;
return( PSA_SUCCESS );
}
/* Copied from psa_crypto.c */
#if defined(MBEDTLS_ECP_C)
if ( PSA_KEY_TYPE_IS_ECC( psa_get_key_type( attributes ) )
&& PSA_KEY_TYPE_IS_KEY_PAIR( psa_get_key_type( attributes ) ) )
{
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( psa_get_key_type( attributes ) );
mbedtls_ecp_group_id grp_id =
mbedtls_ecc_group_of_psa( curve, PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) ) );
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_grp_id( grp_id );
mbedtls_ecp_keypair ecp;
mbedtls_test_rnd_pseudo_info rnd_info;
memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( attributes->domain_parameters_size != 0 )
return( PSA_ERROR_NOT_SUPPORTED );
if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
return( PSA_ERROR_NOT_SUPPORTED );
if( curve_info->bit_size != psa_get_key_bits( attributes ) )
return( PSA_ERROR_INVALID_ARGUMENT );
mbedtls_ecp_keypair_init( &ecp );
ret = mbedtls_ecp_gen_key( grp_id, &ecp,
&mbedtls_test_rnd_pseudo_rand,
&rnd_info );
if( ret != 0 )
{
mbedtls_ecp_keypair_free( &ecp );
return( mbedtls_to_psa_error( ret ) );
}
/* Make sure to use export representation */
size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) );
if( key_size < bytes )
{
mbedtls_ecp_keypair_free( &ecp );
return( PSA_ERROR_BUFFER_TOO_SMALL );
}
psa_status_t status = mbedtls_to_psa_error(
mbedtls_mpi_write_binary( &ecp.d, key, bytes ) );
if( status == PSA_SUCCESS )
{
*key_length = bytes;
}
mbedtls_ecp_keypair_free( &ecp );
return( status );
}
else
#endif /* MBEDTLS_ECP_C */
return( PSA_ERROR_NOT_SUPPORTED );
}
psa_status_t test_opaque_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key, size_t key_size, size_t *key_length )
{
(void) attributes;
(void) key;
(void) key_size;
(void) key_length;
return( PSA_ERROR_NOT_SUPPORTED );
}
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */

View File

@ -0,0 +1,289 @@
/*
* Test driver for signature functions.
* Currently supports signing and verifying precalculated hashes, using
* only deterministic ECDSA on curves secp256r1, secp384r1 and secp521r1.
*/
/* Copyright The Mbed TLS Contributors
* 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.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
#include "psa/crypto.h"
#include "psa_crypto_core.h"
#include "mbedtls/ecp.h"
#include "test/drivers/signature.h"
#include "mbedtls/md.h"
#include "mbedtls/ecdsa.h"
#include "test/random.h"
#include <string.h>
test_driver_signature_hooks_t test_driver_signature_sign_hooks = TEST_DRIVER_SIGNATURE_INIT;
test_driver_signature_hooks_t test_driver_signature_verify_hooks = TEST_DRIVER_SIGNATURE_INIT;
psa_status_t test_transparent_signature_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
uint8_t *signature, size_t signature_size, size_t *signature_length )
{
++test_driver_signature_sign_hooks.hits;
if( test_driver_signature_sign_hooks.forced_status != PSA_SUCCESS )
return( test_driver_signature_sign_hooks.forced_status );
if( test_driver_signature_sign_hooks.forced_output != NULL )
{
if( test_driver_signature_sign_hooks.forced_output_length > signature_size )
return( PSA_ERROR_BUFFER_TOO_SMALL );
memcpy( signature, test_driver_signature_sign_hooks.forced_output,
test_driver_signature_sign_hooks.forced_output_length );
*signature_length = test_driver_signature_sign_hooks.forced_output_length;
return( PSA_SUCCESS );
}
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
defined(MBEDTLS_SHA256_C)
if( alg != PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ) )
return( PSA_ERROR_NOT_SUPPORTED );
mbedtls_ecp_group_id grp_id;
switch( psa_get_key_type( attributes ) )
{
case PSA_ECC_CURVE_SECP_R1:
switch( psa_get_key_bits( attributes ) )
{
case 256:
grp_id = MBEDTLS_ECP_DP_SECP256R1;
break;
case 384:
grp_id = MBEDTLS_ECP_DP_SECP384R1;
break;
case 521:
grp_id = MBEDTLS_ECP_DP_SECP521R1;
break;
default:
return( PSA_ERROR_NOT_SUPPORTED );
}
break;
default:
return( PSA_ERROR_NOT_SUPPORTED );
}
/* Beyond this point, the driver is actually doing the work of
* calculating the signature. */
status = PSA_ERROR_GENERIC_ERROR;
int ret = 0;
mbedtls_mpi r, s;
mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s );
mbedtls_ecp_keypair ecp;
mbedtls_ecp_keypair_init( &ecp );
size_t curve_bytes = PSA_BITS_TO_BYTES( ecp.grp.pbits );
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ecp.grp, grp_id ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &ecp.grp, &ecp.Q,
key, key_length ) );
/* Code adapted from psa_ecdsa_sign() in psa_crypto.c. */
mbedtls_md_type_t md_alg = MBEDTLS_MD_SHA256;
if( signature_size < 2 * curve_bytes )
{
status = PSA_ERROR_BUFFER_TOO_SMALL;
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp.grp, &r, &s, &ecp.d,
hash, hash_length, md_alg ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
signature,
curve_bytes ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
signature + curve_bytes,
curve_bytes ) );
cleanup:
status = mbedtls_to_psa_error( ret );
mbedtls_mpi_free( &r );
mbedtls_mpi_free( &s );
mbedtls_ecp_keypair_free( &ecp );
if( status == PSA_SUCCESS )
*signature_length = 2 * curve_bytes;
#else /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
defined(MBEDTLS_SHA256_C) */
(void) attributes;
(void) key;
(void) key_length;
(void) alg;
(void) hash;
(void) hash_length;
#endif /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
defined(MBEDTLS_SHA256_C) */
return( status );
}
psa_status_t test_opaque_signature_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
uint8_t *signature, size_t signature_size, size_t *signature_length )
{
(void) attributes;
(void) key;
(void) key_length;
(void) alg;
(void) hash;
(void) hash_length;
(void) signature;
(void) signature_size;
(void) signature_length;
return( PSA_ERROR_NOT_SUPPORTED );
}
psa_status_t test_transparent_signature_verify_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length )
{
++test_driver_signature_verify_hooks.hits;
if( test_driver_signature_verify_hooks.forced_status != PSA_SUCCESS )
return( test_driver_signature_verify_hooks.forced_status );
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
defined(MBEDTLS_SHA256_C)
if( alg != PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ) )
return( PSA_ERROR_NOT_SUPPORTED );
mbedtls_ecp_group_id grp_id;
switch( psa_get_key_type( attributes ) )
{
case PSA_ECC_CURVE_SECP_R1:
switch( psa_get_key_bits( attributes ) )
{
case 256:
grp_id = MBEDTLS_ECP_DP_SECP256R1;
break;
case 384:
grp_id = MBEDTLS_ECP_DP_SECP384R1;
break;
case 521:
grp_id = MBEDTLS_ECP_DP_SECP521R1;
break;
default:
return( PSA_ERROR_NOT_SUPPORTED );
}
break;
default:
return( PSA_ERROR_NOT_SUPPORTED );
}
/* Beyond this point, the driver is actually doing the work of
* calculating the signature. */
status = PSA_ERROR_GENERIC_ERROR;
int ret = 0;
mbedtls_mpi r, s;
mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s );
mbedtls_ecp_keypair ecp;
mbedtls_ecp_keypair_init( &ecp );
mbedtls_test_rnd_pseudo_info rnd_info;
memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
size_t curve_bytes = PSA_BITS_TO_BYTES( ecp.grp.pbits );
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ecp.grp, grp_id ) );
/* Code adapted from psa_ecdsa_verify() in psa_crypto.c. */
if( signature_length < 2 * curve_bytes )
{
status = PSA_ERROR_BUFFER_TOO_SMALL;
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
signature,
curve_bytes ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
signature + curve_bytes,
curve_bytes ) );
if( PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( attributes ) ) )
MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &ecp.grp, &ecp.Q,
key, key_length ) );
else
{
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ecp.d, key, key_length ) );
MBEDTLS_MPI_CHK(
mbedtls_ecp_mul( &ecp.grp, &ecp.Q, &ecp.d, &ecp.grp.G,
&mbedtls_test_rnd_pseudo_rand,
&rnd_info ) );
}
MBEDTLS_MPI_CHK( mbedtls_ecdsa_verify( &ecp.grp, hash, hash_length,
&ecp.Q, &r, &s ) );
cleanup:
status = mbedtls_to_psa_error( ret );
mbedtls_mpi_free( &r );
mbedtls_mpi_free( &s );
mbedtls_ecp_keypair_free( &ecp );
#else /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
defined(MBEDTLS_SHA256_C) */
(void) attributes;
(void) key;
(void) key_length;
(void) alg;
(void) hash;
(void) hash_length;
#endif /* defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC) && \
defined(MBEDTLS_SHA256_C) */
return( status );
}
psa_status_t test_opaque_signature_verify_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key, size_t key_length,
psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length )
{
(void) attributes;
(void) key;
(void) key_length;
(void) alg;
(void) hash;
(void) hash_length;
(void) signature;
(void) signature_length;
return( PSA_ERROR_NOT_SUPPORTED );
}
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */

View File

@ -0,0 +1,41 @@
sign_hash through transparent driver: calculate in driver
ecdsa_sign:PSA_SUCCESS:"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":0:PSA_SUCCESS
sign_hash through transparent driver: fallback
ecdsa_sign:PSA_ERROR_NOT_SUPPORTED:"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":0:PSA_SUCCESS
sign_hash through transparent driver: error
ecdsa_sign:PSA_ERROR_GENERIC_ERROR:"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":0:PSA_ERROR_GENERIC_ERROR
sign_hash through transparent driver: fake
ecdsa_sign:PSA_SUCCESS:"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"000102030405060708090A0B0C0D0E0F":1:PSA_SUCCESS
verify_hash using private key through transparent driver: calculate in driver
ecdsa_verify:PSA_SUCCESS:0:"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_SUCCESS
verify_hash using private key through transparent driver: fallback
ecdsa_verify:PSA_ERROR_NOT_SUPPORTED:0:"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_SUCCESS
verify_hash using private key through transparent driver: error
ecdsa_verify:PSA_ERROR_GENERIC_ERROR:0:"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_GENERIC_ERROR
verify_hash using public key through transparent driver: calculate in driver
ecdsa_verify:PSA_SUCCESS:1:"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_SUCCESS
verify_hash using public key through transparent driver: fallback
ecdsa_verify:PSA_ERROR_NOT_SUPPORTED:1:"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_SUCCESS
verify_hash using public key through transparent driver: error
ecdsa_verify:PSA_ERROR_GENERIC_ERROR:1:"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_GENERIC_ERROR
generate_key through transparent driver: fake
generate_key:PSA_SUCCESS:"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_SUCCESS
generate_key through transparent driver: in-driver
generate_key:PSA_SUCCESS:"":PSA_SUCCESS
generate_key through transparent driver: fallback
generate_key:PSA_ERROR_NOT_SUPPORTED:"":PSA_SUCCESS
generate_key through transparent driver: error
generate_key:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR

View File

@ -0,0 +1,185 @@
/* BEGIN_HEADER */
#include "test/psa_crypto_helpers.h"
#include "test/drivers/test_driver.h"
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_CRYPTO_DRIVERS:PSA_CRYPTO_DRIVER_TEST
* END_DEPENDENCIES
*/
/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C */
void ecdsa_sign( int force_status_arg,
data_t *key_input,
data_t *data_input,
data_t *expected_output,
int fake_output,
int expected_status_arg )
{
psa_status_t force_status = force_status_arg;
psa_status_t expected_status = expected_status_arg;
psa_key_handle_t handle = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t alg = PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 );
uint8_t signature[64];
size_t signature_length = 0xdeadbeef;
psa_status_t actual_status;
test_driver_signature_sign_hooks = test_driver_signature_hooks_init();
PSA_ASSERT( psa_crypto_init( ) );
psa_set_key_type( &attributes,
PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP_R1 ) );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
psa_set_key_algorithm( &attributes, alg );
psa_import_key( &attributes,
key_input->x, key_input->len,
&handle );
test_driver_signature_sign_hooks.forced_status = force_status;
if( fake_output == 1 )
{
test_driver_signature_sign_hooks.forced_output = expected_output->x;
test_driver_signature_sign_hooks.forced_output_length = expected_output->len;
}
actual_status = psa_sign_hash( handle, alg,
data_input->x, data_input->len,
signature, sizeof( signature ),
&signature_length );
TEST_EQUAL( actual_status, expected_status );
if( expected_status == PSA_SUCCESS )
{
ASSERT_COMPARE( signature, signature_length,
expected_output->x, expected_output->len );
}
TEST_EQUAL( test_driver_signature_sign_hooks.hits, 1 );
exit:
psa_reset_key_attributes( &attributes );
psa_destroy_key( handle );
PSA_DONE( );
test_driver_signature_sign_hooks = test_driver_signature_hooks_init();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C */
void ecdsa_verify( int force_status_arg,
int register_public_key,
data_t *key_input,
data_t *data_input,
data_t *signature_input,
int expected_status_arg )
{
psa_status_t force_status = force_status_arg;
psa_status_t expected_status = expected_status_arg;
psa_key_handle_t handle = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t alg = PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 );
psa_status_t actual_status;
test_driver_signature_verify_hooks = test_driver_signature_hooks_init();
PSA_ASSERT( psa_crypto_init( ) );
if( register_public_key )
{
psa_set_key_type( &attributes,
PSA_KEY_TYPE_ECC_PUBLIC_KEY( PSA_ECC_CURVE_SECP_R1 ) );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
psa_set_key_algorithm( &attributes, alg );
psa_import_key( &attributes,
key_input->x, key_input->len,
&handle );
}
else
{
psa_set_key_type( &attributes,
PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP_R1 ) );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
psa_set_key_algorithm( &attributes, alg );
psa_import_key( &attributes,
key_input->x, key_input->len,
&handle );
}
test_driver_signature_verify_hooks.forced_status = force_status;
actual_status = psa_verify_hash( handle, alg,
data_input->x, data_input->len,
signature_input->x, signature_input->len );
TEST_EQUAL( actual_status, expected_status );
TEST_EQUAL( test_driver_signature_verify_hooks.hits, 1 );
exit:
psa_reset_key_attributes( &attributes );
psa_destroy_key( handle );
PSA_DONE( );
test_driver_signature_verify_hooks = test_driver_signature_hooks_init();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED */
void generate_key( int force_status_arg,
data_t *fake_output,
int expected_status_arg )
{
psa_status_t force_status = force_status_arg;
psa_status_t expected_status = expected_status_arg;
psa_key_handle_t handle = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t alg = PSA_ALG_ECDSA( PSA_ALG_SHA_256 );
const uint8_t *expected_output = NULL;
size_t expected_output_length = 0;
psa_status_t actual_status;
uint8_t actual_output[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(256)] = {0};
size_t actual_output_length;
test_driver_keygen_hooks = test_driver_keygen_hooks_init();
psa_set_key_type( &attributes,
PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP_R1 ) );
psa_set_key_bits( &attributes, 256 );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT );
psa_set_key_algorithm( &attributes, alg );
if( fake_output->len > 0 )
{
expected_output = test_driver_keygen_hooks.forced_output = fake_output->x;
expected_output_length = test_driver_keygen_hooks.forced_output_length =
fake_output->len;
}
test_driver_keygen_hooks.hits = 0;
test_driver_keygen_hooks.forced_status = force_status;
PSA_ASSERT( psa_crypto_init( ) );
actual_status = psa_generate_key( &attributes, &handle );
TEST_EQUAL( test_driver_keygen_hooks.hits, 1 );
TEST_EQUAL( actual_status, expected_status );
if( actual_status == PSA_SUCCESS )
{
psa_export_key( handle, actual_output, sizeof(actual_output), &actual_output_length );
if( fake_output->len > 0 )
{
ASSERT_COMPARE( actual_output, actual_output_length,
expected_output, expected_output_length );
}
else
{
size_t zeroes = 0;
for( size_t i = 0; i < sizeof(actual_output); i++ )
{
if( actual_output[i] == 0)
zeroes++;
}
TEST_ASSERT( zeroes != sizeof(actual_output) );
}
}
exit:
psa_reset_key_attributes( &attributes );
psa_destroy_key( handle );
PSA_DONE( );
test_driver_keygen_hooks = test_driver_keygen_hooks_init();
}
/* END_CASE */

View File

@ -238,8 +238,12 @@
<ClInclude Include="..\..\tests\include\test\psa_crypto_helpers.h" />
<ClInclude Include="..\..\tests\include\test\psa_helpers.h" />
<ClInclude Include="..\..\tests\include\test\random.h" />
<ClInclude Include="..\..\tests\include\test\drivers\keygen.h" />
<ClInclude Include="..\..\tests\include\test\drivers\signature.h" />
<ClInclude Include="..\..\tests\include\test\drivers\test_driver.h" />
<ClInclude Include="..\..\library\common.h" />
<ClInclude Include="..\..\library\psa_crypto_core.h" />
<ClInclude Include="..\..\library\psa_crypto_driver_wrappers.h" />
<ClInclude Include="..\..\library\psa_crypto_invasive.h" />
<ClInclude Include="..\..\library\psa_crypto_its.h" />
<ClInclude Include="..\..\library\psa_crypto_se.h" />
@ -307,6 +311,7 @@
<ClCompile Include="..\..\library\platform_util.c" />
<ClCompile Include="..\..\library\poly1305.c" />
<ClCompile Include="..\..\library\psa_crypto.c" />
<ClCompile Include="..\..\library\psa_crypto_driver_wrappers.c" />
<ClCompile Include="..\..\library\psa_crypto_se.c" />
<ClCompile Include="..\..\library\psa_crypto_slot_management.c" />
<ClCompile Include="..\..\library\psa_crypto_storage.c" />