summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/Kconfig31
-rw-r--r--crypto/Makefile4
-rw-r--r--crypto/crc32.c174
-rw-r--r--crypto/digest.c11
-rw-r--r--crypto/jwt.c240
-rw-r--r--crypto/rsa.c4
6 files changed, 330 insertions, 134 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig
index f32accb3d0..d1360a2101 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -86,6 +86,27 @@ config DIGEST_SHA256_ARM
SHA-256 secure hash standard (DFIPS 180-2) implemented
using optimized ARM assembler and NEON, when available.
+config DIGEST_SHA1_ARM64_CE
+ tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)"
+ depends on CPU_V8
+ select HAVE_DIGEST_SHA1
+ help
+ SHA-1 secure hash algorithm (FIPS 180)
+
+ Architecture: arm64 using:
+ - ARMv8 Crypto Extensions
+
+config DIGEST_SHA256_ARM64_CE
+ tristate "SHA-224/256 digest algorithm (ARMv8 Crypto Extensions)"
+ depends on CPU_V8
+ select HAVE_DIGEST_SHA256
+ select HAVE_DIGEST_SHA224
+ help
+ SHA-224 and SHA-256 secure hash algorithms (FIPS 180)
+
+ Architecture: arm64 using:
+ - ARMv8 Crypto Extensions
+
endif
config CRYPTO_PBKDF2
@@ -100,6 +121,7 @@ config CRYPTO_RSA
config CRYPTO_RSA_BUILTIN_KEYS
bool
default y if CRYPTO_RSA_KEY != ""
+ select RSATOC
config CRYPTO_RSA_KEY
depends on CRYPTO_RSA
@@ -109,6 +131,9 @@ config CRYPTO_RSA_KEY
X.509 certificates to be included into barebox. If the string starts
with "pkcs11:" it is interpreted as a PKCS#11 URI rather than a file.
+ This avoids the mkimage dependency of CONFIG_BOOTM_FITIMAGE_PUBKEY
+ at the cost of an openssl build-time dependency.
+
config CRYPTO_RSA_KEY_NAME_HINT
depends on CRYPTO_RSA
string "FIT image key name hint"
@@ -122,4 +147,10 @@ config CRYPTO_KEYSTORE
This is a simple keystore, which can be used to pass keys
between several components via simple interface.
+config JWT
+ bool "JSON Web Token support" if COMPILE_TEST
+ select JSMN
+ select BASE64
+ select CRYPTO_RSA
+
endmenu
diff --git a/crypto/Makefile b/crypto/Makefile
index 22035d4f69..cf041dd6b3 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_CRC32) += crc32.o
+obj-pbl-$(CONFIG_CRC32) += crc32.o
obj-pbl-$(CONFIG_CRC_ITU_T) += crc-itu-t.o
obj-$(CONFIG_CRC7) += crc7.o
obj-$(CONFIG_DIGEST) += digest.o
@@ -19,6 +19,8 @@ obj-$(CONFIG_CRYPTO_PBKDF2) += pbkdf2.o
obj-$(CONFIG_CRYPTO_RSA) += rsa.o
obj-$(CONFIG_CRYPTO_KEYSTORE) += keystore.o
+obj-$(CONFIG_JWT) += jwt.o
+
extra-$(CONFIG_CRYPTO_RSA_BUILTIN_KEYS) += rsa-keys.h
ifdef CONFIG_CRYPTO_RSA_BUILTIN_KEYS
diff --git a/crypto/crc32.c b/crypto/crc32.c
index 998cbc9de2..5013556c0b 100644
--- a/crypto/crc32.c
+++ b/crypto/crc32.c
@@ -8,7 +8,7 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
-#ifdef __BAREBOX__ /* Shut down "ANSI does not permit..." warnings */
+#ifdef __BAREBOX__ /* Shut down "ANSI does not permit..." warnings */
#include <common.h>
#include <xfuncs.h>
#include <fs.h>
@@ -22,9 +22,7 @@
#define STATIC static inline
#endif
-#ifdef CONFIG_DYNAMIC_CRC_TABLE
-
-static ulong *crc_table;
+static uint32_t crc_table[sizeof(uint32_t) * 256];
/*
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
@@ -52,145 +50,68 @@ static ulong *crc_table;
*/
static void make_crc_table(void)
{
- ulong c;
- int n, k;
- ulong poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static const char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* make exclusive-or pattern from polynomial (0xedb88320L) */
- poly = 0L;
- for (n = 0; n < sizeof(p)/sizeof(char); n++)
- poly |= 1L << (31 - p[n]);
-
- crc_table = xmalloc(sizeof(ulong) * 256);
-
- for (n = 0; n < 256; n++)
- {
- c = (ulong)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[n] = c;
- }
+ uint32_t c;
+ int n, k;
+ uint32_t poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static const char p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
+
+ if (crc_table[1])
+ return;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320L) */
+ poly = 0;
+ for (n = 0; n < sizeof(p) / sizeof(char); n++)
+ poly |= 1U << (31 - p[n]);
+
+ for (n = 0; n < 256; n++) {
+ c = (uint32_t) n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[n] = c;
+ }
}
-#else
-/* ========================================================================
- * Table of CRC-32's of all single-byte values (made by make_crc_table)
- */
-static const ulong crc_table[256] = {
- 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
- 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
- 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
- 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
- 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
- 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
- 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
- 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
- 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
- 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
- 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
- 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
- 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
- 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
- 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
- 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
- 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
- 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
- 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
- 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
- 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
- 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
- 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
- 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
- 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
- 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
- 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
- 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
- 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
- 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
- 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
- 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
- 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
- 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
- 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
- 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
- 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
- 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
- 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
- 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
- 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
- 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
- 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
- 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
- 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
- 0x2d02ef8dL
-};
-#endif
-
-/* ========================================================================= */
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf);
-/* ========================================================================= */
-STATIC uint32_t crc32(uint32_t crc, const void *_buf, unsigned int len)
-{
- const unsigned char *buf = _buf;
-
-#ifdef CONFIG_DYNAMIC_CRC_TABLE
- if (!crc_table)
- make_crc_table();
-#endif
- crc = crc ^ 0xffffffffL;
- while (len >= 8)
- {
- DO8(buf);
- len -= 8;
- }
- if (len) do {
- DO1(buf);
- } while (--len);
- return crc ^ 0xffffffffL;
-}
-#ifdef __BAREBOX__
-EXPORT_SYMBOL(crc32);
-#endif
-
/* No ones complement version. JFFS2 (and other things ?)
* don't use ones compliment in their CRC calculations.
*/
STATIC uint32_t crc32_no_comp(uint32_t crc, const void *_buf, unsigned int len)
{
- const unsigned char *buf = _buf;
+ const unsigned char *buf = _buf;
-#ifdef CONFIG_DYNAMIC_CRC_TABLE
- if (!crc_table)
- make_crc_table();
-#endif
- while (len >= 8)
- {
- DO8(buf);
- len -= 8;
- }
- if (len) do {
- DO1(buf);
- } while (--len);
-
- return crc;
+ make_crc_table();
+
+ while (len >= 8) {
+ DO8(buf);
+ len -= 8;
+ }
+ if (len)
+ do {
+ DO1(buf);
+ } while (--len);
+
+ return crc;
+}
+
+STATIC uint32_t crc32(uint32_t crc, const void *buf, unsigned int len)
+{
+ return ~crc32_no_comp(~crc, buf, len);
}
+#ifdef __BAREBOX__
+EXPORT_SYMBOL(crc32);
+#endif
+
STATIC uint32_t crc32_be(uint32_t crc, const void *_buf, unsigned int len)
{
const unsigned char *buf = _buf;
int i;
+
while (len--) {
crc ^= *buf++ << 24;
for (i = 0; i < 8; i++)
@@ -199,8 +120,8 @@ STATIC uint32_t crc32_be(uint32_t crc, const void *_buf, unsigned int len)
return crc;
}
-STATIC int file_crc(char *filename, ulong start, ulong size, ulong *crc,
- ulong *total)
+STATIC int file_crc(char *filename, ulong start, ulong size, ulong * crc,
+ ulong * total)
{
int fd, now;
int ret = 0;
@@ -250,6 +171,7 @@ out:
return ret;
}
+
#ifdef __BAREBOX__
EXPORT_SYMBOL(file_crc);
#endif
diff --git a/crypto/digest.c b/crypto/digest.c
index 621d384168..dd2c2ee317 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -27,8 +27,6 @@
static LIST_HEAD(digests);
-static struct digest_algo *digest_algo_get_by_name(const char *name);
-
static int dummy_init(struct digest *d)
{
return 0;
@@ -106,7 +104,7 @@ EXPORT_SYMBOL(digest_algo_unregister);
static struct digest_algo *digest_algo_get_by_name(const char *name)
{
- struct digest_algo *d = NULL;
+ struct digest_algo *d_by_name = NULL, *d_by_driver = NULL;
struct digest_algo *tmp;
int priority = -1;
@@ -114,17 +112,20 @@ static struct digest_algo *digest_algo_get_by_name(const char *name)
return NULL;
list_for_each_entry(tmp, &digests, list) {
+ if (strcmp(tmp->base.driver_name, name) == 0)
+ d_by_driver = tmp;
+
if (strcmp(tmp->base.name, name) != 0)
continue;
if (tmp->base.priority <= priority)
continue;
- d = tmp;
+ d_by_name = tmp;
priority = tmp->base.priority;
}
- return d;
+ return d_by_name ?: d_by_driver;
}
static struct digest_algo *digest_algo_get_by_algo(enum hash_algo algo)
diff --git a/crypto/jwt.c b/crypto/jwt.c
new file mode 100644
index 0000000000..f8d678718a
--- /dev/null
+++ b/crypto/jwt.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) "jwt: " fmt
+
+#include <crypto/jwt.h>
+#include <rsa.h>
+#include <errno.h>
+#include <linux/printk.h>
+#include <base64.h>
+#include <jsmn.h>
+#include <linux/ctype.h>
+
+#define JP(...) (const char *[]) { __VA_ARGS__, NULL }
+
+static enum hash_algo digest_algo_by_jwt_alg(enum jwt_alg alg)
+{
+ switch (alg) {
+ case JWT_ALG_RS256:
+ return HASH_ALGO_SHA256;
+ case JWT_ALG_RS384:
+ return HASH_ALGO_SHA384;
+ case JWT_ALG_RS512:
+ return HASH_ALGO_SHA512;
+ default:
+ BUG();
+ }
+}
+
+static u8 *do_hash(const u8 *buf, size_t len, enum hash_algo algo)
+{
+ struct digest *digest;
+ int ret = 0;
+ u8 *hash;
+
+ digest = digest_alloc_by_algo(algo);
+ if (!digest) {
+ pr_err("signature algorithm not supported\n");
+ return ERR_PTR(-ENOSYS);
+ }
+
+ hash = xzalloc(digest_length(digest));
+ ret = digest_digest(digest, buf, len, hash);
+ digest_free(digest);
+
+ if (ret) {
+ free(hash);
+ return ERR_PTR(ret);
+ }
+
+ return hash;
+}
+
+static int jwt_part_parse(struct jwt_part *part, const char *content, size_t len)
+{
+ size_t decoded_len;
+
+ part->content = xmalloc(len);
+ decoded_len = decode_base64url(part->content, len, content);
+ part->content[decoded_len] = '\0';
+ part->tokens = jsmn_parse_alloc(part->content, decoded_len, &part->token_count);
+ if (!part->tokens) {
+ free(part->content);
+ return -EILSEQ;
+ }
+
+ return 0;
+}
+
+static void jwt_part_free(struct jwt_part *part)
+{
+ free(part->tokens);
+ free(part->content);
+}
+
+static const char *jwt_alg_names[] = {
+ [JWT_ALG_NONE] = "none",
+ [JWT_ALG_HS256] = "HS256",
+ [JWT_ALG_HS384] = "HS384",
+ [JWT_ALG_HS512] = "HS512",
+ [JWT_ALG_PS256] = "PS256",
+ [JWT_ALG_PS384] = "PS384",
+ [JWT_ALG_PS512] = "PS512",
+ [JWT_ALG_RS256] = "RS256",
+ [JWT_ALG_RS384] = "RS384",
+ [JWT_ALG_RS512] = "RS512",
+ [JWT_ALG_ES256] = "ES256",
+ [JWT_ALG_ES256K] = "ES256K",
+ [JWT_ALG_ES384] = "ES384",
+ [JWT_ALG_ES512] = "ES512",
+ [JWT_ALG_EDDSA] = "EDDSA",
+};
+
+static bool jwt_header_ok(struct jwt *jwt, enum jwt_alg alg)
+{
+ struct jwt_part *header = &jwt->header;
+ const jsmntok_t *token;
+
+ token = jsmn_locate(JP("typ"), header->content, header->tokens);
+ if (!token)
+ return false;
+
+ if (!jsmn_strcase_eq("JWT", header->content, token))
+ return false;
+
+ if (alg >= ARRAY_SIZE(jwt_alg_names))
+ return false;
+
+ token = jsmn_locate(JP("alg"), header->content, header->tokens);
+ if (!token)
+ return false;
+
+ return jsmn_strcase_eq(jwt_alg_names[alg], header->content, token);
+}
+
+void jwt_free(struct jwt *jwt)
+{
+ jwt_part_free(&jwt->payload);
+ jwt_part_free(&jwt->header);
+ free(jwt);
+}
+
+const char *jwt_split(const char *token,
+ const char **payload, const char **signature, const char **end)
+{
+ const char *p, *p_end;
+
+ token = skip_spaces(token);
+
+ p = strchr(token, '.');
+ if (!p)
+ return ERR_PTR(-EINVAL);
+ if (payload)
+ *payload = ++p;
+
+ p = strchr(p, '.');
+ if (!p)
+ return ERR_PTR(-EINVAL);
+ if (signature)
+ *signature = ++p;
+
+ /* seek to first space or '\0' */
+ for (p_end = p; *p_end && !isspace(*p_end); p_end++)
+ ;
+
+ /* ensure the trailing spaces aren't followed by anything */
+ if (*skip_spaces(p_end) != '\0')
+ return ERR_PTR(-EINVAL);
+
+ *end = p_end;
+
+ return token;
+}
+
+struct jwt *jwt_decode(const char *token, const struct jwt_key *key)
+{
+ const char *alg_name = jwt_alg_names[key->alg];
+ enum hash_algo hash_algo;
+ const char *payload, *signature, *end;
+ u8 *sigbin;
+ size_t sig_len, sigbin_len;
+ struct jwt *jwt;
+ u8 *hash;
+ int ret;
+
+ token = jwt_split(token, &payload, &signature, &end);
+ if (IS_ERR(token))
+ return ERR_CAST(token);
+
+ sig_len = end - signature;
+
+ switch (key->alg) {
+ case JWT_ALG_RS256:
+ case JWT_ALG_RS384:
+ case JWT_ALG_RS512:
+ if (sig_len == 0)
+ return ERR_PTR(-EILSEQ);
+
+ sigbin = xzalloc(sig_len);
+ sigbin_len = decode_base64url(sigbin, sig_len, signature);
+
+ hash_algo = digest_algo_by_jwt_alg(key->alg);
+ hash = do_hash(token, signature - token - 1, hash_algo);
+ if (IS_ERR(hash)) {
+ free(sigbin);
+ return ERR_CAST(hash);
+ }
+
+ ret = rsa_verify(key->material.rsa_pub, sigbin, sigbin_len, hash,
+ hash_algo);
+ free(hash);
+ free(sigbin);
+ if (ret < 0) {
+ pr_debug("%s signature does not match: %pe\n",
+ alg_name, ERR_PTR(ret));
+ return ERR_PTR(ret);
+ }
+
+ break;
+ default:
+ return ERR_PTR(-ENOSYS);
+ }
+
+ pr_debug("verification for algo %s ok\n", alg_name);
+
+ jwt = xzalloc(sizeof(*jwt));
+
+ ret = jwt_part_parse(&jwt->header, token, payload - token - 1);
+ if (ret || !jwt_header_ok(jwt, key->alg)) {
+ ret = ret ?: -EINVAL;
+ pr_debug("failed to parse header: %pe\n", ERR_PTR(ret));
+ goto err;
+ }
+
+ ret = jwt_part_parse(&jwt->payload, payload, signature - payload - 1);
+ if (ret) {
+ pr_debug("failed to parse payload: %pe\n", ERR_PTR(ret));
+ goto err;
+ }
+
+ return jwt;
+
+err:
+ jwt_free(jwt);
+ return ERR_PTR(ret);
+}
+
+const char *jwt_get_payload(const struct jwt *t)
+{
+ return t->payload.content;
+}
+
+const jsmntok_t *jwt_get_claim(const struct jwt *t, const char *claim)
+{
+ return jsmn_locate(JP(claim), t->payload.content, t->payload.tokens);
+}
+
+char *jwt_get_claim_str(const struct jwt *t, const char *claim)
+{
+ return jsmn_strdup(JP(claim), t->payload.content, t->payload.tokens);
+}
diff --git a/crypto/rsa.c b/crypto/rsa.c
index fc21efdb6d..b798badce0 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -507,8 +507,8 @@ static void rsa_init_keys_of(void)
for_each_child_of_node(sigs, sig) {
key = rsa_of_read_key(sig);
if (IS_ERR(key)) {
- pr_err("Cannot read rsa key from %s: %pe\n",
- sig->full_name, key);
+ pr_err("Cannot read rsa key from %pOF: %pe\n",
+ sig, key);
continue;
}