Add asymmetric key types for SPAKE2+#119
Conversation
|
Some feedback would be very welcome from @silabs-Kusumit, @silabs-hannes, @oberon-sk, and @yanesca; given your involvement in the PAKE API development. |
|
After further consideration on these open issues, my updated thinking is as follows. I am interested to hear any other ideas an opinions.
This seems to make the most sense, and is consistent with the other key APIs. However, given a PAKE primitive value, there is no API to extract the ECC family or key-bits values. I.e. an application using SPAKE2+ needs to either (a) use the retain/use the ECC-FAMILY and key-bits values to build the PAKE primitive, and to construct the key attributes, or (b) reverse engineer the encoding of the PAKE primitive (e.g. from here) to extract these values. Neither of those follow the pattern/spirit of existing Crypto APIs. My preferred suggestion is that we provide three macro APIs to extract the components from the PAKE primitive, so that application can construct the key attributes for SPAKE2+ from a PAKE primitive value. Constructing the key type directly from a PAKE primitive only solves half of the problem, so I would rule this out. An alternative that might address the issue would be a custom key attribute setter for PAKE, or perhaps just SPAKE2+, such as: This can use all of the necessary cipher-suite attributes to determine the correct type and size of the input key for PAKE. Note that for SPAKE2+, this would be the key-pair type, as the cipher-suite does not identify the role.
This association makes the most sense. In the current API,
I would like to stick with key-pair and public-key terminology/identifier names, and just map these to the algorithm-specific terms.
I think we should stick with just |
LGTM |
I agree that the most convenient way (for both implementation and application) to do this is with a dedicated API that constructs the appropriate attributes. (I mean
The only situation when the application needs to know the size of the key is when exporting and then they need to use the
My first thought for this was the key-pair and public-key terminology as well. Thinking about it a bit more it doesn't feel very precise and prone to confusion. That said, I can't think of anything better as the standards don't really use any terminology here. The closest thing they mention that these are stored in the registration record, but that doesn't fit very well what we need here. The key-pair and public-key terminology is probably the best we can do and it should work as long as we document the mappings as you suggested.
Yep, as you say
I think the list of elements approach is easier to read, but can be ambiguous. Which is not the end of the world as we usually reference a standard with detailed description.
Like above, I prefer the narrative style, I can always consult the standard for details if needed.
I think the :math: role is convenient to use and provides the best results. |
If this approach is agreeable, then is there any reason to limit this to setting the key type and size? The key policy can be uniquely determined from the cipher suite: a matching permitted algorithm and the void psa_set_pake_key_attributes(psa_key_attributes_t * attributes, const psa_pake_cipher_suite_t * cipher_suite);Its implementation could be something along the lines of: void psa_set_pake_key_attributes(psa_key_attributes_t * attributes, const psa_pake_cipher_suite_t * cipher_suite) {
const psa_algorithm_t alg = psa_pake_cs_get_algorithm(cipher_suite);
const psa_pake_primitive_t primitive = psa_pake_cs_get_primitive(cipher_suite);
if (PSA_ALG_IS_SPAKE2P(alg)) {
psa_set_key_type(attributes,
PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(PSA_PAKE_PRIMITIVE_GET_FAMILY(primitive)));
psa_set_key_bits(attributes, PSA_PAKE_PRIMITIVE_GET_BITS(primitive);
psa_set_key_algorithm(attributes, alg);
psa_set_key_usage_flags(attributes, PSA_KEY_USAGE_DERIVE);
}
}This would be used by applications during SPAKE2+ when constructing the SPAKE2+ 'keys' from the password: ...
psa_key_id_t spake_key;
psa_key_attributes_t att = PSA_KEY_ATTRIBUTES_INIT;
psa_set_pake_key_attributes(&att, &cipher_suite);
psa_key_derivation_output_key(&pbkdf, &att, &spake_key);
psa_key_derivation_abort(&pbkdf);
psa_pake_operation_t pake = PSA_PAKE_OPERATION_INIT;
psa_pake_setup(&pake, &cipher_suite, spake_key); |
I've realised that this is only helpful for the derivation of the key pair. A parallel solution is needed when importing a SPAKE2+ public key... |
b593449 to
b4264c3
Compare
|
Rebased this PR, and followed up on the feedback. Resolved most outstanding issues. |
* Add key encodings * Define public key format * Define key derivation procedure
* Add macros to crack a PAKE primitive value * Decide on using USAGE_DERIVE for SPAKE2+ keys * Fix typos * Update header file
* Constrain key derivation to SPAKE2+ key pairs * Specify the length of data extracted from the KDF during derivation * Use a list format to define the exported key format
b4264c3 to
3790204
Compare
|
[Rebased on top of merged SPAKE2+ PRs] |
I can see that you went with the getter macros, which makes sense: adding 3 simple getter macros is probably better than adding 2 potentially more complicated API functions. |
|
Open issues resolved:
|
Define and describe the asymmetric key types for the Prover and Verifier in SPAKE2+, as discussed in #73.
Open issues (now resolved):
Did I get the calculation of the bytes-to-extract for the key derivation right, for the 5 elliptic curves?Should we provide a help API (or APIs) to construct the SPAKE2+ key-pair and public-key attributes from a PAKE cipher-suite, for use during key derivation or key import? See this comment and following.