psa-api icon indicating copy to clipboard operation
psa-api copied to clipboard

Compatible reworking of asymmetric key type encoding

Open athoelke opened this issue 1 year ago • 4 comments

In version 1.1, the Crypto API encodes key types according to Appendix B.2.

For asymmetric keys, this allocates 4 bits for an 'ASYM-TYPE' value, and 7 bits for a 'FAMILY' value.

image

In v1.1, the ASYM-TYPE only has 3 values (RSA:0, EC:1, and FFDH:2); and the largest set of FAMILY values is for EC keys, with 10 distinct values (but utilising the 6 least significant bits of the field).

Looking ahead, we are likely to need additional asymmetric key encodings:

  • SM2 - this is a new EC family (see #22)
  • SM9 - maybe an EC family, but may need to be distinct ASYM-TYPE (see #108)
  • SPAKE2+ - new ASYM-TYPE, that can reuse EC families (see #66 and #73)
  • ML-KEM - new ASYM-TYPE (see #95)
  • ML-DSA - new ASYM-TYPE (see (#96)
  • SLH-DSA - new ASYM-TYPE, with family members (see #97)

This would begin to place significant pressure on the ASYM-TYPE field, consuming half of the available values.

Proposal

I propose two changes, that do not affect the values of existing key types, which will provide a better balance of encoding space, and extend the life of the encoding scheme:

  1. Split the bits differently: allocating 5 bits for ASYM-TYPE (bits[7:11]) and 6 for FAMILY (bits [1:6]). Currently bit 7 is zero in all specified key type encodings, so reallocating this bit will change, but not complicate macros that operate with key types.

    asymmetric_key

    Implementations that have internal macros, or other code, that use the ASYM-TYPE values literally (as in 0, 1, and 2) will need to be reviewed and reworked if this change was made.

  2. For key types that do not require FAMILY parameterization, (currently just RSA, but the above list adds ML-KEM and ML-DSA), we could improve use of the encoding space by allocating ASYM-TYPE:0 for key types that are not parameterized. Then use the FAMILY field to specify the specific key type.

This would be worth implementing for v1.2, and adopted by the PAKE extension when adding support for SPAKE2+.

Review

Does this conflict with any vendor-specific key types that have been introduced in implementations of the specification?

athoelke avatar Oct 18 '23 16:10 athoelke

Paying more attention to what we have in the specification today:

  • psa_ecc_family_t defines an 8-bit value. This includes the key type parity bit (bit 0), combined with the ECC-FAMILY field (bits 7:1). This states that the top bit of the ECC-FAMILY field is to define vendor-specific ECC families.
  • psa_dh_family_t defines an 8-bit value. This includes the key type parity bit (bit 0), combined with the DH-FAMILY field (bits 7:1). This states that the top bit of the DH-FAMILY field is to define vendor-specific ECC families.

This contradicts my analysis above, which was based on the Appendix B write-up of the key encoding.

However, the result of this is that ECC and FFDH keys now have two vendor bits: bit 15 and bit 7. It is not clear that this is necessary.

Would it be acceptable to now make an incompatible change and reclaim bit 7, and require that vendor-specific ECC and FFDH keys use bit15==1 to indicate a non-standard key type encoding (including family), and do not use bit 7 to indicate a non-standard family?

I wonder if any implementations are providing custom key encodings for ECC or FFDH? - and if so, are they using bit7==1 in those encodings?

athoelke avatar Oct 31 '23 21:10 athoelke

I wonder if any implementations are providing custom key encodings for ECC or FFDH? - and if so, are they using bit7==1 in those encodings?

Here's one in mbedtls: https://github.com/Mbed-TLS/mbedtls/blob/fc31cb28eeda7fafef1bd392fccee3b99035105b/include/psa/crypto_extra.h#L428. This is reproduced in projects that are forks of mbedtls....

athoelke avatar Nov 03 '23 15:11 athoelke

Although Mbed TLS declares PSA_DH_FAMILY_CUSTOM, we don't actually accept it during key creation, and we don't implement the feature (FFDH domain parameters) that would make it useful. So you can ignore it.

gilles-peskine-arm avatar Nov 03 '23 16:11 gilles-peskine-arm

Thank you for the clarification. I suspect that its presence in forks of mbedtls are unlikely to indicate that this is used by these other implementations of the API...

athoelke avatar Nov 03 '23 16:11 athoelke