summaryrefslogtreecommitdiff
path: root/include/crypto
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2018-11-16 17:26:20 -0800
committerHerbert Xu <herbert@gondor.apana.org.au>2018-11-20 14:26:55 +0800
commitde61d7ae5d3789dcba3749a418f76613fbee8414 (patch)
treed447d7f0f0e97c070b74dfe2ccfd4e8e2090a08c /include/crypto
parent5e04542a0e0763294e9fced73a149c38c4e0cee5 (diff)
downloadlwn-de61d7ae5d3789dcba3749a418f76613fbee8414.tar.gz
lwn-de61d7ae5d3789dcba3749a418f76613fbee8414.zip
crypto: chacha20-generic - add XChaCha20 support
Add support for the XChaCha20 stream cipher. XChaCha20 is the application of the XSalsa20 construction (https://cr.yp.to/snuffle/xsalsa-20081128.pdf) to ChaCha20 rather than to Salsa20. XChaCha20 extends ChaCha20's nonce length from 64 bits (or 96 bits, depending on convention) to 192 bits, while provably retaining ChaCha20's security. XChaCha20 uses the ChaCha20 permutation to map the key and first 128 nonce bits to a 256-bit subkey. Then, it does the ChaCha20 stream cipher with the subkey and remaining 64 bits of nonce. We need XChaCha support in order to add support for the Adiantum encryption mode. Note that to meet our performance requirements, we actually plan to primarily use the variant XChaCha12. But we believe it's wise to first add XChaCha20 as a baseline with a higher security margin, in case there are any situations where it can be used. Supporting both variants is straightforward. Since XChaCha20's subkey differs for each request, XChaCha20 can't be a template that wraps ChaCha20; that would require re-keying the underlying ChaCha20 for every request, which wouldn't be thread-safe. Instead, we make XChaCha20 its own top-level algorithm which calls the ChaCha20 streaming implementation internally. Similar to the existing ChaCha20 implementation, we define the IV to be the nonce and stream position concatenated together. This allows users to seek to any position in the stream. I considered splitting the code into separate chacha20-common, chacha20, and xchacha20 modules, so that chacha20 and xchacha20 could be enabled/disabled independently. However, since nearly all the code is shared anyway, I ultimately decided there would have been little benefit to the added complexity of separate modules. Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Acked-by: Martin Willi <martin@strongswan.org> Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'include/crypto')
-rw-r--r--include/crypto/chacha20.h14
1 files changed, 13 insertions, 1 deletions
diff --git a/include/crypto/chacha20.h b/include/crypto/chacha20.h
index 56073814eef0..c24b4ac03b85 100644
--- a/include/crypto/chacha20.h
+++ b/include/crypto/chacha20.h
@@ -1,6 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Common values for the ChaCha20 algorithm
+ * Common values and helper functions for the ChaCha20 and XChaCha20 algorithms.
+ *
+ * XChaCha20 extends ChaCha20's nonce to 192 bits, while provably retaining
+ * ChaCha20's security. Here they share the same key size, tfm context, and
+ * setkey function; only their IV size and encrypt/decrypt function differ.
*/
#ifndef _CRYPTO_CHACHA20_H
@@ -10,11 +14,16 @@
#include <linux/types.h>
#include <linux/crypto.h>
+/* 32-bit stream position, then 96-bit nonce (RFC7539 convention) */
#define CHACHA20_IV_SIZE 16
+
#define CHACHA20_KEY_SIZE 32
#define CHACHA20_BLOCK_SIZE 64
#define CHACHAPOLY_IV_SIZE 12
+/* 192-bit nonce, then 64-bit stream position */
+#define XCHACHA20_IV_SIZE 32
+
struct chacha20_ctx {
u32 key[8];
};
@@ -23,8 +32,11 @@ void chacha20_block(u32 *state, u8 *stream);
void hchacha20_block(const u32 *in, u32 *out);
void crypto_chacha20_init(u32 *state, struct chacha20_ctx *ctx, u8 *iv);
+
int crypto_chacha20_setkey(struct crypto_skcipher *tfm, const u8 *key,
unsigned int keysize);
+
int crypto_chacha20_crypt(struct skcipher_request *req);
+int crypto_xchacha20_crypt(struct skcipher_request *req);
#endif