ARM-software / psa-api

Documentation source and development of the PSA Certified API
https://arm-software.github.io/psa-api/
Other
56 stars 27 forks source link

New algorithm: Ad-hoc KDF for EC J-PAKE in TLS 1.2 #11

Closed athoelke closed 1 year ago

athoelke commented 1 year ago

Add API elements for the algorithm and supporting macros for the KDF used with EC J-PAKE in the TLS 1.2.

This has already been included in the development branch of Mbed-TLS (see https://github.com/Mbed-TLS/mbedtls/pull/6115), following review with the Crypto API authors.

Todo:

The relevant Mbed-TLS changes are as follows:

/* The TLS 1.2 ECJPAKE-to-PMS KDF. It takes the shared secret K (an EC point
 * in case of EC J-PAKE) and calculates SHA256(K.X) that the rest of TLS 1.2
 * will use to derive the session secret, as defined by step 2 of
 * https://datatracker.ietf.org/doc/html/draft-cragie-tls-ecjpake-01#section-8.7.
 * Uses PSA_ALG_SHA_256.
 * This function takes a single input:
 * #PSA_KEY_DERIVATION_INPUT_SECRET is the shared secret K from EC J-PAKE.
 * The only supported curve is secp256r1 (the 256-bit curve in
 * #PSA_ECC_FAMILY_SECP_R1), so the input must be exactly 65 bytes.
 * The output has to be read as a single chunk of 32 bytes, defined as
 * PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE.
 */
#define PSA_ALG_TLS12_ECJPAKE_TO_PMS            ((psa_algorithm_t)0x08000609)

/* The size of a serialized K.X coordinate to be used in
 * psa_tls12_ecjpake_to_pms_input. This function only accepts the P-256
 * curve. */
#define PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE 32
athoelke commented 1 year ago

Prior to finalizing this in the API specification, there is one area of discussion in relation to this API, that also impacts the EC J-PAKE API as currently defined in the beta PAKE Extension.

The PAKE API currently defines the shared secret output as K, the full uncompressed point on the curve. At the time the PAKE extension was written, this was chosen as it provides the most flexibility for uses of this algorithm - although the x-coordinate K.X has only 1 fewer bies of the information, reconstructing the full point is non-trivial. In contrast, the existing ECDH algorithms are specified to only output the 32-byte x-coordinate from the agreement, for input to a KDF.

RFC 8236 doesn't help here because it does not define precisely what should be used as the shared output from the PAKE exchange.

See this discussion on one of the PRs introducing this functionality into Mbed TLS, for other detalis & opinions.

There are two ways forward:

  1. Redefine the output of EC J-PAKE

    If there is no benefit (from a usage perspective) in retaining the full point out of the EC J-PAKE operation, we could update the PAKE spec to redefine this algorithm output as K.X, and align with the ECDH algorithm.

    We would then define this KDF to just be the SHA-256 of the 32-byte input (from EC J-PAKE).

  2. Retain the existing EC J-PAKE definition

    This results in a definition for the KDF which is awkward (it extracts and hashes bytes 1-32 from the 65-byte input). But this does not introduce any churn/incompatibility for existing implementations of the EC J-PAKE Extension API.

The definition of BKAM2 in ISO 11770 might be a tie-breaker, as it also defines a KDF for use with EC J-PAKE. This avenue of inquiry has not been resolved.

athoelke commented 1 year ago

The current opinion, is to pursue option (2), using the current definition of the output from the EC J-PAKE algorithm in the PAKE extension. The input to this KDF is the uncompressed point K.

Note that the PAKE API only permits the shared secret to be extracted using psa_pake_get_implicit_key(), which directly inputs the secret into a key-derivation operation as the PSA_KEY_DERIVATION_INPUT_SECRET step.

As the PAKE API provides no mechanism to extract the shared PAKE secret into memory, or into a key, the use of this KDF with the PAKE extension does not depend on this KDF accepting input via psa_key_derivation_input_bytes() or psa_key_derivation_input_key().

Although this might appear to suggest we could leave the transfer format for K implementation-defined, that is not adequate if an alternative KDF is used with EC J-PAKE. So, as we must define the format of the PAKE output and KDF input, then should we expect that implementations will support input to this KDF via keys or memory buffers, consistent with other KDFs. Or is it worth treating this differently and permitting implementations to only support input via psa_pake_get_implicit_key()?

athoelke commented 1 year ago

This introduces an output size macro (I've named it more clearly as PSA_TLS12_ECJPAKE_TO_PMS_OUTPUT_SIZE in the PR for this #91) that is algorithm specific.

For consistency with the other APIs, we could make this a category-based macro such as PSA_KEY_DERIVATION_OUTPUT_SIZE(kdf_alg)? For a key derivation operation, though, it is not always obvious what should be returned: