1/*
2 * sha1-ce-core.S - SHA-1 secure hash using ARMv8 Crypto Extensions
3 *
4 * Copyright (C) 2015 Linaro Ltd.
5 * Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14
15	.text
16	.fpu		crypto-neon-fp-armv8
17
18	k0		.req	q0
19	k1		.req	q1
20	k2		.req	q2
21	k3		.req	q3
22
23	ta0		.req	q4
24	ta1		.req	q5
25	tb0		.req	q5
26	tb1		.req	q4
27
28	dga		.req	q6
29	dgb		.req	q7
30	dgbs		.req	s28
31
32	dg0		.req	q12
33	dg1a0		.req	q13
34	dg1a1		.req	q14
35	dg1b0		.req	q14
36	dg1b1		.req	q13
37
38	.macro		add_only, op, ev, rc, s0, dg1
39	.ifnb		\s0
40	vadd.u32	tb\ev, q\s0, \rc
41	.endif
42	sha1h.32	dg1b\ev, dg0
43	.ifb		\dg1
44	sha1\op\().32	dg0, dg1a\ev, ta\ev
45	.else
46	sha1\op\().32	dg0, \dg1, ta\ev
47	.endif
48	.endm
49
50	.macro		add_update, op, ev, rc, s0, s1, s2, s3, dg1
51	sha1su0.32	q\s0, q\s1, q\s2
52	add_only	\op, \ev, \rc, \s1, \dg1
53	sha1su1.32	q\s0, q\s3
54	.endm
55
56	.align		6
57.Lsha1_rcon:
58	.word		0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999
59	.word		0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1
60	.word		0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc
61	.word		0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6
62
63	/*
64	 * void sha1_ce_transform(struct sha1_state *sst, u8 const *src,
65	 *			  int blocks);
66	 */
67ENTRY(sha1_ce_transform)
68	/* load round constants */
69	adr		ip, .Lsha1_rcon
70	vld1.32		{k0-k1}, [ip, :128]!
71	vld1.32		{k2-k3}, [ip, :128]
72
73	/* load state */
74	vld1.32		{dga}, [r0]
75	vldr		dgbs, [r0, #16]
76
77	/* load input */
780:	vld1.32		{q8-q9}, [r1]!
79	vld1.32		{q10-q11}, [r1]!
80	subs		r2, r2, #1
81
82#ifndef CONFIG_CPU_BIG_ENDIAN
83	vrev32.8	q8, q8
84	vrev32.8	q9, q9
85	vrev32.8	q10, q10
86	vrev32.8	q11, q11
87#endif
88
89	vadd.u32	ta0, q8, k0
90	vmov		dg0, dga
91
92	add_update	c, 0, k0,  8,  9, 10, 11, dgb
93	add_update	c, 1, k0,  9, 10, 11,  8
94	add_update	c, 0, k0, 10, 11,  8,  9
95	add_update	c, 1, k0, 11,  8,  9, 10
96	add_update	c, 0, k1,  8,  9, 10, 11
97
98	add_update	p, 1, k1,  9, 10, 11,  8
99	add_update	p, 0, k1, 10, 11,  8,  9
100	add_update	p, 1, k1, 11,  8,  9, 10
101	add_update	p, 0, k1,  8,  9, 10, 11
102	add_update	p, 1, k2,  9, 10, 11,  8
103
104	add_update	m, 0, k2, 10, 11,  8,  9
105	add_update	m, 1, k2, 11,  8,  9, 10
106	add_update	m, 0, k2,  8,  9, 10, 11
107	add_update	m, 1, k2,  9, 10, 11,  8
108	add_update	m, 0, k3, 10, 11,  8,  9
109
110	add_update	p, 1, k3, 11,  8,  9, 10
111	add_only	p, 0, k3,  9
112	add_only	p, 1, k3, 10
113	add_only	p, 0, k3, 11
114	add_only	p, 1
115
116	/* update state */
117	vadd.u32	dga, dga, dg0
118	vadd.u32	dgb, dgb, dg1a0
119	bne		0b
120
121	/* store new state */
122	vst1.32		{dga}, [r0]
123	vstr		dgbs, [r0, #16]
124	bx		lr
125ENDPROC(sha1_ce_transform)
126