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