xref: /openbsd-src/sys/arch/octeon/dev/octcrypto_asm.S (revision 7b6d8aac88f53f0a3699c76d17dc67660a87fb45)
1*7b6d8aacSvisa/*	$OpenBSD: octcrypto_asm.S,v 1.2 2019/01/03 17:06:22 visa Exp $	*/
2d4086a48Svisa
3d4086a48Svisa/*
4d4086a48Svisa * Copyright (c) 2018 Visa Hankala
5d4086a48Svisa *
6d4086a48Svisa * Permission to use, copy, modify, and/or distribute this software for any
7d4086a48Svisa * purpose with or without fee is hereby granted, provided that the above
8d4086a48Svisa * copyright notice and this permission notice appear in all copies.
9d4086a48Svisa *
10d4086a48Svisa * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11d4086a48Svisa * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12d4086a48Svisa * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13d4086a48Svisa * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14d4086a48Svisa * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15d4086a48Svisa * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16d4086a48Svisa * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17d4086a48Svisa */
18d4086a48Svisa
19d4086a48Svisa#include <machine/asm.h>
20d4086a48Svisa
21d4086a48Svisa	.set	noreorder
22d4086a48Svisa	.set	arch=octeon
23d4086a48Svisa
24d4086a48Svisa/*
25d4086a48Svisa * COP2 registers and operation codes
26d4086a48Svisa */
27d4086a48Svisa#define MT_AES_IV		0x0102
28d4086a48Svisa#define MT_AES_KEY		0x0104
29d4086a48Svisa#define MT_AES_ENC0		0x010a
30d4086a48Svisa#define MT_AES_ENC1		0x310b
31d4086a48Svisa#define MT_AES_ENC_CBC0		0x0108
32d4086a48Svisa#define MT_AES_ENC_CBC1		0x3109
33d4086a48Svisa#define MT_AES_DEC_CBC0		0x010c
34d4086a48Svisa#define MT_AES_DEC_CBC1		0x310d
35d4086a48Svisa#define MF_AES_RESINP		0x0100
36d4086a48Svisa#define MT_AES_RESINP		0x0100
37d4086a48Svisa#define MT_HSH_DAT		0x0040
38d4086a48Svisa#define MT_HSH_DATW		0x0240
39d4086a48Svisa#define MT_HSH_IV		0x0048
40d4086a48Svisa#define MF_HSH_IV		0x0048
41d4086a48Svisa#define MT_HSH_IVW		0x0250
42d4086a48Svisa#define MF_HSH_IVW		0x0250
43d4086a48Svisa#define MT_HSH_STARTMD5		0x4047
44d4086a48Svisa#define MT_HSH_STARTSHA		0x4057
45d4086a48Svisa#define MT_HSH_STARTSHA256	0x404f
46d4086a48Svisa#define MT_HSH_STARTSHA512	0x424f
47d4086a48Svisa
48d4086a48Svisa#define MT_GFM_MUL		0x0258
49d4086a48Svisa#define MT_GFM_POLY		0x025e
50d4086a48Svisa#define MF_GFM_RESINP		0x025a
51d4086a48Svisa#define MT_GFM_RESINP		0x025a
52d4086a48Svisa#define MT_GFM_XOR0		0x025c
53d4086a48Svisa#define MT_GFM_XORMUL1		0x425d
54d4086a48Svisa
55d4086a48Svisa#define GF128_POLY		0xe100
56d4086a48Svisa
57d4086a48Svisa/*
58d4086a48Svisa * void octcrypto_aes_set_key(const uint64_t *key, size_t len)
59d4086a48Svisa *
60d4086a48Svisa * Load an AES key to the coprocessor.
61d4086a48Svisa * `len' is in bytes.
62d4086a48Svisa */
63d4086a48SvisaLEAF(octcrypto_aes_set_key, 0)
64d4086a48Svisa	ld	t0, (a0)
65d4086a48Svisa	ld	t1, 8(a0)
66d4086a48Svisa	dmtc2	t0, MT_AES_KEY
67d4086a48Svisa	bltu	a1, 24, 1f
68d4086a48Svisa	 dmtc2	t1, MT_AES_KEY+1	/* 128-bit key */
69d4086a48Svisa	ld	t0, 16(a0)
70d4086a48Svisa	bltu	a1, 32, 1f
71d4086a48Svisa	 dmtc2	t0, MT_AES_KEY+2	/* 192-bit key */
72d4086a48Svisa	ld	t0, 24(a0)
73d4086a48Svisa	dmtc2	t0, MT_AES_KEY+3	/* 256-bit key */
74d4086a48Svisa1:
75d4086a48Svisa	jr	ra
76d4086a48Svisa	 nop
77d4086a48SvisaEND(octcrypto_aes_set_key)
78d4086a48Svisa
79d4086a48Svisa/*
80d4086a48Svisa * void octcrypto_aes_clear(void)
81d4086a48Svisa *
82d4086a48Svisa * Clear AES state.
83d4086a48Svisa */
84d4086a48SvisaLEAF(octcrypto_aes_clear, 0)
85d4086a48Svisa	dmtc2	zero, MT_AES_KEY
86d4086a48Svisa	dmtc2	zero, MT_AES_KEY+1
87d4086a48Svisa	dmtc2	zero, MT_AES_KEY+2
88d4086a48Svisa	dmtc2	zero, MT_AES_KEY+3
89d4086a48Svisa	dmtc2	zero, MT_AES_RESINP
90d4086a48Svisa	jr	ra
91d4086a48Svisa	 dmtc2	zero, MT_AES_RESINP+1
92d4086a48SvisaEND(octcrypto_aes_clear)
93d4086a48Svisa
94d4086a48Svisa/*
95d4086a48Svisa * void octcrypto_aes_enc(uint64_t *buf)
96d4086a48Svisa *
97d4086a48Svisa * AES encrypt a single block.
98d4086a48Svisa */
99d4086a48SvisaLEAF(octcrypto_aes_enc, 0)
100d4086a48Svisa	ld	t0, (a0)
101d4086a48Svisa	ld	t1, 8(a0)
102d4086a48Svisa	dmtc2	t0, MT_AES_ENC0
103d4086a48Svisa	dmtc2	t1, MT_AES_ENC1
104d4086a48Svisa	dmfc2	t0, MF_AES_RESINP
105d4086a48Svisa	dmfc2	t1, MF_AES_RESINP+1
106d4086a48Svisa	sd	t0, (a0)
107d4086a48Svisa	jr	ra
108d4086a48Svisa	 sd	t1, 8(a0)
109d4086a48SvisaEND(octcrypto_aes_enc)
110d4086a48Svisa
111d4086a48Svisa/*
112d4086a48Svisa * void octcrypto_aes_cbc_enc(void *buf, size_t size, const void *iv)
113d4086a48Svisa *
114d4086a48Svisa * AES CBC encrypt a sequence of blocks.
115d4086a48Svisa */
116d4086a48SvisaLEAF(octcrypto_aes_cbc_enc, 0)
117d4086a48Svisa	bltu	a1, 16, 3f
118d4086a48Svisa	 and	t2, a1, 15
119d4086a48Svisa	dsubu	a3, a1, t2
120d4086a48Svisa	daddu	a3, a3, a0		/* Compute buffer end. */
121d4086a48Svisa	and	t2, a0, 7		/* Determine alignment. */
122d4086a48Svisa	ld	t0, (a2)
123d4086a48Svisa	ld	t1, 8(a2)
124d4086a48Svisa	dmtc2	t0, MT_AES_IV
125d4086a48Svisa	bne	t2, zero, 2f
126d4086a48Svisa	 dmtc2	t1, MT_AES_IV+1
127d4086a48Svisa
128d4086a48Svisa	/*
129d4086a48Svisa	 * Aligned buffer
130d4086a48Svisa	 */
131d4086a48Svisa1:
132d4086a48Svisa	ld	t0, (a0)
133d4086a48Svisa	ld	t1, 8(a0)
134d4086a48Svisa	daddu	a0, a0, 16
135d4086a48Svisa	dmtc2	t0, MT_AES_ENC_CBC0
136d4086a48Svisa	dmtc2	t1, MT_AES_ENC_CBC1
137d4086a48Svisa	dmfc2	t0, MF_AES_RESINP
138d4086a48Svisa	dmfc2	t1, MF_AES_RESINP+1
139d4086a48Svisa	sd	t0, -16(a0)
140d4086a48Svisa	bltu	a0, a3, 1b
141d4086a48Svisa	 sd	t1, -8(a0)
142d4086a48Svisa	b	3f
143d4086a48Svisa	 nop
144d4086a48Svisa
145d4086a48Svisa	/*
146d4086a48Svisa	 * Unaligned buffer
147d4086a48Svisa	 */
148d4086a48Svisa2:
149d4086a48Svisa	LDHI	t0, (a0)
150d4086a48Svisa	LDLO	t0, 7(a0)
151d4086a48Svisa	LDHI	t1, 8(a0)
152d4086a48Svisa	LDLO	t1, 15(a0)
153d4086a48Svisa	daddu	a0, a0, 16
154d4086a48Svisa	dmtc2	t0, MT_AES_ENC_CBC0
155d4086a48Svisa	dmtc2	t1, MT_AES_ENC_CBC1
156d4086a48Svisa	dmfc2	t0, MF_AES_RESINP
157d4086a48Svisa	dmfc2	t1, MF_AES_RESINP+1
158d4086a48Svisa	SDHI	t0, -16(a0)
159d4086a48Svisa	SDLO	t0, -9(a0)
160d4086a48Svisa	SDHI	t1, -8(a0)
161d4086a48Svisa	bltu	a0, a3, 2b
162d4086a48Svisa	 SDLO	t1, -1(a0)
163d4086a48Svisa
164d4086a48Svisa3:
165d4086a48Svisa	jr	ra
166d4086a48Svisa	 nop
167d4086a48SvisaEND(octcrypto_aes_cbc_enc)
168d4086a48Svisa
169d4086a48Svisa/*
170d4086a48Svisa * void octcrypto_aes_cbc_dec(void *dst, size_t size, const void *iv)
171d4086a48Svisa *
172d4086a48Svisa * AES CBC decrypt a sequence of blocks.
173d4086a48Svisa */
174d4086a48SvisaLEAF(octcrypto_aes_cbc_dec, 0)
175d4086a48Svisa	bltu	a1, 16, 3f
176d4086a48Svisa	 and	t2, a1, 15
177d4086a48Svisa	dsubu	a3, a1, t2
178d4086a48Svisa	daddu	a3, a3, a0		/* Compute buffer end. */
179d4086a48Svisa	and	t2, a0, 7		/* Determine alignment. */
180d4086a48Svisa	ld	t0, (a2)
181d4086a48Svisa	ld	t1, 8(a2)
182d4086a48Svisa	dmtc2	t0, MT_AES_IV
183d4086a48Svisa	bne	t2, zero, 2f
184d4086a48Svisa	 dmtc2	t1, MT_AES_IV+1
185d4086a48Svisa
186d4086a48Svisa	/*
187d4086a48Svisa	 * Aligned buffer
188d4086a48Svisa	 */
189d4086a48Svisa1:
190d4086a48Svisa	ld	t0, (a0)
191d4086a48Svisa	ld	t1, 8(a0)
192d4086a48Svisa	daddu	a0, a0, 16
193d4086a48Svisa	dmtc2	t0, MT_AES_DEC_CBC0
194d4086a48Svisa	dmtc2	t1, MT_AES_DEC_CBC1
195d4086a48Svisa	dmfc2	t0, MF_AES_RESINP
196d4086a48Svisa	dmfc2	t1, MF_AES_RESINP+1
197d4086a48Svisa	sd	t0, -16(a0)
198d4086a48Svisa	bltu	a0, a3, 1b
199d4086a48Svisa	 sd	t1, -8(a0)
200d4086a48Svisa	b	3f
201d4086a48Svisa	 nop
202d4086a48Svisa
203d4086a48Svisa	/*
204d4086a48Svisa	 * Unaligned buffer
205d4086a48Svisa	 */
206d4086a48Svisa2:
207d4086a48Svisa	LDHI	t0, (a0)
208d4086a48Svisa	LDLO	t0, 7(a0)
209d4086a48Svisa	LDHI	t1, 8(a0)
210d4086a48Svisa	LDLO	t1, 15(a0)
211d4086a48Svisa	daddu	a0, a0, 16
212d4086a48Svisa	dmtc2	t0, MT_AES_DEC_CBC0
213d4086a48Svisa	dmtc2	t1, MT_AES_DEC_CBC1
214d4086a48Svisa	dmfc2	t0, MF_AES_RESINP
215d4086a48Svisa	dmfc2	t1, MF_AES_RESINP+1
216d4086a48Svisa	SDHI	t0, -16(a0)
217d4086a48Svisa	SDLO	t0, -9(a0)
218d4086a48Svisa	SDHI	t1, -8(a0)
219d4086a48Svisa	bltu	a0, a3, 2b
220d4086a48Svisa	 SDLO	t1, -1(a0)
221d4086a48Svisa
222d4086a48Svisa3:
223d4086a48Svisa	jr	ra
224d4086a48Svisa	 nop
225d4086a48SvisaEND(octcrypto_aes_cbc_dec)
226d4086a48Svisa
227d4086a48Svisa/*
228d4086a48Svisa * void octcrypto_aes_ctr_enc(void *buf, size_t size, const void *icb)
229d4086a48Svisa *
230d4086a48Svisa * AES CTR encrypt a sequence of blocks.
231d4086a48Svisa */
232d4086a48SvisaLEAF(octcrypto_aes_ctr_enc, 0)
233d4086a48Svisa	bltu	a1, 16, 3f
234d4086a48Svisa	 and	t2, a1, 15
235d4086a48Svisa	dsubu	a3, a1, t2
236d4086a48Svisa	daddu	a3, a3, a0		/* Compute buffer end. */
237d4086a48Svisa	and	t2, a0, 7		/* Determine alignment. */
238d4086a48Svisa	ld	t0, (a2)
239d4086a48Svisa	bne	t2, zero, 2f
240d4086a48Svisa	 ld	t1, 8(a2)
241d4086a48Svisa
242d4086a48Svisa	/*
243d4086a48Svisa	 * Aligned buffer
244d4086a48Svisa	 */
245d4086a48Svisa1:
246d4086a48Svisa	/*
247d4086a48Svisa	 * Increment the counter.
248d4086a48Svisa	 * Assume big endian byte order and no overflow.
249d4086a48Svisa	 */
250d4086a48Svisa	daddu	t1, 1
251d4086a48Svisa	/* Compute the keystream block. */
252d4086a48Svisa	dmtc2	t0, MT_AES_ENC0
253d4086a48Svisa	dmtc2	t1, MT_AES_ENC1
254d4086a48Svisa	dmfc2	t2, MF_AES_RESINP
255d4086a48Svisa	dmfc2	t3, MF_AES_RESINP+1
256d4086a48Svisa	/* XOR the plaintext and the keystream. */
257d4086a48Svisa	ld	a4, (a0)
258d4086a48Svisa	ld	a5, 8(a0)
259d4086a48Svisa	daddu	a0, a0, 16
260d4086a48Svisa	xor	a4, t2
261d4086a48Svisa	xor	a5, t3
262d4086a48Svisa	sd	a4, -16(a0)
263d4086a48Svisa	bltu	a0, a3, 1b
264d4086a48Svisa	 sd	a5, -8(a0)
265d4086a48Svisa	b	3f
266d4086a48Svisa	 nop
267d4086a48Svisa
268d4086a48Svisa	/*
269d4086a48Svisa	 * Unaligned buffer
270d4086a48Svisa	 */
271d4086a48Svisa2:
272d4086a48Svisa	/*
273d4086a48Svisa	 * Increment the counter.
274d4086a48Svisa	 * Assume big endian byte order and no overflow.
275d4086a48Svisa	 */
276d4086a48Svisa	daddu	t1, 1
277d4086a48Svisa	/* Compute the keystream block. */
278d4086a48Svisa	dmtc2	t0, MT_AES_ENC0
279d4086a48Svisa	dmtc2	t1, MT_AES_ENC1
280d4086a48Svisa	dmfc2	t2, MF_AES_RESINP
281d4086a48Svisa	dmfc2	t3, MF_AES_RESINP+1
282d4086a48Svisa	/* XOR the plaintext and the keystream. */
283d4086a48Svisa	LDHI	a4, (a0)
284d4086a48Svisa	LDLO	a4, 7(a0)
285d4086a48Svisa	LDHI	a5, 8(a0)
286d4086a48Svisa	LDLO	a5, 15(a0)
287d4086a48Svisa	daddu	a0, a0, 16
288d4086a48Svisa	xor	a4, t2
289d4086a48Svisa	xor	a5, t3
290d4086a48Svisa	SDHI	a4, -16(a0)
291d4086a48Svisa	SDLO	a4, -9(a0)
292d4086a48Svisa	SDHI	a5, -8(a0)
293d4086a48Svisa	bltu	a0, a3, 2b
294d4086a48Svisa	 SDLO	a5, -1(a0)
295d4086a48Svisa
296d4086a48Svisa3:
297d4086a48Svisa	jr	ra
298d4086a48Svisa	 nop
299d4086a48SvisaEND(octcrypto_aes_ctr_enc)
300d4086a48Svisa
301d4086a48Svisa#define HASH_NARROW(name, type)						\
302d4086a48SvisaLEAF(octcrypto_hash_##name, 0)						\
303d4086a48Svisa	bltu	a1, 64, 3f;						\
304d4086a48Svisa	 and	t3, a1, 63;						\
305d4086a48Svisa	and	t2, a0, 7;		/* Determine alignment. */	\
306d4086a48Svisa	dsubu	a3, a1, t3;						\
307d4086a48Svisa	bne	t2, zero, 2f;						\
308d4086a48Svisa	 daddu	a3, a3, a0;		/* Compute buffer end. */	\
309d4086a48Svisa									\
310d4086a48Svisa	/*								\
311d4086a48Svisa	 * Aligned buffer						\
312d4086a48Svisa	 */								\
313d4086a48Svisa1:									\
314d4086a48Svisa	ld	t0, (a0);						\
315d4086a48Svisa	ld	t1, 8(a0);						\
316d4086a48Svisa	ld	t2, 16(a0);						\
317d4086a48Svisa	ld	t3, 24(a0);						\
318d4086a48Svisa	dmtc2	t0, MT_HSH_DAT;						\
319d4086a48Svisa	dmtc2	t1, MT_HSH_DAT+1;					\
320d4086a48Svisa	dmtc2	t2, MT_HSH_DAT+2;					\
321d4086a48Svisa	dmtc2	t3, MT_HSH_DAT+3;					\
322d4086a48Svisa	ld	t0, 32(a0);						\
323d4086a48Svisa	ld	t1, 40(a0);						\
324d4086a48Svisa	ld	t2, 48(a0);						\
325d4086a48Svisa	ld	t3, 56(a0);						\
326d4086a48Svisa	daddu	a0, a0, 64;						\
327d4086a48Svisa	dmtc2	t0, MT_HSH_DAT+4;					\
328d4086a48Svisa	dmtc2	t1, MT_HSH_DAT+5;					\
329d4086a48Svisa	dmtc2	t2, MT_HSH_DAT+6;					\
330d4086a48Svisa	bltu	a0, a3, 1b;						\
331d4086a48Svisa	 dmtc2	t3, MT_HSH_START##type;					\
332d4086a48Svisa	b	3f;							\
333d4086a48Svisa	 nop;								\
334d4086a48Svisa									\
335d4086a48Svisa	/*								\
336d4086a48Svisa	 * Unaligned buffer						\
337d4086a48Svisa	 */								\
338d4086a48Svisa2:									\
339d4086a48Svisa	LDHI	t0, (a0);						\
340d4086a48Svisa	LDLO	t0, 7(a0);						\
341d4086a48Svisa	LDHI	t1, 8(a0);						\
342d4086a48Svisa	LDLO	t1, 15(a0);						\
343d4086a48Svisa	LDHI	t2, 16(a0);						\
344d4086a48Svisa	LDLO	t2, 23(a0);						\
345d4086a48Svisa	LDHI	t3, 24(a0);						\
346d4086a48Svisa	LDLO	t3, 31(a0);						\
347d4086a48Svisa	dmtc2	t0, MT_HSH_DAT;						\
348d4086a48Svisa	dmtc2	t1, MT_HSH_DAT+1;					\
349d4086a48Svisa	dmtc2	t2, MT_HSH_DAT+2;					\
350d4086a48Svisa	dmtc2	t3, MT_HSH_DAT+3;					\
351d4086a48Svisa	LDHI	t0, 32(a0);						\
352d4086a48Svisa	LDLO	t0, 39(a0);						\
353d4086a48Svisa	LDHI	t1, 40(a0);						\
354d4086a48Svisa	LDLO	t1, 47(a0);						\
355d4086a48Svisa	LDHI	t2, 48(a0);						\
356d4086a48Svisa	LDLO	t2, 55(a0);						\
357d4086a48Svisa	LDHI	t3, 56(a0);						\
358d4086a48Svisa	LDLO	t3, 63(a0);						\
359d4086a48Svisa	daddu	a0, a0, 64;						\
360d4086a48Svisa	dmtc2	t0, MT_HSH_DAT+4;					\
361d4086a48Svisa	dmtc2	t1, MT_HSH_DAT+5;					\
362d4086a48Svisa	dmtc2	t2, MT_HSH_DAT+6;					\
363d4086a48Svisa	bltu	a0, a3, 2b;						\
364d4086a48Svisa	 dmtc2	t3, MT_HSH_START##type;					\
365d4086a48Svisa3:									\
366d4086a48Svisa	jr	ra;							\
367d4086a48Svisa	 nop;								\
368d4086a48SvisaEND(octcrypto_hash_##name)
369d4086a48Svisa
370d4086a48Svisa#define HASH_WIDE(name, type)						\
371d4086a48SvisaLEAF(octcrypto_hash_##name, 0)						\
372d4086a48Svisa	bltu	a1, 128, 3f;						\
373d4086a48Svisa	 and	t3, a1, 127;						\
374d4086a48Svisa	and	t2, a0, 7;		/* Determine alignment. */	\
375d4086a48Svisa	dsubu	a3, a1, t3;						\
376d4086a48Svisa	bne	t2, zero, 2f;						\
377d4086a48Svisa	 daddu	a3, a3, a0;		/* Compute buffer end. */	\
378d4086a48Svisa									\
379d4086a48Svisa	/*								\
380d4086a48Svisa	 * Aligned buffer						\
381d4086a48Svisa	 */								\
382d4086a48Svisa1:									\
383d4086a48Svisa	ld	t0, (a0);						\
384d4086a48Svisa	ld	t1, 8(a0);						\
385d4086a48Svisa	ld	t2, 16(a0);						\
386d4086a48Svisa	ld	t3, 24(a0);						\
387d4086a48Svisa	dmtc2	t0, MT_HSH_DATW;					\
388d4086a48Svisa	dmtc2	t1, MT_HSH_DATW+1;					\
389d4086a48Svisa	dmtc2	t2, MT_HSH_DATW+2;					\
390d4086a48Svisa	dmtc2	t3, MT_HSH_DATW+3;					\
391d4086a48Svisa	ld	t0, 32(a0);						\
392d4086a48Svisa	ld	t1, 40(a0);						\
393d4086a48Svisa	ld	t2, 48(a0);						\
394d4086a48Svisa	ld	t3, 56(a0);						\
395d4086a48Svisa	dmtc2	t0, MT_HSH_DATW+4;					\
396d4086a48Svisa	dmtc2	t1, MT_HSH_DATW+5;					\
397d4086a48Svisa	dmtc2	t2, MT_HSH_DATW+6;					\
398d4086a48Svisa	dmtc2	t3, MT_HSH_DATW+7;					\
399d4086a48Svisa	ld	t0, 64(a0);						\
400d4086a48Svisa	ld	t1, 72(a0);						\
401d4086a48Svisa	ld	t2, 80(a0);						\
402d4086a48Svisa	ld	t3, 88(a0);						\
403d4086a48Svisa	dmtc2	t0, MT_HSH_DATW+8;					\
404d4086a48Svisa	dmtc2	t1, MT_HSH_DATW+9;					\
405d4086a48Svisa	dmtc2	t2, MT_HSH_DATW+10;					\
406d4086a48Svisa	dmtc2	t3, MT_HSH_DATW+11;					\
407d4086a48Svisa	ld	t0, 96(a0);						\
408d4086a48Svisa	ld	t1, 104(a0);						\
409d4086a48Svisa	ld	t2, 112(a0);						\
410d4086a48Svisa	ld	t3, 120(a0);						\
411d4086a48Svisa	daddu	a0, a0, 128;						\
412d4086a48Svisa	dmtc2	t0, MT_HSH_DATW+12;					\
413d4086a48Svisa	dmtc2	t1, MT_HSH_DATW+13;					\
414d4086a48Svisa	dmtc2	t2, MT_HSH_DATW+14;					\
415d4086a48Svisa	bltu	a0, a3, 1b;						\
416d4086a48Svisa	 dmtc2	t3, MT_HSH_START##type;					\
417d4086a48Svisa	b	3f;							\
418d4086a48Svisa	 nop;								\
419d4086a48Svisa									\
420d4086a48Svisa	/*								\
421d4086a48Svisa	 * Unaligned buffer						\
422d4086a48Svisa	 */								\
423d4086a48Svisa2:									\
424d4086a48Svisa	LDHI	t0, (a0);						\
425d4086a48Svisa	LDLO	t0, 7(a0);						\
426d4086a48Svisa	LDHI	t1, 8(a0);						\
427d4086a48Svisa	LDLO	t1, 15(a0);						\
428d4086a48Svisa	LDHI	t2, 16(a0);						\
429d4086a48Svisa	LDLO	t2, 23(a0);						\
430d4086a48Svisa	LDHI	t3, 24(a0);						\
431d4086a48Svisa	LDLO	t3, 31(a0);						\
432d4086a48Svisa	dmtc2	t0, MT_HSH_DATW;					\
433d4086a48Svisa	dmtc2	t1, MT_HSH_DATW+1;					\
434d4086a48Svisa	dmtc2	t2, MT_HSH_DATW+2;					\
435d4086a48Svisa	dmtc2	t3, MT_HSH_DATW+3;					\
436d4086a48Svisa	LDHI	t0, 32(a0);						\
437d4086a48Svisa	LDLO	t0, 39(a0);						\
438d4086a48Svisa	LDHI	t1, 40(a0);						\
439d4086a48Svisa	LDLO	t1, 47(a0);						\
440d4086a48Svisa	LDHI	t2, 48(a0);						\
441d4086a48Svisa	LDLO	t2, 55(a0);						\
442d4086a48Svisa	LDHI	t3, 56(a0);						\
443d4086a48Svisa	LDLO	t3, 63(a0);						\
444d4086a48Svisa	dmtc2	t0, MT_HSH_DATW+4;					\
445d4086a48Svisa	dmtc2	t1, MT_HSH_DATW+5;					\
446d4086a48Svisa	dmtc2	t2, MT_HSH_DATW+6;					\
447d4086a48Svisa	dmtc2	t3, MT_HSH_DATW+7;					\
448d4086a48Svisa	LDHI	t0, 64(a0);						\
449d4086a48Svisa	LDLO	t0, 71(a0);						\
450d4086a48Svisa	LDHI	t1, 72(a0);						\
451d4086a48Svisa	LDLO	t1, 79(a0);						\
452d4086a48Svisa	LDHI	t2, 80(a0);						\
453d4086a48Svisa	LDLO	t2, 87(a0);						\
454d4086a48Svisa	LDHI	t3, 88(a0);						\
455d4086a48Svisa	LDLO	t3, 95(a0);						\
456d4086a48Svisa	dmtc2	t0, MT_HSH_DATW+8;					\
457d4086a48Svisa	dmtc2	t1, MT_HSH_DATW+9;					\
458d4086a48Svisa	dmtc2	t2, MT_HSH_DATW+10;					\
459d4086a48Svisa	dmtc2	t3, MT_HSH_DATW+11;					\
460d4086a48Svisa	LDHI	t0, 96(a0);						\
461d4086a48Svisa	LDLO	t0, 103(a0);						\
462d4086a48Svisa	LDHI	t1, 104(a0);						\
463d4086a48Svisa	LDLO	t1, 111(a0);						\
464d4086a48Svisa	LDHI	t2, 112(a0);						\
465d4086a48Svisa	LDLO	t2, 119(a0);						\
466d4086a48Svisa	LDHI	t3, 120(a0);						\
467d4086a48Svisa	LDLO	t3, 127(a0);						\
468d4086a48Svisa	daddu	a0, a0, 128;						\
469d4086a48Svisa	dmtc2	t0, MT_HSH_DATW+12;					\
470d4086a48Svisa	dmtc2	t1, MT_HSH_DATW+13;					\
471d4086a48Svisa	dmtc2	t2, MT_HSH_DATW+14;					\
472d4086a48Svisa	bltu	a0, a3, 2b;						\
473d4086a48Svisa	 dmtc2	t3, MT_HSH_START##type;					\
474d4086a48Svisa3:									\
475d4086a48Svisa	jr	ra;							\
476d4086a48Svisa	 nop;								\
477d4086a48SvisaEND(octcrypto_hash_##name)
478d4086a48Svisa
479d4086a48Svisa/*
480d4086a48Svisa * void octcrypto_md5(const void *buf, size_t size)
481d4086a48Svisa */
482d4086a48SvisaHASH_NARROW(md5, MD5)
483d4086a48Svisa
484d4086a48Svisa/*
485d4086a48Svisa * void octcrypto_sha1(const void *buf, size_t size)
486d4086a48Svisa */
487d4086a48SvisaHASH_NARROW(sha1, SHA)
488d4086a48Svisa
489d4086a48Svisa/*
490d4086a48Svisa * void octcrypto_sha256(const void *src, size_t size)
491d4086a48Svisa */
492d4086a48SvisaHASH_NARROW(sha256, SHA256)
493d4086a48Svisa
494d4086a48Svisa/*
495d4086a48Svisa * void octcrypto_sha512(const void *src, size_t size)
496d4086a48Svisa */
497d4086a48SvisaHASH_WIDE(sha512, SHA512)
498d4086a48Svisa
499d4086a48Svisa/*
500d4086a48Svisa * void octcrypto_hash_set_ivn(const uint64_t *iv)
501d4086a48Svisa */
502d4086a48SvisaLEAF(octcrypto_hash_set_ivn, 0)
503d4086a48Svisa	ld	t0, (a0)
504d4086a48Svisa	ld	t1, 8(a0)
505d4086a48Svisa	ld	t2, 16(a0)
506d4086a48Svisa	ld	t3, 24(a0)
507d4086a48Svisa	dmtc2	t0, MT_HSH_IV
508d4086a48Svisa	dmtc2	t1, MT_HSH_IV+1
509d4086a48Svisa	dmtc2	t2, MT_HSH_IV+2
510d4086a48Svisa	jr	ra
511d4086a48Svisa	 dmtc2	t3, MT_HSH_IV+3
512d4086a48SvisaEND(octcrypto_hash_set_ivn)
513d4086a48Svisa
514d4086a48Svisa/*
515d4086a48Svisa * void octcrypto_hash_set_ivw(const uint64_t *iv)
516d4086a48Svisa */
517d4086a48SvisaLEAF(octcrypto_hash_set_ivw, 0)
518d4086a48Svisa	ld	t0, (a0)
519d4086a48Svisa	ld	t1, 8(a0)
520d4086a48Svisa	ld	t2, 16(a0)
521d4086a48Svisa	ld	t3, 24(a0)
522d4086a48Svisa	dmtc2	t0, MT_HSH_IVW
523d4086a48Svisa	dmtc2	t1, MT_HSH_IVW+1
524d4086a48Svisa	dmtc2	t2, MT_HSH_IVW+2
525d4086a48Svisa	dmtc2	t3, MT_HSH_IVW+3
526d4086a48Svisa	ld	t0, 32(a0)
527d4086a48Svisa	ld	t1, 40(a0)
528d4086a48Svisa	ld	t2, 48(a0)
529d4086a48Svisa	ld	t3, 56(a0)
530d4086a48Svisa	dmtc2	t0, MT_HSH_IVW+4
531d4086a48Svisa	dmtc2	t1, MT_HSH_IVW+5
532d4086a48Svisa	dmtc2	t2, MT_HSH_IVW+6
533d4086a48Svisa	jr	ra
534d4086a48Svisa	 dmtc2	t3, MT_HSH_IVW+7
535d4086a48SvisaEND(octcrypto_hash_set_ivw)
536d4086a48Svisa
537d4086a48Svisa/*
538d4086a48Svisa * void octcrypto_hash_get_ivn(uint64_t *iv)
539d4086a48Svisa */
540d4086a48SvisaLEAF(octcrypto_hash_get_ivn, 0)
541d4086a48Svisa	dmfc2	t0, MF_HSH_IV
542d4086a48Svisa	dmfc2	t1, MF_HSH_IV+1
543d4086a48Svisa	dmfc2	t2, MF_HSH_IV+2
544d4086a48Svisa	dmfc2	t3, MF_HSH_IV+3
545d4086a48Svisa	sd	t0, (a0)
546d4086a48Svisa	sd	t1, 8(a0)
547d4086a48Svisa	sd	t2, 16(a0)
548d4086a48Svisa	jr	ra
549d4086a48Svisa	 sd	t3, 24(a0)
550d4086a48SvisaEND(octcrypto_hash_get_ivn)
551d4086a48Svisa
552d4086a48Svisa/*
553d4086a48Svisa * void octcrypto_hash_get_ivw(uint64_t *iv)
554d4086a48Svisa */
555d4086a48SvisaLEAF(octcrypto_hash_get_ivw, 0)
556d4086a48Svisa	dmfc2	t0, MF_HSH_IVW
557d4086a48Svisa	dmfc2	t1, MF_HSH_IVW+1
558d4086a48Svisa	dmfc2	t2, MF_HSH_IVW+2
559d4086a48Svisa	dmfc2	t3, MF_HSH_IVW+3
560d4086a48Svisa	sd	t0, (a0)
561d4086a48Svisa	sd	t1, 8(a0)
562d4086a48Svisa	sd	t2, 16(a0)
563d4086a48Svisa	sd	t3, 24(a0)
564d4086a48Svisa	dmfc2	t0, MF_HSH_IVW+4
565d4086a48Svisa	dmfc2	t1, MF_HSH_IVW+5
566d4086a48Svisa	dmfc2	t2, MF_HSH_IVW+6
567d4086a48Svisa	dmfc2	t3, MF_HSH_IVW+7
568d4086a48Svisa	sd	t0, 32(a0)
569d4086a48Svisa	sd	t1, 40(a0)
570d4086a48Svisa	sd	t2, 48(a0)
571d4086a48Svisa	jr	ra
572d4086a48Svisa	 sd	t3, 56(a0)
573d4086a48SvisaEND(octcrypto_hash_get_ivw)
574d4086a48Svisa
575d4086a48Svisa/*
576d4086a48Svisa * void octcrypto_hash_clearn(void)
577d4086a48Svisa */
578d4086a48SvisaLEAF(octcrypto_hash_clearn, 0)
579d4086a48Svisa	dmtc2	zero, MT_HSH_IV
580d4086a48Svisa	dmtc2	zero, MT_HSH_IV+1
581d4086a48Svisa	dmtc2	zero, MT_HSH_IV+2
582d4086a48Svisa	dmtc2	zero, MT_HSH_IV+3
583d4086a48Svisa	dmtc2	zero, MT_HSH_DAT
584d4086a48Svisa	dmtc2	zero, MT_HSH_DAT+1
585d4086a48Svisa	dmtc2	zero, MT_HSH_DAT+2
586d4086a48Svisa	dmtc2	zero, MT_HSH_DAT+3
587d4086a48Svisa	dmtc2	zero, MT_HSH_DAT+4
588d4086a48Svisa	dmtc2	zero, MT_HSH_DAT+5
589d4086a48Svisa	jr	ra
590d4086a48Svisa	 dmtc2	zero, MT_HSH_DAT+6
591d4086a48SvisaEND(octcrypto_hash_clearn)
592d4086a48Svisa
593d4086a48Svisa/*
594d4086a48Svisa * void octcrypto_hash_clearw(void)
595d4086a48Svisa */
596d4086a48SvisaLEAF(octcrypto_hash_clearw, 0)
597d4086a48Svisa	dmtc2	zero, MT_HSH_IVW
598d4086a48Svisa	dmtc2	zero, MT_HSH_IVW+1
599d4086a48Svisa	dmtc2	zero, MT_HSH_IVW+2
600d4086a48Svisa	dmtc2	zero, MT_HSH_IVW+3
601d4086a48Svisa	dmtc2	zero, MT_HSH_IVW+4
602d4086a48Svisa	dmtc2	zero, MT_HSH_IVW+5
603d4086a48Svisa	dmtc2	zero, MT_HSH_IVW+6
604d4086a48Svisa	dmtc2	zero, MT_HSH_IVW+7
605d4086a48Svisa	dmtc2	zero, MT_HSH_DATW
606d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+1
607d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+2
608d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+3
609d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+4
610d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+5
611d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+6
612d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+7
613d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+8
614d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+9
615d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+10
616d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+11
617d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+12
618d4086a48Svisa	dmtc2	zero, MT_HSH_DATW+13
619d4086a48Svisa	jr	ra
620d4086a48Svisa	 dmtc2	zero, MT_HSH_DATW+14
621d4086a48SvisaEND(octcrypto_hash_clearw)
622d4086a48Svisa
623d4086a48Svisa/*
624d4086a48Svisa * void octcrypto_ghash_init(const uint64_t *key, const uint64_t *state)
625d4086a48Svisa *
626d4086a48Svisa * Initialize the Galois field multiplier unit with the GF(2^128) polynomial
627d4086a48Svisa * and given key.
628d4086a48Svisa * If state is given, load it to the unit; otherwise, use zero state.
629d4086a48Svisa */
630d4086a48SvisaLEAF(octcrypto_ghash_init, 0)
631d4086a48Svisa	/* Set the polynomial. */
632d4086a48Svisa	li	t0, GF128_POLY
633d4086a48Svisa	dmtc2	t0, MT_GFM_POLY
634d4086a48Svisa	/* Set the hash key / multiplier. */
635d4086a48Svisa	ld	t0, (a0)
636d4086a48Svisa	ld	t1, 8(a0)
637d4086a48Svisa	dmtc2	t0, MT_GFM_MUL
638d4086a48Svisa	dmtc2	t1, MT_GFM_MUL+1
639d4086a48Svisa	/* Initialize the state. */
640d4086a48Svisa	bne	a1, zero, 1f
641d4086a48Svisa	 move	t0, zero
642d4086a48Svisa	b	2f
643d4086a48Svisa	 move	t1, zero
644d4086a48Svisa1:
645d4086a48Svisa	ld	t0, (a1)
646d4086a48Svisa	ld	t1, 8(a1)
647d4086a48Svisa2:
648d4086a48Svisa	dmtc2	t0, MT_GFM_RESINP
649d4086a48Svisa	jr	ra
650d4086a48Svisa	 dmtc2	t1, MT_GFM_RESINP+1
651*7b6d8aacSvisaEND(octcrypto_ghash_init)
652d4086a48Svisa
653d4086a48Svisa/*
654d4086a48Svisa * void octcrypto_ghash_finish(uint64_t *x)
655d4086a48Svisa *
656d4086a48Svisa * Store the current GHASH state into buffer `x',
657d4086a48Svisa * and clear the GFM unit's state.
658d4086a48Svisa */
659d4086a48SvisaLEAF(octcrypto_ghash_finish, 0)
660d4086a48Svisa	dmfc2	t0, MF_GFM_RESINP
661d4086a48Svisa	dmfc2	t1, MF_GFM_RESINP+1
662d4086a48Svisa	sd	t0, (a0)
663d4086a48Svisa	sd	t1, 8(a0)
664d4086a48Svisa	dmtc2	zero, MT_GFM_RESINP
665d4086a48Svisa	dmtc2	zero, MT_GFM_RESINP+1
666d4086a48Svisa	dmtc2	zero, MT_GFM_MUL
667d4086a48Svisa	jr	ra
668d4086a48Svisa	 dmtc2	zero, MT_GFM_MUL+1
669d4086a48SvisaEND(octcrypto_ghash_finish)
670d4086a48Svisa
671d4086a48Svisa/*
672d4086a48Svisa * void octcrypto_ghash_update(const void *buf, size_t len)
673d4086a48Svisa *
674d4086a48Svisa * Update the GHASH state.
675d4086a48Svisa *
676d4086a48Svisa * For each X_i in X_0 || X_1 || ... || X_{n-1} = buf:
677d4086a48Svisa *     Y := (Y ^ X_i) * H
678d4086a48Svisa */
679d4086a48SvisaLEAF(octcrypto_ghash_update, 0)
680d4086a48Svisa	bltu	a1, 16, 3f
681d4086a48Svisa	 and	t2, a1, 15
682d4086a48Svisa	dsubu	a3, a1, t2
683d4086a48Svisa	and	t0, a0, 7
684d4086a48Svisa	bne	t0, zero, 2f
685d4086a48Svisa	 daddu	a3, a3, a0
686d4086a48Svisa1:
687d4086a48Svisa	/* Aligned buffer */
688d4086a48Svisa	ld	t0, (a0)
689d4086a48Svisa	ld	t1, 8(a0)
690d4086a48Svisa	daddu	a0, 16
691d4086a48Svisa	dmtc2	t0, MT_GFM_XOR0
692d4086a48Svisa	bltu	a0, a3, 1b
693d4086a48Svisa	 dmtc2	t1, MT_GFM_XORMUL1
694d4086a48Svisa	b	3f
695d4086a48Svisa	 nop
696d4086a48Svisa2:
697d4086a48Svisa	/* Unaligned buffer */
698d4086a48Svisa	LDHI	t0, (a0)
699d4086a48Svisa	LDLO	t0, 7(a0)
700d4086a48Svisa	LDHI	t1, 8(a0)
701d4086a48Svisa	LDLO	t1, 15(a0)
702d4086a48Svisa	daddu	a0, 16
703d4086a48Svisa	dmtc2	t0, MT_GFM_XOR0
704d4086a48Svisa	bltu	a0, a3, 2b
705d4086a48Svisa	 dmtc2	t1, MT_GFM_XORMUL1
706d4086a48Svisa3:
707d4086a48Svisa	jr	ra
708d4086a48Svisa	 nop
709d4086a48SvisaEND(octcrypto_ghash_update)
710