summaryrefslogtreecommitdiffstats
path: root/include/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'include/crypto')
-rw-r--r--include/crypto/crc.h2
-rw-r--r--include/crypto/des.h4
-rw-r--r--include/crypto/jwt.h55
-rw-r--r--include/crypto/sha.h12
-rw-r--r--include/crypto/sha1_base.h104
-rw-r--r--include/crypto/sha256_base.h129
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 */