diff --git a/CMakeLists.txt b/CMakeLists.txt index 88332464b..5af4c8124 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/programs/Makefile b/programs/Makefile index f9c260867..dfe055569 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -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 diff --git a/programs/fuzz/Makefile b/programs/fuzz/Makefile index 8196f3930..fa17918fa 100644 --- a/programs/fuzz/Makefile +++ b/programs/fuzz/Makefile @@ -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} \ diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl index 3d4baca41..469595518 100755 --- a/scripts/generate_visualc_files.pl +++ b/scripts/generate_visualc_files.pl @@ -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/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, ); diff --git a/tests/Makefile b/tests/Makefile index ffa4812bd..511db9db5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -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 diff --git a/tests/include/drivers/signature.h b/tests/include/drivers/signature.h new file mode 100644 index 000000000..1607ba512 --- /dev/null +++ b/tests/include/drivers/signature.h @@ -0,0 +1,55 @@ +/* + * Test driver for signature functions + */ +/* Copyright (C) 2020, 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 MBEDTLS_PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H +#define MBEDTLS_PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_TEST_HOOKS) +#include + +extern void *test_driver_forced_output; +extern size_t test_driver_forced_output_length; + +extern psa_status_t test_transparent_signature_sign_hash_status; +extern unsigned long test_transparent_signature_sign_hash_hit; + +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 ); + +#endif /* MBEDTLS_TEST_HOOKS */ +#endif /* MBEDTLS_PSA_CRYPTO_TEST_DRIVERS_SIGNATURE_H */ diff --git a/tests/include/drivers/test_driver.h b/tests/include/drivers/test_driver.h new file mode 100644 index 000000000..549467447 --- /dev/null +++ b/tests/include/drivers/test_driver.h @@ -0,0 +1,29 @@ +/* + * Umbrella include for all of the test driver functionality + */ +/* Copyright (C) 2020, 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 MBEDTLS_PSA_CRYPTO_TEST_DRIVER_H +#define MBEDTLS_PSA_CRYPTO_TEST_DRIVER_H + +#define MBEDTLS_PSA_CRYPTO_TEST_DRIVER_LIFETIME 0x7fffff + +#include "drivers/signature.h" + +#endif /* MBEDTLS_PSA_CRYPTO_TEST_DRIVER_H */ diff --git a/tests/src/drivers/signature.c b/tests/src/drivers/signature.c new file mode 100644 index 000000000..0f006c70a --- /dev/null +++ b/tests/src/drivers/signature.c @@ -0,0 +1,171 @@ +/* + * Test driver for signature functions + */ +/* Copyright (C) 2020, 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_DRIVERS) && defined(MBEDTLS_TEST_HOOKS) +#include "psa/crypto.h" +#include "mbedtls/ecp.h" + +#include "drivers/signature.h" + +#include "mbedtls/md.h" +#include "mbedtls/ecdsa.h" + +#include + +/* If non-null, on success, copy this to the output. */ +void *test_driver_forced_output = NULL; +size_t test_driver_forced_output_length = 0; + +psa_status_t test_transparent_signature_sign_hash_status = PSA_ERROR_NOT_SUPPORTED; +unsigned long test_transparent_signature_sign_hash_hit = 0; + +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_transparent_signature_sign_hash_hit; + + if( test_transparent_signature_sign_hash_status != PSA_SUCCESS ) + return( test_transparent_signature_sign_hash_status ); + + if( test_driver_forced_output != NULL ) + { + if( test_driver_forced_output_length > signature_size ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + memcpy( signature, test_driver_forced_output, + test_driver_forced_output_length ); + *signature_length = test_driver_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: + /* There's no easy way to translate the error code except through a + * library function that's not exported. Use a debugger. */ + if( ret == 0 ) + status = PSA_SUCCESS; + 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 ); +} + +#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && MBEDTLS_TEST_HOOKS */