quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

psa-limitations.md (14465B)


      1 This document lists current limitations of the PSA Crypto API (as of version
      2 1.1) that may impact our ability to (1) use it for all crypto operations in
      3 TLS and X.509 and (2) support isolation of all long-term secrets in TLS (that
      4 is, goals G1 and G2 in [strategy.md](strategy.md) in the same directory).
      5 
      6 This is supposed to be a complete list, based on a exhaustive review of crypto
      7 operations done in TLS and X.509 code, but of course it's still possible that
      8 subtle-but-important issues have been missed. The only way to be really sure
      9 is, of course, to actually do the migration work.
     10 
     11 Limitations relevant for G1 (performing crypto operations)
     12 ==========================================================
     13 
     14 Executive summary
     15 -----------------
     16 
     17 - Restartable/interruptible ECC operations: some operations (`sign_hash`) are
     18   already supported in PSA, but not used by TLS. The remaining operations
     19 (ECDH `key_agreement` and `export_public`) will be implemented in 4.0 or 4.x,
     20 and used by TLS in 4.x.
     21 - Arbitrary parameters for FFDH: use in TLS will be dropped in 4.0.
     22 - RSA-PSS parameters: already implemented safe though arguably non-compliant
     23   solution in Mbed TLS 3.4, no complaints so far.
     24 
     25 Restartable (aka interruptible) ECC operations
     26 ----------------------------------------------
     27 
     28 Support for interruptible ECDSA sign/verify was added to PSA in Mbed TLS 3.4.
     29 However, support for interruptible ECDH is not present yet. Also, PK, X.509 and
     30 TLS have not yet been adapted to take advantage of the new PSA APIs. See:
     31 - <https://github.com/Mbed-TLS/mbedtls/issues/7292>;
     32 - <https://github.com/Mbed-TLS/mbedtls/issues/7293>;
     33 - <https://github.com/Mbed-TLS/mbedtls/issues/7294>.
     34 
     35 Currently, when `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_ECP_RESTARTABLE` are
     36 both enabled, some operations that should be restartable are not (ECDH in TLS
     37 1.2 clients using ECDHE-ECDSA), as they are using PSA instead, and some
     38 operations that should use PSA do not (signature generation & verification) as
     39 they use the legacy API instead, in order to get restartable behaviour.
     40 
     41 Arbitrary parameters for FFDH
     42 -----------------------------
     43 
     44 Currently, the PSA Crypto API can only perform FFDH with a limited set of
     45 well-known parameters (some of them defined in the spec, but implementations
     46 are free to extend that set).
     47 
     48 TLS 1.2 (and earlier) on the other hand have the server send explicit
     49 parameters (P and G) in its ServerKeyExchange message. This has been found to
     50 be suboptimal for security, as it is prohibitively hard for the client to
     51 verify the strength of these parameters. This led to the development of RFC
     52 7919 which allows use of named groups in TLS 1.2 - however as this is only an
     53 extension, servers can still send custom parameters if they don't support the
     54 extension.
     55 
     56 In TLS 1.3 the situation will be simpler: named groups are the only
     57 option, so the current PSA Crypto API is a good match for that. (Not
     58 coincidentally, all the groups used by RFC 7919 and TLS 1.3 are included
     59 in the PSA specification.)
     60 
     61 There are several options here:
     62 
     63 1. Implement support for custom FFDH parameters in PSA Crypto: this would pose
     64    non-trivial API design problem, but most importantly seems backwards, as
     65 the crypto community is moving away from custom FFDH parameters. (Could be
     66 done any time.)
     67 2. Drop the DHE-RSA and DHE-PSK key exchanges in TLS 1.2 when moving to PSA.
     68    (For people who want some algorithmic variety in case ECC collapses, FFDH
     69 would still be available in TLS 1.3, just not in 1.2.) (Can only be done in
     70 4.0 or another major version.)
     71 3. Variant of the precedent: only drop client-side support. Server-side is
     72    easy to support in terms of API/protocol, as the server picks the
     73 parameters: we just need remove the existing `mbedtls_ssl_conf_dh_param_xxx()`
     74 APIs and tell people to use `mbedtls_ssl_conf_groups()` instead. (Can only be
     75 done in 4.0 or another major version.)
     76 4. Implement RFC 7919, support DHE-RSA and DHE-PSK only in conjunction with it
     77    when moving to PSA. Server-side would work as above; unfortunately
     78 client-side the only option is to offer named groups and break the handshake
     79 if the server didn't take on our offer. This is not fully satisfying, but is
     80 perhaps the least unsatisfying option in terms of result; it's also probably
     81 the one that requires the most work, but it would deliver value beyond PSA
     82 migration by implementing RFC 7919. (Implementing RFC 7919 could be done any
     83 time; making it mandatory can only be done in 4.0 or another major version.)
     84 
     85 As of early 2023, the plan is to go with option 2 in Mbed TLS 4.0, which has
     86 been announced on the mailing-list and got no push-back, see
     87 <https://github.com/Mbed-TLS/mbedtls/issues/5278>.
     88 
     89 RSA-PSS parameters
     90 ------------------
     91 
     92 RSA-PSS signatures are defined by PKCS#1 v2, re-published as RFC 8017
     93 (previously RFC 3447).
     94 
     95 As standardized, the signature scheme takes several parameters, in addition to
     96 the hash algorithm potentially used to hash the message being signed:
     97 - a hash algorithm used for the encoding function
     98 - a mask generation function
     99   - most commonly MGF1, which in turn is parametrized by a hash algorithm
    100 - a salt length
    101 - a trailer field - the value is fixed to 0xBC by PKCS#1 v2.1, but was left
    102   configurable in the original scheme; 0xBC is used everywhere in practice.
    103 
    104 Both the existing `mbedtls_` API and the PSA API support only MGF1 as the
    105 generation function (and only 0xBC as the trailer field), but there are
    106 discrepancies in handling the salt length and which of the various hash
    107 algorithms can differ from each other.
    108 
    109 ### API comparison
    110 
    111 - RSA:
    112   - signature: `mbedtls_rsa_rsassa_pss_sign()`
    113     - message hashed externally
    114     - encoding hash = MGF1 hash (from context, or argument = message hash)
    115     - salt length: always using the maximum legal value
    116   - signature: `mbedtls_rsa_rsassa_pss_sign_ext()`
    117     - message hashed externally
    118     - encoding hash = MGF1 hash (from context, or argument = message hash)
    119     - salt length: specified explicitly
    120   - verification: `mbedtls_rsassa_pss_verify()`
    121     - message hashed externally
    122     - encoding hash = MGF1 hash (from context, or argument = message hash)
    123     - salt length: any valid length accepted
    124   - verification: `mbedtls_rsassa_pss_verify_ext()`
    125     - message hashed externally
    126     - encoding hash = MGF1 hash from dedicated argument
    127     - expected salt length: specified explicitly, can specify "ANY"
    128 - PK:
    129   - signature: not supported
    130   - verification: `mbedtls_pk_verify_ext()`
    131     - message hashed externally
    132     - encoding hash = MGF1 hash, specified explicitly
    133     - expected salt length: specified explicitly, can specify "ANY"
    134 - PSA:
    135   - algorithm specification:
    136     - hash alg used for message hashing, encoding and MGF1
    137     - salt length can be either "standard" (<= hashlen, see note) or "any"
    138   - signature generation:
    139     - salt length: always <= hashlen (see note) and random salt
    140   - verification:
    141     - salt length: either <= hashlen (see note), or any depending on algorithm
    142 
    143 Note: above, "<= hashlen" means that hashlen is used if possible, but if it
    144 doesn't fit because the key is too short, then the maximum length that fits is
    145 used.
    146 
    147 The RSA/PK API is in principle more flexible than the PSA Crypto API. The
    148 following sub-sections study whether and how this matters in practice.
    149 
    150 ### Use in X.509
    151 
    152 RFC 4055 Section 3.1 defines the encoding of RSA-PSS that's used in X.509.
    153 It allows independently specifying the message hash (also used for encoding
    154 hash), the MGF (and its hash if MGF1 is used), and the salt length (plus an
    155 extra parameter "trailer field" that doesn't vary in practice"). These can be
    156 encoded as part of the key, and of the signature. If both encoding are
    157 presents, all values must match except possibly for the salt length, where the
    158 value from the signature parameters is used.
    159 
    160 In Mbed TLS, RSA-PSS parameters can be parsed and displayed for various
    161 objects (certificates, CRLs, CSRs). During parsing, the following properties
    162 are enforced:
    163 - the extra "trailer field" parameter must have its default value
    164 - the mask generation function is MGF1
    165 - encoding hash = message hashing algorithm (may differ from MGF1 hash)
    166 
    167 When it comes to cryptographic operations, only two things are supported:
    168 - verifying the signature on a certificate from its parent;
    169 - verifying the signature on a CRL from the issuing CA.
    170 
    171 The verification is done using `mbedtls_pk_verify_ext()`.
    172 
    173 Note: since X.509 parsing ensures that message hash = encoding hash, and
    174 `mbedtls_pk_verify_ext()` uses encoding hash = mgf1 hash, it looks like all
    175 three hash algorithms must be equal, which would be good news as it would
    176 match a limitation of the PSA API.
    177 
    178 It is unclear what parameters people use in practice. It looks like by default
    179 OpenSSL picks saltlen = keylen - hashlen - 2 (tested with openssl 1.1.1f).
    180 The `certtool` command provided by GnuTLS seems to be picking saltlen = hashlen
    181 by default (tested with GnuTLS 3.6.13). FIPS 186-4 requires 0 <= saltlen <=
    182 hashlen.
    183 
    184 ### Use in TLS
    185 
    186 In TLS 1.2 (or lower), RSA-PSS signatures are never used, except via X.509.
    187 
    188 In TLS 1.3, RSA-PSS signatures can be used directly in the protocol (in
    189 addition to indirect use via X.509). It has two sets of three signature
    190 algorithm identifiers (for SHA-256, SHA-384 and SHA-512), depending of what
    191 the OID of the public key is (rsaEncryption or RSASSA-PSS).
    192 
    193 In both cases, it specifies that:
    194 - the mask generation function is MGF1
    195 - all three hashes are equal
    196 - the length of the salt MUST be equal to the length of the digest algorithm
    197 
    198 When signing, the salt length picked by PSA is the one required by TLS 1.3
    199 (unless the key is unreasonably small).
    200 
    201 When verifying signatures, PSA will by default enforce the salt len is the one
    202 required by TLS 1.3.
    203 
    204 ### Current testing - X509
    205 
    206 All test files use the default trailer field of 0xBC, as enforced by our
    207 parser. (There's a negative test for that using the
    208 `x509_parse_rsassa_pss_params` test function and hex data.)
    209 
    210 Files with "bad" in the name are expected to be invalid and rejected in tests.
    211 
    212 **Test certificates:**
    213 
    214 server9-bad-mgfhash.crt (announcing mgf1(sha224), signed with another mgf)
    215          Hash Algorithm: sha256
    216          Mask Algorithm: mgf1 with sha224
    217           Salt Length: 0xDE
    218 server9-bad-saltlen.crt (announcing saltlen = 0xDE, signed with another len)
    219          Hash Algorithm: sha256
    220          Mask Algorithm: mgf1 with sha256
    221           Salt Length: 0xDE
    222 server9-badsign.crt (one bit flipped in the signature)
    223          Hash Algorithm: sha1 (default)
    224          Mask Algorithm: mgf1 with sha1 (default)
    225           Salt Length: 0xEA
    226 server9-defaults.crt
    227          Hash Algorithm: sha1 (default)
    228          Mask Algorithm: mgf1 with sha1 (default)
    229           Salt Length: 0x14 (default)
    230 server9-sha224.crt
    231          Hash Algorithm: sha224
    232          Mask Algorithm: mgf1 with sha224
    233           Salt Length: 0xE2
    234 server9-sha256.crt
    235          Hash Algorithm: sha256
    236          Mask Algorithm: mgf1 with sha256
    237           Salt Length: 0xDE
    238 server9-sha384.crt
    239          Hash Algorithm: sha384
    240          Mask Algorithm: mgf1 with sha384
    241           Salt Length: 0xCE
    242 server9-sha512.crt
    243          Hash Algorithm: sha512
    244          Mask Algorithm: mgf1 with sha512
    245           Salt Length: 0xBE
    246 server9-with-ca.crt
    247          Hash Algorithm: sha1 (default)
    248          Mask Algorithm: mgf1 with sha1 (default)
    249           Salt Length: 0xEA
    250 server9.crt
    251          Hash Algorithm: sha1 (default)
    252          Mask Algorithm: mgf1 with sha1 (default)
    253           Salt Length: 0xEA
    254 
    255 These certificates are signed with a 2048-bit key. It appears that they are
    256 all using saltlen = keylen - hashlen - 2, except for server9-defaults which is
    257 using saltlen = hashlen.
    258 
    259 **Test CRLs:**
    260 
    261 crl-rsa-pss-sha1-badsign.pem
    262          Hash Algorithm: sha1 (default)
    263          Mask Algorithm: mgf1 with sha1 (default)
    264           Salt Length: 0xEA
    265 crl-rsa-pss-sha1.pem
    266          Hash Algorithm: sha1 (default)
    267          Mask Algorithm: mgf1 with sha1 (default)
    268           Salt Length: 0xEA
    269 crl-rsa-pss-sha224.pem
    270          Hash Algorithm: sha224
    271          Mask Algorithm: mgf1 with sha224
    272           Salt Length: 0xE2
    273 crl-rsa-pss-sha256.pem
    274          Hash Algorithm: sha256
    275          Mask Algorithm: mgf1 with sha256
    276           Salt Length: 0xDE
    277 crl-rsa-pss-sha384.pem
    278          Hash Algorithm: sha384
    279          Mask Algorithm: mgf1 with sha384
    280           Salt Length: 0xCE
    281 crl-rsa-pss-sha512.pem
    282          Hash Algorithm: sha512
    283          Mask Algorithm: mgf1 with sha512
    284           Salt Length: 0xBE
    285 
    286 These CRLs are signed with a 2048-bit key. It appears that they are
    287 all using saltlen = keylen - hashlen - 2.
    288 
    289 **Test CSRs:**
    290 
    291 server9.req.sha1
    292          Hash Algorithm: sha1 (default)
    293          Mask Algorithm: mgf1 with sha1 (default)
    294           Salt Length: 0x6A
    295 server9.req.sha224
    296          Hash Algorithm: sha224
    297          Mask Algorithm: mgf1 with sha224
    298           Salt Length: 0x62
    299 server9.req.sha256
    300          Hash Algorithm: sha256
    301          Mask Algorithm: mgf1 with sha256
    302           Salt Length: 0x5E
    303 server9.req.sha384
    304          Hash Algorithm: sha384
    305          Mask Algorithm: mgf1 with sha384
    306           Salt Length: 0x4E
    307 server9.req.sha512
    308          Hash Algorithm: sha512
    309          Mask Algorithm: mgf1 with sha512
    310           Salt Length: 0x3E
    311 
    312 These CSRs are signed with a 2048-bit key. It appears that they are
    313 all using saltlen = keylen - hashlen - 2.
    314 
    315 ### Possible courses of action
    316 
    317 There's no question about what to do with TLS (any version); the only question
    318 is about X.509 signature verification. Options include:
    319 
    320 1. Doing all verifications with `PSA_ALG_RSA_PSS_ANY_SALT` - while this
    321    wouldn't cause a concrete security issue, this would be non-compliant.
    322 2. Doing verifications with `PSA_ALG_RSA_PSS` when we're lucky and the encoded
    323    saltlen happens to match hashlen, and falling back to `ANY_SALT` otherwise.
    324 Same issue as with the previous point, except more contained.
    325 3. Reject all certificates with saltlen != hashlen. This includes all
    326    certificates generated with OpenSSL using the default parameters, so it's
    327 probably not acceptable.
    328 4. Request an extension to the PSA Crypto API and use one of the above options
    329    in the meantime. Such an extension seems inconvenient and not motivated by
    330 strong security arguments, so it's unclear whether it would be accepted.
    331 
    332 Since Mbed TLS 3.4, option 1 is implemented.
    333 
    334 Limitations relevant for G2 (isolation of long-term secrets)
    335 ============================================================
    336 
    337 Currently none.