576cf8e0f41bb361b4a50014091708e0627202e0
[platform/upstream/nettle.git] / arm / v6 / aes-encrypt-internal.asm
1 C arm/v6/aes-encrypt-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         .arch armv6
34
35 include_src(<arm/aes.m4>)
36
37 C       Benchmarked at at 706, 870, 963 cycles/block on cortex A9,
38 C       for 128, 192 and 256 bit key sizes.
39
40 C       Possible improvements: More efficient load and store with
41 C       aligned accesses. Better scheduling.
42
43 define(<PARAM_ROUNDS>, <r0>)
44 define(<PARAM_KEYS>, <r1>)
45 define(<TABLE>, <r2>)
46 define(<LENGTH>, <r3>)
47 C On stack: DST, SRC
48
49 define(<W0>, <r4>)
50 define(<W1>, <r5>)
51 define(<W2>, <r6>)
52 define(<W3>, <r7>)
53 define(<T0>, <r8>)
54 define(<COUNT>, <r10>)
55 define(<KEY>, <r11>)
56
57 define(<X0>, <r0>)      C Overlaps PARAM_ROUNDS and PARAM_KEYS
58 define(<X1>, <r1>)
59 define(<X2>, <r12>)
60 define(<X3>, <r14>)     C lr
61
62 define(<FRAME_ROUNDS>>,  <[sp]>)
63 define(<FRAME_KEYS>,  <[sp, #+4]>)
64 C 8 saved registers
65 define(<FRAME_DST>,  <[sp, #+40]>)
66 define(<FRAME_SRC>,  <[sp, #+44]>)
67
68 define(<SRC>, <r12>)    C Overlap registers used in inner loop.
69 define(<DST>, <COUNT>)
70
71 C 53 instr.
72 C It's tempting to use eor with rotation, but that's slower.
73 C AES_ENCRYPT_ROUND(x0,x1,x2,x3,w0,w1,w2,w3,key)
74 define(<AES_ENCRYPT_ROUND>, <
75         uxtb    T0, $1 
76         ldr     $5, [TABLE, T0, lsl #2]
77         uxtb    T0, $2
78         ldr     $6, [TABLE, T0, lsl #2]
79         uxtb    T0, $3
80         ldr     $7, [TABLE, T0, lsl #2]
81         uxtb    T0, $4
82         ldr     $8, [TABLE, T0, lsl #2]
83
84         uxtb    T0, $2, ror #8
85         add     TABLE, TABLE, #1024
86         ldr     T0, [TABLE, T0, lsl #2]
87         eor     $5, $5, T0
88         uxtb    T0, $3, ror #8
89         ldr     T0, [TABLE, T0, lsl #2]
90         eor     $6, $6, T0
91         uxtb    T0, $4, ror #8
92         ldr     T0, [TABLE, T0, lsl #2]
93         eor     $7, $7, T0
94         uxtb    T0, $1, ror #8
95         ldr     T0, [TABLE, T0, lsl #2]
96         eor     $8, $8, T0
97
98         uxtb    T0, $3, ror #16
99         add     TABLE, TABLE, #1024
100         ldr     T0, [TABLE, T0, lsl #2]
101         eor     $5, $5, T0
102         uxtb    T0, $4, ror #16
103         ldr     T0, [TABLE, T0, lsl #2]
104         eor     $6, $6, T0
105         uxtb    T0, $1, ror #16
106         ldr     T0, [TABLE, T0, lsl #2]
107         eor     $7, $7, T0
108         uxtb    T0, $2, ror #16
109         ldr     T0, [TABLE, T0, lsl #2]
110         eor     $8, $8, T0
111
112         uxtb    T0, $4, ror #24
113         add     TABLE, TABLE, #1024
114         ldr     T0, [TABLE, T0, lsl #2]
115         eor     $5, $5, T0
116         uxtb    T0, $1, ror #24
117         ldr     T0, [TABLE, T0, lsl #2]
118         eor     $6, $6, T0
119         uxtb    T0, $2, ror #24
120         ldr     T0, [TABLE, T0, lsl #2]
121         eor     $7, $7, T0
122         uxtb    T0, $3, ror #24
123         ldr     T0, [TABLE, T0, lsl #2]
124
125         ldm     $9!, {$1,$2,$3,$4}
126         eor     $8, $8, T0
127         sub     TABLE, TABLE, #3072
128         eor     $5, $5, $1
129         eor     $6, $6, $2
130         eor     $7, $7, $3
131         eor     $8, $8, $4
132 >)
133
134         .file "aes-encrypt-internal.asm"
135         
136         C _aes_encrypt(unsigned rounds, const uint32_t *keys,
137         C              const struct aes_table *T,
138         C              size_t length, uint8_t *dst,
139         C              uint8_t *src)
140         .text
141         ALIGN(4)
142 PROLOGUE(_nettle_aes_encrypt)
143         teq     LENGTH, #0
144         beq     .Lend
145
146         ldr     SRC, [sp, #+4]
147
148         push    {r0,r1, r4,r5,r6,r7,r8,r10,r11,lr}
149
150         ALIGN(16)
151 .Lblock_loop:
152         ldm     sp, {COUNT, KEY}
153
154         add     TABLE, TABLE, #AES_TABLE0
155
156         AES_LOAD(SRC,KEY,W0)
157         AES_LOAD(SRC,KEY,W1)
158         AES_LOAD(SRC,KEY,W2)
159         AES_LOAD(SRC,KEY,W3)
160
161         str     SRC, FRAME_SRC
162
163         b       .Lentry
164         ALIGN(16)
165 .Lround_loop:
166         C       Transform X -> W
167         AES_ENCRYPT_ROUND(X0, X1, X2, X3, W0, W1, W2, W3, KEY)
168         
169 .Lentry:
170         subs    COUNT, COUNT,#2
171         C       Transform W -> X
172         AES_ENCRYPT_ROUND(W0, W1, W2, W3, X0, X1, X2, X3, KEY)
173
174         bne     .Lround_loop
175
176         sub     TABLE, TABLE, #AES_TABLE0
177
178         C       Final round
179         ldr     DST, FRAME_DST
180
181         AES_FINAL_ROUND_V6(X0, X1, X2, X3, KEY, W0)
182         AES_FINAL_ROUND_V6(X1, X2, X3, X0, KEY, W1)
183         AES_FINAL_ROUND_V6(X2, X3, X0, X1, KEY, W2)
184         AES_FINAL_ROUND_V6(X3, X0, X1, X2, KEY, W3)
185
186         ldr     SRC, FRAME_SRC
187         
188         AES_STORE(DST,W0)
189         AES_STORE(DST,W1)
190         AES_STORE(DST,W2)
191         AES_STORE(DST,W3)
192
193         str     DST, FRAME_DST
194         subs    LENGTH, LENGTH, #16
195         bhi     .Lblock_loop
196
197         add     sp, sp, #8      C Drop saved r0, r1
198         pop     {r4,r5,r6,r7,r8,r10,r11,pc}
199         
200 .Lend:
201         bx      lr
202 EPILOGUE(_nettle_aes_encrypt)