/*
 *  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 <psa/crypto.h>
#include "psa_crypto_core.h"
#include "psa_crypto_slot_management.h"

#include <mbedtls/ecjpake.h>
#include <mbedtls/psa_util.h>

#include <mbedtls/platform.h>
#include <mbedtls/error.h>
#include <string.h>

/*
 * 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,
};

/*
 * 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.
 * 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,
    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_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)
{
    /* A context must be freshly initialized before it can be set up. */
    if( operation->alg != PSA_ALG_NONE )
        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_JPAKE)
    if( cipher_suite->algorithm == PSA_ALG_JPAKE )
    {
        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;

        mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
        operation->buffer_length = 0;
        operation->buffer_offset = 0;

        return( PSA_SUCCESS );
    }
    else
#endif
    return( PSA_ERROR_NOT_SUPPORTED );
}

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;
    psa_key_slot_t *slot = NULL;

    if( operation->alg == PSA_ALG_NONE ||
        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 & PSA_KEY_USAGE_DERIVE ) == 0 )
        return( PSA_ERROR_NOT_PERMITTED );

    if( operation->password != NULL )
        return( PSA_ERROR_BAD_STATE );

    status = psa_get_and_lock_key_slot_with_policy( password, &slot,
                                                    PSA_KEY_USAGE_DERIVE,
                                                    PSA_ALG_JPAKE );
    if( status != PSA_SUCCESS )
        return( status );

    operation->password = mbedtls_calloc( 1, slot->key.bytes );
    if( operation->password == NULL )
    {
        psa_unlock_key_slot( slot );
        return( PSA_ERROR_INSUFFICIENT_MEMORY );
    }
    memcpy( operation->password, slot->key.data, slot->key.bytes );
    operation->password_len = slot->key.bytes;

    status = psa_unlock_key_slot( slot );
    if( status != PSA_SUCCESS )
        return( status );

    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 == PSA_ALG_NONE ||
        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 == PSA_ALG_NONE ||
        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 == PSA_ALG_NONE ||
        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_JPAKE)
    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_JPAKE)
static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_ecjpake_role role;

    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( operation->password_len == 0 )
        return( PSA_ERROR_BAD_STATE );

    ret = mbedtls_ecjpake_setup( &operation->ctx.ecjpake,
                                 role,
                                 MBEDTLS_MD_SHA256,
                                 MBEDTLS_ECP_DP_SECP256R1,
                                 operation->password,
                                 operation->password_len );

    mbedtls_platform_zeroize( operation->password, operation->password_len );
    mbedtls_free( operation->password );
    operation->password = NULL;
    operation->password_len = 0;

    if( ret != 0 )
        return( mbedtls_ecjpake_to_psa_error( ret ) );

    operation->state = PSA_PAKE_STATE_READY;

    return( PSA_SUCCESS );
}
#endif

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,
                              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 == PSA_ALG_NONE ||
        operation->state == PSA_PAKE_STATE_INVALID )
        return( PSA_ERROR_BAD_STATE );

    if( output == NULL || output_size == 0 || output_length == NULL )
        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 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.
     *
     * 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 &&
            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 )
                return( status );
        }

        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,
                                                   MBEDTLS_PSA_PAKE_BUFFER_SIZE,
                                                   &operation->buffer_length,
                                                   mbedtls_psa_get_random,
                                                   MBEDTLS_PSA_RANDOM_STATE );
            if( ret != 0 )
                return( mbedtls_ecjpake_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,
                                                   MBEDTLS_PSA_PAKE_BUFFER_SIZE,
                                                   &operation->buffer_length,
                                                   mbedtls_psa_get_random,
                                                   MBEDTLS_PSA_RANDOM_STATE );
            if( ret != 0 )
                return( mbedtls_ecjpake_to_psa_error( ret ) );

            operation->buffer_offset = 0;
        }

        /*
         * 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.
         *
         * 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->role == PSA_PAKE_ROLE_SERVER )
        {
            /* Skip ECParameters, with is 3 bytes (RFC 8422) */
            operation->buffer_offset += 3;
        }

        /* 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 )
            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, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
            operation->buffer_length = 0;
            operation->buffer_offset = 0;

            operation->state = PSA_PAKE_STATE_READY;
            operation->output_step++;
            operation->sequence = PSA_PAKE_SEQ_INVALID;
        }
        else
            operation->sequence++;

        return( PSA_SUCCESS );
    }
    else
#endif
    return( PSA_ERROR_NOT_SUPPORTED );
}

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;

    if( operation->alg == PSA_ALG_NONE ||
        operation->state == PSA_PAKE_STATE_INVALID )
        return( PSA_ERROR_BAD_STATE );

    if( input == NULL || input_length == 0 )
        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 &&
            step != PSA_PAKE_STEP_ZK_PUBLIC &&
            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 )
                return( status );
        }

        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;
        }

        /* 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 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;

        /* 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, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
            operation->buffer_length = 0;

            if( ret != 0 )
                return( mbedtls_ecjpake_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, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
            operation->buffer_length = 0;

            if( ret != 0 )
                return( mbedtls_ecjpake_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 = PSA_PAKE_SEQ_INVALID;
        }
        else
            operation->sequence++;

        return( PSA_SUCCESS );
    }
    else
#endif
    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)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

    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 )
        return( PSA_ERROR_BAD_STATE );

#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
    if( operation->alg == PSA_ALG_JPAKE )
    {
        ret = mbedtls_ecjpake_write_shared_key( &operation->ctx.ecjpake,
                                                operation->buffer,
                                                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 ) );
        }

        status = psa_key_derivation_input_bytes( output,
                                                 PSA_KEY_DERIVATION_INPUT_SECRET,
                                                 operation->buffer,
                                                 operation->buffer_length );

        mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );

        psa_pake_abort( operation );

        return( status );
    }
    else
#endif
    return( PSA_ERROR_NOT_SUPPORTED );
}

psa_status_t psa_pake_abort(psa_pake_operation_t * operation)
{
    if( operation->alg == PSA_ALG_NONE )
    {
        return( PSA_SUCCESS );
    }

#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
    if( operation->alg == PSA_ALG_JPAKE )
    {
        operation->input_step = PSA_PAKE_STEP_INVALID;
        operation->output_step = PSA_PAKE_STEP_INVALID;
        if( operation->password_len > 0 )
            mbedtls_platform_zeroize( operation->password, operation->password_len );
        mbedtls_free( operation->password );
        operation->password = NULL;
        operation->password_len = 0;
        operation->role = PSA_PAKE_ROLE_NONE;
        mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
        operation->buffer_length = 0;
        operation->buffer_offset = 0;
        mbedtls_ecjpake_free( &operation->ctx.ecjpake );
    }
#endif

    operation->alg = PSA_ALG_NONE;
    operation->state = PSA_PAKE_STATE_INVALID;
    operation->sequence = PSA_PAKE_SEQ_INVALID;

    return( PSA_SUCCESS );
}

#endif /* MBEDTLS_PSA_BUILTIN_PAKE */

#endif /* MBEDTLS_PSA_CRYPTO_C */
