-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
This issue is meant as a place to discuss what we want to do with PK in 4.0.
There are two main options:
- Keep it as part of the public API until 5.0, but aim to make it a thin wrapper around PSA Crypto (in 4.0 or 4.x).
- Remove it from the public API in 4.0, and eventually remove it entirely (in 4.0 or 4.x).
Scope of PK
- Crypto operations similar to two PSA Crypto families: asymmetric signature (RSA, ECDSA) and asymmetric encryption (RSA).
- Note: that's not all asymmetric crypto: key agreement (ECDH) and PAKE (EC J-PAKE) are not covered.
- Writing and parsing of public and private keys (ECC, RSA) in a variety of formats currently not supported by PSA.
- The
pk_contextstructure serves as a container for public/private keys, which tend to be longer-lived and more often user-provided.
Note: for low-level modules related to asymmetric crypto (rsa.h, ecdsa.h covered by PK, but also ecdh.h and ecjpake.h, and underneath them ecp.h and bignum.h) I think the plan is to remove them from the public API, regardless of what we do with PK.
The problem of X.509 vs the PSA key store
With option 1 and pk_context structures being thin wrappers around psa_key_id_t, or with option 2 and blindly replacing all uses of pk_context with psa_key_id_t and no other code change, we'd have the following problem:
- It is not unusual with X.509 to have a more than a hundred trust roots (currently 147 on my Ubuntu laptop).
- When parsing these (for example with
mbedtls_x509_crt_parse_path()) apsa_key_id_twould be created to hold each certificate's public key, resulting in 100+ PSA key slots being used simultaneously. - But currently the default size of the PSA key store (
MBEDTLS_PSA_KEY_SLOT_COUNT) is 32. - Hence this use case would break in the default config.
There are a number of ways to avoid that problem; we can act at any step in the chain leading to that potential issue:
- The easiest and most obvious would be to up the default value of
MBEDTLS_PSA_KEY_SLOT_COUNTto something like 256. - We could also change X.509 so that it doesn't load the key into a
pk_context/psa_key_id_twhen parsing a certificate, but only when actually doing an operation with the key. This might be desirable for other reasons and have even been done in the baremetal branch as part of "on-demand parsing" which significantly improved RAM usage. But it requires designing new APIs for users to access the public key embedded in a certificate. - If we keep PK but make it a thin wrapper around PSA, we could go with a hybrid approach where it stores private keys into PSA key slots, but public keys serialized in a way that
psa_import()accepts - and then only load them into a temporary PSA key slot when used. (Note: that's the approach currently used byMBEDTLS_PK_USE_PSA_EC_DATA.)
Rationale for option 1 (keep)
This gives users more time to move to PSA. People who were using low-level modules (including those not covered by PK) need to migrate immediately, but those who were only using the generic PK API can migrate at a convenient time between now and 5.0.
Work needed for option 1 (keep)
In 4.0:
- We may still want to remove some parts:
- strings:
mbedtls_pk_get_name()- see Remove parts of md, cipher and pk #8133 item 1 - access to low-level context: Remove mbedtls_pk_ec and mbedtls_pk_rsa #7572 - this might require providing replacements (see the discussion there).
mbedtls_pk_setup_opaque()as the plainpk_setup()should end up having the same effect.mbedtls_pk_setup_rsa_alt()andMBEDTLS_PK_RSA_ALT_SUPPORTas they seem redundant with the driver API.
- strings:
- We might want to remove
mbedtls_pk_info_tfrom the API in order to make it slicker but that would require users to change their code, so it runs against the stated goal. (Alternatively, we can keep the structure but later make it trivial as it has no public field.) - We need some investigation (probably including a prototype) to make sure the current API can be implemented efficiently as a thin wrapper around PSA. Note: for crypto operations, this is already mostly the case with
USE_PSA_CRYPTO; when usingmbedtls_pk_setup_opaque()(or whenMBEDTLS_PK_USE_PSA_EC_DATAis defined) that's also the case for (ECC) key storage.
In 4.0 or 4.x:
- Actually make it a thin wrapper around PSA crypto.
- Migrate all internal users (library and tests) to use PSA Crypto directly (note: common with option 2).
Rationale for option 2 (remove)
This leaves us with only one PK API to maintain, document and test. For new users, this also gives more clarity.
Note the current pk.h API has a few shortcomings, the most prominent being it doesn't manage key permissions like PSA does. So, pushing users to the PSA API is also pushing them to a better API.
Work needed for option 2 (remove)
In 4.0:
- Design and implement a PSA replacement for PK parse. Note: that's probably an EPIC on its own, but also something we want to do anyway.
- Update all TLS and X.509 APIs that handle a
pk_context:- X.509:
mbedtls_x509write_crt_set_subject_key(),mbedtls_x509write_crt_set_issuer_key()andmbedtls_x509write_csr_set_key()+ public fields inmbedtls_x509_crtandmbedtls_x509_csrstructure, and some private fields too. - TLS:
mbedtls_ssl_conf_own_cert()andmbedtls_ssl_set_hs_own_cert().
- X.509:
- Move
pk.hto an internal location and adapt all files that#includeit. - Change or remove all example programs that used it.
- Provide a migration guide.
In 4.0 or 4.x:
- Refactor
psa_crypto_cipher.cso that it no longer - Migrate all remaining internal users (library and tests) to use PSA Crypto directly (note: common with option 2).
- Then remove Cipher from the code base entirely.
Other options
- We could go for a mix: keep some parts but remove others. For example, we could keep PK parse or
pk_contextbut remove the part about doing operations? - Other?
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status
Status