Interruptible key agreement: bug on operation reuse #846

Open
opened 2026-07-23 06:50:53 -05:00 by gilles-peskine-arm · 0 comments
gilles-peskine-arm commented 2026-07-23 06:50:53 -05:00 (Migrated from github.com)

psa_key_agreement_iop_complete() leaves the operation object in an unexpected state on success, which prevents the operation from being reused.

Workaround: call psa_key_agreement_iop_abort() before reusing the operation object, even after a successful complete().

This snippet shows a nominal usage of interruptible key agreement, where the same operation object is reused for successive operations.

psa_status_t status;
psa_key_agreement_iop_t operation = {0};
psa_key_id_t key1;
psa_key_agreement_iop_setup(&operation, ...); // assume success
do { status = psa_key_agreement_iop_complete(&operation, &key1); } while (status == PSA_OPERATION_INCOMPLETE);
if (status != PSA_SUCCESS) psa_key_agreement_iop_abort(&operation);
psa_key_id_t key2;
psa_key_agreement_iop_setup(&operation, ...); // assume success
do { status = psa_key_agreement_iop_complete(&operation, &key2); } while (status == PSA_OPERATION_INCOMPLETE);

Due to a bug in psa_key_agreement_iop_complete(), operation->error_occurred is set to 1 on success, which causes the second call to psa_key_agreement_iop_setup() to fail.

There is also a separate bug in psa_key_agreement_iop_complete(), whereby it does not set *key = 0 on some failure conditions.

The goal of this issue is to fix both bugs, with proper unit tests, and also check for similar bugs in other PSA interruptible APIs.

Originally reported by Saurav Krrish through a security report channel. After internal evaluation, we conclude that there is a genuine functional bug but it is not a vulnerability.

`psa_key_agreement_iop_complete()` leaves the operation object in an unexpected state on success, which prevents the operation from being reused. Workaround: call `psa_key_agreement_iop_abort()` before reusing the operation object, even after a successful complete(). This snippet shows a nominal usage of interruptible key agreement, where the same operation object is reused for successive operations. ``` psa_status_t status; psa_key_agreement_iop_t operation = {0}; psa_key_id_t key1; psa_key_agreement_iop_setup(&operation, ...); // assume success do { status = psa_key_agreement_iop_complete(&operation, &key1); } while (status == PSA_OPERATION_INCOMPLETE); if (status != PSA_SUCCESS) psa_key_agreement_iop_abort(&operation); psa_key_id_t key2; psa_key_agreement_iop_setup(&operation, ...); // assume success do { status = psa_key_agreement_iop_complete(&operation, &key2); } while (status == PSA_OPERATION_INCOMPLETE); ``` Due to a bug in `psa_key_agreement_iop_complete()`, `operation->error_occurred` is set to 1 on success, which causes the second call to `psa_key_agreement_iop_setup()` to fail. There is also a separate bug in `psa_key_agreement_iop_complete()`, whereby it does not set `*key = 0` on some failure conditions. The goal of this issue is to fix both bugs, with proper unit tests, and also check for similar bugs in other PSA interruptible APIs. Originally reported by Saurav Krrish through a security report channel. After internal evaluation, we conclude that there is a genuine functional bug but it is not a vulnerability.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-Mbed-TLS/TF-PSA-Crypto#846
No description provided.