blob: 1deb48875f354045092e6110530393f53e38d5b8 [file] [log] [blame]
Neil Armstronga4cc7d62022-05-25 11:30:48 +02001/*
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_slot_management.h"
28
29#include <mbedtls/ecjpake.h>
30#include <mbedtls/psa_util.h>
31
32#include <mbedtls/platform.h>
33#include <mbedtls/error.h>
34#include <string.h>
35
Przemek Stekiel348410f2022-11-15 22:22:07 +010036extern psa_status_t psa_get_and_lock_key_slot_with_policy(
37 mbedtls_svc_key_id_t key,
38 psa_key_slot_t **p_slot,
39 psa_key_usage_t usage,
40 psa_algorithm_t alg );
Neil Armstronga4cc7d62022-05-25 11:30:48 +020041/*
42 * State sequence:
43 *
44 * psa_pake_setup()
45 * |
46 * |-- In any order:
47 * | | psa_pake_set_password_key()
48 * | | psa_pake_set_user()
49 * | | psa_pake_set_peer()
Neil Armstrongc29f8472022-06-08 13:34:49 +020050 * | | psa_pake_set_role()
Neil Armstronga4cc7d62022-05-25 11:30:48 +020051 * |
52 * |--- In any order: (First round input before or after first round output)
53 * | |
54 * | |------ In Order
55 * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
56 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
57 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
58 * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
59 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
60 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
61 * | |
62 * | |------ In Order:
63 * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
64 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
65 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
66 * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
67 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
68 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
69 * |
70 * |--- In any order: (Second round input before or after second round output)
71 * | |
72 * | |------ In Order
73 * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
74 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
75 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
76 * | |
77 * | |------ In Order:
78 * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
79 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
80 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
81 * |
82 * psa_pake_get_implicit_key()
83 * psa_pake_abort()
84 */
85
86enum psa_pake_step
87{
88 PSA_PAKE_STEP_INVALID = 0,
89 PSA_PAKE_STEP_X1_X2 = 1,
90 PSA_PAKE_STEP_X2S = 2,
91 PSA_PAKE_STEP_DERIVE = 3,
92};
93
94enum psa_pake_state
95{
96 PSA_PAKE_STATE_INVALID = 0,
97 PSA_PAKE_STATE_SETUP = 1,
98 PSA_PAKE_STATE_READY = 2,
99 PSA_PAKE_OUTPUT_X1_X2 = 3,
100 PSA_PAKE_OUTPUT_X2S = 4,
101 PSA_PAKE_INPUT_X1_X2 = 5,
102 PSA_PAKE_INPUT_X4S = 6,
103};
104
Neil Armstrongbcd5bd92022-09-05 18:33:23 +0200105/*
106 * The first PAKE step shares the same sequences of the second PAKE step
107 * but with a second set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs.
Neil Armstrongb39833c2022-09-06 11:36:02 +0200108 * It's simpler to share the same sequences numbers of the first
Neil Armstrongbcd5bd92022-09-05 18:33:23 +0200109 * set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs in both PAKE steps.
110 *
111 * State sequence with step, state & sequence enums:
112 * => Input & Output Step = PSA_PAKE_STEP_INVALID
113 * => state = PSA_PAKE_STATE_INVALID
114 * psa_pake_setup()
115 * => Input & Output Step = PSA_PAKE_STEP_X1_X2
116 * => state = PSA_PAKE_STATE_SETUP
117 * => sequence = PSA_PAKE_SEQ_INVALID
118 * |
119 * |--- In any order: (First round input before or after first round output)
120 * | | First call of psa_pake_output() or psa_pake_input() sets
121 * | | state = PSA_PAKE_STATE_READY
122 * | |
123 * | |------ In Order: => state = PSA_PAKE_OUTPUT_X1_X2
124 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
125 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
126 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
127 * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE
128 * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC
129 * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF
130 * | | | => state = PSA_PAKE_STATE_READY
131 * | | | => sequence = PSA_PAKE_SEQ_INVALID
Neil Armstrong9720b882022-09-06 11:39:21 +0200132 * | | | => Output Step = PSA_PAKE_STEP_X2S
Neil Armstrongbcd5bd92022-09-05 18:33:23 +0200133 * | |
134 * | |------ In Order: => state = PSA_PAKE_INPUT_X1_X2
135 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
136 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
137 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
138 * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE
139 * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC
140 * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF
141 * | | | => state = PSA_PAKE_STATE_READY
142 * | | | => sequence = PSA_PAKE_SEQ_INVALID
Neil Armstrong9720b882022-09-06 11:39:21 +0200143 * | | | => Output Step = PSA_PAKE_INPUT_X4S
Neil Armstrongbcd5bd92022-09-05 18:33:23 +0200144 * |
145 * |--- In any order: (Second round input before or after second round output)
146 * | |
147 * | |------ In Order: => state = PSA_PAKE_OUTPUT_X2S
148 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
149 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
150 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
151 * | | | => state = PSA_PAKE_STATE_READY
152 * | | | => sequence = PSA_PAKE_SEQ_INVALID
Neil Armstrong9720b882022-09-06 11:39:21 +0200153 * | | | => Output Step = PSA_PAKE_STEP_DERIVE
Neil Armstrongbcd5bd92022-09-05 18:33:23 +0200154 * | |
155 * | |------ In Order: => state = PSA_PAKE_INPUT_X4S
156 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
157 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
158 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
159 * | | | => state = PSA_PAKE_STATE_READY
160 * | | | => sequence = PSA_PAKE_SEQ_INVALID
Neil Armstrong9720b882022-09-06 11:39:21 +0200161 * | | | => Output Step = PSA_PAKE_STEP_DERIVE
Neil Armstrongbcd5bd92022-09-05 18:33:23 +0200162 * |
163 * psa_pake_get_implicit_key()
164 * => Input & Output Step = PSA_PAKE_STEP_INVALID
165 */
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200166enum psa_pake_sequence
167{
168 PSA_PAKE_SEQ_INVALID = 0,
169 PSA_PAKE_X1_STEP_KEY_SHARE = 1, /* also X2S & X4S KEY_SHARE */
170 PSA_PAKE_X1_STEP_ZK_PUBLIC = 2, /* also X2S & X4S ZK_PUBLIC */
171 PSA_PAKE_X1_STEP_ZK_PROOF = 3, /* also X2S & X4S ZK_PROOF */
172 PSA_PAKE_X2_STEP_KEY_SHARE = 4,
173 PSA_PAKE_X2_STEP_ZK_PUBLIC = 5,
174 PSA_PAKE_X2_STEP_ZK_PROOF = 6,
175 PSA_PAKE_SEQ_END = 7,
176};
177
Neil Armstrongdb05cbf2022-06-15 15:25:45 +0200178#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
179static psa_status_t mbedtls_ecjpake_to_psa_error( int ret )
180{
181 switch( ret )
182 {
183 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
184 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
185 case MBEDTLS_ERR_ECP_INVALID_KEY:
186 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
187 return( PSA_ERROR_DATA_INVALID );
188 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
189 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
190 return( PSA_ERROR_BUFFER_TOO_SMALL );
191 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
192 return( PSA_ERROR_NOT_SUPPORTED );
193 case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
194 return( PSA_ERROR_CORRUPTION_DETECTED );
195 default:
196 return( PSA_ERROR_GENERIC_ERROR );
197 }
198}
199#endif
200
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200201#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
202psa_status_t psa_pake_setup( psa_pake_operation_t *operation,
203 const psa_pake_cipher_suite_t *cipher_suite)
204{
205 /* A context must be freshly initialized before it can be set up. */
Neil Armstrongcb679f22022-09-13 14:43:07 +0200206 if( operation->alg != PSA_ALG_NONE )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200207 return( PSA_ERROR_BAD_STATE );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200208
209 if( cipher_suite == NULL ||
210 PSA_ALG_IS_PAKE(cipher_suite->algorithm ) == 0 ||
211 ( cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC &&
212 cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_DH ) ||
213 PSA_ALG_IS_HASH( cipher_suite->hash ) == 0 )
214 {
215 return( PSA_ERROR_INVALID_ARGUMENT );
216 }
217
Neil Armstronga557cb82022-06-10 08:58:32 +0200218#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200219 if( cipher_suite->algorithm == PSA_ALG_JPAKE )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200220 {
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200221 if( cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC ||
222 cipher_suite->family != PSA_ECC_FAMILY_SECP_R1 ||
223 cipher_suite->bits != 256 ||
224 cipher_suite->hash != PSA_ALG_SHA_256 )
225 {
226 return( PSA_ERROR_NOT_SUPPORTED );
227 }
228
229 operation->alg = cipher_suite->algorithm;
230
231 mbedtls_ecjpake_init( &operation->ctx.ecjpake );
232
233 operation->state = PSA_PAKE_STATE_SETUP;
234 operation->sequence = PSA_PAKE_SEQ_INVALID;
235 operation->input_step = PSA_PAKE_STEP_X1_X2;
236 operation->output_step = PSA_PAKE_STEP_X1_X2;
237
Manuel Pégourié-Gonnard79617d92022-10-05 12:55:50 +0200238 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200239 operation->buffer_length = 0;
240 operation->buffer_offset = 0;
241
242 return( PSA_SUCCESS );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200243 }
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200244 else
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200245#endif
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200246 return( PSA_ERROR_NOT_SUPPORTED );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200247}
248
249psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation,
250 mbedtls_svc_key_id_t password )
251{
252 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
253 psa_key_attributes_t attributes = psa_key_attributes_init();
254 psa_key_type_t type;
255 psa_key_usage_t usage;
Przemek Stekiel348410f2022-11-15 22:22:07 +0100256 psa_key_slot_t *slot = NULL;
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200257
Neil Armstrongcb679f22022-09-13 14:43:07 +0200258 if( operation->alg == PSA_ALG_NONE ||
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200259 operation->state != PSA_PAKE_STATE_SETUP )
260 {
261 return( PSA_ERROR_BAD_STATE );
262 }
263
Przemek Stekiel348410f2022-11-15 22:22:07 +0100264 if( psa_is_valid_key_id( password, 1 ) == 0 )
265 return( PSA_ERROR_BAD_STATE );
266
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200267 status = psa_get_key_attributes( password, &attributes );
268 if( status != PSA_SUCCESS )
Neil Armstronge9231112022-06-10 09:03:41 +0200269 return( status );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200270
271 type = psa_get_key_type( &attributes );
272 usage = psa_get_key_usage_flags( &attributes );
273
274 psa_reset_key_attributes( &attributes );
275
276 if( type != PSA_KEY_TYPE_PASSWORD &&
277 type != PSA_KEY_TYPE_PASSWORD_HASH )
278 {
Neil Armstronge9231112022-06-10 09:03:41 +0200279 return( PSA_ERROR_INVALID_ARGUMENT );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200280 }
281
Neil Armstrongdf598ab2022-06-08 17:17:08 +0200282 if( ( usage & PSA_KEY_USAGE_DERIVE ) == 0 )
Neil Armstronge9231112022-06-10 09:03:41 +0200283 return( PSA_ERROR_NOT_PERMITTED );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200284
Przemek Stekiel348410f2022-11-15 22:22:07 +0100285 status = psa_get_and_lock_key_slot_with_policy( password, &slot,
286 PSA_KEY_USAGE_DERIVE,
287 PSA_ALG_JPAKE );
288 if( status != PSA_SUCCESS )
289 return( status );
290
291 if( slot->key.data == NULL || slot->key.bytes == 0 )
292 return( PSA_ERROR_INVALID_ARGUMENT );
293
294 if( operation->password_data != NULL )
295 {
296 mbedtls_free( operation->password_data );
297 operation->password_bytes = 0;
298 }
299
300 operation->password_data = mbedtls_calloc( 1, slot->key.bytes );
301 if( operation->password_data == NULL )
302 {
303 status = psa_unlock_key_slot( slot );
304 return( PSA_ERROR_INSUFFICIENT_MEMORY );
305 }
306 memcpy( operation->password_data, slot->key.data, slot->key.bytes );
307 operation->password_bytes = slot->key.bytes;
308
309 status = psa_unlock_key_slot( slot );
310 if( status != PSA_SUCCESS )
311 return( status );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200312
313 return( PSA_SUCCESS );
314}
315
316psa_status_t psa_pake_set_user( psa_pake_operation_t *operation,
317 const uint8_t *user_id,
318 size_t user_id_len )
319{
Neil Armstrongcb679f22022-09-13 14:43:07 +0200320 if( operation->alg == PSA_ALG_NONE ||
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200321 operation->state != PSA_PAKE_STATE_SETUP )
322 {
323 return( PSA_ERROR_BAD_STATE );
324 }
325
326 if( user_id_len == 0 || user_id == NULL )
Neil Armstronge9231112022-06-10 09:03:41 +0200327 return( PSA_ERROR_INVALID_ARGUMENT );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200328
329 return( PSA_ERROR_NOT_SUPPORTED );
330}
331
332psa_status_t psa_pake_set_peer( psa_pake_operation_t *operation,
333 const uint8_t *peer_id,
334 size_t peer_id_len )
335{
Neil Armstrongcb679f22022-09-13 14:43:07 +0200336 if( operation->alg == PSA_ALG_NONE ||
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200337 operation->state != PSA_PAKE_STATE_SETUP )
338 {
339 return( PSA_ERROR_BAD_STATE );
340 }
341
342 if( peer_id_len == 0 || peer_id == NULL )
Neil Armstronge9231112022-06-10 09:03:41 +0200343 return( PSA_ERROR_INVALID_ARGUMENT );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200344
345 return( PSA_ERROR_NOT_SUPPORTED );
346}
347
348psa_status_t psa_pake_set_role( psa_pake_operation_t *operation,
349 psa_pake_role_t role )
350{
Neil Armstrongcb679f22022-09-13 14:43:07 +0200351 if( operation->alg == PSA_ALG_NONE ||
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200352 operation->state != PSA_PAKE_STATE_SETUP )
353 {
354 return( PSA_ERROR_BAD_STATE );
355 }
356
357 if( role != PSA_PAKE_ROLE_NONE &&
358 role != PSA_PAKE_ROLE_FIRST &&
359 role != PSA_PAKE_ROLE_SECOND &&
360 role != PSA_PAKE_ROLE_CLIENT &&
361 role != PSA_PAKE_ROLE_SERVER )
362 {
Neil Armstronge9231112022-06-10 09:03:41 +0200363 return( PSA_ERROR_INVALID_ARGUMENT );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200364 }
365
Neil Armstronga557cb82022-06-10 08:58:32 +0200366#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200367 if( operation->alg == PSA_ALG_JPAKE )
368 {
369 if( role != PSA_PAKE_ROLE_CLIENT &&
370 role != PSA_PAKE_ROLE_SERVER )
Neil Armstronge9231112022-06-10 09:03:41 +0200371 return( PSA_ERROR_NOT_SUPPORTED );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200372
373 operation->role = role;
374
375 return( PSA_SUCCESS );
376 }
377 else
378#endif
379 return( PSA_ERROR_NOT_SUPPORTED );
380}
381
Neil Armstronga557cb82022-06-10 08:58:32 +0200382#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200383static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
384{
385 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200386 mbedtls_ecjpake_role role;
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200387
388 if( operation->role == PSA_PAKE_ROLE_CLIENT )
389 role = MBEDTLS_ECJPAKE_CLIENT;
390 else if( operation->role == PSA_PAKE_ROLE_SERVER )
391 role = MBEDTLS_ECJPAKE_SERVER;
392 else
393 return( PSA_ERROR_BAD_STATE );
394
Przemek Stekiel348410f2022-11-15 22:22:07 +0100395 if (operation->password_data == NULL ||
396 operation->password_bytes == 0 )
397 {
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200398 return( PSA_ERROR_BAD_STATE );
Przemek Stekiel348410f2022-11-15 22:22:07 +0100399 }
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200400
401 ret = mbedtls_ecjpake_setup( &operation->ctx.ecjpake,
402 role,
403 MBEDTLS_MD_SHA256,
404 MBEDTLS_ECP_DP_SECP256R1,
Przemek Stekiel348410f2022-11-15 22:22:07 +0100405 operation->password_data,
406 operation->password_bytes );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200407
408 if( ret != 0 )
Neil Armstrongdb05cbf2022-06-15 15:25:45 +0200409 return( mbedtls_ecjpake_to_psa_error( ret ) );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200410
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200411 operation->state = PSA_PAKE_STATE_READY;
412
413 return( PSA_SUCCESS );
414}
415#endif
416
Manuel Pégourié-Gonnardf155ab92022-10-13 13:11:52 +0200417static psa_status_t psa_pake_output_internal(
418 psa_pake_operation_t *operation,
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200419 psa_pake_step_t step,
420 uint8_t *output,
421 size_t output_size,
422 size_t *output_length )
423{
424 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
425 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
426 size_t length;
427
Neil Armstrongcb679f22022-09-13 14:43:07 +0200428 if( operation->alg == PSA_ALG_NONE ||
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200429 operation->state == PSA_PAKE_STATE_INVALID )
430 return( PSA_ERROR_BAD_STATE );
431
Neil Armstrong0d001ef2022-06-08 17:42:52 +0200432 if( output == NULL || output_size == 0 || output_length == NULL )
433 return( PSA_ERROR_INVALID_ARGUMENT );
434
Neil Armstronga557cb82022-06-10 08:58:32 +0200435#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
Neil Armstrongfa849622022-09-13 15:10:46 +0200436 /*
437 * The PSA CRYPTO PAKE and MbedTLS JPAKE API have a different
438 * handling of output sequencing.
439 *
Neil Armstrong6a12a772022-09-14 12:17:42 +0200440 * The MbedTLS JPAKE API outputs the whole X1+X2 and X2S steps data
Neil Armstrongfa849622022-09-13 15:10:46 +0200441 * at once, on the other side the PSA CRYPTO PAKE api requires
442 * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X2S to be
443 * retrieved in sequence.
444 *
445 * In order to achieve API compatibility, the whole X1+X2 or X2S steps
446 * data is stored in an intermediate buffer at first step output call,
447 * and data is sliced down by parsing the ECPoint records in order
448 * to return the right parts on each step.
449 */
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200450 if( operation->alg == PSA_ALG_JPAKE )
451 {
Neil Armstrong3d4966a2022-09-13 14:54:15 +0200452 if( step != PSA_PAKE_STEP_KEY_SHARE &&
453 step != PSA_PAKE_STEP_ZK_PUBLIC &&
454 step != PSA_PAKE_STEP_ZK_PROOF )
455 return( PSA_ERROR_INVALID_ARGUMENT );
456
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200457 if( operation->state == PSA_PAKE_STATE_SETUP ) {
458 status = psa_pake_ecjpake_setup( operation );
459 if( status != PSA_SUCCESS )
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200460 return( status );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200461 }
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200462
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200463 if( operation->state != PSA_PAKE_STATE_READY &&
464 operation->state != PSA_PAKE_OUTPUT_X1_X2 &&
465 operation->state != PSA_PAKE_OUTPUT_X2S )
466 {
467 return( PSA_ERROR_BAD_STATE );
468 }
469
470 if( operation->state == PSA_PAKE_STATE_READY )
471 {
472 if( step != PSA_PAKE_STEP_KEY_SHARE )
473 return( PSA_ERROR_BAD_STATE );
474
475 switch( operation->output_step )
476 {
477 case PSA_PAKE_STEP_X1_X2:
478 operation->state = PSA_PAKE_OUTPUT_X1_X2;
479 break;
480 case PSA_PAKE_STEP_X2S:
481 operation->state = PSA_PAKE_OUTPUT_X2S;
482 break;
483 default:
484 return( PSA_ERROR_BAD_STATE );
485 }
486
487 operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
488 }
489
490 /* Check if step matches current sequence */
491 switch( operation->sequence )
492 {
493 case PSA_PAKE_X1_STEP_KEY_SHARE:
494 case PSA_PAKE_X2_STEP_KEY_SHARE:
495 if( step != PSA_PAKE_STEP_KEY_SHARE )
496 return( PSA_ERROR_BAD_STATE );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200497 break;
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200498
499 case PSA_PAKE_X1_STEP_ZK_PUBLIC:
500 case PSA_PAKE_X2_STEP_ZK_PUBLIC:
501 if( step != PSA_PAKE_STEP_ZK_PUBLIC )
502 return( PSA_ERROR_BAD_STATE );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200503 break;
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200504
505 case PSA_PAKE_X1_STEP_ZK_PROOF:
506 case PSA_PAKE_X2_STEP_ZK_PROOF:
507 if( step != PSA_PAKE_STEP_ZK_PROOF )
508 return( PSA_ERROR_BAD_STATE );
509 break;
510
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200511 default:
512 return( PSA_ERROR_BAD_STATE );
513 }
514
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200515 /* Initialize & write round on KEY_SHARE sequences */
516 if( operation->state == PSA_PAKE_OUTPUT_X1_X2 &&
517 operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200518 {
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200519 ret = mbedtls_ecjpake_write_round_one( &operation->ctx.ecjpake,
520 operation->buffer,
Manuel Pégourié-Gonnard79617d92022-10-05 12:55:50 +0200521 MBEDTLS_PSA_PAKE_BUFFER_SIZE,
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200522 &operation->buffer_length,
523 mbedtls_psa_get_random,
524 MBEDTLS_PSA_RANDOM_STATE );
525 if( ret != 0 )
Neil Armstrongdb05cbf2022-06-15 15:25:45 +0200526 return( mbedtls_ecjpake_to_psa_error( ret ) );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200527
528 operation->buffer_offset = 0;
529 }
530 else if( operation->state == PSA_PAKE_OUTPUT_X2S &&
531 operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE )
532 {
533 ret = mbedtls_ecjpake_write_round_two( &operation->ctx.ecjpake,
534 operation->buffer,
Manuel Pégourié-Gonnard79617d92022-10-05 12:55:50 +0200535 MBEDTLS_PSA_PAKE_BUFFER_SIZE,
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200536 &operation->buffer_length,
537 mbedtls_psa_get_random,
538 MBEDTLS_PSA_RANDOM_STATE );
539 if( ret != 0 )
Neil Armstrongdb05cbf2022-06-15 15:25:45 +0200540 return( mbedtls_ecjpake_to_psa_error( ret ) );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200541
542 operation->buffer_offset = 0;
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200543 }
544
Neil Armstrong1d0294f2022-09-13 14:49:24 +0200545 /*
Manuel Pégourié-Gonnardec7012d2022-10-05 12:17:34 +0200546 * mbedtls_ecjpake_write_round_xxx() outputs thing in the format
547 * defined by draft-cragie-tls-ecjpake-01 section 7. The summary is
548 * that the data for each step is prepended with a length byte, and
549 * then they're concatenated. Additionally, the server's second round
550 * output is prepended with a 3-bytes ECParameters structure.
Neil Armstrong1d0294f2022-09-13 14:49:24 +0200551 *
Manuel Pégourié-Gonnardec7012d2022-10-05 12:17:34 +0200552 * In PSA, we output each step separately, and don't prepend the
553 * output with a length byte, even less a curve identifier, as that
554 * information is already available.
Neil Armstrong1d0294f2022-09-13 14:49:24 +0200555 */
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200556 if( operation->state == PSA_PAKE_OUTPUT_X2S &&
Manuel Pégourié-Gonnardec7012d2022-10-05 12:17:34 +0200557 operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
558 operation->role == PSA_PAKE_ROLE_SERVER )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200559 {
Manuel Pégourié-Gonnardec7012d2022-10-05 12:17:34 +0200560 /* Skip ECParameters, with is 3 bytes (RFC 8422) */
561 operation->buffer_offset += 3;
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200562 }
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200563
Manuel Pégourié-Gonnardec7012d2022-10-05 12:17:34 +0200564 /* Read the length byte then move past it to the data */
565 length = operation->buffer[operation->buffer_offset];
566 operation->buffer_offset += 1;
567
568 if( operation->buffer_offset + length > operation->buffer_length )
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200569 return( PSA_ERROR_DATA_CORRUPT );
570
571 if( output_size < length )
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200572 return( PSA_ERROR_BUFFER_TOO_SMALL );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200573
574 memcpy( output,
Manuel Pégourié-Gonnardec7012d2022-10-05 12:17:34 +0200575 operation->buffer + operation->buffer_offset,
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200576 length );
577 *output_length = length;
578
579 operation->buffer_offset += length;
580
581 /* Reset buffer after ZK_PROOF sequence */
582 if( ( operation->state == PSA_PAKE_OUTPUT_X1_X2 &&
583 operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) ||
584 ( operation->state == PSA_PAKE_OUTPUT_X2S &&
585 operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) )
586 {
Manuel Pégourié-Gonnard79617d92022-10-05 12:55:50 +0200587 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200588 operation->buffer_length = 0;
589 operation->buffer_offset = 0;
590
591 operation->state = PSA_PAKE_STATE_READY;
592 operation->output_step++;
Neil Armstrongcb679f22022-09-13 14:43:07 +0200593 operation->sequence = PSA_PAKE_SEQ_INVALID;
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200594 }
595 else
596 operation->sequence++;
597
598 return( PSA_SUCCESS );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200599 }
600 else
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200601#endif
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200602 return( PSA_ERROR_NOT_SUPPORTED );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200603}
604
Manuel Pégourié-Gonnardf155ab92022-10-13 13:11:52 +0200605psa_status_t psa_pake_output( psa_pake_operation_t *operation,
606 psa_pake_step_t step,
607 uint8_t *output,
608 size_t output_size,
609 size_t *output_length )
610{
611 psa_status_t status = psa_pake_output_internal(
612 operation, step, output, output_size, output_length );
613
614 if( status != PSA_SUCCESS )
615 psa_pake_abort( operation );
616
617 return( status );
618}
619
620static psa_status_t psa_pake_input_internal(
621 psa_pake_operation_t *operation,
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200622 psa_pake_step_t step,
623 const uint8_t *input,
624 size_t input_length )
625{
626 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
627 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200628
Neil Armstrongcb679f22022-09-13 14:43:07 +0200629 if( operation->alg == PSA_ALG_NONE ||
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200630 operation->state == PSA_PAKE_STATE_INVALID )
631 return( PSA_ERROR_BAD_STATE );
632
Neil Armstrong0d001ef2022-06-08 17:42:52 +0200633 if( input == NULL || input_length == 0 )
634 return( PSA_ERROR_INVALID_ARGUMENT );
635
Neil Armstronga557cb82022-06-10 08:58:32 +0200636#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
Neil Armstrongfa849622022-09-13 15:10:46 +0200637 /*
638 * The PSA CRYPTO PAKE and MbedTLS JPAKE API have a different
639 * handling of input sequencing.
640 *
641 * The MbedTLS JPAKE API takes the whole X1+X2 or X4S steps data
642 * at once as input, on the other side the PSA CRYPTO PAKE api requires
643 * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X4S to be
644 * given in sequence.
645 *
646 * In order to achieve API compatibility, each X1+X2 or X4S step data
647 * is stored sequentially in an intermediate buffer and given to the
648 * MbedTLS JPAKE API on the last step.
649 *
650 * This causes any input error to be only detected on the last step.
651 */
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200652 if( operation->alg == PSA_ALG_JPAKE )
653 {
Neil Armstrong3d4966a2022-09-13 14:54:15 +0200654 if( step != PSA_PAKE_STEP_KEY_SHARE &&
655 step != PSA_PAKE_STEP_ZK_PUBLIC &&
656 step != PSA_PAKE_STEP_ZK_PROOF )
657 return( PSA_ERROR_INVALID_ARGUMENT );
658
Manuel Pégourié-Gonnard0771d412022-10-06 09:30:34 +0200659 const psa_pake_primitive_t prim = PSA_PAKE_PRIMITIVE(
660 PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256 );
Manuel Pégourié-Gonnard02f82bb2022-10-13 13:32:02 +0200661 if( input_length > (size_t) PSA_PAKE_INPUT_SIZE( PSA_ALG_JPAKE, prim, step ) )
Manuel Pégourié-Gonnard0771d412022-10-06 09:30:34 +0200662 return( PSA_ERROR_INVALID_ARGUMENT );
663
Neil Armstrong5bbdb702022-09-05 17:54:15 +0200664 if( operation->state == PSA_PAKE_STATE_SETUP )
665 {
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200666 status = psa_pake_ecjpake_setup( operation );
667 if( status != PSA_SUCCESS )
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200668 return( status );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200669 }
670
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200671 if( operation->state != PSA_PAKE_STATE_READY &&
672 operation->state != PSA_PAKE_INPUT_X1_X2 &&
673 operation->state != PSA_PAKE_INPUT_X4S )
674 {
675 return( PSA_ERROR_BAD_STATE );
676 }
677
678 if( operation->state == PSA_PAKE_STATE_READY )
679 {
680 if( step != PSA_PAKE_STEP_KEY_SHARE )
681 return( PSA_ERROR_BAD_STATE );
682
683 switch( operation->input_step )
684 {
685 case PSA_PAKE_STEP_X1_X2:
686 operation->state = PSA_PAKE_INPUT_X1_X2;
687 break;
688 case PSA_PAKE_STEP_X2S:
689 operation->state = PSA_PAKE_INPUT_X4S;
690 break;
691 default:
692 return( PSA_ERROR_BAD_STATE );
693 }
694
695 operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
696 }
697
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200698 /* Check if step matches current sequence */
699 switch( operation->sequence )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200700 {
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200701 case PSA_PAKE_X1_STEP_KEY_SHARE:
702 case PSA_PAKE_X2_STEP_KEY_SHARE:
703 if( step != PSA_PAKE_STEP_KEY_SHARE )
704 return( PSA_ERROR_BAD_STATE );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200705 break;
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200706
707 case PSA_PAKE_X1_STEP_ZK_PUBLIC:
708 case PSA_PAKE_X2_STEP_ZK_PUBLIC:
709 if( step != PSA_PAKE_STEP_ZK_PUBLIC )
710 return( PSA_ERROR_BAD_STATE );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200711 break;
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200712
713 case PSA_PAKE_X1_STEP_ZK_PROOF:
714 case PSA_PAKE_X2_STEP_ZK_PROOF:
715 if( step != PSA_PAKE_STEP_ZK_PROOF )
716 return( PSA_ERROR_BAD_STATE );
717 break;
718
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200719 default:
720 return( PSA_ERROR_BAD_STATE );
721 }
722
Manuel Pégourié-Gonnardec7012d2022-10-05 12:17:34 +0200723 /*
724 * Copy input to local buffer and format it as the Mbed TLS API
725 * expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7.
726 * The summary is that the data for each step is prepended with a
727 * length byte, and then they're concatenated. Additionally, the
728 * server's second round output is prepended with a 3-bytes
729 * ECParameters structure - which means we have to prepend that when
730 * we're a client.
731 */
732 if( operation->state == PSA_PAKE_INPUT_X4S &&
733 operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
734 operation->role == PSA_PAKE_ROLE_CLIENT )
735 {
736 /* We only support secp256r1. */
737 /* This is the ECParameters structure defined by RFC 8422. */
738 unsigned char ecparameters[3] = {
739 3, /* named_curve */
740 0, 23 /* secp256r1 */
741 };
742 memcpy( operation->buffer + operation->buffer_length,
743 ecparameters, sizeof( ecparameters ) );
744 operation->buffer_length += sizeof( ecparameters );
745 }
746
747 /* Write the length byte */
Manuel Pégourié-Gonnard0771d412022-10-06 09:30:34 +0200748 operation->buffer[operation->buffer_length] = (uint8_t) input_length;
Manuel Pégourié-Gonnardec7012d2022-10-05 12:17:34 +0200749 operation->buffer_length += 1;
750
751 /* Finally copy the data */
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200752 memcpy( operation->buffer + operation->buffer_length,
753 input, input_length );
754 operation->buffer_length += input_length;
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200755
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200756 /* Load buffer at each last round ZK_PROOF */
757 if( operation->state == PSA_PAKE_INPUT_X1_X2 &&
758 operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200759 {
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200760 ret = mbedtls_ecjpake_read_round_one( &operation->ctx.ecjpake,
761 operation->buffer,
762 operation->buffer_length );
763
Manuel Pégourié-Gonnard79617d92022-10-05 12:55:50 +0200764 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200765 operation->buffer_length = 0;
766
767 if( ret != 0 )
Neil Armstrongdb05cbf2022-06-15 15:25:45 +0200768 return( mbedtls_ecjpake_to_psa_error( ret ) );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200769 }
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200770 else if( operation->state == PSA_PAKE_INPUT_X4S &&
771 operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200772 {
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200773 ret = mbedtls_ecjpake_read_round_two( &operation->ctx.ecjpake,
774 operation->buffer,
775 operation->buffer_length );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200776
Manuel Pégourié-Gonnard79617d92022-10-05 12:55:50 +0200777 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200778 operation->buffer_length = 0;
779
780 if( ret != 0 )
Neil Armstrongdb05cbf2022-06-15 15:25:45 +0200781 return( mbedtls_ecjpake_to_psa_error( ret ) );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200782 }
783
784 if( ( operation->state == PSA_PAKE_INPUT_X1_X2 &&
785 operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) ||
786 ( operation->state == PSA_PAKE_INPUT_X4S &&
787 operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) )
788 {
789 operation->state = PSA_PAKE_STATE_READY;
790 operation->input_step++;
Neil Armstrongcb679f22022-09-13 14:43:07 +0200791 operation->sequence = PSA_PAKE_SEQ_INVALID;
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200792 }
793 else
794 operation->sequence++;
795
796 return( PSA_SUCCESS );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200797 }
798 else
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200799#endif
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200800 return( PSA_ERROR_NOT_SUPPORTED );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200801}
802
Manuel Pégourié-Gonnardf155ab92022-10-13 13:11:52 +0200803psa_status_t psa_pake_input( psa_pake_operation_t *operation,
804 psa_pake_step_t step,
805 const uint8_t *input,
806 size_t input_length )
807{
808 psa_status_t status = psa_pake_input_internal(
809 operation, step, input, input_length );
810
811 if( status != PSA_SUCCESS )
812 psa_pake_abort( operation );
813
814 return( status );
815}
816
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200817psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
818 psa_key_derivation_operation_t *output)
819{
820 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
821 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
822
Neil Armstrongcb679f22022-09-13 14:43:07 +0200823 if( operation->alg == PSA_ALG_NONE ||
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200824 operation->state != PSA_PAKE_STATE_READY ||
Neil Armstrong1e855602022-06-15 11:32:11 +0200825 operation->input_step != PSA_PAKE_STEP_DERIVE ||
826 operation->output_step != PSA_PAKE_STEP_DERIVE )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200827 return( PSA_ERROR_BAD_STATE );
828
Neil Armstronga557cb82022-06-10 08:58:32 +0200829#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200830 if( operation->alg == PSA_ALG_JPAKE )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200831 {
Neil Armstrongf19a3cb2022-06-15 16:00:29 +0200832 ret = mbedtls_ecjpake_write_shared_key( &operation->ctx.ecjpake,
833 operation->buffer,
Manuel Pégourié-Gonnard79617d92022-10-05 12:55:50 +0200834 MBEDTLS_PSA_PAKE_BUFFER_SIZE,
Neil Armstrongf19a3cb2022-06-15 16:00:29 +0200835 &operation->buffer_length,
836 mbedtls_psa_get_random,
837 MBEDTLS_PSA_RANDOM_STATE );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200838 if( ret != 0)
839 {
840 psa_pake_abort( operation );
Neil Armstrongdb05cbf2022-06-15 15:25:45 +0200841 return( mbedtls_ecjpake_to_psa_error( ret ) );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200842 }
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200843
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200844 status = psa_key_derivation_input_bytes( output,
845 PSA_KEY_DERIVATION_INPUT_SECRET,
846 operation->buffer,
847 operation->buffer_length );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200848
Manuel Pégourié-Gonnard79617d92022-10-05 12:55:50 +0200849 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200850
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200851 psa_pake_abort( operation );
852
853 return( status );
854 }
855 else
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200856#endif
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200857 return( PSA_ERROR_NOT_SUPPORTED );
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200858}
859
860psa_status_t psa_pake_abort(psa_pake_operation_t * operation)
861{
Neil Armstrongcb679f22022-09-13 14:43:07 +0200862 if( operation->alg == PSA_ALG_NONE )
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200863 {
864 return( PSA_SUCCESS );
865 }
866
Neil Armstronga557cb82022-06-10 08:58:32 +0200867#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200868 if( operation->alg == PSA_ALG_JPAKE )
869 {
Neil Armstrongcb679f22022-09-13 14:43:07 +0200870 operation->input_step = PSA_PAKE_STEP_INVALID;
871 operation->output_step = PSA_PAKE_STEP_INVALID;
Przemek Stekiel348410f2022-11-15 22:22:07 +0100872 mbedtls_free( operation->password_data );
873 operation->password_data = NULL;
874 operation->password_bytes = 0;
Neil Armstrongcb679f22022-09-13 14:43:07 +0200875 operation->role = PSA_PAKE_ROLE_NONE;
Manuel Pégourié-Gonnard79617d92022-10-05 12:55:50 +0200876 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
Neil Armstrong4efd7a42022-06-08 17:18:31 +0200877 operation->buffer_length = 0;
878 operation->buffer_offset = 0;
879 mbedtls_ecjpake_free( &operation->ctx.ecjpake );
880 }
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200881#endif
882
Neil Armstrongcb679f22022-09-13 14:43:07 +0200883 operation->alg = PSA_ALG_NONE;
884 operation->state = PSA_PAKE_STATE_INVALID;
885 operation->sequence = PSA_PAKE_SEQ_INVALID;
Neil Armstrongfbc4b4a2022-06-10 08:54:53 +0200886
Neil Armstronga4cc7d62022-05-25 11:30:48 +0200887 return( PSA_SUCCESS );
888}
889
890#endif /* MBEDTLS_PSA_BUILTIN_PAKE */
891
892#endif /* MBEDTLS_PSA_CRYPTO_C */