ce8c57f0c90195c6224002868e7f52e334917055
[platform/upstream/nettle.git] / x86 / camellia-crypt-internal.asm
1 C x86/camellia-crypt-internal.asm
2
3 ifelse(<
4    Copyright (C) 2010, 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 C Register usage:
34
35 C Camellia state, 128-bit value in little endian order.
36 C L0, H0 corresponds to D1 in the spec and i0 in the C implementation.
37 C while L1, H1 corresponds to D2/i1.
38 define(<L0>,<%eax>)
39 define(<H0>,<%ebx>)
40 define(<L1>,<%ecx>)
41 define(<H1>,<%edx>)
42
43 define(<TMP>,<%ebp>)
44 define(<KEY>,<%esi>)
45 define(<T>,<%edi>)
46
47 C Locals on the stack
48
49 define(<FRAME_L0>,      <(%esp)>)
50 define(<FRAME_H0>,      <4(%esp)>)
51 define(<FRAME_L1>,      <8(%esp)>)
52 define(<FRAME_H1>,      <12(%esp)>)
53 define(<FRAME_CNT>,     <16(%esp)>)
54         
55 C Arguments on stack.
56 define(<FRAME_NKEYS>,   <40(%esp)>)
57 define(<FRAME_KEYS>,    <44(%esp)>)
58 define(<FRAME_TABLE>,   <48(%esp)>)
59 define(<FRAME_LENGTH>,  <52(%esp)>)
60 define(<FRAME_DST>,     <56(%esp)>)
61 define(<FRAME_SRC>,     <60(%esp)>)
62
63 define(<SP1110>, <(T,$1,4)>)
64 define(<SP0222>, <1024(T,$1,4)>)
65 define(<SP3033>, <2048(T,$1,4)>)
66 define(<SP4404>, <3072(T,$1,4)>)
67
68 C ROUND(xl, xh, yl, yh, key-offset)
69 C xl and xh are rotated 16 bits at the end
70 C yl and yh are read from stack, and left in registers
71 define(<ROUND>, <
72         movzbl  LREG($1), TMP
73         movl    SP1110(TMP), $4
74         movzbl  HREG($1), TMP
75         xorl    SP4404(TMP), $4
76         roll    <$>16, $1
77
78         movzbl  LREG($2), TMP
79         movl    SP4404(TMP), $3
80         movzbl  HREG($2), TMP
81         xorl    SP3033(TMP), $3
82         roll    <$>16, $2
83
84         movzbl  LREG($1), TMP
85         xorl    SP3033(TMP), $4
86         movzbl  HREG($1), TMP
87         xorl    SP0222(TMP), $4
88
89         movzbl  LREG($2), TMP
90         xorl    SP0222(TMP), $3
91         movzbl  HREG($2), TMP
92         xorl    SP1110(TMP), $3
93
94         xorl    $5(KEY), $4
95         xorl    $5 + 4(KEY), $3
96
97         xorl    $3, $4
98         rorl    <$>8, $3
99         xorl    $4, $3
100
101         xorl    FRAME_$3, $3
102         xorl    FRAME_$4, $4
103 >)
104
105 C Six rounds, with inputs and outputs in registers.
106 define(<ROUND6>, <
107         movl    L0, FRAME_L0
108         movl    H0, FRAME_H0
109         movl    L1, FRAME_L1
110         movl    H1, FRAME_H1
111
112         ROUND(L0,H0,<L1>,<H1>,0)
113         movl    L1, FRAME_L1
114         movl    H1, FRAME_H1
115         ROUND(L1,H1,<L0>,<H0>,8)
116         movl    L0, FRAME_L0
117         movl    H0, FRAME_H0
118         ROUND(L0,H0,<L1>,<H1>,16)
119         movl    L1, FRAME_L1
120         movl    H1, FRAME_H1
121         ROUND(L1,H1,<L0>,<H0>,24)
122         movl    L0, FRAME_L0
123         movl    H0, FRAME_H0
124         ROUND(L0,H0,<L1>,<H1>,32)
125         ROUND(L1,H1,<L0>,<H0>,40)
126         roll    <$>16, L1
127         roll    <$>16, H1
128 >)
129
130 C FL(x0, x1, key-offset)
131 define(<FL>, <
132         movl    $3 + 4(KEY), TMP
133         andl    $2, TMP
134         roll    <$>1, TMP
135         xorl    TMP, $1
136         movl    $3(KEY), TMP
137         orl     $1, TMP
138         xorl    TMP, $2
139 >)
140 C FLINV(x0, x1, key-offset)
141 define(<FLINV>, <
142         movl    $3(KEY), TMP
143         orl     $1, TMP
144         xorl    TMP, $2
145         movl    $3 + 4(KEY), TMP
146         andl    $2, TMP
147         roll    <$>1, TMP
148         xorl    TMP, $1
149 >)
150
151 .file "camellia-crypt-internal.asm"
152         
153         C _camellia_crypt(unsigned nkeys, const uint64_t *keys,
154         C                 const struct camellia_table *T,
155         C                 size_t length, uint8_t *dst,
156         C                 uint8_t *src)
157         .text
158         ALIGN(16)
159 PROLOGUE(_nettle_camellia_crypt)
160         C save all registers that need to be saved
161         pushl   %ebx            C  32(%esp)
162         pushl   %ebp            C  28(%esp)
163         pushl   %esi            C  24(%esp)
164         pushl   %edi            C  20(%esp)
165
166         subl    $20, %esp 
167
168         movl    FRAME_LENGTH, %ebp
169         testl   %ebp,%ebp
170         jz      .Lend
171
172 .Lblock_loop:
173         C Load data, note that we'll happily do unaligned loads
174         movl    FRAME_SRC, TMP
175         movl    (TMP), H0
176         bswap   H0
177         movl    4(TMP), L0
178         bswap   L0
179         movl    8(TMP), H1
180         bswap   H1
181         movl    12(TMP), L1
182         bswap   L1
183         addl    $16, FRAME_SRC
184         movl    FRAME_KEYS, KEY
185         movl    FRAME_NKEYS, TMP
186         subl    $8, TMP
187         movl    TMP, FRAME_CNT
188         xorl    (KEY), L0
189         xorl    4(KEY), H0
190         addl    $8, KEY
191
192         movl    FRAME_TABLE, T
193
194         ROUND6
195 .Lround_loop:
196         addl    $64, KEY
197         FL(L0, H0, -16)
198         FLINV(L1, H1, -8)
199         ROUND6
200         subl    $8, FRAME_CNT   
201         ja      .Lround_loop
202
203         movl    FRAME_DST, TMP
204         bswap   H0
205         movl    H0,8(TMP)
206         bswap   L0
207         movl    L0,12(TMP)
208         xorl    52(KEY), H1
209         bswap   H1
210         movl    H1, 0(TMP)
211         xorl    48(KEY), L1
212         bswap   L1
213         movl    L1, 4(TMP)
214         addl    $16, FRAME_DST
215         subl    $16, FRAME_LENGTH
216         ja      .Lblock_loop
217
218 .Lend:
219         addl    $20, %esp
220         popl    %edi
221         popl    %esi
222         popl    %ebp
223         popl    %ebx
224         ret
225 EPILOGUE(_nettle_camellia_crypt)