From 667b556dbc3c82b13521088e92a4456c85fda7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 22 Nov 2021 13:00:17 +0100 Subject: [PATCH 01/30] Add example program psa/hmac_md_psa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is meant to highlight similarities and differences in the multi-part HMAC APIs. Signed-off-by: Manuel Pégourié-Gonnard --- programs/.gitignore | 1 + programs/Makefile | 13 ++- programs/psa/CMakeLists.txt | 1 + programs/psa/hmac_md_psa.c | 174 ++++++++++++++++++++++++++++++++++++ 4 files changed, 185 insertions(+), 4 deletions(-) create mode 100644 programs/psa/hmac_md_psa.c diff --git a/programs/.gitignore b/programs/.gitignore index deb104a40167..72ccb5bd4936 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -39,6 +39,7 @@ pkey/rsa_sign_pss pkey/rsa_verify pkey/rsa_verify_pss psa/crypto_examples +psa/hmac_md_psa psa/key_ladder_demo psa/psa_constant_names random/gen_entropy diff --git a/programs/Makefile b/programs/Makefile index 7f9d11e80daa..782cf90506e8 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -85,6 +85,7 @@ APPS = \ pkey/rsa_verify \ pkey/rsa_verify_pss \ psa/crypto_examples \ + psa/hmac_md_psa \ psa/key_ladder_demo \ psa/psa_constant_names \ random/gen_entropy \ @@ -261,6 +262,14 @@ pkey/rsa_encrypt$(EXEXT): pkey/rsa_encrypt.c $(DEP) echo " CC pkey/rsa_encrypt.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/rsa_encrypt.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 $@ + +psa/hmac_md_psa$(EXEXT): psa/hmac_md_psa.c $(DEP) + echo " CC psa/hmac_md_psa.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/hmac_md_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + psa/key_ladder_demo$(EXEXT): psa/key_ladder_demo.c $(DEP) echo " CC psa/key_ladder_demo.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/key_ladder_demo.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ @@ -396,10 +405,6 @@ 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 $(EXES) diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt index 26ca73c185ce..27732308ce9b 100644 --- a/programs/psa/CMakeLists.txt +++ b/programs/psa/CMakeLists.txt @@ -1,5 +1,6 @@ set(executables crypto_examples + hmac_md_psa key_ladder_demo psa_constant_names ) diff --git a/programs/psa/hmac_md_psa.c b/programs/psa/hmac_md_psa.c new file mode 100644 index 000000000000..cde78f18bbcc --- /dev/null +++ b/programs/psa/hmac_md_psa.c @@ -0,0 +1,174 @@ +/* + * 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. + */ + +/* + * This is a simple example of multi-part HMAC computation using both the old + * MD API and the new PSA API; its goal is to help migration to PSA Crypto. + * + * When in comes to multi-part HMAC operations, the `mbedtls_md_context` + * serves a dual purpose (1) hold the key, and (2) save progress information + * for the current operation. With PSA those roles are held by two disinct + * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for + * multi-part progress. + * + * This program illustrates this by doing the same sequence of multi-part HMAC + * computation with both APIs; looking at the two function md() and mac() side + * by side should make the differences and similarities clear. + */ + +#include + +#include "mbedtls/build_info.h" + +#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_MD_C) +int main( void ) +{ + printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_MD_C not defined.\r\n" ); + return( 0 ); +} +#else /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_MD_C */ + +#include "mbedtls/md.h" +#include "psa/crypto.h" + +/* + * Dummy inputs for HMAC + */ +const unsigned char part1[] = { 0x01, 0x02 }; +const unsigned char part2[] = { 0x03, 0x04 }; +const unsigned char part3[] = { 0x05, 0x05 }; +const unsigned char part4[] = { 0x06, 0x06 }; + +const unsigned char key_bytes[32] = { 0 }; + +unsigned char out[32]; + +void print_out( const char *title ) +{ + printf( "%s:", title ); + for( size_t i = 0; i < sizeof( out ); i++ ) + printf( " %02x", out[i] ); + printf( "\n" ); +} + +#define CHK( code ) \ + do { \ + ret = code; \ + if( ret != 0 ) \ + goto exit; \ + } while( 0 ) + +int md(void) +{ + int ret; + mbedtls_md_context_t ctx; + + mbedtls_md_init( &ctx ); + + /* prepare context and load key */ + CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 1 ) ); + CHK( mbedtls_md_hmac_starts( &ctx, key_bytes, sizeof( key_bytes ) ) ); + + /* compute HMAC(key, part 1 | part 2) */ + CHK( mbedtls_md_hmac_update( &ctx, part1, sizeof( part1 ) ) ); + CHK( mbedtls_md_hmac_update( &ctx, part2, sizeof( part2 ) ) ); + CHK( mbedtls_md_hmac_finish( &ctx, out ) ); + print_out( "12" ); + + /* compute HMAC(key, part 3 | part 4) */ + CHK( mbedtls_md_hmac_reset( &ctx ) ); // prepare for new operation + CHK( mbedtls_md_hmac_update( &ctx, part3, sizeof( part3 ) ) ); + CHK( mbedtls_md_hmac_update( &ctx, part4, sizeof( part4 ) ) ); + CHK( mbedtls_md_hmac_finish( &ctx, out ) ); + print_out( "34" ); + +exit: + mbedtls_md_free( &ctx ); + + return( ret ); +} + +#undef CHK + +#define CHK( code ) \ + do { \ + status = code; \ + if( status != PSA_SUCCESS ) \ + goto exit; \ + } while( 0 ) + +psa_status_t mac(void) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key = 0; + psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256); + + /* prepare key */ + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE ); + psa_set_key_algorithm( &attributes, alg ); + psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); + psa_set_key_bits( &attributes, 8 * sizeof( key_bytes ) ); + + status = psa_import_key( &attributes, key_bytes, sizeof( key_bytes ), &key ); + if( status != PSA_SUCCESS ) + return( status ); + + /* prepare operation */ + psa_mac_operation_t op = PSA_MAC_OPERATION_INIT; + size_t out_len = 0; + + /* compute HMAC(key, part 1 | part 2) */ + CHK( psa_mac_sign_setup( &op, key, alg ) ); + CHK( psa_mac_update( &op, part1, sizeof( part1 ) ) ); + CHK( psa_mac_update( &op, part2, sizeof( part2 ) ) ); + CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); + print_out( "12" ); + + /* compute HMAC(key, part 3 | part 4) */ + CHK( psa_mac_sign_setup( &op, key, alg ) ); + CHK( psa_mac_update( &op, part3, sizeof( part3 ) ) ); + CHK( psa_mac_update( &op, part4, sizeof( part4 ) ) ); + CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); + print_out( "34" ); + +exit: + psa_mac_abort( &op ); + + return( status ); +} + +#undef CHK + +int main(void) +{ + printf( "MD\n" ); + int ret = md(); + if( ret != 0 ) + printf( "ret = %d (-0x%04x)\n", ret, -ret ); + + psa_status_t status = psa_crypto_init(); + if( status != PSA_SUCCESS ) + printf( "psa init: %d\n", status ); + + printf( "\nPSA\n" ); + status = mac(); + if( status != PSA_SUCCESS ) + printf( "psa mac: %d\n", status ); +} + +#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_MD_C */ From 398d45985b894f4e0f88b9adf7effb4dd03b7f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 7 Jan 2022 12:26:32 +0100 Subject: [PATCH 02/30] Add example program psa/aead_cipher_psa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is meant to highlight similarities and differences in the APIs. Signed-off-by: Manuel Pégourié-Gonnard --- programs/.gitignore | 1 + programs/Makefile | 5 + programs/psa/CMakeLists.txt | 1 + programs/psa/aead_cipher_psa.c | 350 +++++++++++++++++++++++++++++++++ 4 files changed, 357 insertions(+) create mode 100644 programs/psa/aead_cipher_psa.c diff --git a/programs/.gitignore b/programs/.gitignore index 72ccb5bd4936..a4ff337f49dd 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -38,6 +38,7 @@ pkey/rsa_sign pkey/rsa_sign_pss pkey/rsa_verify pkey/rsa_verify_pss +psa/aead_cipher_psa psa/crypto_examples psa/hmac_md_psa psa/key_ladder_demo diff --git a/programs/Makefile b/programs/Makefile index 782cf90506e8..62654a5a1ab6 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -84,6 +84,7 @@ APPS = \ pkey/rsa_sign_pss \ pkey/rsa_verify \ pkey/rsa_verify_pss \ + psa/aead_cipher_psa \ psa/crypto_examples \ psa/hmac_md_psa \ psa/key_ladder_demo \ @@ -262,6 +263,10 @@ pkey/rsa_encrypt$(EXEXT): pkey/rsa_encrypt.c $(DEP) echo " CC pkey/rsa_encrypt.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/rsa_encrypt.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +psa/aead_cipher_psa$(EXEXT): psa/aead_cipher_psa.c $(DEP) + echo " CC psa/aead_cipher_psa.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/aead_cipher_psa.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 $@ diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt index 27732308ce9b..450ef36689a8 100644 --- a/programs/psa/CMakeLists.txt +++ b/programs/psa/CMakeLists.txt @@ -1,4 +1,5 @@ set(executables + aead_cipher_psa crypto_examples hmac_md_psa key_ladder_demo diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c new file mode 100644 index 000000000000..301701c18dca --- /dev/null +++ b/programs/psa/aead_cipher_psa.c @@ -0,0 +1,350 @@ +/* + * 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. + */ + +/* + * This is a simple example of multi-part AEAD computation using both the old + * Cipher API and the new PSA API; its goal is to help migration to PSA Crypto. + * + * When in comes to multi-part HMAC operations, the `mbedtls_md_context` + * serves a triple purpose (1) hold the key, (2) store the algorithm, and (3) + * save progress information for the current operation. With PSA those roles + * are held by disinct objects: (1) a psa_key_id_t to hold the key, a (2) + * psa_algorithm_t to represent the algorithm, and (3) a psa_operation_t for + * multi-part progress. + * + * On the other hand, with PSA, the algorithms encodes the desired tag length; + * with Cipher the desired tag length needs to be tracked separately. + * + * This program illustrates this by doing the same sequence of multi-part AEAD + * computation with both APIs; looking at the two series of functions + * cipher_xxx() and aead_xxx() side by side should make the differences and + * similarities clear. + */ + +#include + +#include "mbedtls/build_info.h" + +#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_CIPHER_C) || \ + !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \ + !defined(MBEDTLS_CHACHAPOLY_C) +int main( void ) +{ + printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_MD_C and/or " + "MBEDTLS_AES_C and/or MBEDTLS_GCM_C and/or " + "MBEDTLS_CHACHAPOLY_C not defined.\r\n" ); + return( 0 ); +} +#else + +#include + +#include "mbedtls/cipher.h" +#include "psa/crypto.h" + +/* + * Common data and helper functions + */ +const char usage[] = "Usage: aead_cipher_psa [gcm128|gcm256|gcm128_8|chachapoly]"; + +const unsigned char iv1[12] = { 0x00 }; +const unsigned char ad1[] = { 0x01, 0x02 }; +const unsigned char pa1[] = { 0x03, 0x04 }; +const unsigned char pb1[] = { 0x05, 0x06, 0x07 }; + +const unsigned char iv2[12] = { 0x10 }; +const unsigned char ad2[] = { 0x11, 0x12 }; +const unsigned char pa2[] = { 0x13, 0x14 }; +const unsigned char pb2[] = { 0x15, 0x16, 0x17 }; + +const unsigned char key_bytes[32] = { 0x2a }; + +void print_out( const char *title, unsigned char *out, size_t len ) +{ + printf( "%s:", title ); + for( size_t i = 0; i < len; i++ ) + printf( " %02x", out[i] ); + printf( "\n" ); +} + +/* + * Functions using the Cipher API + */ +#define CHK( code ) \ + do { \ + ret = code; \ + if( ret != 0 ) { \ + printf( "%s:%03d: ret = -0x%04x\n", __func__, __LINE__, -ret ); \ + goto exit; \ + } \ + } while( 0 ) + + +static int cipher_prepare( const char *info, + mbedtls_cipher_context_t *ctx, + size_t *tag_len ) +{ + int ret; + + mbedtls_cipher_type_t type; + if( strcmp( info, "gcm128" ) == 0 ) { + type = MBEDTLS_CIPHER_AES_128_GCM; + *tag_len = 16; + } else if( strcmp( info, "gcm256" ) == 0 ) { + type = MBEDTLS_CIPHER_AES_256_GCM; + *tag_len = 16; + } else if( strcmp( info, "gcm128_8" ) == 0 ) { + type = MBEDTLS_CIPHER_AES_128_GCM; + *tag_len = 8; + } else if( strcmp( info, "chachapoly" ) == 0 ) { + type = MBEDTLS_CIPHER_CHACHA20_POLY1305; + *tag_len = 16; + } else { + puts( usage ); + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + CHK( mbedtls_cipher_setup( ctx, + mbedtls_cipher_info_from_type( type ) ) ); + + size_t key_len = mbedtls_cipher_get_key_bitlen( ctx ); + CHK( mbedtls_cipher_setkey( ctx, key_bytes, key_len, MBEDTLS_ENCRYPT ) ); + +exit: + return( ret ); +} + +static void cipher_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) +{ + // no convenient way to get the cipher type (for example, AES) + const char *ciph = "???"; + int key_bits = mbedtls_cipher_get_key_bitlen( ctx ); + mbedtls_cipher_mode_t mode = mbedtls_cipher_get_cipher_mode( ctx ); + + const char *mode_str = mode == MBEDTLS_MODE_GCM ? "GCM" + : mode == MBEDTLS_MODE_CHACHAPOLY ? "ChachaPoly" + : "???"; + + printf( "cipher: %s, %d, %s, %zu\n", ciph, key_bits, mode_str, tag_len ); +} + +static int cipher_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *pa, size_t pa_len, + const unsigned char *pb, size_t pb_len ) +{ + int ret; + size_t olen; + unsigned char out[32]; + unsigned char *p = out; + + CHK( mbedtls_cipher_set_iv( ctx, iv, iv_len ) ); + CHK( mbedtls_cipher_reset( ctx ) ); + CHK( mbedtls_cipher_update_ad( ctx, ad, ad_len ) ); + CHK( mbedtls_cipher_update( ctx, pa, pa_len, p, &olen ) ); + p += olen; + CHK( mbedtls_cipher_update( ctx, pb, pb_len, p, &olen ) ); + p += olen; + CHK( mbedtls_cipher_finish( ctx, p, &olen ) ); + p += olen; + CHK( mbedtls_cipher_write_tag( ctx, p, tag_len ) ); + p += tag_len; + + olen = p - out; + print_out( "cipher", out, olen ); + +exit: + return( ret ); +} + +static int cipher( const char *info ) +{ + int ret = 0; + + mbedtls_cipher_context_t ctx; + size_t tag_len; + + mbedtls_cipher_init( &ctx ); + + CHK( cipher_prepare( info, &ctx, &tag_len ) ); + + cipher_info( &ctx, tag_len ); + + CHK( cipher_encrypt( &ctx, tag_len, + iv1, sizeof( iv1 ), ad1, sizeof( ad1 ), + pa1, sizeof( pa1 ), pb1, sizeof( pb1 ) ) ); + CHK( cipher_encrypt( &ctx, tag_len, + iv2, sizeof( iv2 ), ad2, sizeof( ad2 ), + pa2, sizeof( pa2 ), pb2, sizeof( pb2 ) ) ); + +exit: + mbedtls_cipher_free( &ctx ); + + return( ret ); +} + +#undef CHK + +/* + * Functions using the PSA Crypto API + */ + +#define CHK( code ) \ + do { \ + status = code; \ + if( status != PSA_SUCCESS ) { \ + printf( "%s:%03d: status = %d\n", __func__, __LINE__, status ); \ + goto exit; \ + } \ + } while( 0 ) + +static psa_status_t aead_prepare( const char *info, + psa_key_id_t *key, + psa_algorithm_t *alg ) +{ + psa_status_t status; + + size_t key_bits; + psa_key_type_t key_type; + if( strcmp( info, "gcm128" ) == 0 ) { + *alg = PSA_ALG_GCM; + key_bits = 128; + key_type = PSA_KEY_TYPE_AES; + } else if( strcmp( info, "gcm256" ) == 0 ) { + *alg = PSA_ALG_GCM; + key_bits = 256; + key_type = PSA_KEY_TYPE_AES; + } else if( strcmp( info, "gcm128_8" ) == 0 ) { + *alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8); + key_bits = 128; + key_type = PSA_KEY_TYPE_AES; + } else if( strcmp( info, "chachapoly" ) == 0 ) { + *alg = PSA_ALG_CHACHA20_POLY1305; + key_bits = 256; + key_type = PSA_KEY_TYPE_CHACHA20; + } else { + puts( usage ); + return( PSA_ERROR_INVALID_ARGUMENT ); + } + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT ); + psa_set_key_algorithm( &attributes, *alg ); + psa_set_key_type( &attributes, key_type ); + psa_set_key_bits( &attributes, key_bits ); + + CHK( psa_import_key( &attributes, key_bytes, key_bits / 8, key ) ); + +exit: + return( status ); +} + +static void aead_info( psa_key_id_t key, psa_algorithm_t alg ) +{ + psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT; + (void) psa_get_key_attributes( key, &attr ); + psa_key_type_t key_type = psa_get_key_type( &attr ); + size_t key_bits = psa_get_key_bits( &attr ); + psa_algorithm_t base_alg = PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG( alg ); + size_t tag_len = PSA_AEAD_TAG_LENGTH( key_type, key_bits, alg ); + + const char *type_str = key_type == PSA_KEY_TYPE_AES ? "AES" + : key_type == PSA_KEY_TYPE_CHACHA20 ? "Chacha" + : "???"; + const char *base_str = base_alg == PSA_ALG_GCM ? "GCM" + : base_alg == PSA_ALG_CHACHA20_POLY1305 ? "ChachaPoly" + : "???"; + + printf( "aead : %s, %zu, %s, %zu\n", type_str, key_bits, base_str, tag_len ); +} + +static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *pa, size_t pa_len, + const unsigned char *pb, size_t pb_len ) +{ + psa_status_t status; + size_t olen, olen_tag; + unsigned char out[32]; + unsigned char *p = out, *end = out + sizeof( out ); + unsigned char tag[16]; + + psa_aead_operation_t op = PSA_AEAD_OPERATION_INIT; + CHK( psa_aead_encrypt_setup( &op, key, alg ) ); + + CHK( psa_aead_set_nonce( &op, iv, iv_len ) ); + CHK( psa_aead_update_ad( &op, ad, ad_len ) ); + CHK( psa_aead_update( &op, pa, pa_len, p, end - p, &olen ) ); + p += olen; + CHK( psa_aead_update( &op, pb, pb_len, p, end - p, &olen ) ); + p += olen; + CHK( psa_aead_finish( &op, p, end - p, &olen, + tag, sizeof( tag ), &olen_tag ) ); + p += olen; + memcpy( p, tag, olen_tag ); + p += olen_tag; + + olen = p - out; + print_out( "aead ", out, olen ); +exit: + return( status ); +} + +static psa_status_t aead( const char *info ) +{ + psa_status_t status; + + psa_key_id_t key; + psa_algorithm_t alg; + + CHK( aead_prepare( info, &key, &alg ) ); + + aead_info( key, alg ); + + CHK( aead_encrypt( key, alg, + iv1, sizeof( iv1 ), ad1, sizeof( ad1 ), + pa1, sizeof( pa1 ), pb1, sizeof( pb1 ) ) ); + CHK( aead_encrypt( key, alg, + iv2, sizeof( iv2 ), ad2, sizeof( ad2 ), + pa2, sizeof( pa2 ), pb2, sizeof( pb2 ) ) ); + +exit: + return( status ); +} + +#undef CHK + +/* + * Main function + */ +int main( int argc, char **argv ) +{ + if( argc != 2 ) + { + puts( usage ); + return( 1 ); + } + + psa_crypto_init(); + + cipher( argv[1] ); + aead( argv[1] ); +} + +#endif From ecffd96910ab27afbc1b82721d2c04b37194898e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 14 Jan 2022 13:06:14 +0100 Subject: [PATCH 03/30] Silence compiler warning in example program MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 2 +- programs/psa/hmac_md_psa.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index 301701c18dca..ef73e7a2e09b 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -88,7 +88,7 @@ void print_out( const char *title, unsigned char *out, size_t len ) do { \ ret = code; \ if( ret != 0 ) { \ - printf( "%s:%03d: ret = -0x%04x\n", __func__, __LINE__, -ret ); \ + printf( "%s:%03d: ret = -0x%04x\n", __func__, __LINE__, (unsigned) -ret ); \ goto exit; \ } \ } while( 0 ) diff --git a/programs/psa/hmac_md_psa.c b/programs/psa/hmac_md_psa.c index cde78f18bbcc..0a9a02bbeff7 100644 --- a/programs/psa/hmac_md_psa.c +++ b/programs/psa/hmac_md_psa.c @@ -159,7 +159,7 @@ int main(void) printf( "MD\n" ); int ret = md(); if( ret != 0 ) - printf( "ret = %d (-0x%04x)\n", ret, -ret ); + printf( "ret = %d (-0x%04x)\n", ret, (unsigned) -ret ); psa_status_t status = psa_crypto_init(); if( status != PSA_SUCCESS ) From 9efbf53f0ef58237280ce87066dbe5dfba9f33c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 17 Jan 2022 11:57:44 +0100 Subject: [PATCH 04/30] Declare incompatibility in new programs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Existing example programs in this directory are already incompatible with that option, so this is probably acceptable here too. Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 6 ++++-- programs/psa/hmac_md_psa.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index ef73e7a2e09b..67dd1e40836c 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -41,12 +41,14 @@ #if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_CIPHER_C) || \ !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \ - !defined(MBEDTLS_CHACHAPOLY_C) + !defined(MBEDTLS_CHACHAPOLY_C) || \ + defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) int main( void ) { printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_MD_C and/or " "MBEDTLS_AES_C and/or MBEDTLS_GCM_C and/or " - "MBEDTLS_CHACHAPOLY_C not defined.\r\n" ); + "MBEDTLS_CHACHAPOLY_C not defined, and/or " + "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined\r\n" ); return( 0 ); } #else diff --git a/programs/psa/hmac_md_psa.c b/programs/psa/hmac_md_psa.c index 0a9a02bbeff7..7230c20cdaa0 100644 --- a/programs/psa/hmac_md_psa.c +++ b/programs/psa/hmac_md_psa.c @@ -34,10 +34,12 @@ #include "mbedtls/build_info.h" -#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_MD_C) +#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_MD_C) || \ + defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) int main( void ) { - printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_MD_C not defined.\r\n" ); + printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_MD_C not defined, " + "and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined\r\n" ); return( 0 ); } #else /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_MD_C */ From 763641a3f5f1a3cfbc202f2e4d4ece6177a06088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 17 Jan 2022 11:58:54 +0100 Subject: [PATCH 05/30] Rm use of non-standard __func__ in example programs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index 67dd1e40836c..7afc2b39c789 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -90,7 +90,7 @@ void print_out( const char *title, unsigned char *out, size_t len ) do { \ ret = code; \ if( ret != 0 ) { \ - printf( "%s:%03d: ret = -0x%04x\n", __func__, __LINE__, (unsigned) -ret ); \ + printf( "%03d: ret = -0x%04x\n", __LINE__, (unsigned) -ret ); \ goto exit; \ } \ } while( 0 ) @@ -210,7 +210,7 @@ static int cipher( const char *info ) do { \ status = code; \ if( status != PSA_SUCCESS ) { \ - printf( "%s:%03d: status = %d\n", __func__, __LINE__, status ); \ + printf( "%03d: status = %d\n", __LINE__, status ); \ goto exit; \ } \ } while( 0 ) From 24e82ded79b9ece798c4c666db6fdddd88e9b2cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 18 Jan 2022 09:29:41 +0100 Subject: [PATCH 06/30] Fix type of temporary variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both functions use int. Using size_t results is a warning from MSVC. Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index 7afc2b39c789..52f33c79dfb8 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -123,7 +123,7 @@ static int cipher_prepare( const char *info, CHK( mbedtls_cipher_setup( ctx, mbedtls_cipher_info_from_type( type ) ) ); - size_t key_len = mbedtls_cipher_get_key_bitlen( ctx ); + int key_len = mbedtls_cipher_get_key_bitlen( ctx ); CHK( mbedtls_cipher_setkey( ctx, key_bytes, key_len, MBEDTLS_ENCRYPT ) ); exit: From aab5258b7adcc0b84c7bf8bb2f0f2fee7f80c59f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 18 Jan 2022 09:30:51 +0100 Subject: [PATCH 07/30] Avoid using %zu, not supported everywhere yet. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index 52f33c79dfb8..9af50eaa5fc4 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -141,7 +141,7 @@ static void cipher_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) : mode == MBEDTLS_MODE_CHACHAPOLY ? "ChachaPoly" : "???"; - printf( "cipher: %s, %d, %s, %zu\n", ciph, key_bits, mode_str, tag_len ); + printf( "cipher: %s, %d, %s, %u\n", ciph, key_bits, mode_str, (unsigned) tag_len ); } static int cipher_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, @@ -272,7 +272,8 @@ static void aead_info( psa_key_id_t key, psa_algorithm_t alg ) : base_alg == PSA_ALG_CHACHA20_POLY1305 ? "ChachaPoly" : "???"; - printf( "aead : %s, %zu, %s, %zu\n", type_str, key_bits, base_str, tag_len ); + printf( "aead : %s, %u, %s, %u\n", + type_str, (unsigned) key_bits, base_str, (unsigned) tag_len ); } static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, From 0e725c33d415604fe73def28c3daac646f042dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Jan 2022 11:15:33 +0100 Subject: [PATCH 08/30] Improve introductory comments. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 18 +++++++++--------- programs/psa/hmac_md_psa.c | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index 9af50eaa5fc4..c8716d8686f8 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -1,4 +1,7 @@ /* + * This is a simple example of multi-part AEAD computation using both the old + * Cipher API and the new PSA API; its goal is to help migration to PSA Crypto. + * * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 * @@ -16,15 +19,12 @@ */ /* - * This is a simple example of multi-part AEAD computation using both the old - * Cipher API and the new PSA API; its goal is to help migration to PSA Crypto. - * - * When in comes to multi-part HMAC operations, the `mbedtls_md_context` - * serves a triple purpose (1) hold the key, (2) store the algorithm, and (3) - * save progress information for the current operation. With PSA those roles - * are held by disinct objects: (1) a psa_key_id_t to hold the key, a (2) - * psa_algorithm_t to represent the algorithm, and (3) a psa_operation_t for - * multi-part progress. + * When used with multi-part AEAD operations, the `mbedtls_cipher_context` + * serves a triple purpose (1) hold the key, (2) store the algorithm when no + * operation is active, and (3) save progress information for the current + * operation. With PSA those roles are held by disinct objects: (1) a + * psa_key_id_t to hold the key, a (2) psa_algorithm_t to represent the + * algorithm, and (3) a psa_operation_t for multi-part progress. * * On the other hand, with PSA, the algorithms encodes the desired tag length; * with Cipher the desired tag length needs to be tracked separately. diff --git a/programs/psa/hmac_md_psa.c b/programs/psa/hmac_md_psa.c index 7230c20cdaa0..130705b33015 100644 --- a/programs/psa/hmac_md_psa.c +++ b/programs/psa/hmac_md_psa.c @@ -1,4 +1,7 @@ /* + * This is a simple example of multi-part HMAC computation using both the old + * MD API and the new PSA API; its goal is to help migration to PSA Crypto. + * * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 * @@ -16,9 +19,6 @@ */ /* - * This is a simple example of multi-part HMAC computation using both the old - * MD API and the new PSA API; its goal is to help migration to PSA Crypto. - * * When in comes to multi-part HMAC operations, the `mbedtls_md_context` * serves a dual purpose (1) hold the key, and (2) save progress information * for the current operation. With PSA those roles are held by two disinct @@ -26,7 +26,7 @@ * multi-part progress. * * This program illustrates this by doing the same sequence of multi-part HMAC - * computation with both APIs; looking at the two function md() and mac() side + * computation with both APIs; looking at the two functions md() and mac() side * by side should make the differences and similarities clear. */ From 428a97ed4749c2fad83a94bb97d3c317f78834e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Jan 2022 11:35:12 +0100 Subject: [PATCH 09/30] Improve option names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index c8716d8686f8..cd44ee0fa5e9 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -61,7 +61,7 @@ int main( void ) /* * Common data and helper functions */ -const char usage[] = "Usage: aead_cipher_psa [gcm128|gcm256|gcm128_8|chachapoly]"; +const char usage[] = "Usage: aead_cipher_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; const unsigned char iv1[12] = { 0x00 }; const unsigned char ad1[] = { 0x01, 0x02 }; @@ -103,13 +103,13 @@ static int cipher_prepare( const char *info, int ret; mbedtls_cipher_type_t type; - if( strcmp( info, "gcm128" ) == 0 ) { + if( strcmp( info, "aes128-gcm" ) == 0 ) { type = MBEDTLS_CIPHER_AES_128_GCM; *tag_len = 16; - } else if( strcmp( info, "gcm256" ) == 0 ) { + } else if( strcmp( info, "aes256-gcm" ) == 0 ) { type = MBEDTLS_CIPHER_AES_256_GCM; *tag_len = 16; - } else if( strcmp( info, "gcm128_8" ) == 0 ) { + } else if( strcmp( info, "aes128-gcm_8" ) == 0 ) { type = MBEDTLS_CIPHER_AES_128_GCM; *tag_len = 8; } else if( strcmp( info, "chachapoly" ) == 0 ) { @@ -223,15 +223,15 @@ static psa_status_t aead_prepare( const char *info, size_t key_bits; psa_key_type_t key_type; - if( strcmp( info, "gcm128" ) == 0 ) { + if( strcmp( info, "aes128-gcm" ) == 0 ) { *alg = PSA_ALG_GCM; key_bits = 128; key_type = PSA_KEY_TYPE_AES; - } else if( strcmp( info, "gcm256" ) == 0 ) { + } else if( strcmp( info, "aes256-gcm" ) == 0 ) { *alg = PSA_ALG_GCM; key_bits = 256; key_type = PSA_KEY_TYPE_AES; - } else if( strcmp( info, "gcm128_8" ) == 0 ) { + } else if( strcmp( info, "aes128-gcm_8" ) == 0 ) { *alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8); key_bits = 128; key_type = PSA_KEY_TYPE_AES; From beef9c231cde6ec9f96ec2ebb2a254ea52eb1e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Jan 2022 11:42:47 +0100 Subject: [PATCH 10/30] Use better names for dummy data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 32 +++++++++++++++------------ programs/psa/hmac_md_psa.c | 40 +++++++++++++++++----------------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index cd44ee0fa5e9..61f053033252 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -64,14 +64,14 @@ int main( void ) const char usage[] = "Usage: aead_cipher_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; const unsigned char iv1[12] = { 0x00 }; -const unsigned char ad1[] = { 0x01, 0x02 }; -const unsigned char pa1[] = { 0x03, 0x04 }; -const unsigned char pb1[] = { 0x05, 0x06, 0x07 }; +const unsigned char add_data1[] = { 0x01, 0x02 }; +const unsigned char msg1_part1[] = { 0x03, 0x04 }; +const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 }; const unsigned char iv2[12] = { 0x10 }; -const unsigned char ad2[] = { 0x11, 0x12 }; -const unsigned char pa2[] = { 0x13, 0x14 }; -const unsigned char pb2[] = { 0x15, 0x16, 0x17 }; +const unsigned char add_data2[] = { 0x11, 0x12 }; +const unsigned char msg2_part1[] = { 0x13, 0x14 }; +const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; const unsigned char key_bytes[32] = { 0x2a }; @@ -188,11 +188,13 @@ static int cipher( const char *info ) cipher_info( &ctx, tag_len ); CHK( cipher_encrypt( &ctx, tag_len, - iv1, sizeof( iv1 ), ad1, sizeof( ad1 ), - pa1, sizeof( pa1 ), pb1, sizeof( pb1 ) ) ); + iv1, sizeof( iv1 ), add_data1, sizeof( add_data1 ), + msg1_part1, sizeof( msg1_part1 ), + msg1_part2, sizeof( msg1_part2 ) ) ); CHK( cipher_encrypt( &ctx, tag_len, - iv2, sizeof( iv2 ), ad2, sizeof( ad2 ), - pa2, sizeof( pa2 ), pb2, sizeof( pb2 ) ) ); + iv2, sizeof( iv2 ), add_data2, sizeof( add_data2 ), + msg2_part1, sizeof( msg2_part1 ), + msg2_part2, sizeof( msg2_part2 ) ) ); exit: mbedtls_cipher_free( &ctx ); @@ -321,11 +323,13 @@ static psa_status_t aead( const char *info ) aead_info( key, alg ); CHK( aead_encrypt( key, alg, - iv1, sizeof( iv1 ), ad1, sizeof( ad1 ), - pa1, sizeof( pa1 ), pb1, sizeof( pb1 ) ) ); + iv1, sizeof( iv1 ), add_data1, sizeof( add_data1 ), + msg1_part1, sizeof( msg1_part1 ), + msg1_part2, sizeof( msg1_part2 ) ) ); CHK( aead_encrypt( key, alg, - iv2, sizeof( iv2 ), ad2, sizeof( ad2 ), - pa2, sizeof( pa2 ), pb2, sizeof( pb2 ) ) ); + iv2, sizeof( iv2 ), add_data2, sizeof( add_data2 ), + msg2_part1, sizeof( msg2_part1 ), + msg2_part2, sizeof( msg2_part2 ) ) ); exit: return( status ); diff --git a/programs/psa/hmac_md_psa.c b/programs/psa/hmac_md_psa.c index 130705b33015..003fb5c7d738 100644 --- a/programs/psa/hmac_md_psa.c +++ b/programs/psa/hmac_md_psa.c @@ -50,10 +50,10 @@ int main( void ) /* * Dummy inputs for HMAC */ -const unsigned char part1[] = { 0x01, 0x02 }; -const unsigned char part2[] = { 0x03, 0x04 }; -const unsigned char part3[] = { 0x05, 0x05 }; -const unsigned char part4[] = { 0x06, 0x06 }; +const unsigned char msg1_part1[] = { 0x01, 0x02 }; +const unsigned char msg1_part2[] = { 0x03, 0x04 }; +const unsigned char msg2_part1[] = { 0x05, 0x05 }; +const unsigned char msg2_part2[] = { 0x06, 0x06 }; const unsigned char key_bytes[32] = { 0 }; @@ -85,18 +85,18 @@ int md(void) CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 1 ) ); CHK( mbedtls_md_hmac_starts( &ctx, key_bytes, sizeof( key_bytes ) ) ); - /* compute HMAC(key, part 1 | part 2) */ - CHK( mbedtls_md_hmac_update( &ctx, part1, sizeof( part1 ) ) ); - CHK( mbedtls_md_hmac_update( &ctx, part2, sizeof( part2 ) ) ); + /* compute HMAC(key, msg1_part1 | msg1_part2) */ + CHK( mbedtls_md_hmac_update( &ctx, msg1_part1, sizeof( msg1_part1 ) ) ); + CHK( mbedtls_md_hmac_update( &ctx, msg1_part2, sizeof( msg1_part2 ) ) ); CHK( mbedtls_md_hmac_finish( &ctx, out ) ); - print_out( "12" ); + print_out( "msg1" ); - /* compute HMAC(key, part 3 | part 4) */ + /* compute HMAC(key, msg2_part1 | msg2_part2) */ CHK( mbedtls_md_hmac_reset( &ctx ) ); // prepare for new operation - CHK( mbedtls_md_hmac_update( &ctx, part3, sizeof( part3 ) ) ); - CHK( mbedtls_md_hmac_update( &ctx, part4, sizeof( part4 ) ) ); + CHK( mbedtls_md_hmac_update( &ctx, msg2_part1, sizeof( msg2_part1 ) ) ); + CHK( mbedtls_md_hmac_update( &ctx, msg2_part2, sizeof( msg2_part2 ) ) ); CHK( mbedtls_md_hmac_finish( &ctx, out ) ); - print_out( "34" ); + print_out( "msg2" ); exit: mbedtls_md_free( &ctx ); @@ -134,19 +134,19 @@ psa_status_t mac(void) psa_mac_operation_t op = PSA_MAC_OPERATION_INIT; size_t out_len = 0; - /* compute HMAC(key, part 1 | part 2) */ + /* compute HMAC(key, msg1_part1 | msg1_part2) */ CHK( psa_mac_sign_setup( &op, key, alg ) ); - CHK( psa_mac_update( &op, part1, sizeof( part1 ) ) ); - CHK( psa_mac_update( &op, part2, sizeof( part2 ) ) ); + CHK( psa_mac_update( &op, msg1_part1, sizeof( msg1_part1 ) ) ); + CHK( psa_mac_update( &op, msg1_part2, sizeof( msg1_part2 ) ) ); CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); - print_out( "12" ); + print_out( "msg1" ); - /* compute HMAC(key, part 3 | part 4) */ + /* compute HMAC(key, msg2_part1 | msg2_part2) */ CHK( psa_mac_sign_setup( &op, key, alg ) ); - CHK( psa_mac_update( &op, part3, sizeof( part3 ) ) ); - CHK( psa_mac_update( &op, part4, sizeof( part4 ) ) ); + CHK( psa_mac_update( &op, msg2_part1, sizeof( msg2_part1 ) ) ); + CHK( psa_mac_update( &op, msg2_part2, sizeof( msg2_part2 ) ) ); CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); - print_out( "34" ); + print_out( "msg2" ); exit: psa_mac_abort( &op ); From 3aae30c224e6fb5c6aebcc5ccdfaf28902f93b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Jan 2022 11:56:24 +0100 Subject: [PATCH 11/30] Use PSA macros for buffer sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index 61f053033252..a2b47d13d4d8 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -67,11 +67,15 @@ const unsigned char iv1[12] = { 0x00 }; const unsigned char add_data1[] = { 0x01, 0x02 }; const unsigned char msg1_part1[] = { 0x03, 0x04 }; const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 }; +const size_t msg1_size = sizeof( msg1_part1 ) + sizeof( msg1_part2 ); const unsigned char iv2[12] = { 0x10 }; const unsigned char add_data2[] = { 0x11, 0x12 }; const unsigned char msg2_part1[] = { 0x13, 0x14 }; const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; +const size_t msg2_size = sizeof( msg2_part1 ) + sizeof( msg2_part2 ); + +const size_t msg_max_size = msg1_size > msg2_size ? msg1_size : msg2_size; const unsigned char key_bytes[32] = { 0x2a }; @@ -152,7 +156,7 @@ static int cipher_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, { int ret; size_t olen; - unsigned char out[32]; + unsigned char out[msg_max_size + 16]; unsigned char *p = out; CHK( mbedtls_cipher_set_iv( ctx, iv, iv_len ) ); @@ -286,9 +290,9 @@ static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, { psa_status_t status; size_t olen, olen_tag; - unsigned char out[32]; + unsigned char out[PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(msg_max_size)]; unsigned char *p = out, *end = out + sizeof( out ); - unsigned char tag[16]; + unsigned char tag[PSA_AEAD_TAG_MAX_SIZE]; psa_aead_operation_t op = PSA_AEAD_OPERATION_INIT; CHK( psa_aead_encrypt_setup( &op, key, alg ) ); From 1a45c713f09415e51239a0af364b25e576433d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Jan 2022 12:17:20 +0100 Subject: [PATCH 12/30] Fix cleanup code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_cipher_psa.c | 5 +++++ programs/psa/hmac_md_psa.c | 1 + 2 files changed, 6 insertions(+) diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_cipher_psa.c index a2b47d13d4d8..bac3ea27d60e 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_cipher_psa.c @@ -311,7 +311,10 @@ static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, olen = p - out; print_out( "aead ", out, olen ); + exit: + /* required on errors, harmless on success */ + psa_aead_abort( &op ); return( status ); } @@ -336,6 +339,8 @@ static psa_status_t aead( const char *info ) msg2_part2, sizeof( msg2_part2 ) ) ); exit: + psa_destroy_key( key ); + return( status ); } diff --git a/programs/psa/hmac_md_psa.c b/programs/psa/hmac_md_psa.c index 003fb5c7d738..49e1eced7928 100644 --- a/programs/psa/hmac_md_psa.c +++ b/programs/psa/hmac_md_psa.c @@ -150,6 +150,7 @@ psa_status_t mac(void) exit: psa_mac_abort( &op ); + psa_destroy_key( key ); return( status ); } From edf6e83cbc11bcc8ff08793d740717ff9d738d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Jan 2022 12:36:39 +0100 Subject: [PATCH 13/30] Split hmac_md_psa.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having two programs might make comparison easier, and will make it easier to people to use just the PSA one as an example. Signed-off-by: Manuel Pégourié-Gonnard --- programs/.gitignore | 3 +- programs/Makefile | 13 ++- programs/psa/CMakeLists.txt | 3 +- programs/psa/hmac_non_psa.c | 113 +++++++++++++++++++++ programs/psa/{hmac_md_psa.c => hmac_psa.c} | 74 +++----------- 5 files changed, 140 insertions(+), 66 deletions(-) create mode 100644 programs/psa/hmac_non_psa.c rename programs/psa/{hmac_md_psa.c => hmac_psa.c} (64%) diff --git a/programs/.gitignore b/programs/.gitignore index a4ff337f49dd..27587be05f61 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -40,7 +40,8 @@ pkey/rsa_verify pkey/rsa_verify_pss psa/aead_cipher_psa psa/crypto_examples -psa/hmac_md_psa +psa/hmac_non_psa +psa/hmac_psa psa/key_ladder_demo psa/psa_constant_names random/gen_entropy diff --git a/programs/Makefile b/programs/Makefile index 62654a5a1ab6..b19f4d883e24 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -86,7 +86,8 @@ APPS = \ pkey/rsa_verify_pss \ psa/aead_cipher_psa \ psa/crypto_examples \ - psa/hmac_md_psa \ + psa/hmac_non_psa \ + psa/hmac_psa \ psa/key_ladder_demo \ psa/psa_constant_names \ random/gen_entropy \ @@ -271,9 +272,13 @@ 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 $@ -psa/hmac_md_psa$(EXEXT): psa/hmac_md_psa.c $(DEP) - echo " CC psa/hmac_md_psa.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/hmac_md_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +psa/hmac_non_psa$(EXEXT): psa/hmac_non_psa.c $(DEP) + echo " CC psa/hmac_non_psa.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/hmac_non_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + +psa/hmac_psa$(EXEXT): psa/hmac_psa.c $(DEP) + echo " CC psa/hmac_psa.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/hmac_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ psa/key_ladder_demo$(EXEXT): psa/key_ladder_demo.c $(DEP) echo " CC psa/key_ladder_demo.c" diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt index 450ef36689a8..6629670fbd58 100644 --- a/programs/psa/CMakeLists.txt +++ b/programs/psa/CMakeLists.txt @@ -1,7 +1,8 @@ set(executables aead_cipher_psa crypto_examples - hmac_md_psa + hmac_non_psa + hmac_psa key_ladder_demo psa_constant_names ) diff --git a/programs/psa/hmac_non_psa.c b/programs/psa/hmac_non_psa.c new file mode 100644 index 000000000000..c7ced7ca27d2 --- /dev/null +++ b/programs/psa/hmac_non_psa.c @@ -0,0 +1,113 @@ +/* + * This is a companion to hmac_psa.c, doing the same operations with the + * legacy MD API. The goal is that comparing the two programs will help people + * migrating to the PSA Crypto API. + * + * 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. + */ + +/* + * When in comes to multi-part HMAC operations, the `mbedtls_md_context` + * serves a dual purpose (1) hold the key, and (2) save progress information + * for the current operation. With PSA those roles are held by two disinct + * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for + * multi-part progress. + * + * This program and its companion hmac_psa.c illustrate this by doing the + * same sequence of multi-part HMAC computation with both APIs; looking at the + * two side by side should make the differences and similarities clear. + */ + +#include + +#include "mbedtls/build_info.h" + +#if !defined(MBEDTLS_MD_C) +int main( void ) +{ + printf( "MBEDTLS_MD_C not defined\r\n" ); + return( 0 ); +} +#else + +#include "mbedtls/md.h" + +/* + * Dummy inputs for HMAC + */ +const unsigned char msg1_part1[] = { 0x01, 0x02 }; +const unsigned char msg1_part2[] = { 0x03, 0x04 }; +const unsigned char msg2_part1[] = { 0x05, 0x05 }; +const unsigned char msg2_part2[] = { 0x06, 0x06 }; + +const unsigned char key_bytes[32] = { 0 }; + +unsigned char out[32]; + +void print_out( const char *title ) +{ + printf( "%s:", title ); + for( size_t i = 0; i < sizeof( out ); i++ ) + printf( " %02x", out[i] ); + printf( "\n" ); +} + +#define CHK( code ) \ + do { \ + ret = code; \ + if( ret != 0 ) \ + goto exit; \ + } while( 0 ) + +int hmac_demo(void) +{ + int ret; + mbedtls_md_context_t ctx; + + mbedtls_md_init( &ctx ); + + /* prepare context and load key */ + CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 1 ) ); + CHK( mbedtls_md_hmac_starts( &ctx, key_bytes, sizeof( key_bytes ) ) ); + + /* compute HMAC(key, msg1_part1 | msg1_part2) */ + CHK( mbedtls_md_hmac_update( &ctx, msg1_part1, sizeof( msg1_part1 ) ) ); + CHK( mbedtls_md_hmac_update( &ctx, msg1_part2, sizeof( msg1_part2 ) ) ); + CHK( mbedtls_md_hmac_finish( &ctx, out ) ); + print_out( "msg1" ); + + /* compute HMAC(key, msg2_part1 | msg2_part2) */ + CHK( mbedtls_md_hmac_reset( &ctx ) ); // prepare for new operation + CHK( mbedtls_md_hmac_update( &ctx, msg2_part1, sizeof( msg2_part1 ) ) ); + CHK( mbedtls_md_hmac_update( &ctx, msg2_part2, sizeof( msg2_part2 ) ) ); + CHK( mbedtls_md_hmac_finish( &ctx, out ) ); + print_out( "msg2" ); + +exit: + mbedtls_md_free( &ctx ); + + return( ret ); +} + +int main(void) +{ + int ret = hmac_demo(); + if( ret != 0 ) + printf( "ret = %d (-0x%04x)\n", ret, (unsigned) -ret ); + +} + +#endif diff --git a/programs/psa/hmac_md_psa.c b/programs/psa/hmac_psa.c similarity index 64% rename from programs/psa/hmac_md_psa.c rename to programs/psa/hmac_psa.c index 49e1eced7928..019b7ff54b8c 100644 --- a/programs/psa/hmac_md_psa.c +++ b/programs/psa/hmac_psa.c @@ -1,6 +1,8 @@ /* - * This is a simple example of multi-part HMAC computation using both the old - * MD API and the new PSA API; its goal is to help migration to PSA Crypto. + * This is a simple example of multi-part HMAC computation using the PSA + * Crypto API. It comes with a companion program hmac_non_psa.c, which does + * the same operations with the legacy MD API. The goal is that comparing the + * two programs will help people migrating to the PSA Crypto API. * * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 @@ -25,26 +27,25 @@ * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for * multi-part progress. * - * This program illustrates this by doing the same sequence of multi-part HMAC - * computation with both APIs; looking at the two functions md() and mac() side - * by side should make the differences and similarities clear. + * This program and its companion hmac_non_psa.c illustrate this by doing the + * same sequence of multi-part HMAC computation with both APIs; looking at the + * two side by side should make the differences and similarities clear. */ #include #include "mbedtls/build_info.h" -#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_MD_C) || \ +#if !defined(MBEDTLS_PSA_CRYPTO_C) || \ defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) int main( void ) { - printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_MD_C not defined, " + printf( "MBEDTLS_PSA_CRYPTO_C not defined, " "and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined\r\n" ); return( 0 ); } -#else /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_MD_C */ +#else -#include "mbedtls/md.h" #include "psa/crypto.h" /* @@ -67,45 +68,6 @@ void print_out( const char *title ) printf( "\n" ); } -#define CHK( code ) \ - do { \ - ret = code; \ - if( ret != 0 ) \ - goto exit; \ - } while( 0 ) - -int md(void) -{ - int ret; - mbedtls_md_context_t ctx; - - mbedtls_md_init( &ctx ); - - /* prepare context and load key */ - CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 1 ) ); - CHK( mbedtls_md_hmac_starts( &ctx, key_bytes, sizeof( key_bytes ) ) ); - - /* compute HMAC(key, msg1_part1 | msg1_part2) */ - CHK( mbedtls_md_hmac_update( &ctx, msg1_part1, sizeof( msg1_part1 ) ) ); - CHK( mbedtls_md_hmac_update( &ctx, msg1_part2, sizeof( msg1_part2 ) ) ); - CHK( mbedtls_md_hmac_finish( &ctx, out ) ); - print_out( "msg1" ); - - /* compute HMAC(key, msg2_part1 | msg2_part2) */ - CHK( mbedtls_md_hmac_reset( &ctx ) ); // prepare for new operation - CHK( mbedtls_md_hmac_update( &ctx, msg2_part1, sizeof( msg2_part1 ) ) ); - CHK( mbedtls_md_hmac_update( &ctx, msg2_part2, sizeof( msg2_part2 ) ) ); - CHK( mbedtls_md_hmac_finish( &ctx, out ) ); - print_out( "msg2" ); - -exit: - mbedtls_md_free( &ctx ); - - return( ret ); -} - -#undef CHK - #define CHK( code ) \ do { \ status = code; \ @@ -113,7 +75,7 @@ int md(void) goto exit; \ } while( 0 ) -psa_status_t mac(void) +psa_status_t hmac_demo(void) { psa_status_t status; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -155,23 +117,15 @@ psa_status_t mac(void) return( status ); } -#undef CHK - int main(void) { - printf( "MD\n" ); - int ret = md(); - if( ret != 0 ) - printf( "ret = %d (-0x%04x)\n", ret, (unsigned) -ret ); - psa_status_t status = psa_crypto_init(); if( status != PSA_SUCCESS ) printf( "psa init: %d\n", status ); - printf( "\nPSA\n" ); - status = mac(); + status = hmac_demo(); if( status != PSA_SUCCESS ) - printf( "psa mac: %d\n", status ); + printf( "hmac_demo: %d\n", status ); } -#endif /* MBEDTLS_PSA_CRYPTO_C && MBEDTLS_MD_C */ +#endif From 7d5ef1731b80a292418cf315517df9504baee5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Jan 2022 13:09:13 +0100 Subject: [PATCH 14/30] Split aead_cipher_psa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same as previous commit Signed-off-by: Manuel Pégourié-Gonnard --- programs/.gitignore | 3 +- programs/Makefile | 13 +- programs/psa/CMakeLists.txt | 3 +- programs/psa/aead_non_psa.c | 217 ++++++++++++++++++ .../psa/{aead_cipher_psa.c => aead_psa.c} | 162 ++----------- 5 files changed, 248 insertions(+), 150 deletions(-) create mode 100644 programs/psa/aead_non_psa.c rename programs/psa/{aead_cipher_psa.c => aead_psa.c} (61%) diff --git a/programs/.gitignore b/programs/.gitignore index 27587be05f61..670c2825e1c6 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -38,7 +38,8 @@ pkey/rsa_sign pkey/rsa_sign_pss pkey/rsa_verify pkey/rsa_verify_pss -psa/aead_cipher_psa +psa/aead_non_psa +psa/aead_psa psa/crypto_examples psa/hmac_non_psa psa/hmac_psa diff --git a/programs/Makefile b/programs/Makefile index b19f4d883e24..2f0d406f3aa0 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -84,7 +84,8 @@ APPS = \ pkey/rsa_sign_pss \ pkey/rsa_verify \ pkey/rsa_verify_pss \ - psa/aead_cipher_psa \ + psa/aead_non_psa \ + psa/aead_psa \ psa/crypto_examples \ psa/hmac_non_psa \ psa/hmac_psa \ @@ -264,9 +265,13 @@ pkey/rsa_encrypt$(EXEXT): pkey/rsa_encrypt.c $(DEP) echo " CC pkey/rsa_encrypt.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/rsa_encrypt.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -psa/aead_cipher_psa$(EXEXT): psa/aead_cipher_psa.c $(DEP) - echo " CC psa/aead_cipher_psa.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/aead_cipher_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +psa/aead_non_psa$(EXEXT): psa/aead_non_psa.c $(DEP) + echo " CC psa/aead_non_psa.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/aead_non_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + +psa/aead_psa$(EXEXT): psa/aead_psa.c $(DEP) + echo " CC psa/aead_psa.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/aead_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ psa/crypto_examples$(EXEXT): psa/crypto_examples.c $(DEP) echo " CC psa/crypto_examples.c" diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt index 6629670fbd58..462fcf643e6c 100644 --- a/programs/psa/CMakeLists.txt +++ b/programs/psa/CMakeLists.txt @@ -1,5 +1,6 @@ set(executables - aead_cipher_psa + aead_non_psa + aead_psa crypto_examples hmac_non_psa hmac_psa diff --git a/programs/psa/aead_non_psa.c b/programs/psa/aead_non_psa.c new file mode 100644 index 000000000000..260ea6b92a34 --- /dev/null +++ b/programs/psa/aead_non_psa.c @@ -0,0 +1,217 @@ +/* + * This is a companion to aead_psa.c, doing the same operations with the + * legacy Cipher API. The goal is that comparing the two programs will help people + * migrating to the PSA Crypto API. + * + * 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. + */ + +/* + * When used with multi-part AEAD operations, the `mbedtls_cipher_context` + * serves a triple purpose (1) hold the key, (2) store the algorithm when no + * operation is active, and (3) save progress information for the current + * operation. With PSA those roles are held by disinct objects: (1) a + * psa_key_id_t to hold the key, a (2) psa_algorithm_t to represent the + * algorithm, and (3) a psa_operation_t for multi-part progress. + * + * On the other hand, with PSA, the algorithms encodes the desired tag length; + * with Cipher the desired tag length needs to be tracked separately. + * + * This program and its compation aead_psa.c illustrate this by doing the + * same sequence of multi-part AEAD computation with both APIs; looking at the + * two side by side should make the differences and similarities clear. + */ + +#include + +#include "mbedtls/build_info.h" + +#if !defined(MBEDTLS_CIPHER_C) || \ + !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \ + !defined(MBEDTLS_CHACHAPOLY_C) +int main( void ) +{ + printf( "MBEDTLS_MD_C and/or " + "MBEDTLS_AES_C and/or MBEDTLS_GCM_C and/or " + "MBEDTLS_CHACHAPOLY_C not defined\r\n" ); + return( 0 ); +} +#else + +#include + +#include "mbedtls/cipher.h" + +/* + * Dummy data and helper functions + */ +const char usage[] = "Usage: aead_non_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; + +const unsigned char iv1[12] = { 0x00 }; +const unsigned char add_data1[] = { 0x01, 0x02 }; +const unsigned char msg1_part1[] = { 0x03, 0x04 }; +const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 }; +const size_t msg1_size = sizeof( msg1_part1 ) + sizeof( msg1_part2 ); + +const unsigned char iv2[12] = { 0x10 }; +const unsigned char add_data2[] = { 0x11, 0x12 }; +const unsigned char msg2_part1[] = { 0x13, 0x14 }; +const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; +const size_t msg2_size = sizeof( msg2_part1 ) + sizeof( msg2_part2 ); + +const size_t msg_max_size = msg1_size > msg2_size ? msg1_size : msg2_size; + +const unsigned char key_bytes[32] = { 0x2a }; + +void print_out( const char *title, unsigned char *out, size_t len ) +{ + printf( "%s:", title ); + for( size_t i = 0; i < len; i++ ) + printf( " %02x", out[i] ); + printf( "\n" ); +} + +#define CHK( code ) \ + do { \ + ret = code; \ + if( ret != 0 ) { \ + printf( "%03d: ret = -0x%04x\n", __LINE__, (unsigned) -ret ); \ + goto exit; \ + } \ + } while( 0 ) + +static int aead_prepare( const char *info, + mbedtls_cipher_context_t *ctx, + size_t *tag_len ) +{ + int ret; + + mbedtls_cipher_type_t type; + if( strcmp( info, "aes128-gcm" ) == 0 ) { + type = MBEDTLS_CIPHER_AES_128_GCM; + *tag_len = 16; + } else if( strcmp( info, "aes256-gcm" ) == 0 ) { + type = MBEDTLS_CIPHER_AES_256_GCM; + *tag_len = 16; + } else if( strcmp( info, "aes128-gcm_8" ) == 0 ) { + type = MBEDTLS_CIPHER_AES_128_GCM; + *tag_len = 8; + } else if( strcmp( info, "chachapoly" ) == 0 ) { + type = MBEDTLS_CIPHER_CHACHA20_POLY1305; + *tag_len = 16; + } else { + puts( usage ); + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + CHK( mbedtls_cipher_setup( ctx, + mbedtls_cipher_info_from_type( type ) ) ); + + int key_len = mbedtls_cipher_get_key_bitlen( ctx ); + CHK( mbedtls_cipher_setkey( ctx, key_bytes, key_len, MBEDTLS_ENCRYPT ) ); + +exit: + return( ret ); +} + +static void aead_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) +{ + // no convenient way to get the cipher type (for example, AES) + const char *ciph = "???"; + int key_bits = mbedtls_cipher_get_key_bitlen( ctx ); + mbedtls_cipher_mode_t mode = mbedtls_cipher_get_cipher_mode( ctx ); + + const char *mode_str = mode == MBEDTLS_MODE_GCM ? "GCM" + : mode == MBEDTLS_MODE_CHACHAPOLY ? "ChachaPoly" + : "???"; + + printf( "cipher: %s, %d, %s, %u\n", ciph, key_bits, mode_str, (unsigned) tag_len ); +} + +static int aead_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *pa, size_t pa_len, + const unsigned char *pb, size_t pb_len ) +{ + int ret; + size_t olen; + unsigned char out[msg_max_size + 16]; + unsigned char *p = out; + + CHK( mbedtls_cipher_set_iv( ctx, iv, iv_len ) ); + CHK( mbedtls_cipher_reset( ctx ) ); + CHK( mbedtls_cipher_update_ad( ctx, ad, ad_len ) ); + CHK( mbedtls_cipher_update( ctx, pa, pa_len, p, &olen ) ); + p += olen; + CHK( mbedtls_cipher_update( ctx, pb, pb_len, p, &olen ) ); + p += olen; + CHK( mbedtls_cipher_finish( ctx, p, &olen ) ); + p += olen; + CHK( mbedtls_cipher_write_tag( ctx, p, tag_len ) ); + p += tag_len; + + olen = p - out; + print_out( "cipher", out, olen ); + +exit: + return( ret ); +} + +static int aead_demo( const char *info ) +{ + int ret = 0; + + mbedtls_cipher_context_t ctx; + size_t tag_len; + + mbedtls_cipher_init( &ctx ); + + CHK( aead_prepare( info, &ctx, &tag_len ) ); + + aead_info( &ctx, tag_len ); + + CHK( aead_encrypt( &ctx, tag_len, + iv1, sizeof( iv1 ), add_data1, sizeof( add_data1 ), + msg1_part1, sizeof( msg1_part1 ), + msg1_part2, sizeof( msg1_part2 ) ) ); + CHK( aead_encrypt( &ctx, tag_len, + iv2, sizeof( iv2 ), add_data2, sizeof( add_data2 ), + msg2_part1, sizeof( msg2_part1 ), + msg2_part2, sizeof( msg2_part2 ) ) ); + +exit: + mbedtls_cipher_free( &ctx ); + + return( ret ); +} + + +/* + * Main function + */ +int main( int argc, char **argv ) +{ + if( argc != 2 ) + { + puts( usage ); + return( 1 ); + } + + aead_demo( argv[1] ); +} + +#endif diff --git a/programs/psa/aead_cipher_psa.c b/programs/psa/aead_psa.c similarity index 61% rename from programs/psa/aead_cipher_psa.c rename to programs/psa/aead_psa.c index bac3ea27d60e..ebc7cd9d4836 100644 --- a/programs/psa/aead_cipher_psa.c +++ b/programs/psa/aead_psa.c @@ -1,6 +1,8 @@ /* - * This is a simple example of multi-part AEAD computation using both the old - * Cipher API and the new PSA API; its goal is to help migration to PSA Crypto. + * This is a simple example of multi-part AEAD computation using the PSA + * Crypto API. It comes with a companion program aead_non_psa.c, which does + * the same operations with the legacy Cipher API. The goal is that comparing the + * two programs will help people migrating to the PSA Crypto API. * * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 @@ -29,23 +31,22 @@ * On the other hand, with PSA, the algorithms encodes the desired tag length; * with Cipher the desired tag length needs to be tracked separately. * - * This program illustrates this by doing the same sequence of multi-part AEAD - * computation with both APIs; looking at the two series of functions - * cipher_xxx() and aead_xxx() side by side should make the differences and - * similarities clear. + * This program and its compation aead_non_psa.c illustrate this by doing the + * same sequence of multi-part AEAD computation with both APIs; looking at the + * two side by side should make the differences and similarities clear. */ #include #include "mbedtls/build_info.h" -#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_CIPHER_C) || \ +#if !defined(MBEDTLS_PSA_CRYPTO_C) || \ !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \ !defined(MBEDTLS_CHACHAPOLY_C) || \ defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) int main( void ) { - printf( "MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_MD_C and/or " + printf( "MBEDTLS_PSA_CRYPTO_C and/or " "MBEDTLS_AES_C and/or MBEDTLS_GCM_C and/or " "MBEDTLS_CHACHAPOLY_C not defined, and/or " "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined\r\n" ); @@ -55,13 +56,12 @@ int main( void ) #include -#include "mbedtls/cipher.h" #include "psa/crypto.h" /* - * Common data and helper functions + * Dummy data and helper functions */ -const char usage[] = "Usage: aead_cipher_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; +const char usage[] = "Usage: aead_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; const unsigned char iv1[12] = { 0x00 }; const unsigned char add_data1[] = { 0x01, 0x02 }; @@ -87,131 +87,6 @@ void print_out( const char *title, unsigned char *out, size_t len ) printf( "\n" ); } -/* - * Functions using the Cipher API - */ -#define CHK( code ) \ - do { \ - ret = code; \ - if( ret != 0 ) { \ - printf( "%03d: ret = -0x%04x\n", __LINE__, (unsigned) -ret ); \ - goto exit; \ - } \ - } while( 0 ) - - -static int cipher_prepare( const char *info, - mbedtls_cipher_context_t *ctx, - size_t *tag_len ) -{ - int ret; - - mbedtls_cipher_type_t type; - if( strcmp( info, "aes128-gcm" ) == 0 ) { - type = MBEDTLS_CIPHER_AES_128_GCM; - *tag_len = 16; - } else if( strcmp( info, "aes256-gcm" ) == 0 ) { - type = MBEDTLS_CIPHER_AES_256_GCM; - *tag_len = 16; - } else if( strcmp( info, "aes128-gcm_8" ) == 0 ) { - type = MBEDTLS_CIPHER_AES_128_GCM; - *tag_len = 8; - } else if( strcmp( info, "chachapoly" ) == 0 ) { - type = MBEDTLS_CIPHER_CHACHA20_POLY1305; - *tag_len = 16; - } else { - puts( usage ); - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - CHK( mbedtls_cipher_setup( ctx, - mbedtls_cipher_info_from_type( type ) ) ); - - int key_len = mbedtls_cipher_get_key_bitlen( ctx ); - CHK( mbedtls_cipher_setkey( ctx, key_bytes, key_len, MBEDTLS_ENCRYPT ) ); - -exit: - return( ret ); -} - -static void cipher_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) -{ - // no convenient way to get the cipher type (for example, AES) - const char *ciph = "???"; - int key_bits = mbedtls_cipher_get_key_bitlen( ctx ); - mbedtls_cipher_mode_t mode = mbedtls_cipher_get_cipher_mode( ctx ); - - const char *mode_str = mode == MBEDTLS_MODE_GCM ? "GCM" - : mode == MBEDTLS_MODE_CHACHAPOLY ? "ChachaPoly" - : "???"; - - printf( "cipher: %s, %d, %s, %u\n", ciph, key_bits, mode_str, (unsigned) tag_len ); -} - -static int cipher_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *pa, size_t pa_len, - const unsigned char *pb, size_t pb_len ) -{ - int ret; - size_t olen; - unsigned char out[msg_max_size + 16]; - unsigned char *p = out; - - CHK( mbedtls_cipher_set_iv( ctx, iv, iv_len ) ); - CHK( mbedtls_cipher_reset( ctx ) ); - CHK( mbedtls_cipher_update_ad( ctx, ad, ad_len ) ); - CHK( mbedtls_cipher_update( ctx, pa, pa_len, p, &olen ) ); - p += olen; - CHK( mbedtls_cipher_update( ctx, pb, pb_len, p, &olen ) ); - p += olen; - CHK( mbedtls_cipher_finish( ctx, p, &olen ) ); - p += olen; - CHK( mbedtls_cipher_write_tag( ctx, p, tag_len ) ); - p += tag_len; - - olen = p - out; - print_out( "cipher", out, olen ); - -exit: - return( ret ); -} - -static int cipher( const char *info ) -{ - int ret = 0; - - mbedtls_cipher_context_t ctx; - size_t tag_len; - - mbedtls_cipher_init( &ctx ); - - CHK( cipher_prepare( info, &ctx, &tag_len ) ); - - cipher_info( &ctx, tag_len ); - - CHK( cipher_encrypt( &ctx, tag_len, - iv1, sizeof( iv1 ), add_data1, sizeof( add_data1 ), - msg1_part1, sizeof( msg1_part1 ), - msg1_part2, sizeof( msg1_part2 ) ) ); - CHK( cipher_encrypt( &ctx, tag_len, - iv2, sizeof( iv2 ), add_data2, sizeof( add_data2 ), - msg2_part1, sizeof( msg2_part1 ), - msg2_part2, sizeof( msg2_part2 ) ) ); - -exit: - mbedtls_cipher_free( &ctx ); - - return( ret ); -} - -#undef CHK - -/* - * Functions using the PSA Crypto API - */ - #define CHK( code ) \ do { \ status = code; \ @@ -278,7 +153,7 @@ static void aead_info( psa_key_id_t key, psa_algorithm_t alg ) : base_alg == PSA_ALG_CHACHA20_POLY1305 ? "ChachaPoly" : "???"; - printf( "aead : %s, %u, %s, %u\n", + printf( "%s, %u, %s, %u\n", type_str, (unsigned) key_bits, base_str, (unsigned) tag_len ); } @@ -310,7 +185,7 @@ static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, p += olen_tag; olen = p - out; - print_out( "aead ", out, olen ); + print_out( "out", out, olen ); exit: /* required on errors, harmless on success */ @@ -318,7 +193,7 @@ static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, return( status ); } -static psa_status_t aead( const char *info ) +static psa_status_t aead_demo( const char *info ) { psa_status_t status; @@ -344,8 +219,6 @@ static psa_status_t aead( const char *info ) return( status ); } -#undef CHK - /* * Main function */ @@ -357,10 +230,11 @@ int main( int argc, char **argv ) return( 1 ); } - psa_crypto_init(); + psa_status_t status = psa_crypto_init(); + if( status != PSA_SUCCESS ) + printf( "psa init: %d\n", status ); - cipher( argv[1] ); - aead( argv[1] ); + aead_demo( argv[1] ); } #endif From fd1d13c8bd37d2fa03e8c3ca7469717e0ae379fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 28 Jan 2022 12:52:35 +0100 Subject: [PATCH 15/30] Avoid requiring too much C99 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MSVC 2013, still supported and used in our CI, did not support that. aead_psa.c(78): error C2099: initializer is not a constant aead_psa.c(168): error C2057: expected constant expression aead_psa.c(168): error C2466: cannot allocate an array of constant size 0 aead_psa.c(168): error C2133: 'out' : unknown size aead_psa.c(169): warning C4034: sizeof returns 0 Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_non_psa.c | 6 ++---- programs/psa/aead_psa.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/programs/psa/aead_non_psa.c b/programs/psa/aead_non_psa.c index 260ea6b92a34..4b48b3a989ce 100644 --- a/programs/psa/aead_non_psa.c +++ b/programs/psa/aead_non_psa.c @@ -64,15 +64,13 @@ const unsigned char iv1[12] = { 0x00 }; const unsigned char add_data1[] = { 0x01, 0x02 }; const unsigned char msg1_part1[] = { 0x03, 0x04 }; const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 }; -const size_t msg1_size = sizeof( msg1_part1 ) + sizeof( msg1_part2 ); const unsigned char iv2[12] = { 0x10 }; const unsigned char add_data2[] = { 0x11, 0x12 }; const unsigned char msg2_part1[] = { 0x13, 0x14 }; const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; -const size_t msg2_size = sizeof( msg2_part1 ) + sizeof( msg2_part2 ); -const size_t msg_max_size = msg1_size > msg2_size ? msg1_size : msg2_size; +#define MSG_MAX_SIZE 5 const unsigned char key_bytes[32] = { 0x2a }; @@ -149,7 +147,7 @@ static int aead_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, { int ret; size_t olen; - unsigned char out[msg_max_size + 16]; + unsigned char out[MSG_MAX_SIZE + 16]; unsigned char *p = out; CHK( mbedtls_cipher_set_iv( ctx, iv, iv_len ) ); diff --git a/programs/psa/aead_psa.c b/programs/psa/aead_psa.c index ebc7cd9d4836..5ed32a5f6ace 100644 --- a/programs/psa/aead_psa.c +++ b/programs/psa/aead_psa.c @@ -67,15 +67,13 @@ const unsigned char iv1[12] = { 0x00 }; const unsigned char add_data1[] = { 0x01, 0x02 }; const unsigned char msg1_part1[] = { 0x03, 0x04 }; const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 }; -const size_t msg1_size = sizeof( msg1_part1 ) + sizeof( msg1_part2 ); const unsigned char iv2[12] = { 0x10 }; const unsigned char add_data2[] = { 0x11, 0x12 }; const unsigned char msg2_part1[] = { 0x13, 0x14 }; const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; -const size_t msg2_size = sizeof( msg2_part1 ) + sizeof( msg2_part2 ); -const size_t msg_max_size = msg1_size > msg2_size ? msg1_size : msg2_size; +#define MSG_MAX_SIZE 5 const unsigned char key_bytes[32] = { 0x2a }; @@ -165,7 +163,7 @@ static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, { psa_status_t status; size_t olen, olen_tag; - unsigned char out[PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(msg_max_size)]; + unsigned char out[PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(MSG_MAX_SIZE)]; unsigned char *p = out, *end = out + sizeof( out ); unsigned char tag[PSA_AEAD_TAG_MAX_SIZE]; From f392a02c50ad469b54d2672e76d8c61885f049bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 31 Jan 2022 12:06:07 +0100 Subject: [PATCH 16/30] Add comments to the HMAC (non-)PSA examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also clean up / align the structure on existing examples. Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/hmac_non_psa.c | 79 ++++++++++++++++-------- programs/psa/hmac_psa.c | 119 +++++++++++++++++++++++------------- 2 files changed, 128 insertions(+), 70 deletions(-) diff --git a/programs/psa/hmac_non_psa.c b/programs/psa/hmac_non_psa.c index c7ced7ca27d2..0b4eff50e207 100644 --- a/programs/psa/hmac_non_psa.c +++ b/programs/psa/hmac_non_psa.c @@ -1,8 +1,24 @@ -/* +/** + * MD API multi-part HMAC demonstration. + * + * This programs computes the HMAC of two messages using the multi-part API. + * * This is a companion to hmac_psa.c, doing the same operations with the * legacy MD API. The goal is that comparing the two programs will help people * migrating to the PSA Crypto API. * + * When it comes to multi-part HMAC operations, the `mbedtls_md_context` + * serves a dual purpose (1) hold the key, and (2) save progress information + * for the current operation. With PSA those roles are held by two disinct + * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for + * multi-part progress. + * + * This program and its companion hmac_non_psa.c illustrate this by doing the + * same sequence of multi-part HMAC computation with both APIs; looking at the + * two side by side should make the differences and similarities clear. + */ + +/* * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 * @@ -19,22 +35,17 @@ * limitations under the License. */ -/* - * When in comes to multi-part HMAC operations, the `mbedtls_md_context` - * serves a dual purpose (1) hold the key, and (2) save progress information - * for the current operation. With PSA those roles are held by two disinct - * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for - * multi-part progress. - * - * This program and its companion hmac_psa.c illustrate this by doing the - * same sequence of multi-part HMAC computation with both APIs; looking at the - * two side by side should make the differences and similarities clear. - */ +/* First include Mbed TLS headers to get the Mbed TLS configuration and + * platform definitions that we'll use in this program. Also include + * standard C headers for functions we'll use here. */ +#include "mbedtls/build_info.h" -#include +#include "mbedtls/md.h" -#include "mbedtls/build_info.h" +#include +#include +/* If the build options we need are not enabled, compile a placeholder. */ #if !defined(MBEDTLS_MD_C) int main( void ) { @@ -43,20 +54,22 @@ int main( void ) } #else -#include "mbedtls/md.h" +/* The real program starts here. */ -/* - * Dummy inputs for HMAC - */ +/* Dummy inputs for HMAC */ const unsigned char msg1_part1[] = { 0x01, 0x02 }; const unsigned char msg1_part2[] = { 0x03, 0x04 }; const unsigned char msg2_part1[] = { 0x05, 0x05 }; const unsigned char msg2_part2[] = { 0x06, 0x06 }; +/* Dummy key material - never do this in production! + * This example program uses SHA-256, so a 32-byte key makes sense. */ const unsigned char key_bytes[32] = { 0 }; +/* Buffer for the output - using SHA-256, so 32-byte output */ unsigned char out[32]; +/* Print the contents of the output buffer in hex */ void print_out( const char *title ) { printf( "%s:", title ); @@ -65,13 +78,25 @@ void print_out( const char *title ) printf( "\n" ); } -#define CHK( code ) \ - do { \ - ret = code; \ - if( ret != 0 ) \ - goto exit; \ +/* Run an Mbed TLS function and bail out if it fails. */ +#define CHK( expr ) \ + do \ + { \ + ret = ( expr ); \ + if( ret != 0 ) \ + { \ + printf( "Error %d at line %d: %s\n", \ + ret, \ + __LINE__, \ + #expr ); \ + goto exit; \ + } \ } while( 0 ) +/* + * This function demonstrates computation of the HMAC of two messages using + * the multipart API. + */ int hmac_demo(void) { int ret; @@ -104,10 +129,12 @@ int hmac_demo(void) int main(void) { - int ret = hmac_demo(); - if( ret != 0 ) - printf( "ret = %d (-0x%04x)\n", ret, (unsigned) -ret ); + int ret; + CHK( hmac_demo() ); + +exit: + return( ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE ); } #endif diff --git a/programs/psa/hmac_psa.c b/programs/psa/hmac_psa.c index 019b7ff54b8c..7bf69ab0911a 100644 --- a/programs/psa/hmac_psa.c +++ b/programs/psa/hmac_psa.c @@ -1,9 +1,24 @@ -/* - * This is a simple example of multi-part HMAC computation using the PSA - * Crypto API. It comes with a companion program hmac_non_psa.c, which does - * the same operations with the legacy MD API. The goal is that comparing the - * two programs will help people migrating to the PSA Crypto API. +/** + * PSA API multi-part HMAC demonstration. + * + * This programs computes the HMAC of two messages using the multi-part API. + * + * It comes with a companion program hmac_non_psa.c, which does the same + * operations with the legacy MD API. The goal is that comparing the two + * programs will help people migrating to the PSA Crypto API. + * + * When it comes to multi-part HMAC operations, the `mbedtls_md_context` + * serves a dual purpose (1) hold the key, and (2) save progress information + * for the current operation. With PSA those roles are held by two disinct + * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for + * multi-part progress. * + * This program and its companion hmac_non_psa.c illustrate this by doing the + * same sequence of multi-part HMAC computation with both APIs; looking at the + * two side by side should make the differences and similarities clear. + */ + +/* * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 * @@ -20,22 +35,17 @@ * limitations under the License. */ -/* - * When in comes to multi-part HMAC operations, the `mbedtls_md_context` - * serves a dual purpose (1) hold the key, and (2) save progress information - * for the current operation. With PSA those roles are held by two disinct - * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for - * multi-part progress. - * - * This program and its companion hmac_non_psa.c illustrate this by doing the - * same sequence of multi-part HMAC computation with both APIs; looking at the - * two side by side should make the differences and similarities clear. - */ +/* First include Mbed TLS headers to get the Mbed TLS configuration and + * platform definitions that we'll use in this program. Also include + * standard C headers for functions we'll use here. */ +#include "mbedtls/build_info.h" -#include +#include "psa/crypto.h" -#include "mbedtls/build_info.h" +#include +#include +/* If the build options we need are not enabled, compile a placeholder. */ #if !defined(MBEDTLS_PSA_CRYPTO_C) || \ defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) int main( void ) @@ -46,20 +56,22 @@ int main( void ) } #else -#include "psa/crypto.h" +/* The real program starts here. */ -/* - * Dummy inputs for HMAC - */ +/* Dummy inputs for HMAC */ const unsigned char msg1_part1[] = { 0x01, 0x02 }; const unsigned char msg1_part2[] = { 0x03, 0x04 }; const unsigned char msg2_part1[] = { 0x05, 0x05 }; const unsigned char msg2_part2[] = { 0x06, 0x06 }; +/* Dummy key material - never do this in production! + * This example program uses SHA-256, so a 32-byte key makes sense. */ const unsigned char key_bytes[32] = { 0 }; +/* Buffer for the output - using SHA-256, so 32-byte output */ unsigned char out[32]; +/* Print the contents of the output buffer in hex */ void print_out( const char *title ) { printf( "%s:", title ); @@ -68,13 +80,26 @@ void print_out( const char *title ) printf( "\n" ); } -#define CHK( code ) \ - do { \ - status = code; \ - if( status != PSA_SUCCESS ) \ - goto exit; \ - } while( 0 ) +/* Run a PSA function and bail out if it fails. */ +#define PSA_CHECK( expr ) \ + do \ + { \ + status = ( expr ); \ + if( status != PSA_SUCCESS ) \ + { \ + printf( "Error %d at line %d: %s\n", \ + (int) status, \ + __LINE__, \ + #expr ); \ + goto exit; \ + } \ + } \ + while( 0 ) +/* + * This function demonstrates computation of the HMAC of two messages using + * the multipart API. + */ psa_status_t hmac_demo(void) { psa_status_t status; @@ -86,7 +111,7 @@ psa_status_t hmac_demo(void) psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE ); psa_set_key_algorithm( &attributes, alg ); psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); - psa_set_key_bits( &attributes, 8 * sizeof( key_bytes ) ); + psa_set_key_bits( &attributes, 8 * sizeof( key_bytes ) ); // optional status = psa_import_key( &attributes, key_bytes, sizeof( key_bytes ), &key ); if( status != PSA_SUCCESS ) @@ -97,21 +122,21 @@ psa_status_t hmac_demo(void) size_t out_len = 0; /* compute HMAC(key, msg1_part1 | msg1_part2) */ - CHK( psa_mac_sign_setup( &op, key, alg ) ); - CHK( psa_mac_update( &op, msg1_part1, sizeof( msg1_part1 ) ) ); - CHK( psa_mac_update( &op, msg1_part2, sizeof( msg1_part2 ) ) ); - CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); + PSA_CHECK( psa_mac_sign_setup( &op, key, alg ) ); + PSA_CHECK( psa_mac_update( &op, msg1_part1, sizeof( msg1_part1 ) ) ); + PSA_CHECK( psa_mac_update( &op, msg1_part2, sizeof( msg1_part2 ) ) ); + PSA_CHECK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); print_out( "msg1" ); /* compute HMAC(key, msg2_part1 | msg2_part2) */ - CHK( psa_mac_sign_setup( &op, key, alg ) ); - CHK( psa_mac_update( &op, msg2_part1, sizeof( msg2_part1 ) ) ); - CHK( psa_mac_update( &op, msg2_part2, sizeof( msg2_part2 ) ) ); - CHK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); + PSA_CHECK( psa_mac_sign_setup( &op, key, alg ) ); + PSA_CHECK( psa_mac_update( &op, msg2_part1, sizeof( msg2_part1 ) ) ); + PSA_CHECK( psa_mac_update( &op, msg2_part2, sizeof( msg2_part2 ) ) ); + PSA_CHECK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); print_out( "msg2" ); exit: - psa_mac_abort( &op ); + psa_mac_abort( &op ); // needed on error, harmless on success psa_destroy_key( key ); return( status ); @@ -119,13 +144,19 @@ psa_status_t hmac_demo(void) int main(void) { - psa_status_t status = psa_crypto_init(); - if( status != PSA_SUCCESS ) - printf( "psa init: %d\n", status ); + psa_status_t status = PSA_SUCCESS; - status = hmac_demo(); - if( status != PSA_SUCCESS ) - printf( "hmac_demo: %d\n", status ); + /* Initialize the PSA crypto library. */ + PSA_CHECK( psa_crypto_init( ) ); + + /* Run the demo */ + PSA_CHECK( hmac_demo() ); + + /* Deinitialize the PSA crypto library. */ + mbedtls_psa_crypto_free( ); + +exit: + return( status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE ); } #endif From 634979464814b7894837064261f9377d1c6348fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 31 Jan 2022 12:23:37 +0100 Subject: [PATCH 17/30] Demonstrate better practices in HMAC examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - avoid hardcoded sizes when there's a macro for that - avoid mutable global variables - zeroize potentially-sensitive local buffer on exit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/hmac_non_psa.c | 24 ++++++++++++++---------- programs/psa/hmac_psa.c | 25 +++++++++++++++---------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/programs/psa/hmac_non_psa.c b/programs/psa/hmac_non_psa.c index 0b4eff50e207..66fcf7e2f533 100644 --- a/programs/psa/hmac_non_psa.c +++ b/programs/psa/hmac_non_psa.c @@ -42,6 +42,8 @@ #include "mbedtls/md.h" +#include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize + #include #include @@ -66,15 +68,12 @@ const unsigned char msg2_part2[] = { 0x06, 0x06 }; * This example program uses SHA-256, so a 32-byte key makes sense. */ const unsigned char key_bytes[32] = { 0 }; -/* Buffer for the output - using SHA-256, so 32-byte output */ -unsigned char out[32]; - -/* Print the contents of the output buffer in hex */ -void print_out( const char *title ) +/* Print the contents of a buffer in hex */ +void print_buf( const char *title, unsigned char *buf, size_t len ) { printf( "%s:", title ); - for( size_t i = 0; i < sizeof( out ); i++ ) - printf( " %02x", out[i] ); + for( size_t i = 0; i < len; i++ ) + printf( " %02x", buf[i] ); printf( "\n" ); } @@ -100,29 +99,34 @@ void print_out( const char *title ) int hmac_demo(void) { int ret; + const mbedtls_md_type_t alg = MBEDTLS_MD_SHA256; + unsigned char out[MBEDTLS_MD_MAX_SIZE]; // safe but not optimal + mbedtls_md_context_t ctx; mbedtls_md_init( &ctx ); /* prepare context and load key */ - CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 1 ) ); + // the last argument to setup is 1 to enable HMAC (not just hashing) + CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( alg ), 1 ) ); CHK( mbedtls_md_hmac_starts( &ctx, key_bytes, sizeof( key_bytes ) ) ); /* compute HMAC(key, msg1_part1 | msg1_part2) */ CHK( mbedtls_md_hmac_update( &ctx, msg1_part1, sizeof( msg1_part1 ) ) ); CHK( mbedtls_md_hmac_update( &ctx, msg1_part2, sizeof( msg1_part2 ) ) ); CHK( mbedtls_md_hmac_finish( &ctx, out ) ); - print_out( "msg1" ); + print_buf( "msg1", out, sizeof( out ) ); /* compute HMAC(key, msg2_part1 | msg2_part2) */ CHK( mbedtls_md_hmac_reset( &ctx ) ); // prepare for new operation CHK( mbedtls_md_hmac_update( &ctx, msg2_part1, sizeof( msg2_part1 ) ) ); CHK( mbedtls_md_hmac_update( &ctx, msg2_part2, sizeof( msg2_part2 ) ) ); CHK( mbedtls_md_hmac_finish( &ctx, out ) ); - print_out( "msg2" ); + print_buf( "msg2", out, sizeof( out ) ); exit: mbedtls_md_free( &ctx ); + mbedtls_platform_zeroize( out, sizeof( out ) ); return( ret ); } diff --git a/programs/psa/hmac_psa.c b/programs/psa/hmac_psa.c index 7bf69ab0911a..c943110dbf7b 100644 --- a/programs/psa/hmac_psa.c +++ b/programs/psa/hmac_psa.c @@ -42,6 +42,8 @@ #include "psa/crypto.h" +#include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize + #include #include @@ -68,15 +70,12 @@ const unsigned char msg2_part2[] = { 0x06, 0x06 }; * This example program uses SHA-256, so a 32-byte key makes sense. */ const unsigned char key_bytes[32] = { 0 }; -/* Buffer for the output - using SHA-256, so 32-byte output */ -unsigned char out[32]; - -/* Print the contents of the output buffer in hex */ -void print_out( const char *title ) +/* Print the contents of a buffer in hex */ +void print_buf( const char *title, uint8_t *buf, size_t len ) { printf( "%s:", title ); - for( size_t i = 0; i < sizeof( out ); i++ ) - printf( " %02x", out[i] ); + for( size_t i = 0; i < len; i++ ) + printf( " %02x", buf[i] ); printf( "\n" ); } @@ -103,9 +102,14 @@ void print_out( const char *title ) psa_status_t hmac_demo(void) { psa_status_t status; +#define ALG PSA_ALG_HMAC(PSA_ALG_SHA_256) + const psa_algorithm_t alg = ALG; + // compilers with insufficient C99 support don't accept the const variable + // 'alg' here, so use a macro instead in order to pacify them + uint8_t out[PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 8 * sizeof( key_bytes ), ALG)]; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_key_id_t key = 0; - psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256); /* prepare key */ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE ); @@ -126,18 +130,19 @@ psa_status_t hmac_demo(void) PSA_CHECK( psa_mac_update( &op, msg1_part1, sizeof( msg1_part1 ) ) ); PSA_CHECK( psa_mac_update( &op, msg1_part2, sizeof( msg1_part2 ) ) ); PSA_CHECK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); - print_out( "msg1" ); + print_buf( "msg1", out, sizeof( out ) ); /* compute HMAC(key, msg2_part1 | msg2_part2) */ PSA_CHECK( psa_mac_sign_setup( &op, key, alg ) ); PSA_CHECK( psa_mac_update( &op, msg2_part1, sizeof( msg2_part1 ) ) ); PSA_CHECK( psa_mac_update( &op, msg2_part2, sizeof( msg2_part2 ) ) ); PSA_CHECK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); - print_out( "msg2" ); + print_buf( "msg2", out, sizeof( out ) ); exit: psa_mac_abort( &op ); // needed on error, harmless on success psa_destroy_key( key ); + mbedtls_platform_zeroize( out, sizeof( out ) ); return( status ); } From 248b385f1b7512292722ed2f10307cc9c131302a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 31 Jan 2022 12:56:39 +0100 Subject: [PATCH 18/30] Add comments to AEAD (non-PSA) examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/aead_non_psa.c | 129 +++++++++++++++++++--------- programs/psa/aead_psa.c | 164 +++++++++++++++++++++++------------- 2 files changed, 196 insertions(+), 97 deletions(-) diff --git a/programs/psa/aead_non_psa.c b/programs/psa/aead_non_psa.c index 4b48b3a989ce..00c7f0ef4463 100644 --- a/programs/psa/aead_non_psa.c +++ b/programs/psa/aead_non_psa.c @@ -1,25 +1,13 @@ -/* - * This is a companion to aead_psa.c, doing the same operations with the - * legacy Cipher API. The goal is that comparing the two programs will help people - * migrating to the PSA Crypto API. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 +/** + * Cipher API multi-part AEAD demonstration. * - * 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 + * This program AEAD-encrypts a message, using the algorithm and key size + * specified on the command line, using the multi-part API. * - * http://www.apache.org/licenses/LICENSE-2.0 + * It comes with a companion program aead_psa.c, which does the same + * operations with the PSA Crypto API. The goal is that comparing the two + * programs will help people migrating to the PSA Crypto API. * - * 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. - */ - -/* * When used with multi-part AEAD operations, the `mbedtls_cipher_context` * serves a triple purpose (1) hold the key, (2) store the algorithm when no * operation is active, and (3) save progress information for the current @@ -30,15 +18,40 @@ * On the other hand, with PSA, the algorithms encodes the desired tag length; * with Cipher the desired tag length needs to be tracked separately. * - * This program and its compation aead_psa.c illustrate this by doing the + * This program and its companion aead_psa.c illustrate this by doing the * same sequence of multi-part AEAD computation with both APIs; looking at the * two side by side should make the differences and similarities clear. */ -#include +/* + * 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. + */ +/* First include Mbed TLS headers to get the Mbed TLS configuration and + * platform definitions that we'll use in this program. Also include + * standard C headers for functions we'll use here. */ #include "mbedtls/build_info.h" +#include "mbedtls/cipher.h" + +#include +#include +#include + +/* If the build options we need are not enabled, compile a placeholder. */ #if !defined(MBEDTLS_CIPHER_C) || \ !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \ !defined(MBEDTLS_CHACHAPOLY_C) @@ -51,52 +64,67 @@ int main( void ) } #else -#include +/* The real program starts here. */ -#include "mbedtls/cipher.h" - -/* - * Dummy data and helper functions - */ -const char usage[] = "Usage: aead_non_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; +const char usage[] = "Usage: aead_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; +/* Dummy data for encryption: IV/nonce, additional data, 2-part message */ const unsigned char iv1[12] = { 0x00 }; const unsigned char add_data1[] = { 0x01, 0x02 }; const unsigned char msg1_part1[] = { 0x03, 0x04 }; const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 }; +/* Dummy data (2nd message) */ const unsigned char iv2[12] = { 0x10 }; const unsigned char add_data2[] = { 0x11, 0x12 }; const unsigned char msg2_part1[] = { 0x13, 0x14 }; const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; +/* This must at least the sum of the length of the 2 parts for each message. + * This is a macro for the sake of compilers with insufficient C99 support. */ #define MSG_MAX_SIZE 5 +/* Dummy key material - never do this in production! + * 32-byte is enough to all the key size supported by this program. */ const unsigned char key_bytes[32] = { 0x2a }; -void print_out( const char *title, unsigned char *out, size_t len ) +/* Print the contents of a buffer in hex */ +void print_buf( const char *title, unsigned char *buf, size_t len ) { printf( "%s:", title ); for( size_t i = 0; i < len; i++ ) - printf( " %02x", out[i] ); + printf( " %02x", buf[i] ); printf( "\n" ); } -#define CHK( code ) \ - do { \ - ret = code; \ - if( ret != 0 ) { \ - printf( "%03d: ret = -0x%04x\n", __LINE__, (unsigned) -ret ); \ - goto exit; \ - } \ +/* Run an Mbed TLS function and bail out if it fails. */ +#define CHK( expr ) \ + do \ + { \ + ret = ( expr ); \ + if( ret != 0 ) \ + { \ + printf( "Error %d at line %d: %s\n", \ + ret, \ + __LINE__, \ + #expr ); \ + goto exit; \ + } \ } while( 0 ) +/* + * Prepare encryption material: + * - interpret command-line argument + * - set up key + * - outputs: context and tag length, which together hold all the information + */ static int aead_prepare( const char *info, mbedtls_cipher_context_t *ctx, size_t *tag_len ) { int ret; + /* Convert arg to type + tag_len */ mbedtls_cipher_type_t type; if( strcmp( info, "aes128-gcm" ) == 0 ) { type = MBEDTLS_CIPHER_AES_128_GCM; @@ -115,9 +143,11 @@ static int aead_prepare( const char *info, return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } + /* Prepare context for the given type */ CHK( mbedtls_cipher_setup( ctx, mbedtls_cipher_info_from_type( type ) ) ); + /* Import key */ int key_len = mbedtls_cipher_get_key_bitlen( ctx ); CHK( mbedtls_cipher_setkey( ctx, key_bytes, key_len, MBEDTLS_ENCRYPT ) ); @@ -125,9 +155,15 @@ static int aead_prepare( const char *info, return( ret ); } +/* + * Print out some information. + * + * All of this information was present in the command line argument, but his + * function demonstrates how each piece can be recovered from (ctx, tag_len). + */ static void aead_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) { - // no convenient way to get the cipher type (for example, AES) + // no convenient way to get the just cipher type (for example, AES) const char *ciph = "???"; int key_bits = mbedtls_cipher_get_key_bitlen( ctx ); mbedtls_cipher_mode_t mode = mbedtls_cipher_get_cipher_mode( ctx ); @@ -139,6 +175,9 @@ static void aead_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) printf( "cipher: %s, %d, %s, %u\n", ciph, key_bits, mode_str, (unsigned) tag_len ); } +/* + * Encrypt a 2-part message. + */ static int aead_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, @@ -163,12 +202,15 @@ static int aead_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, p += tag_len; olen = p - out; - print_out( "cipher", out, olen ); + print_buf( "cipher", out, olen ); exit: return( ret ); } +/* + * AEAD demo: set up key/alg, print out info, encrypt messages. + */ static int aead_demo( const char *info ) { int ret = 0; @@ -203,13 +245,20 @@ static int aead_demo( const char *info ) */ int main( int argc, char **argv ) { + /* Check usage */ if( argc != 2 ) { puts( usage ); return( 1 ); } - aead_demo( argv[1] ); + int ret; + + /* Run the demo */ + CHK( aead_demo( argv[1] ) ); + +exit: + return( ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE ); } #endif diff --git a/programs/psa/aead_psa.c b/programs/psa/aead_psa.c index 5ed32a5f6ace..2f0663d8386b 100644 --- a/programs/psa/aead_psa.c +++ b/programs/psa/aead_psa.c @@ -1,26 +1,13 @@ -/* - * This is a simple example of multi-part AEAD computation using the PSA - * Crypto API. It comes with a companion program aead_non_psa.c, which does - * the same operations with the legacy Cipher API. The goal is that comparing the - * two programs will help people migrating to the PSA Crypto API. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 +/** + * PSA API multi-part AEAD demonstration. * - * 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 + * This program AEAD-encrypts a message, using the algorithm and key size + * specified on the command line, using the multi-part API. * - * http://www.apache.org/licenses/LICENSE-2.0 + * It comes with a companion program aead_non_psa.c, which does the same + * operations with the legacy Cipher API. The goal is that comparing the two + * programs will help people migrating to the PSA Crypto API. * - * 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. - */ - -/* * When used with multi-part AEAD operations, the `mbedtls_cipher_context` * serves a triple purpose (1) hold the key, (2) store the algorithm when no * operation is active, and (3) save progress information for the current @@ -31,15 +18,40 @@ * On the other hand, with PSA, the algorithms encodes the desired tag length; * with Cipher the desired tag length needs to be tracked separately. * - * This program and its compation aead_non_psa.c illustrate this by doing the + * This program and its companion aead_non_psa.c illustrate this by doing the * same sequence of multi-part AEAD computation with both APIs; looking at the * two side by side should make the differences and similarities clear. */ -#include +/* + * 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. + */ +/* First include Mbed TLS headers to get the Mbed TLS configuration and + * platform definitions that we'll use in this program. Also include + * standard C headers for functions we'll use here. */ #include "mbedtls/build_info.h" +#include "psa/crypto.h" + +#include +#include +#include + +/* If the build options we need are not enabled, compile a placeholder. */ #if !defined(MBEDTLS_PSA_CRYPTO_C) || \ !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \ !defined(MBEDTLS_CHACHAPOLY_C) || \ @@ -54,52 +66,68 @@ int main( void ) } #else -#include +/* The real program starts here. */ -#include "psa/crypto.h" - -/* - * Dummy data and helper functions - */ const char usage[] = "Usage: aead_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; +/* Dummy data for encryption: IV/nonce, additional data, 2-part message */ const unsigned char iv1[12] = { 0x00 }; const unsigned char add_data1[] = { 0x01, 0x02 }; const unsigned char msg1_part1[] = { 0x03, 0x04 }; const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 }; +/* Dummy data (2nd message) */ const unsigned char iv2[12] = { 0x10 }; const unsigned char add_data2[] = { 0x11, 0x12 }; const unsigned char msg2_part1[] = { 0x13, 0x14 }; const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; +/* This must at least the sum of the length of the 2 parts for each message. + * This is a macro for the sake of compilers with insufficient C99 support. */ #define MSG_MAX_SIZE 5 +/* Dummy key material - never do this in production! + * 32-byte is enough to all the key size supported by this program. */ const unsigned char key_bytes[32] = { 0x2a }; -void print_out( const char *title, unsigned char *out, size_t len ) +/* Print the contents of a buffer in hex */ +void print_buf( const char *title, uint8_t *buf, size_t len ) { printf( "%s:", title ); for( size_t i = 0; i < len; i++ ) - printf( " %02x", out[i] ); + printf( " %02x", buf[i] ); printf( "\n" ); } -#define CHK( code ) \ - do { \ - status = code; \ - if( status != PSA_SUCCESS ) { \ - printf( "%03d: status = %d\n", __LINE__, status ); \ - goto exit; \ - } \ - } while( 0 ) +/* Run a PSA function and bail out if it fails. */ +#define PSA_CHECK( expr ) \ + do \ + { \ + status = ( expr ); \ + if( status != PSA_SUCCESS ) \ + { \ + printf( "Error %d at line %d: %s\n", \ + (int) status, \ + __LINE__, \ + #expr ); \ + goto exit; \ + } \ + } \ + while( 0 ) +/* + * Prepare encryption material: + * - interpret command-line argument + * - set up key + * - outputs: key and algorithm, which together hold all the information + */ static psa_status_t aead_prepare( const char *info, psa_key_id_t *key, psa_algorithm_t *alg ) { psa_status_t status; + /* Convert arg to alg + key_bits + key_type */ size_t key_bits; psa_key_type_t key_type; if( strcmp( info, "aes128-gcm" ) == 0 ) { @@ -123,18 +151,26 @@ static psa_status_t aead_prepare( const char *info, return( PSA_ERROR_INVALID_ARGUMENT ); } + /* Prepare key attibutes */ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT ); psa_set_key_algorithm( &attributes, *alg ); psa_set_key_type( &attributes, key_type ); - psa_set_key_bits( &attributes, key_bits ); + psa_set_key_bits( &attributes, key_bits ); // optional - CHK( psa_import_key( &attributes, key_bytes, key_bits / 8, key ) ); + /* Import key */ + PSA_CHECK( psa_import_key( &attributes, key_bytes, key_bits / 8, key ) ); exit: return( status ); } +/* + * Print out some information. + * + * All of this information was present in the command line argument, but his + * function demonstrates how each piece can be recovered from (key, alg). + */ static void aead_info( psa_key_id_t key, psa_algorithm_t alg ) { psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT; @@ -155,6 +191,9 @@ static void aead_info( psa_key_id_t key, psa_algorithm_t alg ) type_str, (unsigned) key_bits, base_str, (unsigned) tag_len ); } +/* + * Encrypt a 2-part message. + */ static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, @@ -168,29 +207,31 @@ static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, unsigned char tag[PSA_AEAD_TAG_MAX_SIZE]; psa_aead_operation_t op = PSA_AEAD_OPERATION_INIT; - CHK( psa_aead_encrypt_setup( &op, key, alg ) ); + PSA_CHECK( psa_aead_encrypt_setup( &op, key, alg ) ); - CHK( psa_aead_set_nonce( &op, iv, iv_len ) ); - CHK( psa_aead_update_ad( &op, ad, ad_len ) ); - CHK( psa_aead_update( &op, pa, pa_len, p, end - p, &olen ) ); + PSA_CHECK( psa_aead_set_nonce( &op, iv, iv_len ) ); + PSA_CHECK( psa_aead_update_ad( &op, ad, ad_len ) ); + PSA_CHECK( psa_aead_update( &op, pa, pa_len, p, end - p, &olen ) ); p += olen; - CHK( psa_aead_update( &op, pb, pb_len, p, end - p, &olen ) ); + PSA_CHECK( psa_aead_update( &op, pb, pb_len, p, end - p, &olen ) ); p += olen; - CHK( psa_aead_finish( &op, p, end - p, &olen, + PSA_CHECK( psa_aead_finish( &op, p, end - p, &olen, tag, sizeof( tag ), &olen_tag ) ); p += olen; memcpy( p, tag, olen_tag ); p += olen_tag; olen = p - out; - print_out( "out", out, olen ); + print_buf( "out", out, olen ); exit: - /* required on errors, harmless on success */ - psa_aead_abort( &op ); + psa_aead_abort( &op ); // required on errors, harmless on success return( status ); } +/* + * AEAD demo: set up key/alg, print out info, encrypt messages. + */ static psa_status_t aead_demo( const char *info ) { psa_status_t status; @@ -198,15 +239,15 @@ static psa_status_t aead_demo( const char *info ) psa_key_id_t key; psa_algorithm_t alg; - CHK( aead_prepare( info, &key, &alg ) ); + PSA_CHECK( aead_prepare( info, &key, &alg ) ); aead_info( key, alg ); - CHK( aead_encrypt( key, alg, + PSA_CHECK( aead_encrypt( key, alg, iv1, sizeof( iv1 ), add_data1, sizeof( add_data1 ), msg1_part1, sizeof( msg1_part1 ), msg1_part2, sizeof( msg1_part2 ) ) ); - CHK( aead_encrypt( key, alg, + PSA_CHECK( aead_encrypt( key, alg, iv2, sizeof( iv2 ), add_data2, sizeof( add_data2 ), msg2_part1, sizeof( msg2_part1 ), msg2_part2, sizeof( msg2_part2 ) ) ); @@ -222,17 +263,26 @@ static psa_status_t aead_demo( const char *info ) */ int main( int argc, char **argv ) { + psa_status_t status = PSA_SUCCESS; + + /* Check usage */ if( argc != 2 ) { puts( usage ); - return( 1 ); + return( EXIT_FAILURE ); } - psa_status_t status = psa_crypto_init(); - if( status != PSA_SUCCESS ) - printf( "psa init: %d\n", status ); + /* Initialize the PSA crypto library. */ + PSA_CHECK( psa_crypto_init( ) ); - aead_demo( argv[1] ); + /* Run the demo */ + PSA_CHECK( aead_demo( argv[1] ) ); + + /* Deinitialize the PSA crypto library. */ + mbedtls_psa_crypto_free( ); + +exit: + return( status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE ); } #endif From 69bb3f5332b70739855b2bcf76a9c11085c99806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 31 Jan 2022 13:09:47 +0100 Subject: [PATCH 19/30] Move hmac_non_psa out of psa/ directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/.gitignore | 4 ++-- programs/Makefile | 24 +++++++++---------- programs/hash/CMakeLists.txt | 1 + .../{psa/hmac_non_psa.c => hash/hmac_demo.c} | 4 ++-- programs/psa/CMakeLists.txt | 3 +-- programs/psa/{hmac_psa.c => hmac_demo.c} | 4 ++-- 6 files changed, 20 insertions(+), 20 deletions(-) rename programs/{psa/hmac_non_psa.c => hash/hmac_demo.c} (96%) rename programs/psa/{hmac_psa.c => hmac_demo.c} (97%) diff --git a/programs/.gitignore b/programs/.gitignore index 670c2825e1c6..6500174378b0 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -15,6 +15,7 @@ aes/crypt_and_hash hash/generic_sum hash/hello +hash/hmac_demo hash/md5sum hash/sha1sum hash/sha2sum @@ -41,8 +42,7 @@ pkey/rsa_verify_pss psa/aead_non_psa psa/aead_psa psa/crypto_examples -psa/hmac_non_psa -psa/hmac_psa +psa/hmac_demo psa/key_ladder_demo psa/psa_constant_names random/gen_entropy diff --git a/programs/Makefile b/programs/Makefile index 2f0d406f3aa0..d2f7d8dd9cb6 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -64,6 +64,7 @@ APPS = \ aes/crypt_and_hash \ hash/generic_sum \ hash/hello \ + hash/hmac_demo \ pkey/dh_client \ pkey/dh_genprime \ pkey/dh_server \ @@ -87,8 +88,7 @@ APPS = \ psa/aead_non_psa \ psa/aead_psa \ psa/crypto_examples \ - psa/hmac_non_psa \ - psa/hmac_psa \ + psa/hmac_demo \ psa/key_ladder_demo \ psa/psa_constant_names \ random/gen_entropy \ @@ -177,13 +177,17 @@ aes/crypt_and_hash$(EXEXT): aes/crypt_and_hash.c $(DEP) echo " CC aes/crypt_and_hash.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) aes/crypt_and_hash.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +hash/generic_sum$(EXEXT): hash/generic_sum.c $(DEP) + echo " CC hash/generic_sum.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/generic_sum.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + hash/hello$(EXEXT): hash/hello.c $(DEP) echo " CC hash/hello.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/hello.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -hash/generic_sum$(EXEXT): hash/generic_sum.c $(DEP) - echo " CC hash/generic_sum.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/generic_sum.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +hash/hmac_demo$(EXEXT): hash/hmac_demo.c $(DEP) + echo " CC hash/hmac_demo.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/hmac_demo.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ pkey/dh_client$(EXEXT): pkey/dh_client.c $(DEP) echo " CC pkey/dh_client.c" @@ -277,13 +281,9 @@ 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 $@ -psa/hmac_non_psa$(EXEXT): psa/hmac_non_psa.c $(DEP) - echo " CC psa/hmac_non_psa.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/hmac_non_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ - -psa/hmac_psa$(EXEXT): psa/hmac_psa.c $(DEP) - echo " CC psa/hmac_psa.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/hmac_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +psa/hmac_demo$(EXEXT): psa/hmac_demo.c $(DEP) + echo " CC psa/hmac_demo.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/hmac_demo.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ psa/key_ladder_demo$(EXEXT): psa/key_ladder_demo.c $(DEP) echo " CC psa/key_ladder_demo.c" diff --git a/programs/hash/CMakeLists.txt b/programs/hash/CMakeLists.txt index 729474c0321b..9ff1df1d1834 100644 --- a/programs/hash/CMakeLists.txt +++ b/programs/hash/CMakeLists.txt @@ -1,6 +1,7 @@ set(executables generic_sum hello + hmac_demo ) foreach(exe IN LISTS executables) diff --git a/programs/psa/hmac_non_psa.c b/programs/hash/hmac_demo.c similarity index 96% rename from programs/psa/hmac_non_psa.c rename to programs/hash/hmac_demo.c index 66fcf7e2f533..cae6224012cb 100644 --- a/programs/psa/hmac_non_psa.c +++ b/programs/hash/hmac_demo.c @@ -3,7 +3,7 @@ * * This programs computes the HMAC of two messages using the multi-part API. * - * This is a companion to hmac_psa.c, doing the same operations with the + * This is a companion to psa/hmac_demo.c, doing the same operations with the * legacy MD API. The goal is that comparing the two programs will help people * migrating to the PSA Crypto API. * @@ -13,7 +13,7 @@ * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for * multi-part progress. * - * This program and its companion hmac_non_psa.c illustrate this by doing the + * This program and its companion psa/hmac_demo.c illustrate this by doing the * same sequence of multi-part HMAC computation with both APIs; looking at the * two side by side should make the differences and similarities clear. */ diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt index 462fcf643e6c..37192e34d30b 100644 --- a/programs/psa/CMakeLists.txt +++ b/programs/psa/CMakeLists.txt @@ -2,8 +2,7 @@ set(executables aead_non_psa aead_psa crypto_examples - hmac_non_psa - hmac_psa + hmac_demo key_ladder_demo psa_constant_names ) diff --git a/programs/psa/hmac_psa.c b/programs/psa/hmac_demo.c similarity index 97% rename from programs/psa/hmac_psa.c rename to programs/psa/hmac_demo.c index c943110dbf7b..2786bb376682 100644 --- a/programs/psa/hmac_psa.c +++ b/programs/psa/hmac_demo.c @@ -3,7 +3,7 @@ * * This programs computes the HMAC of two messages using the multi-part API. * - * It comes with a companion program hmac_non_psa.c, which does the same + * It comes with a companion program hash/hmac_demo.c, which does the same * operations with the legacy MD API. The goal is that comparing the two * programs will help people migrating to the PSA Crypto API. * @@ -13,7 +13,7 @@ * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for * multi-part progress. * - * This program and its companion hmac_non_psa.c illustrate this by doing the + * This program and its companion hash/hmac_demo.c illustrate this by doing the * same sequence of multi-part HMAC computation with both APIs; looking at the * two side by side should make the differences and similarities clear. */ From 6fdc9e8df1f2c7895260ac0b5fd5e4577da414a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 31 Jan 2022 13:27:39 +0100 Subject: [PATCH 20/30] Move aead_non_psa out of the psa/ directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/.gitignore | 4 ++-- programs/CMakeLists.txt | 1 + programs/Makefile | 18 +++++++++--------- programs/cipher/CMakeLists.txt | 13 +++++++++++++ .../{psa/aead_non_psa.c => cipher/aead_demo.c} | 6 +++--- programs/psa/CMakeLists.txt | 3 +-- programs/psa/{aead_psa.c => aead_demo.c} | 6 +++--- 7 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 programs/cipher/CMakeLists.txt rename programs/{psa/aead_non_psa.c => cipher/aead_demo.c} (97%) rename programs/psa/{aead_psa.c => aead_demo.c} (97%) diff --git a/programs/.gitignore b/programs/.gitignore index 6500174378b0..076821fceb85 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -13,6 +13,7 @@ *.exe aes/crypt_and_hash +cipher/aead_demo hash/generic_sum hash/hello hash/hmac_demo @@ -39,8 +40,7 @@ pkey/rsa_sign pkey/rsa_sign_pss pkey/rsa_verify pkey/rsa_verify_pss -psa/aead_non_psa -psa/aead_psa +psa/aead_demo psa/crypto_examples psa/hmac_demo psa/key_ladder_demo diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index a8492c6199f0..0633aa6499e2 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(aes) +add_subdirectory(cipher) if (NOT WIN32) add_subdirectory(fuzz) endif() diff --git a/programs/Makefile b/programs/Makefile index d2f7d8dd9cb6..fccddc69dbc8 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -62,6 +62,7 @@ endif ## make sure to check that it still works if you tweak the format here. APPS = \ aes/crypt_and_hash \ + cipher/aead_demo \ hash/generic_sum \ hash/hello \ hash/hmac_demo \ @@ -85,8 +86,7 @@ APPS = \ pkey/rsa_sign_pss \ pkey/rsa_verify \ pkey/rsa_verify_pss \ - psa/aead_non_psa \ - psa/aead_psa \ + psa/aead_demo \ psa/crypto_examples \ psa/hmac_demo \ psa/key_ladder_demo \ @@ -177,6 +177,10 @@ aes/crypt_and_hash$(EXEXT): aes/crypt_and_hash.c $(DEP) echo " CC aes/crypt_and_hash.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) aes/crypt_and_hash.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +cipher/aead_demo$(EXEXT): cipher/aead_demo.c $(DEP) + echo " CC cipher/aead_demo.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) cipher/aead_demo.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + hash/generic_sum$(EXEXT): hash/generic_sum.c $(DEP) echo " CC hash/generic_sum.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/generic_sum.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ @@ -269,13 +273,9 @@ pkey/rsa_encrypt$(EXEXT): pkey/rsa_encrypt.c $(DEP) echo " CC pkey/rsa_encrypt.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) pkey/rsa_encrypt.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -psa/aead_non_psa$(EXEXT): psa/aead_non_psa.c $(DEP) - echo " CC psa/aead_non_psa.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/aead_non_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ - -psa/aead_psa$(EXEXT): psa/aead_psa.c $(DEP) - echo " CC psa/aead_psa.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/aead_psa.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +psa/aead_demo$(EXEXT): psa/aead_demo.c $(DEP) + echo " CC psa/aead_demo.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) psa/aead_demo.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ psa/crypto_examples$(EXEXT): psa/crypto_examples.c $(DEP) echo " CC psa/crypto_examples.c" diff --git a/programs/cipher/CMakeLists.txt b/programs/cipher/CMakeLists.txt new file mode 100644 index 000000000000..cc16849c2a25 --- /dev/null +++ b/programs/cipher/CMakeLists.txt @@ -0,0 +1,13 @@ +set(executables + aead_demo +) + +foreach(exe IN LISTS executables) + add_executable(${exe} ${exe}.c $) + target_link_libraries(${exe} ${mbedcrypto_target}) + target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include) +endforeach() + +install(TARGETS ${executables} + DESTINATION "bin" + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/programs/psa/aead_non_psa.c b/programs/cipher/aead_demo.c similarity index 97% rename from programs/psa/aead_non_psa.c rename to programs/cipher/aead_demo.c index 00c7f0ef4463..894225d80a1c 100644 --- a/programs/psa/aead_non_psa.c +++ b/programs/cipher/aead_demo.c @@ -4,7 +4,7 @@ * This program AEAD-encrypts a message, using the algorithm and key size * specified on the command line, using the multi-part API. * - * It comes with a companion program aead_psa.c, which does the same + * It comes with a companion program psa/aead_demo.c, which does the same * operations with the PSA Crypto API. The goal is that comparing the two * programs will help people migrating to the PSA Crypto API. * @@ -18,7 +18,7 @@ * On the other hand, with PSA, the algorithms encodes the desired tag length; * with Cipher the desired tag length needs to be tracked separately. * - * This program and its companion aead_psa.c illustrate this by doing the + * This program and its companion psa/aead_demo.c illustrate this by doing the * same sequence of multi-part AEAD computation with both APIs; looking at the * two side by side should make the differences and similarities clear. */ @@ -66,7 +66,7 @@ int main( void ) /* The real program starts here. */ -const char usage[] = "Usage: aead_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; +const char usage[] = "Usage: aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; /* Dummy data for encryption: IV/nonce, additional data, 2-part message */ const unsigned char iv1[12] = { 0x00 }; diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt index 37192e34d30b..7ba4af63d9b4 100644 --- a/programs/psa/CMakeLists.txt +++ b/programs/psa/CMakeLists.txt @@ -1,6 +1,5 @@ set(executables - aead_non_psa - aead_psa + aead_demo crypto_examples hmac_demo key_ladder_demo diff --git a/programs/psa/aead_psa.c b/programs/psa/aead_demo.c similarity index 97% rename from programs/psa/aead_psa.c rename to programs/psa/aead_demo.c index 2f0663d8386b..4c7a5222c807 100644 --- a/programs/psa/aead_psa.c +++ b/programs/psa/aead_demo.c @@ -4,7 +4,7 @@ * This program AEAD-encrypts a message, using the algorithm and key size * specified on the command line, using the multi-part API. * - * It comes with a companion program aead_non_psa.c, which does the same + * It comes with a companion program cipher/aead_demo.c, which does the same * operations with the legacy Cipher API. The goal is that comparing the two * programs will help people migrating to the PSA Crypto API. * @@ -18,7 +18,7 @@ * On the other hand, with PSA, the algorithms encodes the desired tag length; * with Cipher the desired tag length needs to be tracked separately. * - * This program and its companion aead_non_psa.c illustrate this by doing the + * This program and its companion cipher/aead_demo.c illustrate this by doing the * same sequence of multi-part AEAD computation with both APIs; looking at the * two side by side should make the differences and similarities clear. */ @@ -68,7 +68,7 @@ int main( void ) /* The real program starts here. */ -const char usage[] = "Usage: aead_psa [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; +const char usage[] = "Usage: aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; /* Dummy data for encryption: IV/nonce, additional data, 2-part message */ const unsigned char iv1[12] = { 0x00 }; From 29088a414610b1eea20aaeb89d31ffd433eb442c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 1 Feb 2022 09:38:26 +0100 Subject: [PATCH 21/30] Avoid duplicate program names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Visual Studio and CMake didn't like having targets with the same name, albeit in different directories. Signed-off-by: Manuel Pégourié-Gonnard --- programs/.gitignore | 4 ++-- programs/Makefile | 16 ++++++++-------- programs/cipher/CMakeLists.txt | 2 +- .../cipher/{aead_demo.c => cipher_aead_demo.c} | 2 +- programs/hash/CMakeLists.txt | 2 +- programs/hash/{hmac_demo.c => md_hmac_demo.c} | 0 programs/psa/aead_demo.c | 4 ++-- programs/psa/hmac_demo.c | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) rename programs/cipher/{aead_demo.c => cipher_aead_demo.c} (98%) rename programs/hash/{hmac_demo.c => md_hmac_demo.c} (100%) diff --git a/programs/.gitignore b/programs/.gitignore index 076821fceb85..7fe0401e579b 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -13,10 +13,10 @@ *.exe aes/crypt_and_hash -cipher/aead_demo +cipher/cipher_aead_demo hash/generic_sum hash/hello -hash/hmac_demo +hash/md_hmac_demo hash/md5sum hash/sha1sum hash/sha2sum diff --git a/programs/Makefile b/programs/Makefile index fccddc69dbc8..31295f67c3bf 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -62,10 +62,10 @@ endif ## make sure to check that it still works if you tweak the format here. APPS = \ aes/crypt_and_hash \ - cipher/aead_demo \ + cipher/cipher_aead_demo \ hash/generic_sum \ hash/hello \ - hash/hmac_demo \ + hash/md_hmac_demo \ pkey/dh_client \ pkey/dh_genprime \ pkey/dh_server \ @@ -177,9 +177,9 @@ aes/crypt_and_hash$(EXEXT): aes/crypt_and_hash.c $(DEP) echo " CC aes/crypt_and_hash.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) aes/crypt_and_hash.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -cipher/aead_demo$(EXEXT): cipher/aead_demo.c $(DEP) - echo " CC cipher/aead_demo.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) cipher/aead_demo.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +cipher/cipher_aead_demo$(EXEXT): cipher/cipher_aead_demo.c $(DEP) + echo " CC cipher/cipher_aead_demo.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) cipher/cipher_aead_demo.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ hash/generic_sum$(EXEXT): hash/generic_sum.c $(DEP) echo " CC hash/generic_sum.c" @@ -189,9 +189,9 @@ hash/hello$(EXEXT): hash/hello.c $(DEP) echo " CC hash/hello.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/hello.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -hash/hmac_demo$(EXEXT): hash/hmac_demo.c $(DEP) - echo " CC hash/hmac_demo.c" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/hmac_demo.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +hash/md_hmac_demo$(EXEXT): hash/md_hmac_demo.c $(DEP) + echo " CC hash/md_hmac_demo.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) hash/md_hmac_demo.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ pkey/dh_client$(EXEXT): pkey/dh_client.c $(DEP) echo " CC pkey/dh_client.c" diff --git a/programs/cipher/CMakeLists.txt b/programs/cipher/CMakeLists.txt index cc16849c2a25..93e5f31ee8a5 100644 --- a/programs/cipher/CMakeLists.txt +++ b/programs/cipher/CMakeLists.txt @@ -1,5 +1,5 @@ set(executables - aead_demo + cipher_aead_demo ) foreach(exe IN LISTS executables) diff --git a/programs/cipher/aead_demo.c b/programs/cipher/cipher_aead_demo.c similarity index 98% rename from programs/cipher/aead_demo.c rename to programs/cipher/cipher_aead_demo.c index 894225d80a1c..4da1bfc5b49e 100644 --- a/programs/cipher/aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -66,7 +66,7 @@ int main( void ) /* The real program starts here. */ -const char usage[] = "Usage: aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; +const char usage[] = "Usage: cipher_aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; /* Dummy data for encryption: IV/nonce, additional data, 2-part message */ const unsigned char iv1[12] = { 0x00 }; diff --git a/programs/hash/CMakeLists.txt b/programs/hash/CMakeLists.txt index 9ff1df1d1834..da981884436b 100644 --- a/programs/hash/CMakeLists.txt +++ b/programs/hash/CMakeLists.txt @@ -1,7 +1,7 @@ set(executables generic_sum hello - hmac_demo + md_hmac_demo ) foreach(exe IN LISTS executables) diff --git a/programs/hash/hmac_demo.c b/programs/hash/md_hmac_demo.c similarity index 100% rename from programs/hash/hmac_demo.c rename to programs/hash/md_hmac_demo.c diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c index 4c7a5222c807..396e82883afb 100644 --- a/programs/psa/aead_demo.c +++ b/programs/psa/aead_demo.c @@ -4,7 +4,7 @@ * This program AEAD-encrypts a message, using the algorithm and key size * specified on the command line, using the multi-part API. * - * It comes with a companion program cipher/aead_demo.c, which does the same + * It comes with a companion program cipher/cipher_aead_demo.c, which does the same * operations with the legacy Cipher API. The goal is that comparing the two * programs will help people migrating to the PSA Crypto API. * @@ -18,7 +18,7 @@ * On the other hand, with PSA, the algorithms encodes the desired tag length; * with Cipher the desired tag length needs to be tracked separately. * - * This program and its companion cipher/aead_demo.c illustrate this by doing the + * This program and its companion cipher/cipher_aead_demo.c illustrate this by doing the * same sequence of multi-part AEAD computation with both APIs; looking at the * two side by side should make the differences and similarities clear. */ diff --git a/programs/psa/hmac_demo.c b/programs/psa/hmac_demo.c index 2786bb376682..54fea038a312 100644 --- a/programs/psa/hmac_demo.c +++ b/programs/psa/hmac_demo.c @@ -3,7 +3,7 @@ * * This programs computes the HMAC of two messages using the multi-part API. * - * It comes with a companion program hash/hmac_demo.c, which does the same + * It comes with a companion program hash/md_hmac_demo.c, which does the same * operations with the legacy MD API. The goal is that comparing the two * programs will help people migrating to the PSA Crypto API. * @@ -13,7 +13,7 @@ * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for * multi-part progress. * - * This program and its companion hash/hmac_demo.c illustrate this by doing the + * This program and its companion hash/md_hmac_demo.c illustrate this by doing the * same sequence of multi-part HMAC computation with both APIs; looking at the * two side by side should make the differences and similarities clear. */ From 12ec5719e7db105ecdeb2182161aecc6d065bafc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 1 Feb 2022 09:47:46 +0100 Subject: [PATCH 22/30] Fix bug in md_hmac_demo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/hash/md_hmac_demo.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/programs/hash/md_hmac_demo.c b/programs/hash/md_hmac_demo.c index cae6224012cb..0f6495c866ed 100644 --- a/programs/hash/md_hmac_demo.c +++ b/programs/hash/md_hmac_demo.c @@ -108,21 +108,22 @@ int hmac_demo(void) /* prepare context and load key */ // the last argument to setup is 1 to enable HMAC (not just hashing) - CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( alg ), 1 ) ); + const mbedtls_md_info_t *info = mbedtls_md_info_from_type( alg ); + CHK( mbedtls_md_setup( &ctx, info, 1 ) ); CHK( mbedtls_md_hmac_starts( &ctx, key_bytes, sizeof( key_bytes ) ) ); /* compute HMAC(key, msg1_part1 | msg1_part2) */ CHK( mbedtls_md_hmac_update( &ctx, msg1_part1, sizeof( msg1_part1 ) ) ); CHK( mbedtls_md_hmac_update( &ctx, msg1_part2, sizeof( msg1_part2 ) ) ); CHK( mbedtls_md_hmac_finish( &ctx, out ) ); - print_buf( "msg1", out, sizeof( out ) ); + print_buf( "msg1", out, mbedtls_md_get_size( info ) ); /* compute HMAC(key, msg2_part1 | msg2_part2) */ CHK( mbedtls_md_hmac_reset( &ctx ) ); // prepare for new operation CHK( mbedtls_md_hmac_update( &ctx, msg2_part1, sizeof( msg2_part1 ) ) ); CHK( mbedtls_md_hmac_update( &ctx, msg2_part2, sizeof( msg2_part2 ) ) ); CHK( mbedtls_md_hmac_finish( &ctx, out ) ); - print_buf( "msg2", out, sizeof( out ) ); + print_buf( "msg2", out, mbedtls_md_get_size( info ) ); exit: mbedtls_md_free( &ctx ); From f6ea19c66c8c4b2ea3a6aafd3a9ea9642e9461b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 1 Feb 2022 13:08:21 +0100 Subject: [PATCH 23/30] Work around bug in PSA_MAC_LENGTH() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/psa/hmac_demo.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/programs/psa/hmac_demo.c b/programs/psa/hmac_demo.c index 54fea038a312..3cb0d21dd155 100644 --- a/programs/psa/hmac_demo.c +++ b/programs/psa/hmac_demo.c @@ -102,11 +102,10 @@ void print_buf( const char *title, uint8_t *buf, size_t len ) psa_status_t hmac_demo(void) { psa_status_t status; -#define ALG PSA_ALG_HMAC(PSA_ALG_SHA_256) - const psa_algorithm_t alg = ALG; - // compilers with insufficient C99 support don't accept the const variable - // 'alg' here, so use a macro instead in order to pacify them - uint8_t out[PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 8 * sizeof( key_bytes ), ALG)]; + const psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256); + uint8_t out[PSA_MAC_MAX_SIZE]; // safe but not optimal + /* PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 8 * sizeof( key_bytes ), alg) + * should work but see https://github.com/ARMmbed/mbedtls/issues/4320 */ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_key_id_t key = 0; @@ -130,14 +129,14 @@ psa_status_t hmac_demo(void) PSA_CHECK( psa_mac_update( &op, msg1_part1, sizeof( msg1_part1 ) ) ); PSA_CHECK( psa_mac_update( &op, msg1_part2, sizeof( msg1_part2 ) ) ); PSA_CHECK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); - print_buf( "msg1", out, sizeof( out ) ); + print_buf( "msg1", out, out_len ); /* compute HMAC(key, msg2_part1 | msg2_part2) */ PSA_CHECK( psa_mac_sign_setup( &op, key, alg ) ); PSA_CHECK( psa_mac_update( &op, msg2_part1, sizeof( msg2_part1 ) ) ); PSA_CHECK( psa_mac_update( &op, msg2_part2, sizeof( msg2_part2 ) ) ); PSA_CHECK( psa_mac_sign_finish( &op, out, sizeof( out ), &out_len ) ); - print_buf( "msg2", out, sizeof( out ) ); + print_buf( "msg2", out, out_len ); exit: psa_mac_abort( &op ); // needed on error, harmless on success From cf99beb8fedbdd43ccca9ddaff2e2dee407e5ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Feb 2022 10:54:26 +0100 Subject: [PATCH 24/30] Improve naming consistency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/cipher/cipher_aead_demo.c | 8 ++++---- programs/psa/aead_demo.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index 4da1bfc5b49e..c9a41ae5a767 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -181,8 +181,8 @@ static void aead_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) static int aead_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, - const unsigned char *pa, size_t pa_len, - const unsigned char *pb, size_t pb_len ) + const unsigned char *part1, size_t part1_len, + const unsigned char *part2, size_t part2_len ) { int ret; size_t olen; @@ -192,9 +192,9 @@ static int aead_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, CHK( mbedtls_cipher_set_iv( ctx, iv, iv_len ) ); CHK( mbedtls_cipher_reset( ctx ) ); CHK( mbedtls_cipher_update_ad( ctx, ad, ad_len ) ); - CHK( mbedtls_cipher_update( ctx, pa, pa_len, p, &olen ) ); + CHK( mbedtls_cipher_update( ctx, part1, part1_len, p, &olen ) ); p += olen; - CHK( mbedtls_cipher_update( ctx, pb, pb_len, p, &olen ) ); + CHK( mbedtls_cipher_update( ctx, part2, part2_len, p, &olen ) ); p += olen; CHK( mbedtls_cipher_finish( ctx, p, &olen ) ); p += olen; diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c index 396e82883afb..322908bedb86 100644 --- a/programs/psa/aead_demo.c +++ b/programs/psa/aead_demo.c @@ -197,8 +197,8 @@ static void aead_info( psa_key_id_t key, psa_algorithm_t alg ) static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, - const unsigned char *pa, size_t pa_len, - const unsigned char *pb, size_t pb_len ) + const unsigned char *part1, size_t part1_len, + const unsigned char *part2, size_t part2_len ) { psa_status_t status; size_t olen, olen_tag; @@ -211,9 +211,9 @@ static int aead_encrypt( psa_key_id_t key, psa_algorithm_t alg, PSA_CHECK( psa_aead_set_nonce( &op, iv, iv_len ) ); PSA_CHECK( psa_aead_update_ad( &op, ad, ad_len ) ); - PSA_CHECK( psa_aead_update( &op, pa, pa_len, p, end - p, &olen ) ); + PSA_CHECK( psa_aead_update( &op, part1, part1_len, p, end - p, &olen ) ); p += olen; - PSA_CHECK( psa_aead_update( &op, pb, pb_len, p, end - p, &olen ) ); + PSA_CHECK( psa_aead_update( &op, part2, part2_len, p, end - p, &olen ) ); p += olen; PSA_CHECK( psa_aead_finish( &op, p, end - p, &olen, tag, sizeof( tag ), &olen_tag ) ); From 48bae0295c064d819b7a199565943a9b27437b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Feb 2022 11:14:58 +0100 Subject: [PATCH 25/30] Avoid hardcoding a size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/cipher/cipher_aead_demo.c | 7 ++++--- programs/psa/aead_demo.c | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index c9a41ae5a767..05d1cb0c4b5f 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -80,9 +80,10 @@ const unsigned char add_data2[] = { 0x11, 0x12 }; const unsigned char msg2_part1[] = { 0x13, 0x14 }; const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; -/* This must at least the sum of the length of the 2 parts for each message. - * This is a macro for the sake of compilers with insufficient C99 support. */ -#define MSG_MAX_SIZE 5 +/* Maximum total size of the messages */ +#define MSG1_SIZE ( sizeof( msg1_part1 ) + sizeof( msg1_part2 ) ) +#define MSG2_SIZE ( sizeof( msg2_part1 ) + sizeof( msg2_part2 ) ) +#define MSG_MAX_SIZE ( MSG1_SIZE > MSG2_SIZE ? MSG1_SIZE : MSG2_SIZE ) /* Dummy key material - never do this in production! * 32-byte is enough to all the key size supported by this program. */ diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c index 322908bedb86..ac7bf65773e8 100644 --- a/programs/psa/aead_demo.c +++ b/programs/psa/aead_demo.c @@ -82,9 +82,10 @@ const unsigned char add_data2[] = { 0x11, 0x12 }; const unsigned char msg2_part1[] = { 0x13, 0x14 }; const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; -/* This must at least the sum of the length of the 2 parts for each message. - * This is a macro for the sake of compilers with insufficient C99 support. */ -#define MSG_MAX_SIZE 5 +/* Maximum total size of the messages */ +#define MSG1_SIZE ( sizeof( msg1_part1 ) + sizeof( msg1_part2 ) ) +#define MSG2_SIZE ( sizeof( msg2_part1 ) + sizeof( msg2_part2 ) ) +#define MSG_MAX_SIZE ( MSG1_SIZE > MSG2_SIZE ? MSG1_SIZE : MSG2_SIZE ) /* Dummy key material - never do this in production! * 32-byte is enough to all the key size supported by this program. */ From 340808ca67b843fab483883197485301adcdcc14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Feb 2022 11:15:26 +0100 Subject: [PATCH 26/30] Add comments on error codes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/cipher/cipher_aead_demo.c | 4 +++- programs/hash/md_hmac_demo.c | 4 +++- programs/psa/aead_demo.c | 4 +++- programs/psa/hmac_demo.c | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index 05d1cb0c4b5f..0cee51f7cf4b 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -98,7 +98,9 @@ void print_buf( const char *title, unsigned char *buf, size_t len ) printf( "\n" ); } -/* Run an Mbed TLS function and bail out if it fails. */ +/* Run an Mbed TLS function and bail out if it fails. + * A string description of the error code can be recovered with: + * programs/util/strerror */ #define CHK( expr ) \ do \ { \ diff --git a/programs/hash/md_hmac_demo.c b/programs/hash/md_hmac_demo.c index 0f6495c866ed..d4cc3ccd4c37 100644 --- a/programs/hash/md_hmac_demo.c +++ b/programs/hash/md_hmac_demo.c @@ -77,7 +77,9 @@ void print_buf( const char *title, unsigned char *buf, size_t len ) printf( "\n" ); } -/* Run an Mbed TLS function and bail out if it fails. */ +/* Run an Mbed TLS function and bail out if it fails. + * A string description of the error code can be recovered with: + * programs/util/strerror */ #define CHK( expr ) \ do \ { \ diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c index ac7bf65773e8..7a07d8b0c4e1 100644 --- a/programs/psa/aead_demo.c +++ b/programs/psa/aead_demo.c @@ -100,7 +100,9 @@ void print_buf( const char *title, uint8_t *buf, size_t len ) printf( "\n" ); } -/* Run a PSA function and bail out if it fails. */ +/* Run a PSA function and bail out if it fails. + * The symbolic name of the error code can be recovered using: + * programs/psa/psa_consant_name status */ #define PSA_CHECK( expr ) \ do \ { \ diff --git a/programs/psa/hmac_demo.c b/programs/psa/hmac_demo.c index 3cb0d21dd155..c6c320bdba18 100644 --- a/programs/psa/hmac_demo.c +++ b/programs/psa/hmac_demo.c @@ -79,7 +79,9 @@ void print_buf( const char *title, uint8_t *buf, size_t len ) printf( "\n" ); } -/* Run a PSA function and bail out if it fails. */ +/* Run a PSA function and bail out if it fails. + * The symbolic name of the error code can be recovered using: + * programs/psa/psa_consant_name status */ #define PSA_CHECK( expr ) \ do \ { \ From 64754e1b8d17d3db7421a02c995b59abb2c0c6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Feb 2022 11:21:14 +0100 Subject: [PATCH 27/30] Wrap long lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/cipher/cipher_aead_demo.c | 6 ++++-- programs/psa/aead_demo.c | 16 +++++++++------- programs/psa/hmac_demo.c | 9 +++++---- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index 0cee51f7cf4b..069c2ee50d23 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -66,7 +66,8 @@ int main( void ) /* The real program starts here. */ -const char usage[] = "Usage: cipher_aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; +const char usage[] = +"Usage: cipher_aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; /* Dummy data for encryption: IV/nonce, additional data, 2-part message */ const unsigned char iv1[12] = { 0x00 }; @@ -175,7 +176,8 @@ static void aead_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) : mode == MBEDTLS_MODE_CHACHAPOLY ? "ChachaPoly" : "???"; - printf( "cipher: %s, %d, %s, %u\n", ciph, key_bits, mode_str, (unsigned) tag_len ); + printf( "cipher: %s, %d, %s, %u\n", + ciph, key_bits, mode_str, (unsigned) tag_len ); } /* diff --git a/programs/psa/aead_demo.c b/programs/psa/aead_demo.c index 7a07d8b0c4e1..5bc0af029744 100644 --- a/programs/psa/aead_demo.c +++ b/programs/psa/aead_demo.c @@ -4,9 +4,9 @@ * This program AEAD-encrypts a message, using the algorithm and key size * specified on the command line, using the multi-part API. * - * It comes with a companion program cipher/cipher_aead_demo.c, which does the same - * operations with the legacy Cipher API. The goal is that comparing the two - * programs will help people migrating to the PSA Crypto API. + * It comes with a companion program cipher/cipher_aead_demo.c, which does the + * same operations with the legacy Cipher API. The goal is that comparing the + * two programs will help people migrating to the PSA Crypto API. * * When used with multi-part AEAD operations, the `mbedtls_cipher_context` * serves a triple purpose (1) hold the key, (2) store the algorithm when no @@ -18,9 +18,10 @@ * On the other hand, with PSA, the algorithms encodes the desired tag length; * with Cipher the desired tag length needs to be tracked separately. * - * This program and its companion cipher/cipher_aead_demo.c illustrate this by doing the - * same sequence of multi-part AEAD computation with both APIs; looking at the - * two side by side should make the differences and similarities clear. + * This program and its companion cipher/cipher_aead_demo.c illustrate this by + * doing the same sequence of multi-part AEAD computation with both APIs; + * looking at the two side by side should make the differences and + * similarities clear. */ /* @@ -68,7 +69,8 @@ int main( void ) /* The real program starts here. */ -const char usage[] = "Usage: aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; +const char usage[] = +"Usage: aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; /* Dummy data for encryption: IV/nonce, additional data, 2-part message */ const unsigned char iv1[12] = { 0x00 }; diff --git a/programs/psa/hmac_demo.c b/programs/psa/hmac_demo.c index c6c320bdba18..aa56b413be45 100644 --- a/programs/psa/hmac_demo.c +++ b/programs/psa/hmac_demo.c @@ -13,9 +13,9 @@ * objects: (1) a psa_key_id_t to hold the key, and (2) a psa_operation_t for * multi-part progress. * - * This program and its companion hash/md_hmac_demo.c illustrate this by doing the - * same sequence of multi-part HMAC computation with both APIs; looking at the - * two side by side should make the differences and similarities clear. + * This program and its companion hash/md_hmac_demo.c illustrate this by doing + * the same sequence of multi-part HMAC computation with both APIs; looking at + * the two side by side should make the differences and similarities clear. */ /* @@ -118,7 +118,8 @@ psa_status_t hmac_demo(void) psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); psa_set_key_bits( &attributes, 8 * sizeof( key_bytes ) ); // optional - status = psa_import_key( &attributes, key_bytes, sizeof( key_bytes ), &key ); + status = psa_import_key( &attributes, + key_bytes, sizeof( key_bytes ), &key ); if( status != PSA_SUCCESS ) return( status ); From 5e6c8843155d2bd3b1526bbfa0a246365c83a544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Feb 2022 11:29:59 +0100 Subject: [PATCH 28/30] Improve info() function in cipher_aead_demo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/cipher/cipher_aead_demo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index 069c2ee50d23..c92eab09d61e 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -167,8 +167,9 @@ static int aead_prepare( const char *info, */ static void aead_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) { - // no convenient way to get the just cipher type (for example, AES) - const char *ciph = "???"; + mbedtls_cipher_type_t type = mbedtls_cipher_get_type( ctx ); + const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type( type ); + const char *ciph = mbedtls_cipher_info_get_name( info ); int key_bits = mbedtls_cipher_get_key_bitlen( ctx ); mbedtls_cipher_mode_t mode = mbedtls_cipher_get_cipher_mode( ctx ); From c82504e22cca38f1c5e0ba6430eec3698d778703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Feb 2022 11:31:36 +0100 Subject: [PATCH 29/30] Clean up output from cipher_aead_demo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Used to print "cipher:" when it was the cipher part of a program that had both cipher and PSA. Now it doesn't really make sense. Align the output to match the PSA version of this program. Signed-off-by: Manuel Pégourié-Gonnard --- programs/cipher/cipher_aead_demo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index c92eab09d61e..366b9a3ec362 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -177,7 +177,7 @@ static void aead_info( const mbedtls_cipher_context_t *ctx, size_t tag_len ) : mode == MBEDTLS_MODE_CHACHAPOLY ? "ChachaPoly" : "???"; - printf( "cipher: %s, %d, %s, %u\n", + printf( "%s, %d, %s, %u\n", ciph, key_bits, mode_str, (unsigned) tag_len ); } @@ -208,7 +208,7 @@ static int aead_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, p += tag_len; olen = p - out; - print_buf( "cipher", out, olen ); + print_buf( "out", out, olen ); exit: return( ret ); From ae1bae841213ecdfb577cbdcf496e7fa880039c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Feb 2022 11:36:28 +0100 Subject: [PATCH 30/30] Give a magic constant a name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- programs/cipher/cipher_aead_demo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/programs/cipher/cipher_aead_demo.c b/programs/cipher/cipher_aead_demo.c index 366b9a3ec362..18bd66c81242 100644 --- a/programs/cipher/cipher_aead_demo.c +++ b/programs/cipher/cipher_aead_demo.c @@ -192,7 +192,8 @@ static int aead_encrypt( mbedtls_cipher_context_t *ctx, size_t tag_len, { int ret; size_t olen; - unsigned char out[MSG_MAX_SIZE + 16]; +#define MAX_TAG_LENGTH 16 + unsigned char out[MSG_MAX_SIZE + MAX_TAG_LENGTH]; unsigned char *p = out; CHK( mbedtls_cipher_set_iv( ctx, iv, iv_len ) );