1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-08-01 10:06:53 +03:00

Merge pull request #6390 from mpg/fix-ecjpake-psa-format

Fix ecjpake PSA format
This commit is contained in:
Gilles Peskine
2022-11-07 17:35:44 +01:00
committed by GitHub
4 changed files with 226 additions and 111 deletions

View File

@ -230,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;
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
operation->buffer_length = 0;
operation->buffer_offset = 0;
@ -385,7 +385,8 @@ static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
}
#endif
psa_status_t psa_pake_output( psa_pake_operation_t *operation,
static psa_status_t psa_pake_output_internal(
psa_pake_operation_t *operation,
psa_pake_step_t step,
uint8_t *output,
size_t output_size,
@ -427,10 +428,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
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 &&
@ -491,15 +489,12 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
{
ret = mbedtls_ecjpake_write_round_one( &operation->ctx.ecjpake,
operation->buffer,
PSA_PAKE_BUFFER_SIZE,
MBEDTLS_PSA_PAKE_BUFFER_SIZE,
&operation->buffer_length,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE );
if( ret != 0 )
{
psa_pake_abort( operation );
return( mbedtls_ecjpake_to_psa_error( ret ) );
}
operation->buffer_offset = 0;
}
@ -508,68 +503,47 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
{
ret = mbedtls_ecjpake_write_round_two( &operation->ctx.ecjpake,
operation->buffer,
PSA_PAKE_BUFFER_SIZE,
MBEDTLS_PSA_PAKE_BUFFER_SIZE,
&operation->buffer_length,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE );
if( ret != 0 )
{
psa_pake_abort( operation );
return( mbedtls_ecjpake_to_psa_error( ret ) );
}
operation->buffer_offset = 0;
}
/*
* Steps sequences are stored as:
* struct {
* opaque point <1..2^8-1>;
* } ECPoint;
* mbedtls_ecjpake_write_round_xxx() outputs thing in the format
* defined by draft-cragie-tls-ecjpake-01 section 7. The summary is
* that the data for each step is prepended with a length byte, and
* then they're concatenated. Additionally, the server's second round
* output is prepended with a 3-bytes ECParameters structure.
*
* 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)
* In PSA, we output each step separately, and don't prepend the
* output with a length byte, even less a curve identifier, as that
* information is already available.
*/
if( operation->state == PSA_PAKE_OUTPUT_X2S &&
operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE )
operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
operation->role == PSA_PAKE_ROLE_SERVER )
{
if( operation->role == PSA_PAKE_ROLE_SERVER )
/*
* 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 = operation->buffer[0] + 1;
/* Skip ECParameters, with is 3 bytes (RFC 8422) */
operation->buffer_offset += 3;
}
else
length = operation->buffer[operation->buffer_offset] + 1;
if( length > operation->buffer_length )
/* Read the length byte then move past it to the data */
length = operation->buffer[operation->buffer_offset];
operation->buffer_offset += 1;
if( operation->buffer_offset + 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,
operation->buffer + operation->buffer_offset,
length );
*output_length = length;
@ -581,7 +555,7 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
( operation->state == PSA_PAKE_OUTPUT_X2S &&
operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) )
{
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
operation->buffer_length = 0;
operation->buffer_offset = 0;
@ -599,14 +573,29 @@ psa_status_t psa_pake_output( psa_pake_operation_t *operation,
return( PSA_ERROR_NOT_SUPPORTED );
}
psa_status_t psa_pake_input( psa_pake_operation_t *operation,
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 )
{
psa_status_t status = psa_pake_output_internal(
operation, step, output, output_size, output_length );
if( status != PSA_SUCCESS )
psa_pake_abort( operation );
return( status );
}
static psa_status_t psa_pake_input_internal(
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 == PSA_ALG_NONE ||
operation->state == PSA_PAKE_STATE_INVALID )
@ -638,14 +627,16 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
step != PSA_PAKE_STEP_ZK_PROOF )
return( PSA_ERROR_INVALID_ARGUMENT );
const psa_pake_primitive_t prim = PSA_PAKE_PRIMITIVE(
PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256 );
if( input_length > (size_t) PSA_PAKE_INPUT_SIZE( PSA_ALG_JPAKE, prim, step ) )
return( PSA_ERROR_INVALID_ARGUMENT );
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 &&
@ -675,15 +666,6 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
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 )
{
@ -709,7 +691,35 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
return( PSA_ERROR_BAD_STATE );
}
/* Copy input to local buffer */
/*
* Copy input to local buffer and format it as the Mbed TLS API
* expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7.
* The summary is that the data for each step is prepended with a
* length byte, and then they're concatenated. Additionally, the
* server's second round output is prepended with a 3-bytes
* ECParameters structure - which means we have to prepend that when
* we're a client.
*/
if( operation->state == PSA_PAKE_INPUT_X4S &&
operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
operation->role == PSA_PAKE_ROLE_CLIENT )
{
/* We only support secp256r1. */
/* This is the ECParameters structure defined by RFC 8422. */
unsigned char ecparameters[3] = {
3, /* named_curve */
0, 23 /* secp256r1 */
};
memcpy( operation->buffer + operation->buffer_length,
ecparameters, sizeof( ecparameters ) );
operation->buffer_length += sizeof( ecparameters );
}
/* Write the length byte */
operation->buffer[operation->buffer_length] = (uint8_t) input_length;
operation->buffer_length += 1;
/* Finally copy the data */
memcpy( operation->buffer + operation->buffer_length,
input, input_length );
operation->buffer_length += input_length;
@ -722,14 +732,11 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
operation->buffer,
operation->buffer_length );
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
operation->buffer_length = 0;
if( ret != 0 )
{
psa_pake_abort( operation );
return( mbedtls_ecjpake_to_psa_error( ret ) );
}
}
else if( operation->state == PSA_PAKE_INPUT_X4S &&
operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF )
@ -738,14 +745,11 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
operation->buffer,
operation->buffer_length );
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
operation->buffer_length = 0;
if( ret != 0 )
{
psa_pake_abort( operation );
return( mbedtls_ecjpake_to_psa_error( ret ) );
}
}
if( ( operation->state == PSA_PAKE_INPUT_X1_X2 &&
@ -767,6 +771,20 @@ psa_status_t psa_pake_input( psa_pake_operation_t *operation,
return( PSA_ERROR_NOT_SUPPORTED );
}
psa_status_t psa_pake_input( psa_pake_operation_t *operation,
psa_pake_step_t step,
const uint8_t *input,
size_t input_length )
{
psa_status_t status = psa_pake_input_internal(
operation, step, input, input_length );
if( status != PSA_SUCCESS )
psa_pake_abort( operation );
return( status );
}
psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
psa_key_derivation_operation_t *output)
{
@ -784,7 +802,7 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
{
ret = mbedtls_ecjpake_write_shared_key( &operation->ctx.ecjpake,
operation->buffer,
PSA_PAKE_BUFFER_SIZE,
MBEDTLS_PSA_PAKE_BUFFER_SIZE,
&operation->buffer_length,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE );
@ -799,7 +817,7 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
operation->buffer,
operation->buffer_length );
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
psa_pake_abort( operation );
@ -824,7 +842,7 @@ psa_status_t psa_pake_abort(psa_pake_operation_t * operation)
operation->output_step = PSA_PAKE_STEP_INVALID;
operation->password = MBEDTLS_SVC_KEY_ID_INIT;
operation->role = PSA_PAKE_ROLE_NONE;
mbedtls_platform_zeroize( operation->buffer, PSA_PAKE_BUFFER_SIZE );
mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
operation->buffer_length = 0;
operation->buffer_offset = 0;
mbedtls_ecjpake_free( &operation->ctx.ecjpake );