quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

psa_crypto_pake.c (20586B)


      1 /*
      2  *  PSA PAKE layer on top of Mbed TLS software crypto
      3  */
      4 /*
      5  *  Copyright The Mbed TLS Contributors
      6  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      7  */
      8 
      9 #include "common.h"
     10 
     11 #if defined(MBEDTLS_PSA_CRYPTO_C)
     12 
     13 #include <psa/crypto.h>
     14 #include "psa_crypto_core.h"
     15 #include "psa_crypto_pake.h"
     16 #include "psa_crypto_slot_management.h"
     17 
     18 #include <mbedtls/ecjpake.h>
     19 #include "psa_util_internal.h"
     20 
     21 #include <mbedtls/platform.h>
     22 #include <mbedtls/error.h>
     23 #include <string.h>
     24 
     25 /*
     26  * State sequence:
     27  *
     28  *   psa_pake_setup()
     29  *   |
     30  *   |-- In any order:
     31  *   |   | psa_pake_set_password_key()
     32  *   |   | psa_pake_set_user()
     33  *   |   | psa_pake_set_peer()
     34  *   |   | psa_pake_set_role()
     35  *   |
     36  *   |--- In any order: (First round input before or after first round output)
     37  *   |   |
     38  *   |   |------ In Order
     39  *   |   |       | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
     40  *   |   |       | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
     41  *   |   |       | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
     42  *   |   |       | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
     43  *   |   |       | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
     44  *   |   |       | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
     45  *   |   |
     46  *   |   |------ In Order:
     47  *   |           | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
     48  *   |           | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
     49  *   |           | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
     50  *   |           | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
     51  *   |           | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
     52  *   |           | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
     53  *   |
     54  *   |--- In any order: (Second round input before or after second round output)
     55  *   |   |
     56  *   |   |------ In Order
     57  *   |   |       | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
     58  *   |   |       | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
     59  *   |   |       | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
     60  *   |   |
     61  *   |   |------ In Order:
     62  *   |           | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
     63  *   |           | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
     64  *   |           | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
     65  *   |
     66  *   psa_pake_get_implicit_key()
     67  *   psa_pake_abort()
     68  */
     69 
     70 /*
     71  * Possible sequence of calls to implementation:
     72  *
     73  * |--- In any order:
     74  * |   |
     75  * |   |------ In Order
     76  * |   |       | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_KEY_SHARE)
     77  * |   |       | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PUBLIC)
     78  * |   |       | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PROOF)
     79  * |   |       | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_KEY_SHARE)
     80  * |   |       | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PUBLIC)
     81  * |   |       | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PROOF)
     82  * |   |
     83  * |   |------ In Order:
     84  * |           | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_KEY_SHARE)
     85  * |           | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PUBLIC)
     86  * |           | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PROOF)
     87  * |           | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_KEY_SHARE)
     88  * |           | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PUBLIC)
     89  * |           | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PROOF)
     90  * |
     91  * |--- In any order:
     92  * |   |
     93  * |   |------ In Order
     94  * |   |       | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_KEY_SHARE)
     95  * |   |       | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PUBLIC)
     96  * |   |       | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PROOF)
     97  * |   |
     98  * |   |------ In Order:
     99  * |           | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_KEY_SHARE)
    100  * |           | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PUBLIC)
    101  * |           | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PROOF)
    102  */
    103 
    104 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
    105 static psa_status_t mbedtls_ecjpake_to_psa_error(int ret)
    106 {
    107     switch (ret) {
    108         case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
    109         case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
    110         case MBEDTLS_ERR_ECP_INVALID_KEY:
    111         case MBEDTLS_ERR_ECP_VERIFY_FAILED:
    112             return PSA_ERROR_DATA_INVALID;
    113         case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
    114         case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
    115             return PSA_ERROR_BUFFER_TOO_SMALL;
    116         case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
    117             return PSA_ERROR_NOT_SUPPORTED;
    118         case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
    119             return PSA_ERROR_CORRUPTION_DETECTED;
    120         default:
    121             return PSA_ERROR_GENERIC_ERROR;
    122     }
    123 }
    124 #endif
    125 
    126 #if defined(MBEDTLS_PSA_BUILTIN_PAKE)
    127 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
    128 static psa_status_t psa_pake_ecjpake_setup(mbedtls_psa_pake_operation_t *operation)
    129 {
    130     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    131 
    132     mbedtls_ecjpake_init(&operation->ctx.jpake);
    133 
    134     ret = mbedtls_ecjpake_setup(&operation->ctx.jpake,
    135                                 operation->role,
    136                                 MBEDTLS_MD_SHA256,
    137                                 MBEDTLS_ECP_DP_SECP256R1,
    138                                 operation->password,
    139                                 operation->password_len);
    140 
    141     mbedtls_platform_zeroize(operation->password, operation->password_len);
    142 
    143     if (ret != 0) {
    144         return mbedtls_ecjpake_to_psa_error(ret);
    145     }
    146 
    147     return PSA_SUCCESS;
    148 }
    149 #endif
    150 
    151 /* The only two JPAKE user/peer identifiers supported in built-in implementation. */
    152 static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
    153 static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };
    154 
    155 psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
    156                                     const psa_crypto_driver_pake_inputs_t *inputs)
    157 {
    158     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    159     size_t user_len = 0, peer_len = 0, password_len = 0;
    160     uint8_t *peer = NULL, *user = NULL;
    161     size_t actual_user_len = 0, actual_peer_len = 0, actual_password_len = 0;
    162     psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
    163 
    164     status = psa_crypto_driver_pake_get_password_len(inputs, &password_len);
    165     if (status != PSA_SUCCESS) {
    166         return status;
    167     }
    168 
    169     status = psa_crypto_driver_pake_get_user_len(inputs, &user_len);
    170     if (status != PSA_SUCCESS) {
    171         return status;
    172     }
    173 
    174     status = psa_crypto_driver_pake_get_peer_len(inputs, &peer_len);
    175     if (status != PSA_SUCCESS) {
    176         return status;
    177     }
    178 
    179     status = psa_crypto_driver_pake_get_cipher_suite(inputs, &cipher_suite);
    180     if (status != PSA_SUCCESS) {
    181         return status;
    182     }
    183 
    184     operation->password = mbedtls_calloc(1, password_len);
    185     if (operation->password == NULL) {
    186         status = PSA_ERROR_INSUFFICIENT_MEMORY;
    187         goto error;
    188     }
    189 
    190     user = mbedtls_calloc(1, user_len);
    191     if (user == NULL) {
    192         status = PSA_ERROR_INSUFFICIENT_MEMORY;
    193         goto error;
    194     }
    195 
    196     peer = mbedtls_calloc(1, peer_len);
    197     if (peer == NULL) {
    198         status = PSA_ERROR_INSUFFICIENT_MEMORY;
    199         goto error;
    200     }
    201 
    202     status = psa_crypto_driver_pake_get_password(inputs, operation->password,
    203                                                  password_len, &actual_password_len);
    204     if (status != PSA_SUCCESS) {
    205         goto error;
    206     }
    207 
    208     status = psa_crypto_driver_pake_get_user(inputs, user,
    209                                              user_len, &actual_user_len);
    210     if (status != PSA_SUCCESS) {
    211         goto error;
    212     }
    213 
    214     status = psa_crypto_driver_pake_get_peer(inputs, peer,
    215                                              peer_len, &actual_peer_len);
    216     if (status != PSA_SUCCESS) {
    217         goto error;
    218     }
    219 
    220     operation->password_len = actual_password_len;
    221     operation->alg = cipher_suite.algorithm;
    222 
    223 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
    224     if (cipher_suite.algorithm == PSA_ALG_JPAKE) {
    225         if (cipher_suite.type != PSA_PAKE_PRIMITIVE_TYPE_ECC ||
    226             cipher_suite.family != PSA_ECC_FAMILY_SECP_R1 ||
    227             cipher_suite.bits != 256 ||
    228             cipher_suite.hash != PSA_ALG_SHA_256) {
    229             status = PSA_ERROR_NOT_SUPPORTED;
    230             goto error;
    231         }
    232 
    233         const size_t user_peer_len = sizeof(jpake_client_id); // client and server have the same length
    234         if (actual_user_len != user_peer_len ||
    235             actual_peer_len != user_peer_len) {
    236             status = PSA_ERROR_NOT_SUPPORTED;
    237             goto error;
    238         }
    239 
    240         if (memcmp(user, jpake_client_id, actual_user_len) == 0 &&
    241             memcmp(peer, jpake_server_id, actual_peer_len) == 0) {
    242             operation->role = MBEDTLS_ECJPAKE_CLIENT;
    243         } else
    244         if (memcmp(user, jpake_server_id, actual_user_len) == 0 &&
    245             memcmp(peer, jpake_client_id, actual_peer_len) == 0) {
    246             operation->role = MBEDTLS_ECJPAKE_SERVER;
    247         } else {
    248             status = PSA_ERROR_NOT_SUPPORTED;
    249             goto error;
    250         }
    251 
    252         operation->buffer_length = 0;
    253         operation->buffer_offset = 0;
    254 
    255         status = psa_pake_ecjpake_setup(operation);
    256         if (status != PSA_SUCCESS) {
    257             goto error;
    258         }
    259 
    260         /* Role has been set, release user/peer buffers. */
    261         mbedtls_free(user); mbedtls_free(peer);
    262 
    263         return PSA_SUCCESS;
    264     } else
    265 #else
    266     (void) operation;
    267     (void) inputs;
    268 #endif
    269     { status = PSA_ERROR_NOT_SUPPORTED; }
    270 
    271 error:
    272     mbedtls_free(user); mbedtls_free(peer);
    273     /* In case of failure of the setup of a multipart operation, the PSA driver interface
    274      * specifies that the core does not call any other driver entry point thus does not
    275      * call mbedtls_psa_pake_abort(). Therefore call it here to do the needed clean
    276      * up like freeing the memory that may have been allocated to store the password.
    277      */
    278     mbedtls_psa_pake_abort(operation);
    279     return status;
    280 }
    281 
    282 static psa_status_t mbedtls_psa_pake_output_internal(
    283     mbedtls_psa_pake_operation_t *operation,
    284     psa_crypto_driver_pake_step_t step,
    285     uint8_t *output,
    286     size_t output_size,
    287     size_t *output_length)
    288 {
    289     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    290     size_t length;
    291     (void) step; // Unused parameter
    292 
    293 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
    294     /*
    295      * The PSA CRYPTO PAKE and Mbed TLS JPAKE API have a different
    296      * handling of output sequencing.
    297      *
    298      * The Mbed TLS JPAKE API outputs the whole X1+X2 and X2S steps data
    299      * at once, on the other side the PSA CRYPTO PAKE api requires
    300      * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X2S to be
    301      * retrieved in sequence.
    302      *
    303      * In order to achieve API compatibility, the whole X1+X2 or X2S steps
    304      * data is stored in an intermediate buffer at first step output call,
    305      * and data is sliced down by parsing the ECPoint records in order
    306      * to return the right parts on each step.
    307      */
    308     if (operation->alg == PSA_ALG_JPAKE) {
    309         /* Initialize & write round on KEY_SHARE sequences */
    310         if (step == PSA_JPAKE_X1_STEP_KEY_SHARE) {
    311             ret = mbedtls_ecjpake_write_round_one(&operation->ctx.jpake,
    312                                                   operation->buffer,
    313                                                   sizeof(operation->buffer),
    314                                                   &operation->buffer_length,
    315                                                   mbedtls_psa_get_random,
    316                                                   MBEDTLS_PSA_RANDOM_STATE);
    317             if (ret != 0) {
    318                 return mbedtls_ecjpake_to_psa_error(ret);
    319             }
    320 
    321             operation->buffer_offset = 0;
    322         } else if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE) {
    323             ret = mbedtls_ecjpake_write_round_two(&operation->ctx.jpake,
    324                                                   operation->buffer,
    325                                                   sizeof(operation->buffer),
    326                                                   &operation->buffer_length,
    327                                                   mbedtls_psa_get_random,
    328                                                   MBEDTLS_PSA_RANDOM_STATE);
    329             if (ret != 0) {
    330                 return mbedtls_ecjpake_to_psa_error(ret);
    331             }
    332 
    333             operation->buffer_offset = 0;
    334         }
    335 
    336         /*
    337          * mbedtls_ecjpake_write_round_xxx() outputs thing in the format
    338          * defined by draft-cragie-tls-ecjpake-01 section 7. The summary is
    339          * that the data for each step is prepended with a length byte, and
    340          * then they're concatenated. Additionally, the server's second round
    341          * output is prepended with a 3-bytes ECParameters structure.
    342          *
    343          * In PSA, we output each step separately, and don't prepend the
    344          * output with a length byte, even less a curve identifier, as that
    345          * information is already available.
    346          */
    347         if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE &&
    348             operation->role == MBEDTLS_ECJPAKE_SERVER) {
    349             /* Skip ECParameters, with is 3 bytes (RFC 8422) */
    350             operation->buffer_offset += 3;
    351         }
    352 
    353         /* Read the length byte then move past it to the data */
    354         length = operation->buffer[operation->buffer_offset];
    355         operation->buffer_offset += 1;
    356 
    357         if (operation->buffer_offset + length > operation->buffer_length) {
    358             return PSA_ERROR_DATA_CORRUPT;
    359         }
    360 
    361         if (output_size < length) {
    362             return PSA_ERROR_BUFFER_TOO_SMALL;
    363         }
    364 
    365         memcpy(output,
    366                operation->buffer + operation->buffer_offset,
    367                length);
    368         *output_length = length;
    369 
    370         operation->buffer_offset += length;
    371 
    372         /* Reset buffer after ZK_PROOF sequence */
    373         if ((step == PSA_JPAKE_X2_STEP_ZK_PROOF) ||
    374             (step == PSA_JPAKE_X2S_STEP_ZK_PROOF)) {
    375             mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
    376             operation->buffer_length = 0;
    377             operation->buffer_offset = 0;
    378         }
    379 
    380         return PSA_SUCCESS;
    381     } else
    382 #else
    383     (void) step;
    384     (void) output;
    385     (void) output_size;
    386     (void) output_length;
    387 #endif
    388     { return PSA_ERROR_NOT_SUPPORTED; }
    389 }
    390 
    391 psa_status_t mbedtls_psa_pake_output(mbedtls_psa_pake_operation_t *operation,
    392                                      psa_crypto_driver_pake_step_t step,
    393                                      uint8_t *output,
    394                                      size_t output_size,
    395                                      size_t *output_length)
    396 {
    397     psa_status_t status = mbedtls_psa_pake_output_internal(
    398         operation, step, output, output_size, output_length);
    399 
    400     return status;
    401 }
    402 
    403 static psa_status_t mbedtls_psa_pake_input_internal(
    404     mbedtls_psa_pake_operation_t *operation,
    405     psa_crypto_driver_pake_step_t step,
    406     const uint8_t *input,
    407     size_t input_length)
    408 {
    409     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    410     (void) step; // Unused parameter
    411 
    412 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
    413     /*
    414      * The PSA CRYPTO PAKE and Mbed TLS JPAKE API have a different
    415      * handling of input sequencing.
    416      *
    417      * The Mbed TLS JPAKE API takes the whole X1+X2 or X4S steps data
    418      * at once as input, on the other side the PSA CRYPTO PAKE api requires
    419      * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X4S to be
    420      * given in sequence.
    421      *
    422      * In order to achieve API compatibility, each X1+X2 or X4S step data
    423      * is stored sequentially in an intermediate buffer and given to the
    424      * Mbed TLS JPAKE API on the last step.
    425      *
    426      * This causes any input error to be only detected on the last step.
    427      */
    428     if (operation->alg == PSA_ALG_JPAKE) {
    429         /*
    430          * Copy input to local buffer and format it as the Mbed TLS API
    431          * expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7.
    432          * The summary is that the data for each step is prepended with a
    433          * length byte, and then they're concatenated. Additionally, the
    434          * server's second round output is prepended with a 3-bytes
    435          * ECParameters structure - which means we have to prepend that when
    436          * we're a client.
    437          */
    438         if (step == PSA_JPAKE_X4S_STEP_KEY_SHARE &&
    439             operation->role == MBEDTLS_ECJPAKE_CLIENT) {
    440             /* We only support secp256r1. */
    441             /* This is the ECParameters structure defined by RFC 8422. */
    442             unsigned char ecparameters[3] = {
    443                 3, /* named_curve */
    444                 0, 23 /* secp256r1 */
    445             };
    446 
    447             if (operation->buffer_length + sizeof(ecparameters) >
    448                 sizeof(operation->buffer)) {
    449                 return PSA_ERROR_BUFFER_TOO_SMALL;
    450             }
    451 
    452             memcpy(operation->buffer + operation->buffer_length,
    453                    ecparameters, sizeof(ecparameters));
    454             operation->buffer_length += sizeof(ecparameters);
    455         }
    456 
    457         /*
    458          * The core checks that input_length is smaller than
    459          * PSA_PAKE_INPUT_MAX_SIZE.
    460          * Thus no risk of integer overflow here.
    461          */
    462         if (operation->buffer_length + input_length + 1 > sizeof(operation->buffer)) {
    463             return PSA_ERROR_BUFFER_TOO_SMALL;
    464         }
    465 
    466         /* Write the length byte */
    467         operation->buffer[operation->buffer_length] = (uint8_t) input_length;
    468         operation->buffer_length += 1;
    469 
    470         /* Finally copy the data */
    471         memcpy(operation->buffer + operation->buffer_length,
    472                input, input_length);
    473         operation->buffer_length += input_length;
    474 
    475         /* Load buffer at each last round ZK_PROOF */
    476         if (step == PSA_JPAKE_X2_STEP_ZK_PROOF) {
    477             ret = mbedtls_ecjpake_read_round_one(&operation->ctx.jpake,
    478                                                  operation->buffer,
    479                                                  operation->buffer_length);
    480 
    481             mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
    482             operation->buffer_length = 0;
    483 
    484             if (ret != 0) {
    485                 return mbedtls_ecjpake_to_psa_error(ret);
    486             }
    487         } else if (step == PSA_JPAKE_X4S_STEP_ZK_PROOF) {
    488             ret = mbedtls_ecjpake_read_round_two(&operation->ctx.jpake,
    489                                                  operation->buffer,
    490                                                  operation->buffer_length);
    491 
    492             mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
    493             operation->buffer_length = 0;
    494 
    495             if (ret != 0) {
    496                 return mbedtls_ecjpake_to_psa_error(ret);
    497             }
    498         }
    499 
    500         return PSA_SUCCESS;
    501     } else
    502 #else
    503     (void) step;
    504     (void) input;
    505     (void) input_length;
    506 #endif
    507     { return PSA_ERROR_NOT_SUPPORTED; }
    508 }
    509 
    510 psa_status_t mbedtls_psa_pake_input(mbedtls_psa_pake_operation_t *operation,
    511                                     psa_crypto_driver_pake_step_t step,
    512                                     const uint8_t *input,
    513                                     size_t input_length)
    514 {
    515     psa_status_t status = mbedtls_psa_pake_input_internal(
    516         operation, step, input, input_length);
    517 
    518     return status;
    519 }
    520 
    521 psa_status_t mbedtls_psa_pake_get_implicit_key(
    522     mbedtls_psa_pake_operation_t *operation,
    523     uint8_t *output, size_t output_size,
    524     size_t *output_length)
    525 {
    526     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    527 
    528 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
    529     if (operation->alg == PSA_ALG_JPAKE) {
    530         ret = mbedtls_ecjpake_write_shared_key(&operation->ctx.jpake,
    531                                                output,
    532                                                output_size,
    533                                                output_length,
    534                                                mbedtls_psa_get_random,
    535                                                MBEDTLS_PSA_RANDOM_STATE);
    536         if (ret != 0) {
    537             return mbedtls_ecjpake_to_psa_error(ret);
    538         }
    539 
    540         return PSA_SUCCESS;
    541     } else
    542 #else
    543     (void) output;
    544 #endif
    545     { return PSA_ERROR_NOT_SUPPORTED; }
    546 }
    547 
    548 psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation)
    549 {
    550     mbedtls_zeroize_and_free(operation->password, operation->password_len);
    551     operation->password = NULL;
    552     operation->password_len = 0;
    553 
    554 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
    555     if (operation->alg == PSA_ALG_JPAKE) {
    556         operation->role = MBEDTLS_ECJPAKE_NONE;
    557         mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
    558         operation->buffer_length = 0;
    559         operation->buffer_offset = 0;
    560         mbedtls_ecjpake_free(&operation->ctx.jpake);
    561     }
    562 #endif
    563 
    564     operation->alg = PSA_ALG_NONE;
    565 
    566     return PSA_SUCCESS;
    567 }
    568 
    569 #endif /* MBEDTLS_PSA_BUILTIN_PAKE */
    570 
    571 #endif /* MBEDTLS_PSA_CRYPTO_C */