summaryrefslogtreecommitdiff
path: root/include/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'include/crypto')
-rw-r--r--include/crypto/acompress.h5
-rw-r--r--include/crypto/aes-cbc-macs.h154
-rw-r--r--include/crypto/aes.h66
-rw-r--r--include/crypto/chacha20poly1305.h2
-rw-r--r--include/crypto/cryptd.h33
-rw-r--r--include/crypto/des.h8
-rw-r--r--include/crypto/gcm.h4
-rw-r--r--include/crypto/gf128hash.h (renamed from include/crypto/polyval.h)126
-rw-r--r--include/crypto/gf128mul.h17
-rw-r--r--include/crypto/ghash.h12
-rw-r--r--include/crypto/hkdf.h20
-rw-r--r--include/crypto/if_alg.h5
-rw-r--r--include/crypto/internal/acompress.h1
-rw-r--r--include/crypto/internal/blockhash.h52
-rw-r--r--include/crypto/internal/ecc.h22
-rw-r--r--include/crypto/internal/geniv.h2
-rw-r--r--include/crypto/internal/scompress.h1
-rw-r--r--include/crypto/internal/simd.h19
-rw-r--r--include/crypto/krb5.h9
-rw-r--r--include/crypto/rng.h25
-rw-r--r--include/crypto/skcipher.h1
-rw-r--r--include/crypto/sm3.h85
-rw-r--r--include/crypto/sm3_base.h82
23 files changed, 437 insertions, 314 deletions
diff --git a/include/crypto/acompress.h b/include/crypto/acompress.h
index 9eacb9fa375d..5d5358dfab73 100644
--- a/include/crypto/acompress.h
+++ b/include/crypto/acompress.h
@@ -240,9 +240,10 @@ static inline const char *crypto_acomp_driver_name(struct crypto_acomp *tfm)
}
/**
- * acomp_request_alloc() -- allocates asynchronous (de)compression request
+ * acomp_request_alloc_extra() -- allocates asynchronous (de)compression request
*
* @tfm: ACOMPRESS tfm handle allocated with crypto_alloc_acomp()
+ * @extra: amount of extra memory
* @gfp: gfp to pass to kzalloc (defaults to GFP_KERNEL)
*
* Return: allocated handle in case of success or NULL in case of an error
@@ -318,7 +319,7 @@ static inline void acomp_request_free(struct acomp_req *req)
*
* @req: request that the callback will be set for
* @flgs: specify for instance if the operation may backlog
- * @cmlp: callback which will be called
+ * @cmpl: callback which will be called
* @data: private data used by the caller
*/
static inline void acomp_request_set_callback(struct acomp_req *req,
diff --git a/include/crypto/aes-cbc-macs.h b/include/crypto/aes-cbc-macs.h
new file mode 100644
index 000000000000..e61df108b926
--- /dev/null
+++ b/include/crypto/aes-cbc-macs.h
@@ -0,0 +1,154 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Support for AES-CMAC, AES-XCBC-MAC, and AES-CBC-MAC
+ *
+ * Copyright 2026 Google LLC
+ */
+#ifndef _CRYPTO_AES_CBC_MACS_H
+#define _CRYPTO_AES_CBC_MACS_H
+
+#include <crypto/aes.h>
+
+/**
+ * struct aes_cmac_key - Prepared key for AES-CMAC or AES-XCBC-MAC
+ * @aes: The AES key for cipher block chaining
+ * @k_final: Finalization subkeys for the final block.
+ * k_final[0] (CMAC K1, XCBC-MAC K2) is used if it's a full block.
+ * k_final[1] (CMAC K2, XCBC-MAC K3) is used if it's a partial block.
+ */
+struct aes_cmac_key {
+ struct aes_enckey aes;
+ union {
+ u8 b[AES_BLOCK_SIZE];
+ __be64 w[2];
+ } k_final[2];
+};
+
+/**
+ * struct aes_cmac_ctx - Context for computing an AES-CMAC or AES-XCBC-MAC value
+ * @key: Pointer to the key struct. A pointer is used rather than a copy of the
+ * struct, since the key struct size may be large. It is assumed that the
+ * key lives at least as long as the context.
+ * @partial_len: Number of bytes that have been XOR'ed into @h since the last
+ * AES encryption. This is 0 if no data has been processed yet,
+ * or between 1 and AES_BLOCK_SIZE inclusive otherwise.
+ * @h: The current chaining value
+ */
+struct aes_cmac_ctx {
+ const struct aes_cmac_key *key;
+ size_t partial_len;
+ u8 h[AES_BLOCK_SIZE];
+};
+
+/**
+ * aes_cmac_preparekey() - Prepare a key for AES-CMAC
+ * @key: (output) The key struct to initialize
+ * @in_key: The raw AES key
+ * @key_len: Length of the raw key in bytes. The supported values are
+ * AES_KEYSIZE_128, AES_KEYSIZE_192, and AES_KEYSIZE_256.
+ *
+ * Context: Any context.
+ * Return: 0 on success or -EINVAL if the given key length is invalid. No other
+ * errors are possible, so callers that always pass a valid key length
+ * don't need to check for errors.
+ */
+int aes_cmac_preparekey(struct aes_cmac_key *key, const u8 *in_key,
+ size_t key_len);
+
+/**
+ * aes_xcbcmac_preparekey() - Prepare a key for AES-XCBC-MAC
+ * @key: (output) The key struct to initialize
+ * @in_key: The raw key. As per the AES-XCBC-MAC specification (RFC 3566), this
+ * is 128 bits, matching the internal use of AES-128.
+ *
+ * AES-XCBC-MAC and AES-CMAC are the same except for the key preparation. After
+ * that step, AES-XCBC-MAC is supported via the aes_cmac_* functions.
+ *
+ * New users should use AES-CMAC instead of AES-XCBC-MAC.
+ *
+ * Context: Any context.
+ */
+void aes_xcbcmac_preparekey(struct aes_cmac_key *key,
+ const u8 in_key[at_least AES_KEYSIZE_128]);
+
+/**
+ * aes_cmac_init() - Start computing an AES-CMAC or AES-XCBC-MAC value
+ * @ctx: (output) The context to initialize
+ * @key: The key to use. Note that a pointer to the key is saved in the
+ * context, so the key must live at least as long as the context.
+ *
+ * This supports both AES-CMAC and AES-XCBC-MAC. Which one is done depends on
+ * whether aes_cmac_preparekey() or aes_xcbcmac_preparekey() was called.
+ */
+static inline void aes_cmac_init(struct aes_cmac_ctx *ctx,
+ const struct aes_cmac_key *key)
+{
+ *ctx = (struct aes_cmac_ctx){ .key = key };
+}
+
+/**
+ * aes_cmac_update() - Update an AES-CMAC or AES-XCBC-MAC context with more data
+ * @ctx: The context to update; must have been initialized
+ * @data: The message data
+ * @data_len: The data length in bytes. Doesn't need to be block-aligned.
+ *
+ * This can be called any number of times.
+ *
+ * Context: Any context.
+ */
+void aes_cmac_update(struct aes_cmac_ctx *ctx, const u8 *data, size_t data_len);
+
+/**
+ * aes_cmac_final() - Finish computing an AES-CMAC or AES-XCBC-MAC value
+ * @ctx: The context to finalize; must have been initialized
+ * @out: (output) The resulting MAC
+ *
+ * After finishing, this zeroizes @ctx. So the caller does not need to do it.
+ *
+ * Context: Any context.
+ */
+void aes_cmac_final(struct aes_cmac_ctx *ctx, u8 out[at_least AES_BLOCK_SIZE]);
+
+/**
+ * aes_cmac() - Compute AES-CMAC or AES-XCBC-MAC in one shot
+ * @key: The key to use
+ * @data: The message data
+ * @data_len: The data length in bytes
+ * @out: (output) The resulting AES-CMAC or AES-XCBC-MAC value
+ *
+ * This supports both AES-CMAC and AES-XCBC-MAC. Which one is done depends on
+ * whether aes_cmac_preparekey() or aes_xcbcmac_preparekey() was called.
+ *
+ * Context: Any context.
+ */
+static inline void aes_cmac(const struct aes_cmac_key *key, const u8 *data,
+ size_t data_len, u8 out[at_least AES_BLOCK_SIZE])
+{
+ struct aes_cmac_ctx ctx;
+
+ aes_cmac_init(&ctx, key);
+ aes_cmac_update(&ctx, data, data_len);
+ aes_cmac_final(&ctx, out);
+}
+
+/*
+ * AES-CBC-MAC support. This is provided only for use by the implementation of
+ * AES-CCM. It should have no other users. Warning: unlike AES-CMAC and
+ * AES-XCBC-MAC, AES-CBC-MAC isn't a secure MAC for variable-length messages.
+ */
+struct aes_cbcmac_ctx {
+ const struct aes_enckey *key;
+ size_t partial_len;
+ u8 h[AES_BLOCK_SIZE];
+};
+static inline void aes_cbcmac_init(struct aes_cbcmac_ctx *ctx,
+ const struct aes_enckey *key)
+{
+ *ctx = (struct aes_cbcmac_ctx){ .key = key };
+}
+void aes_cbcmac_update(struct aes_cbcmac_ctx *ctx, const u8 *data,
+ size_t data_len);
+void aes_cbcmac_final(struct aes_cbcmac_ctx *ctx,
+ u8 out[at_least AES_BLOCK_SIZE]);
+
+#endif /* _CRYPTO_AES_CBC_MACS_H */
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
index cbf1cc96db52..16fbfd93e2bd 100644
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -167,6 +167,72 @@ int aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key,
#ifdef CONFIG_ARM64
int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key,
unsigned int key_len);
+asmlinkage void neon_aes_ecb_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int blocks);
+asmlinkage void neon_aes_ecb_decrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int blocks);
+asmlinkage void neon_aes_cbc_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int blocks, u8 iv[]);
+asmlinkage void neon_aes_cbc_decrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int blocks, u8 iv[]);
+asmlinkage void neon_aes_cbc_cts_encrypt(u8 out[], u8 const in[],
+ u32 const rk[], int rounds, int bytes,
+ u8 const iv[]);
+asmlinkage void neon_aes_cbc_cts_decrypt(u8 out[], u8 const in[],
+ u32 const rk[], int rounds, int bytes,
+ u8 const iv[]);
+asmlinkage void neon_aes_ctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int bytes, u8 ctr[]);
+asmlinkage void neon_aes_xctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int bytes, u8 ctr[],
+ int byte_ctr);
+asmlinkage void neon_aes_xts_encrypt(u8 out[], u8 const in[], u32 const rk1[],
+ int rounds, int bytes, u32 const rk2[],
+ u8 iv[], int first);
+asmlinkage void neon_aes_xts_decrypt(u8 out[], u8 const in[], u32 const rk1[],
+ int rounds, int bytes, u32 const rk2[],
+ u8 iv[], int first);
+asmlinkage void neon_aes_essiv_cbc_encrypt(u8 out[], u8 const in[],
+ u32 const rk1[], int rounds,
+ int blocks, u8 iv[],
+ u32 const rk2[]);
+asmlinkage void neon_aes_essiv_cbc_decrypt(u8 out[], u8 const in[],
+ u32 const rk1[], int rounds,
+ int blocks, u8 iv[],
+ u32 const rk2[]);
+
+asmlinkage void ce_aes_ecb_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int blocks);
+asmlinkage void ce_aes_ecb_decrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int blocks);
+asmlinkage void ce_aes_cbc_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int blocks, u8 iv[]);
+asmlinkage void ce_aes_cbc_decrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int blocks, u8 iv[]);
+asmlinkage void ce_aes_cbc_cts_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int bytes, u8 const iv[]);
+asmlinkage void ce_aes_cbc_cts_decrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int bytes, u8 const iv[]);
+asmlinkage void ce_aes_ctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int bytes, u8 ctr[]);
+asmlinkage void ce_aes_xctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
+ int rounds, int bytes, u8 ctr[],
+ int byte_ctr);
+asmlinkage void ce_aes_xts_encrypt(u8 out[], u8 const in[], u32 const rk1[],
+ int rounds, int bytes, u32 const rk2[],
+ u8 iv[], int first);
+asmlinkage void ce_aes_xts_decrypt(u8 out[], u8 const in[], u32 const rk1[],
+ int rounds, int bytes, u32 const rk2[],
+ u8 iv[], int first);
+asmlinkage void ce_aes_essiv_cbc_encrypt(u8 out[], u8 const in[],
+ u32 const rk1[], int rounds,
+ int blocks, u8 iv[], u32 const rk2[]);
+asmlinkage void ce_aes_essiv_cbc_decrypt(u8 out[], u8 const in[],
+ u32 const rk1[], int rounds,
+ int blocks, u8 iv[], u32 const rk2[]);
+asmlinkage void ce_aes_mac_update(u8 const in[], u32 const rk[], int rounds,
+ size_t blocks, u8 dg[], int enc_before,
+ int enc_after);
#elif defined(CONFIG_PPC)
void ppc_expand_key_128(u32 *key_enc, const u8 *key);
void ppc_expand_key_192(u32 *key_enc, const u8 *key);
diff --git a/include/crypto/chacha20poly1305.h b/include/crypto/chacha20poly1305.h
index 0f71b037702d..0f6d99170aaf 100644
--- a/include/crypto/chacha20poly1305.h
+++ b/include/crypto/chacha20poly1305.h
@@ -46,6 +46,4 @@ bool chacha20poly1305_decrypt_sg_inplace(struct scatterlist *src, size_t src_len
const u64 nonce,
const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
-bool chacha20poly1305_selftest(void);
-
#endif /* __CHACHA20POLY1305_H */
diff --git a/include/crypto/cryptd.h b/include/crypto/cryptd.h
index 796d986e58e1..29c5878a3609 100644
--- a/include/crypto/cryptd.h
+++ b/include/crypto/cryptd.h
@@ -16,39 +16,6 @@
#include <linux/types.h>
#include <crypto/aead.h>
-#include <crypto/hash.h>
-#include <crypto/skcipher.h>
-
-struct cryptd_skcipher {
- struct crypto_skcipher base;
-};
-
-/* alg_name should be algorithm to be cryptd-ed */
-struct cryptd_skcipher *cryptd_alloc_skcipher(const char *alg_name,
- u32 type, u32 mask);
-struct crypto_skcipher *cryptd_skcipher_child(struct cryptd_skcipher *tfm);
-/* Must be called without moving CPUs. */
-bool cryptd_skcipher_queued(struct cryptd_skcipher *tfm);
-void cryptd_free_skcipher(struct cryptd_skcipher *tfm);
-
-struct cryptd_ahash {
- struct crypto_ahash base;
-};
-
-static inline struct cryptd_ahash *__cryptd_ahash_cast(
- struct crypto_ahash *tfm)
-{
- return (struct cryptd_ahash *)tfm;
-}
-
-/* alg_name should be algorithm to be cryptd-ed */
-struct cryptd_ahash *cryptd_alloc_ahash(const char *alg_name,
- u32 type, u32 mask);
-struct crypto_shash *cryptd_ahash_child(struct cryptd_ahash *tfm);
-struct shash_desc *cryptd_shash_desc(struct ahash_request *req);
-/* Must be called without moving CPUs. */
-bool cryptd_ahash_queued(struct cryptd_ahash *tfm);
-void cryptd_free_ahash(struct cryptd_ahash *tfm);
struct cryptd_aead {
struct crypto_aead base;
diff --git a/include/crypto/des.h b/include/crypto/des.h
index 7812b4331ae4..73eec617f480 100644
--- a/include/crypto/des.h
+++ b/include/crypto/des.h
@@ -34,9 +34,9 @@ void des3_ede_decrypt(const struct des3_ede_ctx *dctx, u8 *dst, const u8 *src);
* des_expand_key - Expand a DES input key into a key schedule
* @ctx: the key schedule
* @key: buffer containing the input key
- * @len: size of the buffer contents
+ * @keylen: size of the buffer contents
*
- * Returns 0 on success, -EINVAL if the input key is rejected and -ENOKEY if
+ * Returns: 0 on success, -EINVAL if the input key is rejected and -ENOKEY if
* the key is accepted but has been found to be weak.
*/
int des_expand_key(struct des_ctx *ctx, const u8 *key, unsigned int keylen);
@@ -45,9 +45,9 @@ int des_expand_key(struct des_ctx *ctx, const u8 *key, unsigned int keylen);
* des3_ede_expand_key - Expand a triple DES input key into a key schedule
* @ctx: the key schedule
* @key: buffer containing the input key
- * @len: size of the buffer contents
+ * @keylen: size of the buffer contents
*
- * Returns 0 on success, -EINVAL if the input key is rejected and -ENOKEY if
+ * Returns: 0 on success, -EINVAL if the input key is rejected and -ENOKEY if
* the key is accepted but has been found to be weak. Note that weak keys will
* be rejected (and -EINVAL will be returned) when running in FIPS mode.
*/
diff --git a/include/crypto/gcm.h b/include/crypto/gcm.h
index b524e47bd4d0..1d5f39ff1dc4 100644
--- a/include/crypto/gcm.h
+++ b/include/crypto/gcm.h
@@ -4,7 +4,7 @@
#include <linux/errno.h>
#include <crypto/aes.h>
-#include <crypto/gf128mul.h>
+#include <crypto/gf128hash.h>
#define GCM_AES_IV_SIZE 12
#define GCM_RFC4106_IV_SIZE 8
@@ -65,7 +65,7 @@ static inline int crypto_ipsec_check_assoclen(unsigned int assoclen)
}
struct aesgcm_ctx {
- be128 ghash_key;
+ struct ghash_key ghash_key;
struct aes_enckey aes_key;
unsigned int authsize;
};
diff --git a/include/crypto/polyval.h b/include/crypto/gf128hash.h
index b28b8ef11353..41c557d55965 100644
--- a/include/crypto/polyval.h
+++ b/include/crypto/gf128hash.h
@@ -1,13 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
- * POLYVAL library API
+ * GF(2^128) polynomial hashing: GHASH and POLYVAL
*
* Copyright 2025 Google LLC
*/
-#ifndef _CRYPTO_POLYVAL_H
-#define _CRYPTO_POLYVAL_H
+#ifndef _CRYPTO_GF128HASH_H
+#define _CRYPTO_GF128HASH_H
+#include <crypto/ghash.h>
#include <linux/string.h>
#include <linux/types.h>
@@ -34,6 +35,24 @@ struct polyval_elem {
};
/**
+ * struct ghash_key - Prepared key for GHASH
+ *
+ * Use ghash_preparekey() to initialize this.
+ */
+struct ghash_key {
+#if defined(CONFIG_CRYPTO_LIB_GF128HASH_ARCH) && defined(CONFIG_PPC64)
+ /** @htable: GHASH key format used by the POWER8 assembly code */
+ u64 htable[4][2];
+#elif defined(CONFIG_CRYPTO_LIB_GF128HASH_ARCH) && \
+ (defined(CONFIG_RISCV) || defined(CONFIG_S390))
+ /** @h_raw: The hash key H, in GHASH format */
+ u8 h_raw[GHASH_BLOCK_SIZE];
+#endif
+ /** @h: The hash key H, in POLYVAL format */
+ struct polyval_elem h;
+};
+
+/**
* struct polyval_key - Prepared key for POLYVAL
*
* This may contain just the raw key H, or it may contain precomputed key
@@ -44,20 +63,28 @@ struct polyval_elem {
* exponentiation repeats the POLYVAL dot operation, with its "extra" x^-128.
*/
struct polyval_key {
-#ifdef CONFIG_CRYPTO_LIB_POLYVAL_ARCH
-#ifdef CONFIG_ARM64
- /** @h_powers: Powers of the hash key H^8 through H^1 */
- struct polyval_elem h_powers[8];
-#elif defined(CONFIG_X86)
+#if defined(CONFIG_CRYPTO_LIB_GF128HASH_ARCH) && \
+ (defined(CONFIG_ARM64) || defined(CONFIG_X86))
/** @h_powers: Powers of the hash key H^8 through H^1 */
struct polyval_elem h_powers[8];
#else
-#error "Unhandled arch"
-#endif
-#else /* CONFIG_CRYPTO_LIB_POLYVAL_ARCH */
/** @h: The hash key H */
struct polyval_elem h;
-#endif /* !CONFIG_CRYPTO_LIB_POLYVAL_ARCH */
+#endif
+};
+
+/**
+ * struct ghash_ctx - Context for computing a GHASH value
+ * @key: Pointer to the prepared GHASH key. The user of the API is
+ * responsible for ensuring that the key lives as long as the context.
+ * @acc: The accumulator. It is stored in POLYVAL format rather than GHASH
+ * format, since most implementations want it in POLYVAL format.
+ * @partial: Number of data bytes processed so far modulo GHASH_BLOCK_SIZE
+ */
+struct ghash_ctx {
+ const struct ghash_key *key;
+ struct polyval_elem acc;
+ size_t partial;
};
/**
@@ -74,6 +101,18 @@ struct polyval_ctx {
};
/**
+ * ghash_preparekey() - Prepare a GHASH key
+ * @key: (output) The key structure to initialize
+ * @raw_key: The raw hash key
+ *
+ * Initialize a GHASH key structure from a raw key.
+ *
+ * Context: Any context.
+ */
+void ghash_preparekey(struct ghash_key *key,
+ const u8 raw_key[GHASH_BLOCK_SIZE]);
+
+/**
* polyval_preparekey() - Prepare a POLYVAL key
* @key: (output) The key structure to initialize
* @raw_key: The raw hash key
@@ -84,18 +123,20 @@ struct polyval_ctx {
*
* Context: Any context.
*/
-#ifdef CONFIG_CRYPTO_LIB_POLYVAL_ARCH
void polyval_preparekey(struct polyval_key *key,
const u8 raw_key[POLYVAL_BLOCK_SIZE]);
-#else
-static inline void polyval_preparekey(struct polyval_key *key,
- const u8 raw_key[POLYVAL_BLOCK_SIZE])
+/**
+ * ghash_init() - Initialize a GHASH context for a new message
+ * @ctx: The context to initialize
+ * @key: The key to use. Note that a pointer to the key is saved in the
+ * context, so the key must live at least as long as the context.
+ */
+static inline void ghash_init(struct ghash_ctx *ctx,
+ const struct ghash_key *key)
{
- /* Just a simple copy, so inline it. */
- memcpy(key->h.bytes, raw_key, POLYVAL_BLOCK_SIZE);
+ *ctx = (struct ghash_ctx){ .key = key };
}
-#endif
/**
* polyval_init() - Initialize a POLYVAL context for a new message
@@ -142,6 +183,18 @@ static inline void polyval_export_blkaligned(const struct polyval_ctx *ctx,
}
/**
+ * ghash_update() - Update a GHASH context with message data
+ * @ctx: The context to update; must have been initialized
+ * @data: The message data
+ * @len: The data length in bytes. Doesn't need to be block-aligned.
+ *
+ * This can be called any number of times.
+ *
+ * Context: Any context.
+ */
+void ghash_update(struct ghash_ctx *ctx, const u8 *data, size_t len);
+
+/**
* polyval_update() - Update a POLYVAL context with message data
* @ctx: The context to update; must have been initialized
* @data: The message data
@@ -154,6 +207,20 @@ static inline void polyval_export_blkaligned(const struct polyval_ctx *ctx,
void polyval_update(struct polyval_ctx *ctx, const u8 *data, size_t len);
/**
+ * ghash_final() - Finish computing a GHASH value
+ * @ctx: The context to finalize
+ * @out: The output value
+ *
+ * If the total data length isn't a multiple of GHASH_BLOCK_SIZE, then the
+ * final block is automatically zero-padded.
+ *
+ * After finishing, this zeroizes @ctx. So the caller does not need to do it.
+ *
+ * Context: Any context.
+ */
+void ghash_final(struct ghash_ctx *ctx, u8 out[GHASH_BLOCK_SIZE]);
+
+/**
* polyval_final() - Finish computing a POLYVAL value
* @ctx: The context to finalize
* @out: The output value
@@ -168,6 +235,25 @@ void polyval_update(struct polyval_ctx *ctx, const u8 *data, size_t len);
void polyval_final(struct polyval_ctx *ctx, u8 out[POLYVAL_BLOCK_SIZE]);
/**
+ * ghash() - Compute a GHASH value
+ * @key: The prepared key
+ * @data: The message data
+ * @len: The data length in bytes. Doesn't need to be block-aligned.
+ * @out: The output value
+ *
+ * Context: Any context.
+ */
+static inline void ghash(const struct ghash_key *key, const u8 *data,
+ size_t len, u8 out[GHASH_BLOCK_SIZE])
+{
+ struct ghash_ctx ctx;
+
+ ghash_init(&ctx, key);
+ ghash_update(&ctx, data, len);
+ ghash_final(&ctx, out);
+}
+
+/**
* polyval() - Compute a POLYVAL value
* @key: The prepared key
* @data: The message data
@@ -187,4 +273,4 @@ static inline void polyval(const struct polyval_key *key,
polyval_final(&ctx, out);
}
-#endif /* _CRYPTO_POLYVAL_H */
+#endif /* _CRYPTO_GF128HASH_H */
diff --git a/include/crypto/gf128mul.h b/include/crypto/gf128mul.h
index b0853f7cada0..6ed2a8351902 100644
--- a/include/crypto/gf128mul.h
+++ b/include/crypto/gf128mul.h
@@ -215,25 +215,14 @@ static inline void gf128mul_x_ble(le128 *r, const le128 *x)
r->b = cpu_to_le64((b << 1) ^ _tt);
}
-/* 4k table optimization */
-
-struct gf128mul_4k {
- be128 t[256];
-};
-
-struct gf128mul_4k *gf128mul_init_4k_lle(const be128 *g);
-void gf128mul_4k_lle(be128 *a, const struct gf128mul_4k *t);
void gf128mul_x8_ble(le128 *r, const le128 *x);
-static inline void gf128mul_free_4k(struct gf128mul_4k *t)
-{
- kfree_sensitive(t);
-}
-
/* 64k table optimization, implemented for bbe */
struct gf128mul_64k {
- struct gf128mul_4k *t[16];
+ struct {
+ be128 t[256];
+ } *t[16];
};
/* First initialize with the constant factor with which you
diff --git a/include/crypto/ghash.h b/include/crypto/ghash.h
index 043d938e9a2c..d187e5af9925 100644
--- a/include/crypto/ghash.h
+++ b/include/crypto/ghash.h
@@ -6,19 +6,7 @@
#ifndef __CRYPTO_GHASH_H__
#define __CRYPTO_GHASH_H__
-#include <linux/types.h>
-
#define GHASH_BLOCK_SIZE 16
#define GHASH_DIGEST_SIZE 16
-struct gf128mul_4k;
-
-struct ghash_ctx {
- struct gf128mul_4k *gf128;
-};
-
-struct ghash_desc_ctx {
- u8 buffer[GHASH_BLOCK_SIZE];
-};
-
#endif
diff --git a/include/crypto/hkdf.h b/include/crypto/hkdf.h
deleted file mode 100644
index 6a9678f508f5..000000000000
--- a/include/crypto/hkdf.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * HKDF: HMAC-based Key Derivation Function (HKDF), RFC 5869
- *
- * Extracted from fs/crypto/hkdf.c, which has
- * Copyright 2019 Google LLC
- */
-
-#ifndef _CRYPTO_HKDF_H
-#define _CRYPTO_HKDF_H
-
-#include <crypto/hash.h>
-
-int hkdf_extract(struct crypto_shash *hmac_tfm, const u8 *ikm,
- unsigned int ikmlen, const u8 *salt, unsigned int saltlen,
- u8 *prk);
-int hkdf_expand(struct crypto_shash *hmac_tfm,
- const u8 *info, unsigned int infolen,
- u8 *okm, unsigned int okmlen);
-#endif
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index 107b797c33ec..0cc8fa749f68 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -230,9 +230,8 @@ static inline bool af_alg_readable(struct sock *sk)
return PAGE_SIZE <= af_alg_rcvbuf(sk);
}
-unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset);
-void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
- size_t dst_offset);
+unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes);
+void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst);
void af_alg_wmem_wakeup(struct sock *sk);
int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min);
int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
diff --git a/include/crypto/internal/acompress.h b/include/crypto/internal/acompress.h
index 9a3f28baa804..9cd37df32dc4 100644
--- a/include/crypto/internal/acompress.h
+++ b/include/crypto/internal/acompress.h
@@ -42,6 +42,7 @@
*
* @base: Common crypto API algorithm data structure
* @calg: Cmonn algorithm data structure shared with scomp
+ * @COMP_ALG_COMMON: see struct comp_alg_common
*/
struct acomp_alg {
int (*compress)(struct acomp_req *req);
diff --git a/include/crypto/internal/blockhash.h b/include/crypto/internal/blockhash.h
deleted file mode 100644
index 52d9d4c82493..000000000000
--- a/include/crypto/internal/blockhash.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Handle partial blocks for block hash.
- *
- * Copyright (c) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
- * Copyright (c) 2025 Herbert Xu <herbert@gondor.apana.org.au>
- */
-
-#ifndef _CRYPTO_INTERNAL_BLOCKHASH_H
-#define _CRYPTO_INTERNAL_BLOCKHASH_H
-
-#include <linux/string.h>
-#include <linux/types.h>
-
-#define BLOCK_HASH_UPDATE_BASE(block_fn, state, src, nbytes, bs, dv, \
- buf, buflen) \
- ({ \
- typeof(block_fn) *_block_fn = &(block_fn); \
- typeof(state + 0) _state = (state); \
- unsigned int _buflen = (buflen); \
- size_t _nbytes = (nbytes); \
- unsigned int _bs = (bs); \
- const u8 *_src = (src); \
- u8 *_buf = (buf); \
- while ((_buflen + _nbytes) >= _bs) { \
- const u8 *data = _src; \
- size_t len = _nbytes; \
- size_t blocks; \
- int remain; \
- if (_buflen) { \
- remain = _bs - _buflen; \
- memcpy(_buf + _buflen, _src, remain); \
- data = _buf; \
- len = _bs; \
- } \
- remain = len % bs; \
- blocks = (len - remain) / (dv); \
- (*_block_fn)(_state, data, blocks); \
- _src += len - remain - _buflen; \
- _nbytes -= len - remain - _buflen; \
- _buflen = 0; \
- } \
- memcpy(_buf + _buflen, _src, _nbytes); \
- _buflen += _nbytes; \
- })
-
-#define BLOCK_HASH_UPDATE(block, state, src, nbytes, bs, buf, buflen) \
- BLOCK_HASH_UPDATE_BASE(block, state, src, nbytes, bs, 1, buf, buflen)
-#define BLOCK_HASH_UPDATE_BLOCKS(block, state, src, nbytes, bs, buf, buflen) \
- BLOCK_HASH_UPDATE_BASE(block, state, src, nbytes, bs, bs, buf, buflen)
-
-#endif /* _CRYPTO_INTERNAL_BLOCKHASH_H */
diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index 57cd75242141..a4b48d76f53a 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -72,8 +72,8 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit
/**
* ecc_digits_from_bytes() - Create ndigits-sized digits array from byte array
* @in: Input byte array
- * @nbytes Size of input byte array
- * @out Output digits array
+ * @nbytes: Size of input byte array
+ * @out: Output digits array
* @ndigits: Number of digits to create from byte array
*
* The first byte in the input byte array is expected to hold the most
@@ -90,7 +90,7 @@ void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
* @private_key: private key to be used for the given curve
* @private_key_len: private key length
*
- * Returns 0 if the key is acceptable, a negative value otherwise
+ * Returns: 0 if the key is acceptable, a negative value otherwise
*/
int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
const u64 *private_key, unsigned int private_key_len);
@@ -104,7 +104,7 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
* @ndigits: curve number of digits
* @private_key: buffer for storing the generated private key
*
- * Returns 0 if the private key was generated successfully, a negative value
+ * Returns: 0 if the private key was generated successfully, a negative value
* if an error occurred.
*/
int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits,
@@ -118,7 +118,7 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits,
* @private_key: pregenerated private key for the given curve
* @public_key: buffer for storing the generated public key
*
- * Returns 0 if the public key was generated successfully, a negative value
+ * Returns: 0 if the public key was generated successfully, a negative value
* if an error occurred.
*/
int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
@@ -136,7 +136,7 @@ int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
* Note: It is recommended that you hash the result of crypto_ecdh_shared_secret
* before using it for symmetric encryption or HMAC.
*
- * Returns 0 if the shared secret was generated successfully, a negative value
+ * Returns: 0 if the shared secret was generated successfully, a negative value
* if an error occurred.
*/
int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
@@ -179,6 +179,8 @@ int ecc_is_pubkey_valid_full(const struct ecc_curve *curve,
*
* @vli: vli to check.
* @ndigits: length of the @vli
+ *
+ * Returns: %true if vli == 0, %false otherwise.
*/
bool vli_is_zero(const u64 *vli, unsigned int ndigits);
@@ -189,7 +191,7 @@ bool vli_is_zero(const u64 *vli, unsigned int ndigits);
* @right: vli
* @ndigits: length of both vlis
*
- * Returns sign of @left - @right, i.e. -1 if @left < @right,
+ * Returns: sign of @left - @right, i.e. -1 if @left < @right,
* 0 if @left == @right, 1 if @left > @right.
*/
int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits);
@@ -199,7 +201,7 @@ int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits);
*
* @result: where to write result
* @left: vli
- * @right vli
+ * @right: vli
* @ndigits: length of all vlis
*
* Note: can modify in-place.
@@ -263,7 +265,7 @@ void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right,
unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits);
/**
- * ecc_aloc_point() - Allocate ECC point.
+ * ecc_alloc_point() - Allocate ECC point.
*
* @ndigits: Length of vlis in u64 qwords.
*
@@ -281,7 +283,7 @@ void ecc_free_point(struct ecc_point *p);
/**
* ecc_point_is_zero() - Check if point is zero.
*
- * @p: Point to check for zero.
+ * @point: Point to check for zero.
*
* Return: true if point is the point at infinity, false otherwise.
*/
diff --git a/include/crypto/internal/geniv.h b/include/crypto/internal/geniv.h
index 012f5fb22d43..e38d9f0487ec 100644
--- a/include/crypto/internal/geniv.h
+++ b/include/crypto/internal/geniv.h
@@ -9,11 +9,9 @@
#define _CRYPTO_INTERNAL_GENIV_H
#include <crypto/internal/aead.h>
-#include <linux/spinlock.h>
#include <linux/types.h>
struct aead_geniv_ctx {
- spinlock_t lock;
struct crypto_aead *child;
u8 salt[] __attribute__ ((aligned(__alignof__(u32))));
};
diff --git a/include/crypto/internal/scompress.h b/include/crypto/internal/scompress.h
index 6a2c5f2e90f9..13a0851a995b 100644
--- a/include/crypto/internal/scompress.h
+++ b/include/crypto/internal/scompress.h
@@ -22,6 +22,7 @@ struct crypto_scomp {
* @decompress: Function performs a de-compress operation
* @streams: Per-cpu memory for algorithm
* @calg: Cmonn algorithm data structure shared with acomp
+ * @COMP_ALG_COMMON: see struct comp_alg_common
*/
struct scomp_alg {
int (*compress)(struct crypto_scomp *tfm, const u8 *src,
diff --git a/include/crypto/internal/simd.h b/include/crypto/internal/simd.h
index 9e338e7aafbd..f5e5d7b63951 100644
--- a/include/crypto/internal/simd.h
+++ b/include/crypto/internal/simd.h
@@ -10,25 +10,6 @@
#include <linux/percpu.h>
#include <linux/types.h>
-/* skcipher support */
-
-struct simd_skcipher_alg;
-struct skcipher_alg;
-
-struct simd_skcipher_alg *simd_skcipher_create_compat(struct skcipher_alg *ialg,
- const char *algname,
- const char *drvname,
- const char *basename);
-void simd_skcipher_free(struct simd_skcipher_alg *alg);
-
-int simd_register_skciphers_compat(struct skcipher_alg *algs, int count,
- struct simd_skcipher_alg **simd_algs);
-
-void simd_unregister_skciphers(struct skcipher_alg *algs, int count,
- struct simd_skcipher_alg **simd_algs);
-
-/* AEAD support */
-
struct simd_aead_alg;
struct aead_alg;
diff --git a/include/crypto/krb5.h b/include/crypto/krb5.h
index 71dd38f59be1..aac3ecf88467 100644
--- a/include/crypto/krb5.h
+++ b/include/crypto/krb5.h
@@ -121,9 +121,12 @@ size_t crypto_krb5_how_much_buffer(const struct krb5_enctype *krb5,
size_t crypto_krb5_how_much_data(const struct krb5_enctype *krb5,
enum krb5_crypto_mode mode,
size_t *_buffer_size, size_t *_offset);
-void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
- enum krb5_crypto_mode mode,
- size_t *_offset, size_t *_len);
+int crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
+ enum krb5_crypto_mode mode,
+ size_t *_offset, size_t *_len);
+int crypto_krb5_check_data_len(const struct krb5_enctype *krb5,
+ enum krb5_crypto_mode mode,
+ size_t len, size_t min_content);
struct crypto_aead *crypto_krb5_prepare_encryption(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
u32 usage, gfp_t gfp);
diff --git a/include/crypto/rng.h b/include/crypto/rng.h
index d451b54b322a..07f494b2c881 100644
--- a/include/crypto/rng.h
+++ b/include/crypto/rng.h
@@ -12,6 +12,8 @@
#include <linux/atomic.h>
#include <linux/container_of.h>
#include <linux/crypto.h>
+#include <linux/fips.h>
+#include <linux/random.h>
struct crypto_rng;
@@ -57,10 +59,27 @@ struct crypto_rng {
struct crypto_tfm base;
};
-extern struct crypto_rng *crypto_default_rng;
+int __crypto_stdrng_get_bytes(void *buf, unsigned int len);
-int crypto_get_default_rng(void);
-void crypto_put_default_rng(void);
+/**
+ * crypto_stdrng_get_bytes() - get cryptographically secure random bytes
+ * @buf: output buffer holding the random numbers
+ * @len: length of the output buffer
+ *
+ * This function fills the caller-allocated buffer with random numbers using the
+ * normal Linux RNG if fips_enabled=0, or the highest-priority "stdrng"
+ * algorithm in the crypto_rng subsystem if fips_enabled=1.
+ *
+ * Context: May sleep
+ * Return: 0 function was successful; < 0 if an error occurred
+ */
+static inline int crypto_stdrng_get_bytes(void *buf, unsigned int len)
+{
+ might_sleep();
+ if (fips_enabled)
+ return __crypto_stdrng_get_bytes(buf, len);
+ return get_random_bytes_wait(buf, len);
+}
/**
* DOC: Random number generator API
diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h
index 9e5853464345..4efe2ca8c4d1 100644
--- a/include/crypto/skcipher.h
+++ b/include/crypto/skcipher.h
@@ -145,6 +145,7 @@ struct skcipher_alg_common SKCIPHER_ALG_COMMON;
* considerably more efficient if it can operate on multiple chunks
* in parallel. Should be a multiple of chunksize.
* @co: see struct skcipher_alg_common
+ * @SKCIPHER_ALG_COMMON: see struct skcipher_alg_common
*
* All fields except @ivsize are mandatory and must be filled.
*/
diff --git a/include/crypto/sm3.h b/include/crypto/sm3.h
index c8d02c86c298..371e8a661705 100644
--- a/include/crypto/sm3.h
+++ b/include/crypto/sm3.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Common values for SM3 algorithm
+ * SM3 hash algorithm
*
* Copyright (C) 2017 ARM Limited or its affiliates.
* Copyright (C) 2017 Gilad Ben-Yossef <gilad@benyossef.com>
@@ -14,10 +14,6 @@
#define SM3_DIGEST_SIZE 32
#define SM3_BLOCK_SIZE 64
-#define SM3_STATE_SIZE 40
-
-#define SM3_T1 0x79CC4519
-#define SM3_T2 0x7A879D8A
#define SM3_IVA 0x7380166f
#define SM3_IVB 0x4914b2b9
@@ -28,37 +24,64 @@
#define SM3_IVG 0xe38dee4d
#define SM3_IVH 0xb0fb0e4e
-extern const u8 sm3_zero_message_hash[SM3_DIGEST_SIZE];
+/* State for the SM3 compression function */
+struct sm3_block_state {
+ u32 h[SM3_DIGEST_SIZE / 4];
+};
-struct sm3_state {
- u32 state[SM3_DIGEST_SIZE / 4];
- u64 count;
- u8 buffer[SM3_BLOCK_SIZE];
+/**
+ * struct sm3_ctx - Context for hashing a message with SM3
+ * @state: the compression function state
+ * @bytecount: number of bytes processed so far
+ * @buf: partial block buffer; bytecount % SM3_BLOCK_SIZE bytes are valid
+ */
+struct sm3_ctx {
+ struct sm3_block_state state;
+ u64 bytecount;
+ u8 buf[SM3_BLOCK_SIZE] __aligned(__alignof__(__be64));
};
-/*
- * Stand-alone implementation of the SM3 algorithm. It is designed to
- * have as little dependencies as possible so it can be used in the
- * kexec_file purgatory. In other cases you should generally use the
- * hash APIs from include/crypto/hash.h. Especially when hashing large
- * amounts of data as those APIs may be hw-accelerated.
+/**
+ * sm3_init() - Initialize an SM3 context for a new message
+ * @ctx: the context to initialize
+ *
+ * If you don't need incremental computation, consider sm3() instead.
+ *
+ * Context: Any context.
+ */
+void sm3_init(struct sm3_ctx *ctx);
+
+/**
+ * sm3_update() - Update an SM3 context with message data
+ * @ctx: the context to update; must have been initialized
+ * @data: the message data
+ * @len: the data length in bytes
+ *
+ * This can be called any number of times.
*
- * For details see lib/crypto/sm3.c
+ * Context: Any context.
*/
+void sm3_update(struct sm3_ctx *ctx, const u8 *data, size_t len);
-static inline void sm3_init(struct sm3_state *sctx)
-{
- sctx->state[0] = SM3_IVA;
- sctx->state[1] = SM3_IVB;
- sctx->state[2] = SM3_IVC;
- sctx->state[3] = SM3_IVD;
- sctx->state[4] = SM3_IVE;
- sctx->state[5] = SM3_IVF;
- sctx->state[6] = SM3_IVG;
- sctx->state[7] = SM3_IVH;
- sctx->count = 0;
-}
+/**
+ * sm3_final() - Finish computing an SM3 message digest
+ * @ctx: the context to finalize; must have been initialized
+ * @out: (output) the resulting SM3 message digest
+ *
+ * After finishing, this zeroizes @ctx. So the caller does not need to do it.
+ *
+ * Context: Any context.
+ */
+void sm3_final(struct sm3_ctx *ctx, u8 out[at_least SM3_DIGEST_SIZE]);
-void sm3_block_generic(struct sm3_state *sctx, u8 const *data, int blocks);
+/**
+ * sm3() - Compute SM3 message digest in one shot
+ * @data: the message data
+ * @len: the data length in bytes
+ * @out: (output) the resulting SM3 message digest
+ *
+ * Context: Any context.
+ */
+void sm3(const u8 *data, size_t len, u8 out[at_least SM3_DIGEST_SIZE]);
-#endif
+#endif /* _CRYPTO_SM3_H */
diff --git a/include/crypto/sm3_base.h b/include/crypto/sm3_base.h
deleted file mode 100644
index 7c53570bc05e..000000000000
--- a/include/crypto/sm3_base.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * sm3_base.h - core logic for SM3 implementations
- *
- * Copyright (C) 2017 ARM Limited or its affiliates.
- * Written by Gilad Ben-Yossef <gilad@benyossef.com>
- */
-
-#ifndef _CRYPTO_SM3_BASE_H
-#define _CRYPTO_SM3_BASE_H
-
-#include <crypto/internal/hash.h>
-#include <crypto/sm3.h>
-#include <linux/math.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/unaligned.h>
-
-typedef void (sm3_block_fn)(struct sm3_state *sst, u8 const *src, int blocks);
-
-static inline int sm3_base_init(struct shash_desc *desc)
-{
- sm3_init(shash_desc_ctx(desc));
- return 0;
-}
-
-static inline int sm3_base_do_update_blocks(struct shash_desc *desc,
- const u8 *data, unsigned int len,
- sm3_block_fn *block_fn)
-{
- unsigned int remain = len - round_down(len, SM3_BLOCK_SIZE);
- struct sm3_state *sctx = shash_desc_ctx(desc);
-
- sctx->count += len - remain;
- block_fn(sctx, data, len / SM3_BLOCK_SIZE);
- return remain;
-}
-
-static inline int sm3_base_do_finup(struct shash_desc *desc,
- const u8 *src, unsigned int len,
- sm3_block_fn *block_fn)
-{
- unsigned int bit_offset = SM3_BLOCK_SIZE / 8 - 1;
- struct sm3_state *sctx = shash_desc_ctx(desc);
- union {
- __be64 b64[SM3_BLOCK_SIZE / 4];
- u8 u8[SM3_BLOCK_SIZE * 2];
- } block = {};
-
- if (len >= SM3_BLOCK_SIZE) {
- int remain;
-
- remain = sm3_base_do_update_blocks(desc, src, len, block_fn);
- src += len - remain;
- len = remain;
- }
-
- if (len >= bit_offset * 8)
- bit_offset += SM3_BLOCK_SIZE / 8;
- memcpy(&block, src, len);
- block.u8[len] = 0x80;
- sctx->count += len;
- block.b64[bit_offset] = cpu_to_be64(sctx->count << 3);
- block_fn(sctx, block.u8, (bit_offset + 1) * 8 / SM3_BLOCK_SIZE);
- memzero_explicit(&block, sizeof(block));
-
- return 0;
-}
-
-static inline int sm3_base_finish(struct shash_desc *desc, u8 *out)
-{
- struct sm3_state *sctx = shash_desc_ctx(desc);
- __be32 *digest = (__be32 *)out;
- int i;
-
- for (i = 0; i < SM3_DIGEST_SIZE / sizeof(__be32); i++)
- put_unaligned_be32(sctx->state[i], digest++);
- return 0;
-}
-
-#endif /* _CRYPTO_SM3_BASE_H */