/*
 *  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)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

    /* A context must be freshly initialized before it can be set up. */
    if (operation->alg != PSA_ALG_NONE) {
        status = PSA_ERROR_BAD_STATE;
        goto error;
    }

    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) {
        status = PSA_ERROR_INVALID_ARGUMENT;
        goto error;
    }

#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) {
            status = PSA_ERROR_NOT_SUPPORTED;
            goto error;
        }

        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
    status = PSA_ERROR_NOT_SUPPORTED;

error:
    psa_pake_abort(operation);
    return status;
}

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) {
        status = PSA_ERROR_BAD_STATE;
        goto error;
    }

    status = psa_get_key_attributes(password, &attributes);
    if (status != PSA_SUCCESS) {
        goto error;
    }

    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) {
        status = PSA_ERROR_INVALID_ARGUMENT;
        goto error;
    }

    if ((usage & PSA_KEY_USAGE_DERIVE) == 0) {
        status = PSA_ERROR_NOT_PERMITTED;
        goto error;
    }

    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;

error:
    psa_pake_abort(operation);
    return status;
}

psa_status_t psa_pake_set_user(psa_pake_operation_t *operation,
                               const uint8_t *user_id,
                               size_t user_id_len)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

    if (operation->alg == PSA_ALG_NONE ||
        operation->state != PSA_PAKE_STATE_SETUP) {
        status = PSA_ERROR_BAD_STATE;
        goto error;
    }

    if (user_id_len == 0 || user_id == NULL) {
        status = PSA_ERROR_INVALID_ARGUMENT;
        goto error;
    }

    status = PSA_ERROR_NOT_SUPPORTED;

error:
    psa_pake_abort(operation);
    return status;
}

psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation,
                               const uint8_t *peer_id,
                               size_t peer_id_len)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

    if (operation->alg == PSA_ALG_NONE ||
        operation->state != PSA_PAKE_STATE_SETUP) {
        status = PSA_ERROR_BAD_STATE;
        goto error;
    }

    if (peer_id_len == 0 || peer_id == NULL) {
        status = PSA_ERROR_INVALID_ARGUMENT;
        goto error;
    }

    status = PSA_ERROR_NOT_SUPPORTED;

error:
    psa_pake_abort(operation);
    return status;
}

psa_status_t psa_pake_set_role(psa_pake_operation_t *operation,
                               psa_pake_role_t role)
{
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

    if (operation->alg == PSA_ALG_NONE ||
        operation->state != PSA_PAKE_STATE_SETUP) {
        status = PSA_ERROR_BAD_STATE;
        goto error;
    }

    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) {
        status = PSA_ERROR_INVALID_ARGUMENT;
        goto error;
    }

#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
    status = PSA_ERROR_NOT_SUPPORTED;

error:
    psa_pake_abort(operation);
    return status;
}

#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) {
        status = PSA_ERROR_BAD_STATE;
        goto error;
    }

#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
    status = PSA_ERROR_NOT_SUPPORTED;

error:
    psa_key_derivation_abort(output);
    psa_pake_abort(operation);

    return status;
}

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