Browse Source

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 <vsetti@baylibre.com>
pull/80953/head
Valerio Setti 9 months ago committed by Mahesh Mahadevan
parent
commit
7f5574817f
  1. 20
      doc/releases/migration-guide-4.0.rst
  2. 12
      doc/releases/release-notes-4.0.rst
  3. 6
      subsys/jwt/CMakeLists.txt
  4. 67
      subsys/jwt/Kconfig
  5. 8
      subsys/jwt/jwt.c
  6. 82
      subsys/jwt/jwt_legacy_ecdsa.c
  7. 6
      subsys/jwt/jwt_psa.c
  8. 4
      tests/subsys/jwt/src/jwt-test-private.c
  9. 13
      tests/subsys/jwt/testcase.yaml

20
doc/releases/migration-guide-4.0.rst

@ -576,11 +576,21 @@ Shell
JWT (JSON Web Token) JWT (JSON Web Token)
==================== ====================
* By default, the signature is now computed through PSA Crypto API for both RSA and ECDSA. * By default, the signature is now computed using the PSA Crypto API for both RSA and ECDSA
The newly-added :kconfig:option:`CONFIG_JWT_USE_LEGACY` can be used to switch (:github:`78243`). The conversion to the PSA Crypto API is part of the adoption
back to previous libraries (TinyCrypt for ECDSA and Mbed TLS for RSA). of a standard interface for crypto operations (:github:`43712`). Moreover,
The conversion to the PSA Crypto API is being done in preparation for the following the deprecation of the TinyCrypt library (:github:`79566`), usage
deprecation of TinyCrypt. (:github:`78243` and :github:`43712`) 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 Architectures
************* *************

12
doc/releases/release-notes-4.0.rst

@ -608,12 +608,14 @@ Libraries / Subsystems
* JWT (JSON Web Token) * JWT (JSON Web Token)
* The following new Kconfigs were added to specify which library to use for the * The following new symbols were added to allow specifying both the signature
signature: algorithm and crypto library:
* :kconfig:option:`CONFIG_JWT_USE_PSA` (default) use the PSA Crypto API; * :kconfig:option:`CONFIG_JWT_SIGN_RSA_PSA` (default) RSA signature using the PSA Crypto API;
* :kconfig:option:`CONFIG_JWT_USE_LEGACY` use legacy libraries, i.e. TinyCrypt * :kconfig:option:`CONFIG_JWT_SIGN_RSA_LEGACY` RSA signature using Mbed TLS;
for ECDSA and Mbed TLS for RSA. * :kconfig:option:`CONFIG_JWT_SIGN_ECDSA_PSA` ECDSA signature using the PSA Crypto API.
(:github:`79653`)
HALs HALs
**** ****

6
subsys/jwt/CMakeLists.txt

@ -3,8 +3,10 @@
zephyr_library() zephyr_library()
zephyr_library_sources(jwt.c) 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_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) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS)

67
subsys/jwt/Kconfig

@ -12,69 +12,34 @@ if JWT
choice choice
prompt "JWT signature algorithm" prompt "JWT signature algorithm"
default JWT_SIGN_RSA default JWT_SIGN_RSA_PSA
help help
Select which algorithm to use for signing JWT tokens. Select which algorithm to use for signing JWT tokens.
config JWT_SIGN_RSA config JWT_SIGN_RSA_LEGACY
bool "Use RSA signature (RS-256)" bool "Use RSA signature (RS-256). Use Mbed TLS as crypto library."
depends on CSPRNG_ENABLED
config JWT_SIGN_ECDSA select MBEDTLS
bool "Use ECDSA signature (ES-256)" select MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
endchoice
choice
default JWT_USE_PSA
prompt "Select crypto library to be used"
config JWT_USE_PSA config JWT_SIGN_RSA_PSA
bool "PSA crypto API library" bool "Use RSA signature (RS-256). Use PSA Crypto API."
select MBEDTLS if !BUILD_WITH_TFM select MBEDTLS if !BUILD_WITH_TFM
select MBEDTLS_PSA_CRYPTO_C 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 config JWT_SIGN_ECDSA_PSA
bool bool "Use ECDSA signature (ES-256). Use PSA Crypto API."
default y select MBEDTLS if !BUILD_WITH_TFM
depends on JWT_SIGN_ECDSA && JWT_USE_PSA select MBEDTLS_PSA_CRYPTO_C if !BUILD_WITH_TFM
select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT
select PSA_WANT_ALG_ECDSA select PSA_WANT_ALG_ECDSA
select PSA_WANT_ECC_SECP_R1_256 select PSA_WANT_ECC_SECP_R1_256
select PSA_WANT_ALG_SHA_256 select PSA_WANT_ALG_SHA_256
config JWT_SIGN_ECDSA_LEGACY endchoice
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
endif # JWT endif # JWT

8
subsys/jwt/jwt.c

@ -14,9 +14,9 @@
#include "jwt.h" #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 #define JWT_SIGNATURE_LEN 256
#else /* CONFIG_JWT_SIGN_ECDSA */ #else /* CONFIG_JWT_SIGN_ECDSA_PSA */
#define JWT_SIGNATURE_LEN 64 #define JWT_SIGNATURE_LEN 64
#endif #endif
@ -143,10 +143,10 @@ static int jwt_add_header(struct jwt_builder *builder)
* Use https://www.base64encode.org/ for update * Use https://www.base64encode.org/ for update
*/ */
const char jwt_header[] = 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"} */ /* {"alg":"RS256","typ":"JWT"} */
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"; "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9";
#else /* CONFIG_JWT_SIGN_ECDSA */ #else /* CONFIG_JWT_SIGN_ECDSA_PSA */
/* {"alg":"ES256","typ":"JWT"} */ /* {"alg":"ES256","typ":"JWT"} */
"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9"; "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9";
#endif #endif

82
subsys/jwt/jwt_legacy_ecdsa.c

@ -1,82 +0,0 @@
/*
* Copyright (C) 2024 BayLibre SAS
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <zephyr/types.h>
#include <errno.h>
#include <zephyr/data/jwt.h>
#include <zephyr/data/json.h>
#include <zephyr/random/random.h>
#include <tinycrypt/ctr_prng.h>
#include <tinycrypt/sha256.h>
#include <tinycrypt/ecc_dsa.h>
#include <tinycrypt/constants.h>
#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;
}

6
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; psa_algorithm_t alg;
int ret; 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_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)); psa_set_key_algorithm(&attr, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
alg = 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_type(&attr, PSA_KEY_TYPE_RSA_KEY_PAIR);
psa_set_key_algorithm(&attr, PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256)); psa_set_key_algorithm(&attr, PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256));
alg = 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); psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE);
status = psa_import_key(&attr, der_key, der_key_len, &key_id); status = psa_import_key(&attr, der_key, der_key_len, &key_id);

4
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: /* To generate the key in the correct format use the following command:
* $ openssl genrsa 2048 | openssl rsa -outform DER | xxd -i * $ openssl genrsa 2048 | openssl rsa -outform DER | xxd -i
@ -113,7 +113,7 @@ unsigned char jwt_test_private_der[] = {
0x05, 0xfd, 0x71, 0xb0, 0x3e 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: /* Here's how to generate the key in the correct format:
* - generate the key using OpenSSL: * - generate the key using OpenSSL:

13
tests/subsys/jwt/testcase.yaml

@ -9,24 +9,17 @@ common:
extra_configs: extra_configs:
- CONFIG_TEST_RANDOM_GENERATOR=y - CONFIG_TEST_RANDOM_GENERATOR=y
tests: tests:
libraries.encoding.jwt.ecdsa.legacy:
extra_configs:
- CONFIG_JWT_SIGN_ECDSA=y
- CONFIG_JWT_USE_LEGACY=y
libraries.encoding.jwt.ecdsa.psa: libraries.encoding.jwt.ecdsa.psa:
extra_configs: extra_configs:
- CONFIG_JWT_SIGN_ECDSA=y - CONFIG_JWT_SIGN_ECDSA_PSA=y
- CONFIG_JWT_USE_PSA=y
- CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y
- CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y
libraries.encoding.jwt.rsa.legacy: libraries.encoding.jwt.rsa.legacy:
filter: CSPRNG_ENABLED filter: CSPRNG_ENABLED
extra_configs: extra_configs:
- CONFIG_JWT_SIGN_RSA=y - CONFIG_JWT_SIGN_RSA_LEGACY=y
- CONFIG_JWT_USE_LEGACY=y
libraries.encoding.jwt.rsa.psa: libraries.encoding.jwt.rsa.psa:
extra_configs: extra_configs:
- CONFIG_JWT_SIGN_RSA=y - CONFIG_JWT_SIGN_RSA_PSA=y
- CONFIG_JWT_USE_PSA=y
- CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y
- CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y

Loading…
Cancel
Save