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_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
36 /*
37 * State sequence:
38 *
39 * psa_pake_setup()
40 * |
41 * |-- In any order:
42 * | | psa_pake_set_password_key()
43 * | | psa_pake_set_user()
44 * | | psa_pake_set_peer()
45 * | | psa_pake_set_role()
46 * |
47 * |--- In any order: (First round input before or after first round output)
48 * | |
49 * | |------ In Order
50 * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
51 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
52 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
53 * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
54 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
55 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
56 * | |
57 * | |------ In Order:
58 * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
59 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
60 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
61 * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
62 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
63 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
64 * |
65 * |--- In any order: (Second round input before or after second round output)
66 * | |
67 * | |------ In Order
68 * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
69 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
70 * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
71 * | |
72 * | |------ In Order:
73 * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
74 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
75 * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
76 * |
77 * psa_pake_get_implicit_key()
78 * psa_pake_abort()
79 */
80
81 enum psa_pake_step
82 {
83 PSA_PAKE_STEP_INVALID = 0,
84 PSA_PAKE_STEP_X1_X2 = 1,
85 PSA_PAKE_STEP_X2S = 2,
86 PSA_PAKE_STEP_DERIVE = 3,
87 };
88
89 enum psa_pake_state
90 {
91 PSA_PAKE_STATE_INVALID = 0,
92 PSA_PAKE_STATE_SETUP = 1,
93 PSA_PAKE_STATE_READY = 2,
94 PSA_PAKE_OUTPUT_X1_X2 = 3,
95 PSA_PAKE_OUTPUT_X2S = 4,
96 PSA_PAKE_INPUT_X1_X2 = 5,
97 PSA_PAKE_INPUT_X4S = 6,
98 };
99
100 /*
101 * The first PAKE step shares the same sequences of the second PAKE step
102 * but with a second set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs.
103 * It's simpler to share the same sequences numbers of the first
104 * set of KEY_SHARE/ZK_PUBLIC/ZK_PROOF outputs/inputs in both PAKE steps.
105 *
106 * State sequence with step, state & sequence enums:
107 * => Input & Output Step = PSA_PAKE_STEP_INVALID
108 * => state = PSA_PAKE_STATE_INVALID
109 * psa_pake_setup()
110 * => Input & Output Step = PSA_PAKE_STEP_X1_X2
111 * => state = PSA_PAKE_STATE_SETUP
112 * => sequence = PSA_PAKE_SEQ_INVALID
113 * |
114 * |--- In any order: (First round input before or after first round output)
115 * | | First call of psa_pake_output() or psa_pake_input() sets
116 * | | state = PSA_PAKE_STATE_READY
117 * | |
118 * | |------ In Order: => state = PSA_PAKE_OUTPUT_X1_X2
119 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
120 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
121 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
122 * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE
123 * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC
124 * | | | psa_pake_output() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF
125 * | | | => state = PSA_PAKE_STATE_READY
126 * | | | => sequence = PSA_PAKE_SEQ_INVALID
127 * | | | => Output Step = PSA_PAKE_STEP_X2S
128 * | |
129 * | |------ In Order: => state = PSA_PAKE_INPUT_X1_X2
130 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
131 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
132 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
133 * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_KEY_SHARE
134 * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PUBLIC
135 * | | | psa_pake_input() => sequence = PSA_PAKE_X2_STEP_ZK_PROOF
136 * | | | => state = PSA_PAKE_STATE_READY
137 * | | | => sequence = PSA_PAKE_SEQ_INVALID
138 * | | | => Output Step = PSA_PAKE_INPUT_X4S
139 * |
140 * |--- In any order: (Second round input before or after second round output)
141 * | |
142 * | |------ In Order: => state = PSA_PAKE_OUTPUT_X2S
143 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
144 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
145 * | | | psa_pake_output() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
146 * | | | => state = PSA_PAKE_STATE_READY
147 * | | | => sequence = PSA_PAKE_SEQ_INVALID
148 * | | | => Output Step = PSA_PAKE_STEP_DERIVE
149 * | |
150 * | |------ In Order: => state = PSA_PAKE_INPUT_X4S
151 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_KEY_SHARE
152 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PUBLIC
153 * | | | psa_pake_input() => sequence = PSA_PAKE_X1_STEP_ZK_PROOF
154 * | | | => state = PSA_PAKE_STATE_READY
155 * | | | => sequence = PSA_PAKE_SEQ_INVALID
156 * | | | => Output Step = PSA_PAKE_STEP_DERIVE
157 * |
158 * psa_pake_get_implicit_key()
159 * => Input & Output Step = PSA_PAKE_STEP_INVALID
160 */
161 enum psa_pake_sequence
162 {
163 PSA_PAKE_SEQ_INVALID = 0,
164 PSA_PAKE_X1_STEP_KEY_SHARE = 1, /* also X2S & X4S KEY_SHARE */
165 PSA_PAKE_X1_STEP_ZK_PUBLIC = 2, /* also X2S & X4S ZK_PUBLIC */
166 PSA_PAKE_X1_STEP_ZK_PROOF = 3, /* also X2S & X4S ZK_PROOF */
167 PSA_PAKE_X2_STEP_KEY_SHARE = 4,
168 PSA_PAKE_X2_STEP_ZK_PUBLIC = 5,
169 PSA_PAKE_X2_STEP_ZK_PROOF = 6,
170 PSA_PAKE_SEQ_END = 7,
171 };
172
173 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
mbedtls_ecjpake_to_psa_error(int ret)174 static psa_status_t mbedtls_ecjpake_to_psa_error( int ret )
175 {
176 switch( ret )
177 {
178 case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
179 case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
180 case MBEDTLS_ERR_ECP_INVALID_KEY:
181 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
182 return( PSA_ERROR_DATA_INVALID );
183 case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
184 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
185 return( PSA_ERROR_BUFFER_TOO_SMALL );
186 case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
187 return( PSA_ERROR_NOT_SUPPORTED );
188 case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
189 return( PSA_ERROR_CORRUPTION_DETECTED );
190 default:
191 return( PSA_ERROR_GENERIC_ERROR );
192 }
193 }
194 #endif
195
196 #if defined(MBEDTLS_PSA_BUILTIN_PAKE)
psa_pake_setup(psa_pake_operation_t * operation,const psa_pake_cipher_suite_t * cipher_suite)197 psa_status_t psa_pake_setup( psa_pake_operation_t *operation,
198 const psa_pake_cipher_suite_t *cipher_suite)
199 {
200 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
201
202 /* A context must be freshly initialized before it can be set up. */
203 if( operation->alg != PSA_ALG_NONE )
204 {
205 status = PSA_ERROR_BAD_STATE;
206 goto error;
207 }
208
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 status = PSA_ERROR_INVALID_ARGUMENT;
216 goto error;
217 }
218
219 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
220 if( cipher_suite->algorithm == PSA_ALG_JPAKE )
221 {
222 if( cipher_suite->type != PSA_PAKE_PRIMITIVE_TYPE_ECC ||
223 cipher_suite->family != PSA_ECC_FAMILY_SECP_R1 ||
224 cipher_suite->bits != 256 ||
225 cipher_suite->hash != PSA_ALG_SHA_256 )
226 {
227 status = PSA_ERROR_NOT_SUPPORTED;
228 goto error;
229 }
230
231 operation->alg = cipher_suite->algorithm;
232
233 mbedtls_ecjpake_init( &operation->ctx.ecjpake );
234
235 operation->state = PSA_PAKE_STATE_SETUP;
236 operation->sequence = PSA_PAKE_SEQ_INVALID;
237 operation->input_step = PSA_PAKE_STEP_X1_X2;
238 operation->output_step = PSA_PAKE_STEP_X1_X2;
239
240 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
241 operation->buffer_length = 0;
242 operation->buffer_offset = 0;
243
244 return( PSA_SUCCESS );
245 }
246 else
247 #endif
248 status = PSA_ERROR_NOT_SUPPORTED;
249
250 error:
251 psa_pake_abort( operation );
252 return status;
253 }
254
psa_pake_set_password_key(psa_pake_operation_t * operation,mbedtls_svc_key_id_t password)255 psa_status_t psa_pake_set_password_key( psa_pake_operation_t *operation,
256 mbedtls_svc_key_id_t password )
257 {
258 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
259 psa_key_attributes_t attributes = psa_key_attributes_init();
260 psa_key_type_t type;
261 psa_key_usage_t usage;
262 psa_key_slot_t *slot = NULL;
263
264 if( operation->alg == PSA_ALG_NONE ||
265 operation->state != PSA_PAKE_STATE_SETUP )
266 {
267 status = PSA_ERROR_BAD_STATE;
268 goto error;
269 }
270
271 status = psa_get_key_attributes( password, &attributes );
272 if( status != PSA_SUCCESS )
273 goto error;
274
275 type = psa_get_key_type( &attributes );
276 usage = psa_get_key_usage_flags( &attributes );
277
278 psa_reset_key_attributes( &attributes );
279
280 if( type != PSA_KEY_TYPE_PASSWORD &&
281 type != PSA_KEY_TYPE_PASSWORD_HASH )
282 {
283 status = PSA_ERROR_INVALID_ARGUMENT;
284 goto error;
285 }
286
287 if( ( usage & PSA_KEY_USAGE_DERIVE ) == 0 ) {
288 status = PSA_ERROR_NOT_PERMITTED;
289 goto error;
290 }
291
292 if( operation->password != NULL )
293 return( PSA_ERROR_BAD_STATE );
294
295 status = psa_get_and_lock_key_slot_with_policy( password, &slot,
296 PSA_KEY_USAGE_DERIVE,
297 PSA_ALG_JPAKE );
298 if( status != PSA_SUCCESS )
299 return( status );
300
301 operation->password = mbedtls_calloc( 1, slot->key.bytes );
302 if( operation->password == NULL )
303 {
304 psa_unlock_key_slot( slot );
305 return( PSA_ERROR_INSUFFICIENT_MEMORY );
306 }
307 memcpy( operation->password, slot->key.data, slot->key.bytes );
308 operation->password_len = slot->key.bytes;
309
310 status = psa_unlock_key_slot( slot );
311 if( status != PSA_SUCCESS )
312 return( status );
313
314 return( PSA_SUCCESS );
315
316 error:
317 psa_pake_abort(operation);
318 return( status );
319 }
320
psa_pake_set_user(psa_pake_operation_t * operation,const uint8_t * user_id,size_t user_id_len)321 psa_status_t psa_pake_set_user( psa_pake_operation_t *operation,
322 const uint8_t *user_id,
323 size_t user_id_len )
324 {
325 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
326
327 if( operation->alg == PSA_ALG_NONE ||
328 operation->state != PSA_PAKE_STATE_SETUP )
329 {
330 status = PSA_ERROR_BAD_STATE;
331 goto error;
332 }
333
334 if( user_id_len == 0 || user_id == NULL )
335 {
336 status = PSA_ERROR_INVALID_ARGUMENT;
337 goto error;
338 }
339
340 status = PSA_ERROR_NOT_SUPPORTED;
341
342 error:
343 psa_pake_abort(operation);
344 return( status );
345 }
346
psa_pake_set_peer(psa_pake_operation_t * operation,const uint8_t * peer_id,size_t peer_id_len)347 psa_status_t psa_pake_set_peer( psa_pake_operation_t *operation,
348 const uint8_t *peer_id,
349 size_t peer_id_len )
350 {
351 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
352
353 if( operation->alg == PSA_ALG_NONE ||
354 operation->state != PSA_PAKE_STATE_SETUP )
355 {
356 status = PSA_ERROR_BAD_STATE;
357 goto error;
358 }
359
360 if( peer_id_len == 0 || peer_id == NULL )
361 {
362 status = PSA_ERROR_INVALID_ARGUMENT;
363 goto error;
364 }
365
366 status = PSA_ERROR_NOT_SUPPORTED;
367
368 error:
369 psa_pake_abort(operation);
370 return( status );
371 }
372
psa_pake_set_role(psa_pake_operation_t * operation,psa_pake_role_t role)373 psa_status_t psa_pake_set_role( psa_pake_operation_t *operation,
374 psa_pake_role_t role )
375 {
376 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
377
378 if( operation->alg == PSA_ALG_NONE ||
379 operation->state != PSA_PAKE_STATE_SETUP )
380 {
381 status = PSA_ERROR_BAD_STATE;
382 goto error;
383 }
384
385 if( role != PSA_PAKE_ROLE_NONE &&
386 role != PSA_PAKE_ROLE_FIRST &&
387 role != PSA_PAKE_ROLE_SECOND &&
388 role != PSA_PAKE_ROLE_CLIENT &&
389 role != PSA_PAKE_ROLE_SERVER )
390 {
391 status = PSA_ERROR_INVALID_ARGUMENT;
392 goto error;
393 }
394
395 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
396 if( operation->alg == PSA_ALG_JPAKE )
397 {
398 if( role != PSA_PAKE_ROLE_CLIENT &&
399 role != PSA_PAKE_ROLE_SERVER )
400 return( PSA_ERROR_NOT_SUPPORTED );
401
402 operation->role = role;
403
404 return( PSA_SUCCESS );
405 }
406 else
407 #endif
408 status = PSA_ERROR_NOT_SUPPORTED;
409
410 error:
411 psa_pake_abort(operation);
412 return( status );
413 }
414
415 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
psa_pake_ecjpake_setup(psa_pake_operation_t * operation)416 static psa_status_t psa_pake_ecjpake_setup( psa_pake_operation_t *operation )
417 {
418 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
419 mbedtls_ecjpake_role role;
420
421 if( operation->role == PSA_PAKE_ROLE_CLIENT )
422 role = MBEDTLS_ECJPAKE_CLIENT;
423 else if( operation->role == PSA_PAKE_ROLE_SERVER )
424 role = MBEDTLS_ECJPAKE_SERVER;
425 else
426 return( PSA_ERROR_BAD_STATE );
427
428 if( operation->password_len == 0 )
429 return( PSA_ERROR_BAD_STATE );
430
431 ret = mbedtls_ecjpake_setup( &operation->ctx.ecjpake,
432 role,
433 MBEDTLS_MD_SHA256,
434 MBEDTLS_ECP_DP_SECP256R1,
435 operation->password,
436 operation->password_len );
437
438 mbedtls_platform_zeroize( operation->password, operation->password_len );
439 mbedtls_free( operation->password );
440 operation->password = NULL;
441 operation->password_len = 0;
442
443 if( ret != 0 )
444 return( mbedtls_ecjpake_to_psa_error( ret ) );
445
446 operation->state = PSA_PAKE_STATE_READY;
447
448 return( PSA_SUCCESS );
449 }
450 #endif
451
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)452 static psa_status_t psa_pake_output_internal(
453 psa_pake_operation_t *operation,
454 psa_pake_step_t step,
455 uint8_t *output,
456 size_t output_size,
457 size_t *output_length )
458 {
459 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
460 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
461 size_t length;
462
463 if( operation->alg == PSA_ALG_NONE ||
464 operation->state == PSA_PAKE_STATE_INVALID )
465 return( PSA_ERROR_BAD_STATE );
466
467 if( output == NULL || output_size == 0 || output_length == NULL )
468 return( PSA_ERROR_INVALID_ARGUMENT );
469
470 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
471 /*
472 * The PSA CRYPTO PAKE and MbedTLS JPAKE API have a different
473 * handling of output sequencing.
474 *
475 * The MbedTLS JPAKE API outputs the whole X1+X2 and X2S steps data
476 * at once, on the other side the PSA CRYPTO PAKE api requires
477 * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X2S to be
478 * retrieved in sequence.
479 *
480 * In order to achieve API compatibility, the whole X1+X2 or X2S steps
481 * data is stored in an intermediate buffer at first step output call,
482 * and data is sliced down by parsing the ECPoint records in order
483 * to return the right parts on each step.
484 */
485 if( operation->alg == PSA_ALG_JPAKE )
486 {
487 if( step != PSA_PAKE_STEP_KEY_SHARE &&
488 step != PSA_PAKE_STEP_ZK_PUBLIC &&
489 step != PSA_PAKE_STEP_ZK_PROOF )
490 return( PSA_ERROR_INVALID_ARGUMENT );
491
492 if( operation->state == PSA_PAKE_STATE_SETUP ) {
493 status = psa_pake_ecjpake_setup( operation );
494 if( status != PSA_SUCCESS )
495 return( status );
496 }
497
498 if( operation->state != PSA_PAKE_STATE_READY &&
499 operation->state != PSA_PAKE_OUTPUT_X1_X2 &&
500 operation->state != PSA_PAKE_OUTPUT_X2S )
501 {
502 return( PSA_ERROR_BAD_STATE );
503 }
504
505 if( operation->state == PSA_PAKE_STATE_READY )
506 {
507 if( step != PSA_PAKE_STEP_KEY_SHARE )
508 return( PSA_ERROR_BAD_STATE );
509
510 switch( operation->output_step )
511 {
512 case PSA_PAKE_STEP_X1_X2:
513 operation->state = PSA_PAKE_OUTPUT_X1_X2;
514 break;
515 case PSA_PAKE_STEP_X2S:
516 operation->state = PSA_PAKE_OUTPUT_X2S;
517 break;
518 default:
519 return( PSA_ERROR_BAD_STATE );
520 }
521
522 operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
523 }
524
525 /* Check if step matches current sequence */
526 switch( operation->sequence )
527 {
528 case PSA_PAKE_X1_STEP_KEY_SHARE:
529 case PSA_PAKE_X2_STEP_KEY_SHARE:
530 if( step != PSA_PAKE_STEP_KEY_SHARE )
531 return( PSA_ERROR_BAD_STATE );
532 break;
533
534 case PSA_PAKE_X1_STEP_ZK_PUBLIC:
535 case PSA_PAKE_X2_STEP_ZK_PUBLIC:
536 if( step != PSA_PAKE_STEP_ZK_PUBLIC )
537 return( PSA_ERROR_BAD_STATE );
538 break;
539
540 case PSA_PAKE_X1_STEP_ZK_PROOF:
541 case PSA_PAKE_X2_STEP_ZK_PROOF:
542 if( step != PSA_PAKE_STEP_ZK_PROOF )
543 return( PSA_ERROR_BAD_STATE );
544 break;
545
546 default:
547 return( PSA_ERROR_BAD_STATE );
548 }
549
550 /* Initialize & write round on KEY_SHARE sequences */
551 if( operation->state == PSA_PAKE_OUTPUT_X1_X2 &&
552 operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE )
553 {
554 ret = mbedtls_ecjpake_write_round_one( &operation->ctx.ecjpake,
555 operation->buffer,
556 MBEDTLS_PSA_PAKE_BUFFER_SIZE,
557 &operation->buffer_length,
558 mbedtls_psa_get_random,
559 MBEDTLS_PSA_RANDOM_STATE );
560 if( ret != 0 )
561 return( mbedtls_ecjpake_to_psa_error( ret ) );
562
563 operation->buffer_offset = 0;
564 }
565 else if( operation->state == PSA_PAKE_OUTPUT_X2S &&
566 operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE )
567 {
568 ret = mbedtls_ecjpake_write_round_two( &operation->ctx.ecjpake,
569 operation->buffer,
570 MBEDTLS_PSA_PAKE_BUFFER_SIZE,
571 &operation->buffer_length,
572 mbedtls_psa_get_random,
573 MBEDTLS_PSA_RANDOM_STATE );
574 if( ret != 0 )
575 return( mbedtls_ecjpake_to_psa_error( ret ) );
576
577 operation->buffer_offset = 0;
578 }
579
580 /*
581 * mbedtls_ecjpake_write_round_xxx() outputs thing in the format
582 * defined by draft-cragie-tls-ecjpake-01 section 7. The summary is
583 * that the data for each step is prepended with a length byte, and
584 * then they're concatenated. Additionally, the server's second round
585 * output is prepended with a 3-bytes ECParameters structure.
586 *
587 * In PSA, we output each step separately, and don't prepend the
588 * output with a length byte, even less a curve identifier, as that
589 * information is already available.
590 */
591 if( operation->state == PSA_PAKE_OUTPUT_X2S &&
592 operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
593 operation->role == PSA_PAKE_ROLE_SERVER )
594 {
595 /* Skip ECParameters, with is 3 bytes (RFC 8422) */
596 operation->buffer_offset += 3;
597 }
598
599 /* Read the length byte then move past it to the data */
600 length = operation->buffer[operation->buffer_offset];
601 operation->buffer_offset += 1;
602
603 if( operation->buffer_offset + length > operation->buffer_length )
604 return( PSA_ERROR_DATA_CORRUPT );
605
606 if( output_size < length )
607 return( PSA_ERROR_BUFFER_TOO_SMALL );
608
609 memcpy( output,
610 operation->buffer + operation->buffer_offset,
611 length );
612 *output_length = length;
613
614 operation->buffer_offset += length;
615
616 /* Reset buffer after ZK_PROOF sequence */
617 if( ( operation->state == PSA_PAKE_OUTPUT_X1_X2 &&
618 operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) ||
619 ( operation->state == PSA_PAKE_OUTPUT_X2S &&
620 operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) )
621 {
622 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
623 operation->buffer_length = 0;
624 operation->buffer_offset = 0;
625
626 operation->state = PSA_PAKE_STATE_READY;
627 operation->output_step++;
628 operation->sequence = PSA_PAKE_SEQ_INVALID;
629 }
630 else
631 operation->sequence++;
632
633 return( PSA_SUCCESS );
634 }
635 else
636 #endif
637 return( PSA_ERROR_NOT_SUPPORTED );
638 }
639
psa_pake_output(psa_pake_operation_t * operation,psa_pake_step_t step,uint8_t * output,size_t output_size,size_t * output_length)640 psa_status_t psa_pake_output( psa_pake_operation_t *operation,
641 psa_pake_step_t step,
642 uint8_t *output,
643 size_t output_size,
644 size_t *output_length )
645 {
646 psa_status_t status = psa_pake_output_internal(
647 operation, step, output, output_size, output_length );
648
649 if( status != PSA_SUCCESS )
650 psa_pake_abort( operation );
651
652 return( status );
653 }
654
psa_pake_input_internal(psa_pake_operation_t * operation,psa_pake_step_t step,const uint8_t * input,size_t input_length)655 static psa_status_t psa_pake_input_internal(
656 psa_pake_operation_t *operation,
657 psa_pake_step_t step,
658 const uint8_t *input,
659 size_t input_length )
660 {
661 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
662 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
663
664 if( operation->alg == PSA_ALG_NONE ||
665 operation->state == PSA_PAKE_STATE_INVALID )
666 return( PSA_ERROR_BAD_STATE );
667
668 if( input == NULL || input_length == 0 )
669 return( PSA_ERROR_INVALID_ARGUMENT );
670
671 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
672 /*
673 * The PSA CRYPTO PAKE and MbedTLS JPAKE API have a different
674 * handling of input sequencing.
675 *
676 * The MbedTLS JPAKE API takes the whole X1+X2 or X4S steps data
677 * at once as input, on the other side the PSA CRYPTO PAKE api requires
678 * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X4S to be
679 * given in sequence.
680 *
681 * In order to achieve API compatibility, each X1+X2 or X4S step data
682 * is stored sequentially in an intermediate buffer and given to the
683 * MbedTLS JPAKE API on the last step.
684 *
685 * This causes any input error to be only detected on the last step.
686 */
687 if( operation->alg == PSA_ALG_JPAKE )
688 {
689 if( step != PSA_PAKE_STEP_KEY_SHARE &&
690 step != PSA_PAKE_STEP_ZK_PUBLIC &&
691 step != PSA_PAKE_STEP_ZK_PROOF )
692 return( PSA_ERROR_INVALID_ARGUMENT );
693
694 const psa_pake_primitive_t prim = PSA_PAKE_PRIMITIVE(
695 PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256 );
696 if( input_length > (size_t) PSA_PAKE_INPUT_SIZE( PSA_ALG_JPAKE, prim, step ) )
697 return( PSA_ERROR_INVALID_ARGUMENT );
698
699 if( operation->state == PSA_PAKE_STATE_SETUP )
700 {
701 status = psa_pake_ecjpake_setup( operation );
702 if( status != PSA_SUCCESS )
703 return( status );
704 }
705
706 if( operation->state != PSA_PAKE_STATE_READY &&
707 operation->state != PSA_PAKE_INPUT_X1_X2 &&
708 operation->state != PSA_PAKE_INPUT_X4S )
709 {
710 return( PSA_ERROR_BAD_STATE );
711 }
712
713 if( operation->state == PSA_PAKE_STATE_READY )
714 {
715 if( step != PSA_PAKE_STEP_KEY_SHARE )
716 return( PSA_ERROR_BAD_STATE );
717
718 switch( operation->input_step )
719 {
720 case PSA_PAKE_STEP_X1_X2:
721 operation->state = PSA_PAKE_INPUT_X1_X2;
722 break;
723 case PSA_PAKE_STEP_X2S:
724 operation->state = PSA_PAKE_INPUT_X4S;
725 break;
726 default:
727 return( PSA_ERROR_BAD_STATE );
728 }
729
730 operation->sequence = PSA_PAKE_X1_STEP_KEY_SHARE;
731 }
732
733 /* Check if step matches current sequence */
734 switch( operation->sequence )
735 {
736 case PSA_PAKE_X1_STEP_KEY_SHARE:
737 case PSA_PAKE_X2_STEP_KEY_SHARE:
738 if( step != PSA_PAKE_STEP_KEY_SHARE )
739 return( PSA_ERROR_BAD_STATE );
740 break;
741
742 case PSA_PAKE_X1_STEP_ZK_PUBLIC:
743 case PSA_PAKE_X2_STEP_ZK_PUBLIC:
744 if( step != PSA_PAKE_STEP_ZK_PUBLIC )
745 return( PSA_ERROR_BAD_STATE );
746 break;
747
748 case PSA_PAKE_X1_STEP_ZK_PROOF:
749 case PSA_PAKE_X2_STEP_ZK_PROOF:
750 if( step != PSA_PAKE_STEP_ZK_PROOF )
751 return( PSA_ERROR_BAD_STATE );
752 break;
753
754 default:
755 return( PSA_ERROR_BAD_STATE );
756 }
757
758 /*
759 * Copy input to local buffer and format it as the Mbed TLS API
760 * expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7.
761 * The summary is that the data for each step is prepended with a
762 * length byte, and then they're concatenated. Additionally, the
763 * server's second round output is prepended with a 3-bytes
764 * ECParameters structure - which means we have to prepend that when
765 * we're a client.
766 */
767 if( operation->state == PSA_PAKE_INPUT_X4S &&
768 operation->sequence == PSA_PAKE_X1_STEP_KEY_SHARE &&
769 operation->role == PSA_PAKE_ROLE_CLIENT )
770 {
771 /* We only support secp256r1. */
772 /* This is the ECParameters structure defined by RFC 8422. */
773 unsigned char ecparameters[3] = {
774 3, /* named_curve */
775 0, 23 /* secp256r1 */
776 };
777 memcpy( operation->buffer + operation->buffer_length,
778 ecparameters, sizeof( ecparameters ) );
779 operation->buffer_length += sizeof( ecparameters );
780 }
781
782 /* Write the length byte */
783 operation->buffer[operation->buffer_length] = (uint8_t) input_length;
784 operation->buffer_length += 1;
785
786 /* Finally copy the data */
787 memcpy( operation->buffer + operation->buffer_length,
788 input, input_length );
789 operation->buffer_length += input_length;
790
791 /* Load buffer at each last round ZK_PROOF */
792 if( operation->state == PSA_PAKE_INPUT_X1_X2 &&
793 operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF )
794 {
795 ret = mbedtls_ecjpake_read_round_one( &operation->ctx.ecjpake,
796 operation->buffer,
797 operation->buffer_length );
798
799 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
800 operation->buffer_length = 0;
801
802 if( ret != 0 )
803 return( mbedtls_ecjpake_to_psa_error( ret ) );
804 }
805 else if( operation->state == PSA_PAKE_INPUT_X4S &&
806 operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF )
807 {
808 ret = mbedtls_ecjpake_read_round_two( &operation->ctx.ecjpake,
809 operation->buffer,
810 operation->buffer_length );
811
812 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
813 operation->buffer_length = 0;
814
815 if( ret != 0 )
816 return( mbedtls_ecjpake_to_psa_error( ret ) );
817 }
818
819 if( ( operation->state == PSA_PAKE_INPUT_X1_X2 &&
820 operation->sequence == PSA_PAKE_X2_STEP_ZK_PROOF ) ||
821 ( operation->state == PSA_PAKE_INPUT_X4S &&
822 operation->sequence == PSA_PAKE_X1_STEP_ZK_PROOF ) )
823 {
824 operation->state = PSA_PAKE_STATE_READY;
825 operation->input_step++;
826 operation->sequence = PSA_PAKE_SEQ_INVALID;
827 }
828 else
829 operation->sequence++;
830
831 return( PSA_SUCCESS );
832 }
833 else
834 #endif
835 return( PSA_ERROR_NOT_SUPPORTED );
836 }
837
psa_pake_input(psa_pake_operation_t * operation,psa_pake_step_t step,const uint8_t * input,size_t input_length)838 psa_status_t psa_pake_input( psa_pake_operation_t *operation,
839 psa_pake_step_t step,
840 const uint8_t *input,
841 size_t input_length )
842 {
843 psa_status_t status = psa_pake_input_internal(
844 operation, step, input, input_length );
845
846 if( status != PSA_SUCCESS )
847 psa_pake_abort( operation );
848
849 return( status );
850 }
851
psa_pake_get_implicit_key(psa_pake_operation_t * operation,psa_key_derivation_operation_t * output)852 psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation,
853 psa_key_derivation_operation_t *output)
854 {
855 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
856 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
857
858 if( operation->alg == PSA_ALG_NONE ||
859 operation->state != PSA_PAKE_STATE_READY ||
860 operation->input_step != PSA_PAKE_STEP_DERIVE ||
861 operation->output_step != PSA_PAKE_STEP_DERIVE )
862 {
863 status = PSA_ERROR_BAD_STATE;
864 goto error;
865 }
866
867 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
868 if( operation->alg == PSA_ALG_JPAKE )
869 {
870 ret = mbedtls_ecjpake_write_shared_key( &operation->ctx.ecjpake,
871 operation->buffer,
872 MBEDTLS_PSA_PAKE_BUFFER_SIZE,
873 &operation->buffer_length,
874 mbedtls_psa_get_random,
875 MBEDTLS_PSA_RANDOM_STATE );
876 if( ret != 0)
877 {
878 psa_pake_abort( operation );
879 return( mbedtls_ecjpake_to_psa_error( ret ) );
880 }
881
882 status = psa_key_derivation_input_bytes( output,
883 PSA_KEY_DERIVATION_INPUT_SECRET,
884 operation->buffer,
885 operation->buffer_length );
886
887 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
888
889 psa_pake_abort( operation );
890
891 return( status );
892 }
893 else
894 #endif
895 status = PSA_ERROR_NOT_SUPPORTED;
896
897 error:
898 psa_key_derivation_abort( output );
899 psa_pake_abort( operation );
900
901 return( status );
902 }
903
psa_pake_abort(psa_pake_operation_t * operation)904 psa_status_t psa_pake_abort(psa_pake_operation_t * operation)
905 {
906 if( operation->alg == PSA_ALG_NONE )
907 {
908 return( PSA_SUCCESS );
909 }
910
911 #if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
912 if( operation->alg == PSA_ALG_JPAKE )
913 {
914 operation->input_step = PSA_PAKE_STEP_INVALID;
915 operation->output_step = PSA_PAKE_STEP_INVALID;
916 if( operation->password_len > 0 )
917 mbedtls_platform_zeroize( operation->password, operation->password_len );
918 mbedtls_free( operation->password );
919 operation->password = NULL;
920 operation->password_len = 0;
921 operation->role = PSA_PAKE_ROLE_NONE;
922 mbedtls_platform_zeroize( operation->buffer, MBEDTLS_PSA_PAKE_BUFFER_SIZE );
923 operation->buffer_length = 0;
924 operation->buffer_offset = 0;
925 mbedtls_ecjpake_free( &operation->ctx.ecjpake );
926 }
927 #endif
928
929 operation->alg = PSA_ALG_NONE;
930 operation->state = PSA_PAKE_STATE_INVALID;
931 operation->sequence = PSA_PAKE_SEQ_INVALID;
932
933 return( PSA_SUCCESS );
934 }
935
936 #endif /* MBEDTLS_PSA_BUILTIN_PAKE */
937
938 #endif /* MBEDTLS_PSA_CRYPTO_C */
939