From 35269d93da0bb5ae4d872bce0503761dc2842781 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 25 May 2022 11:26:31 +0200 Subject: [PATCH 01/55] Fill psa_pake_operation and INPUT/OUTPUT min/max sizes for PSA PAKE builtin implementation Signed-off-by: Neil Armstrong --- include/psa/crypto_extra.h | 47 ++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 6de464d9db..eaadf817c0 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -1760,7 +1760,13 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); * recognized, or the parameters are incompatible, * return 0. */ -#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) 0 +#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \ + ( alg == PSA_ALG_JPAKE && \ + primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \ + PSA_ECC_FAMILY_SECP_R1, 256) ? \ + ( output_step == PSA_PAKE_STEP_KEY_SHARE ? 69 : \ + ( output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 66 : 33 ) ) : 0 ) + /** A sufficient input buffer size for psa_pake_input(). * @@ -1781,7 +1787,12 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); * the input type or PAKE algorithm is not recognized, or * the parameters are incompatible, return 0. */ -#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) 0 +#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \ + ( alg == PSA_ALG_JPAKE && \ + primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \ + PSA_ECC_FAMILY_SECP_R1, 256) ? \ + ( input_step == PSA_PAKE_STEP_KEY_SHARE ? 69 : \ + ( input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 66 : 33 ) ) : 0 ) /** Output buffer size for psa_pake_output() for any of the supported PAKE * algorithm and primitive suites and output step. @@ -1790,7 +1801,7 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); * * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p step). */ -#define PSA_PAKE_OUTPUT_MAX_SIZE 0 +#define PSA_PAKE_OUTPUT_MAX_SIZE 69 /** Input buffer size for psa_pake_input() for any of the supported PAKE * algorithm and primitive suites and input step. @@ -1799,7 +1810,7 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); * * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p step). */ -#define PSA_PAKE_INPUT_MAX_SIZE 0 +#define PSA_PAKE_INPUT_MAX_SIZE 69 /** Returns a suitable initializer for a PAKE cipher suite object of type * psa_pake_cipher_suite_t. @@ -1809,7 +1820,11 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); /** Returns a suitable initializer for a PAKE operation object of type * psa_pake_operation_t. */ -#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, {0}} +#if defined(MBEDTLS_PSA_BUILTIN_PAKE) +#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0, MBEDTLS_SVC_KEY_ID_INIT, 0, NULL, 0, 0, { .dummy = 0 } } +#else +#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, {0}} +#endif struct psa_pake_cipher_suite_s { @@ -1879,14 +1894,32 @@ static inline void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite, cipher_suite->hash = hash; } +#if defined(MBEDTLS_PSA_BUILTIN_PAKE) +#include +#endif + struct psa_pake_operation_s { - psa_algorithm_t alg; + psa_algorithm_t MBEDTLS_PRIVATE(alg); + unsigned int MBEDTLS_PRIVATE(state); + unsigned int MBEDTLS_PRIVATE(sequence); +#if defined(MBEDTLS_PSA_BUILTIN_PAKE) + unsigned int MBEDTLS_PRIVATE(input_step); + unsigned int MBEDTLS_PRIVATE(output_step); + mbedtls_svc_key_id_t MBEDTLS_PRIVATE(password); + psa_pake_role_t MBEDTLS_PRIVATE(role); + uint8_t *MBEDTLS_PRIVATE(buffer); + size_t MBEDTLS_PRIVATE(buffer_length); + size_t MBEDTLS_PRIVATE(buffer_offset); +#endif union { +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) + mbedtls_ecjpake_context ecjpake; +#endif /* Make the union non-empty even with no supported algorithms. */ uint8_t dummy; - } ctx; + } MBEDTLS_PRIVATE(ctx); }; static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init( void ) From 4b5710f8a0a41afd0031cf59e1239a6b58b5acc2 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 25 May 2022 11:30:27 +0200 Subject: [PATCH 02/55] Allow KEY_TYPE_PASSWORD/KEY_TYPE_PASSWORD_HASH to be imported Signed-off-by: Neil Armstrong --- library/psa_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index b0116ddfb4..4a0bd83316 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -445,6 +445,8 @@ psa_status_t psa_validate_unstructured_key_bit_size( psa_key_type_t type, case PSA_KEY_TYPE_RAW_DATA: case PSA_KEY_TYPE_HMAC: case PSA_KEY_TYPE_DERIVE: + case PSA_KEY_TYPE_PASSWORD: + case PSA_KEY_TYPE_PASSWORD_HASH: break; #if defined(PSA_WANT_KEY_TYPE_AES) case PSA_KEY_TYPE_AES: From a4cc7d6d6ba18dbfe66829dd944d2d9237a92148 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 25 May 2022 11:30:48 +0200 Subject: [PATCH 03/55] Add PSA PAKE buildin implementation Signed-off-by: Neil Armstrong --- library/CMakeLists.txt | 1 + library/Makefile | 1 + library/psa_crypto_pake.c | 720 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 722 insertions(+) create mode 100644 library/psa_crypto_pake.c diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 378cfb4570..951381475e 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -70,6 +70,7 @@ set(src_crypto psa_crypto_ecp.c psa_crypto_hash.c psa_crypto_mac.c + psa_crypto_pake.c psa_crypto_rsa.c psa_crypto_se.c psa_crypto_slot_management.c diff --git a/library/Makefile b/library/Makefile index 85cea6b08d..9c3af3b9b5 100644 --- a/library/Makefile +++ b/library/Makefile @@ -135,6 +135,7 @@ OBJS_CRYPTO= \ psa_crypto_ecp.o \ psa_crypto_hash.o \ psa_crypto_mac.o \ + psa_crypto_pake.o \ psa_crypto_rsa.o \ psa_crypto_se.o \ psa_crypto_slot_management.o \ diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c new file mode 100644 index 0000000000..9f91a5ee16 --- /dev/null +++ b/library/psa_crypto_pake.c @@ -0,0 +1,720 @@ +/* + * PSA PAKE layer on top of Mbed TLS software crypto + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" + +#if defined(MBEDTLS_PSA_CRYPTO_C) + +#include +#include "psa_crypto_core.h" +#include "psa_crypto_slot_management.h" + +#include +#include + +#include +#include +#include + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#define PSA_PAKE_BUFFER_SIZE ( ( 69 + 66 + 33 ) * 2 ) +#endif + +/* + * State sequence: + * + * psa_pake_setup() + * | + * |-- In any order: + * | | psa_pake_set_password_key() + * | | psa_pake_set_user() + * | | psa_pake_set_peer() + * | | psa_pake_set_role + * | + * |--- In any order: (First round input before or after first round output) + * | | + * | |------ In Order + * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE) + * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC) + * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF) + * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE) + * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC) + * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF) + * | | + * | |------ In Order: + * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE) + * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC) + * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF) + * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE) + * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC) + * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF) + * | + * |--- In any order: (Second round input before or after second round output) + * | | + * | |------ In Order + * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE) + * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC) + * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF) + * | | + * | |------ In Order: + * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE) + * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC) + * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF) + * | + * psa_pake_get_implicit_key() + * psa_pake_abort() + */ + +enum psa_pake_step +{ + PSA_PAKE_STEP_INVALID = 0, + PSA_PAKE_STEP_X1_X2 = 1, + PSA_PAKE_STEP_X2S = 2, + PSA_PAKE_STEP_DERIVE = 3, +}; + +enum psa_pake_state +{ + PSA_PAKE_STATE_INVALID = 0, + PSA_PAKE_STATE_SETUP = 1, + PSA_PAKE_STATE_READY = 2, + PSA_PAKE_OUTPUT_X1_X2 = 3, + PSA_PAKE_OUTPUT_X2S = 4, + PSA_PAKE_INPUT_X1_X2 = 5, + PSA_PAKE_INPUT_X4S = 6, +}; + +enum psa_pake_sequence +{ + PSA_PAKE_SEQ_INVALID = 0, + PSA_PAKE_X1_STEP_KEY_SHARE = 1, /* also X2S & X4S KEY_SHARE */ + PSA_PAKE_X1_STEP_ZK_PUBLIC = 2, /* also X2S & X4S ZK_PUBLIC */ + PSA_PAKE_X1_STEP_ZK_PROOF = 3, /* also X2S & X4S ZK_PROOF */ + PSA_PAKE_X2_STEP_KEY_SHARE = 4, + PSA_PAKE_X2_STEP_ZK_PUBLIC = 5, + PSA_PAKE_X2_STEP_ZK_PROOF = 6, + PSA_PAKE_SEQ_END = 7, +}; + +#if defined(MBEDTLS_PSA_BUILTIN_PAKE) +psa_status_t psa_pake_setup( psa_pake_operation_t *operation, + const psa_pake_cipher_suite_t *cipher_suite) +{ + /* A context must be freshly initialized before it can be set up. */ + if( operation->alg != 0 || operation->state != PSA_PAKE_STATE_INVALID ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( cipher_suite == NULL || + PSA_ALG_IS_PAKE(cipher_suite->algorithm ) == 0 || + ( cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC && + cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_DH ) || + PSA_ALG_IS_HASH( cipher_suite->hash ) == 0 ) + { + return( PSA_ERROR_INVALID_ARGUMENT ); + } + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) + if( cipher_suite->algorithm != PSA_ALG_JPAKE || + cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC || + cipher_suite->family != PSA_ECC_FAMILY_SECP_R1 || + cipher_suite->bits != 256 || + cipher_suite->hash != PSA_ALG_SHA_256 ) + { + return( PSA_ERROR_NOT_SUPPORTED ); + } + + operation->alg = cipher_suite->algorithm; + + mbedtls_ecjpake_init( &operation->ctx.ecjpake ); + + operation->state = PSA_PAKE_STATE_SETUP; + operation->sequence = PSA_PAKE_SEQ_INVALID; + operation->input_step = PSA_PAKE_STEP_X1_X2; + operation->output_step = PSA_PAKE_STEP_X1_X2; + + operation->buffer = NULL; + operation->buffer_length = 0; + operation->buffer_offset = 0; + + return( PSA_SUCCESS ); +#else + return( PSA_ERROR_NOT_SUPPORTED ); +#endif +} + +psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation, + mbedtls_svc_key_id_t password ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_attributes_t attributes = psa_key_attributes_init(); + psa_key_type_t type; + psa_key_usage_t usage; + + if( operation->alg == 0 || + operation->state != PSA_PAKE_STATE_SETUP ) + { + return( PSA_ERROR_BAD_STATE ); + } + + status = psa_get_key_attributes( password, &attributes ); + if( status != PSA_SUCCESS ) + return status; + + type = psa_get_key_type( &attributes ); + usage = psa_get_key_usage_flags( &attributes ); + + psa_reset_key_attributes( &attributes ); + + if( type != PSA_KEY_TYPE_PASSWORD && + type != PSA_KEY_TYPE_PASSWORD_HASH ) + { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if( usage == 0 || + ( usage & PSA_KEY_USAGE_DERIVE ) == 0 ) + { + return PSA_ERROR_NOT_PERMITTED; + } + + operation->password = password; + + return( PSA_SUCCESS ); +} + +psa_status_t psa_pake_set_user( psa_pake_operation_t *operation, + const uint8_t *user_id, + size_t user_id_len ) +{ + if( operation->alg == 0 || + operation->state != PSA_PAKE_STATE_SETUP ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( user_id_len == 0 || user_id == NULL ) + return PSA_ERROR_INVALID_ARGUMENT; + + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t psa_pake_set_peer( psa_pake_operation_t *operation, + const uint8_t *peer_id, + size_t peer_id_len ) +{ + if( operation->alg == 0 || + operation->state != PSA_PAKE_STATE_SETUP ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( peer_id_len == 0 || peer_id == NULL ) + return PSA_ERROR_INVALID_ARGUMENT; + + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t psa_pake_set_role( psa_pake_operation_t *operation, + psa_pake_role_t role ) +{ + if( operation->alg == 0 || + operation->state != PSA_PAKE_STATE_SETUP ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( role != PSA_PAKE_ROLE_NONE && + role != PSA_PAKE_ROLE_FIRST && + role != PSA_PAKE_ROLE_SECOND && + role != PSA_PAKE_ROLE_CLIENT && + role != PSA_PAKE_ROLE_SERVER ) + { + return PSA_ERROR_INVALID_ARGUMENT; + } + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) + if( operation->alg == PSA_ALG_JPAKE ) + { + if( role != PSA_PAKE_ROLE_CLIENT && + role != PSA_PAKE_ROLE_SERVER ) + return PSA_ERROR_NOT_SUPPORTED; + + operation->role = role; + + return( PSA_SUCCESS ); + } + else +#endif + return( PSA_ERROR_NOT_SUPPORTED ); +} + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + mbedtls_ecjpake_role role; + psa_key_slot_t *slot = NULL; + + if( operation->role == PSA_PAKE_ROLE_CLIENT ) + role = MBEDTLS_ECJPAKE_CLIENT; + else if( operation->role == PSA_PAKE_ROLE_SERVER ) + role = MBEDTLS_ECJPAKE_SERVER; + else + return( PSA_ERROR_BAD_STATE ); + + if( psa_is_valid_key_id( operation->password, 1 ) == 0 ) + return( PSA_ERROR_BAD_STATE ); + + status = psa_get_and_lock_key_slot( operation->password, &slot ); + if( status != PSA_SUCCESS ) + return( status ); + + + ret = mbedtls_ecjpake_setup( &operation->ctx.ecjpake, + role, + MBEDTLS_MD_SHA256, + MBEDTLS_ECP_DP_SECP256R1, + slot->key.data, slot->key.bytes ); + + psa_unlock_key_slot( slot ); + slot = NULL; + + if( ret != 0 ) + return( mbedtls_to_psa_error( ret ) ); + + operation->buffer = mbedtls_calloc( 1, 512 ); + if( operation->buffer == NULL ) + return( PSA_ERROR_INSUFFICIENT_MEMORY ); + + operation->state = PSA_PAKE_STATE_READY; + + return( PSA_SUCCESS ); +} +#endif + +psa_status_t psa_pake_output( psa_pake_operation_t *operation, + psa_pake_step_t step, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t length; + + if( operation->alg == 0 || + operation->state == PSA_PAKE_STATE_INVALID ) + return( PSA_ERROR_BAD_STATE ); + + if( step != PSA_PAKE_STEP_KEY_SHARE && + step != PSA_PAKE_STEP_ZK_PUBLIC && + step != PSA_PAKE_STEP_ZK_PROOF ) + return( PSA_ERROR_INVALID_ARGUMENT ); + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) + if( operation->state == PSA_PAKE_STATE_SETUP ) { + status = psa_pake_ecjpake_setup( operation ); + if( status != PSA_SUCCESS ) + { + psa_pake_abort( operation ); + return( status ); + } + } + + if( operation->state >= PSA_PAKE_STATE_READY && + ( mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 || + operation->buffer == NULL ) ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( operation->state != PSA_PAKE_STATE_READY && + operation->state != PSA_PAKE_OUTPUT_X1_X2 && + operation->state != PSA_PAKE_OUTPUT_X2S ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( operation->state == PSA_PAKE_STATE_READY ) + { + if( step != PSA_PAKE_STEP_KEY_SHARE ) + return( PSA_ERROR_BAD_STATE ); + + switch( operation->output_step ) + { + case PSA_PAKE_STEP_X1_X2: + operation->state = PSA_PAKE_OUTPUT_X1_X2; + break; + case PSA_PAKE_STEP_X2S: + operation->state = PSA_PAKE_OUTPUT_X2S; + break; + default: + return( PSA_ERROR_BAD_STATE ); + } + + operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE; + } + + /* Check if step matches current sequence */ + switch( operation->sequence ) + { + case PSA_PAKE_X1_STEP_KEY_SHARE: + case PSA_PAKE_X2_STEP_KEY_SHARE: + if( step != PSA_PAKE_STEP_KEY_SHARE ) + return( PSA_ERROR_BAD_STATE ); + break; + + case PSA_PAKE_X1_STEP_ZK_PUBLIC: + case PSA_PAKE_X2_STEP_ZK_PUBLIC: + if( step != PSA_PAKE_STEP_ZK_PUBLIC ) + return( PSA_ERROR_BAD_STATE ); + break; + + case PSA_PAKE_X1_STEP_ZK_PROOF: + case PSA_PAKE_X2_STEP_ZK_PROOF: + if( step != PSA_PAKE_STEP_ZK_PROOF ) + return( PSA_ERROR_BAD_STATE ); + break; + + default: + return( PSA_ERROR_BAD_STATE ); + } + + /* Initialize & write round on KEY_SHARE sequences */ + if( operation->state == PSA_PAKE_OUTPUT_X1_X2 && + operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) + { + ret = mbedtls_ecjpake_write_round_one( &operation->ctx.ecjpake, + operation->buffer, + PSA_PAKE_BUFFER_SIZE, + &operation->buffer_length, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE ); + if( ret != 0 ) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } + + operation->buffer_offset = 0; + } + else if( operation->state == PSA_PAKE_OUTPUT_X2S && + operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) + { + ret = mbedtls_ecjpake_write_round_two( &operation->ctx.ecjpake, + operation->buffer, + PSA_PAKE_BUFFER_SIZE, + &operation->buffer_length, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE ); + if( ret != 0 ) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } + + operation->buffer_offset = 0; + } + + /* Load output sequence length */ + if( operation->state == PSA_PAKE_OUTPUT_X2S && + operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) + { + if( operation->role == PSA_PAKE_ROLE_SERVER ) + /* Length is stored after 3bytes curve */ + length = 3 + operation->buffer[3] + 1; + else + /* Length is stored at the first byte */ + length = operation->buffer[0] + 1; + } + else + { + /* Length is stored at the first byte */ + length = operation->buffer[operation->buffer_offset] + 1; + } + + if( length > operation->buffer_length ) + return( PSA_ERROR_DATA_CORRUPT ); + + if( output_size < length ) + { + psa_pake_abort( operation ); + return( PSA_ERROR_BUFFER_TOO_SMALL ); + } + + memcpy( output, + operation->buffer + operation->buffer_offset, + length ); + *output_length = length; + + operation->buffer_offset += length; + + /* Reset buffer after ZK_PROOF sequence */ + if( ( operation->state == PSA_PAKE_OUTPUT_X1_X2 && + operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) || + ( operation->state == PSA_PAKE_OUTPUT_X2S && + operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) ) + { + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); + operation->buffer_length = 0; + operation->buffer_offset = 0; + + operation->state = PSA_PAKE_STATE_READY; + operation->output_step++; + operation->sequence = 0; + } + else + { + operation->sequence++; + } + + return( PSA_SUCCESS ); +#else + return( PSA_ERROR_NOT_SUPPORTED ); +#endif +} + +psa_status_t psa_pake_input( psa_pake_operation_t *operation, + psa_pake_step_t step, + const uint8_t *input, + size_t input_length ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t buffer_remain; + + if( operation->alg == 0 || + operation->state == PSA_PAKE_STATE_INVALID ) + return( PSA_ERROR_BAD_STATE ); + + if( step != PSA_PAKE_STEP_KEY_SHARE && + step != PSA_PAKE_STEP_ZK_PUBLIC && + step != PSA_PAKE_STEP_ZK_PROOF ) + return( PSA_ERROR_INVALID_ARGUMENT ); + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) + if( operation->state == PSA_PAKE_STATE_SETUP ) { + status = psa_pake_ecjpake_setup( operation ); + if( status != PSA_SUCCESS ) + { + psa_pake_abort( operation ); + return( status ); + } + } + + if( operation->state >= PSA_PAKE_STATE_READY && + ( mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 || + operation->buffer == NULL ) ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( operation->state != PSA_PAKE_STATE_READY && + operation->state != PSA_PAKE_INPUT_X1_X2 && + operation->state != PSA_PAKE_INPUT_X4S ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( operation->state == PSA_PAKE_STATE_READY ) + { + if( step != PSA_PAKE_STEP_KEY_SHARE ) + return( PSA_ERROR_BAD_STATE ); + + switch( operation->input_step ) + { + case PSA_PAKE_STEP_X1_X2: + operation->state = PSA_PAKE_INPUT_X1_X2; + break; + case PSA_PAKE_STEP_X2S: + operation->state = PSA_PAKE_INPUT_X4S; + break; + default: + return( PSA_ERROR_BAD_STATE ); + } + + operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE; + } + + buffer_remain = PSA_PAKE_BUFFER_SIZE - operation->buffer_length; + + if( input_length == 0 || + input_length > buffer_remain ) + { + psa_pake_abort( operation ); + return( PSA_ERROR_INSUFFICIENT_MEMORY ); + } + + /* Check if step matches current sequence */ + switch( operation->sequence ) + { + case PSA_PAKE_X1_STEP_KEY_SHARE: + case PSA_PAKE_X2_STEP_KEY_SHARE: + if( step != PSA_PAKE_STEP_KEY_SHARE ) + return( PSA_ERROR_BAD_STATE ); + break; + + case PSA_PAKE_X1_STEP_ZK_PUBLIC: + case PSA_PAKE_X2_STEP_ZK_PUBLIC: + if( step != PSA_PAKE_STEP_ZK_PUBLIC ) + return( PSA_ERROR_BAD_STATE ); + break; + + case PSA_PAKE_X1_STEP_ZK_PROOF: + case PSA_PAKE_X2_STEP_ZK_PROOF: + if( step != PSA_PAKE_STEP_ZK_PROOF ) + return( PSA_ERROR_BAD_STATE ); + break; + + default: + return( PSA_ERROR_BAD_STATE ); + } + + /* Copy input to local buffer */ + memcpy( operation->buffer + operation->buffer_length, + input, input_length ); + operation->buffer_length += input_length; + + /* Load buffer at each last round ZK_PROOF */ + if( operation->state == PSA_PAKE_INPUT_X1_X2 && + operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) + { + ret = mbedtls_ecjpake_read_round_one( &operation->ctx.ecjpake, + operation->buffer, + operation->buffer_length ); + + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); + operation->buffer_length = 0; + + if( ret != 0 ) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } + } + else if( operation->state == PSA_PAKE_INPUT_X4S && + operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) + { + ret = mbedtls_ecjpake_read_round_two( &operation->ctx.ecjpake, + operation->buffer, + operation->buffer_length ); + + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); + operation->buffer_length = 0; + + if( ret != 0 ) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } + } + + if( ( operation->state == PSA_PAKE_INPUT_X1_X2 && + operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) || + ( operation->state == PSA_PAKE_INPUT_X4S && + operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) ) + { + operation->state = PSA_PAKE_STATE_READY; + operation->input_step++; + operation->sequence = 0; + } + else + { + operation->sequence++; + } + + return( PSA_SUCCESS ); +#else + return( PSA_ERROR_NOT_SUPPORTED ); +#endif +} + +psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, + psa_key_derivation_operation_t *output) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + if( operation->alg == 0 || + operation->state != PSA_PAKE_STATE_READY || + ( operation->input_step != PSA_PAKE_STEP_DERIVE && + operation->output_step != PSA_PAKE_STEP_DERIVE ) ) + return( PSA_ERROR_BAD_STATE ); + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) + ret = mbedtls_ecjpake_derive_secret( &operation->ctx.ecjpake, + operation->buffer, + PSA_PAKE_BUFFER_SIZE, + &operation->buffer_length, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE ); + if( ret != 0) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } + + status = psa_key_derivation_input_bytes( output, + PSA_KEY_DERIVATION_INPUT_SECRET, + operation->buffer, + operation->buffer_length ); + + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); + + psa_pake_abort( operation ); + + return( status ); +#else + return( PSA_ERROR_NOT_SUPPORTED ); +#endif +} + +psa_status_t psa_pake_abort(psa_pake_operation_t * operation) +{ + if( operation->alg == 0 ) + { + return( PSA_SUCCESS ); + } + + operation->alg = 0; + operation->state = 0; + operation->sequence = 0; + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) + operation->input_step = 0; + operation->output_step = 0; + operation->password = MBEDTLS_SVC_KEY_ID_INIT; + operation->role = 0; + mbedtls_free( operation->buffer ); + operation->buffer = NULL; + operation->buffer_length = 0; + operation->buffer_offset = 0; + mbedtls_ecjpake_free( &operation->ctx.ecjpake ); +#endif + + return( PSA_SUCCESS ); +} + +#endif /* MBEDTLS_PSA_BUILTIN_PAKE */ + +#endif /* MBEDTLS_PSA_CRYPTO_C */ From 637d0a0290cab9308cc67db00aa9a7344070a911 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 25 May 2022 11:28:22 +0200 Subject: [PATCH 04/55] Enable buildin PSA PAKE implementation when ECJPAKE_C is selected Signed-off-by: Neil Armstrong --- include/mbedtls/config_psa.h | 16 ++++++++++++++++ include/psa/crypto_config.h | 1 + 2 files changed, 17 insertions(+) diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h index fbfcdc3d2d..80b11951f0 100644 --- a/include/mbedtls/config_psa.h +++ b/include/mbedtls/config_psa.h @@ -146,6 +146,16 @@ extern "C" { #define MBEDTLS_MD5_C #endif +#if defined(PSA_WANT_ALG_ECJPAKE) +#define MBEDTLS_PSA_BUILTIN_PAKE 1 +#define MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE 1 +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_ECP_C +#define MBEDTLS_MD_C +#define MBEDTLS_ECJPAKE_C +#endif /* PSA_WANT_ALG_ECJPAKE */ + #if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) #define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1 #define MBEDTLS_RIPEMD160_C @@ -635,6 +645,12 @@ extern "C" { #define PSA_WANT_ALG_MD5 1 #endif +#if defined(MBEDTLS_ECJPAKE_C) +#define MBEDTLS_PSA_BUILTIN_PAKE 1 +#define MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE 1 +#define PSA_WANT_ALG_ECJPAKE 1 +#endif + #if defined(MBEDTLS_RIPEMD160_C) #define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1 #define PSA_WANT_ALG_RIPEMD160 1 diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h index 991be96ef4..58fb3b1190 100644 --- a/include/psa/crypto_config.h +++ b/include/psa/crypto_config.h @@ -65,6 +65,7 @@ #define PSA_WANT_ALG_ECB_NO_PADDING 1 #define PSA_WANT_ALG_ECDH 1 #define PSA_WANT_ALG_ECDSA 1 +#define PSA_WANT_ALG_ECJPAKE 1 #define PSA_WANT_ALG_GCM 1 #define PSA_WANT_ALG_HKDF 1 #define PSA_WANT_ALG_HKDF_EXTRACT 1 From d597bc705fd42db86baa8addd35d1d08c2f5200a Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 25 May 2022 11:28:39 +0200 Subject: [PATCH 05/55] Add PSA PAKE tests Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.data | 48 +++ tests/suites/test_suite_psa_crypto.function | 324 ++++++++++++++++++++ 2 files changed, 372 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 1182c00693..298a5af0ff 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6445,3 +6445,51 @@ persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY PSA derive persistent key: HKDF SHA-256, exportable persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_TYPE_RAW_DATA:1024:PSA_KEY_USAGE_EXPORT:0:DERIVE_KEY + +PSA PAKE: invalid alg +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_SHA_256:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_INVALID_ARGUMENT + +PSA PAKE: invalid primitive type +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_DH, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED + +PSA PAKE: invalid primitive family +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_K1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED + +PSA PAKE: invalid primitive bits +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 128):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED + +PSA PAKE: ecjpake setup server +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":0 + +PSA PAKE: ecjpake setup server empty password +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"":PSA_ERROR_BAD_STATE + +PSA PAKE: ecjpake setup server invalid step +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_ZK_PROOF:"abcd":PSA_ERROR_BAD_STATE + +PSA PAKE: ecjpake setup client +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:PSA_PAKE_STEP_KEY_SHARE:"abcd":0 + +PSA PAKE: ecjpake setup client empty password +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:PSA_PAKE_STEP_KEY_SHARE:"":PSA_ERROR_BAD_STATE + +PSA PAKE: ecjpake setup client invalid step +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:PSA_PAKE_STEP_ZK_PROOF:"abcd":PSA_ERROR_BAD_STATE + +PSA PAKE: ecjpake setup invalid role NONE +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_NONE:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED + +PSA PAKE: ecjpake rounds +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef" diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 7d368cf162..9b7bb20ec3 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8091,3 +8091,327 @@ exit: PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_ECJPAKE_C */ +void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, + int output_step_arg, data_t *pw_data, + int expected_status_arg ) +{ + psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); + psa_pake_operation_t operation = psa_pake_operation_init(); + psa_algorithm_t alg = alg_arg; + psa_algorithm_t hash_alg = hash_arg; + psa_pake_role_t role = role_arg; + psa_pake_step_t step = output_step_arg; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t expected_status = expected_status_arg; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + unsigned char *output_buffer = NULL; + size_t output_len = 0; + + PSA_INIT( ); + + ASSERT_ALLOC( output_buffer, + PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg, step) ); + + if( pw_data->len > 0 ) + { + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); + psa_set_key_algorithm( &attributes, alg ); + psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); + PSA_ASSERT( psa_import_key( &attributes, pw_data->x, pw_data->len, + &key ) ); + } + + psa_pake_cs_set_algorithm( &cipher_suite, alg ); + psa_pake_cs_set_primitive( &cipher_suite, primitive_arg ); + psa_pake_cs_set_hash( &cipher_suite, hash_alg ); + + status = psa_pake_setup( &operation, &cipher_suite ); + if( status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + goto exit; + } + else + PSA_ASSERT( status ); + + status = psa_pake_set_role( &operation, role ); + if( status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + goto exit; + } + else + PSA_ASSERT( status ); + + if( pw_data->len > 0 ) + { + status = psa_pake_set_password_key( &operation, key ); + if( status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + goto exit; + } + else + PSA_ASSERT( status ); + } + + /* First round Output */ + status = psa_pake_output( &operation, step, output_buffer, + 512, &output_len ); + if( status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + goto exit; + } + else + PSA_ASSERT( status ); + + TEST_ASSERT( output_len > 0 ); + +exit: + PSA_ASSERT( psa_destroy_key( key ) ); + PSA_ASSERT( psa_pake_abort( &operation ) ); + mbedtls_free( output_buffer ); + PSA_DONE( ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_ECJPAKE_C */ +void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, + int derive_alg_arg, data_t *pw_data ) +{ + psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); + psa_pake_operation_t server = psa_pake_operation_init(); + psa_pake_operation_t client = psa_pake_operation_init(); + psa_algorithm_t alg = alg_arg; + psa_algorithm_t hash_alg = hash_arg; + psa_algorithm_t derive_alg = derive_alg_arg; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_derivation_operation_t server_derive = + PSA_KEY_DERIVATION_OPERATION_INIT; + psa_key_derivation_operation_t client_derive = + PSA_KEY_DERIVATION_OPERATION_INIT; + unsigned char *buffer0 = NULL, *buffer1 = NULL; + size_t buffer_length = ( + PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg, PSA_PAKE_STEP_KEY_SHARE) + + PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg, PSA_PAKE_STEP_ZK_PUBLIC) + + PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg, PSA_PAKE_STEP_ZK_PROOF)) * 2; + size_t buffer0_off = 0; + size_t buffer1_off = 0; + size_t s_g1_len, s_g2_len, s_a_len; + size_t s_g1_off, s_g2_off, s_a_off; + size_t s_x1_pk_len, s_x2_pk_len, s_x2s_pk_len; + size_t s_x1_pk_off, s_x2_pk_off, s_x2s_pk_off; + size_t s_x1_pr_len, s_x2_pr_len, s_x2s_pr_len; + size_t s_x1_pr_off, s_x2_pr_off, s_x2s_pr_off; + size_t c_g1_len, c_g2_len, c_a_len; + size_t c_g1_off, c_g2_off, c_a_off; + size_t c_x1_pk_len, c_x2_pk_len, c_x2s_pk_len; + size_t c_x1_pk_off, c_x2_pk_off, c_x2s_pk_off; + size_t c_x1_pr_len, c_x2_pr_len, c_x2s_pr_len; + size_t c_x1_pr_off, c_x2_pr_off, c_x2s_pr_off; + + PSA_INIT( ); + + ASSERT_ALLOC( buffer0, buffer_length ); + ASSERT_ALLOC( buffer1, buffer_length ); + + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); + psa_set_key_algorithm( &attributes, alg ); + psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); + PSA_ASSERT( psa_import_key( &attributes, pw_data->x, pw_data->len, + &key ) ); + + psa_pake_cs_set_algorithm( &cipher_suite, alg ); + psa_pake_cs_set_primitive( &cipher_suite, primitive_arg ); + psa_pake_cs_set_hash( &cipher_suite, hash_alg ); + + PSA_ASSERT( psa_pake_setup( &server, &cipher_suite ) ); + PSA_ASSERT( psa_pake_setup( &client, &cipher_suite ) ); + + PSA_ASSERT( psa_pake_set_role( &server, PSA_PAKE_ROLE_SERVER ) ); + PSA_ASSERT( psa_pake_set_role( &client, PSA_PAKE_ROLE_CLIENT ) ); + + PSA_ASSERT( psa_pake_set_password_key( &server, key ) ); + PSA_ASSERT( psa_pake_set_password_key( &client, key ) ); + + /* Server first round Output */ + PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_g1_len ) ); + s_g1_off = buffer0_off; + buffer0_off += s_g1_len; + PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x1_pk_len ) ); + s_x1_pk_off = buffer0_off; + buffer0_off += s_x1_pk_len; + PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x1_pr_len ) ); + s_x1_pr_off = buffer0_off; + buffer0_off += s_x1_pr_len; + PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_g2_len ) ); + s_g2_off = buffer0_off; + buffer0_off += s_g2_len; + PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x2_pk_len ) ); + s_x2_pk_off = buffer0_off; + buffer0_off += s_x2_pk_len; + PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x2_pr_len ) ); + s_x2_pr_off = buffer0_off; + buffer0_off += s_x2_pr_len; + + /* Client first round Output */ + PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_g1_len ) ); + c_g1_off = buffer1_off; + buffer1_off += c_g1_len; + PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x1_pk_len ) ); + c_x1_pk_off = buffer1_off; + buffer1_off += c_x1_pk_len; + PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x1_pr_len ) ); + c_x1_pr_off = buffer1_off; + buffer1_off += c_x1_pr_len; + PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_g2_len ) ); + c_g2_off = buffer1_off; + buffer1_off += c_g2_len; + PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x2_pk_len ) ); + c_x2_pk_off = buffer1_off; + buffer1_off += c_x2_pk_len; + PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x2_pr_len ) ); + c_x2_pr_off = buffer1_off; + buffer1_off += c_x2_pr_len; + + /* Client first round Input */ + PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g1_off, s_g1_len ) ); + PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x1_pk_off, s_x1_pk_len ) ); + PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x1_pr_off, s_x1_pr_len ) ); + PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g2_off, s_g2_len ) ); + PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2_pk_off, s_x2_pk_len ) ); + PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2_pr_off, s_x2_pr_len ) ); + + /* Server first round Input */ + PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_g1_off, c_g1_len ) ); + PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + c_x1_pk_off, c_x1_pk_len ) ); + PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + c_x1_pr_off, c_x1_pr_len ) ); + PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_g2_off, c_g2_len ) ); + PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + c_x2_pk_off, c_x2_pk_len ) ); + PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + c_x2_pr_off, c_x2_pr_len ) ); + + /* Server second round Output */ + buffer0_off = 0; + + PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_a_len ) ); + s_a_off = buffer0_off; + buffer0_off += s_a_len; + PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x2s_pk_len ) ); + s_x2s_pk_off = buffer0_off; + buffer0_off += s_x2s_pk_len; + PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x2s_pr_len ) ); + s_x2s_pr_off = buffer0_off; + buffer0_off += s_x2s_pr_len; + + /* Client second round Output */ + buffer1_off = 0; + + PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_a_len ) ); + c_a_off = buffer1_off; + buffer1_off += c_a_len; + PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x2s_pk_len ) ); + c_x2s_pk_off = buffer1_off; + buffer1_off += c_x2s_pk_len; + PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x2s_pr_len ) ); + c_x2s_pr_off = buffer1_off; + buffer1_off += c_x2s_pr_len; + + /* Client second round Input */ + PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_a_off, s_a_len ) ); + PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2s_pk_off, s_x2s_pk_len ) ); + PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2s_pr_off, s_x2s_pr_len ) ); + + /* Server second round Input */ + PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_a_off, c_a_len ) ); + PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + c_x2s_pk_off, c_x2s_pk_len ) ); + PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + c_x2s_pr_off, c_x2s_pr_len ) ); + + + /* Get shared key */ + PSA_ASSERT( psa_key_derivation_setup( &server_derive, derive_alg ) ); + PSA_ASSERT( psa_key_derivation_setup( &client_derive, derive_alg ) ); + + if( PSA_ALG_IS_TLS12_PRF( derive_alg ) || + PSA_ALG_IS_TLS12_PSK_TO_MS( derive_alg ) ) + { + PSA_ASSERT( psa_key_derivation_input_bytes( &server_derive, + PSA_KEY_DERIVATION_INPUT_SEED, + (const uint8_t*) "", 0) ); + PSA_ASSERT( psa_key_derivation_input_bytes( &client_derive, + PSA_KEY_DERIVATION_INPUT_SEED, + (const uint8_t*) "", 0) ); + } + + PSA_ASSERT( psa_pake_get_implicit_key( &server, &server_derive ) ); + PSA_ASSERT( psa_pake_get_implicit_key( &client, &client_derive ) ); + +exit: + psa_key_derivation_abort( &server_derive ); + psa_key_derivation_abort( &client_derive ); + psa_destroy_key( key ); + psa_pake_abort( &server ); + psa_pake_abort( &client ); + mbedtls_free( buffer0 ); + mbedtls_free( buffer1 ); + PSA_DONE( ); +} +/* END_CASE */ From c29f8477e2db90372aaea400340d10ccb8d9183c Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 13:34:49 +0200 Subject: [PATCH 06/55] Fix comments in psa_crypto_pake.c Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 9f91a5ee16..594def2ba6 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -46,7 +46,7 @@ * | | psa_pake_set_password_key() * | | psa_pake_set_user() * | | psa_pake_set_peer() - * | | psa_pake_set_role + * | | psa_pake_set_role() * | * |--- In any order: (First round input before or after first round output) * | | @@ -449,7 +449,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, } else { - /* Length is stored at the first byte */ + /* Length is stored at the first byte of the next chunk */ length = operation->buffer[operation->buffer_offset] + 1; } From 5282393091588d6d12c955f83278577d7254d969 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 13:36:12 +0200 Subject: [PATCH 07/55] Remove useless braces in psa_crypto_pake.c Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 594def2ba6..7f730e58db 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -119,9 +119,7 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation, { /* A context must be freshly initialized before it can be set up. */ if( operation->alg != 0 || operation->state != PSA_PAKE_STATE_INVALID ) - { return( PSA_ERROR_BAD_STATE ); - } if( cipher_suite == NULL || PSA_ALG_IS_PAKE(cipher_suite->algorithm ) == 0 || @@ -448,10 +446,8 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, length = operation->buffer[0] + 1; } else - { /* Length is stored at the first byte of the next chunk */ length = operation->buffer[operation->buffer_offset] + 1; - } if( length > operation->buffer_length ) return( PSA_ERROR_DATA_CORRUPT ); @@ -484,9 +480,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, operation->sequence = 0; } else - { operation->sequence++; - } return( PSA_SUCCESS ); #else @@ -639,9 +633,7 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, operation->sequence = 0; } else - { operation->sequence++; - } return( PSA_SUCCESS ); #else From 6b1f99f5f17da4ae9783991928f8f7e611c678e3 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 13:37:37 +0200 Subject: [PATCH 08/55] Use proper buffer size macro for allocation in psa_pake_ecjpake_setup() Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 7f730e58db..05d5854059 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -300,7 +300,7 @@ static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation ) if( ret != 0 ) return( mbedtls_to_psa_error( ret ) ); - operation->buffer = mbedtls_calloc( 1, 512 ); + operation->buffer = mbedtls_calloc( 1, PSA_PAKE_BUFFER_SIZE ); if( operation->buffer == NULL ) return( PSA_ERROR_INSUFFICIENT_MEMORY ); From 7aaa34a1ba49aae25b5371dde1656e7759c751d9 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 14:05:02 +0200 Subject: [PATCH 09/55] Fix formatting of PSA_PAKE_OUTPUT_SIZE & PSA_PAKE_INPUT_SIZE macros Signed-off-by: Neil Armstrong --- include/psa/crypto_extra.h | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index eaadf817c0..16a0c42593 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -1760,13 +1760,16 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); * recognized, or the parameters are incompatible, * return 0. */ -#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \ - ( alg == PSA_ALG_JPAKE && \ - primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \ - PSA_ECC_FAMILY_SECP_R1, 256) ? \ - ( output_step == PSA_PAKE_STEP_KEY_SHARE ? 69 : \ - ( output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 66 : 33 ) ) : 0 ) - +#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \ + ( alg == PSA_ALG_JPAKE && \ + primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \ + PSA_ECC_FAMILY_SECP_R1, 256) ? \ + ( \ + output_step == PSA_PAKE_STEP_KEY_SHARE ? 69 : \ + output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 66 : \ + 33 \ + ) : \ + 0 ) /** A sufficient input buffer size for psa_pake_input(). * @@ -1787,12 +1790,16 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); * the input type or PAKE algorithm is not recognized, or * the parameters are incompatible, return 0. */ -#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \ - ( alg == PSA_ALG_JPAKE && \ - primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \ - PSA_ECC_FAMILY_SECP_R1, 256) ? \ - ( input_step == PSA_PAKE_STEP_KEY_SHARE ? 69 : \ - ( input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 66 : 33 ) ) : 0 ) +#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \ + ( alg == PSA_ALG_JPAKE && \ + primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \ + PSA_ECC_FAMILY_SECP_R1, 256) ? \ + ( \ + input_step == PSA_PAKE_STEP_KEY_SHARE ? 69 : \ + input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 66 : \ + 33 \ + ) : \ + 0 ) /** Output buffer size for psa_pake_output() for any of the supported PAKE * algorithm and primitive suites and output step. From 63212ddf2f7f71e623e8767bfd10b69f015dd9f6 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 14:06:22 +0200 Subject: [PATCH 10/55] Fix formatting of PSA_PAKE_OPERATION_INIT macro Signed-off-by: Neil Armstrong --- include/psa/crypto_extra.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 16a0c42593..9ced06674a 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -1828,7 +1828,9 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); * psa_pake_operation_t. */ #if defined(MBEDTLS_PSA_BUILTIN_PAKE) -#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0, MBEDTLS_SVC_KEY_ID_INIT, 0, NULL, 0, 0, { .dummy = 0 } } +#define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0, \ + MBEDTLS_SVC_KEY_ID_INIT, 0, NULL, 0, 0, \ + {.dummy = 0}} #else #define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, {0}} #endif From 7616ad28e3b7482525490e52d4380c777ef5437b Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 14:07:58 +0200 Subject: [PATCH 11/55] Fix guard of ecjpake.h include in crypto_extra.h Signed-off-by: Neil Armstrong --- include/psa/crypto_extra.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 9ced06674a..32bb358c24 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -1903,7 +1903,7 @@ static inline void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite, cipher_suite->hash = hash; } -#if defined(MBEDTLS_PSA_BUILTIN_PAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) #include #endif From df598abbd3908d4ec7b1fec2a1b0c2aff290ca1c Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 17:17:08 +0200 Subject: [PATCH 12/55] Fix key usage test in psa_pake_set_password_key() Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 05d5854059..7288cacf64 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -188,11 +188,8 @@ psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation, return PSA_ERROR_INVALID_ARGUMENT; } - if( usage == 0 || - ( usage & PSA_KEY_USAGE_DERIVE ) == 0 ) - { + if( ( usage & PSA_KEY_USAGE_DERIVE ) == 0 ) return PSA_ERROR_NOT_PERMITTED; - } operation->password = password; From 4efd7a463d2bf479900a6c0cc6ef29e3d50aac6e Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 17:18:31 +0200 Subject: [PATCH 13/55] Check for PSA_ALG_ECJPAKE alg for the ECJPAKE builtin implementation Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 618 +++++++++++++++++++------------------- 1 file changed, 316 insertions(+), 302 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 7288cacf64..b8a08a1a07 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -131,32 +131,34 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation, } #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) - if( cipher_suite->algorithm != PSA_ALG_JPAKE || - cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC || - cipher_suite->family != PSA_ECC_FAMILY_SECP_R1 || - cipher_suite->bits != 256 || - cipher_suite->hash != PSA_ALG_SHA_256 ) + if( cipher_suite->algorithm == PSA_ALG_JPAKE ) { - return( PSA_ERROR_NOT_SUPPORTED ); + if( cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC || + cipher_suite->family != PSA_ECC_FAMILY_SECP_R1 || + cipher_suite->bits != 256 || + cipher_suite->hash != PSA_ALG_SHA_256 ) + { + return( PSA_ERROR_NOT_SUPPORTED ); + } + + operation->alg = cipher_suite->algorithm; + + mbedtls_ecjpake_init( &operation->ctx.ecjpake ); + + operation->state = PSA_PAKE_STATE_SETUP; + operation->sequence = PSA_PAKE_SEQ_INVALID; + operation->input_step = PSA_PAKE_STEP_X1_X2; + operation->output_step = PSA_PAKE_STEP_X1_X2; + + operation->buffer = NULL; + operation->buffer_length = 0; + operation->buffer_offset = 0; + + return( PSA_SUCCESS ); } - - operation->alg = cipher_suite->algorithm; - - mbedtls_ecjpake_init( &operation->ctx.ecjpake ); - - operation->state = PSA_PAKE_STATE_SETUP; - operation->sequence = PSA_PAKE_SEQ_INVALID; - operation->input_step = PSA_PAKE_STEP_X1_X2; - operation->output_step = PSA_PAKE_STEP_X1_X2; - - operation->buffer = NULL; - operation->buffer_length = 0; - operation->buffer_offset = 0; - - return( PSA_SUCCESS ); -#else - return( PSA_ERROR_NOT_SUPPORTED ); + else #endif + return( PSA_ERROR_NOT_SUPPORTED ); } psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation, @@ -327,162 +329,165 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, return( PSA_ERROR_INVALID_ARGUMENT ); #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) - if( operation->state == PSA_PAKE_STATE_SETUP ) { - status = psa_pake_ecjpake_setup( operation ); - if( status != PSA_SUCCESS ) - { - psa_pake_abort( operation ); - return( status ); + if( operation->alg == PSA_ALG_JPAKE ) + { + if( operation->state == PSA_PAKE_STATE_SETUP ) { + status = psa_pake_ecjpake_setup( operation ); + if( status != PSA_SUCCESS ) + { + psa_pake_abort( operation ); + return( status ); + } } - } - if( operation->state >= PSA_PAKE_STATE_READY && - ( mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 || - operation->buffer == NULL ) ) - { - return( PSA_ERROR_BAD_STATE ); - } - - if( operation->state != PSA_PAKE_STATE_READY && - operation->state != PSA_PAKE_OUTPUT_X1_X2 && - operation->state != PSA_PAKE_OUTPUT_X2S ) - { - return( PSA_ERROR_BAD_STATE ); - } - - if( operation->state == PSA_PAKE_STATE_READY ) - { - if( step != PSA_PAKE_STEP_KEY_SHARE ) - return( PSA_ERROR_BAD_STATE ); - - switch( operation->output_step ) + if( operation->state >= PSA_PAKE_STATE_READY && + ( mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 || + operation->buffer == NULL ) ) { - case PSA_PAKE_STEP_X1_X2: - operation->state = PSA_PAKE_OUTPUT_X1_X2; + return( PSA_ERROR_BAD_STATE ); + } + + if( operation->state != PSA_PAKE_STATE_READY && + operation->state != PSA_PAKE_OUTPUT_X1_X2 && + operation->state != PSA_PAKE_OUTPUT_X2S ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( operation->state == PSA_PAKE_STATE_READY ) + { + if( step != PSA_PAKE_STEP_KEY_SHARE ) + return( PSA_ERROR_BAD_STATE ); + + switch( operation->output_step ) + { + case PSA_PAKE_STEP_X1_X2: + operation->state = PSA_PAKE_OUTPUT_X1_X2; + break; + case PSA_PAKE_STEP_X2S: + operation->state = PSA_PAKE_OUTPUT_X2S; + break; + default: + return( PSA_ERROR_BAD_STATE ); + } + + operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE; + } + + /* Check if step matches current sequence */ + switch( operation->sequence ) + { + case PSA_PAKE_X1_STEP_KEY_SHARE: + case PSA_PAKE_X2_STEP_KEY_SHARE: + if( step != PSA_PAKE_STEP_KEY_SHARE ) + return( PSA_ERROR_BAD_STATE ); break; - case PSA_PAKE_STEP_X2S: - operation->state = PSA_PAKE_OUTPUT_X2S; + + case PSA_PAKE_X1_STEP_ZK_PUBLIC: + case PSA_PAKE_X2_STEP_ZK_PUBLIC: + if( step != PSA_PAKE_STEP_ZK_PUBLIC ) + return( PSA_ERROR_BAD_STATE ); break; + + case PSA_PAKE_X1_STEP_ZK_PROOF: + case PSA_PAKE_X2_STEP_ZK_PROOF: + if( step != PSA_PAKE_STEP_ZK_PROOF ) + return( PSA_ERROR_BAD_STATE ); + break; + default: return( PSA_ERROR_BAD_STATE ); } - operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE; - } - - /* Check if step matches current sequence */ - switch( operation->sequence ) - { - case PSA_PAKE_X1_STEP_KEY_SHARE: - case PSA_PAKE_X2_STEP_KEY_SHARE: - if( step != PSA_PAKE_STEP_KEY_SHARE ) - return( PSA_ERROR_BAD_STATE ); - break; - - case PSA_PAKE_X1_STEP_ZK_PUBLIC: - case PSA_PAKE_X2_STEP_ZK_PUBLIC: - if( step != PSA_PAKE_STEP_ZK_PUBLIC ) - return( PSA_ERROR_BAD_STATE ); - break; - - case PSA_PAKE_X1_STEP_ZK_PROOF: - case PSA_PAKE_X2_STEP_ZK_PROOF: - if( step != PSA_PAKE_STEP_ZK_PROOF ) - return( PSA_ERROR_BAD_STATE ); - break; - - default: - return( PSA_ERROR_BAD_STATE ); - } - - /* Initialize & write round on KEY_SHARE sequences */ - if( operation->state == PSA_PAKE_OUTPUT_X1_X2 && - operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) - { - ret = mbedtls_ecjpake_write_round_one( &operation->ctx.ecjpake, - operation->buffer, - PSA_PAKE_BUFFER_SIZE, - &operation->buffer_length, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE ); - if( ret != 0 ) + /* Initialize & write round on KEY_SHARE sequences */ + if( operation->state == PSA_PAKE_OUTPUT_X1_X2 && + operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) { - psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); + ret = mbedtls_ecjpake_write_round_one( &operation->ctx.ecjpake, + operation->buffer, + PSA_PAKE_BUFFER_SIZE, + &operation->buffer_length, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE ); + if( ret != 0 ) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } + + operation->buffer_offset = 0; + } + else if( operation->state == PSA_PAKE_OUTPUT_X2S && + operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) + { + ret = mbedtls_ecjpake_write_round_two( &operation->ctx.ecjpake, + operation->buffer, + PSA_PAKE_BUFFER_SIZE, + &operation->buffer_length, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE ); + if( ret != 0 ) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } + + operation->buffer_offset = 0; } - operation->buffer_offset = 0; - } - else if( operation->state == PSA_PAKE_OUTPUT_X2S && - operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) - { - ret = mbedtls_ecjpake_write_round_two( &operation->ctx.ecjpake, - operation->buffer, - PSA_PAKE_BUFFER_SIZE, - &operation->buffer_length, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE ); - if( ret != 0 ) + /* Load output sequence length */ + if( operation->state == PSA_PAKE_OUTPUT_X2S && + operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) { - psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); + if( operation->role == PSA_PAKE_ROLE_SERVER ) + /* Length is stored after 3bytes curve */ + length = 3 + operation->buffer[3] + 1; + else + /* Length is stored at the first byte */ + length = operation->buffer[0] + 1; } - - operation->buffer_offset = 0; - } - - /* Load output sequence length */ - if( operation->state == PSA_PAKE_OUTPUT_X2S && - operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) - { - if( operation->role == PSA_PAKE_ROLE_SERVER ) - /* Length is stored after 3bytes curve */ - length = 3 + operation->buffer[3] + 1; else - /* Length is stored at the first byte */ - length = operation->buffer[0] + 1; + /* Length is stored at the first byte of the next chunk */ + length = operation->buffer[operation->buffer_offset] + 1; + + if( length > operation->buffer_length ) + return( PSA_ERROR_DATA_CORRUPT ); + + if( output_size < length ) + { + psa_pake_abort( operation ); + return( PSA_ERROR_BUFFER_TOO_SMALL ); + } + + memcpy( output, + operation->buffer + operation->buffer_offset, + length ); + *output_length = length; + + operation->buffer_offset += length; + + /* Reset buffer after ZK_PROOF sequence */ + if( ( operation->state == PSA_PAKE_OUTPUT_X1_X2 && + operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) || + ( operation->state == PSA_PAKE_OUTPUT_X2S && + operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) ) + { + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); + operation->buffer_length = 0; + operation->buffer_offset = 0; + + operation->state = PSA_PAKE_STATE_READY; + operation->output_step++; + operation->sequence = 0; + } + else + operation->sequence++; + + return( PSA_SUCCESS ); } else - /* Length is stored at the first byte of the next chunk */ - length = operation->buffer[operation->buffer_offset] + 1; - - if( length > operation->buffer_length ) - return( PSA_ERROR_DATA_CORRUPT ); - - if( output_size < length ) - { - psa_pake_abort( operation ); - return( PSA_ERROR_BUFFER_TOO_SMALL ); - } - - memcpy( output, - operation->buffer + operation->buffer_offset, - length ); - *output_length = length; - - operation->buffer_offset += length; - - /* Reset buffer after ZK_PROOF sequence */ - if( ( operation->state == PSA_PAKE_OUTPUT_X1_X2 && - operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) || - ( operation->state == PSA_PAKE_OUTPUT_X2S && - operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) ) - { - mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); - operation->buffer_length = 0; - operation->buffer_offset = 0; - - operation->state = PSA_PAKE_STATE_READY; - operation->output_step++; - operation->sequence = 0; - } - else - operation->sequence++; - - return( PSA_SUCCESS ); -#else - return( PSA_ERROR_NOT_SUPPORTED ); #endif + return( PSA_ERROR_NOT_SUPPORTED ); } psa_status_t psa_pake_input( psa_pake_operation_t *operation, @@ -504,138 +509,141 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, return( PSA_ERROR_INVALID_ARGUMENT ); #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) - if( operation->state == PSA_PAKE_STATE_SETUP ) { - status = psa_pake_ecjpake_setup( operation ); - if( status != PSA_SUCCESS ) + if( operation->alg == PSA_ALG_JPAKE ) + { + if( operation->state == PSA_PAKE_STATE_SETUP ) { + status = psa_pake_ecjpake_setup( operation ); + if( status != PSA_SUCCESS ) + { + psa_pake_abort( operation ); + return( status ); + } + } + + if( operation->state >= PSA_PAKE_STATE_READY && + ( mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 || + operation->buffer == NULL ) ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( operation->state != PSA_PAKE_STATE_READY && + operation->state != PSA_PAKE_INPUT_X1_X2 && + operation->state != PSA_PAKE_INPUT_X4S ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( operation->state == PSA_PAKE_STATE_READY ) + { + if( step != PSA_PAKE_STEP_KEY_SHARE ) + return( PSA_ERROR_BAD_STATE ); + + switch( operation->input_step ) + { + case PSA_PAKE_STEP_X1_X2: + operation->state = PSA_PAKE_INPUT_X1_X2; + break; + case PSA_PAKE_STEP_X2S: + operation->state = PSA_PAKE_INPUT_X4S; + break; + default: + return( PSA_ERROR_BAD_STATE ); + } + + operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE; + } + + buffer_remain = PSA_PAKE_BUFFER_SIZE - operation->buffer_length; + + if( input_length == 0 || + input_length > buffer_remain ) { psa_pake_abort( operation ); - return( status ); + return( PSA_ERROR_INSUFFICIENT_MEMORY ); } - } - if( operation->state >= PSA_PAKE_STATE_READY && - ( mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 || - operation->buffer == NULL ) ) - { - return( PSA_ERROR_BAD_STATE ); - } - - if( operation->state != PSA_PAKE_STATE_READY && - operation->state != PSA_PAKE_INPUT_X1_X2 && - operation->state != PSA_PAKE_INPUT_X4S ) - { - return( PSA_ERROR_BAD_STATE ); - } - - if( operation->state == PSA_PAKE_STATE_READY ) - { - if( step != PSA_PAKE_STEP_KEY_SHARE ) - return( PSA_ERROR_BAD_STATE ); - - switch( operation->input_step ) + /* Check if step matches current sequence */ + switch( operation->sequence ) { - case PSA_PAKE_STEP_X1_X2: - operation->state = PSA_PAKE_INPUT_X1_X2; + case PSA_PAKE_X1_STEP_KEY_SHARE: + case PSA_PAKE_X2_STEP_KEY_SHARE: + if( step != PSA_PAKE_STEP_KEY_SHARE ) + return( PSA_ERROR_BAD_STATE ); break; - case PSA_PAKE_STEP_X2S: - operation->state = PSA_PAKE_INPUT_X4S; + + case PSA_PAKE_X1_STEP_ZK_PUBLIC: + case PSA_PAKE_X2_STEP_ZK_PUBLIC: + if( step != PSA_PAKE_STEP_ZK_PUBLIC ) + return( PSA_ERROR_BAD_STATE ); break; + + case PSA_PAKE_X1_STEP_ZK_PROOF: + case PSA_PAKE_X2_STEP_ZK_PROOF: + if( step != PSA_PAKE_STEP_ZK_PROOF ) + return( PSA_ERROR_BAD_STATE ); + break; + default: return( PSA_ERROR_BAD_STATE ); } - operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE; - } + /* Copy input to local buffer */ + memcpy( operation->buffer + operation->buffer_length, + input, input_length ); + operation->buffer_length += input_length; - buffer_remain = PSA_PAKE_BUFFER_SIZE - operation->buffer_length; - - if( input_length == 0 || - input_length > buffer_remain ) - { - psa_pake_abort( operation ); - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - } - - /* Check if step matches current sequence */ - switch( operation->sequence ) - { - case PSA_PAKE_X1_STEP_KEY_SHARE: - case PSA_PAKE_X2_STEP_KEY_SHARE: - if( step != PSA_PAKE_STEP_KEY_SHARE ) - return( PSA_ERROR_BAD_STATE ); - break; - - case PSA_PAKE_X1_STEP_ZK_PUBLIC: - case PSA_PAKE_X2_STEP_ZK_PUBLIC: - if( step != PSA_PAKE_STEP_ZK_PUBLIC ) - return( PSA_ERROR_BAD_STATE ); - break; - - case PSA_PAKE_X1_STEP_ZK_PROOF: - case PSA_PAKE_X2_STEP_ZK_PROOF: - if( step != PSA_PAKE_STEP_ZK_PROOF ) - return( PSA_ERROR_BAD_STATE ); - break; - - default: - return( PSA_ERROR_BAD_STATE ); - } - - /* Copy input to local buffer */ - memcpy( operation->buffer + operation->buffer_length, - input, input_length ); - operation->buffer_length += input_length; - - /* Load buffer at each last round ZK_PROOF */ - if( operation->state == PSA_PAKE_INPUT_X1_X2 && - operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) - { - ret = mbedtls_ecjpake_read_round_one( &operation->ctx.ecjpake, - operation->buffer, - operation->buffer_length ); - - mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); - operation->buffer_length = 0; - - if( ret != 0 ) + /* Load buffer at each last round ZK_PROOF */ + if( operation->state == PSA_PAKE_INPUT_X1_X2 && + operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) { - psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); + ret = mbedtls_ecjpake_read_round_one( &operation->ctx.ecjpake, + operation->buffer, + operation->buffer_length ); + + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); + operation->buffer_length = 0; + + if( ret != 0 ) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } } - } - else if( operation->state == PSA_PAKE_INPUT_X4S && - operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) - { - ret = mbedtls_ecjpake_read_round_two( &operation->ctx.ecjpake, - operation->buffer, - operation->buffer_length ); - - mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); - operation->buffer_length = 0; - - if( ret != 0 ) + else if( operation->state == PSA_PAKE_INPUT_X4S && + operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) { - psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); - } - } + ret = mbedtls_ecjpake_read_round_two( &operation->ctx.ecjpake, + operation->buffer, + operation->buffer_length ); - if( ( operation->state == PSA_PAKE_INPUT_X1_X2 && - operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) || - ( operation->state == PSA_PAKE_INPUT_X4S && - operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) ) - { - operation->state = PSA_PAKE_STATE_READY; - operation->input_step++; - operation->sequence = 0; + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); + operation->buffer_length = 0; + + if( ret != 0 ) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } + } + + if( ( operation->state == PSA_PAKE_INPUT_X1_X2 && + operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) || + ( operation->state == PSA_PAKE_INPUT_X4S && + operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) ) + { + operation->state = PSA_PAKE_STATE_READY; + operation->input_step++; + operation->sequence = 0; + } + else + operation->sequence++; + + return( PSA_SUCCESS ); } else - operation->sequence++; - - return( PSA_SUCCESS ); -#else - return( PSA_ERROR_NOT_SUPPORTED ); #endif + return( PSA_ERROR_NOT_SUPPORTED ); } psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, @@ -651,31 +659,34 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, return( PSA_ERROR_BAD_STATE ); #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) - ret = mbedtls_ecjpake_derive_secret( &operation->ctx.ecjpake, - operation->buffer, - PSA_PAKE_BUFFER_SIZE, - &operation->buffer_length, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE ); - if( ret != 0) + if( operation->alg == PSA_ALG_JPAKE ) { - psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); - } - - status = psa_key_derivation_input_bytes( output, - PSA_KEY_DERIVATION_INPUT_SECRET, + ret = mbedtls_ecjpake_derive_secret( &operation->ctx.ecjpake, operation->buffer, - operation->buffer_length ); + PSA_PAKE_BUFFER_SIZE, + &operation->buffer_length, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE ); + if( ret != 0) + { + psa_pake_abort( operation ); + return( mbedtls_to_psa_error( ret ) ); + } - mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); + status = psa_key_derivation_input_bytes( output, + PSA_KEY_DERIVATION_INPUT_SECRET, + operation->buffer, + operation->buffer_length ); - psa_pake_abort( operation ); + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); - return( status ); -#else - return( PSA_ERROR_NOT_SUPPORTED ); + psa_pake_abort( operation ); + + return( status ); + } + else #endif + return( PSA_ERROR_NOT_SUPPORTED ); } psa_status_t psa_pake_abort(psa_pake_operation_t * operation) @@ -690,15 +701,18 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation) operation->sequence = 0; #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) - operation->input_step = 0; - operation->output_step = 0; - operation->password = MBEDTLS_SVC_KEY_ID_INIT; - operation->role = 0; - mbedtls_free( operation->buffer ); - operation->buffer = NULL; - operation->buffer_length = 0; - operation->buffer_offset = 0; - mbedtls_ecjpake_free( &operation->ctx.ecjpake ); + if( operation->alg == PSA_ALG_JPAKE ) + { + operation->input_step = 0; + operation->output_step = 0; + operation->password = MBEDTLS_SVC_KEY_ID_INIT; + operation->role = 0; + mbedtls_free( operation->buffer ); + operation->buffer = NULL; + operation->buffer_length = 0; + operation->buffer_offset = 0; + mbedtls_ecjpake_free( &operation->ctx.ecjpake ); + } #endif return( PSA_SUCCESS ); From ebd9a03743a204d537dcca0e4b93e2f337d9a2b8 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 17:24:56 +0200 Subject: [PATCH 14/55] Cleanup PSA pake test dependency Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.data | 24 ++++++++++----------- tests/suites/test_suite_psa_crypto.function | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 298a5af0ff..799ec04d37 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6447,49 +6447,49 @@ PSA derive persistent key: HKDF SHA-256, exportable persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_TYPE_RAW_DATA:1024:PSA_KEY_USAGE_EXPORT:0:DERIVE_KEY PSA PAKE: invalid alg -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_SHA_256:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_INVALID_ARGUMENT PSA PAKE: invalid primitive type -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_DH, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED PSA PAKE: invalid primitive family -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_K1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED PSA PAKE: invalid primitive bits -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 128):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED PSA PAKE: ecjpake setup server -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":0 PSA PAKE: ecjpake setup server empty password -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"":PSA_ERROR_BAD_STATE PSA PAKE: ecjpake setup server invalid step -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_ZK_PROOF:"abcd":PSA_ERROR_BAD_STATE PSA PAKE: ecjpake setup client -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:PSA_PAKE_STEP_KEY_SHARE:"abcd":0 PSA PAKE: ecjpake setup client empty password -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:PSA_PAKE_STEP_KEY_SHARE:"":PSA_ERROR_BAD_STATE PSA PAKE: ecjpake setup client invalid step -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:PSA_PAKE_STEP_ZK_PROOF:"abcd":PSA_ERROR_BAD_STATE PSA PAKE: ecjpake setup invalid role NONE -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_NONE:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED PSA PAKE: ecjpake rounds -depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef" diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 9b7bb20ec3..31aa98d9d1 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8092,7 +8092,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_ECJPAKE_C */ +/* BEGIN_CASE depends_on:PSA_WANT_ALG_ECJPAKE */ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, int output_step_arg, data_t *pw_data, int expected_status_arg ) @@ -8179,7 +8179,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_ECJPAKE_C */ +/* BEGIN_CASE depends_on:PSA_WANT_ALG_ECJPAKE */ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, int derive_alg_arg, data_t *pw_data ) { From 707d9574f80d840e3b7c47524485b22ac5167718 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 17:31:49 +0200 Subject: [PATCH 15/55] Add checks for psa_pake_set_user/psa_pake_set_peer in test_suite_psa_crypto Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.function | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 31aa98d9d1..caa5987405 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8158,6 +8158,18 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, PSA_ASSERT( status ); } + TEST_EQUAL( psa_pake_set_user( &operation, NULL, 0 ), + PSA_ERROR_INVALID_ARGUMENT ); + TEST_EQUAL( psa_pake_set_peer( &operation, NULL, 0 ), + PSA_ERROR_INVALID_ARGUMENT ); + + const uint8_t unsupported_id[] = "abcd"; + + TEST_EQUAL( psa_pake_set_user( &operation, unsupported_id, 4 ), + PSA_ERROR_NOT_SUPPORTED ); + TEST_EQUAL( psa_pake_set_peer( &operation, unsupported_id, 4 ), + PSA_ERROR_NOT_SUPPORTED ); + /* First round Output */ status = psa_pake_output( &operation, step, output_buffer, 512, &output_len ); From 645cccd6a836d5dcb0f523da3b4e6550260e44c8 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 17:36:23 +0200 Subject: [PATCH 16/55] Add checks for BAD_STATE before calling psa_pake_setup() in ecjpake_setup() test Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.function | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index caa5987405..e7746a45d6 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8128,6 +8128,23 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, psa_pake_cs_set_primitive( &cipher_suite, primitive_arg ); psa_pake_cs_set_hash( &cipher_suite, hash_alg ); + PSA_ASSERT( psa_pake_abort( &operation ) ); + + TEST_EQUAL( psa_pake_set_user( &operation, NULL, 0 ), + PSA_ERROR_BAD_STATE ); + TEST_EQUAL( psa_pake_set_peer( &operation, NULL, 0 ), + PSA_ERROR_BAD_STATE ); + TEST_EQUAL( psa_pake_set_password_key( &operation, key ), + PSA_ERROR_BAD_STATE ); + TEST_EQUAL( psa_pake_set_role( &operation, role ), + PSA_ERROR_BAD_STATE ); + TEST_EQUAL( psa_pake_output( &operation, step, NULL, 0, NULL ), + PSA_ERROR_BAD_STATE ); + TEST_EQUAL( psa_pake_input( &operation, step, NULL, 0), + PSA_ERROR_BAD_STATE ); + + PSA_ASSERT( psa_pake_abort( &operation ) ); + status = psa_pake_setup( &operation, &cipher_suite ); if( status != PSA_SUCCESS ) { From 0d001ef3da8461d8cf529371843287bd54bc9740 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 17:42:52 +0200 Subject: [PATCH 17/55] Check more parameters of psa_pake_output/psa_pake_input Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index b8a08a1a07..7f147b7cca 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -328,6 +328,9 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, step != PSA_PAKE_STEP_ZK_PROOF ) return( PSA_ERROR_INVALID_ARGUMENT ); + if( output == NULL || output_size == 0 || output_length == NULL ) + return( PSA_ERROR_INVALID_ARGUMENT ); + #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) if( operation->alg == PSA_ALG_JPAKE ) { @@ -508,6 +511,9 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, step != PSA_PAKE_STEP_ZK_PROOF ) return( PSA_ERROR_INVALID_ARGUMENT ); + if( input == NULL || input_length == 0 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) if( operation->alg == PSA_ALG_JPAKE ) { From 98506ab6771fffb4fb98036ae79e2dd702b26e14 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 17:43:20 +0200 Subject: [PATCH 18/55] Add checks for INVALID_ARGUMENT for psa_pake_output/psa_pake_input in ecjpake_setup() test Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.function | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index e7746a45d6..bb21b98ba7 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8198,6 +8198,9 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, else PSA_ASSERT( status ); + TEST_EQUAL( psa_pake_output( &operation, step, NULL, 0, NULL), + PSA_ERROR_INVALID_ARGUMENT ); + TEST_ASSERT( output_len > 0 ); exit: From 50de0ae0c4403037dfc4f0ecbef904d514205b3b Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 17:46:24 +0200 Subject: [PATCH 19/55] Add check calling psa_pake_setup() on an already initialized operation in ecjpake_setup() test Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.function | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index bb21b98ba7..66572670ad 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8154,6 +8154,9 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, else PSA_ASSERT( status ); + TEST_EQUAL( psa_pake_setup( &operation, &cipher_suite ), + PSA_ERROR_BAD_STATE ); + status = psa_pake_set_role( &operation, role ); if( status != PSA_SUCCESS ) { From 9c8b492052335899f6d1b86d61d5b558d79dabc6 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 17:59:07 +0200 Subject: [PATCH 20/55] Add advanced psa_pake_input/psa_pake_output test in ecjpake_setup() test Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.data | 34 ++++----- tests/suites/test_suite_psa_crypto.function | 81 +++++++++++++++++---- 2 files changed, 83 insertions(+), 32 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 799ec04d37..34c416326f 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6448,47 +6448,47 @@ persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b PSA PAKE: invalid alg depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_SHA_256:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_INVALID_ARGUMENT +ecjpake_setup:PSA_ALG_SHA_256:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_INVALID_ARGUMENT PSA PAKE: invalid primitive type depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_DH, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_DH, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED PSA PAKE: invalid primitive family depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_K1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_K1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED PSA PAKE: invalid primitive bits depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 128):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 128):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED -PSA PAKE: ecjpake setup server +PSA PAKE: ecjpake setup server output step first depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"abcd":0 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":0 + +PSA PAKE: ecjpake setup server input step first +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:1:"abcd":0 PSA PAKE: ecjpake setup server empty password depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_KEY_SHARE:"":PSA_ERROR_BAD_STATE +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"":PSA_ERROR_BAD_STATE -PSA PAKE: ecjpake setup server invalid step +PSA PAKE: ecjpake setup client output step first depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:PSA_PAKE_STEP_ZK_PROOF:"abcd":PSA_ERROR_BAD_STATE +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:0:"abcd":0 -PSA PAKE: ecjpake setup client +PSA PAKE: ecjpake setup client input step first depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:PSA_PAKE_STEP_KEY_SHARE:"abcd":0 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:1:"abcd":0 PSA PAKE: ecjpake setup client empty password depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:PSA_PAKE_STEP_KEY_SHARE:"":PSA_ERROR_BAD_STATE - -PSA PAKE: ecjpake setup client invalid step -depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:PSA_PAKE_STEP_ZK_PROOF:"abcd":PSA_ERROR_BAD_STATE +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:0:"":PSA_ERROR_BAD_STATE PSA PAKE: ecjpake setup invalid role NONE depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_NONE:PSA_PAKE_STEP_KEY_SHARE:"abcd":PSA_ERROR_NOT_SUPPORTED +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_NONE:0:"abcd":PSA_ERROR_NOT_SUPPORTED PSA PAKE: ecjpake rounds depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 66572670ad..e091ad405a 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8094,7 +8094,7 @@ exit: /* BEGIN_CASE depends_on:PSA_WANT_ALG_ECJPAKE */ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, - int output_step_arg, data_t *pw_data, + int input_first, data_t *pw_data, int expected_status_arg ) { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); @@ -8102,7 +8102,6 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, psa_algorithm_t alg = alg_arg; psa_algorithm_t hash_alg = hash_arg; psa_pake_role_t role = role_arg; - psa_pake_step_t step = output_step_arg; mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_status_t expected_status = expected_status_arg; @@ -8113,7 +8112,8 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, PSA_INIT( ); ASSERT_ALLOC( output_buffer, - PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg, step) ); + PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg, + PSA_PAKE_STEP_KEY_SHARE) ); if( pw_data->len > 0 ) { @@ -8138,9 +8138,10 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, PSA_ERROR_BAD_STATE ); TEST_EQUAL( psa_pake_set_role( &operation, role ), PSA_ERROR_BAD_STATE ); - TEST_EQUAL( psa_pake_output( &operation, step, NULL, 0, NULL ), + TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_KEY_SHARE, + NULL, 0, NULL ), PSA_ERROR_BAD_STATE ); - TEST_EQUAL( psa_pake_input( &operation, step, NULL, 0), + TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_KEY_SHARE, NULL, 0), PSA_ERROR_BAD_STATE ); PSA_ASSERT( psa_pake_abort( &operation ) ); @@ -8190,21 +8191,71 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, TEST_EQUAL( psa_pake_set_peer( &operation, unsupported_id, 4 ), PSA_ERROR_NOT_SUPPORTED ); - /* First round Output */ - status = psa_pake_output( &operation, step, output_buffer, - 512, &output_len ); - if( status != PSA_SUCCESS ) + /* First round */ + if( input_first ) { - TEST_EQUAL( status, expected_status ); - goto exit; + /* Invalid parameters */ + TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PROOF, + NULL, 0 ), + PSA_ERROR_INVALID_ARGUMENT ); + TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PROOF + 10, + output_buffer, 66 ), + PSA_ERROR_INVALID_ARGUMENT ); + /* Invalid first step */ + TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PROOF, + output_buffer, 66 ), + PSA_ERROR_BAD_STATE ); + + TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_KEY_SHARE, + output_buffer, 66 ), + expected_status); + + if( expected_status == PSA_SUCCESS ) + { + /* Buffer too large */ + TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PUBLIC, + output_buffer, 512 ), + PSA_ERROR_INSUFFICIENT_MEMORY ); + + /* The operation should be aborted at this point */ + TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PUBLIC, + output_buffer, 66 ), + PSA_ERROR_BAD_STATE ); + } } else - PSA_ASSERT( status ); + { + /* Invalid parameters */ + TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PROOF, + NULL, 0, NULL ), + PSA_ERROR_INVALID_ARGUMENT ); + TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PROOF + 10, + output_buffer, 512, &output_len ), + PSA_ERROR_INVALID_ARGUMENT ); + /* Invalid first step */ + TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PROOF, + output_buffer, 512, &output_len ), + PSA_ERROR_BAD_STATE ); - TEST_EQUAL( psa_pake_output( &operation, step, NULL, 0, NULL), - PSA_ERROR_INVALID_ARGUMENT ); + TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_KEY_SHARE, + output_buffer, 512, &output_len ), + expected_status ); - TEST_ASSERT( output_len > 0 ); + if( expected_status == PSA_SUCCESS ) + { + TEST_ASSERT( output_len > 0 ); + + /* Buffer too small */ + TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PUBLIC, + output_buffer, 5, &output_len ), + PSA_ERROR_BUFFER_TOO_SMALL ); + + /* The operation should be aborted at this point */ + TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_ZK_PUBLIC, + output_buffer, 512, &output_len ), + PSA_ERROR_BAD_STATE ); + } + } exit: PSA_ASSERT( psa_destroy_key( key ) ); From a24278a74a574154e4534c6597a45790bef67471 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 8 Jun 2022 18:10:26 +0200 Subject: [PATCH 21/55] Add invalid hash ecjpake_setup() test case Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.data | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 34c416326f..e571e517d8 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6462,6 +6462,10 @@ PSA PAKE: invalid primitive bits depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 128):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED +PSA PAKE: invalid hash +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_1:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED + PSA PAKE: ecjpake setup server output step first depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":0 From fbc4b4aa8e86fc3f2c584a1ad5157ccb90bb5d9f Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 10 Jun 2022 08:54:53 +0200 Subject: [PATCH 22/55] Fix psa_pake_abort() order to correctly free memory when alg is PSA_ALG_JPAKE Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 7f147b7cca..48995dd0d1 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -702,10 +702,6 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation) return( PSA_SUCCESS ); } - operation->alg = 0; - operation->state = 0; - operation->sequence = 0; - #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) if( operation->alg == PSA_ALG_JPAKE ) { @@ -721,6 +717,10 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation) } #endif + operation->alg = 0; + operation->state = 0; + operation->sequence = 0; + return( PSA_SUCCESS ); } From a557cb8c8bfeb6a327e6e15b5e812a4ab42b4333 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 10 Jun 2022 08:58:32 +0200 Subject: [PATCH 23/55] Fixing XXX_ALG_ECJPAKE to XXX_ALG_JPAKE to match specification Signed-off-by: Neil Armstrong --- include/mbedtls/config_psa.h | 10 +++++----- include/psa/crypto_config.h | 2 +- include/psa/crypto_extra.h | 4 ++-- library/psa_crypto_pake.c | 16 ++++++++-------- tests/suites/test_suite_psa_crypto.function | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h index 80b11951f0..7518e187f6 100644 --- a/include/mbedtls/config_psa.h +++ b/include/mbedtls/config_psa.h @@ -146,15 +146,15 @@ extern "C" { #define MBEDTLS_MD5_C #endif -#if defined(PSA_WANT_ALG_ECJPAKE) +#if defined(PSA_WANT_ALG_JPAKE) #define MBEDTLS_PSA_BUILTIN_PAKE 1 -#define MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE 1 +#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1 #define MBEDTLS_ECP_DP_SECP192R1_ENABLED #define MBEDTLS_BIGNUM_C #define MBEDTLS_ECP_C #define MBEDTLS_MD_C #define MBEDTLS_ECJPAKE_C -#endif /* PSA_WANT_ALG_ECJPAKE */ +#endif /* PSA_WANT_ALG_JPAKE */ #if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) #define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1 @@ -647,8 +647,8 @@ extern "C" { #if defined(MBEDTLS_ECJPAKE_C) #define MBEDTLS_PSA_BUILTIN_PAKE 1 -#define MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE 1 -#define PSA_WANT_ALG_ECJPAKE 1 +#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1 +#define PSA_WANT_ALG_JPAKE 1 #endif #if defined(MBEDTLS_RIPEMD160_C) diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h index 58fb3b1190..9011a5596a 100644 --- a/include/psa/crypto_config.h +++ b/include/psa/crypto_config.h @@ -65,7 +65,7 @@ #define PSA_WANT_ALG_ECB_NO_PADDING 1 #define PSA_WANT_ALG_ECDH 1 #define PSA_WANT_ALG_ECDSA 1 -#define PSA_WANT_ALG_ECJPAKE 1 +#define PSA_WANT_ALG_JPAKE 1 #define PSA_WANT_ALG_GCM 1 #define PSA_WANT_ALG_HKDF 1 #define PSA_WANT_ALG_HKDF_EXTRACT 1 diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 32bb358c24..e625f0d982 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -1903,7 +1903,7 @@ static inline void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite, cipher_suite->hash = hash; } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) #include #endif @@ -1923,7 +1923,7 @@ struct psa_pake_operation_s #endif union { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) mbedtls_ecjpake_context ecjpake; #endif /* Make the union non-empty even with no supported algorithms. */ diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 48995dd0d1..1aa8a72d89 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -33,7 +33,7 @@ #include #include -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) #define PSA_PAKE_BUFFER_SIZE ( ( 69 + 66 + 33 ) * 2 ) #endif @@ -130,7 +130,7 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation, return( PSA_ERROR_INVALID_ARGUMENT ); } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( cipher_suite->algorithm == PSA_ALG_JPAKE ) { if( cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC || @@ -248,7 +248,7 @@ psa_status_t psa_pake_set_role( psa_pake_operation_t *operation, return PSA_ERROR_INVALID_ARGUMENT; } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { if( role != PSA_PAKE_ROLE_CLIENT && @@ -264,7 +264,7 @@ psa_status_t psa_pake_set_role( psa_pake_operation_t *operation, return( PSA_ERROR_NOT_SUPPORTED ); } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -331,7 +331,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, if( output == NULL || output_size == 0 || output_length == NULL ) return( PSA_ERROR_INVALID_ARGUMENT ); -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { if( operation->state == PSA_PAKE_STATE_SETUP ) { @@ -514,7 +514,7 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, if( input == NULL || input_length == 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { if( operation->state == PSA_PAKE_STATE_SETUP ) { @@ -664,7 +664,7 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, operation->output_step != PSA_PAKE_STEP_DERIVE ) ) return( PSA_ERROR_BAD_STATE ); -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { ret = mbedtls_ecjpake_derive_secret( &operation->ctx.ecjpake, @@ -702,7 +702,7 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation) return( PSA_SUCCESS ); } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECJPAKE) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { operation->input_step = 0; diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index e091ad405a..727784f4ab 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8092,7 +8092,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:PSA_WANT_ALG_ECJPAKE */ +/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, int input_first, data_t *pw_data, int expected_status_arg ) @@ -8265,7 +8265,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:PSA_WANT_ALG_ECJPAKE */ +/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, int derive_alg_arg, data_t *pw_data ) { From 5fb07c6a968e6302f05208c161b1246c223ee651 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 10 Jun 2022 09:00:00 +0200 Subject: [PATCH 24/55] No need to check for state in psa_pake_setup() Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 1aa8a72d89..e7037ce2dc 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -118,7 +118,7 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation, const psa_pake_cipher_suite_t *cipher_suite) { /* A context must be freshly initialized before it can be set up. */ - if( operation->alg != 0 || operation->state != PSA_PAKE_STATE_INVALID ) + if( operation->alg != 0 ) return( PSA_ERROR_BAD_STATE ); if( cipher_suite == NULL || From e92311176a3961661de7b2a92c2f25ba340b5690 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 10 Jun 2022 09:03:41 +0200 Subject: [PATCH 25/55] Add missing parentheses on return statements Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index e7037ce2dc..f7fb384dd7 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -177,7 +177,7 @@ psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation, status = psa_get_key_attributes( password, &attributes ); if( status != PSA_SUCCESS ) - return status; + return( status ); type = psa_get_key_type( &attributes ); usage = psa_get_key_usage_flags( &attributes ); @@ -187,11 +187,11 @@ psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation, if( type != PSA_KEY_TYPE_PASSWORD && type != PSA_KEY_TYPE_PASSWORD_HASH ) { - return PSA_ERROR_INVALID_ARGUMENT; + return( PSA_ERROR_INVALID_ARGUMENT ); } if( ( usage & PSA_KEY_USAGE_DERIVE ) == 0 ) - return PSA_ERROR_NOT_PERMITTED; + return( PSA_ERROR_NOT_PERMITTED ); operation->password = password; @@ -209,7 +209,7 @@ psa_status_t psa_pake_set_user( psa_pake_operation_t *operation, } if( user_id_len == 0 || user_id == NULL ) - return PSA_ERROR_INVALID_ARGUMENT; + return( PSA_ERROR_INVALID_ARGUMENT ); return( PSA_ERROR_NOT_SUPPORTED ); } @@ -225,7 +225,7 @@ psa_status_t psa_pake_set_peer( psa_pake_operation_t *operation, } if( peer_id_len == 0 || peer_id == NULL ) - return PSA_ERROR_INVALID_ARGUMENT; + return( PSA_ERROR_INVALID_ARGUMENT ); return( PSA_ERROR_NOT_SUPPORTED ); } @@ -245,7 +245,7 @@ psa_status_t psa_pake_set_role( psa_pake_operation_t *operation, role != PSA_PAKE_ROLE_CLIENT && role != PSA_PAKE_ROLE_SERVER ) { - return PSA_ERROR_INVALID_ARGUMENT; + return( PSA_ERROR_INVALID_ARGUMENT ); } #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) @@ -253,7 +253,7 @@ psa_status_t psa_pake_set_role( psa_pake_operation_t *operation, { if( role != PSA_PAKE_ROLE_CLIENT && role != PSA_PAKE_ROLE_SERVER ) - return PSA_ERROR_NOT_SUPPORTED; + return( PSA_ERROR_NOT_SUPPORTED ); operation->role = role; From bb28c5679698d6e80003d78065ee005b2d9d72ba Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 10 Jun 2022 09:29:06 +0200 Subject: [PATCH 26/55] Add changelog entry for new PSA PAKE feature Signed-off-by: Neil Armstrong --- ChangeLog.d/psa_crypto_pake.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 ChangeLog.d/psa_crypto_pake.txt diff --git a/ChangeLog.d/psa_crypto_pake.txt b/ChangeLog.d/psa_crypto_pake.txt new file mode 100644 index 0000000000..27e3b5c34f --- /dev/null +++ b/ChangeLog.d/psa_crypto_pake.txt @@ -0,0 +1,2 @@ +Features + * Expose the EC J-PAKE functionality through the PSA PAKE Crypto API. From 19bb9913c20d9ecb125805cccb3b77141355f1cb Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 13 Jun 2022 18:43:32 +0200 Subject: [PATCH 27/55] Update changelog entry for new PSA PAKE feature Signed-off-by: Neil Armstrong --- ChangeLog.d/psa_crypto_pake.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog.d/psa_crypto_pake.txt b/ChangeLog.d/psa_crypto_pake.txt index 27e3b5c34f..e0ae046387 100644 --- a/ChangeLog.d/psa_crypto_pake.txt +++ b/ChangeLog.d/psa_crypto_pake.txt @@ -1,2 +1,4 @@ Features - * Expose the EC J-PAKE functionality through the PSA PAKE Crypto API. + * Expose the EC J-PAKE functionality through the Draft PSA PAKE Crypto API. + Only the ECC primitive with secp256r1 curve and SHA-256 hash algorithm + are supported in this implementation. From ed40782628e818f21e6e13d4b0cddfd8ed72a22b Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2022 11:21:33 +0200 Subject: [PATCH 28/55] Fix SECP256R1 enable when PSA_WANT_ALG_JPAKE is defined Signed-off-by: Neil Armstrong --- include/mbedtls/config_psa.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h index 7518e187f6..96083d8102 100644 --- a/include/mbedtls/config_psa.h +++ b/include/mbedtls/config_psa.h @@ -149,7 +149,7 @@ extern "C" { #if defined(PSA_WANT_ALG_JPAKE) #define MBEDTLS_PSA_BUILTIN_PAKE 1 #define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1 -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED #define MBEDTLS_BIGNUM_C #define MBEDTLS_ECP_C #define MBEDTLS_MD_C From 1e855601ca2372070ad41b861a0586bc00d8cf8a Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2022 11:32:11 +0200 Subject: [PATCH 29/55] Fix psa_pake_get_implicit_key() state & add corresponding tests in ecjpake_rounds() Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 4 +- tests/suites/test_suite_psa_crypto.function | 54 +++++++++++++++------ 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index f7fb384dd7..8ceacd952f 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -660,8 +660,8 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, if( operation->alg == 0 || operation->state != PSA_PAKE_STATE_READY || - ( operation->input_step != PSA_PAKE_STEP_DERIVE && - operation->output_step != PSA_PAKE_STEP_DERIVE ) ) + operation->input_step != PSA_PAKE_STEP_DERIVE || + operation->output_step != PSA_PAKE_STEP_DERIVE ) return( PSA_ERROR_BAD_STATE ); #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 727784f4ab..6d4f2a8a01 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8316,6 +8316,21 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, psa_pake_cs_set_primitive( &cipher_suite, primitive_arg ); psa_pake_cs_set_hash( &cipher_suite, hash_alg ); + /* Get shared key */ + PSA_ASSERT( psa_key_derivation_setup( &server_derive, derive_alg ) ); + PSA_ASSERT( psa_key_derivation_setup( &client_derive, derive_alg ) ); + + if( PSA_ALG_IS_TLS12_PRF( derive_alg ) || + PSA_ALG_IS_TLS12_PSK_TO_MS( derive_alg ) ) + { + PSA_ASSERT( psa_key_derivation_input_bytes( &server_derive, + PSA_KEY_DERIVATION_INPUT_SEED, + (const uint8_t*) "", 0) ); + PSA_ASSERT( psa_key_derivation_input_bytes( &client_derive, + PSA_KEY_DERIVATION_INPUT_SEED, + (const uint8_t*) "", 0) ); + } + PSA_ASSERT( psa_pake_setup( &server, &cipher_suite ) ); PSA_ASSERT( psa_pake_setup( &client, &cipher_suite ) ); @@ -8325,6 +8340,11 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, PSA_ASSERT( psa_pake_set_password_key( &server, key ) ); PSA_ASSERT( psa_pake_set_password_key( &client, key ) ); + TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), + PSA_ERROR_BAD_STATE ); + TEST_EQUAL( psa_pake_get_implicit_key( &client, &client_derive ), + PSA_ERROR_BAD_STATE ); + /* Server first round Output */ PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_KEY_SHARE, buffer0 + buffer0_off, @@ -8389,6 +8409,11 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, c_x2_pr_off = buffer1_off; buffer1_off += c_x2_pr_len; + TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), + PSA_ERROR_BAD_STATE ); + TEST_EQUAL( psa_pake_get_implicit_key( &client, &client_derive ), + PSA_ERROR_BAD_STATE ); + /* Client first round Input */ PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_KEY_SHARE, buffer0 + s_g1_off, s_g1_len ) ); @@ -8417,6 +8442,11 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PROOF, buffer1 + c_x2_pr_off, c_x2_pr_len ) ); + TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), + PSA_ERROR_BAD_STATE ); + TEST_EQUAL( psa_pake_get_implicit_key( &client, &client_derive ), + PSA_ERROR_BAD_STATE ); + /* Server second round Output */ buffer0_off = 0; @@ -8455,6 +8485,11 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, c_x2s_pr_off = buffer1_off; buffer1_off += c_x2s_pr_len; + TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), + PSA_ERROR_BAD_STATE ); + TEST_EQUAL( psa_pake_get_implicit_key( &client, &client_derive ), + PSA_ERROR_BAD_STATE ); + /* Client second round Input */ PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_KEY_SHARE, buffer0 + s_a_off, s_a_len ) ); @@ -8463,6 +8498,9 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PROOF, buffer0 + s_x2s_pr_off, s_x2s_pr_len ) ); + TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), + PSA_ERROR_BAD_STATE ); + /* Server second round Input */ PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_KEY_SHARE, buffer1 + c_a_off, c_a_len ) ); @@ -8471,22 +8509,6 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PROOF, buffer1 + c_x2s_pr_off, c_x2s_pr_len ) ); - - /* Get shared key */ - PSA_ASSERT( psa_key_derivation_setup( &server_derive, derive_alg ) ); - PSA_ASSERT( psa_key_derivation_setup( &client_derive, derive_alg ) ); - - if( PSA_ALG_IS_TLS12_PRF( derive_alg ) || - PSA_ALG_IS_TLS12_PSK_TO_MS( derive_alg ) ) - { - PSA_ASSERT( psa_key_derivation_input_bytes( &server_derive, - PSA_KEY_DERIVATION_INPUT_SEED, - (const uint8_t*) "", 0) ); - PSA_ASSERT( psa_key_derivation_input_bytes( &client_derive, - PSA_KEY_DERIVATION_INPUT_SEED, - (const uint8_t*) "", 0) ); - } - PSA_ASSERT( psa_pake_get_implicit_key( &server, &server_derive ) ); PSA_ASSERT( psa_pake_get_implicit_key( &client, &client_derive ) ); From db05cbfb862a4a213a49272c3952f2a1c5c088b5 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2022 15:25:45 +0200 Subject: [PATCH 30/55] Introduce and use mbedtls_ecjpake_to_psa_error() to translate various ECP/MPI errors to expected PSA errors Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 8ceacd952f..556acd99b7 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -113,6 +113,29 @@ enum psa_pake_sequence PSA_PAKE_SEQ_END = 7, }; +#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) +static psa_status_t mbedtls_ecjpake_to_psa_error( int ret ) +{ + switch( ret ) + { + case MBEDTLS_ERR_MPI_BAD_INPUT_DATA: + case MBEDTLS_ERR_ECP_BAD_INPUT_DATA: + case MBEDTLS_ERR_ECP_INVALID_KEY: + case MBEDTLS_ERR_ECP_VERIFY_FAILED: + return( PSA_ERROR_DATA_INVALID ); + case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL: + case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL: + return( PSA_ERROR_BUFFER_TOO_SMALL ); + case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE: + return( PSA_ERROR_NOT_SUPPORTED ); + case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED: + return( PSA_ERROR_CORRUPTION_DETECTED ); + default: + return( PSA_ERROR_GENERIC_ERROR ); + } +} +#endif + #if defined(MBEDTLS_PSA_BUILTIN_PAKE) psa_status_t psa_pake_setup( psa_pake_operation_t *operation, const psa_pake_cipher_suite_t *cipher_suite) @@ -297,7 +320,7 @@ static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation ) slot = NULL; if( ret != 0 ) - return( mbedtls_to_psa_error( ret ) ); + return( mbedtls_ecjpake_to_psa_error( ret ) ); operation->buffer = mbedtls_calloc( 1, PSA_PAKE_BUFFER_SIZE ); if( operation->buffer == NULL ) @@ -415,7 +438,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, if( ret != 0 ) { psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); + return( mbedtls_ecjpake_to_psa_error( ret ) ); } operation->buffer_offset = 0; @@ -432,7 +455,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, if( ret != 0 ) { psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); + return( mbedtls_ecjpake_to_psa_error( ret ) ); } operation->buffer_offset = 0; @@ -613,7 +636,7 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, if( ret != 0 ) { psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); + return( mbedtls_ecjpake_to_psa_error( ret ) ); } } else if( operation->state == PSA_PAKE_INPUT_X4S && @@ -629,7 +652,7 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, if( ret != 0 ) { psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); + return( mbedtls_ecjpake_to_psa_error( ret ) ); } } @@ -676,7 +699,7 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, if( ret != 0) { psa_pake_abort( operation ); - return( mbedtls_to_psa_error( ret ) ); + return( mbedtls_ecjpake_to_psa_error( ret ) ); } status = psa_key_derivation_input_bytes( output, From f983caf6c43d64bb6b0753b797138a666d59e6d3 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2022 15:27:48 +0200 Subject: [PATCH 31/55] Move JPAKE rounds into a common function, add reordering and error injection Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.data | 6 +- tests/suites/test_suite_psa_crypto.function | 480 ++++++++++++-------- 2 files changed, 303 insertions(+), 183 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index e571e517d8..fef475abc4 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6496,4 +6496,8 @@ ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ PSA PAKE: ecjpake rounds depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef" +ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":0 + +PSA PAKE: ecjpake rounds, client input first +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":1 diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 6d4f2a8a01..cf7ea7d382 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -705,6 +705,296 @@ exit: return( test_ok ); } +static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, + psa_pake_operation_t *server, + psa_pake_operation_t *client, + int client_input_first, + int round, int inject_error ) +{ + unsigned char *buffer0 = NULL, *buffer1 = NULL; + size_t buffer_length = ( + PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_KEY_SHARE) + + PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PUBLIC) + + PSA_PAKE_OUTPUT_SIZE(alg, primitive, PSA_PAKE_STEP_ZK_PROOF)) * 2; + size_t buffer0_off = 0; + size_t buffer1_off = 0; + size_t s_g1_len, s_g2_len, s_a_len; + size_t s_g1_off, s_g2_off, s_a_off; + size_t s_x1_pk_len, s_x2_pk_len, s_x2s_pk_len; + size_t s_x1_pk_off, s_x2_pk_off, s_x2s_pk_off; + size_t s_x1_pr_len, s_x2_pr_len, s_x2s_pr_len; + size_t s_x1_pr_off, s_x2_pr_off, s_x2s_pr_off; + size_t c_g1_len, c_g2_len, c_a_len; + size_t c_g1_off, c_g2_off, c_a_off; + size_t c_x1_pk_len, c_x2_pk_len, c_x2s_pk_len; + size_t c_x1_pk_off, c_x2_pk_off, c_x2s_pk_off; + size_t c_x1_pr_len, c_x2_pr_len, c_x2s_pr_len; + size_t c_x1_pr_off, c_x2_pr_off, c_x2s_pr_off; + psa_status_t expected_status = PSA_SUCCESS; + int ret; + + ASSERT_ALLOC( buffer0, buffer_length ); + ASSERT_ALLOC( buffer1, buffer_length ); + + switch( round ) + { + case 1: + /* Server first round Output */ + PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_g1_len ) ); + s_g1_off = buffer0_off; + buffer0_off += s_g1_len; + PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x1_pk_len ) ); + s_x1_pk_off = buffer0_off; + buffer0_off += s_x1_pk_len; + PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x1_pr_len ) ); + s_x1_pr_off = buffer0_off; + buffer0_off += s_x1_pr_len; + PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_g2_len ) ); + s_g2_off = buffer0_off; + buffer0_off += s_g2_len; + PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x2_pk_len ) ); + s_x2_pk_off = buffer0_off; + buffer0_off += s_x2_pk_len; + PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x2_pr_len ) ); + s_x2_pr_off = buffer0_off; + buffer0_off += s_x2_pr_len; + + if( inject_error == 1 ) + { + buffer0[s_x1_pk_off + 12] >>= 4; + buffer0[s_x2_pk_off + 7] <<= 4; + expected_status = PSA_ERROR_DATA_INVALID; + } + + if( client_input_first == 1 ) + { + /* Client first round Input */ + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g1_off, s_g1_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x1_pk_off, + s_x1_pk_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x1_pr_off, + s_x1_pr_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g2_off, + s_g2_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2_pk_off, + s_x2_pk_len ) ); + TEST_EQUAL( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2_pr_off, + s_x2_pr_len ), + expected_status ); + + if( inject_error == 1 ) + { + ret = 1; + goto exit; + } + } + + /* Client first round Output */ + PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_g1_len ) ); + c_g1_off = buffer1_off; + buffer1_off += c_g1_len; + PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x1_pk_len ) ); + c_x1_pk_off = buffer1_off; + buffer1_off += c_x1_pk_len; + PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x1_pr_len ) ); + c_x1_pr_off = buffer1_off; + buffer1_off += c_x1_pr_len; + PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_g2_len ) ); + c_g2_off = buffer1_off; + buffer1_off += c_g2_len; + PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x2_pk_len ) ); + c_x2_pk_off = buffer1_off; + buffer1_off += c_x2_pk_len; + PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x2_pr_len ) ); + c_x2_pr_off = buffer1_off; + buffer1_off += c_x2_pr_len; + + if( client_input_first == 0 ) + { + /* Client first round Input */ + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g1_off, s_g1_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x1_pk_off, + s_x1_pk_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x1_pr_off, + s_x1_pr_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g2_off, + s_g2_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2_pk_off, + s_x2_pk_len ) ); + TEST_EQUAL( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2_pr_off, + s_x2_pr_len ), + expected_status ); + + if( inject_error == 1 ) + break; + } + + if( inject_error == 2 ) + { + buffer1[c_x1_pk_off + 12] >>= 4; + buffer1[c_x2_pk_off + 7] <<= 4; + expected_status = PSA_ERROR_DATA_INVALID; + } + + /* Server first round Input */ + PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_g1_off, c_g1_len ) ); + PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + c_x1_pk_off, c_x1_pk_len ) ); + PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + c_x1_pr_off, c_x1_pr_len ) ); + PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_g2_off, c_g2_len ) ); + PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + c_x2_pk_off, c_x2_pk_len ) ); + TEST_EQUAL( psa_pake_input( server, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + c_x2_pr_off, c_x2_pr_len ), + expected_status ); + + break; + + case 2: + /* Server second round Output */ + buffer0_off = 0; + + PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_a_len ) ); + s_a_off = buffer0_off; + buffer0_off += s_a_len; + PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x2s_pk_len ) ); + s_x2s_pk_off = buffer0_off; + buffer0_off += s_x2s_pk_len; + PSA_ASSERT( psa_pake_output( server, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + buffer0_off, + 512 - buffer0_off, &s_x2s_pr_len ) ); + s_x2s_pr_off = buffer0_off; + buffer0_off += s_x2s_pr_len; + + if( inject_error == 3 ) + { + buffer0[s_x2s_pk_off + 12] >>= 4; + expected_status = PSA_ERROR_DATA_INVALID; + } + + if( client_input_first == 1 ) + { + /* Client second round Input */ + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_a_off, s_a_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2s_pk_off, + s_x2s_pk_len ) ); + TEST_EQUAL( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2s_pr_off, + s_x2s_pr_len ), + expected_status ); + + if( inject_error == 3 ) + break; + } + + /* Client second round Output */ + buffer1_off = 0; + + PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_a_len ) ); + c_a_off = buffer1_off; + buffer1_off += c_a_len; + PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x2s_pk_len ) ); + c_x2s_pk_off = buffer1_off; + buffer1_off += c_x2s_pk_len; + PSA_ASSERT( psa_pake_output( client, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + buffer1_off, + 512 - buffer1_off, &c_x2s_pr_len ) ); + c_x2s_pr_off = buffer1_off; + buffer1_off += c_x2s_pr_len; + + if( client_input_first == 0 ) + { + /* Client second round Input */ + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_a_off, s_a_len ) ); + PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2s_pk_off, + s_x2s_pk_len ) ); + TEST_EQUAL( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2s_pr_off, + s_x2s_pr_len ), + expected_status ); + + if( inject_error == 3 ) + break; + } + + if( inject_error == 4 ) + { + buffer1[c_x2s_pk_off + 12] >>= 4; + expected_status = PSA_ERROR_DATA_INVALID; + } + + /* Server second round Input */ + PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_a_off, c_a_len ) ); + PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + c_x2s_pk_off, c_x2s_pk_len ) ); + TEST_EQUAL( psa_pake_input( server, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + c_x2s_pr_off, c_x2s_pr_len ), + expected_status ); + + break; + + } + + ret = 1; + +exit: + mbedtls_free( buffer0 ); + mbedtls_free( buffer1 ); + return( ret ); +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -8267,7 +8557,8 @@ exit: /* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, - int derive_alg_arg, data_t *pw_data ) + int derive_alg_arg, data_t *pw_data, + int client_input_first ) { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); psa_pake_operation_t server = psa_pake_operation_init(); @@ -8281,31 +8572,9 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, PSA_KEY_DERIVATION_OPERATION_INIT; psa_key_derivation_operation_t client_derive = PSA_KEY_DERIVATION_OPERATION_INIT; - unsigned char *buffer0 = NULL, *buffer1 = NULL; - size_t buffer_length = ( - PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg, PSA_PAKE_STEP_KEY_SHARE) + - PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg, PSA_PAKE_STEP_ZK_PUBLIC) + - PSA_PAKE_OUTPUT_SIZE(alg, primitive_arg, PSA_PAKE_STEP_ZK_PROOF)) * 2; - size_t buffer0_off = 0; - size_t buffer1_off = 0; - size_t s_g1_len, s_g2_len, s_a_len; - size_t s_g1_off, s_g2_off, s_a_off; - size_t s_x1_pk_len, s_x2_pk_len, s_x2s_pk_len; - size_t s_x1_pk_off, s_x2_pk_off, s_x2s_pk_off; - size_t s_x1_pr_len, s_x2_pr_len, s_x2s_pr_len; - size_t s_x1_pr_off, s_x2_pr_off, s_x2s_pr_off; - size_t c_g1_len, c_g2_len, c_a_len; - size_t c_g1_off, c_g2_off, c_a_off; - size_t c_x1_pk_len, c_x2_pk_len, c_x2s_pk_len; - size_t c_x1_pk_off, c_x2_pk_off, c_x2s_pk_off; - size_t c_x1_pr_len, c_x2_pr_len, c_x2s_pr_len; - size_t c_x1_pr_off, c_x2_pr_off, c_x2s_pr_off; PSA_INIT( ); - ASSERT_ALLOC( buffer0, buffer_length ); - ASSERT_ALLOC( buffer1, buffer_length ); - psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); psa_set_key_algorithm( &attributes, alg ); psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); @@ -8345,169 +8614,18 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, TEST_EQUAL( psa_pake_get_implicit_key( &client, &client_derive ), PSA_ERROR_BAD_STATE ); - /* Server first round Output */ - PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + buffer0_off, - 512 - buffer0_off, &s_g1_len ) ); - s_g1_off = buffer0_off; - buffer0_off += s_g1_len; - PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + buffer0_off, - 512 - buffer0_off, &s_x1_pk_len ) ); - s_x1_pk_off = buffer0_off; - buffer0_off += s_x1_pk_len; - PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + buffer0_off, - 512 - buffer0_off, &s_x1_pr_len ) ); - s_x1_pr_off = buffer0_off; - buffer0_off += s_x1_pr_len; - PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + buffer0_off, - 512 - buffer0_off, &s_g2_len ) ); - s_g2_off = buffer0_off; - buffer0_off += s_g2_len; - PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + buffer0_off, - 512 - buffer0_off, &s_x2_pk_len ) ); - s_x2_pk_off = buffer0_off; - buffer0_off += s_x2_pk_len; - PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + buffer0_off, - 512 - buffer0_off, &s_x2_pr_len ) ); - s_x2_pr_off = buffer0_off; - buffer0_off += s_x2_pr_len; - - /* Client first round Output */ - PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_KEY_SHARE, - buffer1 + buffer1_off, - 512 - buffer1_off, &c_g1_len ) ); - c_g1_off = buffer1_off; - buffer1_off += c_g1_len; - PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer1 + buffer1_off, - 512 - buffer1_off, &c_x1_pk_len ) ); - c_x1_pk_off = buffer1_off; - buffer1_off += c_x1_pk_len; - PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PROOF, - buffer1 + buffer1_off, - 512 - buffer1_off, &c_x1_pr_len ) ); - c_x1_pr_off = buffer1_off; - buffer1_off += c_x1_pr_len; - PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_KEY_SHARE, - buffer1 + buffer1_off, - 512 - buffer1_off, &c_g2_len ) ); - c_g2_off = buffer1_off; - buffer1_off += c_g2_len; - PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer1 + buffer1_off, - 512 - buffer1_off, &c_x2_pk_len ) ); - c_x2_pk_off = buffer1_off; - buffer1_off += c_x2_pk_len; - PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PROOF, - buffer1 + buffer1_off, - 512 - buffer1_off, &c_x2_pr_len ) ); - c_x2_pr_off = buffer1_off; - buffer1_off += c_x2_pr_len; + /* First round */ + TEST_EQUAL( ecjpake_do_round( alg, primitive_arg, &server, &client, + client_input_first, 1, 0 ), 1 ); TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), PSA_ERROR_BAD_STATE ); TEST_EQUAL( psa_pake_get_implicit_key( &client, &client_derive ), PSA_ERROR_BAD_STATE ); - /* Client first round Input */ - PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + s_g1_off, s_g1_len ) ); - PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + s_x1_pk_off, s_x1_pk_len ) ); - PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + s_x1_pr_off, s_x1_pr_len ) ); - PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + s_g2_off, s_g2_len ) ); - PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + s_x2_pk_off, s_x2_pk_len ) ); - PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + s_x2_pr_off, s_x2_pr_len ) ); - - /* Server first round Input */ - PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_KEY_SHARE, - buffer1 + c_g1_off, c_g1_len ) ); - PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PUBLIC, - buffer1 + c_x1_pk_off, c_x1_pk_len ) ); - PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PROOF, - buffer1 + c_x1_pr_off, c_x1_pr_len ) ); - PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_KEY_SHARE, - buffer1 + c_g2_off, c_g2_len ) ); - PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PUBLIC, - buffer1 + c_x2_pk_off, c_x2_pk_len ) ); - PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PROOF, - buffer1 + c_x2_pr_off, c_x2_pr_len ) ); - - TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), - PSA_ERROR_BAD_STATE ); - TEST_EQUAL( psa_pake_get_implicit_key( &client, &client_derive ), - PSA_ERROR_BAD_STATE ); - - /* Server second round Output */ - buffer0_off = 0; - - PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + buffer0_off, - 512 - buffer0_off, &s_a_len ) ); - s_a_off = buffer0_off; - buffer0_off += s_a_len; - PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + buffer0_off, - 512 - buffer0_off, &s_x2s_pk_len ) ); - s_x2s_pk_off = buffer0_off; - buffer0_off += s_x2s_pk_len; - PSA_ASSERT( psa_pake_output( &server, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + buffer0_off, - 512 - buffer0_off, &s_x2s_pr_len ) ); - s_x2s_pr_off = buffer0_off; - buffer0_off += s_x2s_pr_len; - - /* Client second round Output */ - buffer1_off = 0; - - PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_KEY_SHARE, - buffer1 + buffer1_off, - 512 - buffer1_off, &c_a_len ) ); - c_a_off = buffer1_off; - buffer1_off += c_a_len; - PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer1 + buffer1_off, - 512 - buffer1_off, &c_x2s_pk_len ) ); - c_x2s_pk_off = buffer1_off; - buffer1_off += c_x2s_pk_len; - PSA_ASSERT( psa_pake_output( &client, PSA_PAKE_STEP_ZK_PROOF, - buffer1 + buffer1_off, - 512 - buffer1_off, &c_x2s_pr_len ) ); - c_x2s_pr_off = buffer1_off; - buffer1_off += c_x2s_pr_len; - - TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), - PSA_ERROR_BAD_STATE ); - TEST_EQUAL( psa_pake_get_implicit_key( &client, &client_derive ), - PSA_ERROR_BAD_STATE ); - - /* Client second round Input */ - PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + s_a_off, s_a_len ) ); - PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + s_x2s_pk_off, s_x2s_pk_len ) ); - PSA_ASSERT( psa_pake_input( &client, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + s_x2s_pr_off, s_x2s_pr_len ) ); - - TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), - PSA_ERROR_BAD_STATE ); - - /* Server second round Input */ - PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_KEY_SHARE, - buffer1 + c_a_off, c_a_len ) ); - PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PUBLIC, - buffer1 + c_x2s_pk_off, c_x2s_pk_len ) ); - PSA_ASSERT( psa_pake_input( &server, PSA_PAKE_STEP_ZK_PROOF, - buffer1 + c_x2s_pr_off, c_x2s_pr_len ) ); + /* Second round */ + TEST_EQUAL( ecjpake_do_round( alg, primitive_arg, &server, &client, + client_input_first, 2, 0 ), 1 ); PSA_ASSERT( psa_pake_get_implicit_key( &server, &server_derive ) ); PSA_ASSERT( psa_pake_get_implicit_key( &client, &client_derive ) ); @@ -8518,8 +8636,6 @@ exit: psa_destroy_key( key ); psa_pake_abort( &server ); psa_pake_abort( &client ); - mbedtls_free( buffer0 ); - mbedtls_free( buffer1 ); PSA_DONE( ); } /* END_CASE */ From 8c2e8a6cda40480b6ef66b0ca3b27e3b3c15e375 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2022 15:28:32 +0200 Subject: [PATCH 32/55] Add ecjpake_rounds_inject tests to exercise error injection Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.data | 40 +++++++++++++++ tests/suites/test_suite_psa_crypto.function | 54 +++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index fef475abc4..2e876ff24b 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6501,3 +6501,43 @@ ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA PSA PAKE: ecjpake rounds, client input first depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":1 + +PSA PAKE: ecjpake no input errors +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:0:"abcdef" + +PSA PAKE: ecjpake no input errors, client input first +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:0:"abcdef" + +PSA PAKE: ecjpake inject input errors, first round client +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:1:"abcdef" + +PSA PAKE: ecjpake inject input errors, first round client, client input first +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:1:"abcdef" + +PSA PAKE: ecjpake inject input errors, first round server +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:2:"abcdef" + +PSA PAKE: ecjpake inject input errors, first round server, client input first +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:2:"abcdef" + +PSA PAKE: ecjpake inject input errors, second round client +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:3:"abcdef" + +PSA PAKE: ecjpake inject input errors, second round client, client input first +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:3:"abcdef" + +PSA PAKE: ecjpake inject input errors, second round server +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:0:4:"abcdef" + +PSA PAKE: ecjpake inject input errors, second round server, client input first +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_rounds_inject:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:1:4:"abcdef" diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index cf7ea7d382..67b0dd2ada 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8555,6 +8555,60 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ +void ecjpake_rounds_inject( int alg_arg, int primitive_arg, int hash_arg, + int client_input_first, int inject_error, + data_t *pw_data ) +{ + psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); + psa_pake_operation_t server = psa_pake_operation_init(); + psa_pake_operation_t client = psa_pake_operation_init(); + psa_algorithm_t alg = alg_arg; + psa_algorithm_t hash_alg = hash_arg; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + PSA_INIT( ); + + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); + psa_set_key_algorithm( &attributes, alg ); + psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); + PSA_ASSERT( psa_import_key( &attributes, pw_data->x, pw_data->len, + &key ) ); + + psa_pake_cs_set_algorithm( &cipher_suite, alg ); + psa_pake_cs_set_primitive( &cipher_suite, primitive_arg ); + psa_pake_cs_set_hash( &cipher_suite, hash_alg ); + + + PSA_ASSERT( psa_pake_setup( &server, &cipher_suite ) ); + PSA_ASSERT( psa_pake_setup( &client, &cipher_suite ) ); + + PSA_ASSERT( psa_pake_set_role( &server, PSA_PAKE_ROLE_SERVER ) ); + PSA_ASSERT( psa_pake_set_role( &client, PSA_PAKE_ROLE_CLIENT ) ); + + PSA_ASSERT( psa_pake_set_password_key( &server, key ) ); + PSA_ASSERT( psa_pake_set_password_key( &client, key ) ); + + TEST_EQUAL( ecjpake_do_round( alg, primitive_arg, &server, &client, + client_input_first, 1, + inject_error ), 1 ); + + if( inject_error == 1 || inject_error == 2 ) + goto exit; + + TEST_EQUAL( ecjpake_do_round( alg, primitive_arg, &server, &client, + client_input_first, 2, + inject_error ), 1 ); + +exit: + psa_destroy_key( key ); + psa_pake_abort( &server ); + psa_pake_abort( &client ); + PSA_DONE( ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, int derive_alg_arg, data_t *pw_data, From 75673abef52e5f8d692dd7ec7b27d266bcdad313 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2022 17:39:01 +0200 Subject: [PATCH 33/55] Only build ecjpake_do_round() is PSA_WANT_ALG_JPAKE is defined Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.function | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 67b0dd2ada..29a007792f 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -705,6 +705,7 @@ exit: return( test_ok ); } +#if defined(PSA_WANT_ALG_JPAKE) static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, psa_pake_operation_t *server, psa_pake_operation_t *client, @@ -994,6 +995,7 @@ exit: mbedtls_free( buffer1 ); return( ret ); } +#endif /* PSA_WANT_ALG_JPAKE */ /* END_HEADER */ From 12663092bc042d1c59ae0d4879167c47a9b2fc4f Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2022 16:00:00 +0200 Subject: [PATCH 34/55] Introduce mbedtls_ecjpake_write_shared_key() to export the EC J-PAKE shared key material before the KDF() Signed-off-by: Neil Armstrong --- include/mbedtls/ecjpake.h | 23 ++++++++++ library/ecjpake.c | 97 ++++++++++++++++++++++++++++++++------- 2 files changed, 104 insertions(+), 16 deletions(-) diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h index ffdea05bcf..5b57455576 100644 --- a/include/mbedtls/ecjpake.h +++ b/include/mbedtls/ecjpake.h @@ -258,6 +258,29 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +/** + * \brief Write the shared key material to be passed to a Key + * Derivation Function as described in RFC8236. + * + * \param ctx The ECJPAKE context to use. This must be initialized, + * set up and have performed both round one and two. + * \param buf The buffer to write the derived secret to. This must + * be a writable buffer of length \p len Bytes. + * \param len The length of \p buf in Bytes. + * \param olen The address at which to store the total number of Bytes + * written to \p buf. This must not be \c NULL. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. This + * may be \c NULL if \p f_rng doesn't use a context. + * + * \return \c 0 if successful. + * \return A negative error code on failure. + */ +int mbedtls_ecjpake_write_shared_key( mbedtls_ecjpake_context *ctx, + unsigned char *buf, size_t len, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + /** * \brief This clears an ECJPAKE context and frees any * embedded data structure. diff --git a/library/ecjpake.c b/library/ecjpake.c index 7447354bc5..17d04387d4 100644 --- a/library/ecjpake.c +++ b/library/ecjpake.c @@ -760,22 +760,14 @@ cleanup: /* * Derive PMS (7.4.2.7 / 7.4.2.8) */ -int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) +static int mbedtls_ecjpake_derive_k( mbedtls_ecjpake_context *ctx, + mbedtls_ecp_point *K, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point K; mbedtls_mpi m_xm2_s, one; - unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; - size_t x_bytes; - *olen = mbedtls_hash_info_get_size( ctx->md_type ); - if( len < *olen ) - return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); - - mbedtls_ecp_point_init( &K ); mbedtls_mpi_init( &m_xm2_s ); mbedtls_mpi_init( &one ); @@ -788,12 +780,39 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, */ MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s, &ctx->grp.N, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K, + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, K, &one, &ctx->Xp, &m_xm2_s, &ctx->Xp2 ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K, + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, K, &ctx->xm2, K, f_rng, p_rng ) ); +cleanup: + mbedtls_mpi_free( &m_xm2_s ); + mbedtls_mpi_free( &one ); + + return( ret ); +} + +int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, + unsigned char *buf, size_t len, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_point K; + unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; + size_t x_bytes; + + *olen = mbedtls_hash_info_get_size( ctx->md_type ); + if( len < *olen ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + mbedtls_ecp_point_init( &K ); + + ret = mbedtls_ecjpake_derive_k(ctx, &K, f_rng, p_rng); + if( ret ) + goto cleanup; + /* PMS = SHA-256( K.X ) */ x_bytes = ( ctx->grp.pbits + 7 ) / 8; MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) ); @@ -802,8 +821,31 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, cleanup: mbedtls_ecp_point_free( &K ); - mbedtls_mpi_free( &m_xm2_s ); - mbedtls_mpi_free( &one ); + + return( ret ); +} + +int mbedtls_ecjpake_write_shared_key( mbedtls_ecjpake_context *ctx, + unsigned char *buf, size_t len, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_point K; + + mbedtls_ecp_point_init( &K ); + + ret = mbedtls_ecjpake_derive_k(ctx, &K, f_rng, p_rng); + if( ret ) + goto cleanup; + + ret = mbedtls_ecp_point_write_binary( &ctx->grp, &K, ctx->point_format, + olen, buf, len ); + if( ret != 0 ) + goto cleanup; + +cleanup: + mbedtls_ecp_point_free( &K ); return( ret ); } @@ -958,6 +1000,15 @@ static const unsigned char ecjpake_test_cli_two[] = { 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c }; +static const unsigned char ecjpake_test_shared_key[] = { + 0x04, 0x01, 0xab, 0xe9, 0xf2, 0xc7, 0x3a, 0x99, 0x14, 0xcb, 0x1f, 0x80, + 0xfb, 0x9d, 0xdb, 0x7e, 0x00, 0x12, 0xa8, 0x9c, 0x2f, 0x39, 0x27, 0x79, + 0xf9, 0x64, 0x40, 0x14, 0x75, 0xea, 0xc1, 0x31, 0x28, 0x43, 0x8f, 0xe1, + 0x12, 0x41, 0xd6, 0xc1, 0xe5, 0x5f, 0x7b, 0x80, 0x88, 0x94, 0xc9, 0xc0, + 0x27, 0xa3, 0x34, 0x41, 0xf5, 0xcb, 0xa1, 0xfe, 0x6c, 0xc7, 0xe6, 0x12, + 0x17, 0xc3, 0xde, 0x27, 0xb4, +}; + static const unsigned char ecjpake_test_pms[] = { 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7, 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9, @@ -1144,6 +1195,13 @@ int mbedtls_ecjpake_self_test( int verbose ) TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); + /* Server derives K as unsigned binary data */ + TEST_ASSERT( mbedtls_ecjpake_write_shared_key( &srv, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( len == sizeof( ecjpake_test_shared_key ) ); + TEST_ASSERT( memcmp( buf, ecjpake_test_shared_key, len ) == 0 ); + memset( buf, 0, len ); /* Avoid interferences with next step */ /* Client derives PMS */ @@ -1153,6 +1211,13 @@ int mbedtls_ecjpake_self_test( int verbose ) TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); + /* Client derives K as unsigned binary data */ + TEST_ASSERT( mbedtls_ecjpake_write_shared_key( &cli, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( len == sizeof( ecjpake_test_shared_key ) ); + TEST_ASSERT( memcmp( buf, ecjpake_test_shared_key, len ) == 0 ); + if( verbose != 0 ) mbedtls_printf( "passed\n" ); #endif /* ! MBEDTLS_ECJPAKE_ALT */ From f19a3cb61333150650067e51de4242f6305000a0 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 15 Jun 2022 16:00:29 +0200 Subject: [PATCH 35/55] Use the mbedtls_ecjpake_write_shared_key() to input raw shared key material as derivation secret Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 556acd99b7..dd1a91e5a4 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -690,12 +690,12 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { - ret = mbedtls_ecjpake_derive_secret( &operation->ctx.ecjpake, - operation->buffer, - PSA_PAKE_BUFFER_SIZE, - &operation->buffer_length, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE ); + ret = mbedtls_ecjpake_write_shared_key( &operation->ctx.ecjpake, + operation->buffer, + PSA_PAKE_BUFFER_SIZE, + &operation->buffer_length, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE ); if( ret != 0) { psa_pake_abort( operation ); From db5b960a7e12f33fe7a3e47da5bfaf4edb135063 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 20 Jun 2022 14:56:50 +0200 Subject: [PATCH 36/55] Permit any psa_pake_input() step to fail when error injected in input Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.function | 438 ++++++++++++++++---- 1 file changed, 353 insertions(+), 85 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 29a007792f..5261dedb44 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -732,7 +732,8 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, size_t c_x1_pr_len, c_x2_pr_len, c_x2s_pr_len; size_t c_x1_pr_off, c_x2_pr_off, c_x2s_pr_off; psa_status_t expected_status = PSA_SUCCESS; - int ret; + psa_status_t status; + int ret = 0; ASSERT_ALLOC( buffer0, buffer_length ); ASSERT_ALLOC( buffer1, buffer_length ); @@ -782,30 +783,86 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, if( client_input_first == 1 ) { /* Client first round Input */ - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + s_g1_off, s_g1_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + s_x1_pk_off, - s_x1_pk_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + s_x1_pr_off, - s_x1_pr_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + s_g2_off, - s_g2_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + s_x2_pk_off, - s_x2_pk_len ) ); - TEST_EQUAL( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + s_x2_pr_off, - s_x2_pr_len ), - expected_status ); - - if( inject_error == 1 ) + status = psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g1_off, s_g1_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) { - ret = 1; - goto exit; + TEST_EQUAL( status, expected_status ); + break; } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x1_pk_off, + s_x1_pk_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x1_pr_off, + s_x1_pr_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g2_off, + s_g2_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2_pk_off, + s_x2_pk_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2_pr_off, + s_x2_pr_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + /* Error didn't trigger, exit with error */ + if( inject_error == 1 ) + goto exit; } /* Client first round Output */ @@ -843,27 +900,86 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, if( client_input_first == 0 ) { /* Client first round Input */ - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + s_g1_off, s_g1_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + s_x1_pk_off, - s_x1_pk_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + s_x1_pr_off, - s_x1_pr_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + s_g2_off, - s_g2_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + s_x2_pk_off, - s_x2_pk_len ) ); - TEST_EQUAL( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + s_x2_pr_off, - s_x2_pr_len ), - expected_status ); - - if( inject_error == 1 ) + status = psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g1_off, s_g1_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x1_pk_off, + s_x1_pk_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x1_pr_off, + s_x1_pr_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_g2_off, + s_g2_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2_pk_off, + s_x2_pk_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2_pr_off, + s_x2_pr_len ); + if( inject_error == 1 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + /* Error didn't trigger, exit with error */ + if( inject_error == 1 ) + goto exit; } if( inject_error == 2 ) @@ -874,19 +990,81 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, } /* Server first round Input */ - PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_KEY_SHARE, - buffer1 + c_g1_off, c_g1_len ) ); - PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_ZK_PUBLIC, - buffer1 + c_x1_pk_off, c_x1_pk_len ) ); - PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_ZK_PROOF, - buffer1 + c_x1_pr_off, c_x1_pr_len ) ); - PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_KEY_SHARE, - buffer1 + c_g2_off, c_g2_len ) ); - PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_ZK_PUBLIC, - buffer1 + c_x2_pk_off, c_x2_pk_len ) ); - TEST_EQUAL( psa_pake_input( server, PSA_PAKE_STEP_ZK_PROOF, - buffer1 + c_x2_pr_off, c_x2_pr_len ), - expected_status ); + status = psa_pake_input( server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_g1_off, c_g1_len ); + if( inject_error == 2 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + c_x1_pk_off, c_x1_pk_len ); + if( inject_error == 2 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( server, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + c_x1_pr_off, c_x1_pr_len ); + if( inject_error == 2 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_g2_off, c_g2_len ); + if( inject_error == 2 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + c_x2_pk_off, c_x2_pk_len ); + if( inject_error == 2 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( server, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + c_x2_pr_off, c_x2_pr_len ); + if( inject_error == 2 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + /* Error didn't trigger, exit with error */ + if( inject_error == 2 ) + goto exit; break; @@ -919,18 +1097,47 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, if( client_input_first == 1 ) { /* Client second round Input */ - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + s_a_off, s_a_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + s_x2s_pk_off, - s_x2s_pk_len ) ); - TEST_EQUAL( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + s_x2s_pr_off, - s_x2s_pr_len ), - expected_status ); - - if( inject_error == 3 ) + status = psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_a_off, s_a_len ); + if( inject_error == 3 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2s_pk_off, + s_x2s_pk_len ); + if( inject_error == 3 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2s_pr_off, + s_x2s_pr_len ); + if( inject_error == 3 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + /* Error didn't trigger, exit with error */ + if( inject_error == 3 ) + goto exit; } /* Client second round Output */ @@ -955,18 +1162,47 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, if( client_input_first == 0 ) { /* Client second round Input */ - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, - buffer0 + s_a_off, s_a_len ) ); - PSA_ASSERT( psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, - buffer0 + s_x2s_pk_off, - s_x2s_pk_len ) ); - TEST_EQUAL( psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, - buffer0 + s_x2s_pr_off, - s_x2s_pr_len ), - expected_status ); - - if( inject_error == 3 ) + status = psa_pake_input( client, PSA_PAKE_STEP_KEY_SHARE, + buffer0 + s_a_off, s_a_len ); + if( inject_error == 3 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PUBLIC, + buffer0 + s_x2s_pk_off, + s_x2s_pk_len ); + if( inject_error == 3 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( client, PSA_PAKE_STEP_ZK_PROOF, + buffer0 + s_x2s_pr_off, + s_x2s_pr_len ); + if( inject_error == 3 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + /* Error didn't trigger, exit with error */ + if( inject_error == 3 ) + goto exit; } if( inject_error == 4 ) @@ -976,13 +1212,45 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, } /* Server second round Input */ - PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_KEY_SHARE, - buffer1 + c_a_off, c_a_len ) ); - PSA_ASSERT( psa_pake_input( server, PSA_PAKE_STEP_ZK_PUBLIC, - buffer1 + c_x2s_pk_off, c_x2s_pk_len ) ); - TEST_EQUAL( psa_pake_input( server, PSA_PAKE_STEP_ZK_PROOF, - buffer1 + c_x2s_pr_off, c_x2s_pr_len ), - expected_status ); + status = psa_pake_input( server, PSA_PAKE_STEP_KEY_SHARE, + buffer1 + c_a_off, c_a_len ); + if( inject_error == 4 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( server, PSA_PAKE_STEP_ZK_PUBLIC, + buffer1 + c_x2s_pk_off, c_x2s_pk_len ); + if( inject_error == 4 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + status = psa_pake_input( server, PSA_PAKE_STEP_ZK_PROOF, + buffer1 + c_x2s_pr_off, c_x2s_pr_len ); + if( inject_error == 4 && status != PSA_SUCCESS ) + { + TEST_EQUAL( status, expected_status ); + break; + } + else + { + TEST_EQUAL( status, PSA_SUCCESS ); + } + + /* Error didn't trigger, exit with error */ + if( inject_error == 4 ) + goto exit; break; From eae1dfcc46e3fe03809989637ca2a7cfe1373d32 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 21 Jun 2022 13:37:06 +0200 Subject: [PATCH 37/55] Change to more efficient error injection in ecjpake_do_round() Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.function | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 5261dedb44..c5a8cde6fa 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -775,7 +775,7 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, if( inject_error == 1 ) { - buffer0[s_x1_pk_off + 12] >>= 4; + buffer0[s_x1_pk_off + 8] >>= 4; buffer0[s_x2_pk_off + 7] <<= 4; expected_status = PSA_ERROR_DATA_INVALID; } @@ -1090,7 +1090,7 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, if( inject_error == 3 ) { - buffer0[s_x2s_pk_off + 12] >>= 4; + buffer0[s_x2s_pk_off + 12] += 0x33; expected_status = PSA_ERROR_DATA_INVALID; } @@ -1207,7 +1207,7 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, if( inject_error == 4 ) { - buffer1[c_x2s_pk_off + 12] >>= 4; + buffer1[c_x2s_pk_off + 7] += 0x28; expected_status = PSA_ERROR_DATA_INVALID; } From e5fdf20a7957a7e2e2fca28c103b7fe8a728e2a1 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 30 Aug 2022 10:24:39 +0200 Subject: [PATCH 38/55] Make ecjpake_rounds test depends on PSA_WANT_ALG_TLS12_PSK_TO_MS Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.data | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 2e876ff24b..38bc64cc18 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6495,11 +6495,11 @@ depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_NONE:0:"abcd":PSA_ERROR_NOT_SUPPORTED PSA PAKE: ecjpake rounds -depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PSK_TO_MS ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":0 PSA PAKE: ecjpake rounds, client input first -depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PSK_TO_MS ecjpake_rounds:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"abcdef":1 PSA PAKE: ecjpake no input errors From b764fb60aa554ddb01980bf0da01473175f9a744 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 30 Aug 2022 14:38:57 +0200 Subject: [PATCH 39/55] Remove MBEDTLS_MD_C dep in config_psa.h when ECJPAJE is wanted Signed-off-by: Neil Armstrong --- include/mbedtls/config_psa.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h index 96083d8102..342f005747 100644 --- a/include/mbedtls/config_psa.h +++ b/include/mbedtls/config_psa.h @@ -152,7 +152,6 @@ extern "C" { #define MBEDTLS_ECP_DP_SECP256R1_ENABLED #define MBEDTLS_BIGNUM_C #define MBEDTLS_ECP_C -#define MBEDTLS_MD_C #define MBEDTLS_ECJPAKE_C #endif /* PSA_WANT_ALG_JPAKE */ From 5bbdb7013146b67e680f2e473137fb18b64f90c8 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 5 Sep 2022 17:54:15 +0200 Subject: [PATCH 40/55] Fix style in psa_pake_input() Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index dd1a91e5a4..dfd95d06dd 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -540,7 +540,8 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { - if( operation->state == PSA_PAKE_STATE_SETUP ) { + if( operation->state == PSA_PAKE_STATE_SETUP ) + { status = psa_pake_ecjpake_setup( operation ); if( status != PSA_SUCCESS ) { From 51009d72970de6fe1a97a6a655031a24ba1f3532 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 5 Sep 2022 17:59:54 +0200 Subject: [PATCH 41/55] Add comment in ecjpake_do_round() explaining input errors can be detected any time in the input sequence Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.function | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index c5a8cde6fa..12d7a89fba 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -780,6 +780,14 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, expected_status = PSA_ERROR_DATA_INVALID; } + /* + * When injecting errors in inputs, the implementation is + * free to detect it right away of with a delay. + * This permits delaying the error until the end of the input + * sequence, if no error appears then, this will be treated + * as an error. + */ + if( client_input_first == 1 ) { /* Client first round Input */ From 78c4e8e9cba09c9386fce0dbb47dcc1640e0a930 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 5 Sep 2022 18:08:13 +0200 Subject: [PATCH 42/55] Make ecjpake_do_round() return void and use TEST_ASSERT with a descriptive text instead of returning a value Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.function | 56 +++++++++------------ 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 12d7a89fba..4ca308d1ae 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -706,11 +706,11 @@ exit: } #if defined(PSA_WANT_ALG_JPAKE) -static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, - psa_pake_operation_t *server, - psa_pake_operation_t *client, - int client_input_first, - int round, int inject_error ) +static void ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, + psa_pake_operation_t *server, + psa_pake_operation_t *client, + int client_input_first, + int round, int inject_error ) { unsigned char *buffer0 = NULL, *buffer1 = NULL; size_t buffer_length = ( @@ -733,7 +733,6 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, size_t c_x1_pr_off, c_x2_pr_off, c_x2s_pr_off; psa_status_t expected_status = PSA_SUCCESS; psa_status_t status; - int ret = 0; ASSERT_ALLOC( buffer0, buffer_length ); ASSERT_ALLOC( buffer1, buffer_length ); @@ -868,9 +867,9 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, TEST_EQUAL( status, PSA_SUCCESS ); } - /* Error didn't trigger, exit with error */ + /* Error didn't trigger, make test fail */ if( inject_error == 1 ) - goto exit; + TEST_ASSERT( ! "One of the last psa_pake_input() calls should have returned the expected error." ); } /* Client first round Output */ @@ -985,9 +984,9 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, TEST_EQUAL( status, PSA_SUCCESS ); } - /* Error didn't trigger, exit with error */ + /* Error didn't trigger, make test fail */ if( inject_error == 1 ) - goto exit; + TEST_ASSERT( ! "One of the last psa_pake_input() calls should have returned the expected error." ); } if( inject_error == 2 ) @@ -1070,9 +1069,9 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, TEST_EQUAL( status, PSA_SUCCESS ); } - /* Error didn't trigger, exit with error */ + /* Error didn't trigger, make test fail */ if( inject_error == 2 ) - goto exit; + TEST_ASSERT( ! "One of the last psa_pake_input() calls should have returned the expected error." ); break; @@ -1143,9 +1142,9 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, TEST_EQUAL( status, PSA_SUCCESS ); } - /* Error didn't trigger, exit with error */ + /* Error didn't trigger, make test fail */ if( inject_error == 3 ) - goto exit; + TEST_ASSERT( ! "One of the last psa_pake_input() calls should have returned the expected error." ); } /* Client second round Output */ @@ -1208,9 +1207,9 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, TEST_EQUAL( status, PSA_SUCCESS ); } - /* Error didn't trigger, exit with error */ + /* Error didn't trigger, make test fail */ if( inject_error == 3 ) - goto exit; + TEST_ASSERT( ! "One of the last psa_pake_input() calls should have returned the expected error." ); } if( inject_error == 4 ) @@ -1256,20 +1255,17 @@ static int ecjpake_do_round( psa_algorithm_t alg, unsigned int primitive, TEST_EQUAL( status, PSA_SUCCESS ); } - /* Error didn't trigger, exit with error */ + /* Error didn't trigger, make test fail */ if( inject_error == 4 ) - goto exit; + TEST_ASSERT( ! "One of the last psa_pake_input() calls should have returned the expected error." ); break; } - ret = 1; - exit: mbedtls_free( buffer0 ); mbedtls_free( buffer1 ); - return( ret ); } #endif /* PSA_WANT_ALG_JPAKE */ @@ -8868,16 +8864,14 @@ void ecjpake_rounds_inject( int alg_arg, int primitive_arg, int hash_arg, PSA_ASSERT( psa_pake_set_password_key( &server, key ) ); PSA_ASSERT( psa_pake_set_password_key( &client, key ) ); - TEST_EQUAL( ecjpake_do_round( alg, primitive_arg, &server, &client, - client_input_first, 1, - inject_error ), 1 ); + ecjpake_do_round( alg, primitive_arg, &server, &client, + client_input_first, 1, inject_error ); if( inject_error == 1 || inject_error == 2 ) goto exit; - TEST_EQUAL( ecjpake_do_round( alg, primitive_arg, &server, &client, - client_input_first, 2, - inject_error ), 1 ); + ecjpake_do_round( alg, primitive_arg, &server, &client, + client_input_first, 2, inject_error ); exit: psa_destroy_key( key ); @@ -8947,8 +8941,8 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, PSA_ERROR_BAD_STATE ); /* First round */ - TEST_EQUAL( ecjpake_do_round( alg, primitive_arg, &server, &client, - client_input_first, 1, 0 ), 1 ); + ecjpake_do_round( alg, primitive_arg, &server, &client, + client_input_first, 1, 0 ); TEST_EQUAL( psa_pake_get_implicit_key( &server, &server_derive ), PSA_ERROR_BAD_STATE ); @@ -8956,8 +8950,8 @@ void ecjpake_rounds( int alg_arg, int primitive_arg, int hash_arg, PSA_ERROR_BAD_STATE ); /* Second round */ - TEST_EQUAL( ecjpake_do_round( alg, primitive_arg, &server, &client, - client_input_first, 2, 0 ), 1 ); + ecjpake_do_round( alg, primitive_arg, &server, &client, + client_input_first, 2, 0 ); PSA_ASSERT( psa_pake_get_implicit_key( &server, &server_derive ) ); PSA_ASSERT( psa_pake_get_implicit_key( &client, &client_derive ) ); From bcd5bd933e6d6fd8a89ae117464092a41fcb5be4 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 5 Sep 2022 18:33:23 +0200 Subject: [PATCH 43/55] Add a comment expliciting usage of internal PAKE step/state/sequence enums Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index dfd95d06dd..3383ce29f3 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -101,6 +101,67 @@ enum psa_pake_state PSA_PAKE_INPUT_X4S = 6, }; +/* + * The first PAKE step shares the same sequences of the second PAKE step + * but with a second set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs. + * This it's simpler to share the same sequences numbers of the first + * set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs in both PAKE steps. + * + * State sequence with step, state & sequence enums: + * => Input & Output Step = PSA_PAKE_STEP_INVALID + * => state = PSA_PAKE_STATE_INVALID + * psa_pake_setup() + * => Input & Output Step = PSA_PAKE_STEP_X1_X2 + * => state = PSA_PAKE_STATE_SETUP + * => sequence = PSA_PAKE_SEQ_INVALID + * | + * |--- In any order: (First round input before or after first round output) + * | | First call of psa_pake_output() or psa_pake_input() sets + * | | state = PSA_PAKE_STATE_READY + * | | + * | |------ In Order: => state = PSA_PAKE_OUTPUT_X1_X2 + * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE + * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC + * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF + * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE + * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC + * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF + * | | | => state = PSA_PAKE_STATE_READY + * | | | => sequence = PSA_PAKE_SEQ_INVALID + * | | \ => Output Step = PSA_PAKE_STEP_X2S + * | | + * | |------ In Order: => state = PSA_PAKE_INPUT_X1_X2 + * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE + * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC + * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF + * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE + * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC + * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF + * | | | => state = PSA_PAKE_STATE_READY + * | | | => sequence = PSA_PAKE_SEQ_INVALID + * | | \ => Output Step = PSA_PAKE_INPUT_X4S + * | + * |--- In any order: (Second round input before or after second round output) + * | | + * | |------ In Order: => state = PSA_PAKE_OUTPUT_X2S + * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE + * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC + * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF + * | | | => state = PSA_PAKE_STATE_READY + * | | | => sequence = PSA_PAKE_SEQ_INVALID + * | | \ => Output Step = PSA_PAKE_STEP_DERIVE + * | | + * | |------ In Order: => state = PSA_PAKE_INPUT_X4S + * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE + * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC + * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF + * | | | => state = PSA_PAKE_STATE_READY + * | | | => sequence = PSA_PAKE_SEQ_INVALID + * | | \ => Output Step = PSA_PAKE_STEP_DERIVE + * | + * psa_pake_get_implicit_key() + * => Input & Output Step = PSA_PAKE_STEP_INVALID + */ enum psa_pake_sequence { PSA_PAKE_SEQ_INVALID = 0, From 2a73f2187827bde02978d655f39a714e7b662cbd Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 6 Sep 2022 11:34:54 +0200 Subject: [PATCH 44/55] Fixup expected status handling in ecjpake_setup() and add more coverage for psa_pake_set_password_key() Signed-off-by: Neil Armstrong --- tests/suites/test_suite_psa_crypto.data | 32 ++++++----- tests/suites/test_suite_psa_crypto.function | 60 ++++++++++----------- 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 38bc64cc18..c8b229c7f4 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6448,51 +6448,59 @@ persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b PSA PAKE: invalid alg depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_SHA_256:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_INVALID_ARGUMENT +ecjpake_setup:PSA_ALG_SHA_256:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_INVALID_ARGUMENT:0:0:0 PSA PAKE: invalid primitive type depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_DH, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_DH, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED:0:0:0 PSA PAKE: invalid primitive family depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_K1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_K1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED:0:0:0 PSA PAKE: invalid primitive bits depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 128):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 128):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED:0:0:0 PSA PAKE: invalid hash depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_1:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_1:PSA_PAKE_ROLE_SERVER:0:"abcd":PSA_ERROR_NOT_SUPPORTED:0:0:0 PSA PAKE: ecjpake setup server output step first depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":0 +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"abcd":0:0:0:0 PSA PAKE: ecjpake setup server input step first depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:1:"abcd":0 +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:1:"abcd":0:0:0:0 PSA PAKE: ecjpake setup server empty password depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"":PSA_ERROR_BAD_STATE +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_SERVER:0:"":0:0:0:PSA_ERROR_BAD_STATE PSA PAKE: ecjpake setup client output step first depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:0:"abcd":0 +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:0:"abcd":0:0:0:0 PSA PAKE: ecjpake setup client input step first depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:1:"abcd":0 +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:1:"abcd":0:0:0:0 PSA PAKE: ecjpake setup client empty password depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:0:"":PSA_ERROR_BAD_STATE +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:0:"":0:0:0:PSA_ERROR_BAD_STATE + +PSA PAKE: ecjpake setup client bad password key type +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_DERIVE:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:0:"abcd":0:0:PSA_ERROR_INVALID_ARGUMENT:0 + +PSA PAKE: ecjpake setup client bad password key usage +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_ENCRYPT:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_CLIENT:0:"abcd":0:0:PSA_ERROR_NOT_PERMITTED:0 PSA PAKE: ecjpake setup invalid role NONE depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256 -ecjpake_setup:PSA_ALG_JPAKE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_NONE:0:"abcd":PSA_ERROR_NOT_SUPPORTED +ecjpake_setup:PSA_ALG_JPAKE:PSA_KEY_TYPE_PASSWORD:PSA_KEY_USAGE_DERIVE:PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256):PSA_ALG_SHA_256:PSA_PAKE_ROLE_NONE:0:"abcd":0:PSA_ERROR_NOT_SUPPORTED:0:0 PSA PAKE: ecjpake rounds depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PSK_TO_MS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 4ca308d1ae..c74acf6715 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8657,19 +8657,29 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:PSA_WANT_ALG_JPAKE */ -void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, +void ecjpake_setup( int alg_arg, int key_type_pw_arg, int key_usage_pw_arg, + int primitive_arg, int hash_arg, int role_arg, int input_first, data_t *pw_data, - int expected_status_arg ) + int expected_status_setup_arg, + int expected_status_set_role_arg, + int expected_status_set_password_key_arg, + int expected_status_input_output_arg) { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); psa_pake_operation_t operation = psa_pake_operation_init(); psa_algorithm_t alg = alg_arg; + psa_key_type_t key_type_pw = key_type_pw_arg; + psa_key_usage_t key_usage_pw = key_usage_pw_arg; psa_algorithm_t hash_alg = hash_arg; psa_pake_role_t role = role_arg; mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t expected_status = expected_status_arg; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t expected_status_setup = expected_status_setup_arg; + psa_status_t expected_status_set_role = expected_status_set_role_arg; + psa_status_t expected_status_set_password_key = + expected_status_set_password_key_arg; + psa_status_t expected_status_input_output = + expected_status_input_output_arg; unsigned char *output_buffer = NULL; size_t output_len = 0; @@ -8681,9 +8691,9 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, if( pw_data->len > 0 ) { - psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); + psa_set_key_usage_flags( &attributes, key_usage_pw ); psa_set_key_algorithm( &attributes, alg ); - psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); + psa_set_key_type( &attributes, key_type_pw ); PSA_ASSERT( psa_import_key( &attributes, pw_data->x, pw_data->len, &key ) ); } @@ -8710,37 +8720,25 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, PSA_ASSERT( psa_pake_abort( &operation ) ); - status = psa_pake_setup( &operation, &cipher_suite ); - if( status != PSA_SUCCESS ) - { - TEST_EQUAL( status, expected_status ); + TEST_EQUAL( psa_pake_setup( &operation, &cipher_suite ), + expected_status_setup ); + if( expected_status_setup != PSA_SUCCESS ) goto exit; - } - else - PSA_ASSERT( status ); TEST_EQUAL( psa_pake_setup( &operation, &cipher_suite ), PSA_ERROR_BAD_STATE ); - status = psa_pake_set_role( &operation, role ); - if( status != PSA_SUCCESS ) - { - TEST_EQUAL( status, expected_status ); + TEST_EQUAL( psa_pake_set_role( &operation, role), + expected_status_set_role ); + if( expected_status_set_role != PSA_SUCCESS ) goto exit; - } - else - PSA_ASSERT( status ); if( pw_data->len > 0 ) { - status = psa_pake_set_password_key( &operation, key ); - if( status != PSA_SUCCESS ) - { - TEST_EQUAL( status, expected_status ); + TEST_EQUAL( psa_pake_set_password_key( &operation, key ), + expected_status_set_password_key ); + if( expected_status_set_password_key != PSA_SUCCESS ) goto exit; - } - else - PSA_ASSERT( status ); } TEST_EQUAL( psa_pake_set_user( &operation, NULL, 0 ), @@ -8772,9 +8770,9 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_KEY_SHARE, output_buffer, 66 ), - expected_status); + expected_status_input_output); - if( expected_status == PSA_SUCCESS ) + if( expected_status_input_output == PSA_SUCCESS ) { /* Buffer too large */ TEST_EQUAL( psa_pake_input( &operation, PSA_PAKE_STEP_ZK_PUBLIC, @@ -8803,9 +8801,9 @@ void ecjpake_setup( int alg_arg, int primitive_arg, int hash_arg, int role_arg, TEST_EQUAL( psa_pake_output( &operation, PSA_PAKE_STEP_KEY_SHARE, output_buffer, 512, &output_len ), - expected_status ); + expected_status_input_output ); - if( expected_status == PSA_SUCCESS ) + if( expected_status_input_output == PSA_SUCCESS ) { TEST_ASSERT( output_len > 0 ); From b39833cff2cba3a327d6b60bc6428d9b2ee41884 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 6 Sep 2022 11:36:02 +0200 Subject: [PATCH 45/55] Fix typo in psa_pake_sequence comment Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 3383ce29f3..519825084b 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -104,7 +104,7 @@ enum psa_pake_state /* * The first PAKE step shares the same sequences of the second PAKE step * but with a second set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs. - * This it's simpler to share the same sequences numbers of the first + * It's simpler to share the same sequences numbers of the first * set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs in both PAKE steps. * * State sequence with step, state & sequence enums: From 9720b881f5b839e53f9e39505bdf6a43a5625226 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 6 Sep 2022 11:39:21 +0200 Subject: [PATCH 46/55] Remove doxygen markup outside doxygen block in psa_pake_sequence comment Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 519825084b..f7be68786d 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -128,7 +128,7 @@ enum psa_pake_state * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF * | | | => state = PSA_PAKE_STATE_READY * | | | => sequence = PSA_PAKE_SEQ_INVALID - * | | \ => Output Step = PSA_PAKE_STEP_X2S + * | | | => Output Step = PSA_PAKE_STEP_X2S * | | * | |------ In Order: => state = PSA_PAKE_INPUT_X1_X2 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE @@ -139,7 +139,7 @@ enum psa_pake_state * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF * | | | => state = PSA_PAKE_STATE_READY * | | | => sequence = PSA_PAKE_SEQ_INVALID - * | | \ => Output Step = PSA_PAKE_INPUT_X4S + * | | | => Output Step = PSA_PAKE_INPUT_X4S * | * |--- In any order: (Second round input before or after second round output) * | | @@ -149,7 +149,7 @@ enum psa_pake_state * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF * | | | => state = PSA_PAKE_STATE_READY * | | | => sequence = PSA_PAKE_SEQ_INVALID - * | | \ => Output Step = PSA_PAKE_STEP_DERIVE + * | | | => Output Step = PSA_PAKE_STEP_DERIVE * | | * | |------ In Order: => state = PSA_PAKE_INPUT_X4S * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE @@ -157,7 +157,7 @@ enum psa_pake_state * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF * | | | => state = PSA_PAKE_STATE_READY * | | | => sequence = PSA_PAKE_SEQ_INVALID - * | | \ => Output Step = PSA_PAKE_STEP_DERIVE + * | | | => Output Step = PSA_PAKE_STEP_DERIVE * | * psa_pake_get_implicit_key() * => Input & Output Step = PSA_PAKE_STEP_INVALID From ecb221b1ffc120cb7920f316deefac3a10c08fa4 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 8 Sep 2022 11:21:07 +0200 Subject: [PATCH 47/55] Move operation buffer in operation struct and remove dynamic allocation Signed-off-by: Neil Armstrong --- include/psa/crypto_extra.h | 5 +++-- library/psa_crypto_pake.c | 19 ++++--------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index e625f0d982..3330bf63ea 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -1829,7 +1829,7 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); */ #if defined(MBEDTLS_PSA_BUILTIN_PAKE) #define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0, \ - MBEDTLS_SVC_KEY_ID_INIT, 0, NULL, 0, 0, \ + MBEDTLS_SVC_KEY_ID_INIT, 0, {0}, 0, 0, \ {.dummy = 0}} #else #define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, {0}} @@ -1905,6 +1905,7 @@ static inline void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite, #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) #include +#define PSA_PAKE_BUFFER_SIZE ( ( 69 + 66 + 33 ) * 2 ) #endif struct psa_pake_operation_s @@ -1917,7 +1918,7 @@ struct psa_pake_operation_s unsigned int MBEDTLS_PRIVATE(output_step); mbedtls_svc_key_id_t MBEDTLS_PRIVATE(password); psa_pake_role_t MBEDTLS_PRIVATE(role); - uint8_t *MBEDTLS_PRIVATE(buffer); + uint8_t MBEDTLS_PRIVATE(buffer[PSA_PAKE_BUFFER_SIZE]); size_t MBEDTLS_PRIVATE(buffer_length); size_t MBEDTLS_PRIVATE(buffer_offset); #endif diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index f7be68786d..1fd91290e6 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -33,10 +33,6 @@ #include #include -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) -#define PSA_PAKE_BUFFER_SIZE ( ( 69 + 66 + 33 ) * 2 ) -#endif - /* * State sequence: * @@ -234,7 +230,7 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation, operation->input_step = PSA_PAKE_STEP_X1_X2; operation->output_step = PSA_PAKE_STEP_X1_X2; - operation->buffer = NULL; + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); operation->buffer_length = 0; operation->buffer_offset = 0; @@ -383,10 +379,6 @@ static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation ) if( ret != 0 ) return( mbedtls_ecjpake_to_psa_error( ret ) ); - operation->buffer = mbedtls_calloc( 1, PSA_PAKE_BUFFER_SIZE ); - if( operation->buffer == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - operation->state = PSA_PAKE_STATE_READY; return( PSA_SUCCESS ); @@ -428,8 +420,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, } if( operation->state >= PSA_PAKE_STATE_READY && - ( mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 || - operation->buffer == NULL ) ) + mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 ) { return( PSA_ERROR_BAD_STATE ); } @@ -612,8 +603,7 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, } if( operation->state >= PSA_PAKE_STATE_READY && - ( mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 || - operation->buffer == NULL ) ) + mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 ) { return( PSA_ERROR_BAD_STATE ); } @@ -794,8 +784,7 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation) operation->output_step = 0; operation->password = MBEDTLS_SVC_KEY_ID_INIT; operation->role = 0; - mbedtls_free( operation->buffer ); - operation->buffer = NULL; + mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); operation->buffer_length = 0; operation->buffer_offset = 0; mbedtls_ecjpake_free( &operation->ctx.ecjpake ); From 7cd4eacbd4cf5a05e5d3043e2f90096d89999712 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 8 Sep 2022 14:57:55 +0200 Subject: [PATCH 48/55] Fix typo in mbedtls_ecjpake_write_shared_key() comment Signed-off-by: Neil Armstrong --- include/mbedtls/ecjpake.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h index 5b57455576..e7ca1b2354 100644 --- a/include/mbedtls/ecjpake.h +++ b/include/mbedtls/ecjpake.h @@ -267,7 +267,7 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, * \param buf The buffer to write the derived secret to. This must * be a writable buffer of length \p len Bytes. * \param len The length of \p buf in Bytes. - * \param olen The address at which to store the total number of Bytes + * \param olen The address at which to store the total number of bytes * written to \p buf. This must not be \c NULL. * \param f_rng The RNG function to use. This must not be \c NULL. * \param p_rng The RNG parameter to be passed to \p f_rng. This From fb3093a9cbc6ac163bac8efa5c39493b42552684 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 8 Sep 2022 14:59:32 +0200 Subject: [PATCH 49/55] Use PSA_PAKE_ROLE_NONE in PSA_PAKE_OPERATION_INIT macro instead of 0 Signed-off-by: Neil Armstrong --- include/psa/crypto_extra.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 3330bf63ea..6c2e06e503 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -1829,7 +1829,8 @@ psa_status_t psa_pake_abort( psa_pake_operation_t * operation ); */ #if defined(MBEDTLS_PSA_BUILTIN_PAKE) #define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, 0, 0, \ - MBEDTLS_SVC_KEY_ID_INIT, 0, {0}, 0, 0, \ + MBEDTLS_SVC_KEY_ID_INIT, \ + PSA_PAKE_ROLE_NONE, {0}, 0, 0, \ {.dummy = 0}} #else #define PSA_PAKE_OPERATION_INIT {PSA_ALG_NONE, 0, 0, {0}} From cb679f23bc44c4709670c1228353a28881d0a4ef Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 13 Sep 2022 14:43:07 +0200 Subject: [PATCH 50/55] Replace 0s with proper defines when possible Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 1fd91290e6..adff60fc65 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -198,7 +198,7 @@ psa_status_t psa_pake_setup( psa_pake_operation_t *operation, const psa_pake_cipher_suite_t *cipher_suite) { /* A context must be freshly initialized before it can be set up. */ - if( operation->alg != 0 ) + if( operation->alg != PSA_ALG_NONE ) return( PSA_ERROR_BAD_STATE ); if( cipher_suite == NULL || @@ -249,7 +249,7 @@ psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation, psa_key_type_t type; psa_key_usage_t usage; - if( operation->alg == 0 || + if( operation->alg == PSA_ALG_NONE || operation->state != PSA_PAKE_STATE_SETUP ) { return( PSA_ERROR_BAD_STATE ); @@ -282,7 +282,7 @@ psa_status_t psa_pake_set_user( psa_pake_operation_t *operation, const uint8_t *user_id, size_t user_id_len ) { - if( operation->alg == 0 || + if( operation->alg == PSA_ALG_NONE || operation->state != PSA_PAKE_STATE_SETUP ) { return( PSA_ERROR_BAD_STATE ); @@ -298,7 +298,7 @@ psa_status_t psa_pake_set_peer( psa_pake_operation_t *operation, const uint8_t *peer_id, size_t peer_id_len ) { - if( operation->alg == 0 || + if( operation->alg == PSA_ALG_NONE || operation->state != PSA_PAKE_STATE_SETUP ) { return( PSA_ERROR_BAD_STATE ); @@ -313,7 +313,7 @@ psa_status_t psa_pake_set_peer( psa_pake_operation_t *operation, psa_status_t psa_pake_set_role( psa_pake_operation_t *operation, psa_pake_role_t role ) { - if( operation->alg == 0 || + if( operation->alg == PSA_ALG_NONE || operation->state != PSA_PAKE_STATE_SETUP ) { return( PSA_ERROR_BAD_STATE ); @@ -395,7 +395,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t length; - if( operation->alg == 0 || + if( operation->alg == PSA_ALG_NONE || operation->state == PSA_PAKE_STATE_INVALID ) return( PSA_ERROR_BAD_STATE ); @@ -556,7 +556,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, operation->state = PSA_PAKE_STATE_READY; operation->output_step++; - operation->sequence = 0; + operation->sequence = PSA_PAKE_SEQ_INVALID; } else operation->sequence++; @@ -577,7 +577,7 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t buffer_remain; - if( operation->alg == 0 || + if( operation->alg == PSA_ALG_NONE || operation->state == PSA_PAKE_STATE_INVALID ) return( PSA_ERROR_BAD_STATE ); @@ -715,7 +715,7 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, { operation->state = PSA_PAKE_STATE_READY; operation->input_step++; - operation->sequence = 0; + operation->sequence = PSA_PAKE_SEQ_INVALID; } else operation->sequence++; @@ -733,7 +733,7 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - if( operation->alg == 0 || + if( operation->alg == PSA_ALG_NONE || operation->state != PSA_PAKE_STATE_READY || operation->input_step != PSA_PAKE_STEP_DERIVE || operation->output_step != PSA_PAKE_STEP_DERIVE ) @@ -772,7 +772,7 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, psa_status_t psa_pake_abort(psa_pake_operation_t * operation) { - if( operation->alg == 0 ) + if( operation->alg == PSA_ALG_NONE ) { return( PSA_SUCCESS ); } @@ -780,10 +780,10 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation) #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { - operation->input_step = 0; - operation->output_step = 0; + operation->input_step = PSA_PAKE_STEP_INVALID; + operation->output_step = PSA_PAKE_STEP_INVALID; operation->password = MBEDTLS_SVC_KEY_ID_INIT; - operation->role = 0; + operation->role = PSA_PAKE_ROLE_NONE; mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE ); operation->buffer_length = 0; operation->buffer_offset = 0; @@ -791,9 +791,9 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation) } #endif - operation->alg = 0; - operation->state = 0; - operation->sequence = 0; + operation->alg = PSA_ALG_NONE; + operation->state = PSA_PAKE_STATE_INVALID; + operation->sequence = PSA_PAKE_SEQ_INVALID; return( PSA_SUCCESS ); } From 1d0294f6ede39c985a5ca8ddeaee3c6b68401bff Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 13 Sep 2022 14:49:24 +0200 Subject: [PATCH 51/55] Clarify sequence length calculation comment Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index adff60fc65..617187f10f 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -513,19 +513,42 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, operation->buffer_offset = 0; } - /* Load output sequence length */ + /* + * Steps sequences are stored as: + * struct { + * opaque point <1..2^8-1>; + * } ECPoint; + * + * Where byte 0 stores the ECPoint curve point length. + * + * The sequence length is equal to: + * - data length extracted from byte 0 + * - byte 0 size (1) + */ if( operation->state == PSA_PAKE_OUTPUT_X2S && operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE ) { if( operation->role == PSA_PAKE_ROLE_SERVER ) - /* Length is stored after 3bytes curve */ + /* + * The X2S KEY SHARE Server steps sequence is stored as: + * struct { + * ECPoint X; + * opaque r <1..2^8-1>; + * } ECSchnorrZKP; + * + * And MbedTLS uses a 3 bytes Ephemeral public key ECPoint, + * so byte 3 stores the r Schnorr signature length. + * + * The sequence length is equal to: + * - curve storage size (3) + * - data length extracted from byte 3 + * - byte 3 size (1) + */ length = 3 + operation->buffer[3] + 1; else - /* Length is stored at the first byte */ length = operation->buffer[0] + 1; } else - /* Length is stored at the first byte of the next chunk */ length = operation->buffer[operation->buffer_offset] + 1; if( length > operation->buffer_length ) From 017db4cddae4ce022f976b12bc89150c5cd688b8 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 13 Sep 2022 14:49:53 +0200 Subject: [PATCH 52/55] Drop calls to mbedtls_ecjpake_check() Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 617187f10f..83fcb41172 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -419,12 +419,6 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, } } - if( operation->state >= PSA_PAKE_STATE_READY && - mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 ) - { - return( PSA_ERROR_BAD_STATE ); - } - if( operation->state != PSA_PAKE_STATE_READY && operation->state != PSA_PAKE_OUTPUT_X1_X2 && operation->state != PSA_PAKE_OUTPUT_X2S ) @@ -625,12 +619,6 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, } } - if( operation->state >= PSA_PAKE_STATE_READY && - mbedtls_ecjpake_check( &operation->ctx.ecjpake ) != 0 ) - { - return( PSA_ERROR_BAD_STATE ); - } - if( operation->state != PSA_PAKE_STATE_READY && operation->state != PSA_PAKE_INPUT_X1_X2 && operation->state != PSA_PAKE_INPUT_X4S ) From 3d4966a5cbfbaffb18a131ea84d8e0ddb0b1cb55 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 13 Sep 2022 14:54:15 +0200 Subject: [PATCH 53/55] Move possible input/output steps check inside PSA_ALG_JPAKE handling Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 83fcb41172..73b01624f2 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -399,17 +399,17 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, operation->state == PSA_PAKE_STATE_INVALID ) return( PSA_ERROR_BAD_STATE ); - if( step != PSA_PAKE_STEP_KEY_SHARE && - step != PSA_PAKE_STEP_ZK_PUBLIC && - step != PSA_PAKE_STEP_ZK_PROOF ) - return( PSA_ERROR_INVALID_ARGUMENT ); - if( output == NULL || output_size == 0 || output_length == NULL ) return( PSA_ERROR_INVALID_ARGUMENT ); #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { + if( step != PSA_PAKE_STEP_KEY_SHARE && + step != PSA_PAKE_STEP_ZK_PUBLIC && + step != PSA_PAKE_STEP_ZK_PROOF ) + return( PSA_ERROR_INVALID_ARGUMENT ); + if( operation->state == PSA_PAKE_STATE_SETUP ) { status = psa_pake_ecjpake_setup( operation ); if( status != PSA_SUCCESS ) @@ -598,17 +598,17 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, operation->state == PSA_PAKE_STATE_INVALID ) return( PSA_ERROR_BAD_STATE ); - if( step != PSA_PAKE_STEP_KEY_SHARE && - step != PSA_PAKE_STEP_ZK_PUBLIC && - step != PSA_PAKE_STEP_ZK_PROOF ) - return( PSA_ERROR_INVALID_ARGUMENT ); - if( input == NULL || input_length == 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) if( operation->alg == PSA_ALG_JPAKE ) { + if( step != PSA_PAKE_STEP_KEY_SHARE && + step != PSA_PAKE_STEP_ZK_PUBLIC && + step != PSA_PAKE_STEP_ZK_PROOF ) + return( PSA_ERROR_INVALID_ARGUMENT ); + if( operation->state == PSA_PAKE_STATE_SETUP ) { status = psa_pake_ecjpake_setup( operation ); From fa849622962e1fb5bcb07fb87912fc965fa6d62c Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 13 Sep 2022 15:10:46 +0200 Subject: [PATCH 54/55] Add comment explaining PSA PAKE vs Mbedtls J-PAKE API matching strategy Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 73b01624f2..9c8eebb298 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -403,6 +403,20 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, return( PSA_ERROR_INVALID_ARGUMENT ); #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) + /* + * The PSA CRYPTO PAKE and MbedTLS JPAKE API have a different + * handling of output sequencing. + * + * The MbedTLS JPAKE API outputs the whole X1+X2 anf X2S steps data + * at once, on the other side the PSA CRYPTO PAKE api requires + * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X2S to be + * retrieved in sequence. + * + * In order to achieve API compatibility, the whole X1+X2 or X2S steps + * data is stored in an intermediate buffer at first step output call, + * and data is sliced down by parsing the ECPoint records in order + * to return the right parts on each step. + */ if( operation->alg == PSA_ALG_JPAKE ) { if( step != PSA_PAKE_STEP_KEY_SHARE && @@ -602,6 +616,21 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation, return( PSA_ERROR_INVALID_ARGUMENT ); #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) + /* + * The PSA CRYPTO PAKE and MbedTLS JPAKE API have a different + * handling of input sequencing. + * + * The MbedTLS JPAKE API takes the whole X1+X2 or X4S steps data + * at once as input, on the other side the PSA CRYPTO PAKE api requires + * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X4S to be + * given in sequence. + * + * In order to achieve API compatibility, each X1+X2 or X4S step data + * is stored sequentially in an intermediate buffer and given to the + * MbedTLS JPAKE API on the last step. + * + * This causes any input error to be only detected on the last step. + */ if( operation->alg == PSA_ALG_JPAKE ) { if( step != PSA_PAKE_STEP_KEY_SHARE && From 6a12a7704d0429fdab96c15d6f7ab69cb50d1b2c Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 14 Sep 2022 12:17:42 +0200 Subject: [PATCH 55/55] Fix typo in comment Signed-off-by: Neil Armstrong --- library/psa_crypto_pake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto_pake.c b/library/psa_crypto_pake.c index 9c8eebb298..10d3e4a1b0 100644 --- a/library/psa_crypto_pake.c +++ b/library/psa_crypto_pake.c @@ -407,7 +407,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation, * The PSA CRYPTO PAKE and MbedTLS JPAKE API have a different * handling of output sequencing. * - * The MbedTLS JPAKE API outputs the whole X1+X2 anf X2S steps data + * The MbedTLS JPAKE API outputs the whole X1+X2 and X2S steps data * at once, on the other side the PSA CRYPTO PAKE api requires * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X2S to be * retrieved in sequence.