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 @@ -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
*************

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

@ -608,12 +608,14 @@ Libraries / Subsystems @@ -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
****

6
subsys/jwt/CMakeLists.txt

@ -3,8 +3,10 @@ @@ -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)

67
subsys/jwt/Kconfig

@ -12,69 +12,34 @@ if JWT @@ -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

8
subsys/jwt/jwt.c

@ -14,9 +14,9 @@ @@ -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) @@ -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

82
subsys/jwt/jwt_legacy_ecdsa.c

@ -1,82 +0,0 @@ @@ -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 @@ -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);

4
tests/subsys/jwt/src/jwt-test-private.c

@ -4,7 +4,7 @@ @@ -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[] = { @@ -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:

13
tests/subsys/jwt/testcase.yaml

@ -9,24 +9,17 @@ common: @@ -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

Loading…
Cancel
Save