bfaa6ef80d6760f0f52b8235cc4179211c519e8a
[platform/upstream/nettle.git] / x86_64 / gcm-hash8.asm
1 C x86_64/gcm-hash8.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 C Register usage:
34
35 define(<KEY>, <%rdi>)
36 define(<XP>, <%rsi>)
37 define(<LENGTH>, <%rdx>)
38 define(<SRC>, <%rcx>)
39 define(<X0>, <%rax>)
40 define(<X1>, <%rbx>)
41 define(<CNT>, <%ebp>)
42 define(<T0>, <%r8>)
43 define(<T1>, <%r9>)
44 define(<T2>, <%r10>)
45 define(<Z0>, <%r11>)
46 define(<Z1>, <%r12>)
47 define(<SHIFT_TABLE>, <%r13>)
48
49         .file "gcm-hash8.asm"
50
51         C void gcm_hash (const struct gcm_key *key, union gcm_block *x,
52         C                size_t length, const uint8_t *data)
53
54         .text
55         ALIGN(16)
56 PROLOGUE(_nettle_gcm_hash8)
57         W64_ENTRY(4, 0)
58         push    %rbx
59         push    %rbp
60         push    %r12
61         push    %r13
62         sub     $16, LENGTH
63         lea     .Lshift_table(%rip), SHIFT_TABLE
64         mov     (XP), X0
65         mov     8(XP), X1
66         jc      .Lfinal
67 ALIGN(16)
68 .Lblock_loop:
69
70         xor (SRC), X0
71         xor 8(SRC), X1
72
73 .Lblock_mul:
74         rol     $8, X1
75         movzbl  LREG(X1), XREG(T1)
76         shl     $4, T1
77         mov     (KEY, T1), Z0
78         mov     8(KEY, T1), Z1
79
80         C shift Z1, Z0, transforming
81         C +-----------------------+-----------------------+
82         C |15 14 13 12 11 10 09 08|07 06 05 04 03 02 01 00|
83         C +-----------------------+-----------------------+
84         C into
85         C +-----------------------+-----------------------+
86         C |14 13 12 11 10 09 08 07|06 05 04 03 02 01 00   |
87         C +-----------------------+-----------------+-----+
88         C                               xor         |T[15]|
89         C                                           +-----+
90
91         mov     $7, CNT
92
93 ALIGN(16)
94 .Loop_X1:
95         mov     Z1, T1
96         shr     $56, T1
97         shl     $8, Z1
98         mov     Z0, T0
99         shl     $8, Z0
100         shr     $56, T0
101         movzwl  (SHIFT_TABLE, T1, 2), XREG(T1)
102         xor     T1, Z0
103         rol     $8, X1
104         movzbl  LREG(X1), XREG(T2)
105         shl     $4, T2
106         xor     (KEY, T2), Z0
107         add     T0, Z1
108         xor     8(KEY, T2), Z1
109         decl    CNT
110         jne     .Loop_X1
111
112         mov     $7, CNT
113
114 ALIGN(16)
115 .Loop_X0:
116         mov     Z1, T1
117         shr     $56, T1
118         shl     $8, Z1
119         mov     Z0, T0
120         shl     $8, Z0
121         shr     $56, T0
122         movzwl  (SHIFT_TABLE, T1, 2), XREG(T1)
123         xor     T1, Z0
124         rol     $8, X0
125         movzbl  LREG(X0), XREG(T2)
126         shl     $4, T2
127         xor     (KEY, T2), Z0
128         add     T0, Z1
129         xor     8(KEY, T2), Z1
130         decl    CNT
131         jne     .Loop_X0
132
133         mov     Z1, T1
134         shr     $56, T1
135         shl     $8, Z1
136         mov     Z0, T0
137         shl     $8, Z0
138         shr     $56, T0
139         movzwl  (SHIFT_TABLE, T1, 2), XREG(T1)
140         xor     T1, Z0
141         rol     $8, X0
142         movzbl  LREG(X0), XREG(T2)
143         shl     $4, T2
144         mov     (KEY, T2), X0
145         xor     Z0, X0
146         add     T0, Z1
147         mov     8(KEY, T2), X1
148         xor     Z1, X1
149
150         add     $16, SRC
151         sub     $16, LENGTH
152         jnc     .Lblock_loop
153
154 .Lfinal:
155         add     $16, LENGTH
156         jnz     .Lpartial
157
158         mov     X0, (XP)
159         mov     X1, 8(XP)
160
161         pop     %r13
162         pop     %r12
163         pop     %rbp
164         pop     %rbx
165         W64_EXIT(4, 0)
166         ret
167
168 .Lpartial:
169         C Read and xor partial block, then jump back into the loop
170         C with LENGTH == 0.
171
172         cmp     $8, LENGTH
173         jc      .Llt8
174
175         C       8 <= LENGTH < 16
176         xor     (SRC), X0
177         add     $8, SRC
178         sub     $8, LENGTH
179         jz      .Lblock_mul
180         call    .Lread_bytes
181         xor     T0, X1
182         jmp     .Lblock_mul
183
184 .Llt8:  C 0 < LENGTH < 8
185         call    .Lread_bytes
186         xor     T0, X0
187         jmp     .Lblock_mul
188
189 C Read 0 < LENGTH < 8 bytes at SRC, result in T0
190 .Lread_bytes:
191         xor     T0, T0
192         sub     $1, SRC
193 ALIGN(16)
194 .Lread_loop:
195         shl     $8, T0
196         orb     (SRC, LENGTH), LREG(T0)
197 .Lread_next:
198         sub     $1, LENGTH
199         jnz     .Lread_loop
200         ret
201 EPILOGUE(_nettle_gcm_hash8)
202
203 define(<W>, <0x$2$1>)
204         RODATA
205         ALIGN(2)
206 C NOTE: Sun/Oracle assembler doesn't support ".short".
207 C Using ".value" seems more portable.
208 .Lshift_table:
209 .value W(00,00),W(01,c2),W(03,84),W(02,46),W(07,08),W(06,ca),W(04,8c),W(05,4e)
210 .value W(0e,10),W(0f,d2),W(0d,94),W(0c,56),W(09,18),W(08,da),W(0a,9c),W(0b,5e)
211 .value W(1c,20),W(1d,e2),W(1f,a4),W(1e,66),W(1b,28),W(1a,ea),W(18,ac),W(19,6e)
212 .value W(12,30),W(13,f2),W(11,b4),W(10,76),W(15,38),W(14,fa),W(16,bc),W(17,7e)
213 .value W(38,40),W(39,82),W(3b,c4),W(3a,06),W(3f,48),W(3e,8a),W(3c,cc),W(3d,0e)
214 .value W(36,50),W(37,92),W(35,d4),W(34,16),W(31,58),W(30,9a),W(32,dc),W(33,1e)
215 .value W(24,60),W(25,a2),W(27,e4),W(26,26),W(23,68),W(22,aa),W(20,ec),W(21,2e)
216 .value W(2a,70),W(2b,b2),W(29,f4),W(28,36),W(2d,78),W(2c,ba),W(2e,fc),W(2f,3e)
217 .value W(70,80),W(71,42),W(73,04),W(72,c6),W(77,88),W(76,4a),W(74,0c),W(75,ce)
218 .value W(7e,90),W(7f,52),W(7d,14),W(7c,d6),W(79,98),W(78,5a),W(7a,1c),W(7b,de)
219 .value W(6c,a0),W(6d,62),W(6f,24),W(6e,e6),W(6b,a8),W(6a,6a),W(68,2c),W(69,ee)
220 .value W(62,b0),W(63,72),W(61,34),W(60,f6),W(65,b8),W(64,7a),W(66,3c),W(67,fe)
221 .value W(48,c0),W(49,02),W(4b,44),W(4a,86),W(4f,c8),W(4e,0a),W(4c,4c),W(4d,8e)
222 .value W(46,d0),W(47,12),W(45,54),W(44,96),W(41,d8),W(40,1a),W(42,5c),W(43,9e)
223 .value W(54,e0),W(55,22),W(57,64),W(56,a6),W(53,e8),W(52,2a),W(50,6c),W(51,ae)
224 .value W(5a,f0),W(5b,32),W(59,74),W(58,b6),W(5d,f8),W(5c,3a),W(5e,7c),W(5f,be)
225 .value W(e1,00),W(e0,c2),W(e2,84),W(e3,46),W(e6,08),W(e7,ca),W(e5,8c),W(e4,4e)
226 .value W(ef,10),W(ee,d2),W(ec,94),W(ed,56),W(e8,18),W(e9,da),W(eb,9c),W(ea,5e)
227 .value W(fd,20),W(fc,e2),W(fe,a4),W(ff,66),W(fa,28),W(fb,ea),W(f9,ac),W(f8,6e)
228 .value W(f3,30),W(f2,f2),W(f0,b4),W(f1,76),W(f4,38),W(f5,fa),W(f7,bc),W(f6,7e)
229 .value W(d9,40),W(d8,82),W(da,c4),W(db,06),W(de,48),W(df,8a),W(dd,cc),W(dc,0e)
230 .value W(d7,50),W(d6,92),W(d4,d4),W(d5,16),W(d0,58),W(d1,9a),W(d3,dc),W(d2,1e)
231 .value W(c5,60),W(c4,a2),W(c6,e4),W(c7,26),W(c2,68),W(c3,aa),W(c1,ec),W(c0,2e)
232 .value W(cb,70),W(ca,b2),W(c8,f4),W(c9,36),W(cc,78),W(cd,ba),W(cf,fc),W(ce,3e)
233 .value W(91,80),W(90,42),W(92,04),W(93,c6),W(96,88),W(97,4a),W(95,0c),W(94,ce)
234 .value W(9f,90),W(9e,52),W(9c,14),W(9d,d6),W(98,98),W(99,5a),W(9b,1c),W(9a,de)
235 .value W(8d,a0),W(8c,62),W(8e,24),W(8f,e6),W(8a,a8),W(8b,6a),W(89,2c),W(88,ee)
236 .value W(83,b0),W(82,72),W(80,34),W(81,f6),W(84,b8),W(85,7a),W(87,3c),W(86,fe)
237 .value W(a9,c0),W(a8,02),W(aa,44),W(ab,86),W(ae,c8),W(af,0a),W(ad,4c),W(ac,8e)
238 .value W(a7,d0),W(a6,12),W(a4,54),W(a5,96),W(a0,d8),W(a1,1a),W(a3,5c),W(a2,9e)
239 .value W(b5,e0),W(b4,22),W(b6,64),W(b7,a6),W(b2,e8),W(b3,2a),W(b1,6c),W(b0,ae)
240 .value W(bb,f0),W(ba,32),W(b8,74),W(b9,b6),W(bc,f8),W(bd,3a),W(bf,7c),W(be,be)