Apply %restore_fcommon macro for Address Sanitizer
[platform/upstream/nettle.git] / arm / aes-decrypt-internal.asm
1 C arm/aes-decrypt-internal.asm
2
3 ifelse(<
4    Copyright (C) 2013 Niels Möller
5
6    This file is part of GNU Nettle.
7
8    GNU Nettle is free software: you can redistribute it and/or
9    modify it under the terms of either:
10
11      * the GNU Lesser General Public License as published by the Free
12        Software Foundation; either version 3 of the License, or (at your
13        option) any later version.
14
15    or
16
17      * the GNU General Public License as published by the Free
18        Software Foundation; either version 2 of the License, or (at your
19        option) any later version.
20
21    or both in parallel, as here.
22
23    GNU Nettle is distributed in the hope that it will be useful,
24    but WITHOUT ANY WARRANTY; without even the implied warranty of
25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26    General Public License for more details.
27
28    You should have received copies of the GNU General Public License and
29    the GNU Lesser General Public License along with this program.  If
30    not, see http://www.gnu.org/licenses/.
31 >) 
32
33 include_src(<arm/aes.m4>)
34
35 define(<PARAM_ROUNDS>, <r0>)
36 define(<PARAM_KEYS>, <r1>)
37 define(<TABLE>, <r2>)
38 define(<PARAM_LENGTH>, <r3>)
39 C On stack: DST, SRC
40         
41 define(<W0>, <r4>)
42 define(<W1>, <r5>)
43 define(<W2>, <r6>)
44 define(<W3>, <r7>)
45 define(<T0>, <r8>)
46 define(<COUNT>, <r10>)
47 define(<KEY>, <r11>)
48
49 define(<MASK>, <r0>)    C Overlaps inputs, except TABLE
50 define(<X0>, <r1>)
51 define(<X1>, <r3>)
52 define(<X2>, <r12>)
53 define(<X3>, <r14>)     C lr
54
55 define(<FRAME_ROUNDS>,  <[sp]>)
56 define(<FRAME_KEYS>,  <[sp, #+4]>)
57 define(<FRAME_LENGTH>,  <[sp, #+8]>)
58 C 8 saved registers
59 define(<FRAME_DST>,  <[sp, #+44]>)
60 define(<FRAME_SRC>,  <[sp, #+48]>)
61
62
63 define(<AES_DECRYPT_ROUND>, <
64         and     T0, MASK, $1, lsl #2
65         ldr     $5, [TABLE, T0]
66         and     T0, MASK, $2, lsl #2
67         ldr     $6, [TABLE, T0]
68         and     T0, MASK, $3, lsl #2
69         ldr     $7, [TABLE, T0]
70         and     T0, MASK, $4, lsl #2
71         ldr     $8, [TABLE, T0]
72
73         and     T0, MASK, $4, ror #6
74         add     TABLE, TABLE, #1024
75         ldr     T0, [TABLE, T0]
76         eor     $5, $5, T0
77         and     T0, MASK, $1, ror #6
78         ldr     T0, [TABLE, T0]
79         eor     $6, $6, T0
80         and     T0, MASK, $2, ror #6
81         ldr     T0, [TABLE, T0]
82         eor     $7, $7, T0
83         and     T0, MASK, $3, ror #6
84         ldr     T0, [TABLE, T0]
85         eor     $8, $8, T0
86
87         and     T0, MASK, $3, ror #14
88         add     TABLE, TABLE, #1024
89         ldr     T0, [TABLE, T0]
90         eor     $5, $5, T0
91         and     T0, MASK, $4, ror #14
92         ldr     T0, [TABLE, T0]
93         eor     $6, $6, T0
94         and     T0, MASK, $1, ror #14
95         ldr     T0, [TABLE, T0]
96         eor     $7, $7, T0
97         and     T0, MASK, $2, ror #14
98         ldr     T0, [TABLE, T0]
99         eor     $8, $8, T0
100
101         and     T0, MASK, $2, ror #22
102         add     TABLE, TABLE, #1024
103         ldr     T0, [TABLE, T0]
104         eor     $5, $5, T0
105         and     T0, MASK, $3, ror #22
106         ldr     T0, [TABLE, T0]
107         eor     $6, $6, T0
108         and     T0, MASK, $4, ror #22
109         ldr     T0, [TABLE, T0]
110         eor     $7, $7, T0
111         and     T0, MASK, $1, ror #22
112         ldr     T0, [TABLE, T0]
113
114         ldm     $9!, {$1,$2,$3,$4}
115         eor     $8, $8, T0
116         sub     TABLE, TABLE, #3072
117         eor     $5, $5, $1
118         eor     $6, $6, $2
119         eor     $7, $7, $3
120         eor     $8, $8, $4
121 >)
122
123         .file "aes-decrypt-internal.asm"
124         
125         C _aes_decrypt(unsigned rounds, const uint32_t *keys,
126         C              const struct aes_table *T,
127         C              size_t length, uint8_t *dst,
128         C              uint8_t *src)
129         .text
130         ALIGN(4)
131 PROLOGUE(_nettle_aes_decrypt)
132         teq     PARAM_LENGTH, #0
133         beq     .Lend
134
135         push    {r0,r1,r3, r4,r5,r6,r7,r8,r10,r11,lr}
136         mov     MASK, #0x3fc
137         ALIGN(16)
138 .Lblock_loop:
139         ldr     X0, FRAME_SRC           C Use X0 as SRC pointer
140         ldm     sp, {COUNT, KEY}
141
142         AES_LOAD(X0,KEY,W0)
143         AES_LOAD(X0,KEY,W1)
144         AES_LOAD(X0,KEY,W2)
145         AES_LOAD(X0,KEY,W3)
146
147         str     X0, FRAME_SRC
148
149         add     TABLE, TABLE, #AES_TABLE0
150
151         b       .Lentry
152         ALIGN(16)
153 .Lround_loop:
154         C       Transform X -> W
155         AES_DECRYPT_ROUND(X0, X1, X2, X3, W0, W1, W2, W3, KEY)
156         
157 .Lentry:
158         subs    COUNT, COUNT,#2
159         C       Transform W -> X
160         AES_DECRYPT_ROUND(W0, W1, W2, W3, X0, X1, X2, X3, KEY)
161
162         bne     .Lround_loop
163
164         lsr     COUNT, MASK, #2 C Put the needed mask in the unused COUNT register
165         sub     TABLE, TABLE, #AES_TABLE0
166         C       Final round
167         AES_FINAL_ROUND_V5(X0, X3, X2, X1, KEY, W0, COUNT)
168         AES_FINAL_ROUND_V5(X1, X0, X3, X2, KEY, W1, COUNT)
169         AES_FINAL_ROUND_V5(X2, X1, X0, X3, KEY, W2, COUNT)
170         AES_FINAL_ROUND_V5(X3, X2, X1, X0, KEY, W3, COUNT)
171
172         ldr     X0, FRAME_DST
173         ldr     X1, FRAME_LENGTH
174
175         AES_STORE(X0,W0)
176         AES_STORE(X0,W1)
177         AES_STORE(X0,W2)
178         AES_STORE(X0,W3)
179
180         subs    X1, X1, #16
181         str     X0, FRAME_DST
182         str     X1, FRAME_LENGTH
183
184         bhi     .Lblock_loop
185
186         add     sp, sp, #12     C Drop saved r0, r1, r3
187         pop     {r4,r5,r6,r7,r8,r10,r11,pc}
188         
189 .Lend:
190         bx      lr
191 EPILOGUE(_nettle_aes_decrypt)