diff options
Diffstat (limited to 'include/crypto')
-rw-r--r-- | include/crypto/crc.h | 2 | ||||
-rw-r--r-- | include/crypto/des.h | 4 | ||||
-rw-r--r-- | include/crypto/jwt.h | 55 | ||||
-rw-r--r-- | include/crypto/sha.h | 12 | ||||
-rw-r--r-- | include/crypto/sha1_base.h | 104 | ||||
-rw-r--r-- | include/crypto/sha256_base.h | 129 |
6 files changed, 302 insertions, 4 deletions
diff --git a/include/crypto/crc.h b/include/crypto/crc.h index 6428634d0a..f36c2d6445 100644 --- a/include/crypto/crc.h +++ b/include/crypto/crc.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + /* * Common values for CRC algorithms */ diff --git a/include/crypto/des.h b/include/crypto/des.h index 58fdaaa99d..645a9c9969 100644 --- a/include/crypto/des.h +++ b/include/crypto/des.h @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* * DES & Triple DES EDE Cipher Algorithms. */ diff --git a/include/crypto/jwt.h b/include/crypto/jwt.h new file mode 100644 index 0000000000..4e20b5950e --- /dev/null +++ b/include/crypto/jwt.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __JWT_H_ +#define __JWT_H_ + +#include <linux/types.h> +#include <jsmn.h> + +enum jwt_alg { + JWT_ALG_NONE, + JWT_ALG_HS256, + JWT_ALG_HS384, + JWT_ALG_HS512, + JWT_ALG_PS256, + JWT_ALG_PS384, + JWT_ALG_PS512, + JWT_ALG_RS256, /* supported */ + JWT_ALG_RS384, /* supported */ + JWT_ALG_RS512, /* supported */ + JWT_ALG_ES256, + JWT_ALG_ES256K, + JWT_ALG_ES384, + JWT_ALG_ES512, + JWT_ALG_EDDSA, +}; + +struct jwt_key { + enum jwt_alg alg; + union { + const struct rsa_public_key *rsa_pub; + } material; +}; + +struct jwt_part { + char *content; + int token_count; + jsmntok_t *tokens; +}; + +struct jwt { + struct jwt_part header; + struct jwt_part payload; +}; + +const char *jwt_split(const char *token, + const char **payload, const char **signature, const char **end); + +struct jwt *jwt_decode(const char *token, const struct jwt_key *key); +void jwt_free(struct jwt *jwt); + +const char *jwt_get_payload(const struct jwt *t); + +const jsmntok_t *jwt_get_claim(const struct jwt *t, const char *claim); +char *jwt_get_claim_str(const struct jwt *t, const char *claim); + +#endif diff --git a/include/crypto/sha.h b/include/crypto/sha.h index 190f8a0e02..e23d7cb766 100644 --- a/include/crypto/sha.h +++ b/include/crypto/sha.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + /* * Common values for SHA algorithms */ @@ -64,21 +66,25 @@ #define SHA512_H6 0x1f83d9abfb41bd6bULL #define SHA512_H7 0x5be0cd19137e2179ULL +/* + * State must be first member for compatibility with assembly + * code imported from Linux + */ struct sha1_state { - u64 count; u32 state[SHA1_DIGEST_SIZE / 4]; + u64 count; u8 buffer[SHA1_BLOCK_SIZE]; }; struct sha256_state { - u64 count; u32 state[SHA256_DIGEST_SIZE / 4]; + u64 count; u8 buf[SHA256_BLOCK_SIZE]; }; struct sha512_state { - u64 count[2]; u64 state[SHA512_DIGEST_SIZE / 8]; + u64 count[2]; u8 buf[SHA512_BLOCK_SIZE]; }; diff --git a/include/crypto/sha1_base.h b/include/crypto/sha1_base.h new file mode 100644 index 0000000000..8e1a5fdcc8 --- /dev/null +++ b/include/crypto/sha1_base.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * sha1_base.h - core logic for SHA-1 implementations + * + * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org> + */ + +#ifndef _CRYPTO_SHA1_BASE_H +#define _CRYPTO_SHA1_BASE_H + +#include <digest.h> +#include <crypto/sha.h> +#include <linux/string.h> + +#include <asm/unaligned.h> + +typedef void (sha1_block_fn)(struct sha1_state *sst, u8 const *src, int blocks); + +static inline int sha1_base_init(struct digest *desc) +{ + struct sha1_state *sctx = digest_ctx(desc); + + *sctx = (struct sha1_state){ + .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 }, + }; + + return 0; +} + +static inline int sha1_base_do_update(struct digest *desc, + const u8 *data, + unsigned int len, + sha1_block_fn *block_fn) +{ + struct sha1_state *sctx = digest_ctx(desc); + unsigned int partial = sctx->count % SHA1_BLOCK_SIZE; + + sctx->count += len; + + if (unlikely((partial + len) >= SHA1_BLOCK_SIZE)) { + int blocks; + + if (partial) { + int p = SHA1_BLOCK_SIZE - partial; + + memcpy(sctx->buffer + partial, data, p); + data += p; + len -= p; + + block_fn(sctx, sctx->buffer, 1); + } + + blocks = len / SHA1_BLOCK_SIZE; + len %= SHA1_BLOCK_SIZE; + + if (blocks) { + block_fn(sctx, data, blocks); + data += blocks * SHA1_BLOCK_SIZE; + } + partial = 0; + } + if (len) + memcpy(sctx->buffer + partial, data, len); + + return 0; +} + +static inline int sha1_base_do_finalize(struct digest *desc, + sha1_block_fn *block_fn) +{ + const int bit_offset = SHA1_BLOCK_SIZE - sizeof(__be64); + struct sha1_state *sctx = digest_ctx(desc); + __be64 *bits = (__be64 *)(sctx->buffer + bit_offset); + unsigned int partial = sctx->count % SHA1_BLOCK_SIZE; + + sctx->buffer[partial++] = 0x80; + if (partial > bit_offset) { + memset(sctx->buffer + partial, 0x0, SHA1_BLOCK_SIZE - partial); + partial = 0; + + block_fn(sctx, sctx->buffer, 1); + } + + memset(sctx->buffer + partial, 0x0, bit_offset - partial); + *bits = cpu_to_be64(sctx->count << 3); + block_fn(sctx, sctx->buffer, 1); + + return 0; +} + +static inline int sha1_base_finish(struct digest *desc, u8 *out) +{ + struct sha1_state *sctx = digest_ctx(desc); + __be32 *digest = (__be32 *)out; + int i; + + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++) + put_unaligned_be32(sctx->state[i], digest++); + + memzero_explicit(sctx, sizeof(*sctx)); + return 0; +} + +#endif /* _CRYPTO_SHA1_BASE_H */ diff --git a/include/crypto/sha256_base.h b/include/crypto/sha256_base.h new file mode 100644 index 0000000000..b9e48eb942 --- /dev/null +++ b/include/crypto/sha256_base.h @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * sha256_base.h - core logic for SHA-256 implementations + * + * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org> + */ + +#ifndef _CRYPTO_SHA256_BASE_H +#define _CRYPTO_SHA256_BASE_H + +#include <digest.h> +#include <crypto/sha.h> +#include <linux/string.h> + +#include <asm/unaligned.h> + +typedef void (sha256_block_fn)(struct sha256_state *sst, u8 const *src, + int blocks); + +static inline int sha224_base_init(struct digest *desc) +{ + struct sha256_state *sctx = digest_ctx(desc); + + sctx->state[0] = SHA224_H0; + sctx->state[1] = SHA224_H1; + sctx->state[2] = SHA224_H2; + sctx->state[3] = SHA224_H3; + sctx->state[4] = SHA224_H4; + sctx->state[5] = SHA224_H5; + sctx->state[6] = SHA224_H6; + sctx->state[7] = SHA224_H7; + sctx->count = 0; + + return 0; +} + +static inline int sha256_base_init(struct digest *desc) +{ + struct sha256_state *sctx = digest_ctx(desc); + + sctx->state[0] = SHA256_H0; + sctx->state[1] = SHA256_H1; + sctx->state[2] = SHA256_H2; + sctx->state[3] = SHA256_H3; + sctx->state[4] = SHA256_H4; + sctx->state[5] = SHA256_H5; + sctx->state[6] = SHA256_H6; + sctx->state[7] = SHA256_H7; + sctx->count = 0; + + return 0; +} + +static inline int sha256_base_do_update(struct digest *desc, + const u8 *data, + unsigned int len, + sha256_block_fn *block_fn) +{ + struct sha256_state *sctx = digest_ctx(desc); + unsigned int partial = sctx->count % SHA256_BLOCK_SIZE; + + sctx->count += len; + + if (unlikely((partial + len) >= SHA256_BLOCK_SIZE)) { + int blocks; + + if (partial) { + int p = SHA256_BLOCK_SIZE - partial; + + memcpy(sctx->buf + partial, data, p); + data += p; + len -= p; + + block_fn(sctx, sctx->buf, 1); + } + + blocks = len / SHA256_BLOCK_SIZE; + len %= SHA256_BLOCK_SIZE; + + if (blocks) { + block_fn(sctx, data, blocks); + data += blocks * SHA256_BLOCK_SIZE; + } + partial = 0; + } + if (len) + memcpy(sctx->buf + partial, data, len); + + return 0; +} + +static inline int sha256_base_do_finalize(struct digest *desc, + sha256_block_fn *block_fn) +{ + const int bit_offset = SHA256_BLOCK_SIZE - sizeof(__be64); + struct sha256_state *sctx = digest_ctx(desc); + __be64 *bits = (__be64 *)(sctx->buf + bit_offset); + unsigned int partial = sctx->count % SHA256_BLOCK_SIZE; + + sctx->buf[partial++] = 0x80; + if (partial > bit_offset) { + memset(sctx->buf + partial, 0x0, SHA256_BLOCK_SIZE - partial); + partial = 0; + + block_fn(sctx, sctx->buf, 1); + } + + memset(sctx->buf + partial, 0x0, bit_offset - partial); + *bits = cpu_to_be64(sctx->count << 3); + block_fn(sctx, sctx->buf, 1); + + return 0; +} + +static inline int sha256_base_finish(struct digest *desc, u8 *out) +{ + unsigned int digest_size = digest_length(desc); + struct sha256_state *sctx = digest_ctx(desc); + __be32 *digest = (__be32 *)out; + int i; + + for (i = 0; digest_size > 0; i++, digest_size -= sizeof(__be32)) + put_unaligned_be32(sctx->state[i], digest++); + + memzero_explicit(sctx, sizeof(*sctx)); + return 0; +} + +#endif /* _CRYPTO_SHA256_BASE_H */ |