Document PSA limitations that could be problems
(WIP: the study of RSA-PSS is incomplete.) Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This commit is contained in:
parent
b89fd95146
commit
d9edd56bf8
1 changed files with 224 additions and 0 deletions
224
docs/architecture/psa-migration/psa-limitations.md
Normal file
224
docs/architecture/psa-migration/psa-limitations.md
Normal file
|
@ -0,0 +1,224 @@
|
|||
This document lists current limitations of the PSA Crypto API (as of version
|
||||
1.1) that may impact our ability to (1) use it for all crypto operations in
|
||||
TLS and X.509 and (2) support isolation of all long-term secrets in TLS (that
|
||||
is, goals G1 and G2 in [strategy.md][] in the same directory).
|
||||
|
||||
This is supposed to be a complete list, based on a exhaustive review of crypto
|
||||
operations done in TLS and X.509 code, but of course it's still possible that
|
||||
subtle-but-important issues have been missed. The only way to be really sure
|
||||
is, of course, to actually do the migration work.
|
||||
|
||||
Limitations relevant for G1 (performing crypto operations)
|
||||
==========================================================
|
||||
|
||||
Restartable ECC operations
|
||||
--------------------------
|
||||
|
||||
There is currently no support for that in PSA at all. API design, as well as
|
||||
implementation, would be non-trivial.
|
||||
|
||||
Currently, `MBEDTLS_USE_PSA_CRYPTO` is simply incompatible with
|
||||
`MBEDTLS_ECP_RESTARTABLE`.
|
||||
|
||||
Arbitrary parameters for FFDH
|
||||
-----------------------------
|
||||
|
||||
Currently, the PSA Crypto API can only perform FFDH with a limited set of
|
||||
well-know parameters (some of them defined in the spec, but implementations
|
||||
are free to extend that set).
|
||||
|
||||
TLS 1.2 (and earlier) on the other hand have the server send explicit
|
||||
parameters (P and G) in is ServerKeyExchange message. This has been found to
|
||||
be suboptimal for security, as it is prohibitively hard for the client to
|
||||
verify the strength of these parameters. This led to the development of RFC
|
||||
7919 which allows use of named groups in TLS 1.2 - however as this is only an
|
||||
extension, servers can still send custom parameters if they don't support the
|
||||
extension.
|
||||
|
||||
In TLS 1.3 the situation will be simpler: named groups are the only
|
||||
option, so the current PSA Crypto API is a good match for that. (Not
|
||||
coincidentally, the groups used by RFC 7919 and TLS 1.3 are part those defined
|
||||
in the specification.)
|
||||
|
||||
There are several options here:
|
||||
|
||||
1. Implement support for custom FFDH parameters in PSA Crypto: this would pose
|
||||
non-trivial API design problem, but most importantly seems backwards, as
|
||||
the crypto community is moving away from custom FFDH parameters.
|
||||
2. Drop the DHE-RSA and DHE-PSK key exchanges in TLS 1.2 when moving to PSA.
|
||||
3. Implement RFC 7919, support DHE-RSA and DHE-PSK only in conjunction with it
|
||||
when moving to PSA. We can modify our server so that it only selects a DHE
|
||||
ciphersuite if the client offered name FFDH groups; unfortunately
|
||||
client-side the only option is to offer named groups and break the handshake
|
||||
if the server didn't take on our offer. This is not fully satisfying, but is
|
||||
perhaps the least unsatisfying option in terms of result; it's also probably
|
||||
the one that requires the most work, but it would deliver value beyond PSA
|
||||
migration by implementing RFC 7919.
|
||||
|
||||
RSA-PSS parameters
|
||||
------------------
|
||||
|
||||
RSA-PSS signatures are defined by PKCS#1 v2, re-published as RFC 8017
|
||||
(previously RFC 3447).
|
||||
|
||||
As standardized, the signature scheme takes several parameters, in addition to
|
||||
the hash algorithm potentially used to hash the message being signed:
|
||||
- a hash algorithm use for the encoding function
|
||||
- a mask generation function
|
||||
- most commonly MGF1, which in turn is parametrized by a hash algorithm
|
||||
- a salt length
|
||||
|
||||
Both the existing `mbedtls_` API and the PSA API support only MGF1 as the
|
||||
generation function, but there are discrepancy in handling the salt length and
|
||||
which of the various hash algorithms can differ from each other.
|
||||
|
||||
### API comparison
|
||||
|
||||
- RSA:
|
||||
- signature: `mbedtls_rsa_rsassa_pss_sign()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash (from context, or argument = message hash)
|
||||
- salt length: always using the maximum legal value
|
||||
- signature: `mbedtls_rsa_rsassa_pss_sign_ext()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash (from context, or argument = message hash)
|
||||
- salt length: specified explicitly
|
||||
- verification: `mbedtls_rsassa_pss_verify()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash (from context, or argument = message hash)
|
||||
- salt length: any valid length accepted
|
||||
- verification: `mbedtls_rsassa_pss_verify_ext()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash from dedicated argument
|
||||
- expected salt length: specified explicitly, can specify "ANY"
|
||||
- PK:
|
||||
- signature: not supported
|
||||
- verification: `mbedtls_pk_verify_ext()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash, specified explicitly
|
||||
- expected salt length: specified explicitly, can specify "ANY"
|
||||
- PSA:
|
||||
- algorithm specification:
|
||||
- hash alg used for message hashing, encoding and MGF1
|
||||
- salt length cannot be specified
|
||||
- signature generation:
|
||||
- salt length: always using the maximum legal value
|
||||
- verification:
|
||||
- salt length: any valid length accepted
|
||||
|
||||
The RSA/PK API is in principle more flexible than the PSA Crypto API. The
|
||||
following sub-sections study whether and how this matters in practice.
|
||||
|
||||
### Use in X.509
|
||||
|
||||
RFC 4055 Section 3.1 defines the encoding of RSA-PSS that's used in X.509.
|
||||
It allows independently specifying the message hash (also used for encoding
|
||||
hash), the MGF (and its hash if MGF1 is used), and the salt length (plus an
|
||||
extra parameter "trailer field" that doesn't vary in practice"). These can be
|
||||
encoded as part of the key, and of the signature. If both encoding are
|
||||
presents, all values must match except possibly for the salt length, where the
|
||||
value from the signature parameters is used.
|
||||
|
||||
In Mbed TLS, RSA-PSS parameters can be parsed and displayed for various
|
||||
objects (certificates, CRLs, CSRs). During parsing, the following properties
|
||||
are enforced:
|
||||
- (the extra "trailer field" parameter must has its default value)
|
||||
- the mask generation function is MGF1
|
||||
- encoding hash = message hashing algorithm (may differ from MGF1 hash)
|
||||
|
||||
When it comes to cryptographic operations, only two things are supported:
|
||||
- verifying the signature on a certificate from its parent;
|
||||
- verifying the signature on a CRL from the issuing CA.
|
||||
|
||||
The verification is done using `mbedtls_pk_verify_ext()`.
|
||||
|
||||
Note: since X.509 parsing ensures that message hash = encoding hash, and
|
||||
`mbedtls_pk_verify_ext()` use encoding hash = mgf1 hash, it looks like all
|
||||
three hash algorithms must be equal, which would be good news as it would
|
||||
match a limitation of the PSA API. (TODO: double-check that.)
|
||||
|
||||
Also, since we only use signature verification, the fact that PSA accepts any
|
||||
valid salt length means that no valid certificate would be wrongly rejected;
|
||||
however it means that signatures that don't match the announced salt length
|
||||
would be incorrectly accepted. At first glance, it looks like this doesn't
|
||||
allow an attacker to forge certificates, so this might be acceptable in
|
||||
practice, while not fully implementing all the checks in the standard. (TODO:
|
||||
triple-check that.)
|
||||
|
||||
It is unclear what parameters people use in practice.
|
||||
|
||||
### Use in TLS
|
||||
|
||||
In TLS 1.2 (or lower), RSA-PSS signatures are never used, except via X.509.
|
||||
|
||||
In TLS 1.3, RSA-PSS signatures can be used directly in the protocol (in
|
||||
addition to indirect use via X.509). It has two sets of three signature
|
||||
algorithm identifiers (for SHA-256, SHA-384 and SHA-512), depending of what
|
||||
the OID of the public key is (rsaEncryption or RSASSA-PSS).
|
||||
|
||||
In both cases, it specifies that:
|
||||
- the mask generation function is MGF1
|
||||
- all three hashes are equal
|
||||
- the length of the salt MUST be equal to the length of the digest algorithm
|
||||
|
||||
When signing, the salt length picked by PSA is the one required by TLS 1.3
|
||||
(unless the key is unreasonably small).
|
||||
|
||||
When verifying signatures, again is doesn't look like accepting any salt
|
||||
length would give an attacker any advantage, but this must be triple-checked
|
||||
(TODO).
|
||||
|
||||
### Current testing - X509
|
||||
|
||||
TODO: look at the parameters used by the various test files
|
||||
|
||||
- server9.crt
|
||||
-HASH
|
||||
-badsign
|
||||
-defaults
|
||||
-bad-saltlen
|
||||
-bad-mgfhash
|
||||
- crl-rsa-pss-HASH.pem
|
||||
- server9.req.HASH
|
||||
|
||||
### Possible course of actions
|
||||
|
||||
TODO - once the previous section has been completed
|
||||
|
||||
Limitations relevant for G2 (isolation of long-term secrets)
|
||||
============================================================
|
||||
|
||||
Custom key derivations for mixed-PSK handshake
|
||||
----------------------------------------------
|
||||
|
||||
Currently, `MBEDTLS_USE_PSA_CRYPTO` enables the new configuration function
|
||||
`mbedtls_ssl_conf_psk_opaque()` which allows a PSA-held key to be used for the
|
||||
(pure) `PSK` key exchange in TLS 1.2. This requires that the derivation of the
|
||||
Master Secret (MS) be done on the PSA side. To support this, an algorithm
|
||||
family `PSA_ALG_TLS12_PSK_TO_MS(hash_alg)` was added to PSA Crypto.
|
||||
|
||||
If we want to support key isolation for the "mixed PSK" key exchanges:
|
||||
DHE-PSK, RSA-PSK, ECDHE-PSK, where the PSK is concatenated with the result of
|
||||
a DH key agreement (resp. RSA decryption) to form the pre-master secret (PMS)
|
||||
from which the MS is derived. If the value of the PSK is to remain hidden, we
|
||||
need the derivation PSK + secondary secret -> MS to be implemented as an
|
||||
ad-hoc PSA key derivation algorithm.
|
||||
|
||||
Adding this new, TLS-specific, key derivation algorithm to PSA Crypto should
|
||||
be no harder than it was to add `PSA_ALG_TLS12_PSK_TO_MS()` but still requires
|
||||
an extension to PSA Crypto.
|
||||
|
||||
Note: looking at RFCs 4279 and 5489, it appears that the structure of the PMS
|
||||
is always the same: 2-byte length of the secondary secret, secondary secret,
|
||||
2-byte length of the PSK, PSK. So, a single key derivation algorithm should be
|
||||
able to cover the 3 key exchanges DHE-PSK, RSA-PSK and ECDHE-PSK. (That's a
|
||||
minor gain: adding 3 algorithms would not be a blocker anyway.)
|
||||
|
||||
Note: if later we want to also isolate short-term secret (G3), the "secondary
|
||||
secret" (output of DHE/ECDHE key agreement or RSA decryption) could be a
|
||||
candidate. This wouldn't be a problem as the PSA key derivation API always
|
||||
allows inputs from key slots. (Tangent: the hard part in isolating the result
|
||||
of RSA decryption would be still checking that is has the correct format:
|
||||
48 bytes, the first two matching the TLS version - note that this is timing
|
||||
sensitive.)
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue