Home | History | Annotate | Line # | Download | only in arm
      1 #include "arm_asm.h"
      2 .text
      3 
      4 .type	_vpaes_consts,%object
      5 .align	7	// totally strategic alignment
      6 _vpaes_consts:
      7 .Lk_mc_forward:	//	mc_forward
      8 .quad	0x0407060500030201, 0x0C0F0E0D080B0A09
      9 .quad	0x080B0A0904070605, 0x000302010C0F0E0D
     10 .quad	0x0C0F0E0D080B0A09, 0x0407060500030201
     11 .quad	0x000302010C0F0E0D, 0x080B0A0904070605
     12 .Lk_mc_backward:	//	mc_backward
     13 .quad	0x0605040702010003, 0x0E0D0C0F0A09080B
     14 .quad	0x020100030E0D0C0F, 0x0A09080B06050407
     15 .quad	0x0E0D0C0F0A09080B, 0x0605040702010003
     16 .quad	0x0A09080B06050407, 0x020100030E0D0C0F
     17 .Lk_sr:	//	sr
     18 .quad	0x0706050403020100, 0x0F0E0D0C0B0A0908
     19 .quad	0x030E09040F0A0500, 0x0B06010C07020D08
     20 .quad	0x0F060D040B020900, 0x070E050C030A0108
     21 .quad	0x0B0E0104070A0D00, 0x0306090C0F020508
     22 
     23 //
     24 // "Hot" constants
     25 //
     26 .Lk_inv:	//	inv, inva
     27 .quad	0x0E05060F0D080180, 0x040703090A0B0C02
     28 .quad	0x01040A060F0B0780, 0x030D0E0C02050809
     29 .Lk_ipt:	//	input transform (lo, hi)
     30 .quad	0xC2B2E8985A2A7000, 0xCABAE09052227808
     31 .quad	0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
     32 .Lk_sbo:	//	sbou, sbot
     33 .quad	0xD0D26D176FBDC700, 0x15AABF7AC502A878
     34 .quad	0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
     35 .Lk_sb1:	//	sb1u, sb1t
     36 .quad	0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
     37 .quad	0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
     38 .Lk_sb2:	//	sb2u, sb2t
     39 .quad	0x69EB88400AE12900, 0xC2A163C8AB82234A
     40 .quad	0xE27A93C60B712400, 0x5EB7E955BC982FCD
     41 
     42 //
     43 //  Decryption stuff
     44 //
     45 .Lk_dipt:	//	decryption input transform
     46 .quad	0x0F505B040B545F00, 0x154A411E114E451A
     47 .quad	0x86E383E660056500, 0x12771772F491F194
     48 .Lk_dsbo:	//	decryption sbox final output
     49 .quad	0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
     50 .quad	0x12D7560F93441D00, 0xCA4B8159D8C58E9C
     51 .Lk_dsb9:	//	decryption sbox output *9*u, *9*t
     52 .quad	0x851C03539A86D600, 0xCAD51F504F994CC9
     53 .quad	0xC03B1789ECD74900, 0x725E2C9EB2FBA565
     54 .Lk_dsbd:	//	decryption sbox output *D*u, *D*t
     55 .quad	0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
     56 .quad	0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
     57 .Lk_dsbb:	//	decryption sbox output *B*u, *B*t
     58 .quad	0xD022649296B44200, 0x602646F6B0F2D404
     59 .quad	0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
     60 .Lk_dsbe:	//	decryption sbox output *E*u, *E*t
     61 .quad	0x46F2929626D4D000, 0x2242600464B4F6B0
     62 .quad	0x0C55A6CDFFAAC100, 0x9467F36B98593E32
     63 
     64 //
     65 //  Key schedule constants
     66 //
     67 .Lk_dksd:	//	decryption key schedule: invskew x*D
     68 .quad	0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
     69 .quad	0x41C277F4B5368300, 0x5FDC69EAAB289D1E
     70 .Lk_dksb:	//	decryption key schedule: invskew x*B
     71 .quad	0x9A4FCA1F8550D500, 0x03D653861CC94C99
     72 .quad	0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
     73 .Lk_dkse:	//	decryption key schedule: invskew x*E + 0x63
     74 .quad	0xD5031CCA1FC9D600, 0x53859A4C994F5086
     75 .quad	0xA23196054FDC7BE8, 0xCD5EF96A20B31487
     76 .Lk_dks9:	//	decryption key schedule: invskew x*9
     77 .quad	0xB6116FC87ED9A700, 0x4AED933482255BFC
     78 .quad	0x4576516227143300, 0x8BB89FACE9DAFDCE
     79 
     80 .Lk_rcon:	//	rcon
     81 .quad	0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
     82 
     83 .Lk_opt:	//	output transform
     84 .quad	0xFF9F4929D6B66000, 0xF7974121DEBE6808
     85 .quad	0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
     86 .Lk_deskew:	//	deskew tables: inverts the sbox's "skew"
     87 .quad	0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
     88 .quad	0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
     89 
     90 .byte	86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,65,82,77,118,56,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0
     91 .align	2
     92 .size	_vpaes_consts,.-_vpaes_consts
     93 .align	6
     94 ##
     95 ##  _aes_preheat
     96 ##
     97 ##  Fills register %r10 -> .aes_consts (so you can -fPIC)
     98 ##  and %xmm9-%xmm15 as specified below.
     99 ##
    100 .type	_vpaes_encrypt_preheat,%function
    101 .align	4
    102 _vpaes_encrypt_preheat:
    103 	adr	x10, .Lk_inv
    104 	movi	v17.16b, #0x0f
    105 	ld1	{v18.2d,v19.2d}, [x10],#32	// .Lk_inv
    106 	ld1	{v20.2d,v21.2d,v22.2d,v23.2d}, [x10],#64	// .Lk_ipt, .Lk_sbo
    107 	ld1	{v24.2d,v25.2d,v26.2d,v27.2d}, [x10]		// .Lk_sb1, .Lk_sb2
    108 	ret
    109 .size	_vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat
    110 
    111 ##
    112 ##  _aes_encrypt_core
    113 ##
    114 ##  AES-encrypt %xmm0.
    115 ##
    116 ##  Inputs:
    117 ##     %xmm0 = input
    118 ##     %xmm9-%xmm15 as in _vpaes_preheat
    119 ##    (%rdx) = scheduled keys
    120 ##
    121 ##  Output in %xmm0
    122 ##  Clobbers  %xmm1-%xmm5, %r9, %r10, %r11, %rax
    123 ##  Preserves %xmm6 - %xmm8 so you get some local vectors
    124 ##
    125 ##
    126 .type	_vpaes_encrypt_core,%function
    127 .align	4
    128 _vpaes_encrypt_core:
    129 	mov	x9, x2
    130 	ldr	w8, [x2,#240]			// pull rounds
    131 	adr	x11, .Lk_mc_forward+16
    132 						// vmovdqa	.Lk_ipt(%rip),	%xmm2	# iptlo
    133 	ld1	{v16.2d}, [x9], #16		// vmovdqu	(%r9),	%xmm5		# round0 key
    134 	and	v1.16b, v7.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1
    135 	ushr	v0.16b, v7.16b, #4		// vpsrlb	$4,	%xmm0,	%xmm0
    136 	tbl	v1.16b, {v20.16b}, v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm1
    137 						// vmovdqa	.Lk_ipt+16(%rip), %xmm3	# ipthi
    138 	tbl	v2.16b, {v21.16b}, v0.16b	// vpshufb	%xmm0,	%xmm3,	%xmm2
    139 	eor	v0.16b, v1.16b, v16.16b		// vpxor	%xmm5,	%xmm1,	%xmm0
    140 	eor	v0.16b, v0.16b, v2.16b		// vpxor	%xmm2,	%xmm0,	%xmm0
    141 	b	.Lenc_entry
    142 
    143 .align	4
    144 .Lenc_loop:
    145 	// middle of middle round
    146 	add	x10, x11, #0x40
    147 	tbl	v4.16b, {v25.16b}, v2.16b		// vpshufb	%xmm2,	%xmm13,	%xmm4	# 4 = sb1u
    148 	ld1	{v1.2d}, [x11], #16		// vmovdqa	-0x40(%r11,%r10), %xmm1	# .Lk_mc_forward[]
    149 	tbl	v0.16b, {v24.16b}, v3.16b		// vpshufb	%xmm3,	%xmm12,	%xmm0	# 0 = sb1t
    150 	eor	v4.16b, v4.16b, v16.16b		// vpxor	%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
    151 	tbl	v5.16b,	{v27.16b}, v2.16b		// vpshufb	%xmm2,	%xmm15,	%xmm5	# 4 = sb2u
    152 	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0	# 0 = A
    153 	tbl	v2.16b, {v26.16b}, v3.16b		// vpshufb	%xmm3,	%xmm14,	%xmm2	# 2 = sb2t
    154 	ld1	{v4.2d}, [x10]			// vmovdqa	(%r11,%r10), %xmm4	# .Lk_mc_backward[]
    155 	tbl	v3.16b, {v0.16b}, v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm3	# 0 = B
    156 	eor	v2.16b, v2.16b, v5.16b		// vpxor	%xmm5,	%xmm2,	%xmm2	# 2 = 2A
    157 	tbl	v0.16b, {v0.16b}, v4.16b	// vpshufb	%xmm4,	%xmm0,	%xmm0	# 3 = D
    158 	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3	# 0 = 2A+B
    159 	tbl	v4.16b, {v3.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm4	# 0 = 2B+C
    160 	eor	v0.16b, v0.16b, v3.16b		// vpxor	%xmm3,	%xmm0,	%xmm0	# 3 = 2A+B+D
    161 	and	x11, x11, #~(1<<6)		// and		$0x30,	%r11		# ... mod 4
    162 	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0, %xmm0	# 0 = 2A+3B+C+D
    163 	sub	w8, w8, #1			// nr--
    164 
    165 .Lenc_entry:
    166 	// top of round
    167 	and	v1.16b, v0.16b, v17.16b		// vpand	%xmm0,	%xmm9,	%xmm1   # 0 = k
    168 	ushr	v0.16b, v0.16b, #4		// vpsrlb	$4,	%xmm0,	%xmm0	# 1 = i
    169 	tbl	v5.16b, {v19.16b}, v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm5	# 2 = a/k
    170 	eor	v1.16b, v1.16b, v0.16b		// vpxor	%xmm0,	%xmm1,	%xmm1	# 0 = j
    171 	tbl	v3.16b, {v18.16b}, v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3  	# 3 = 1/i
    172 	tbl	v4.16b, {v18.16b}, v1.16b	// vpshufb	%xmm1, 	%xmm10,	%xmm4  	# 4 = 1/j
    173 	eor	v3.16b, v3.16b, v5.16b		// vpxor	%xmm5,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
    174 	eor	v4.16b, v4.16b, v5.16b		// vpxor	%xmm5,	%xmm4,	%xmm4  	# 4 = jak = 1/j + a/k
    175 	tbl	v2.16b, {v18.16b}, v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm2  	# 2 = 1/iak
    176 	tbl	v3.16b, {v18.16b}, v4.16b	// vpshufb	%xmm4,	%xmm10,	%xmm3	# 3 = 1/jak
    177 	eor	v2.16b, v2.16b, v1.16b		// vpxor	%xmm1,	%xmm2,	%xmm2  	# 2 = io
    178 	eor	v3.16b, v3.16b, v0.16b		// vpxor	%xmm0,	%xmm3,	%xmm3	# 3 = jo
    179 	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm5
    180 	cbnz	w8, .Lenc_loop
    181 
    182 	// middle of last round
    183 	add	x10, x11, #0x80
    184 						// vmovdqa	-0x60(%r10), %xmm4	# 3 : sbou	.Lk_sbo
    185 						// vmovdqa	-0x50(%r10), %xmm0	# 0 : sbot	.Lk_sbo+16
    186 	tbl	v4.16b, {v22.16b}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
    187 	ld1	{v1.2d}, [x10]			// vmovdqa	0x40(%r11,%r10), %xmm1	# .Lk_sr[]
    188 	tbl	v0.16b, {v23.16b}, v3.16b		// vpshufb	%xmm3,	%xmm0,	%xmm0	# 0 = sb1t
    189 	eor	v4.16b, v4.16b, v16.16b		// vpxor	%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
    190 	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0	# 0 = A
    191 	tbl	v0.16b, {v0.16b}, v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm0
    192 	ret
    193 .size	_vpaes_encrypt_core,.-_vpaes_encrypt_core
    194 
    195 .globl	vpaes_encrypt
    196 .type	vpaes_encrypt,%function
    197 .align	4
    198 vpaes_encrypt:
    199 .inst	0xd503233f			// paciasp
    200 	stp	x29,x30,[sp,#-16]!
    201 	add	x29,sp,#0
    202 
    203 	ld1	{v7.16b}, [x0]
    204 	bl	_vpaes_encrypt_preheat
    205 	bl	_vpaes_encrypt_core
    206 	st1	{v0.16b}, [x1]
    207 
    208 	ldp	x29,x30,[sp],#16
    209 .inst	0xd50323bf			// autiasp
    210 	ret
    211 .size	vpaes_encrypt,.-vpaes_encrypt
    212 
    213 .type	_vpaes_encrypt_2x,%function
    214 .align	4
    215 _vpaes_encrypt_2x:
    216 	mov	x9, x2
    217 	ldr	w8, [x2,#240]			// pull rounds
    218 	adr	x11, .Lk_mc_forward+16
    219 						// vmovdqa	.Lk_ipt(%rip),	%xmm2	# iptlo
    220 	ld1	{v16.2d}, [x9], #16		// vmovdqu	(%r9),	%xmm5		# round0 key
    221 	and	v1.16b,  v14.16b,  v17.16b	// vpand	%xmm9,	%xmm0,	%xmm1
    222 	ushr	v0.16b,  v14.16b,  #4		// vpsrlb	$4,	%xmm0,	%xmm0
    223 	and	v9.16b,  v15.16b,  v17.16b
    224 	ushr	v8.16b,  v15.16b,  #4
    225 	tbl	v1.16b,  {v20.16b}, v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm1
    226 	tbl	v9.16b,  {v20.16b}, v9.16b
    227 						// vmovdqa	.Lk_ipt+16(%rip), %xmm3	# ipthi
    228 	tbl	v2.16b,  {v21.16b}, v0.16b	// vpshufb	%xmm0,	%xmm3,	%xmm2
    229 	tbl	v10.16b, {v21.16b}, v8.16b
    230 	eor	v0.16b,  v1.16b,   v16.16b	// vpxor	%xmm5,	%xmm1,	%xmm0
    231 	eor	v8.16b,  v9.16b,   v16.16b
    232 	eor	v0.16b,  v0.16b,   v2.16b	// vpxor	%xmm2,	%xmm0,	%xmm0
    233 	eor	v8.16b,  v8.16b,   v10.16b
    234 	b	.Lenc_2x_entry
    235 
    236 .align	4
    237 .Lenc_2x_loop:
    238 	// middle of middle round
    239 	add	x10, x11, #0x40
    240 	tbl	v4.16b,  {v25.16b}, v2.16b	// vpshufb	%xmm2,	%xmm13,	%xmm4	# 4 = sb1u
    241 	tbl	v12.16b, {v25.16b}, v10.16b
    242 	ld1	{v1.2d}, [x11], #16		// vmovdqa	-0x40(%r11,%r10), %xmm1	# .Lk_mc_forward[]
    243 	tbl	v0.16b,  {v24.16b}, v3.16b	// vpshufb	%xmm3,	%xmm12,	%xmm0	# 0 = sb1t
    244 	tbl	v8.16b,  {v24.16b}, v11.16b
    245 	eor	v4.16b,  v4.16b,  v16.16b	// vpxor	%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
    246 	eor	v12.16b, v12.16b, v16.16b
    247 	tbl	v5.16b,	 {v27.16b}, v2.16b	// vpshufb	%xmm2,	%xmm15,	%xmm5	# 4 = sb2u
    248 	tbl	v13.16b, {v27.16b}, v10.16b
    249 	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0	# 0 = A
    250 	eor	v8.16b,  v8.16b,  v12.16b
    251 	tbl	v2.16b,  {v26.16b}, v3.16b	// vpshufb	%xmm3,	%xmm14,	%xmm2	# 2 = sb2t
    252 	tbl	v10.16b, {v26.16b}, v11.16b
    253 	ld1	{v4.2d}, [x10]			// vmovdqa	(%r11,%r10), %xmm4	# .Lk_mc_backward[]
    254 	tbl	v3.16b,  {v0.16b}, v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm3	# 0 = B
    255 	tbl	v11.16b, {v8.16b}, v1.16b
    256 	eor	v2.16b,  v2.16b,  v5.16b	// vpxor	%xmm5,	%xmm2,	%xmm2	# 2 = 2A
    257 	eor	v10.16b, v10.16b, v13.16b
    258 	tbl	v0.16b,  {v0.16b}, v4.16b	// vpshufb	%xmm4,	%xmm0,	%xmm0	# 3 = D
    259 	tbl	v8.16b,  {v8.16b}, v4.16b
    260 	eor	v3.16b,  v3.16b,  v2.16b	// vpxor	%xmm2,	%xmm3,	%xmm3	# 0 = 2A+B
    261 	eor	v11.16b, v11.16b, v10.16b
    262 	tbl	v4.16b,  {v3.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm4	# 0 = 2B+C
    263 	tbl	v12.16b, {v11.16b},v1.16b
    264 	eor	v0.16b,  v0.16b,  v3.16b	// vpxor	%xmm3,	%xmm0,	%xmm0	# 3 = 2A+B+D
    265 	eor	v8.16b,  v8.16b,  v11.16b
    266 	and	x11, x11, #~(1<<6)		// and		$0x30,	%r11		# ... mod 4
    267 	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0, %xmm0	# 0 = 2A+3B+C+D
    268 	eor	v8.16b,  v8.16b,  v12.16b
    269 	sub	w8, w8, #1			// nr--
    270 
    271 .Lenc_2x_entry:
    272 	// top of round
    273 	and	v1.16b,  v0.16b, v17.16b	// vpand	%xmm0,	%xmm9,	%xmm1   # 0 = k
    274 	ushr	v0.16b,  v0.16b, #4		// vpsrlb	$4,	%xmm0,	%xmm0	# 1 = i
    275 	and	v9.16b,  v8.16b, v17.16b
    276 	ushr	v8.16b,  v8.16b, #4
    277 	tbl	v5.16b,  {v19.16b},v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm5	# 2 = a/k
    278 	tbl	v13.16b, {v19.16b},v9.16b
    279 	eor	v1.16b,  v1.16b,  v0.16b	// vpxor	%xmm0,	%xmm1,	%xmm1	# 0 = j
    280 	eor	v9.16b,  v9.16b,  v8.16b
    281 	tbl	v3.16b,  {v18.16b},v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3  	# 3 = 1/i
    282 	tbl	v11.16b, {v18.16b},v8.16b
    283 	tbl	v4.16b,  {v18.16b},v1.16b	// vpshufb	%xmm1, 	%xmm10,	%xmm4  	# 4 = 1/j
    284 	tbl	v12.16b, {v18.16b},v9.16b
    285 	eor	v3.16b,  v3.16b,  v5.16b	// vpxor	%xmm5,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
    286 	eor	v11.16b, v11.16b, v13.16b
    287 	eor	v4.16b,  v4.16b,  v5.16b	// vpxor	%xmm5,	%xmm4,	%xmm4  	# 4 = jak = 1/j + a/k
    288 	eor	v12.16b, v12.16b, v13.16b
    289 	tbl	v2.16b,  {v18.16b},v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm2  	# 2 = 1/iak
    290 	tbl	v10.16b, {v18.16b},v11.16b
    291 	tbl	v3.16b,  {v18.16b},v4.16b	// vpshufb	%xmm4,	%xmm10,	%xmm3	# 3 = 1/jak
    292 	tbl	v11.16b, {v18.16b},v12.16b
    293 	eor	v2.16b,  v2.16b,  v1.16b	// vpxor	%xmm1,	%xmm2,	%xmm2  	# 2 = io
    294 	eor	v10.16b, v10.16b, v9.16b
    295 	eor	v3.16b,  v3.16b,  v0.16b	// vpxor	%xmm0,	%xmm3,	%xmm3	# 3 = jo
    296 	eor	v11.16b, v11.16b, v8.16b
    297 	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm5
    298 	cbnz	w8, .Lenc_2x_loop
    299 
    300 	// middle of last round
    301 	add	x10, x11, #0x80
    302 						// vmovdqa	-0x60(%r10), %xmm4	# 3 : sbou	.Lk_sbo
    303 						// vmovdqa	-0x50(%r10), %xmm0	# 0 : sbot	.Lk_sbo+16
    304 	tbl	v4.16b,  {v22.16b}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
    305 	tbl	v12.16b, {v22.16b}, v10.16b
    306 	ld1	{v1.2d}, [x10]			// vmovdqa	0x40(%r11,%r10), %xmm1	# .Lk_sr[]
    307 	tbl	v0.16b,  {v23.16b}, v3.16b	// vpshufb	%xmm3,	%xmm0,	%xmm0	# 0 = sb1t
    308 	tbl	v8.16b,  {v23.16b}, v11.16b
    309 	eor	v4.16b,  v4.16b,  v16.16b	// vpxor	%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
    310 	eor	v12.16b, v12.16b, v16.16b
    311 	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0	# 0 = A
    312 	eor	v8.16b,  v8.16b,  v12.16b
    313 	tbl	v0.16b,  {v0.16b},v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm0
    314 	tbl	v1.16b,  {v8.16b},v1.16b
    315 	ret
    316 .size	_vpaes_encrypt_2x,.-_vpaes_encrypt_2x
    317 
    318 .type	_vpaes_decrypt_preheat,%function
    319 .align	4
    320 _vpaes_decrypt_preheat:
    321 	adr	x10, .Lk_inv
    322 	movi	v17.16b, #0x0f
    323 	adr	x11, .Lk_dipt
    324 	ld1	{v18.2d,v19.2d}, [x10],#32	// .Lk_inv
    325 	ld1	{v20.2d,v21.2d,v22.2d,v23.2d}, [x11],#64	// .Lk_dipt, .Lk_dsbo
    326 	ld1	{v24.2d,v25.2d,v26.2d,v27.2d}, [x11],#64	// .Lk_dsb9, .Lk_dsbd
    327 	ld1	{v28.2d,v29.2d,v30.2d,v31.2d}, [x11]		// .Lk_dsbb, .Lk_dsbe
    328 	ret
    329 .size	_vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat
    330 
    331 ##
    332 ##  Decryption core
    333 ##
    334 ##  Same API as encryption core.
    335 ##
    336 .type	_vpaes_decrypt_core,%function
    337 .align	4
    338 _vpaes_decrypt_core:
    339 	mov	x9, x2
    340 	ldr	w8, [x2,#240]			// pull rounds
    341 
    342 						// vmovdqa	.Lk_dipt(%rip), %xmm2	# iptlo
    343 	lsl	x11, x8, #4			// mov	%rax,	%r11;	shl	$4, %r11
    344 	eor	x11, x11, #0x30			// xor		$0x30,	%r11
    345 	adr	x10, .Lk_sr
    346 	and	x11, x11, #0x30			// and		$0x30,	%r11
    347 	add	x11, x11, x10
    348 	adr	x10, .Lk_mc_forward+48
    349 
    350 	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm4		# round0 key
    351 	and	v1.16b, v7.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1
    352 	ushr	v0.16b, v7.16b, #4		// vpsrlb	$4,	%xmm0,	%xmm0
    353 	tbl	v2.16b, {v20.16b}, v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm2
    354 	ld1	{v5.2d}, [x10]			// vmovdqa	.Lk_mc_forward+48(%rip), %xmm5
    355 						// vmovdqa	.Lk_dipt+16(%rip), %xmm1 # ipthi
    356 	tbl	v0.16b, {v21.16b}, v0.16b	// vpshufb	%xmm0,	%xmm1,	%xmm0
    357 	eor	v2.16b, v2.16b, v16.16b		// vpxor	%xmm4,	%xmm2,	%xmm2
    358 	eor	v0.16b, v0.16b, v2.16b		// vpxor	%xmm2,	%xmm0,	%xmm0
    359 	b	.Ldec_entry
    360 
    361 .align	4
    362 .Ldec_loop:
    363 //
    364 //  Inverse mix columns
    365 //
    366 						// vmovdqa	-0x20(%r10),%xmm4		# 4 : sb9u
    367 						// vmovdqa	-0x10(%r10),%xmm1		# 0 : sb9t
    368 	tbl	v4.16b, {v24.16b}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sb9u
    369 	tbl	v1.16b, {v25.16b}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sb9t
    370 	eor	v0.16b, v4.16b, v16.16b		// vpxor	%xmm4,	%xmm0,	%xmm0
    371 						// vmovdqa	0x00(%r10),%xmm4		# 4 : sbdu
    372 	eor	v0.16b, v0.16b, v1.16b		// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
    373 						// vmovdqa	0x10(%r10),%xmm1		# 0 : sbdt
    374 
    375 	tbl	v4.16b, {v26.16b}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbdu
    376 	tbl	v0.16b, {v0.16b}, v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
    377 	tbl	v1.16b, {v27.16b}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbdt
    378 	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
    379 						// vmovdqa	0x20(%r10),	%xmm4		# 4 : sbbu
    380 	eor	v0.16b, v0.16b, v1.16b		// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
    381 						// vmovdqa	0x30(%r10),	%xmm1		# 0 : sbbt
    382 
    383 	tbl	v4.16b, {v28.16b}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbbu
    384 	tbl	v0.16b, {v0.16b}, v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
    385 	tbl	v1.16b, {v29.16b}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbbt
    386 	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
    387 						// vmovdqa	0x40(%r10),	%xmm4		# 4 : sbeu
    388 	eor	v0.16b, v0.16b, v1.16b		// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
    389 						// vmovdqa	0x50(%r10),	%xmm1		# 0 : sbet
    390 
    391 	tbl	v4.16b, {v30.16b}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbeu
    392 	tbl	v0.16b, {v0.16b}, v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
    393 	tbl	v1.16b, {v31.16b}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbet
    394 	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
    395 	ext	v5.16b, v5.16b, v5.16b, #12	// vpalignr $12,	%xmm5,	%xmm5,	%xmm5
    396 	eor	v0.16b, v0.16b, v1.16b		// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
    397 	sub	w8, w8, #1			// sub		$1,%rax			# nr--
    398 
    399 .Ldec_entry:
    400 	// top of round
    401 	and	v1.16b, v0.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1	# 0 = k
    402 	ushr	v0.16b, v0.16b, #4		// vpsrlb	$4,	%xmm0,	%xmm0	# 1 = i
    403 	tbl	v2.16b, {v19.16b}, v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm2	# 2 = a/k
    404 	eor	v1.16b,	v1.16b, v0.16b		// vpxor	%xmm0,	%xmm1,	%xmm1	# 0 = j
    405 	tbl	v3.16b, {v18.16b}, v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3	# 3 = 1/i
    406 	tbl	v4.16b, {v18.16b}, v1.16b	// vpshufb	%xmm1,	%xmm10,	%xmm4	# 4 = 1/j
    407 	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
    408 	eor	v4.16b, v4.16b, v2.16b		// vpxor	%xmm2, 	%xmm4,	%xmm4	# 4 = jak = 1/j + a/k
    409 	tbl	v2.16b, {v18.16b}, v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm2	# 2 = 1/iak
    410 	tbl	v3.16b, {v18.16b}, v4.16b	// vpshufb	%xmm4,  %xmm10,	%xmm3	# 3 = 1/jak
    411 	eor	v2.16b, v2.16b, v1.16b		// vpxor	%xmm1,	%xmm2,	%xmm2	# 2 = io
    412 	eor	v3.16b, v3.16b, v0.16b		// vpxor	%xmm0,  %xmm3,	%xmm3	# 3 = jo
    413 	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm0
    414 	cbnz	w8, .Ldec_loop
    415 
    416 	// middle of last round
    417 						// vmovdqa	0x60(%r10),	%xmm4	# 3 : sbou
    418 	tbl	v4.16b, {v22.16b}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
    419 						// vmovdqa	0x70(%r10),	%xmm1	# 0 : sbot
    420 	ld1	{v2.2d}, [x11]			// vmovdqa	-0x160(%r11),	%xmm2	# .Lk_sr-.Lk_dsbd=-0x160
    421 	tbl	v1.16b, {v23.16b}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1	# 0 = sb1t
    422 	eor	v4.16b, v4.16b, v16.16b		// vpxor	%xmm0,	%xmm4,	%xmm4	# 4 = sb1u + k
    423 	eor	v0.16b, v1.16b, v4.16b		// vpxor	%xmm4,	%xmm1,	%xmm0	# 0 = A
    424 	tbl	v0.16b, {v0.16b}, v2.16b	// vpshufb	%xmm2,	%xmm0,	%xmm0
    425 	ret
    426 .size	_vpaes_decrypt_core,.-_vpaes_decrypt_core
    427 
    428 .globl	vpaes_decrypt
    429 .type	vpaes_decrypt,%function
    430 .align	4
    431 vpaes_decrypt:
    432 .inst	0xd503233f			// paciasp
    433 	stp	x29,x30,[sp,#-16]!
    434 	add	x29,sp,#0
    435 
    436 	ld1	{v7.16b}, [x0]
    437 	bl	_vpaes_decrypt_preheat
    438 	bl	_vpaes_decrypt_core
    439 	st1	{v0.16b}, [x1]
    440 
    441 	ldp	x29,x30,[sp],#16
    442 .inst	0xd50323bf			// autiasp
    443 	ret
    444 .size	vpaes_decrypt,.-vpaes_decrypt
    445 
    446 // v14-v15 input, v0-v1 output
    447 .type	_vpaes_decrypt_2x,%function
    448 .align	4
    449 _vpaes_decrypt_2x:
    450 	mov	x9, x2
    451 	ldr	w8, [x2,#240]			// pull rounds
    452 
    453 						// vmovdqa	.Lk_dipt(%rip), %xmm2	# iptlo
    454 	lsl	x11, x8, #4			// mov	%rax,	%r11;	shl	$4, %r11
    455 	eor	x11, x11, #0x30			// xor		$0x30,	%r11
    456 	adr	x10, .Lk_sr
    457 	and	x11, x11, #0x30			// and		$0x30,	%r11
    458 	add	x11, x11, x10
    459 	adr	x10, .Lk_mc_forward+48
    460 
    461 	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm4		# round0 key
    462 	and	v1.16b,  v14.16b, v17.16b	// vpand	%xmm9,	%xmm0,	%xmm1
    463 	ushr	v0.16b,  v14.16b, #4		// vpsrlb	$4,	%xmm0,	%xmm0
    464 	and	v9.16b,  v15.16b, v17.16b
    465 	ushr	v8.16b,  v15.16b, #4
    466 	tbl	v2.16b,  {v20.16b},v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm2
    467 	tbl	v10.16b, {v20.16b},v9.16b
    468 	ld1	{v5.2d}, [x10]			// vmovdqa	.Lk_mc_forward+48(%rip), %xmm5
    469 						// vmovdqa	.Lk_dipt+16(%rip), %xmm1 # ipthi
    470 	tbl	v0.16b,  {v21.16b},v0.16b	// vpshufb	%xmm0,	%xmm1,	%xmm0
    471 	tbl	v8.16b,  {v21.16b},v8.16b
    472 	eor	v2.16b,  v2.16b,  v16.16b	// vpxor	%xmm4,	%xmm2,	%xmm2
    473 	eor	v10.16b, v10.16b, v16.16b
    474 	eor	v0.16b,  v0.16b,  v2.16b	// vpxor	%xmm2,	%xmm0,	%xmm0
    475 	eor	v8.16b,  v8.16b,  v10.16b
    476 	b	.Ldec_2x_entry
    477 
    478 .align	4
    479 .Ldec_2x_loop:
    480 //
    481 //  Inverse mix columns
    482 //
    483 						// vmovdqa	-0x20(%r10),%xmm4		# 4 : sb9u
    484 						// vmovdqa	-0x10(%r10),%xmm1		# 0 : sb9t
    485 	tbl	v4.16b,  {v24.16b}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sb9u
    486 	tbl	v12.16b, {v24.16b}, v10.16b
    487 	tbl	v1.16b,  {v25.16b}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sb9t
    488 	tbl	v9.16b,  {v25.16b}, v11.16b
    489 	eor	v0.16b,  v4.16b,  v16.16b	// vpxor	%xmm4,	%xmm0,	%xmm0
    490 	eor	v8.16b,  v12.16b, v16.16b
    491 						// vmovdqa	0x00(%r10),%xmm4		# 4 : sbdu
    492 	eor	v0.16b,  v0.16b,  v1.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
    493 	eor	v8.16b,  v8.16b,  v9.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
    494 						// vmovdqa	0x10(%r10),%xmm1		# 0 : sbdt
    495 
    496 	tbl	v4.16b,  {v26.16b}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbdu
    497 	tbl	v12.16b, {v26.16b}, v10.16b
    498 	tbl	v0.16b,  {v0.16b},v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
    499 	tbl	v8.16b,  {v8.16b},v5.16b
    500 	tbl	v1.16b,  {v27.16b}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbdt
    501 	tbl	v9.16b,  {v27.16b}, v11.16b
    502 	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
    503 	eor	v8.16b,  v8.16b,  v12.16b
    504 						// vmovdqa	0x20(%r10),	%xmm4		# 4 : sbbu
    505 	eor	v0.16b,  v0.16b,  v1.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
    506 	eor	v8.16b,  v8.16b,  v9.16b
    507 						// vmovdqa	0x30(%r10),	%xmm1		# 0 : sbbt
    508 
    509 	tbl	v4.16b,  {v28.16b}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbbu
    510 	tbl	v12.16b, {v28.16b}, v10.16b
    511 	tbl	v0.16b,  {v0.16b},v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
    512 	tbl	v8.16b,  {v8.16b},v5.16b
    513 	tbl	v1.16b,  {v29.16b}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbbt
    514 	tbl	v9.16b,  {v29.16b}, v11.16b
    515 	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
    516 	eor	v8.16b,  v8.16b,  v12.16b
    517 						// vmovdqa	0x40(%r10),	%xmm4		# 4 : sbeu
    518 	eor	v0.16b,  v0.16b,  v1.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
    519 	eor	v8.16b,  v8.16b,  v9.16b
    520 						// vmovdqa	0x50(%r10),	%xmm1		# 0 : sbet
    521 
    522 	tbl	v4.16b,  {v30.16b}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbeu
    523 	tbl	v12.16b, {v30.16b}, v10.16b
    524 	tbl	v0.16b,  {v0.16b},v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
    525 	tbl	v8.16b,  {v8.16b},v5.16b
    526 	tbl	v1.16b,  {v31.16b}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbet
    527 	tbl	v9.16b,  {v31.16b}, v11.16b
    528 	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
    529 	eor	v8.16b,  v8.16b,  v12.16b
    530 	ext	v5.16b,  v5.16b,  v5.16b, #12	// vpalignr $12,	%xmm5,	%xmm5,	%xmm5
    531 	eor	v0.16b,  v0.16b,  v1.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
    532 	eor	v8.16b,  v8.16b,  v9.16b
    533 	sub	w8, w8, #1			// sub		$1,%rax			# nr--
    534 
    535 .Ldec_2x_entry:
    536 	// top of round
    537 	and	v1.16b,  v0.16b,  v17.16b	// vpand	%xmm9,	%xmm0,	%xmm1	# 0 = k
    538 	ushr	v0.16b,  v0.16b,  #4		// vpsrlb	$4,	%xmm0,	%xmm0	# 1 = i
    539 	and	v9.16b,  v8.16b,  v17.16b
    540 	ushr	v8.16b,  v8.16b,  #4
    541 	tbl	v2.16b,  {v19.16b},v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm2	# 2 = a/k
    542 	tbl	v10.16b, {v19.16b},v9.16b
    543 	eor	v1.16b,	 v1.16b,  v0.16b	// vpxor	%xmm0,	%xmm1,	%xmm1	# 0 = j
    544 	eor	v9.16b,	 v9.16b,  v8.16b
    545 	tbl	v3.16b,  {v18.16b},v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3	# 3 = 1/i
    546 	tbl	v11.16b, {v18.16b},v8.16b
    547 	tbl	v4.16b,  {v18.16b},v1.16b	// vpshufb	%xmm1,	%xmm10,	%xmm4	# 4 = 1/j
    548 	tbl	v12.16b, {v18.16b},v9.16b
    549 	eor	v3.16b,  v3.16b,  v2.16b	// vpxor	%xmm2,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
    550 	eor	v11.16b, v11.16b, v10.16b
    551 	eor	v4.16b,  v4.16b,  v2.16b	// vpxor	%xmm2, 	%xmm4,	%xmm4	# 4 = jak = 1/j + a/k
    552 	eor	v12.16b, v12.16b, v10.16b
    553 	tbl	v2.16b,  {v18.16b},v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm2	# 2 = 1/iak
    554 	tbl	v10.16b, {v18.16b},v11.16b
    555 	tbl	v3.16b,  {v18.16b},v4.16b	// vpshufb	%xmm4,  %xmm10,	%xmm3	# 3 = 1/jak
    556 	tbl	v11.16b, {v18.16b},v12.16b
    557 	eor	v2.16b,  v2.16b,  v1.16b	// vpxor	%xmm1,	%xmm2,	%xmm2	# 2 = io
    558 	eor	v10.16b, v10.16b, v9.16b
    559 	eor	v3.16b,  v3.16b,  v0.16b	// vpxor	%xmm0,  %xmm3,	%xmm3	# 3 = jo
    560 	eor	v11.16b, v11.16b, v8.16b
    561 	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm0
    562 	cbnz	w8, .Ldec_2x_loop
    563 
    564 	// middle of last round
    565 						// vmovdqa	0x60(%r10),	%xmm4	# 3 : sbou
    566 	tbl	v4.16b,  {v22.16b}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
    567 	tbl	v12.16b, {v22.16b}, v10.16b
    568 						// vmovdqa	0x70(%r10),	%xmm1	# 0 : sbot
    569 	tbl	v1.16b,  {v23.16b}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1	# 0 = sb1t
    570 	tbl	v9.16b,  {v23.16b}, v11.16b
    571 	ld1	{v2.2d}, [x11]			// vmovdqa	-0x160(%r11),	%xmm2	# .Lk_sr-.Lk_dsbd=-0x160
    572 	eor	v4.16b,  v4.16b,  v16.16b	// vpxor	%xmm0,	%xmm4,	%xmm4	# 4 = sb1u + k
    573 	eor	v12.16b, v12.16b, v16.16b
    574 	eor	v0.16b,  v1.16b,  v4.16b	// vpxor	%xmm4,	%xmm1,	%xmm0	# 0 = A
    575 	eor	v8.16b,  v9.16b,  v12.16b
    576 	tbl	v0.16b,  {v0.16b},v2.16b	// vpshufb	%xmm2,	%xmm0,	%xmm0
    577 	tbl	v1.16b,  {v8.16b},v2.16b
    578 	ret
    579 .size	_vpaes_decrypt_2x,.-_vpaes_decrypt_2x
    580 ########################################################
    581 ##                                                    ##
    582 ##                  AES key schedule                  ##
    583 ##                                                    ##
    584 ########################################################
    585 .type	_vpaes_key_preheat,%function
    586 .align	4
    587 _vpaes_key_preheat:
    588 	adr	x10, .Lk_inv
    589 	movi	v16.16b, #0x5b			// .Lk_s63
    590 	adr	x11, .Lk_sb1
    591 	movi	v17.16b, #0x0f			// .Lk_s0F
    592 	ld1	{v18.2d,v19.2d,v20.2d,v21.2d}, [x10]		// .Lk_inv, .Lk_ipt
    593 	adr	x10, .Lk_dksd
    594 	ld1	{v22.2d,v23.2d}, [x11]		// .Lk_sb1
    595 	adr	x11, .Lk_mc_forward
    596 	ld1	{v24.2d,v25.2d,v26.2d,v27.2d}, [x10],#64	// .Lk_dksd, .Lk_dksb
    597 	ld1	{v28.2d,v29.2d,v30.2d,v31.2d}, [x10],#64	// .Lk_dkse, .Lk_dks9
    598 	ld1	{v8.2d}, [x10]			// .Lk_rcon
    599 	ld1	{v9.2d}, [x11]			// .Lk_mc_forward[0]
    600 	ret
    601 .size	_vpaes_key_preheat,.-_vpaes_key_preheat
    602 
    603 .type	_vpaes_schedule_core,%function
    604 .align	4
    605 _vpaes_schedule_core:
    606 .inst	0xd503233f			// paciasp
    607 	stp	x29, x30, [sp,#-16]!
    608 	add	x29,sp,#0
    609 
    610 	bl	_vpaes_key_preheat		// load the tables
    611 
    612 	ld1	{v0.16b}, [x0],#16		// vmovdqu	(%rdi),	%xmm0		# load key (unaligned)
    613 
    614 	// input transform
    615 	mov	v3.16b, v0.16b			// vmovdqa	%xmm0,	%xmm3
    616 	bl	_vpaes_schedule_transform
    617 	mov	v7.16b, v0.16b			// vmovdqa	%xmm0,	%xmm7
    618 
    619 	adr	x10, .Lk_sr			// lea	.Lk_sr(%rip),%r10
    620 	add	x8, x8, x10
    621 	cbnz	w3, .Lschedule_am_decrypting
    622 
    623 	// encrypting, output zeroth round key after transform
    624 	st1	{v0.2d}, [x2]			// vmovdqu	%xmm0,	(%rdx)
    625 	b	.Lschedule_go
    626 
    627 .Lschedule_am_decrypting:
    628 	// decrypting, output zeroth round key after shiftrows
    629 	ld1	{v1.2d}, [x8]			// vmovdqa	(%r8,%r10),	%xmm1
    630 	tbl	v3.16b, {v3.16b}, v1.16b	// vpshufb  %xmm1,	%xmm3,	%xmm3
    631 	st1	{v3.2d}, [x2]			// vmovdqu	%xmm3,	(%rdx)
    632 	eor	x8, x8, #0x30			// xor	$0x30, %r8
    633 
    634 .Lschedule_go:
    635 	cmp	w1, #192			// cmp	$192,	%esi
    636 	b.hi	.Lschedule_256
    637 	b.eq	.Lschedule_192
    638 	// 128: fall though
    639 
    640 ##
    641 ##  .schedule_128
    642 ##
    643 ##  128-bit specific part of key schedule.
    644 ##
    645 ##  This schedule is really simple, because all its parts
    646 ##  are accomplished by the subroutines.
    647 ##
    648 .Lschedule_128:
    649 	mov	x0, #10			// mov	$10, %esi
    650 
    651 .Loop_schedule_128:
    652 	sub	x0, x0, #1			// dec	%esi
    653 	bl	_vpaes_schedule_round
    654 	cbz	x0, .Lschedule_mangle_last
    655 	bl	_vpaes_schedule_mangle		// write output
    656 	b	.Loop_schedule_128
    657 
    658 ##
    659 ##  .aes_schedule_192
    660 ##
    661 ##  192-bit specific part of key schedule.
    662 ##
    663 ##  The main body of this schedule is the same as the 128-bit
    664 ##  schedule, but with more smearing.  The long, high side is
    665 ##  stored in %xmm7 as before, and the short, low side is in
    666 ##  the high bits of %xmm6.
    667 ##
    668 ##  This schedule is somewhat nastier, however, because each
    669 ##  round produces 192 bits of key material, or 1.5 round keys.
    670 ##  Therefore, on each cycle we do 2 rounds and produce 3 round
    671 ##  keys.
    672 ##
    673 .align	4
    674 .Lschedule_192:
    675 	sub	x0, x0, #8
    676 	ld1	{v0.16b}, [x0]		// vmovdqu	8(%rdi),%xmm0		# load key part 2 (very unaligned)
    677 	bl	_vpaes_schedule_transform	// input transform
    678 	mov	v6.16b, v0.16b			// vmovdqa	%xmm0,	%xmm6		# save short part
    679 	eor	v4.16b, v4.16b, v4.16b		// vpxor	%xmm4,	%xmm4, %xmm4	# clear 4
    680 	ins	v6.d[0], v4.d[0]		// vmovhlps	%xmm4,	%xmm6,	%xmm6		# clobber low side with zeros
    681 	mov	x0, #4			// mov	$4,	%esi
    682 
    683 .Loop_schedule_192:
    684 	sub	x0, x0, #1			// dec	%esi
    685 	bl	_vpaes_schedule_round
    686 	ext	v0.16b, v6.16b, v0.16b, #8	// vpalignr	$8,%xmm6,%xmm0,%xmm0
    687 	bl	_vpaes_schedule_mangle		// save key n
    688 	bl	_vpaes_schedule_192_smear
    689 	bl	_vpaes_schedule_mangle		// save key n+1
    690 	bl	_vpaes_schedule_round
    691 	cbz	x0, .Lschedule_mangle_last
    692 	bl	_vpaes_schedule_mangle		// save key n+2
    693 	bl	_vpaes_schedule_192_smear
    694 	b	.Loop_schedule_192
    695 
    696 ##
    697 ##  .aes_schedule_256
    698 ##
    699 ##  256-bit specific part of key schedule.
    700 ##
    701 ##  The structure here is very similar to the 128-bit
    702 ##  schedule, but with an additional "low side" in
    703 ##  %xmm6.  The low side's rounds are the same as the
    704 ##  high side's, except no rcon and no rotation.
    705 ##
    706 .align	4
    707 .Lschedule_256:
    708 	ld1	{v0.16b}, [x0]		// vmovdqu	16(%rdi),%xmm0		# load key part 2 (unaligned)
    709 	bl	_vpaes_schedule_transform	// input transform
    710 	mov	x0, #7			// mov	$7, %esi
    711 
    712 .Loop_schedule_256:
    713 	sub	x0, x0, #1			// dec	%esi
    714 	bl	_vpaes_schedule_mangle		// output low result
    715 	mov	v6.16b, v0.16b			// vmovdqa	%xmm0,	%xmm6		# save cur_lo in xmm6
    716 
    717 	// high round
    718 	bl	_vpaes_schedule_round
    719 	cbz	x0, .Lschedule_mangle_last
    720 	bl	_vpaes_schedule_mangle
    721 
    722 	// low round. swap xmm7 and xmm6
    723 	dup	v0.4s, v0.s[3]			// vpshufd	$0xFF,	%xmm0,	%xmm0
    724 	movi	v4.16b, #0
    725 	mov	v5.16b, v7.16b			// vmovdqa	%xmm7,	%xmm5
    726 	mov	v7.16b, v6.16b			// vmovdqa	%xmm6,	%xmm7
    727 	bl	_vpaes_schedule_low_round
    728 	mov	v7.16b, v5.16b			// vmovdqa	%xmm5,	%xmm7
    729 
    730 	b	.Loop_schedule_256
    731 
    732 ##
    733 ##  .aes_schedule_mangle_last
    734 ##
    735 ##  Mangler for last round of key schedule
    736 ##  Mangles %xmm0
    737 ##    when encrypting, outputs out(%xmm0) ^ 63
    738 ##    when decrypting, outputs unskew(%xmm0)
    739 ##
    740 ##  Always called right before return... jumps to cleanup and exits
    741 ##
    742 .align	4
    743 .Lschedule_mangle_last:
    744 	// schedule last round key from xmm0
    745 	adr	x11, .Lk_deskew			// lea	.Lk_deskew(%rip),%r11	# prepare to deskew
    746 	cbnz	w3, .Lschedule_mangle_last_dec
    747 
    748 	// encrypting
    749 	ld1	{v1.2d}, [x8]			// vmovdqa	(%r8,%r10),%xmm1
    750 	adr	x11, .Lk_opt			// lea	.Lk_opt(%rip),	%r11		# prepare to output transform
    751 	add	x2, x2, #32			// add	$32,	%rdx
    752 	tbl	v0.16b, {v0.16b}, v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm0		# output permute
    753 
    754 .Lschedule_mangle_last_dec:
    755 	ld1	{v20.2d,v21.2d}, [x11]		// reload constants
    756 	sub	x2, x2, #16			// add	$-16,	%rdx
    757 	eor	v0.16b, v0.16b, v16.16b		// vpxor	.Lk_s63(%rip),	%xmm0,	%xmm0
    758 	bl	_vpaes_schedule_transform	// output transform
    759 	st1	{v0.2d}, [x2]			// vmovdqu	%xmm0,	(%rdx)		# save last key
    760 
    761 	// cleanup
    762 	eor	v0.16b, v0.16b, v0.16b		// vpxor	%xmm0,	%xmm0,	%xmm0
    763 	eor	v1.16b, v1.16b, v1.16b		// vpxor	%xmm1,	%xmm1,	%xmm1
    764 	eor	v2.16b, v2.16b, v2.16b		// vpxor	%xmm2,	%xmm2,	%xmm2
    765 	eor	v3.16b, v3.16b, v3.16b		// vpxor	%xmm3,	%xmm3,	%xmm3
    766 	eor	v4.16b, v4.16b, v4.16b		// vpxor	%xmm4,	%xmm4,	%xmm4
    767 	eor	v5.16b, v5.16b, v5.16b		// vpxor	%xmm5,	%xmm5,	%xmm5
    768 	eor	v6.16b, v6.16b, v6.16b		// vpxor	%xmm6,	%xmm6,	%xmm6
    769 	eor	v7.16b, v7.16b, v7.16b		// vpxor	%xmm7,	%xmm7,	%xmm7
    770 	ldp	x29, x30, [sp],#16
    771 .inst	0xd50323bf			// autiasp
    772 	ret
    773 .size	_vpaes_schedule_core,.-_vpaes_schedule_core
    774 
    775 ##
    776 ##  .aes_schedule_192_smear
    777 ##
    778 ##  Smear the short, low side in the 192-bit key schedule.
    779 ##
    780 ##  Inputs:
    781 ##    %xmm7: high side, b  a  x  y
    782 ##    %xmm6:  low side, d  c  0  0
    783 ##    %xmm13: 0
    784 ##
    785 ##  Outputs:
    786 ##    %xmm6: b+c+d  b+c  0  0
    787 ##    %xmm0: b+c+d  b+c  b  a
    788 ##
    789 .type	_vpaes_schedule_192_smear,%function
    790 .align	4
    791 _vpaes_schedule_192_smear:
    792 	movi	v1.16b, #0
    793 	dup	v0.4s, v7.s[3]
    794 	ins	v1.s[3], v6.s[2]	// vpshufd	$0x80,	%xmm6,	%xmm1	# d c 0 0 -> c 0 0 0
    795 	ins	v0.s[0], v7.s[2]	// vpshufd	$0xFE,	%xmm7,	%xmm0	# b a _ _ -> b b b a
    796 	eor	v6.16b, v6.16b, v1.16b	// vpxor	%xmm1,	%xmm6,	%xmm6	# -> c+d c 0 0
    797 	eor	v1.16b, v1.16b, v1.16b	// vpxor	%xmm1,	%xmm1,	%xmm1
    798 	eor	v6.16b, v6.16b, v0.16b	// vpxor	%xmm0,	%xmm6,	%xmm6	# -> b+c+d b+c b a
    799 	mov	v0.16b, v6.16b		// vmovdqa	%xmm6,	%xmm0
    800 	ins	v6.d[0], v1.d[0]	// vmovhlps	%xmm1,	%xmm6,	%xmm6	# clobber low side with zeros
    801 	ret
    802 .size	_vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
    803 
    804 ##
    805 ##  .aes_schedule_round
    806 ##
    807 ##  Runs one main round of the key schedule on %xmm0, %xmm7
    808 ##
    809 ##  Specifically, runs subbytes on the high dword of %xmm0
    810 ##  then rotates it by one byte and xors into the low dword of
    811 ##  %xmm7.
    812 ##
    813 ##  Adds rcon from low byte of %xmm8, then rotates %xmm8 for
    814 ##  next rcon.
    815 ##
    816 ##  Smears the dwords of %xmm7 by xoring the low into the
    817 ##  second low, result into third, result into highest.
    818 ##
    819 ##  Returns results in %xmm7 = %xmm0.
    820 ##  Clobbers %xmm1-%xmm4, %r11.
    821 ##
    822 .type	_vpaes_schedule_round,%function
    823 .align	4
    824 _vpaes_schedule_round:
    825 	// extract rcon from xmm8
    826 	movi	v4.16b, #0			// vpxor	%xmm4,	%xmm4,	%xmm4
    827 	ext	v1.16b, v8.16b, v4.16b, #15	// vpalignr	$15,	%xmm8,	%xmm4,	%xmm1
    828 	ext	v8.16b, v8.16b, v8.16b, #15	// vpalignr	$15,	%xmm8,	%xmm8,	%xmm8
    829 	eor	v7.16b, v7.16b, v1.16b		// vpxor	%xmm1,	%xmm7,	%xmm7
    830 
    831 	// rotate
    832 	dup	v0.4s, v0.s[3]			// vpshufd	$0xFF,	%xmm0,	%xmm0
    833 	ext	v0.16b, v0.16b, v0.16b, #1	// vpalignr	$1,	%xmm0,	%xmm0,	%xmm0
    834 
    835 	// fall through...
    836 
    837 	// low round: same as high round, but no rotation and no rcon.
    838 _vpaes_schedule_low_round:
    839 	// smear xmm7
    840 	ext	v1.16b, v4.16b, v7.16b, #12	// vpslldq	$4,	%xmm7,	%xmm1
    841 	eor	v7.16b, v7.16b, v1.16b		// vpxor	%xmm1,	%xmm7,	%xmm7
    842 	ext	v4.16b, v4.16b, v7.16b, #8	// vpslldq	$8,	%xmm7,	%xmm4
    843 
    844 	// subbytes
    845 	and	v1.16b, v0.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1		# 0 = k
    846 	ushr	v0.16b, v0.16b, #4		// vpsrlb	$4,	%xmm0,	%xmm0		# 1 = i
    847 	eor	v7.16b, v7.16b, v4.16b		// vpxor	%xmm4,	%xmm7,	%xmm7
    848 	tbl	v2.16b, {v19.16b}, v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm2		# 2 = a/k
    849 	eor	v1.16b, v1.16b, v0.16b		// vpxor	%xmm0,	%xmm1,	%xmm1		# 0 = j
    850 	tbl	v3.16b, {v18.16b}, v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3		# 3 = 1/i
    851 	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3		# 3 = iak = 1/i + a/k
    852 	tbl	v4.16b, {v18.16b}, v1.16b	// vpshufb	%xmm1,	%xmm10,	%xmm4		# 4 = 1/j
    853 	eor	v7.16b, v7.16b, v16.16b		// vpxor	.Lk_s63(%rip),	%xmm7,	%xmm7
    854 	tbl	v3.16b, {v18.16b}, v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm3		# 2 = 1/iak
    855 	eor	v4.16b, v4.16b, v2.16b		// vpxor	%xmm2,	%xmm4,	%xmm4		# 4 = jak = 1/j + a/k
    856 	tbl	v2.16b, {v18.16b}, v4.16b	// vpshufb	%xmm4,	%xmm10,	%xmm2		# 3 = 1/jak
    857 	eor	v3.16b, v3.16b, v1.16b		// vpxor	%xmm1,	%xmm3,	%xmm3		# 2 = io
    858 	eor	v2.16b, v2.16b, v0.16b		// vpxor	%xmm0,	%xmm2,	%xmm2		# 3 = jo
    859 	tbl	v4.16b, {v23.16b}, v3.16b	// vpshufb	%xmm3,	%xmm13,	%xmm4		# 4 = sbou
    860 	tbl	v1.16b, {v22.16b}, v2.16b	// vpshufb	%xmm2,	%xmm12,	%xmm1		# 0 = sb1t
    861 	eor	v1.16b, v1.16b, v4.16b		// vpxor	%xmm4,	%xmm1,	%xmm1		# 0 = sbox output
    862 
    863 	// add in smeared stuff
    864 	eor	v0.16b, v1.16b, v7.16b		// vpxor	%xmm7,	%xmm1,	%xmm0
    865 	eor	v7.16b, v1.16b, v7.16b		// vmovdqa	%xmm0,	%xmm7
    866 	ret
    867 .size	_vpaes_schedule_round,.-_vpaes_schedule_round
    868 
    869 ##
    870 ##  .aes_schedule_transform
    871 ##
    872 ##  Linear-transform %xmm0 according to tables at (%r11)
    873 ##
    874 ##  Requires that %xmm9 = 0x0F0F... as in preheat
    875 ##  Output in %xmm0
    876 ##  Clobbers %xmm1, %xmm2
    877 ##
    878 .type	_vpaes_schedule_transform,%function
    879 .align	4
    880 _vpaes_schedule_transform:
    881 	and	v1.16b, v0.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1
    882 	ushr	v0.16b, v0.16b, #4		// vpsrlb	$4,	%xmm0,	%xmm0
    883 						// vmovdqa	(%r11),	%xmm2 	# lo
    884 	tbl	v2.16b, {v20.16b}, v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm2
    885 						// vmovdqa	16(%r11),	%xmm1 # hi
    886 	tbl	v0.16b, {v21.16b}, v0.16b	// vpshufb	%xmm0,	%xmm1,	%xmm0
    887 	eor	v0.16b, v0.16b, v2.16b		// vpxor	%xmm2,	%xmm0,	%xmm0
    888 	ret
    889 .size	_vpaes_schedule_transform,.-_vpaes_schedule_transform
    890 
    891 ##
    892 ##  .aes_schedule_mangle
    893 ##
    894 ##  Mangle xmm0 from (basis-transformed) standard version
    895 ##  to our version.
    896 ##
    897 ##  On encrypt,
    898 ##    xor with 0x63
    899 ##    multiply by circulant 0,1,1,1
    900 ##    apply shiftrows transform
    901 ##
    902 ##  On decrypt,
    903 ##    xor with 0x63
    904 ##    multiply by "inverse mixcolumns" circulant E,B,D,9
    905 ##    deskew
    906 ##    apply shiftrows transform
    907 ##
    908 ##
    909 ##  Writes out to (%rdx), and increments or decrements it
    910 ##  Keeps track of round number mod 4 in %r8
    911 ##  Preserves xmm0
    912 ##  Clobbers xmm1-xmm5
    913 ##
    914 .type	_vpaes_schedule_mangle,%function
    915 .align	4
    916 _vpaes_schedule_mangle:
    917 	mov	v4.16b, v0.16b			// vmovdqa	%xmm0,	%xmm4	# save xmm0 for later
    918 						// vmovdqa	.Lk_mc_forward(%rip),%xmm5
    919 	cbnz	w3, .Lschedule_mangle_dec
    920 
    921 	// encrypting
    922 	eor	v4.16b, v0.16b, v16.16b		// vpxor	.Lk_s63(%rip),	%xmm0,	%xmm4
    923 	add	x2, x2, #16			// add	$16,	%rdx
    924 	tbl	v4.16b, {v4.16b}, v9.16b	// vpshufb	%xmm5,	%xmm4,	%xmm4
    925 	tbl	v1.16b, {v4.16b}, v9.16b	// vpshufb	%xmm5,	%xmm4,	%xmm1
    926 	tbl	v3.16b, {v1.16b}, v9.16b	// vpshufb	%xmm5,	%xmm1,	%xmm3
    927 	eor	v4.16b, v4.16b, v1.16b		// vpxor	%xmm1,	%xmm4,	%xmm4
    928 	ld1	{v1.2d}, [x8]			// vmovdqa	(%r8,%r10),	%xmm1
    929 	eor	v3.16b, v3.16b, v4.16b		// vpxor	%xmm4,	%xmm3,	%xmm3
    930 
    931 	b	.Lschedule_mangle_both
    932 .align	4
    933 .Lschedule_mangle_dec:
    934 	// inverse mix columns
    935 						// lea	.Lk_dksd(%rip),%r11
    936 	ushr	v1.16b, v4.16b, #4		// vpsrlb	$4,	%xmm4,	%xmm1	# 1 = hi
    937 	and	v4.16b, v4.16b, v17.16b		// vpand	%xmm9,	%xmm4,	%xmm4	# 4 = lo
    938 
    939 						// vmovdqa	0x00(%r11),	%xmm2
    940 	tbl	v2.16b, {v24.16b}, v4.16b	// vpshufb	%xmm4,	%xmm2,	%xmm2
    941 						// vmovdqa	0x10(%r11),	%xmm3
    942 	tbl	v3.16b,	{v25.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm3
    943 	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3
    944 	tbl	v3.16b, {v3.16b}, v9.16b	// vpshufb	%xmm5,	%xmm3,	%xmm3
    945 
    946 						// vmovdqa	0x20(%r11),	%xmm2
    947 	tbl	v2.16b, {v26.16b}, v4.16b	// vpshufb	%xmm4,	%xmm2,	%xmm2
    948 	eor	v2.16b, v2.16b, v3.16b		// vpxor	%xmm3,	%xmm2,	%xmm2
    949 						// vmovdqa	0x30(%r11),	%xmm3
    950 	tbl	v3.16b, {v27.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm3
    951 	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3
    952 	tbl	v3.16b, {v3.16b}, v9.16b	// vpshufb	%xmm5,	%xmm3,	%xmm3
    953 
    954 						// vmovdqa	0x40(%r11),	%xmm2
    955 	tbl	v2.16b, {v28.16b}, v4.16b	// vpshufb	%xmm4,	%xmm2,	%xmm2
    956 	eor	v2.16b, v2.16b, v3.16b		// vpxor	%xmm3,	%xmm2,	%xmm2
    957 						// vmovdqa	0x50(%r11),	%xmm3
    958 	tbl	v3.16b, {v29.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm3
    959 	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3
    960 
    961 						// vmovdqa	0x60(%r11),	%xmm2
    962 	tbl	v2.16b, {v30.16b}, v4.16b	// vpshufb	%xmm4,	%xmm2,	%xmm2
    963 	tbl	v3.16b, {v3.16b}, v9.16b	// vpshufb	%xmm5,	%xmm3,	%xmm3
    964 						// vmovdqa	0x70(%r11),	%xmm4
    965 	tbl	v4.16b, {v31.16b}, v1.16b	// vpshufb	%xmm1,	%xmm4,	%xmm4
    966 	ld1	{v1.2d}, [x8]			// vmovdqa	(%r8,%r10),	%xmm1
    967 	eor	v2.16b, v2.16b, v3.16b		// vpxor	%xmm3,	%xmm2,	%xmm2
    968 	eor	v3.16b, v4.16b, v2.16b		// vpxor	%xmm2,	%xmm4,	%xmm3
    969 
    970 	sub	x2, x2, #16			// add	$-16,	%rdx
    971 
    972 .Lschedule_mangle_both:
    973 	tbl	v3.16b, {v3.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm3
    974 	add	x8, x8, #64-16			// add	$-16,	%r8
    975 	and	x8, x8, #~(1<<6)		// and	$0x30,	%r8
    976 	st1	{v3.2d}, [x2]			// vmovdqu	%xmm3,	(%rdx)
    977 	ret
    978 .size	_vpaes_schedule_mangle,.-_vpaes_schedule_mangle
    979 
    980 .globl	vpaes_set_encrypt_key
    981 .type	vpaes_set_encrypt_key,%function
    982 .align	4
    983 vpaes_set_encrypt_key:
    984 .inst	0xd503233f		// paciasp
    985 	stp	x29,x30,[sp,#-16]!
    986 	add	x29,sp,#0
    987 	stp	d8,d9,[sp,#-16]!	// ABI spec says so
    988 
    989 	lsr	w9, w1, #5		// shr	$5,%eax
    990 	add	w9, w9, #5		// $5,%eax
    991 	str	w9, [x2,#240]		// mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
    992 
    993 	mov	w3, #0		// mov	$0,%ecx
    994 	mov	x8, #0x30		// mov	$0x30,%r8d
    995 	bl	_vpaes_schedule_core
    996 	eor	x0, x0, x0
    997 
    998 	ldp	d8,d9,[sp],#16
    999 	ldp	x29,x30,[sp],#16
   1000 .inst	0xd50323bf		// autiasp
   1001 	ret
   1002 .size	vpaes_set_encrypt_key,.-vpaes_set_encrypt_key
   1003 
   1004 .globl	vpaes_set_decrypt_key
   1005 .type	vpaes_set_decrypt_key,%function
   1006 .align	4
   1007 vpaes_set_decrypt_key:
   1008 .inst	0xd503233f		// paciasp
   1009 	stp	x29,x30,[sp,#-16]!
   1010 	add	x29,sp,#0
   1011 	stp	d8,d9,[sp,#-16]!	// ABI spec says so
   1012 
   1013 	lsr	w9, w1, #5		// shr	$5,%eax
   1014 	add	w9, w9, #5		// $5,%eax
   1015 	str	w9, [x2,#240]		// mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
   1016 	lsl	w9, w9, #4		// shl	$4,%eax
   1017 	add	x2, x2, #16		// lea	16(%rdx,%rax),%rdx
   1018 	add	x2, x2, x9
   1019 
   1020 	mov	w3, #1		// mov	$1,%ecx
   1021 	lsr	w8, w1, #1		// shr	$1,%r8d
   1022 	and	x8, x8, #32		// and	$32,%r8d
   1023 	eor	x8, x8, #32		// xor	$32,%r8d	# nbits==192?0:32
   1024 	bl	_vpaes_schedule_core
   1025 
   1026 	ldp	d8,d9,[sp],#16
   1027 	ldp	x29,x30,[sp],#16
   1028 .inst	0xd50323bf		// autiasp
   1029 	ret
   1030 .size	vpaes_set_decrypt_key,.-vpaes_set_decrypt_key
   1031 .globl	vpaes_cbc_encrypt
   1032 .type	vpaes_cbc_encrypt,%function
   1033 .align	4
   1034 vpaes_cbc_encrypt:
   1035 	cbz	x2, .Lcbc_abort
   1036 	cmp	w5, #0			// check direction
   1037 	b.eq	vpaes_cbc_decrypt
   1038 
   1039 .inst	0xd503233f		// paciasp
   1040 	stp	x29,x30,[sp,#-16]!
   1041 	add	x29,sp,#0
   1042 
   1043 	mov	x17, x2		// reassign
   1044 	mov	x2,  x3		// reassign
   1045 
   1046 	ld1	{v0.16b}, [x4]	// load ivec
   1047 	bl	_vpaes_encrypt_preheat
   1048 	b	.Lcbc_enc_loop
   1049 
   1050 .align	4
   1051 .Lcbc_enc_loop:
   1052 	ld1	{v7.16b}, [x0],#16	// load input
   1053 	eor	v7.16b, v7.16b, v0.16b	// xor with ivec
   1054 	bl	_vpaes_encrypt_core
   1055 	st1	{v0.16b}, [x1],#16	// save output
   1056 	subs	x17, x17, #16
   1057 	b.hi	.Lcbc_enc_loop
   1058 
   1059 	st1	{v0.16b}, [x4]	// write ivec
   1060 
   1061 	ldp	x29,x30,[sp],#16
   1062 .inst	0xd50323bf		// autiasp
   1063 .Lcbc_abort:
   1064 	ret
   1065 .size	vpaes_cbc_encrypt,.-vpaes_cbc_encrypt
   1066 
   1067 .type	vpaes_cbc_decrypt,%function
   1068 .align	4
   1069 vpaes_cbc_decrypt:
   1070 .inst	0xd503233f		// paciasp
   1071 	stp	x29,x30,[sp,#-16]!
   1072 	add	x29,sp,#0
   1073 	stp	d8,d9,[sp,#-16]!	// ABI spec says so
   1074 	stp	d10,d11,[sp,#-16]!
   1075 	stp	d12,d13,[sp,#-16]!
   1076 	stp	d14,d15,[sp,#-16]!
   1077 
   1078 	mov	x17, x2		// reassign
   1079 	mov	x2,  x3		// reassign
   1080 	ld1	{v6.16b}, [x4]	// load ivec
   1081 	bl	_vpaes_decrypt_preheat
   1082 	tst	x17, #16
   1083 	b.eq	.Lcbc_dec_loop2x
   1084 
   1085 	ld1	{v7.16b}, [x0], #16	// load input
   1086 	bl	_vpaes_decrypt_core
   1087 	eor	v0.16b, v0.16b, v6.16b	// xor with ivec
   1088 	orr	v6.16b, v7.16b, v7.16b	// next ivec value
   1089 	st1	{v0.16b}, [x1], #16
   1090 	subs	x17, x17, #16
   1091 	b.ls	.Lcbc_dec_done
   1092 
   1093 .align	4
   1094 .Lcbc_dec_loop2x:
   1095 	ld1	{v14.16b,v15.16b}, [x0], #32
   1096 	bl	_vpaes_decrypt_2x
   1097 	eor	v0.16b, v0.16b, v6.16b	// xor with ivec
   1098 	eor	v1.16b, v1.16b, v14.16b
   1099 	orr	v6.16b, v15.16b, v15.16b
   1100 	st1	{v0.16b,v1.16b}, [x1], #32
   1101 	subs	x17, x17, #32
   1102 	b.hi	.Lcbc_dec_loop2x
   1103 
   1104 .Lcbc_dec_done:
   1105 	st1	{v6.16b}, [x4]
   1106 
   1107 	ldp	d14,d15,[sp],#16
   1108 	ldp	d12,d13,[sp],#16
   1109 	ldp	d10,d11,[sp],#16
   1110 	ldp	d8,d9,[sp],#16
   1111 	ldp	x29,x30,[sp],#16
   1112 .inst	0xd50323bf		// autiasp
   1113 	ret
   1114 .size	vpaes_cbc_decrypt,.-vpaes_cbc_decrypt
   1115 .globl	vpaes_ecb_encrypt
   1116 .type	vpaes_ecb_encrypt,%function
   1117 .align	4
   1118 vpaes_ecb_encrypt:
   1119 .inst	0xd503233f		// paciasp
   1120 	stp	x29,x30,[sp,#-16]!
   1121 	add	x29,sp,#0
   1122 	stp	d8,d9,[sp,#-16]!	// ABI spec says so
   1123 	stp	d10,d11,[sp,#-16]!
   1124 	stp	d12,d13,[sp,#-16]!
   1125 	stp	d14,d15,[sp,#-16]!
   1126 
   1127 	mov	x17, x2
   1128 	mov	x2,  x3
   1129 	bl	_vpaes_encrypt_preheat
   1130 	tst	x17, #16
   1131 	b.eq	.Lecb_enc_loop
   1132 
   1133 	ld1	{v7.16b}, [x0],#16
   1134 	bl	_vpaes_encrypt_core
   1135 	st1	{v0.16b}, [x1],#16
   1136 	subs	x17, x17, #16
   1137 	b.ls	.Lecb_enc_done
   1138 
   1139 .align	4
   1140 .Lecb_enc_loop:
   1141 	ld1	{v14.16b,v15.16b}, [x0], #32
   1142 	bl	_vpaes_encrypt_2x
   1143 	st1	{v0.16b,v1.16b}, [x1], #32
   1144 	subs	x17, x17, #32
   1145 	b.hi	.Lecb_enc_loop
   1146 
   1147 .Lecb_enc_done:
   1148 	ldp	d14,d15,[sp],#16
   1149 	ldp	d12,d13,[sp],#16
   1150 	ldp	d10,d11,[sp],#16
   1151 	ldp	d8,d9,[sp],#16
   1152 	ldp	x29,x30,[sp],#16
   1153 .inst	0xd50323bf		// autiasp
   1154 	ret
   1155 .size	vpaes_ecb_encrypt,.-vpaes_ecb_encrypt
   1156 
   1157 .globl	vpaes_ecb_decrypt
   1158 .type	vpaes_ecb_decrypt,%function
   1159 .align	4
   1160 vpaes_ecb_decrypt:
   1161 .inst	0xd503233f		// paciasp
   1162 	stp	x29,x30,[sp,#-16]!
   1163 	add	x29,sp,#0
   1164 	stp	d8,d9,[sp,#-16]!	// ABI spec says so
   1165 	stp	d10,d11,[sp,#-16]!
   1166 	stp	d12,d13,[sp,#-16]!
   1167 	stp	d14,d15,[sp,#-16]!
   1168 
   1169 	mov	x17, x2
   1170 	mov	x2,  x3
   1171 	bl	_vpaes_decrypt_preheat
   1172 	tst	x17, #16
   1173 	b.eq	.Lecb_dec_loop
   1174 
   1175 	ld1	{v7.16b}, [x0],#16
   1176 	bl	_vpaes_encrypt_core
   1177 	st1	{v0.16b}, [x1],#16
   1178 	subs	x17, x17, #16
   1179 	b.ls	.Lecb_dec_done
   1180 
   1181 .align	4
   1182 .Lecb_dec_loop:
   1183 	ld1	{v14.16b,v15.16b}, [x0], #32
   1184 	bl	_vpaes_decrypt_2x
   1185 	st1	{v0.16b,v1.16b}, [x1], #32
   1186 	subs	x17, x17, #32
   1187 	b.hi	.Lecb_dec_loop
   1188 
   1189 .Lecb_dec_done:
   1190 	ldp	d14,d15,[sp],#16
   1191 	ldp	d12,d13,[sp],#16
   1192 	ldp	d10,d11,[sp],#16
   1193 	ldp	d8,d9,[sp],#16
   1194 	ldp	x29,x30,[sp],#16
   1195 .inst	0xd50323bf		// autiasp
   1196 	ret
   1197 .size	vpaes_ecb_decrypt,.-vpaes_ecb_decrypt
   1198