ff535b6ad0bbe9a9fd6d9f7441ab072bc8c7381c
[platform/upstream/nettle.git] / x86 / aes-decrypt-internal.asm
1 C x86/aes-decrypt-internal.asm
2
3 ifelse(<
4    Copyright (C) 2001, 2002, 2005, Rafael R. Sevilla, Niels Möller
5    Copyright (C) 2008, 2013 Niels Möller
6
7    This file is part of GNU Nettle.
8
9    GNU Nettle is free software: you can redistribute it and/or
10    modify it under the terms of either:
11
12      * the GNU Lesser General Public License as published by the Free
13        Software Foundation; either version 3 of the License, or (at your
14        option) any later version.
15
16    or
17
18      * the GNU General Public License as published by the Free
19        Software Foundation; either version 2 of the License, or (at your
20        option) any later version.
21
22    or both in parallel, as here.
23
24    GNU Nettle is distributed in the hope that it will be useful,
25    but WITHOUT ANY WARRANTY; without even the implied warranty of
26    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27    General Public License for more details.
28
29    You should have received copies of the GNU General Public License and
30    the GNU Lesser General Public License along with this program.  If
31    not, see http://www.gnu.org/licenses/.
32 >)
33
34 include_src(<x86/aes.m4>)
35
36 C Register usage:
37
38 C AES state
39 define(<SA>,<%eax>)
40 define(<SB>,<%ebx>)
41 define(<SC>,<%ecx>)
42 define(<SD>,<%edx>)
43
44 C Primary use of these registers. They're also used temporarily for other things.
45 define(<T>,<%ebp>)
46 define(<TMP>,<%edi>)
47 define(<KEY>,<%esi>)
48
49 define(<PARAM_ROUNDS>,  <40(%esp)>)
50 define(<PARAM_KEYS>,    <44(%esp)>)
51 define(<PARAM_TABLE>,   <48(%esp)>)
52 define(<PARAM_LENGTH>,  <52(%esp)>)
53 define(<PARAM_DST>,     <56(%esp)>)
54 define(<PARAM_SRC>,     <60(%esp)>)
55
56 define(<FRAME_KEY>,     <16(%esp)>)
57 define(<FRAME_COUNT>,   <12(%esp)>)
58 define(<TA>,            <8(%esp)>)
59 define(<TB>,            <4(%esp)>)
60 define(<TC>,            <(%esp)>)
61
62 C The aes state is kept in %eax, %ebx, %ecx and %edx
63 C
64 C %esi is used as temporary, to point to the input, and to the
65 C subkeys, etc.
66 C
67 C %ebp is used as the round counter, and as a temporary in the final round.
68 C
69 C %edi is a temporary, often used as an accumulator.
70
71         .file "aes-decrypt-internal.asm"
72         
73         C _aes_decrypt(unsigned rounds, const uint32_t *keys,
74         C              const struct aes_table *T,
75         C              size_t length, uint8_t *dst,
76         C              uint8_t *src)
77         .text
78         ALIGN(16)
79 PROLOGUE(_nettle_aes_decrypt)
80         C save all registers that need to be saved
81         pushl   %ebx            C  20(%esp)
82         pushl   %ebp            C  16(%esp)
83         pushl   %esi            C  12(%esp)
84         pushl   %edi            C  8(%esp)
85
86         subl    $20, %esp       C  loop counter and save area for the key pointer
87
88         movl    PARAM_LENGTH, %ebp
89         testl   %ebp,%ebp
90         jz      .Lend
91
92         shrl    $4, PARAM_LENGTH
93         subl    $1, PARAM_ROUNDS
94 .Lblock_loop:
95         movl    PARAM_KEYS, KEY C  address of subkeys
96         
97         movl    PARAM_SRC, TMP  C  address of plaintext
98         AES_LOAD(SA, SB, SC, SD, TMP, KEY)
99         addl    $16, PARAM_SRC  C Increment src pointer
100         movl    PARAM_TABLE, T
101
102         movl    PARAM_ROUNDS, TMP
103         C Loop counter on stack
104         movl    TMP, FRAME_COUNT
105
106         addl    $16,KEY         C  point to next key
107         movl    KEY,FRAME_KEY
108         ALIGN(16)
109 .Lround_loop:
110         AES_ROUND(T, SA,SD,SC,SB, TMP, KEY)
111         movl    TMP, TA
112
113         AES_ROUND(T, SB,SA,SD,SC, TMP, KEY)
114         movl    TMP, TB
115
116         AES_ROUND(T, SC,SB,SA,SD, TMP, KEY)
117         movl    TMP, TC
118
119         AES_ROUND(T, SD,SC,SB,SA, SD, KEY)
120         
121         movl    TA, SA
122         movl    TB, SB
123         movl    TC, SC
124         
125         movl    FRAME_KEY, KEY
126
127         xorl    (KEY),SA        C  add current session key to plaintext
128         xorl    4(KEY),SB
129         xorl    8(KEY),SC
130         xorl    12(KEY),SD
131         addl    $16,FRAME_KEY   C  point to next key
132         decl    FRAME_COUNT
133         jnz     .Lround_loop
134
135         C last round
136
137         AES_FINAL_ROUND(SA,SD,SC,SB,T, TMP, KEY)
138         movl    TMP, TA
139
140         AES_FINAL_ROUND(SB,SA,SD,SC,T, TMP, KEY)
141         movl    TMP, TB
142
143         AES_FINAL_ROUND(SC,SB,SA,SD,T, TMP, KEY)
144         movl    TMP, TC
145
146         AES_FINAL_ROUND(SD,SC,SB,SA,T, SD, KEY)
147
148         movl    TA, SA
149         movl    TB, SB
150         movl    TC, SC
151
152         C Inverse S-box substitution
153         mov     $3,TMP
154 .Lsubst:
155         AES_SUBST_BYTE(SA,SB,SC,SD, T, KEY)
156
157         decl    TMP
158         jnz     .Lsubst
159
160         C Add last subkey, and store decrypted data
161         movl    PARAM_DST,TMP
162         movl    FRAME_KEY, KEY
163         AES_STORE(SA,SB,SC,SD, KEY, TMP)
164         
165         addl    $16, PARAM_DST          C Increment destination pointer
166         decl    PARAM_LENGTH
167
168         jnz     .Lblock_loop
169
170 .Lend:
171         addl    $20, %esp
172         popl    %edi
173         popl    %esi
174         popl    %ebp
175         popl    %ebx
176         ret
177 EPILOGUE(_nettle_aes_decrypt)