2019-06-04 10:11:33 +02:00
/* SPDX-License-Identifier: GPL-2.0-only */
2015-03-10 09:47:47 +01:00
/ *
* aes- c e - c o r e . S - A E S i n C B C / C T R / X T S m o d e u s i n g A R M v8 C r y p t o E x t e n s i o n s
*
* Copyright ( C ) 2 0 1 5 L i n a r o L t d < a r d . b i e s h e u v e l @linaro.org>
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
.text
.fpu crypto- n e o n - f p - a r m v8
.align 3
.macro enc_ r o u n d , s t a t e , k e y
aese. 8 \ s t a t e , \ k e y
aesmc. 8 \ s t a t e , \ s t a t e
.endm
.macro dec_ r o u n d , s t a t e , k e y
aesd. 8 \ s t a t e , \ k e y
aesimc. 8 \ s t a t e , \ s t a t e
.endm
.macro enc_ d r o u n d , k e y 1 , k e y 2
enc_ r o u n d q0 , \ k e y 1
enc_ r o u n d q0 , \ k e y 2
.endm
.macro dec_ d r o u n d , k e y 1 , k e y 2
dec_ r o u n d q0 , \ k e y 1
dec_ r o u n d q0 , \ k e y 2
.endm
.macro enc_ f r o u n d , k e y 1 , k e y 2 , k e y 3
enc_ r o u n d q0 , \ k e y 1
aese. 8 q0 , \ k e y 2
veor q0 , q0 , \ k e y 3
.endm
.macro dec_ f r o u n d , k e y 1 , k e y 2 , k e y 3
dec_ r o u n d q0 , \ k e y 1
aesd. 8 q0 , \ k e y 2
veor q0 , q0 , \ k e y 3
.endm
.macro enc_ d r o u n d _ 3 x , k e y 1 , k e y 2
enc_ r o u n d q0 , \ k e y 1
enc_ r o u n d q1 , \ k e y 1
enc_ r o u n d q2 , \ k e y 1
enc_ r o u n d q0 , \ k e y 2
enc_ r o u n d q1 , \ k e y 2
enc_ r o u n d q2 , \ k e y 2
.endm
.macro dec_ d r o u n d _ 3 x , k e y 1 , k e y 2
dec_ r o u n d q0 , \ k e y 1
dec_ r o u n d q1 , \ k e y 1
dec_ r o u n d q2 , \ k e y 1
dec_ r o u n d q0 , \ k e y 2
dec_ r o u n d q1 , \ k e y 2
dec_ r o u n d q2 , \ k e y 2
.endm
.macro enc_ f r o u n d _ 3 x , k e y 1 , k e y 2 , k e y 3
enc_ r o u n d q0 , \ k e y 1
enc_ r o u n d q1 , \ k e y 1
enc_ r o u n d q2 , \ k e y 1
aese. 8 q0 , \ k e y 2
aese. 8 q1 , \ k e y 2
aese. 8 q2 , \ k e y 2
veor q0 , q0 , \ k e y 3
veor q1 , q1 , \ k e y 3
veor q2 , q2 , \ k e y 3
.endm
.macro dec_ f r o u n d _ 3 x , k e y 1 , k e y 2 , k e y 3
dec_ r o u n d q0 , \ k e y 1
dec_ r o u n d q1 , \ k e y 1
dec_ r o u n d q2 , \ k e y 1
aesd. 8 q0 , \ k e y 2
aesd. 8 q1 , \ k e y 2
aesd. 8 q2 , \ k e y 2
veor q0 , q0 , \ k e y 3
veor q1 , q1 , \ k e y 3
veor q2 , q2 , \ k e y 3
.endm
.macro do_ b l o c k , d r o u n d , f r o u n d
cmp r3 , #12 @ which key size?
vld1 . 8 { q10 - q11 } , [ i p ] !
\ dround q8 , q9
vld1 . 8 { q12 - q13 } , [ i p ] !
\ dround q10 , q11
vld1 . 8 { q10 - q11 } , [ i p ] !
\ dround q12 , q13
vld1 . 8 { q12 - q13 } , [ i p ] !
\ dround q10 , q11
blo 0 f @ AES-128: 10 rounds
vld1 . 8 { q10 - q11 } , [ i p ] !
\ dround q12 , q13
2015-05-08 10:46:22 +02:00
beq 1 f @ AES-192: 12 rounds
2015-03-10 09:47:47 +01:00
vld1 . 8 { q12 - q13 } , [ i p ]
\ dround q10 , q11
0 : \ fround q12 , q13 , q14
bx l r
2015-05-08 10:46:22 +02:00
1 : \ fround q10 , q11 , q14
2015-03-10 09:47:47 +01:00
bx l r
.endm
/ *
* Internal, n o n - A A P C S c o m p l i a n t f u n c t i o n s t h a t i m p l e m e n t t h e c o r e A E S
* transforms. T h e s e s h o u l d p r e s e r v e a l l r e g i s t e r s e x c e p t q0 - q2 a n d i p
* Arguments :
* q0 : f i r s t i n / o u t p u t b l o c k
* q1 : s e c o n d i n / o u t p u t b l o c k ( _ 3 x v e r s i o n o n l y )
* q2 : t h i r d i n / o u t p u t b l o c k ( _ 3 x v e r s i o n o n l y )
* q8 : f i r s t r o u n d k e y
* q9 : s e c o u n d r o u n d k e y
* q1 4 : f i n a l r o u n d k e y
2015-05-08 10:46:22 +02:00
* r2 : a d d r e s s o f r o u n d k e y a r r a y
2015-03-10 09:47:47 +01:00
* r3 : n u m b e r o f r o u n d s
* /
.align 6
aes_encrypt :
add i p , r2 , #32 @ 3rd round key
.Laes_encrypt_tweak :
do_ b l o c k e n c _ d r o u n d , e n c _ f r o u n d
ENDPROC( a e s _ e n c r y p t )
.align 6
aes_decrypt :
add i p , r2 , #32 @ 3rd round key
do_ b l o c k d e c _ d r o u n d , d e c _ f r o u n d
ENDPROC( a e s _ d e c r y p t )
.align 6
aes_encrypt_3x :
add i p , r2 , #32 @ 3rd round key
do_ b l o c k e n c _ d r o u n d _ 3 x , e n c _ f r o u n d _ 3 x
ENDPROC( a e s _ e n c r y p t _ 3 x )
.align 6
aes_decrypt_3x :
add i p , r2 , #32 @ 3rd round key
do_ b l o c k d e c _ d r o u n d _ 3 x , d e c _ f r o u n d _ 3 x
ENDPROC( a e s _ d e c r y p t _ 3 x )
.macro prepare_ k e y , r k , r o u n d s
add i p , \ r k , \ r o u n d s , l s l #4
vld1 . 8 { q8 - q9 } , [ \ r k ] @ load first 2 round keys
vld1 . 8 { q14 } , [ i p ] @ load last round key
.endm
/ *
* aes_ e c b _ e n c r y p t ( u 8 o u t [ ] , u 8 c o n s t i n [ ] , u 8 c o n s t r k [ ] , i n t r o u n d s ,
* int b l o c k s )
* aes_ e c b _ d e c r y p t ( u 8 o u t [ ] , u 8 c o n s t i n [ ] , u 8 c o n s t r k [ ] , i n t r o u n d s ,
* int b l o c k s )
* /
ENTRY( c e _ a e s _ e c b _ e n c r y p t )
push { r4 , l r }
ldr r4 , [ s p , #8 ]
prepare_ k e y r2 , r3
.Lecbencloop3x :
subs r4 , r4 , #3
bmi . L e c b e n c1 x
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 - q1 } , [ r1 ] !
vld1 . 8 { q2 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
bl a e s _ e n c r y p t _ 3 x
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 - q1 } , [ r0 ] !
vst1 . 8 { q2 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
b . L e c b e n c l o o p3 x
.Lecbenc1x :
adds r4 , r4 , #3
beq . L e c b e n c o u t
.Lecbencloop :
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
bl a e s _ e n c r y p t
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
subs r4 , r4 , #1
bne . L e c b e n c l o o p
.Lecbencout :
pop { r4 , p c }
ENDPROC( c e _ a e s _ e c b _ e n c r y p t )
ENTRY( c e _ a e s _ e c b _ d e c r y p t )
push { r4 , l r }
ldr r4 , [ s p , #8 ]
prepare_ k e y r2 , r3
.Lecbdecloop3x :
subs r4 , r4 , #3
bmi . L e c b d e c1 x
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 - q1 } , [ r1 ] !
vld1 . 8 { q2 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
bl a e s _ d e c r y p t _ 3 x
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 - q1 } , [ r0 ] !
vst1 . 8 { q2 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
b . L e c b d e c l o o p3 x
.Lecbdec1x :
adds r4 , r4 , #3
beq . L e c b d e c o u t
.Lecbdecloop :
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
bl a e s _ d e c r y p t
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
subs r4 , r4 , #1
bne . L e c b d e c l o o p
.Lecbdecout :
pop { r4 , p c }
ENDPROC( c e _ a e s _ e c b _ d e c r y p t )
/ *
* aes_ c b c _ e n c r y p t ( u 8 o u t [ ] , u 8 c o n s t i n [ ] , u 8 c o n s t r k [ ] , i n t r o u n d s ,
* int b l o c k s , u 8 i v [ ] )
* aes_ c b c _ d e c r y p t ( u 8 o u t [ ] , u 8 c o n s t i n [ ] , u 8 c o n s t r k [ ] , i n t r o u n d s ,
* int b l o c k s , u 8 i v [ ] )
* /
ENTRY( c e _ a e s _ c b c _ e n c r y p t )
push { r4 - r6 , l r }
ldrd r4 , r5 , [ s p , #16 ]
vld1 . 8 { q0 } , [ r5 ]
prepare_ k e y r2 , r3
.Lcbcencloop :
2017-01-28 23:25:31 +00:00
vld1 . 8 { q1 } , [ r1 ] ! @ get next pt block
2015-03-10 09:47:47 +01:00
veor q0 , q0 , q1 @ ..and xor with iv
bl a e s _ e n c r y p t
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
subs r4 , r4 , #1
bne . L c b c e n c l o o p
vst1 . 8 { q0 } , [ r5 ]
pop { r4 - r6 , p c }
ENDPROC( c e _ a e s _ c b c _ e n c r y p t )
ENTRY( c e _ a e s _ c b c _ d e c r y p t )
push { r4 - r6 , l r }
ldrd r4 , r5 , [ s p , #16 ]
vld1 . 8 { q6 } , [ r5 ] @ keep iv in q6
prepare_ k e y r2 , r3
.Lcbcdecloop3x :
subs r4 , r4 , #3
bmi . L c b c d e c1 x
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 - q1 } , [ r1 ] !
vld1 . 8 { q2 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
vmov q3 , q0
vmov q4 , q1
vmov q5 , q2
bl a e s _ d e c r y p t _ 3 x
veor q0 , q0 , q6
veor q1 , q1 , q3
veor q2 , q2 , q4
vmov q6 , q5
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 - q1 } , [ r0 ] !
vst1 . 8 { q2 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
b . L c b c d e c l o o p3 x
.Lcbcdec1x :
adds r4 , r4 , #3
beq . L c b c d e c o u t
vmov q15 , q14 @ preserve last round key
.Lcbcdecloop :
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 } , [ r1 ] ! @ get next ct block
2015-03-10 09:47:47 +01:00
veor q14 , q15 , q6 @ combine prev ct with last key
vmov q6 , q0
bl a e s _ d e c r y p t
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
subs r4 , r4 , #1
bne . L c b c d e c l o o p
.Lcbcdecout :
vst1 . 8 { q6 } , [ r5 ] @ keep iv in q6
pop { r4 - r6 , p c }
ENDPROC( c e _ a e s _ c b c _ d e c r y p t )
/ *
* aes_ c t r _ e n c r y p t ( u 8 o u t [ ] , u 8 c o n s t i n [ ] , u 8 c o n s t r k [ ] , i n t r o u n d s ,
* int b l o c k s , u 8 c t r [ ] )
* /
ENTRY( c e _ a e s _ c t r _ e n c r y p t )
push { r4 - r6 , l r }
ldrd r4 , r5 , [ s p , #16 ]
vld1 . 8 { q6 } , [ r5 ] @ load ctr
prepare_ k e y r2 , r3
vmov r6 , s27 @ keep swabbed ctr in r6
rev r6 , r6
cmn r6 , r4 @ 32 bit overflow?
bcs . L c t r l o o p
.Lctrloop3x :
subs r4 , r4 , #3
bmi . L c t r1 x
add r6 , r6 , #1
vmov q0 , q6
vmov q1 , q6
rev i p , r6
add r6 , r6 , #1
vmov q2 , q6
vmov s7 , i p
rev i p , r6
add r6 , r6 , #1
vmov s11 , i p
2017-01-28 23:25:31 +00:00
vld1 . 8 { q3 - q4 } , [ r1 ] !
vld1 . 8 { q5 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
bl a e s _ e n c r y p t _ 3 x
veor q0 , q0 , q3
veor q1 , q1 , q4
veor q2 , q2 , q5
rev i p , r6
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 - q1 } , [ r0 ] !
vst1 . 8 { q2 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
vmov s27 , i p
b . L c t r l o o p3 x
.Lctr1x :
adds r4 , r4 , #3
beq . L c t r o u t
.Lctrloop :
vmov q0 , q6
bl a e s _ e n c r y p t
adds r6 , r6 , #1 @ increment BE ctr
rev i p , r6
vmov s27 , i p
bcs . L c t r c a r r y
2019-02-14 00:03:55 -08:00
.Lctrcarrydone :
subs r4 , r4 , #1
bmi . L c t r t a i l b l o c k @ blocks < 0 means tail block
vld1 . 8 { q3 } , [ r1 ] !
veor q3 , q0 , q3
vst1 . 8 { q3 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
bne . L c t r l o o p
2019-02-14 00:03:55 -08:00
2015-03-10 09:47:47 +01:00
.Lctrout :
2019-02-14 00:03:55 -08:00
vst1 . 8 { q6 } , [ r5 ] @ return next CTR value
2015-03-10 09:47:47 +01:00
pop { r4 - r6 , p c }
2017-01-28 23:25:31 +00:00
.Lctrtailblock :
2019-02-14 00:03:55 -08:00
vst1 . 8 { q0 } , [ r0 , : 6 4 ] @ return the key stream
b . L c t r o u t
2015-03-10 09:47:47 +01:00
.Lctrcarry :
.irp sreg, s26 , s25 , s24
vmov i p , \ s r e g @ load next word of ctr
rev i p , i p @ ... to handle the carry
adds i p , i p , #1
rev i p , i p
vmov \ s r e g , i p
2019-02-14 00:03:55 -08:00
bcc . L c t r c a r r y d o n e
2015-03-10 09:47:47 +01:00
.endr
2019-02-14 00:03:55 -08:00
b . L c t r c a r r y d o n e
2015-03-10 09:47:47 +01:00
ENDPROC( c e _ a e s _ c t r _ e n c r y p t )
/ *
* aes_ x t s _ e n c r y p t ( u 8 o u t [ ] , u 8 c o n s t i n [ ] , u 8 c o n s t r k 1 [ ] , i n t r o u n d s ,
* int b l o c k s , u 8 i v [ ] , u 8 c o n s t r k 2 [ ] , i n t f i r s t )
* aes_ x t s _ d e c r y p t ( u 8 o u t [ ] , u 8 c o n s t i n [ ] , u 8 c o n s t r k 1 [ ] , i n t r o u n d s ,
* int b l o c k s , u 8 i v [ ] , u 8 c o n s t r k 2 [ ] , i n t f i r s t )
* /
.macro next_ t w e a k , o u t , i n , c o n s t , t m p
vshr. s64 \ t m p , \ i n , #63
vand \ t m p , \ t m p , \ c o n s t
vadd. u 6 4 \ o u t , \ i n , \ i n
vext. 8 \ t m p , \ t m p , \ t m p , #8
veor \ o u t , \ o u t , \ t m p
.endm
.align 3
.Lxts_mul_x :
.quad 1 , 0 x8 7
ce_aes_xts_init :
vldr d14 , . L x t s _ m u l _ x
vldr d15 , . L x t s _ m u l _ x + 8
ldrd r4 , r5 , [ s p , #16 ] @ load args
ldr r6 , [ s p , #28 ]
vld1 . 8 { q0 } , [ r5 ] @ load iv
teq r6 , #1 @ start of a block?
bxne l r
@ Encrypt the IV in q0 with the second AES key. This should only
@ be done at the start of a block.
ldr r6 , [ s p , #24 ] @ load AES key 2
prepare_ k e y r6 , r3
add i p , r6 , #32 @ 3rd round key of key 2
b . L a e s _ e n c r y p t _ t w e a k @ tail call
ENDPROC( c e _ a e s _ x t s _ i n i t )
ENTRY( c e _ a e s _ x t s _ e n c r y p t )
push { r4 - r6 , l r }
bl c e _ a e s _ x t s _ i n i t @ run shared prologue
prepare_ k e y r2 , r3
vmov q3 , q0
teq r6 , #0 @ start of a block?
bne . L x t s e n c3 x
.Lxtsencloop3x :
next_ t w e a k q3 , q3 , q7 , q6
.Lxtsenc3x :
subs r4 , r4 , #3
bmi . L x t s e n c1 x
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 - q1 } , [ r1 ] ! @ get 3 pt blocks
vld1 . 8 { q2 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
next_ t w e a k q4 , q3 , q7 , q6
veor q0 , q0 , q3
next_ t w e a k q5 , q4 , q7 , q6
veor q1 , q1 , q4
veor q2 , q2 , q5
bl a e s _ e n c r y p t _ 3 x
veor q0 , q0 , q3
veor q1 , q1 , q4
veor q2 , q2 , q5
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 - q1 } , [ r0 ] ! @ write 3 ct blocks
vst1 . 8 { q2 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
vmov q3 , q5
teq r4 , #0
beq . L x t s e n c o u t
b . L x t s e n c l o o p3 x
.Lxtsenc1x :
adds r4 , r4 , #3
beq . L x t s e n c o u t
.Lxtsencloop :
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
veor q0 , q0 , q3
bl a e s _ e n c r y p t
veor q0 , q0 , q3
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
subs r4 , r4 , #1
beq . L x t s e n c o u t
next_ t w e a k q3 , q3 , q7 , q6
b . L x t s e n c l o o p
.Lxtsencout :
vst1 . 8 { q3 } , [ r5 ]
pop { r4 - r6 , p c }
ENDPROC( c e _ a e s _ x t s _ e n c r y p t )
ENTRY( c e _ a e s _ x t s _ d e c r y p t )
push { r4 - r6 , l r }
bl c e _ a e s _ x t s _ i n i t @ run shared prologue
prepare_ k e y r2 , r3
vmov q3 , q0
teq r6 , #0 @ start of a block?
bne . L x t s d e c3 x
.Lxtsdecloop3x :
next_ t w e a k q3 , q3 , q7 , q6
.Lxtsdec3x :
subs r4 , r4 , #3
bmi . L x t s d e c1 x
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 - q1 } , [ r1 ] ! @ get 3 ct blocks
vld1 . 8 { q2 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
next_ t w e a k q4 , q3 , q7 , q6
veor q0 , q0 , q3
next_ t w e a k q5 , q4 , q7 , q6
veor q1 , q1 , q4
veor q2 , q2 , q5
bl a e s _ d e c r y p t _ 3 x
veor q0 , q0 , q3
veor q1 , q1 , q4
veor q2 , q2 , q5
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 - q1 } , [ r0 ] ! @ write 3 pt blocks
vst1 . 8 { q2 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
vmov q3 , q5
teq r4 , #0
beq . L x t s d e c o u t
b . L x t s d e c l o o p3 x
.Lxtsdec1x :
adds r4 , r4 , #3
beq . L x t s d e c o u t
.Lxtsdecloop :
2017-01-28 23:25:31 +00:00
vld1 . 8 { q0 } , [ r1 ] !
2015-03-10 09:47:47 +01:00
veor q0 , q0 , q3
add i p , r2 , #32 @ 3rd round key
bl a e s _ d e c r y p t
veor q0 , q0 , q3
2017-01-28 23:25:31 +00:00
vst1 . 8 { q0 } , [ r0 ] !
2015-03-10 09:47:47 +01:00
subs r4 , r4 , #1
beq . L x t s d e c o u t
next_ t w e a k q3 , q3 , q7 , q6
b . L x t s d e c l o o p
.Lxtsdecout :
vst1 . 8 { q3 } , [ r5 ]
pop { r4 - r6 , p c }
ENDPROC( c e _ a e s _ x t s _ d e c r y p t )
/ *
* u3 2 c e _ a e s _ s u b ( u 3 2 i n p u t ) - u s e t h e a e s e i n s t r u c t i o n t o p e r f o r m t h e
* AES s b o x s u b s t i t u t i o n o n e a c h b y t e i n
* ' input'
* /
ENTRY( c e _ a e s _ s u b )
vdup. 3 2 q1 , r0
veor q0 , q0 , q0
aese. 8 q0 , q1
vmov r0 , s0
bx l r
ENDPROC( c e _ a e s _ s u b )
/ *
* void c e _ a e s _ i n v e r t ( u 8 * d s t , u 8 * s r c ) - p e r f o r m t h e I n v e r s e M i x C o l u m n s
* operation o n r o u n d k e y * s r c
* /
ENTRY( c e _ a e s _ i n v e r t )
vld1 . 8 { q0 } , [ r1 ]
aesimc. 8 q0 , q0
vst1 . 8 { q0 } , [ r0 ]
bx l r
ENDPROC( c e _ a e s _ i n v e r t )