From 7f5574817fab1a422e19f6b66de5cd764f4ab78f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 10 Oct 2024 15:45:08 +0200 Subject: [PATCH] jwt: remove TinyCrypt usage As part of TinyCrypt deprecation process (#79566) this commit removes usage of this library from the JWT subsystem and its related tests. Signed-off-by: Valerio Setti --- doc/releases/migration-guide-4.0.rst | 20 ++++-- doc/releases/release-notes-4.0.rst | 12 ++-- subsys/jwt/CMakeLists.txt | 6 +- subsys/jwt/Kconfig | 67 +++++--------------- subsys/jwt/jwt.c | 8 +-- subsys/jwt/jwt_legacy_ecdsa.c | 82 ------------------------- subsys/jwt/jwt_psa.c | 6 +- tests/subsys/jwt/src/jwt-test-private.c | 4 +- tests/subsys/jwt/testcase.yaml | 13 +--- 9 files changed, 54 insertions(+), 164 deletions(-) delete mode 100644 subsys/jwt/jwt_legacy_ecdsa.c diff --git a/doc/releases/migration-guide-4.0.rst b/doc/releases/migration-guide-4.0.rst index 49b7e4e0be4..dbe25167620 100644 --- a/doc/releases/migration-guide-4.0.rst +++ b/doc/releases/migration-guide-4.0.rst @@ -576,11 +576,21 @@ Shell JWT (JSON Web Token) ==================== -* By default, the signature is now computed through PSA Crypto API for both RSA and ECDSA. - The newly-added :kconfig:option:`CONFIG_JWT_USE_LEGACY` can be used to switch - back to previous libraries (TinyCrypt for ECDSA and Mbed TLS for RSA). - The conversion to the PSA Crypto API is being done in preparation for the - deprecation of TinyCrypt. (:github:`78243` and :github:`43712`) +* By default, the signature is now computed using the PSA Crypto API for both RSA and ECDSA + (:github:`78243`). The conversion to the PSA Crypto API is part of the adoption + of a standard interface for crypto operations (:github:`43712`). Moreover, + following the deprecation of the TinyCrypt library (:github:`79566`), usage + of TinyCrypt was removed from the JWT subsystem (:github:`79653`). + +* The following new symbols were added to allow specifying both the signature + algorithm and crypto library: + + * :kconfig:option:`CONFIG_JWT_SIGN_RSA_PSA` (default) RSA signature using the PSA Crypto API; + * :kconfig:option:`CONFIG_JWT_SIGN_RSA_LEGACY` RSA signature using Mbed TLS; + * :kconfig:option:`CONFIG_JWT_SIGN_ECDSA_PSA` ECDSA signature using the PSA Crypto API. + + They replace the previously-existing Kconfigs ``CONFIG_JWT_SIGN_RSA`` and + ``CONFIG_JWT_SIGN_ECDSA``. (:github:`79653`) Architectures ************* diff --git a/doc/releases/release-notes-4.0.rst b/doc/releases/release-notes-4.0.rst index 16c1b595ac1..dba6c620904 100644 --- a/doc/releases/release-notes-4.0.rst +++ b/doc/releases/release-notes-4.0.rst @@ -608,12 +608,14 @@ Libraries / Subsystems * JWT (JSON Web Token) - * The following new Kconfigs were added to specify which library to use for the - signature: + * The following new symbols were added to allow specifying both the signature + algorithm and crypto library: - * :kconfig:option:`CONFIG_JWT_USE_PSA` (default) use the PSA Crypto API; - * :kconfig:option:`CONFIG_JWT_USE_LEGACY` use legacy libraries, i.e. TinyCrypt - for ECDSA and Mbed TLS for RSA. + * :kconfig:option:`CONFIG_JWT_SIGN_RSA_PSA` (default) RSA signature using the PSA Crypto API; + * :kconfig:option:`CONFIG_JWT_SIGN_RSA_LEGACY` RSA signature using Mbed TLS; + * :kconfig:option:`CONFIG_JWT_SIGN_ECDSA_PSA` ECDSA signature using the PSA Crypto API. + + (:github:`79653`) HALs **** diff --git a/subsys/jwt/CMakeLists.txt b/subsys/jwt/CMakeLists.txt index 82c65f11f41..6bc93cd92b8 100644 --- a/subsys/jwt/CMakeLists.txt +++ b/subsys/jwt/CMakeLists.txt @@ -3,8 +3,10 @@ zephyr_library() zephyr_library_sources(jwt.c) -zephyr_library_sources_ifdef(CONFIG_JWT_SIGN_ECDSA_LEGACY jwt_legacy_ecdsa.c) zephyr_library_sources_ifdef(CONFIG_JWT_SIGN_RSA_LEGACY jwt_legacy_rsa.c) -zephyr_library_sources_ifdef(CONFIG_JWT_USE_PSA jwt_psa.c) + +if (CONFIG_JWT_SIGN_RSA_PSA OR CONFIG_JWT_SIGN_ECDSA_PSA) + zephyr_library_sources(jwt_psa.c) +endif() zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) diff --git a/subsys/jwt/Kconfig b/subsys/jwt/Kconfig index 651fe46cbf5..97446e27d9e 100644 --- a/subsys/jwt/Kconfig +++ b/subsys/jwt/Kconfig @@ -12,69 +12,34 @@ if JWT choice prompt "JWT signature algorithm" - default JWT_SIGN_RSA + default JWT_SIGN_RSA_PSA help Select which algorithm to use for signing JWT tokens. -config JWT_SIGN_RSA - bool "Use RSA signature (RS-256)" - -config JWT_SIGN_ECDSA - bool "Use ECDSA signature (ES-256)" - -endchoice - -choice - default JWT_USE_PSA - prompt "Select crypto library to be used" +config JWT_SIGN_RSA_LEGACY + bool "Use RSA signature (RS-256). Use Mbed TLS as crypto library." + depends on CSPRNG_ENABLED + select MBEDTLS + select MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -config JWT_USE_PSA - bool "PSA crypto API library" +config JWT_SIGN_RSA_PSA + bool "Use RSA signature (RS-256). Use PSA Crypto API." select MBEDTLS if !BUILD_WITH_TFM select MBEDTLS_PSA_CRYPTO_C if !BUILD_WITH_TFM + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + select PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT + select PSA_WANT_ALG_RSA_PKCS1V15_SIGN + select PSA_WANT_ALG_SHA_256 -config JWT_USE_LEGACY - bool "Legacy library: TinyCrypt for ECDSA, Mbed TLS for RSA" - -endchoice - -# Prompless Kconfigs to effectively select which algorithm and library will be used -# to sign the JWT. User's selections on the above choices will determine which -# element will be picked here. config JWT_SIGN_ECDSA_PSA - bool - default y - depends on JWT_SIGN_ECDSA && JWT_USE_PSA + bool "Use ECDSA signature (ES-256). Use PSA Crypto API." + select MBEDTLS if !BUILD_WITH_TFM + select MBEDTLS_PSA_CRYPTO_C if !BUILD_WITH_TFM select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT select PSA_WANT_ALG_ECDSA select PSA_WANT_ECC_SECP_R1_256 select PSA_WANT_ALG_SHA_256 -config JWT_SIGN_ECDSA_LEGACY - bool - default y - depends on JWT_SIGN_ECDSA && JWT_USE_LEGACY - select TINYCRYPT - select TINYCRYPT_SHA256 - select TINYCRYPT_ECC_DSA - select TINYCRYPT_CTR_PRNG - select TINYCRYPT_AES - -config JWT_SIGN_RSA_PSA - bool - default y - depends on JWT_SIGN_RSA && JWT_USE_PSA - select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY - select PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT - select PSA_WANT_ALG_RSA_PKCS1V15_SIGN - select PSA_WANT_ALG_SHA_256 - -config JWT_SIGN_RSA_LEGACY - bool - default y - depends on JWT_SIGN_RSA && JWT_USE_LEGACY - depends on CSPRNG_ENABLED - select MBEDTLS - select MBEDTLS_KEY_EXCHANGE_RSA_ENABLED +endchoice endif # JWT diff --git a/subsys/jwt/jwt.c b/subsys/jwt/jwt.c index 4487e557096..1774637cff9 100644 --- a/subsys/jwt/jwt.c +++ b/subsys/jwt/jwt.c @@ -14,9 +14,9 @@ #include "jwt.h" -#if defined(CONFIG_JWT_SIGN_RSA) +#if defined(CONFIG_JWT_SIGN_RSA_PSA) || defined(JWT_SIGN_RSA_LEGACY) #define JWT_SIGNATURE_LEN 256 -#else /* CONFIG_JWT_SIGN_ECDSA */ +#else /* CONFIG_JWT_SIGN_ECDSA_PSA */ #define JWT_SIGNATURE_LEN 64 #endif @@ -143,10 +143,10 @@ static int jwt_add_header(struct jwt_builder *builder) * Use https://www.base64encode.org/ for update */ const char jwt_header[] = -#ifdef CONFIG_JWT_SIGN_RSA +#if defined(CONFIG_JWT_SIGN_RSA_PSA) || defined(CONFIG_JWT_SIGN_RSA_LEGACY) /* {"alg":"RS256","typ":"JWT"} */ "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"; -#else /* CONFIG_JWT_SIGN_ECDSA */ +#else /* CONFIG_JWT_SIGN_ECDSA_PSA */ /* {"alg":"ES256","typ":"JWT"} */ "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9"; #endif diff --git a/subsys/jwt/jwt_legacy_ecdsa.c b/subsys/jwt/jwt_legacy_ecdsa.c deleted file mode 100644 index d8368280270..00000000000 --- a/subsys/jwt/jwt_legacy_ecdsa.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2024 BayLibre SAS - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "jwt.h" - -static TCCtrPrng_t prng_state; -static bool prng_init; - -static const char personalize[] = "zephyr:drivers/jwt/jwt.c"; - -static int setup_prng(void) -{ - if (prng_init) { - return 0; - } - prng_init = true; - - uint8_t entropy[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; - - sys_rand_get(entropy, sizeof(entropy)); - - int res = tc_ctr_prng_init(&prng_state, (const uint8_t *)&entropy, sizeof(entropy), - personalize, sizeof(personalize)); - - return res == TC_CRYPTO_SUCCESS ? 0 : -EINVAL; -} - -/* This function is declared in - * modules/crypto/tinycrypt/lib/include/tinycrypt/ecc_platform_specific.h. - * - * TinyCrypt expects this function to be implemented somewhere when using the - * ECC module. - */ -int default_CSPRNG(uint8_t *dest, unsigned int size) -{ - int res = tc_ctr_prng_generate(&prng_state, NULL, 0, dest, size); - return res; -} - -int jwt_sign_impl(struct jwt_builder *builder, const unsigned char *der_key, size_t der_key_len, - unsigned char *sig, size_t sig_size) -{ - struct tc_sha256_state_struct ctx; - uint8_t hash[32]; - int res; - - ARG_UNUSED(sig_size); - - tc_sha256_init(&ctx); - tc_sha256_update(&ctx, builder->base, builder->buf - builder->base); - tc_sha256_final(hash, &ctx); - - res = setup_prng(); - - if (res != 0) { - return res; - } - - /* Note that tinycrypt only supports P-256. */ - res = uECC_sign(der_key, hash, sizeof(hash), sig, &curve_secp256r1); - if (res != TC_CRYPTO_SUCCESS) { - return -EINVAL; - } - - return 0; -} diff --git a/subsys/jwt/jwt_psa.c b/subsys/jwt/jwt_psa.c index edbafa6fefe..ce5928c09bb 100644 --- a/subsys/jwt/jwt_psa.c +++ b/subsys/jwt/jwt_psa.c @@ -24,15 +24,15 @@ int jwt_sign_impl(struct jwt_builder *builder, const unsigned char *der_key, siz psa_algorithm_t alg; int ret; -#if defined(CONFIG_JWT_SIGN_ECDSA) +#if defined(CONFIG_JWT_SIGN_ECDSA_PSA) psa_set_key_type(&attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); psa_set_key_algorithm(&attr, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256); -#else /* CONFIG_JWT_SIGN_RSA */ +#else psa_set_key_type(&attr, PSA_KEY_TYPE_RSA_KEY_PAIR); psa_set_key_algorithm(&attr, PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)); alg = PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256); -#endif /* CONFIG_JWT_SIGN_ECDSA || CONFIG_JWT_SIGN_RSA */ +#endif psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE); status = psa_import_key(&attr, der_key, der_key_len, &key_id); diff --git a/tests/subsys/jwt/src/jwt-test-private.c b/tests/subsys/jwt/src/jwt-test-private.c index a6fc98a8fb7..600eaf62d5b 100644 --- a/tests/subsys/jwt/src/jwt-test-private.c +++ b/tests/subsys/jwt/src/jwt-test-private.c @@ -4,7 +4,7 @@ * */ -#if defined(CONFIG_JWT_SIGN_RSA) +#if defined(CONFIG_JWT_SIGN_RSA_PSA) || defined(CONFIG_JWT_SIGN_RSA_LEGACY) /* To generate the key in the correct format use the following command: * $ openssl genrsa 2048 | openssl rsa -outform DER | xxd -i @@ -113,7 +113,7 @@ unsigned char jwt_test_private_der[] = { 0x05, 0xfd, 0x71, 0xb0, 0x3e }; -#else /* CONFIG_JWT_SIGN_ECDSA */ +#else /* CONFIG_JWT_SIGN_ECDSA_PSA */ /* Here's how to generate the key in the correct format: * - generate the key using OpenSSL: diff --git a/tests/subsys/jwt/testcase.yaml b/tests/subsys/jwt/testcase.yaml index 6606780a9f1..f439e9aea9e 100644 --- a/tests/subsys/jwt/testcase.yaml +++ b/tests/subsys/jwt/testcase.yaml @@ -9,24 +9,17 @@ common: extra_configs: - CONFIG_TEST_RANDOM_GENERATOR=y tests: - libraries.encoding.jwt.ecdsa.legacy: - extra_configs: - - CONFIG_JWT_SIGN_ECDSA=y - - CONFIG_JWT_USE_LEGACY=y libraries.encoding.jwt.ecdsa.psa: extra_configs: - - CONFIG_JWT_SIGN_ECDSA=y - - CONFIG_JWT_USE_PSA=y + - CONFIG_JWT_SIGN_ECDSA_PSA=y - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y libraries.encoding.jwt.rsa.legacy: filter: CSPRNG_ENABLED extra_configs: - - CONFIG_JWT_SIGN_RSA=y - - CONFIG_JWT_USE_LEGACY=y + - CONFIG_JWT_SIGN_RSA_LEGACY=y libraries.encoding.jwt.rsa.psa: extra_configs: - - CONFIG_JWT_SIGN_RSA=y - - CONFIG_JWT_USE_PSA=y + - CONFIG_JWT_SIGN_RSA_PSA=y - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y