Skip to content

Draft : SPAKE2PLUS protocol flow proposal#65

Closed
silabs-Saketh wants to merge 1 commit intoARM-software:mainfrom
silabs-Saketh:spake2plus-proposal-draft
Closed

Draft : SPAKE2PLUS protocol flow proposal#65
silabs-Saketh wants to merge 1 commit intoARM-software:mainfrom
silabs-Saketh:spake2plus-proposal-draft

Conversation

@silabs-Saketh
Copy link
Copy Markdown

As per discussion in mbedTLS forum, creating this PR for a draft proposal of SPAKE2+ protocol flow for PSA Cryptography API 1.1 PAKE Extension. This PR is intended for finalising the expected spake2+ flow using PAKE API. If flow is finalised, we'll have an actual PR with expected api changes to review later.

Please let me know if there are any aspects that need more explanation or if I missed anything.

Copy link
Copy Markdown
Contributor

@athoelke athoelke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution. It is really helpful to have this concrete attempt to describe how this would work in the Crypto API, in order to tease out the issues that arise from supporting SPAKE2+.

It is clear that the inclusion of SPAKE2+ does require some additions, and perhaps even some changes, to the current beta PAKE specification, beyond a new PAKE algorithm id.

I've added some observations and questions to your proposal.

* `psa_pake_set_user()` to input ProverID
* `psa_pake_set_peer()` to input VerifierID
* Proposed new API
* `psa_pake_set_context()` to input context (additional data).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason that the context could not be provided using psa_pake_input()? - we might need to define a suitable PAKE step value for this

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can use psa_pake_input() for context input, will update this.
My thought was context can be input during setup phase, felt it could have an API similar to psa_pake_set_user or psa_pake_set_peer.

Copy link
Copy Markdown

@silabs-Kusumit silabs-Kusumit Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add a step PSA_PAKE_STEP_ADDITIONAL_DATA to psa_pake_input() and use that for setting the context.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Continuing the thread in new PR: #73 (comment)


* Existing API's (when user is Prover)
* `psa_pake_set_user()` to input ProverID
* `psa_pake_set_peer()` to input VerifierID
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect that for SPAKE2+ we would want the Prover to call psa_pake_set_role(..., PSA_PAKE_ROLE_CLIENT), and the Verifier would set it's role to be SERVER?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, the comments in the Mbed TLS header still reference psa_pake_set_user() and psa_pake_set_peer(). That is incorrect and the official PSA Crypto documentation has the correct description.

I normally use this page https://armmbed.github.io/mbed-crypto/1.1_PAKE_Extension.0-bet.0/html/pake.html. @athoelke is that the official copy or is there a more up to date/reliable source?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The now official location for the APIs is at arm-software.github.io/psa-api. The PAKE extension is here: https://arm-software.github.io/psa-api/crypto/1.1/ext-pake/

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect that for SPAKE2+ we would want the Prover to call psa_pake_set_role(..., PSA_PAKE_ROLE_CLIENT), and the Verifier would set it's role to be SERVER?

Yes, we would need 'psa_pake_set_role', will update.

`W1 = w1s mod p`
`L = w1*P`

Computing these values is considered Out of Scope for PAKE API as this a registration phase which could happen out of actual protocol flow.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this makes sense, and the specification permits for variation in how this is done:

  • Specific applications might have a preferred PBKDF and parameterization
  • The size of w0s and w1s is application specific - a longer-than-strictly-necessary string here can reduce the bias caused by the modulo p computation of w0 and w1

However, the registration phase involves big-integer arithmetic to compute w0, w1, and L - something that is not ideally required to be done by a caller of the Crypto API.

Copy link
Copy Markdown
Contributor

@yanesca yanesca May 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PBKDF part is covered well by the key derivation API. I agree that we should provide a tool for computing w0, w1 and L.

There are several ways to go about this, here is a couple of options that come to mind:

  • Provide a new function in the PAKE API to generate them (might be hard to make it universal enough to support other PAKEs as well)
  • Add input and output steps to handle the generation (the input/output flow is confusing enough already as it is, this would make it even worse)
  • Add a new algorithm to the key derivation API (each PAKE that needs this would take up a point in the key derivation algorithm identifier space and separating the 3 outputs would be error prone)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summarizing the discussion from above and other comments, I see two options.

  1. Accept only w0 || w1 on the prover side and w0 || L on verifier side
    • Pros: Can use psa_pake_set_password_key() directly.
    • Cons: Bignum calculation of obtaining w0, w1, and L needs to be done by user.
  2. Accept w0s || w1s. Can also accept instead w0, w1 and L.
    • Pros: Addresses concerns of bignum calculations. Can directly feed output of PBKDF operation to PAKE API.
    • Cons: Need to create new function or expand existing psa_pake_set_password_key() to accept multiple inputs by adding steps/input types. Can create a generic psa_pake_input_key() which accepts keys.

In both options the input is treated as a secret.
I am personally leaning towards option 2. We can generalize the input function for keys/secrets e.g. psa_pake_input_key() and add the input steps accordingly. This option offers the greatest flexibility in usage.


Computing these values is considered Out of Scope for PAKE API as this a registration phase which could happen out of actual protocol flow.

Since W0 & W1 and L serve as registartion records and verification value, these values can be treated as secrets.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be a nice property of the API for SPAKE2+, if we had a mechanism by which the caller can present either the shared password and identities, or the PBKDF output w0s || w1s, and the implementation computes and then stores the w0, w1, and L values as secrets within the crypto-processor.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are use cases where these values might visible outside of the key store (we allow them to be imported, or exported), then we also need to define how these integers and points are encoded as byte strings in the API.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard allows/suggests several different formats, but here I think it would make sense to mandate the same format as for ECC private (W0 and W1) and public (L) keys.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(For what it worths, I can't think of any use case where these values would need to be visible outside of the key store.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that a registration flow design might compute w0 and L in the client/prover, and then transfer & register these in the server/verifier, rather than transmit the password in the clear to the server to compute w0 and L? - this makes use of the property of SPAKE2+ that an eavesdropper who sees w0 and L is unable to spoof the Prover role, without knowing the initial passphrase, or w1.

Copy link
Copy Markdown
Contributor

@yanesca yanesca May 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible and I agree that it is how the registration flow should go. However, nothing should be sent in the clear. Whatever the API will be, we need to emphasise, that this is an out of band one-time setup to the protocol, that has to go through secure channels.

eavesdropper who sees w0 and L is unable to spoof the Prover role

That is true, but they still can impersonate the Verifier, which is undesirable as well.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for inputs. Let me check possible application use cases for secret usage in SPAKE2+ and get back on this.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Continuing the thread in the new PR: #73 (comment)


**Input methods** : Proposing three different approaches, protocol flow diagram has approach 1 mentioned below

1. `psa_pake_input()` can be extended to support input of W0, W1 and L.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these values should be treated as secrets, and psa_pake_input() currently only takes an in-memory parameter. These were envisaged for EC J-PAKE to be used for data that is transferred between the participants in the protocol.

Perhaps we extend the API with a version of psa_pake_input() that takes a key - but perhaps this looks more like option 2 or 3?

2. Given secret nature of these values, we can use current `psa_pake_set_password_key()` to input these secrets.
1. `W0||W1` as secret key on Prover side.
2. `W0||L` as secret key on Verifier side.
3. Extend `psa_pake_set_password_key()` to input mutiple secret keys
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is making this function a bit more like psa_pake_input(), as it would need a step parameter to enable multiple inputs for a single exchange. If we went down this route, then probably the API should change and 'set password' just becomes 'input key'. But then we also need identifier names for each of the password keys...

Not sure this provides a real benefit over option (2)

**Input methods** : Proposing three different approaches, protocol flow diagram has approach 1 mentioned below

1. `psa_pake_input()` can be extended to support input of W0, W1 and L.
2. Given secret nature of these values, we can use current `psa_pake_set_password_key()` to input these secrets.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I like this the most of the options here:

  • It encourages the participants to keep these derived secrets as keys in the keystore, rather than maintain them itself.
  • It fits within the current API design better, which separates the concept of the shared key (of key-derived secrets), from the input and output that is exchanged between particpants.


Key confirmation is part of the SPAKE2+ protocol. Current PSA Cryptography API 1.1 PAKE Extension only supports implicit key confirmation.

* New API `psa_pake_get_explicit_key()` is required to provide keys with explicit key confirmation. No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense: the naming of the current API was done deliberately because we wanted to ensure that developers and code reviewers understood that the output from EC J=PAKE is not authenticated.

Q: I presume there is no valid reason to use psa_pake_get_implicit_key() at all for SPAKE2+ (e.g. to extract Ke prior to confirmation)? - in which case we would make that API fail for SPAKE2+, and the inverse for trying to call psa_pake_get_explicit_key() for EC J-PAKE.

Are there other approaches that might unify the API? - or is a Bad Idea™ to make it easier to mix usage of authenticating and non-authenticating PAKE algorithms?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep the implicit and explicit key confirmation functions separate to avoid confusion.

The psa_pake_get_implicit_key() would not be called in the SPAKE2+ flow and should fail in case it is called.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a dependency point of view, there is some flexibility in the sequencing of the steps on both sides of the operation. For example, Y = pB only depends on B knowing that an exchange is under way - this might be only as a result of receipt of the first message from A (in which case the pake setup only happens then as well), or might be expected following earlier messages - but providing input X to the operation is only required to compute Z, V, etc., after Y = pB has been output from the operation.

Parallel execution is maximized if we permit psa_pake_output(Y) to happen before psa_pake_input(X) on B. We could mandate that (simpler for implementation as only one valid sequence through states). Application flexibility is maximized if we also allow psa_pake_input(X) to occur before psa_pake_output(Y).

There are similar interactions in the later stages. In theory cA and cB could both be sent prior to either participant verifying them and outputting the shared key. Although the specification states that A verifies cB before sending cA, it is not clear that this has any significant security advantage, and it definitely removes a parallelization opportunity

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, some steps can be parallelized, will update the flow to reflect the same and will add comments for any specific cases which mandates a particular sequence. Thanks.


SPAKE2+ has an offline initialization step where both parties may share parties identities and additional data (the context). This step is considered out of scope but these shared information may be required for SPAKE2+ protocol execution.

**Shared Information** : ProverID, VerifierID and Context.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the SPAKE2+ ciphersuite needs to be common between the participants.

This also needs to be encoded in the API. The current PAKE ciphersuite can encode the PAKE algorithm, the primitive (e.g. ECC over sec256p1), and a hash. For SPAKE2+, we also need to encode a KDF, and maybe also a MAC. However:

  • The specification currently only uses HKDF in the table of cipher suites - can we just assume that KDF = HDFK?
  • Can we assume that cA and cB are KcA and KcB (and avoid the MAC), or do we have use cases for using this in applications that specify the use of a MAC for key confirmation?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SPAKE2+ draft only includes HKDF as option for KDF in the given ciphersuite (Latest draft also doesn't give option for any other KDF). Therefore no need to include the KDF field in ciphersuite and assume it to be HKDF. Recommended MACs are HMAC and CMAC, therefore we should add MAC field in the ciphersuite

@athoelke athoelke linked an issue Apr 27, 2023 that may be closed by this pull request
@athoelke athoelke added Crypto API Issue or PR related to the Cryptography API proposal An RFC, or proposal for discussion labels Apr 27, 2023
@yanesca
Copy link
Copy Markdown
Contributor

yanesca commented May 10, 2023

@silabs-Saketh after the new API is agreed on, are you planning to implement SPAKE2+ in hardware or in software?

@silabs-Kusumit
Copy link
Copy Markdown

silabs-Saketh has left our organization and will not be contributing further. I will be taking over this pull request.

silabs-Kusumit pushed a commit to silabs-Kusumit/psa-api that referenced this pull request Jun 27, 2023
Signed-off-by: Kusumit Ghoderao <Kusumit.Ghoder@silabs.com>
@silabs-Kusumit
Copy link
Copy Markdown

silabs-Kusumit commented Jun 27, 2023

This PR will not be developed further. Please refer to #73 for the continuation of this PR.

I have addressed the review comments and incorporated the changes there.

@athoelke
Copy link
Copy Markdown
Contributor

athoelke commented Jul 7, 2023

The comments on this draft have all been addressed in the follow-up #73. I am closing this PR so that continuing discussion occurs there.

@athoelke athoelke closed this Jul 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Crypto API Issue or PR related to the Cryptography API proposal An RFC, or proposal for discussion

Projects

Development

Successfully merging this pull request may close these issues.

5 participants