194742Sobrien// SPDX-License-Identifier: GPL-2.0-or-later
294742Sobrien/*
3146890Speter * Glue code for the SHA1 Secure Hash Algorithm assembler implementation using
4146890Speter * ARM NEON instructions.
5146890Speter *
6146890Speter * Copyright �� 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
7146890Speter *
8146890Speter * This file is based on sha1_generic.c and sha1_ssse3_glue.c:
9146890Speter *  Copyright (c) Alan Smithee.
10146890Speter *  Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
11146890Speter *  Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
12146890Speter *  Copyright (c) Mathias Krause <minipli@googlemail.com>
13146890Speter *  Copyright (c) Chandramouli Narayanan <mouli@linux.intel.com>
14146890Speter */
15146890Speter
16146890Speter#include <crypto/internal/hash.h>
17146890Speter#include <crypto/internal/simd.h>
18146890Speter#include <linux/init.h>
19146890Speter#include <linux/module.h>
20146890Speter#include <linux/mm.h>
2194742Sobrien#include <linux/types.h>
2295253Sru#include <crypto/sha1.h>
2394742Sobrien#include <crypto/sha1_base.h>
2496991Srwatson#include <asm/neon.h>
2596991Srwatson#include <asm/simd.h>
2696991Srwatson
27102773Srwatson#include "sha1.h"
28102773Srwatson
2994854Ssosasmlinkage void sha1_transform_neon(struct sha1_state *state_h,
3094917Simp				    const u8 *data, int rounds);
31126445Sobrien
3294917Simpstatic int sha1_neon_update(struct shash_desc *desc, const u8 *data,
3394917Simp			  unsigned int len)
34146933Simp{
35146918Smarkm	struct sha1_state *sctx = shash_desc_ctx(desc);
36146918Smarkm
37125244Snectar	if (!crypto_simd_usable() ||
38125244Snectar	    (sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE)
3994847Sjhb		return sha1_update_arm(desc, data, len);
4094847Sjhb
4194847Sjhb	kernel_neon_begin();
42126337Svkashyap	sha1_base_do_update(desc, data, len, sha1_transform_neon);
43128023Svkashyap	kernel_neon_end();
4494855Sscottl
45126054Sscottl	return 0;
46126054Sscottl}
47126054Sscottl
48126054Sscottlstatic int sha1_neon_finup(struct shash_desc *desc, const u8 *data,
49126054Sscottl			   unsigned int len, u8 *out)
50126054Sscottl{
5194915Sken	if (!crypto_simd_usable())
5299607Smjacob		return sha1_finup_arm(desc, data, len, out);
5394915Sken
5494915Sken	kernel_neon_begin();
5594915Sken	if (len)
5694915Sken		sha1_base_do_update(desc, data, len, sha1_transform_neon);
5794915Sken	sha1_base_do_finalize(desc, sha1_transform_neon);
5894915Sken	kernel_neon_end();
5994915Sken
6094915Sken	return sha1_base_finish(desc, out);
6199607Smjacob}
62106734Smjacob
63128435Stackermanstatic int sha1_neon_final(struct shash_desc *desc, u8 *out)
6497611Sbillf{
6594918Sgshapiro	return sha1_neon_finup(desc, NULL, 0, out);
6694918Sgshapiro}
6794918Sgshapiro
6894918Sgshapirostatic struct shash_alg alg = {
6994918Sgshapiro	.digestsize	=	SHA1_DIGEST_SIZE,
70118316Smbr	.init		=	sha1_base_init,
7194955Smurray	.update		=	sha1_neon_update,
72106187Sdes	.final		=	sha1_neon_final,
73106187Sdes	.finup		=	sha1_neon_finup,
7495455Sdes	.descsize	=	sizeof(struct sha1_state),
7598750Sdes	.base		=	{
7699606Sdes		.cra_name		= "sha1",
7799606Sdes		.cra_driver_name	= "sha1-neon",
7899606Sdes		.cra_priority		= 250,
7996268Sgad		.cra_blocksize		= SHA1_BLOCK_SIZE,
8096268Sgad		.cra_module		= THIS_MODULE,
81116233Sgad	}
82139390Sgad};
83139390Sgad
84139390Sgadstatic int __init sha1_neon_mod_init(void)
8596332Speter{
8696332Speter	if (!cpu_has_neon())
8796332Speter		return -ENODEV;
8896332Speter
8996332Speter	return crypto_register_shash(&alg);
90100314Sru}
91146921Sru
92146921Srustatic void __exit sha1_neon_mod_fini(void)
9397611Sbillf{
9498333Sanholt	crypto_unregister_shash(&alg);
95111061Sjmallett}
9699732Sjoerg
9799732Sjoergmodule_init(sha1_neon_mod_init);
98113692Snectarmodule_exit(sha1_neon_mod_fini);
99113692Snectar
100115825SfanfMODULE_LICENSE("GPL");
101126445SobrienMODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, NEON accelerated");
102117645SdwmaloneMODULE_ALIAS_CRYPTO("sha1");
103118204Sbp