1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build !purego
6
7#include "textflag.h"
8
9// func cryptBlocks(c code, key, dst, src *byte, length int)
10TEXT ·cryptBlocks(SB),NOSPLIT,$0-40
11	MOVD	key+8(FP), R1
12	MOVD	dst+16(FP), R2
13	MOVD	src+24(FP), R4
14	MOVD	length+32(FP), R5
15	MOVD	c+0(FP), R0
16loop:
17	KM	R2, R4      // cipher message (KM)
18	BVS	loop        // branch back if interrupted
19	XOR	R0, R0
20	RET
21
22// func cryptBlocksChain(c code, iv, key, dst, src *byte, length int)
23TEXT ·cryptBlocksChain(SB),NOSPLIT,$48-48
24	LA	params-48(SP), R1
25	MOVD	iv+8(FP), R8
26	MOVD	key+16(FP), R9
27	MVC	$16, 0(R8), 0(R1)  // move iv into params
28	MVC	$32, 0(R9), 16(R1) // move key into params
29	MOVD	dst+24(FP), R2
30	MOVD	src+32(FP), R4
31	MOVD	length+40(FP), R5
32	MOVD	c+0(FP), R0
33loop:
34	KMC	R2, R4            // cipher message with chaining (KMC)
35	BVS	loop              // branch back if interrupted
36	XOR	R0, R0
37	MVC	$16, 0(R1), 0(R8) // update iv
38	RET
39
40// func xorBytes(dst, a, b []byte) int
41TEXT ·xorBytes(SB),NOSPLIT,$0-80
42	MOVD	dst_base+0(FP), R1
43	MOVD	a_base+24(FP), R2
44	MOVD	b_base+48(FP), R3
45	MOVD	a_len+32(FP), R4
46	MOVD	b_len+56(FP), R5
47	CMPBLE	R4, R5, skip
48	MOVD	R5, R4
49skip:
50	MOVD	R4, ret+72(FP)
51	MOVD	$0, R5
52	CMPBLT	R4, $8, tail
53loop:
54	MOVD	0(R2)(R5*1), R7
55	MOVD	0(R3)(R5*1), R8
56	XOR	R7, R8
57	MOVD	R8, 0(R1)(R5*1)
58	LAY	8(R5), R5
59	SUB	$8, R4
60	CMPBGE	R4, $8, loop
61tail:
62	CMPBEQ	R4, $0, done
63	MOVB	0(R2)(R5*1), R7
64	MOVB	0(R3)(R5*1), R8
65	XOR	R7, R8
66	MOVB	R8, 0(R1)(R5*1)
67	LAY	1(R5), R5
68	SUB	$1, R4
69	BR	tail
70done:
71	RET
72
73// func cryptBlocksGCM(fn code, key, dst, src, buf []byte, cnt *[16]byte)
74TEXT ·cryptBlocksGCM(SB),NOSPLIT,$0-112
75	MOVD	src_len+64(FP), R0
76	MOVD	buf_base+80(FP), R1
77	MOVD	cnt+104(FP), R12
78	LMG	(R12), R2, R3
79
80	// Check that the src size is less than or equal to the buffer size.
81	MOVD	buf_len+88(FP), R4
82	CMP	R0, R4
83	BGT	crash
84
85	// Check that the src size is a multiple of 16-bytes.
86	MOVD	R0, R4
87	AND	$0xf, R4
88	BLT	crash // non-zero
89
90	// Check that the src size is less than or equal to the dst size.
91	MOVD	dst_len+40(FP), R4
92	CMP	R0, R4
93	BGT	crash
94
95	MOVD	R2, R4
96	MOVD	R2, R6
97	MOVD	R2, R8
98	MOVD	R3, R5
99	MOVD	R3, R7
100	MOVD	R3, R9
101	ADDW	$1, R5
102	ADDW	$2, R7
103	ADDW	$3, R9
104incr:
105	CMP	R0, $64
106	BLT	tail
107	STMG	R2, R9, (R1)
108	ADDW	$4, R3
109	ADDW	$4, R5
110	ADDW	$4, R7
111	ADDW	$4, R9
112	MOVD	$64(R1), R1
113	SUB	$64, R0
114	BR	incr
115tail:
116	CMP	R0, $0
117	BEQ	crypt
118	STMG	R2, R3, (R1)
119	ADDW	$1, R3
120	MOVD	$16(R1), R1
121	SUB	$16, R0
122	BR	tail
123crypt:
124	STMG	R2, R3, (R12)       // update next counter value
125	MOVD	fn+0(FP), R0        // function code (encryption)
126	MOVD	key_base+8(FP), R1  // key
127	MOVD	buf_base+80(FP), R2 // counter values
128	MOVD	dst_base+32(FP), R4 // dst
129	MOVD	src_base+56(FP), R6 // src
130	MOVD	src_len+64(FP), R7  // len
131loop:
132	KMCTR	R4, R2, R6          // cipher message with counter (KMCTR)
133	BVS	loop                // branch back if interrupted
134	RET
135crash:
136	MOVD	$0, (R0)
137	RET
138
139// func ghash(key *gcmHashKey, hash *[16]byte, data []byte)
140TEXT ·ghash(SB),NOSPLIT,$32-40
141	MOVD    $65, R0 // GHASH function code
142	MOVD	key+0(FP), R2
143	LMG	(R2), R6, R7
144	MOVD	hash+8(FP), R8
145	LMG	(R8), R4, R5
146	MOVD	$params-32(SP), R1
147	STMG	R4, R7, (R1)
148	LMG	data+16(FP), R2, R3 // R2=base, R3=len
149loop:
150	KIMD	R0, R2      // compute intermediate message digest (KIMD)
151	BVS     loop        // branch back if interrupted
152	MVC     $16, (R1), (R8)
153	MOVD	$0, R0
154	RET
155
156// func kmaGCM(fn code, key, dst, src, aad []byte, tag *[16]byte, cnt *gcmCount)
157TEXT ·kmaGCM(SB),NOSPLIT,$112-120
158	MOVD	fn+0(FP), R0
159	MOVD	$params-112(SP), R1
160
161	// load ptr/len pairs
162	LMG	dst+32(FP), R2, R3 // R2=base R3=len
163	LMG	src+56(FP), R4, R5 // R4=base R5=len
164	LMG	aad+80(FP), R6, R7 // R6=base R7=len
165
166	// setup parameters
167	MOVD	cnt+112(FP), R8
168	XC	$12, (R1), (R1)     // reserved
169	MVC	$4, 12(R8), 12(R1)  // set chain value
170	MVC	$16, (R8), 64(R1)   // set initial counter value
171	XC	$32, 16(R1), 16(R1) // set hash subkey and tag
172	SLD	$3, R7, R12
173	MOVD	R12, 48(R1)         // set total AAD length
174	SLD	$3, R5, R12
175	MOVD	R12, 56(R1)         // set total plaintext/ciphertext length
176
177	LMG	key+8(FP), R8, R9   // R8=base R9=len
178	MVC	$16, (R8), 80(R1)   // set key
179	CMPBEQ	R9, $16, kma
180	MVC	$8, 16(R8), 96(R1)
181	CMPBEQ	R9, $24, kma
182	MVC	$8, 24(R8), 104(R1)
183
184kma:
185	KMA	R2, R6, R4       // Cipher Message with Authentication
186	BVS	kma
187
188	MOVD	tag+104(FP), R2
189	MVC	$16, 16(R1), 0(R2) // copy tag to output
190	MOVD	cnt+112(FP), R8
191	MVC	$4, 12(R1), 12(R8) // update counter value
192
193	RET
194