forked from Minki/linux
c80ae7ca37
This replaces the SHA-512 NEON module with the faster and more versatile implementation from the OpenSSL project. It consists of both a NEON and a generic ASM version of the core SHA-512 transform, where the NEON version reverts to the ASM version when invoked in non-process context. This patch is based on the OpenSSL upstream version b1a5d1c65208 of sha512-armv4.pl, which can be found here: https://git.openssl.org/gitweb/?p=openssl.git;h=b1a5d1c65208 Performance relative to the generic implementation (measured using tcrypt.ko mode=306 sec=1 running on a Cortex-A57 under KVM): input size block size asm neon old neon 16 16 1.39 2.54 2.21 64 16 1.32 2.33 2.09 64 64 1.38 2.53 2.19 256 16 1.31 2.28 2.06 256 64 1.38 2.54 2.25 256 256 1.40 2.77 2.39 1024 16 1.29 2.22 2.01 1024 256 1.40 2.82 2.45 1024 1024 1.41 2.93 2.53 2048 16 1.33 2.21 2.00 2048 256 1.40 2.84 2.46 2048 1024 1.41 2.96 2.55 2048 2048 1.41 2.98 2.56 4096 16 1.34 2.20 1.99 4096 256 1.40 2.84 2.46 4096 1024 1.41 2.97 2.56 4096 4096 1.41 3.01 2.58 8192 16 1.34 2.19 1.99 8192 256 1.40 2.85 2.47 8192 1024 1.41 2.98 2.56 8192 4096 1.41 2.71 2.59 8192 8192 1.51 3.51 2.69 Acked-by: Jussi Kivilinna <jussi.kivilinna@iki.fi> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
122 lines
3.1 KiB
C
122 lines
3.1 KiB
C
/*
|
|
* sha512-glue.c - accelerated SHA-384/512 for ARM
|
|
*
|
|
* Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <crypto/internal/hash.h>
|
|
#include <crypto/sha.h>
|
|
#include <crypto/sha512_base.h>
|
|
#include <linux/crypto.h>
|
|
#include <linux/module.h>
|
|
|
|
#include <asm/hwcap.h>
|
|
#include <asm/neon.h>
|
|
|
|
#include "sha512.h"
|
|
|
|
MODULE_DESCRIPTION("Accelerated SHA-384/SHA-512 secure hash for ARM");
|
|
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
|
|
MODULE_LICENSE("GPL v2");
|
|
|
|
MODULE_ALIAS_CRYPTO("sha384");
|
|
MODULE_ALIAS_CRYPTO("sha512");
|
|
MODULE_ALIAS_CRYPTO("sha384-arm");
|
|
MODULE_ALIAS_CRYPTO("sha512-arm");
|
|
|
|
asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks);
|
|
|
|
int sha512_arm_update(struct shash_desc *desc, const u8 *data,
|
|
unsigned int len)
|
|
{
|
|
return sha512_base_do_update(desc, data, len,
|
|
(sha512_block_fn *)sha512_block_data_order);
|
|
}
|
|
|
|
int sha512_arm_final(struct shash_desc *desc, u8 *out)
|
|
{
|
|
sha512_base_do_finalize(desc,
|
|
(sha512_block_fn *)sha512_block_data_order);
|
|
return sha512_base_finish(desc, out);
|
|
}
|
|
|
|
int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
|
|
unsigned int len, u8 *out)
|
|
{
|
|
sha512_base_do_update(desc, data, len,
|
|
(sha512_block_fn *)sha512_block_data_order);
|
|
return sha512_arm_final(desc, out);
|
|
}
|
|
|
|
static struct shash_alg sha512_arm_algs[] = { {
|
|
.init = sha384_base_init,
|
|
.update = sha512_arm_update,
|
|
.final = sha512_arm_final,
|
|
.finup = sha512_arm_finup,
|
|
.descsize = sizeof(struct sha512_state),
|
|
.digestsize = SHA384_DIGEST_SIZE,
|
|
.base = {
|
|
.cra_name = "sha384",
|
|
.cra_driver_name = "sha384-arm",
|
|
.cra_priority = 250,
|
|
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
|
.cra_blocksize = SHA512_BLOCK_SIZE,
|
|
.cra_module = THIS_MODULE,
|
|
}
|
|
}, {
|
|
.init = sha512_base_init,
|
|
.update = sha512_arm_update,
|
|
.final = sha512_arm_final,
|
|
.finup = sha512_arm_finup,
|
|
.descsize = sizeof(struct sha512_state),
|
|
.digestsize = SHA512_DIGEST_SIZE,
|
|
.base = {
|
|
.cra_name = "sha512",
|
|
.cra_driver_name = "sha512-arm",
|
|
.cra_priority = 250,
|
|
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
|
.cra_blocksize = SHA512_BLOCK_SIZE,
|
|
.cra_module = THIS_MODULE,
|
|
}
|
|
} };
|
|
|
|
static int __init sha512_arm_mod_init(void)
|
|
{
|
|
int err;
|
|
|
|
err = crypto_register_shashes(sha512_arm_algs,
|
|
ARRAY_SIZE(sha512_arm_algs));
|
|
if (err)
|
|
return err;
|
|
|
|
if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon()) {
|
|
err = crypto_register_shashes(sha512_neon_algs,
|
|
ARRAY_SIZE(sha512_neon_algs));
|
|
if (err)
|
|
goto err_unregister;
|
|
}
|
|
return 0;
|
|
|
|
err_unregister:
|
|
crypto_unregister_shashes(sha512_arm_algs,
|
|
ARRAY_SIZE(sha512_arm_algs));
|
|
|
|
return err;
|
|
}
|
|
|
|
static void __exit sha512_arm_mod_fini(void)
|
|
{
|
|
crypto_unregister_shashes(sha512_arm_algs,
|
|
ARRAY_SIZE(sha512_arm_algs));
|
|
if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon())
|
|
crypto_unregister_shashes(sha512_neon_algs,
|
|
ARRAY_SIZE(sha512_neon_algs));
|
|
}
|
|
|
|
module_init(sha512_arm_mod_init);
|
|
module_exit(sha512_arm_mod_fini);
|