-
Notifications
You must be signed in to change notification settings - Fork 96
Streamline PSA key type and curve encodings #330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Streamline PSA key type and curve encodings #330
Conversation
(type) == PSA_KEY_TYPE_ARC4 ? 1 : \ | ||
(type) == PSA_KEY_TYPE_CHACHA20 ? 1 : \ | ||
0) | ||
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically redundant test as the specification of the macro says "unspecified if not a supported cipher key type".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the Mbed Crypto implementation which currently tends to favor robustness over minimal code size.
include/psa/crypto_values.h
Outdated
* 2048, 3072, 4096, 6144, 8192. A given implementation may support | ||
* all of these sizes or only a subet. | ||
*/ | ||
#define PSA_DH_GROUP_RFC7919 ((psa_dh_group_t) 0x02) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presume this should bx 0x020000
? - to align with the definition of the ECC group families?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least - when first introduced, until the commit that changes to 16-bit key types...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I amended the old commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a design perspective, this looks pretty sound to me. It deals with some primary concerns:
- improves code size and coding logic for applications, by not encoding the key size in different ways in two places
- increases room for vendor defined keys in the ECC and DH spaces
- Provides some mitigation against bit-flip fault attacks.
cc2dbc6
to
450546a
Compare
include/psa/crypto_values.h
Outdated
* | ||
* This family includes groups with the following key sizes (in bits): | ||
* 2048, 3072, 4096. A given implementation may support | ||
* all of these sizes or only a subet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"subet" -> "subset"
include/psa/crypto_values.h
Outdated
@@ -568,14 +581,22 @@ | |||
((type) & PSA_KEY_TYPE_DH_GROUP_MASK) : \ | |||
0)) | |||
|
|||
/** Diffie-Hellman groups defined in RFC 7919 Appendix A. | |||
/** Diffie-Hellman FFDHE groups defined in RFC 7919 Appendix A. | |||
* | |||
* This family includes groups with the following key sizes (in bits): | |||
* 2048, 3072, 4096, 6144, 8192. A given implementation may support | |||
* all of these sizes or only a subet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"subet" -> "subset"
c58e7df
to
f8255b0
Compare
f8255b0
to
7442f9e
Compare
7442f9e
to
7066307
Compare
include/psa/crypto_sizes.h
Outdated
(curve) == PSA_ECC_CURVE_CURVE25519 ? 255 : \ | ||
(curve) == PSA_ECC_CURVE_CURVE448 ? 448 : \ | ||
0) | ||
#define PSA_ECC_CURVE_BITS(curve) ((curve) & 0xffff) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't going to work anymore after the removal of the curve size from the key type.
There are a few more places which refer to the ECC curves using wildcard references (PSA_ECC_CURVE_XXX):
|
a680910
to
48d4763
Compare
Internally, use the corresponding function from psa_crypto.c instead. Externally, this function is not used in Mbed TLS and is documented as "may change at any time".
Don't assume that the PSA encoding of elliptic curves is identical to the TLS encoding. This is currently true but about to change. The new implementation only works when MBEDTLS_ECP_C is defined. This is ok because the function is only used with MBEDTLS_ECP_C defined.
Change the representation of psa_ecc_curve_t and psa_dh_group_t from the IETF 16-bit encoding to a custom 24-bit encoding where the upper 8 bits represent a curve family and the lower 16 bits are the key size in bits. Families are based on naming and mathematical similarity, with sufficiently precise families that no two curves in a family have the same bit size (for example SECP-R1 and SECP-R2 are two different families). As a consequence, the lower 16 bits of a key type value are always either the key size or 0.
Define constants for ECC curve families and DH group families. These constants have 0x0000 in the lower 16 bits of the key type. Support these constants in the implementation and in the PSA metadata tests. Switch the slot management and secure element driver HAL tests to the new curve encodings. This requires SE driver code to become slightly more clever when figuring out the bit-size of an imported EC key since it now needs to take the data size into account. Switch some documentation to the new encodings. Remove the macro PSA_ECC_CURVE_BITS which can no longer be implemented.
Use the same translation function that the PSA crypto implementation uses.
This is a change to an internal API that is exposed only for the sake of Mbed TLS.
Remove the values of curve encodings that are based on the TLS registry and include the curve size, keeping only the new encoding that merely encodes a curve family in 8 bits. Keep the old constant names as aliases for the new values and deprecate the old names.
All key types now have an encoding on 32 bits where the bottom 16 bits are zero. Change to using 16 bits only. Keep 32 bits for key types in storage, but move the significant half-word from the top to the bottom. Likewise, change EC curve and DH group families from 32 bits out of which the top 8 and bottom 16 bits are zero, to 8 bits only. Reorder psa_core_key_attributes_t to avoid padding.
Change the encoding of key types, EC curve families and DH group families to make the low-order bit a parity bit (with even parity). This ensures that distinct key type values always have a Hamming distance of at least 2, which makes it easier for implementations to resist single bit flips.
If psa_key_agreement_ecdh fails, there may be output that leaks sensitive information in the output buffer. Zeroize it. If this is due to an underlying failure in the ECDH implementation, it is currently not an issue since both the traditional Mbed TLS/Crypto implementation and Everest only write to the output buffer once every intermediate step has succeeded, but zeroizing is more robust. If this is because the recently added key size check fails, a leak could be a serious issue.
79ab5ce
to
3e819b7
Compare
The Crypto CI passed except for Mbed OS which is already broken before this PR and will require a further update after this PR. The TLS CI is not expected to pass here because an update of the crypto submodule is required. Mbed-TLS/mbedtls#2964 updates the crypto submodule. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only subjective clarity improvements recommended, non-blocking.
With two approvals and with acceptable CI (crypto and TLS pass except for known unrelated failures), this is ready for merge. Since it will disrupt TLS testing until the corresponding TLS PR Mbed-TLS/mbedtls#2964 is merged, we should merge this when we're ready to move on with Mbed-TLS/mbedtls#2964. |
Previously in d875285: * ARMmbed#333: Streamline PSA key type encodings: prepare * ARMmbed#323: Initialise return values to an error Previously in dbcb442: * ARMmbed#291: Test MBEDTLS_CTR_DRBG_USE_128_BIT_KEY * ARMmbed#334: Fix some pylint warnings Previously in ceceedb: * ARMmbed#348: Bump version to Mbed TLS 2.20.0 and crypto SO version to 4 * ARMmbed#354: Fix incrementing pointer instead of value In this commit: * ARMmbed#349: Fix minor defects found by Coverity * ARMmbed#179: Add option to build SHA-512 without SHA-384 * ARMmbed#327: Implement psa_hash_compute and psa_hash_compare * ARMmbed#330: Streamline PSA key type and curve encodings
Change
psa_key_type_t
to a more compact 16-bit type.Change the encoding of elliptic curves (and FFDH groups) drastically: now there is an 8-bit curve family in the lower 8 bits of the key type. A curve family can include several curves as long as they all have different octet lengths. The precise curve is determined by the curve family and the key size, which is fully known when generating or deriving a key and known up to byte granularity when importing a key. Rationale: it makes the encoding more compact, and makes it easier for applications to work with multiple curves without having to embed a conversion between the curve/type encoding and the size.
Distinct key types have a Hamming distance of at least 2. This helps implementations that protect against a single bit flip. This is done by making the least significant bit a parity bit.
Elliptic curves no longer use the encoding from the TLS registry, which was restrictive because it has little room reserved for curves that aren't in the registry, but the world outside TLS uses quite a few curves that aren't used in TLS.
Private discussion about the design: https://github.com/ARMmbed/psa-crypto/issues/122#issuecomment-561096308
This breaks the build of the attestation service in Mbed OS due to the change in how elliptic curves are encoded.
Needs preceding PRs: