From a3ff8a6ed59e9c8e803f5388a41a1bba18f77919 Mon Sep 17 00:00:00 2001 From: itayzafrir Date: Tue, 10 Jul 2018 10:10:21 +0300 Subject: [PATCH 1/5] psa: programs: Add cipher example Add `programs/psa/crypto_examples.c`. Update relevant Makefiles, CMakeLists.txt, and .gitignore files. --- programs/.gitignore | 1 + programs/CMakeLists.txt | 1 + programs/Makefile | 5 +++++ programs/psa/CMakeLists.txt | 7 +++++++ programs/psa/crypto_examples.c | 4 ++++ 5 files changed, 18 insertions(+) create mode 100644 programs/psa/CMakeLists.txt create mode 100644 programs/psa/crypto_examples.c diff --git a/programs/.gitignore b/programs/.gitignore index d58253d49..453ae0d13 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -29,6 +29,7 @@ pkey/rsa_sign pkey/rsa_sign_pss pkey/rsa_verify pkey/rsa_verify_pss +psa/crypto_examples psa/psa_constant_names psa/psa_constant_names_generated.c psa/key_ladder_demo diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 4cdae7821..661b12071 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(aes) add_subdirectory(hash) add_subdirectory(pkey) +add_subdirectory(psa) add_subdirectory(random) add_subdirectory(ssl) add_subdirectory(test) diff --git a/programs/Makefile b/programs/Makefile index 9e1a5279e..b1534071c 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -60,6 +60,7 @@ APPS = aes/aescrypt2$(EXEXT) aes/crypt_and_hash$(EXEXT) \ pkey/rsa_decrypt$(EXEXT) pkey/rsa_encrypt$(EXEXT) \ pkey/rsa_sign$(EXEXT) pkey/rsa_verify$(EXEXT) \ pkey/rsa_sign_pss$(EXEXT) pkey/rsa_verify_pss$(EXEXT) \ + psa/crypto_examples$(EXEXT) \ psa/key_ladder_demo$(EXEXT) psa/psa_constant_names$(EXEXT) \ ssl/dtls_client$(EXEXT) ssl/dtls_server$(EXEXT) \ ssl/ssl_client1$(EXEXT) ssl/ssl_client2$(EXEXT) \ @@ -308,6 +309,10 @@ x509/req_app$(EXEXT): x509/req_app.c $(DEP) echo " CC x509/req_app.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) x509/req_app.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +psa/crypto_examples$(EXEXT): psa/crypto_examples.c $(DEP) + echo " CC psa/crypto_examples.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/crypto_examples.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + clean: ifndef WINDOWS rm -f $(APPS) $(EXTRA_GENERATED) diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt new file mode 100644 index 000000000..a0fe803d7 --- /dev/null +++ b/programs/psa/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable(crypto_examples crypto_examples.c) +target_link_libraries(crypto_examples mbedtls) + +install(TARGETS crypto_examples + DESTINATION "bin" + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + diff --git a/programs/psa/crypto_examples.c b/programs/psa/crypto_examples.c new file mode 100644 index 000000000..3a549ff86 --- /dev/null +++ b/programs/psa/crypto_examples.c @@ -0,0 +1,4 @@ +int main( void ) +{ + return( 0 ); +} From 10366708d6a4c6c68ae6961ca0620919aaf71ea3 Mon Sep 17 00:00:00 2001 From: itayzafrir Date: Wed, 11 Jul 2018 13:44:41 +0300 Subject: [PATCH 2/5] psa: programs: Add cipher AES CBC no padding --- programs/psa/crypto_examples.c | 210 +++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) diff --git a/programs/psa/crypto_examples.c b/programs/psa/crypto_examples.c index 3a549ff86..18f93a299 100644 --- a/programs/psa/crypto_examples.c +++ b/programs/psa/crypto_examples.c @@ -1,4 +1,214 @@ +#include "psa/crypto.h" +#include + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif + +#define ASSERT( predicate ) \ + do \ + { \ + if( ! ( predicate ) ) \ + { \ + mbedtls_printf( "\tassertion failed at %s:%d - '%s'\r\n", \ + __FILE__, __LINE__, #predicate); \ + goto exit; \ + } \ + } while ( 0 ) + +#define ASSERT_STATUS( actual, expected ) \ + do \ + { \ + if( ( actual ) != ( expected ) ) \ + { \ + mbedtls_printf( "\tassertion failed at %s:%d - " \ + "actual:%d expected:%d\r\n", __FILE__, __LINE__, \ + (psa_status_t) actual, (psa_status_t) expected ); \ + goto exit; \ + } \ + } while ( 0 ) + +/* Use key slot 1 for our cipher key. Key slot 0 is reserved as unused. */ +static const psa_key_slot_t key_slot_cipher = 1; + +static psa_status_t set_key_policy( psa_key_slot_t key_slot, + psa_key_usage_t key_usage, + psa_algorithm_t alg ) +{ + psa_status_t status; + psa_key_policy_t policy; + + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, key_usage, alg ); + status = psa_set_key_policy( key_slot, &policy ); + ASSERT_STATUS( status, PSA_SUCCESS ); +exit: + return( status ); +} + +static psa_status_t cipher_operation( psa_cipher_operation_t *operation, + const uint8_t * input, + size_t input_size, + size_t part_size, + uint8_t * output, + size_t output_size, + size_t *output_len ) +{ + psa_status_t status; + size_t bytes_to_write = 0, bytes_written = 0, len = 0; + + *output_len = 0; + while( bytes_written != input_size ) + { + bytes_to_write = ( input_size - bytes_written > part_size ? + part_size : + input_size - bytes_written ); + + status = psa_cipher_update( operation, input + bytes_written, + bytes_to_write, output + *output_len, + output_size - *output_len, &len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + bytes_written += bytes_to_write; + *output_len += len; + } + + status = psa_cipher_finish( operation, output + *output_len, + output_size - *output_len, &len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + *output_len += len; + +exit: + return( status ); +} + +static psa_status_t cipher_encrypt( psa_key_slot_t key_slot, + psa_algorithm_t alg, + uint8_t * iv, + size_t iv_size, + const uint8_t * input, + size_t input_size, + size_t part_size, + uint8_t * output, + size_t output_size, + size_t *output_len ) +{ + psa_status_t status; + psa_cipher_operation_t operation; + size_t iv_len = 0; + + memset( &operation, 0, sizeof( operation ) ); + status = psa_cipher_encrypt_setup( &operation, key_slot, alg ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = psa_cipher_generate_iv( &operation, iv, iv_size, &iv_len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = cipher_operation( &operation, input, input_size, part_size, + output, output_size, output_len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + +exit: + psa_cipher_abort( &operation ); + return( status ); +} + +static psa_status_t cipher_decrypt( psa_key_slot_t key_slot, + psa_algorithm_t alg, + const uint8_t * iv, + size_t iv_size, + const uint8_t * input, + size_t input_size, + size_t part_size, + uint8_t * output, + size_t output_size, + size_t *output_len ) +{ + psa_status_t status; + psa_cipher_operation_t operation; + + memset( &operation, 0, sizeof( operation ) ); + status = psa_cipher_decrypt_setup( &operation, key_slot, alg ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = psa_cipher_set_iv( &operation, iv, iv_size ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = cipher_operation( &operation, input, input_size, part_size, + output, output_size, output_len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + +exit: + psa_cipher_abort( &operation ); + return( status ); +} + +static psa_status_t +cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void ) +{ + enum { + block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ), + key_bits = 256, + part_size = block_size, + }; + const psa_algorithm_t alg = PSA_ALG_CBC_BASE | + PSA_ALG_BLOCK_CIPHER_PAD_NONE; + + psa_status_t status; + size_t output_len = 0; + uint8_t iv[block_size]; + uint8_t input[block_size]; + uint8_t encrypt[block_size]; + uint8_t decrypt[block_size]; + + status = psa_generate_random( input, sizeof( input ) ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = set_key_policy( key_slot_cipher, + PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, + alg ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits, + NULL, 0 ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ), + input, sizeof( input ), part_size, + encrypt, sizeof( encrypt ), &output_len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ), + encrypt, output_len, part_size, + decrypt, sizeof( decrypt ), &output_len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = memcmp( input, decrypt, sizeof( input ) ); + ASSERT_STATUS( status, PSA_SUCCESS ); + +exit: + psa_destroy_key( key_slot_cipher ); + return( status ); +} + +static void cipher_examples( void ) +{ + psa_status_t status; + + mbedtls_printf( "cipher encrypt/decrypt AES CBC no padding:\r\n" ); + status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( ); + if( status == PSA_SUCCESS ) + mbedtls_printf( "\tsuccess!\r\n" ); +} + int main( void ) { + ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + cipher_examples( ); +exit: + mbedtls_psa_crypto_free( ); return( 0 ); } From a2d0804b334347cd7899bd90d16b6d1594066d8c Mon Sep 17 00:00:00 2001 From: itayzafrir Date: Thu, 12 Jul 2018 10:27:58 +0300 Subject: [PATCH 3/5] psa: programs: Add cipher AES CBC PKCS7 multipart --- programs/psa/crypto_examples.c | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/programs/psa/crypto_examples.c b/programs/psa/crypto_examples.c index 18f93a299..e2d2cf553 100644 --- a/programs/psa/crypto_examples.c +++ b/programs/psa/crypto_examples.c @@ -194,6 +194,53 @@ exit: return( status ); } +static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void ) +{ + enum { + block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ), + key_bits = 256, + input_size = 100, + part_size = 10, + }; + + const psa_algorithm_t alg = PSA_ALG_CBC_BASE | + PSA_ALG_BLOCK_CIPHER_PAD_PKCS7; + + psa_status_t status; + size_t output_len = 0; + uint8_t iv[block_size], input[input_size], + encrypt[input_size + block_size], decrypt[input_size + block_size]; + + status = psa_generate_random( input, sizeof( input ) ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = set_key_policy( key_slot_cipher, + PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, + alg ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits, + NULL, 0 ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ), + input, sizeof( input ), part_size, + encrypt, sizeof( encrypt ), &output_len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ), + encrypt, output_len, part_size, + decrypt, sizeof( decrypt ), &output_len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = memcmp( input, decrypt, sizeof( input ) ); + ASSERT_STATUS( status, PSA_SUCCESS ); + +exit: + psa_destroy_key( key_slot_cipher ); + return( status ); +} + static void cipher_examples( void ) { psa_status_t status; @@ -202,6 +249,11 @@ static void cipher_examples( void ) status = cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( ); if( status == PSA_SUCCESS ) mbedtls_printf( "\tsuccess!\r\n" ); + + mbedtls_printf( "cipher encrypt/decrypt AES CBC PKCS7 multipart:\r\n" ); + status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( ); + if( status == PSA_SUCCESS ) + mbedtls_printf( "\tsuccess!\r\n" ); } int main( void ) From 44b09d2a67a4c33eb39d4eb4ebbe3e9877a7c22d Mon Sep 17 00:00:00 2001 From: itayzafrir Date: Thu, 12 Jul 2018 13:06:41 +0300 Subject: [PATCH 4/5] psa: programs: Add cipher AES CTR multipart --- programs/psa/crypto_examples.c | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/programs/psa/crypto_examples.c b/programs/psa/crypto_examples.c index e2d2cf553..a7c36fa04 100644 --- a/programs/psa/crypto_examples.c +++ b/programs/psa/crypto_examples.c @@ -241,6 +241,51 @@ exit: return( status ); } +static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void ) +{ + enum { + block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( PSA_KEY_TYPE_AES ), + key_bits = 256, + input_size = 100, + part_size = 10, + }; + const psa_algorithm_t alg = PSA_ALG_CTR; + + psa_status_t status; + size_t output_len = 0; + uint8_t iv[block_size], input[input_size], encrypt[input_size], + decrypt[input_size]; + + status = psa_generate_random( input, sizeof( input ) ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = set_key_policy( key_slot_cipher, + PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, + alg ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits, + NULL, 0 ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ), + input, sizeof( input ), part_size, + encrypt, sizeof( encrypt ), &output_len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ), + encrypt, output_len, part_size, + decrypt, sizeof( decrypt ), &output_len ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = memcmp( input, decrypt, sizeof( input ) ); + ASSERT_STATUS( status, PSA_SUCCESS ); + +exit: + psa_destroy_key( key_slot_cipher ); + return( status ); +} + static void cipher_examples( void ) { psa_status_t status; @@ -254,6 +299,11 @@ static void cipher_examples( void ) status = cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( ); if( status == PSA_SUCCESS ) mbedtls_printf( "\tsuccess!\r\n" ); + + mbedtls_printf( "cipher encrypt/decrypt AES CTR multipart:\r\n" ); + status = cipher_example_encrypt_decrypt_aes_ctr_multi( ); + if( status == PSA_SUCCESS ) + mbedtls_printf( "\tsuccess!\r\n" ); } int main( void ) From 18ac331e1517897a66cbb39be0d38cfcee55e07e Mon Sep 17 00:00:00 2001 From: itayzafrir Date: Tue, 17 Jul 2018 09:28:11 +0300 Subject: [PATCH 5/5] psa: programs: Add cipher example fallback main When dependencies are missing, print an error message from the example about missing dependencies at run-time. --- programs/psa/crypto_examples.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/programs/psa/crypto_examples.c b/programs/psa/crypto_examples.c index a7c36fa04..e8b64f19a 100644 --- a/programs/psa/crypto_examples.c +++ b/programs/psa/crypto_examples.c @@ -31,6 +31,19 @@ } \ } while ( 0 ) +#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_AES_C) || \ + !defined(MBEDTLS_CIPHER_MODE_CBC) || !defined(MBEDTLS_CIPHER_MODE_CTR) || \ + !defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +int main( void ) +{ + mbedtls_printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_AES_C and/or " + "MBEDTLS_CIPHER_MODE_CBC and/or MBEDTLS_CIPHER_MODE_CTR " + "and/or MBEDTLS_CIPHER_MODE_WITH_PADDING " + "not defined.\r\n" ); + return( 0 ); +} +#else + /* Use key slot 1 for our cipher key. Key slot 0 is reserved as unused. */ static const psa_key_slot_t key_slot_cipher = 1; @@ -314,3 +327,5 @@ exit: mbedtls_psa_crypto_free( ); return( 0 ); } +#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC && + MBEDTLS_CIPHER_MODE_CTR && MBEDTLS_CIPHER_MODE_WITH_PADDING */