Skip to content

Commit

Permalink
crypto: s390 - add crypto library interface for ChaCha20
Browse files Browse the repository at this point in the history
Implement a crypto library interface for the s390-native ChaCha20 cipher
algorithm. This allows us to stop to select CRYPTO_CHACHA20 and instead
select CRYPTO_ARCH_HAVE_LIB_CHACHA. This allows BIG_KEYS=y not to build
a whole ChaCha20 crypto infrastructure as a built-in, but build a smaller
CRYPTO_LIB_CHACHA instead.

Make CRYPTO_CHACHA_S390 config entry to look like similar ones on other
architectures. Remove CRYPTO_ALGAPI select as anyway it is selected by
CRYPTO_SKCIPHER.

Add a new test module and a test script for ChaCha20 cipher and its
interfaces. Here are test results on an idle z15 machine:

Data | Generic crypto TFM |  s390 crypto TFM |    s390 lib
size |      enc      dec  |     enc     dec  |     enc     dec
-----+--------------------+------------------+----------------
512b |   1545ns   1295ns  |   604ns   446ns  |   430ns  407ns
4k   |   9536ns   9463ns  |  2329ns  2174ns  |  2170ns  2154ns
64k  |  149.6us  149.3us  |  34.4us  34.5us  |  33.9us  33.1us
6M   |  23.61ms  23.11ms  |  4223us  4160us  |  3951us  4008us
60M  |  143.9ms  143.9ms  |  33.5ms  33.2ms  |  32.2ms  32.1ms

Signed-off-by: Vladis Dronov <[email protected]>
Reviewed-by: Harald Freudenberger <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
nefigtut authored and herbertx committed May 13, 2022
1 parent 6ae7a8b commit 349d03f
Show file tree
Hide file tree
Showing 5 changed files with 452 additions and 4 deletions.
34 changes: 32 additions & 2 deletions arch/s390/crypto/chacha-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,34 @@ static int chacha20_s390(struct skcipher_request *req)
return rc;
}

void hchacha_block_arch(const u32 *state, u32 *stream, int nrounds)
{
/* TODO: implement hchacha_block_arch() in assembly */
hchacha_block_generic(state, stream, nrounds);
}
EXPORT_SYMBOL(hchacha_block_arch);

void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv)
{
chacha_init_generic(state, key, iv);
}
EXPORT_SYMBOL(chacha_init_arch);

void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src,
unsigned int bytes, int nrounds)
{
/* s390 chacha20 implementation has 20 rounds hard-coded,
* it cannot handle a block of data or less, but otherwise
* it can handle data of arbitrary size
*/
if (bytes <= CHACHA_BLOCK_SIZE || nrounds != 20)
chacha_crypt_generic(state, dst, src, bytes, nrounds);
else
chacha20_crypt_s390(state, dst, src, bytes,
&state[4], &state[12]);
}
EXPORT_SYMBOL(chacha_crypt_arch);

static struct skcipher_alg chacha_algs[] = {
{
.base.cra_name = "chacha20",
Expand All @@ -83,12 +111,14 @@ static struct skcipher_alg chacha_algs[] = {

static int __init chacha_mod_init(void)
{
return crypto_register_skciphers(chacha_algs, ARRAY_SIZE(chacha_algs));
return IS_REACHABLE(CONFIG_CRYPTO_SKCIPHER) ?
crypto_register_skciphers(chacha_algs, ARRAY_SIZE(chacha_algs)) : 0;
}

static void __exit chacha_mod_fini(void)
{
crypto_unregister_skciphers(chacha_algs, ARRAY_SIZE(chacha_algs));
if (IS_REACHABLE(CONFIG_CRYPTO_SKCIPHER))
crypto_unregister_skciphers(chacha_algs, ARRAY_SIZE(chacha_algs));
}

module_cpu_feature_match(VXRS, chacha_mod_init);
Expand Down
4 changes: 2 additions & 2 deletions drivers/crypto/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,9 @@ config CRYPTO_AES_S390
config CRYPTO_CHACHA_S390
tristate "ChaCha20 stream cipher"
depends on S390
select CRYPTO_ALGAPI
select CRYPTO_SKCIPHER
select CRYPTO_CHACHA20
select CRYPTO_LIB_CHACHA_GENERIC
select CRYPTO_ARCH_HAVE_LIB_CHACHA
help
This is the s390 SIMD implementation of the ChaCha20 stream
cipher (RFC 7539).
Expand Down
12 changes: 12 additions & 0 deletions tools/testing/crypto/chacha20-s390/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2022 Red Hat, Inc.
# Author: Vladis Dronov <[email protected]>

obj-m += test_cipher.o
test_cipher-y := test-cipher.o

all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
34 changes: 34 additions & 0 deletions tools/testing/crypto/chacha20-s390/run-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2022 Red Hat, Inc.
# Author: Vladis Dronov <[email protected]>
#
# This script runs (via instmod) test-cipher.ko module which invokes
# generic and s390-native ChaCha20 encryprion algorithms with different
# size of data. Check 'dmesg' for results.
#
# The insmod error is expected:
# insmod: ERROR: could not insert module test_cipher.ko: Operation not permitted

lsmod | grep chacha | cut -f1 -d' ' | xargs rmmod
modprobe chacha_generic
modprobe chacha_s390

# run encryption for different data size, including whole block(s) +/- 1
insmod test_cipher.ko size=63
insmod test_cipher.ko size=64
insmod test_cipher.ko size=65
insmod test_cipher.ko size=127
insmod test_cipher.ko size=128
insmod test_cipher.ko size=129
insmod test_cipher.ko size=511
insmod test_cipher.ko size=512
insmod test_cipher.ko size=513
insmod test_cipher.ko size=4096
insmod test_cipher.ko size=65611
insmod test_cipher.ko size=6291456
insmod test_cipher.ko size=62914560

# print test logs
dmesg | tail -170
Loading

0 comments on commit 349d03f

Please sign in to comment.