aes-neon.S 12.3 KB
Newer Older
1 2 3
/*
 * linux/arch/arm64/crypto/aes-neon.S - AES cipher for ARMv8 NEON
 *
4
 * Copyright (C) 2013 - 2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
5 6 7 8 9 10 11
 *
 * 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 <linux/linkage.h>
12
#include <asm/assembler.h>
13 14 15 16

#define AES_ENTRY(func)		ENTRY(neon_ ## func)
#define AES_ENDPROC(func)	ENDPROC(neon_ ## func)

17 18 19 20 21 22
	xtsmask		.req	v7

	.macro		xts_reload_mask, tmp
	xts_load_mask	\tmp
	.endm

23 24 25
	/* multiply by polynomial 'x' in GF(2^8) */
	.macro		mul_by_x, out, in, temp, const
	sshr		\temp, \in, #7
26
	shl		\out, \in, #1
27 28 29 30
	and		\temp, \temp, \const
	eor		\out, \out, \temp
	.endm

31 32 33 34 35 36 37 38
	/* multiply by polynomial 'x^2' in GF(2^8) */
	.macro		mul_by_x2, out, in, temp, const
	ushr		\temp, \in, #6
	shl		\out, \in, #2
	pmul		\temp, \temp, \const
	eor		\out, \out, \temp
	.endm

39 40
	/* preload the entire Sbox */
	.macro		prepare, sbox, shiftrows, temp
41
	movi		v12.16b, #0x1b
42 43 44
	ldr_l		q13, \shiftrows, \temp
	ldr_l		q14, .Lror32by8, \temp
	adr_l		\temp, \sbox
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
	ld1		{v16.16b-v19.16b}, [\temp], #64
	ld1		{v20.16b-v23.16b}, [\temp], #64
	ld1		{v24.16b-v27.16b}, [\temp], #64
	ld1		{v28.16b-v31.16b}, [\temp]
	.endm

	/* do preload for encryption */
	.macro		enc_prepare, ignore0, ignore1, temp
	prepare		.LForward_Sbox, .LForward_ShiftRows, \temp
	.endm

	.macro		enc_switch_key, ignore0, ignore1, temp
	/* do nothing */
	.endm

	/* do preload for decryption */
	.macro		dec_prepare, ignore0, ignore1, temp
	prepare		.LReverse_Sbox, .LReverse_ShiftRows, \temp
	.endm

	/* apply SubBytes transformation using the the preloaded Sbox */
	.macro		sub_bytes, in
67
	sub		v9.16b, \in\().16b, v15.16b
68
	tbl		\in\().16b, {v16.16b-v19.16b}, \in\().16b
69
	sub		v10.16b, v9.16b, v15.16b
70
	tbx		\in\().16b, {v20.16b-v23.16b}, v9.16b
71
	sub		v11.16b, v10.16b, v15.16b
72 73 74 75 76
	tbx		\in\().16b, {v24.16b-v27.16b}, v10.16b
	tbx		\in\().16b, {v28.16b-v31.16b}, v11.16b
	.endm

	/* apply MixColumns transformation */
77 78
	.macro		mix_columns, in, enc
	.if		\enc == 0
79
	/* Inverse MixColumns: pre-multiply by { 5, 0, 4, 0 } */
80 81 82 83 84 85 86 87 88 89 90 91
	mul_by_x2	v8.16b, \in\().16b, v9.16b, v12.16b
	eor		\in\().16b, \in\().16b, v8.16b
	rev32		v8.8h, v8.8h
	eor		\in\().16b, \in\().16b, v8.16b
	.endif

	mul_by_x	v9.16b, \in\().16b, v8.16b, v12.16b
	rev32		v8.8h, \in\().8h
	eor		v8.16b, v8.16b, v9.16b
	eor		\in\().16b, \in\().16b, v8.16b
	tbl		\in\().16b, {\in\().16b}, v14.16b
	eor		\in\().16b, \in\().16b, v8.16b
92 93 94
	.endm

	.macro		do_block, enc, in, rounds, rk, rkp, i
95
	ld1		{v15.4s}, [\rk]
96 97 98
	add		\rkp, \rk, #16
	mov		\i, \rounds
1111:	eor		\in\().16b, \in\().16b, v15.16b		/* ^round key */
99
	movi		v15.16b, #0x40
100 101 102
	tbl		\in\().16b, {\in\().16b}, v13.16b	/* ShiftRows */
	sub_bytes	\in
	subs		\i, \i, #1
103
	ld1		{v15.4s}, [\rkp], #16
104
	beq		2222f
105
	mix_columns	\in, \enc
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
	b		1111b
2222:	eor		\in\().16b, \in\().16b, v15.16b		/* ^round key */
	.endm

	.macro		encrypt_block, in, rounds, rk, rkp, i
	do_block	1, \in, \rounds, \rk, \rkp, \i
	.endm

	.macro		decrypt_block, in, rounds, rk, rkp, i
	do_block	0, \in, \rounds, \rk, \rkp, \i
	.endm

	/*
	 * Interleaved versions: functionally equivalent to the
	 * ones above, but applied to 2 or 4 AES states in parallel.
	 */

	.macro		sub_bytes_2x, in0, in1
124
	sub		v8.16b, \in0\().16b, v15.16b
125
	tbl		\in0\().16b, {v16.16b-v19.16b}, \in0\().16b
126
	sub		v9.16b, \in1\().16b, v15.16b
127
	tbl		\in1\().16b, {v16.16b-v19.16b}, \in1\().16b
128
	sub		v10.16b, v8.16b, v15.16b
129
	tbx		\in0\().16b, {v20.16b-v23.16b}, v8.16b
130
	sub		v11.16b, v9.16b, v15.16b
131
	tbx		\in1\().16b, {v20.16b-v23.16b}, v9.16b
132
	sub		v8.16b, v10.16b, v15.16b
133
	tbx		\in0\().16b, {v24.16b-v27.16b}, v10.16b
134
	sub		v9.16b, v11.16b, v15.16b
135 136 137 138 139 140
	tbx		\in1\().16b, {v24.16b-v27.16b}, v11.16b
	tbx		\in0\().16b, {v28.16b-v31.16b}, v8.16b
	tbx		\in1\().16b, {v28.16b-v31.16b}, v9.16b
	.endm

	.macro		sub_bytes_4x, in0, in1, in2, in3
141
	sub		v8.16b, \in0\().16b, v15.16b
142
	tbl		\in0\().16b, {v16.16b-v19.16b}, \in0\().16b
143
	sub		v9.16b, \in1\().16b, v15.16b
144
	tbl		\in1\().16b, {v16.16b-v19.16b}, \in1\().16b
145
	sub		v10.16b, \in2\().16b, v15.16b
146
	tbl		\in2\().16b, {v16.16b-v19.16b}, \in2\().16b
147
	sub		v11.16b, \in3\().16b, v15.16b
148 149 150
	tbl		\in3\().16b, {v16.16b-v19.16b}, \in3\().16b
	tbx		\in0\().16b, {v20.16b-v23.16b}, v8.16b
	tbx		\in1\().16b, {v20.16b-v23.16b}, v9.16b
151
	sub		v8.16b, v8.16b, v15.16b
152
	tbx		\in2\().16b, {v20.16b-v23.16b}, v10.16b
153
	sub		v9.16b, v9.16b, v15.16b
154
	tbx		\in3\().16b, {v20.16b-v23.16b}, v11.16b
155
	sub		v10.16b, v10.16b, v15.16b
156
	tbx		\in0\().16b, {v24.16b-v27.16b}, v8.16b
157
	sub		v11.16b, v11.16b, v15.16b
158
	tbx		\in1\().16b, {v24.16b-v27.16b}, v9.16b
159
	sub		v8.16b, v8.16b, v15.16b
160
	tbx		\in2\().16b, {v24.16b-v27.16b}, v10.16b
161
	sub		v9.16b, v9.16b, v15.16b
162
	tbx		\in3\().16b, {v24.16b-v27.16b}, v11.16b
163
	sub		v10.16b, v10.16b, v15.16b
164
	tbx		\in0\().16b, {v28.16b-v31.16b}, v8.16b
165
	sub		v11.16b, v11.16b, v15.16b
166 167 168 169 170 171
	tbx		\in1\().16b, {v28.16b-v31.16b}, v9.16b
	tbx		\in2\().16b, {v28.16b-v31.16b}, v10.16b
	tbx		\in3\().16b, {v28.16b-v31.16b}, v11.16b
	.endm

	.macro		mul_by_x_2x, out0, out1, in0, in1, tmp0, tmp1, const
172 173 174
	sshr		\tmp0\().16b, \in0\().16b, #7
	shl		\out0\().16b, \in0\().16b, #1
	sshr		\tmp1\().16b, \in1\().16b, #7
175
	and		\tmp0\().16b, \tmp0\().16b, \const\().16b
176
	shl		\out1\().16b, \in1\().16b, #1
177 178 179 180 181
	and		\tmp1\().16b, \tmp1\().16b, \const\().16b
	eor		\out0\().16b, \out0\().16b, \tmp0\().16b
	eor		\out1\().16b, \out1\().16b, \tmp1\().16b
	.endm

182 183 184 185 186 187 188 189 190
	.macro		mul_by_x2_2x, out0, out1, in0, in1, tmp0, tmp1, const
	ushr		\tmp0\().16b, \in0\().16b, #6
	shl		\out0\().16b, \in0\().16b, #2
	ushr		\tmp1\().16b, \in1\().16b, #6
	pmul		\tmp0\().16b, \tmp0\().16b, \const\().16b
	shl		\out1\().16b, \in1\().16b, #2
	pmul		\tmp1\().16b, \tmp1\().16b, \const\().16b
	eor		\out0\().16b, \out0\().16b, \tmp0\().16b
	eor		\out1\().16b, \out1\().16b, \tmp1\().16b
191 192
	.endm

193 194 195 196
	.macro		mix_columns_2x, in0, in1, enc
	.if		\enc == 0
	/* Inverse MixColumns: pre-multiply by { 5, 0, 4, 0 } */
	mul_by_x2_2x	v8, v9, \in0, \in1, v10, v11, v12
197 198 199 200 201 202
	eor		\in0\().16b, \in0\().16b, v8.16b
	rev32		v8.8h, v8.8h
	eor		\in1\().16b, \in1\().16b, v9.16b
	rev32		v9.8h, v9.8h
	eor		\in0\().16b, \in0\().16b, v8.16b
	eor		\in1\().16b, \in1\().16b, v9.16b
203 204 205 206 207 208 209 210 211 212 213 214 215
	.endif

	mul_by_x_2x	v8, v9, \in0, \in1, v10, v11, v12
	rev32		v10.8h, \in0\().8h
	rev32		v11.8h, \in1\().8h
	eor		v10.16b, v10.16b, v8.16b
	eor		v11.16b, v11.16b, v9.16b
	eor		\in0\().16b, \in0\().16b, v10.16b
	eor		\in1\().16b, \in1\().16b, v11.16b
	tbl		\in0\().16b, {\in0\().16b}, v14.16b
	tbl		\in1\().16b, {\in1\().16b}, v14.16b
	eor		\in0\().16b, \in0\().16b, v10.16b
	eor		\in1\().16b, \in1\().16b, v11.16b
216 217
	.endm

218
	.macro		do_block_2x, enc, in0, in1, rounds, rk, rkp, i
219
	ld1		{v15.4s}, [\rk]
220 221 222 223
	add		\rkp, \rk, #16
	mov		\i, \rounds
1111:	eor		\in0\().16b, \in0\().16b, v15.16b	/* ^round key */
	eor		\in1\().16b, \in1\().16b, v15.16b	/* ^round key */
224
	movi		v15.16b, #0x40
225 226
	tbl		\in0\().16b, {\in0\().16b}, v13.16b	/* ShiftRows */
	tbl		\in1\().16b, {\in1\().16b}, v13.16b	/* ShiftRows */
227
	sub_bytes_2x	\in0, \in1
228
	subs		\i, \i, #1
229
	ld1		{v15.4s}, [\rkp], #16
230
	beq		2222f
231
	mix_columns_2x	\in0, \in1, \enc
232 233 234 235 236 237
	b		1111b
2222:	eor		\in0\().16b, \in0\().16b, v15.16b	/* ^round key */
	eor		\in1\().16b, \in1\().16b, v15.16b	/* ^round key */
	.endm

	.macro		do_block_4x, enc, in0, in1, in2, in3, rounds, rk, rkp, i
238
	ld1		{v15.4s}, [\rk]
239 240 241 242 243 244
	add		\rkp, \rk, #16
	mov		\i, \rounds
1111:	eor		\in0\().16b, \in0\().16b, v15.16b	/* ^round key */
	eor		\in1\().16b, \in1\().16b, v15.16b	/* ^round key */
	eor		\in2\().16b, \in2\().16b, v15.16b	/* ^round key */
	eor		\in3\().16b, \in3\().16b, v15.16b	/* ^round key */
245
	movi		v15.16b, #0x40
246 247 248 249
	tbl		\in0\().16b, {\in0\().16b}, v13.16b	/* ShiftRows */
	tbl		\in1\().16b, {\in1\().16b}, v13.16b	/* ShiftRows */
	tbl		\in2\().16b, {\in2\().16b}, v13.16b	/* ShiftRows */
	tbl		\in3\().16b, {\in3\().16b}, v13.16b	/* ShiftRows */
250
	sub_bytes_4x	\in0, \in1, \in2, \in3
251
	subs		\i, \i, #1
252
	ld1		{v15.4s}, [\rkp], #16
253
	beq		2222f
254 255
	mix_columns_2x	\in0, \in1, \enc
	mix_columns_2x	\in2, \in3, \enc
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
	b		1111b
2222:	eor		\in0\().16b, \in0\().16b, v15.16b	/* ^round key */
	eor		\in1\().16b, \in1\().16b, v15.16b	/* ^round key */
	eor		\in2\().16b, \in2\().16b, v15.16b	/* ^round key */
	eor		\in3\().16b, \in3\().16b, v15.16b	/* ^round key */
	.endm

	.macro		encrypt_block2x, in0, in1, rounds, rk, rkp, i
	do_block_2x	1, \in0, \in1, \rounds, \rk, \rkp, \i
	.endm

	.macro		decrypt_block2x, in0, in1, rounds, rk, rkp, i
	do_block_2x	0, \in0, \in1, \rounds, \rk, \rkp, \i
	.endm

	.macro		encrypt_block4x, in0, in1, in2, in3, rounds, rk, rkp, i
	do_block_4x	1, \in0, \in1, \in2, \in3, \rounds, \rk, \rkp, \i
	.endm

	.macro		decrypt_block4x, in0, in1, in2, in3, rounds, rk, rkp, i
	do_block_4x	0, \in0, \in1, \in2, \in3, \rounds, \rk, \rkp, \i
	.endm

#include "aes-modes.S"

281
	.section	".rodata", "a"
282
	.align		6
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
.LForward_Sbox:
	.byte		0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
	.byte		0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
	.byte		0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
	.byte		0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
	.byte		0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
	.byte		0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
	.byte		0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
	.byte		0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
	.byte		0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
	.byte		0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
	.byte		0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
	.byte		0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
	.byte		0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
	.byte		0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
	.byte		0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
	.byte		0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
	.byte		0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
	.byte		0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
	.byte		0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
	.byte		0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
	.byte		0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
	.byte		0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
	.byte		0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
	.byte		0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
	.byte		0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
	.byte		0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
	.byte		0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
	.byte		0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
	.byte		0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
	.byte		0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
	.byte		0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
	.byte		0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16

.LReverse_Sbox:
	.byte		0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
	.byte		0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
	.byte		0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
	.byte		0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
	.byte		0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
	.byte		0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
	.byte		0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
	.byte		0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
	.byte		0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
	.byte		0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
	.byte		0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
	.byte		0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
	.byte		0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
	.byte		0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
	.byte		0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
	.byte		0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
	.byte		0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
	.byte		0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
	.byte		0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
	.byte		0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
	.byte		0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
	.byte		0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
	.byte		0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
	.byte		0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
	.byte		0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
	.byte		0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
	.byte		0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
	.byte		0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
	.byte		0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
	.byte		0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
	.byte		0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
	.byte		0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
350 351 352 353 354 355 356 357 358

.LForward_ShiftRows:
	.octa		0x0b06010c07020d08030e09040f0a0500

.LReverse_ShiftRows:
	.octa		0x0306090c0f0205080b0e0104070a0d00

.Lror32by8:
	.octa		0x0c0f0e0d080b0a090407060500030201