]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - include/crypto/chacha.h
Merge tag 'linux-watchdog-5.5-rc1' of git://www.linux-watchdog.org/linux-watchdog
[linux.git] / include / crypto / chacha.h
index d1e723c6a37dd9e3faac1452e1e28d9cca2eef3b..2676f4fbd4c16cbc3d890b1e7415b6435f1a55cc 100644 (file)
@@ -15,9 +15,8 @@
 #ifndef _CRYPTO_CHACHA_H
 #define _CRYPTO_CHACHA_H
 
-#include <crypto/skcipher.h>
+#include <asm/unaligned.h>
 #include <linux/types.h>
-#include <linux/crypto.h>
 
 /* 32-bit stream position, then 96-bit nonce (RFC7539 convention) */
 #define CHACHA_IV_SIZE         16
 #define CHACHA_BLOCK_SIZE      64
 #define CHACHAPOLY_IV_SIZE     12
 
+#ifdef CONFIG_X86_64
+#define CHACHA_STATE_WORDS     ((CHACHA_BLOCK_SIZE + 12) / sizeof(u32))
+#else
+#define CHACHA_STATE_WORDS     (CHACHA_BLOCK_SIZE / sizeof(u32))
+#endif
+
 /* 192-bit nonce, then 64-bit stream position */
 #define XCHACHA_IV_SIZE                32
 
-struct chacha_ctx {
-       u32 key[8];
-       int nrounds;
-};
-
-void chacha_block(u32 *state, u8 *stream, int nrounds);
+void chacha_block_generic(u32 *state, u8 *stream, int nrounds);
 static inline void chacha20_block(u32 *state, u8 *stream)
 {
-       chacha_block(state, stream, 20);
+       chacha_block_generic(state, stream, 20);
+}
+
+void hchacha_block_arch(const u32 *state, u32 *out, int nrounds);
+void hchacha_block_generic(const u32 *state, u32 *out, int nrounds);
+
+static inline void hchacha_block(const u32 *state, u32 *out, int nrounds)
+{
+       if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA))
+               hchacha_block_arch(state, out, nrounds);
+       else
+               hchacha_block_generic(state, out, nrounds);
+}
+
+void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv);
+static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv)
+{
+       state[0]  = 0x61707865; /* "expa" */
+       state[1]  = 0x3320646e; /* "nd 3" */
+       state[2]  = 0x79622d32; /* "2-by" */
+       state[3]  = 0x6b206574; /* "te k" */
+       state[4]  = key[0];
+       state[5]  = key[1];
+       state[6]  = key[2];
+       state[7]  = key[3];
+       state[8]  = key[4];
+       state[9]  = key[5];
+       state[10] = key[6];
+       state[11] = key[7];
+       state[12] = get_unaligned_le32(iv +  0);
+       state[13] = get_unaligned_le32(iv +  4);
+       state[14] = get_unaligned_le32(iv +  8);
+       state[15] = get_unaligned_le32(iv + 12);
+}
+
+static inline void chacha_init(u32 *state, const u32 *key, const u8 *iv)
+{
+       if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA))
+               chacha_init_arch(state, key, iv);
+       else
+               chacha_init_generic(state, key, iv);
 }
-void hchacha_block(const u32 *in, u32 *out, int nrounds);
 
-void crypto_chacha_init(u32 *state, const struct chacha_ctx *ctx, const u8 *iv);
+void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src,
+                      unsigned int bytes, int nrounds);
+void chacha_crypt_generic(u32 *state, u8 *dst, const u8 *src,
+                         unsigned int bytes, int nrounds);
 
-int crypto_chacha20_setkey(struct crypto_skcipher *tfm, const u8 *key,
-                          unsigned int keysize);
-int crypto_chacha12_setkey(struct crypto_skcipher *tfm, const u8 *key,
-                          unsigned int keysize);
+static inline void chacha_crypt(u32 *state, u8 *dst, const u8 *src,
+                               unsigned int bytes, int nrounds)
+{
+       if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA))
+               chacha_crypt_arch(state, dst, src, bytes, nrounds);
+       else
+               chacha_crypt_generic(state, dst, src, bytes, nrounds);
+}
 
-int crypto_chacha_crypt(struct skcipher_request *req);
-int crypto_xchacha_crypt(struct skcipher_request *req);
+static inline void chacha20_crypt(u32 *state, u8 *dst, const u8 *src,
+                                 unsigned int bytes)
+{
+       chacha_crypt(state, dst, src, bytes, 20);
+}
 
 #endif /* _CRYPTO_CHACHA_H */