Merge pull request #9005 from valeriosetti/issue8712-backport

[Backport 3.6] Clarify the documentation of mbedtls_pk_setup_opaque
This commit is contained in:
Bence Szépkúti 2024-04-04 13:41:15 +00:00 committed by GitHub
commit ec17c1c1ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 53 additions and 61 deletions

View File

@ -75,13 +75,8 @@ operations and its public part can be exported.
**Benefits:** isolation of long-term secrets, use of PSA Crypto drivers.
**Limitations:** can only wrap a key pair, can only use it for private key
operations. (That is, signature generation, and for RSA decryption too.)
Note: for ECDSA, currently this uses randomized ECDSA while Mbed TLS uses
deterministic ECDSA by default. The following operations are not supported
with a context set this way, while they would be available with a normal
context: `mbedtls_pk_check_pair()`, `mbedtls_pk_debug()`, all public key
operations.
**Limitations:** please refer to the documentation of `mbedtls_pk_setup_opaque()`
for a full list of supported operations and limitations.
**Use in X.509 and TLS:** opt-in. The application needs to construct the PK context
using the new API in order to get the benefits; it can then pass the

View File

@ -359,32 +359,40 @@ int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info);
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief Initialize a PK context to wrap a PSA key.
* \brief Initialize a PK context to wrap a PSA key.
*
* \note This function replaces mbedtls_pk_setup() for contexts
* that wrap a (possibly opaque) PSA key instead of
* storing and manipulating the key material directly.
* This function creates a PK context which wraps a PSA key. The PSA wrapped
* key must be an EC or RSA key pair (DH is not suported in the PK module).
*
* \param ctx The context to initialize. It must be empty (type NONE).
* \param key The PSA key to wrap, which must hold an ECC or RSA key
* pair (see notes below).
* Under the hood PSA functions will be used to perform the required
* operations and, based on the key type, used algorithms will be:
* * EC:
* * verify, verify_ext, sign, sign_ext: ECDSA.
* * RSA:
* * sign, decrypt: use the primary algorithm in the wrapped PSA key;
* * sign_ext: RSA PSS if the pk_type is #MBEDTLS_PK_RSASSA_PSS, otherwise
* it falls back to the sign() case;
* * verify, verify_ext, encrypt: not supported.
*
* \note The wrapped key must remain valid as long as the
* wrapping PK context is in use, that is at least between
* the point this function is called and the point
* mbedtls_pk_free() is called on this context. The wrapped
* key might then be independently used or destroyed.
* In order for the above operations to succeed, the policy of the wrapped PSA
* key must allow the specified algorithm.
*
* \note This function is currently only available for ECC or RSA
* key pairs (that is, keys containing private key material).
* Support for other key types may be added later.
* Opaque PK contexts wrapping an EC keys also support \c mbedtls_pk_check_pair(),
* whereas RSA ones do not.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
* (context already used, invalid key identifier).
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an
* ECC key pair.
* \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
* \warning The PSA wrapped key must remain valid as long as the wrapping PK
* context is in use, that is at least between the point this function
* is called and the point mbedtls_pk_free() is called on this context.
*
* \param ctx The context to initialize. It must be empty (type NONE).
* \param key The PSA key to wrap, which must hold an ECC or RSA key pair.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input (context already
* used, invalid key identifier).
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an ECC or
* RSA key pair.
* \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
*/
int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
const mbedtls_svc_key_id_t key);

View File

@ -1327,43 +1327,19 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
}
if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t psa_alg, sign_alg;
#if defined(MBEDTLS_PSA_CRYPTO_C)
psa_algorithm_t psa_enrollment_alg;
#endif /* MBEDTLS_PSA_CRYPTO_C */
psa_status_t status;
status = psa_get_key_attributes(ctx->priv_id, &key_attr);
if (status != PSA_SUCCESS) {
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
}
psa_alg = psa_get_key_algorithm(&key_attr);
#if defined(MBEDTLS_PSA_CRYPTO_C)
psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr);
#endif /* MBEDTLS_PSA_CRYPTO_C */
psa_reset_key_attributes(&key_attr);
/* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between
* alg and enrollment alg should be of type RSA_PSS. */
if (PSA_ALG_IS_RSA_PSS(psa_alg)) {
sign_alg = psa_alg;
}
#if defined(MBEDTLS_PSA_CRYPTO_C)
else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) {
sign_alg = psa_enrollment_alg;
}
#endif /* MBEDTLS_PSA_CRYPTO_C */
else {
/* The opaque key has no RSA PSS algorithm associated. */
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* Adjust the hashing algorithm. */
sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg);
status = psa_sign_hash(ctx->priv_id, sign_alg,
/* PSA_ALG_RSA_PSS() behaves the same as PSA_ALG_RSA_PSS_ANY_SALT() when
* performing a signature, but they are encoded differently. Instead of
* extracting the proper one from the wrapped key policy, just try both. */
status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
hash, hash_len,
sig, sig_size, sig_len);
if (status == PSA_ERROR_NOT_PERMITTED) {
status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg),
hash, hash_len,
sig, sig_size, sig_len);
}
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
}

View File

@ -2082,6 +2082,19 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg
memset(hash, 0x2a, sizeof(hash));
memset(sig, 0, sizeof(sig));
#if defined(MBEDTLS_PKCS1_V21)
/* Check that trying to use the wrong pk_type in sign_ext() results in a failure.
* The PSA key was setup to use PKCS1 v1.5 signature algorithm, but here we try
* to use it for PSS (PKCS1 v2.1) and it should fail. */
if (key_pk_type == MBEDTLS_PK_RSA) {
TEST_EQUAL(mbedtls_pk_sign_ext(MBEDTLS_PK_RSASSA_PSS, &pk, md_alg, hash, hash_len,
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand, NULL),
MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
}
#endif /* MBEDTLS_PKCS1_V21 */
/* Perform sign_ext() with the correct pk_type. */
TEST_EQUAL(mbedtls_pk_sign_ext(key_pk_type, &pk, md_alg, hash, hash_len,
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand, NULL), 0);