aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-08-21 06:58:13 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-22 17:29:33 -0400
commit9bf4852d3d195f771503d5be547ac940b0b3472a (patch)
tree63508c354ec0f085afd253c204f320af7c53c451 /arch/sparc
parentfa4dfedcc23a589f953750de54eebf986336fa70 (diff)
sparc64: Add AES driver making use of the new aes opcodes.
Signed-off-by: David S. Miller <davem@davemloft.net> Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/crypto/Makefile4
-rw-r--r--arch/sparc/crypto/aes_asm.S836
-rw-r--r--arch/sparc/crypto/aes_glue.c323
3 files changed, 1163 insertions, 0 deletions
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile
index 535669828d47..5034324fdd46 100644
--- a/arch/sparc/crypto/Makefile
+++ b/arch/sparc/crypto/Makefile
@@ -7,7 +7,11 @@ obj-$(CONFIG_CRYPTO_SHA256_SPARC64) += sha256-sparc64.o
7obj-$(CONFIG_CRYPTO_SHA512_SPARC64) += sha512-sparc64.o 7obj-$(CONFIG_CRYPTO_SHA512_SPARC64) += sha512-sparc64.o
8obj-$(CONFIG_CRYPTO_MD5_SPARC64) += md5-sparc64.o 8obj-$(CONFIG_CRYPTO_MD5_SPARC64) += md5-sparc64.o
9 9
10obj-$(CONFIG_CRYPTO_AES_SPARC64) += aes-sparc64.o
11
10sha1-sparc64-y := sha1_asm.o sha1_glue.o 12sha1-sparc64-y := sha1_asm.o sha1_glue.o
11sha256-sparc64-y := sha256_asm.o sha256_glue.o 13sha256-sparc64-y := sha256_asm.o sha256_glue.o
12sha512-sparc64-y := sha512_asm.o sha512_glue.o 14sha512-sparc64-y := sha512_asm.o sha512_glue.o
13md5-sparc64-y := md5_asm.o md5_glue.o 15md5-sparc64-y := md5_asm.o md5_glue.o
16
17aes-sparc64-y := aes_asm.o aes_glue.o
diff --git a/arch/sparc/crypto/aes_asm.S b/arch/sparc/crypto/aes_asm.S
new file mode 100644
index 000000000000..f656dc7a173e
--- /dev/null
+++ b/arch/sparc/crypto/aes_asm.S
@@ -0,0 +1,836 @@
1#include <linux/linkage.h>
2#include <asm/visasm.h>
3
4#define F3F(x,y,z) (((x)<<30)|((y)<<19)|((z)<<5))
5
6#define FPD_ENCODE(x) (((x) >> 5) | ((x) & ~(0x20)))
7
8#define RS1(x) (FPD_ENCODE(x) << 14)
9#define RS2(x) (FPD_ENCODE(x) << 0)
10#define RS3(x) (FPD_ENCODE(x) << 9)
11#define RD(x) (FPD_ENCODE(x) << 25)
12#define IMM5(x) ((x) << 9)
13
14#define AES_EROUND01(a,b,c,d) \
15 .word (F3F(2, 0x19, 0)|RS1(a)|RS2(b)|RS3(c)|RD(d));
16#define AES_EROUND23(a,b,c,d) \
17 .word (F3F(2, 0x19, 1)|RS1(a)|RS2(b)|RS3(c)|RD(d));
18#define AES_DROUND01(a,b,c,d) \
19 .word (F3F(2, 0x19, 2)|RS1(a)|RS2(b)|RS3(c)|RD(d));
20#define AES_DROUND23(a,b,c,d) \
21 .word (F3F(2, 0x19, 3)|RS1(a)|RS2(b)|RS3(c)|RD(d));
22#define AES_EROUND01_L(a,b,c,d) \
23 .word (F3F(2, 0x19, 4)|RS1(a)|RS2(b)|RS3(c)|RD(d));
24#define AES_EROUND23_L(a,b,c,d) \
25 .word (F3F(2, 0x19, 5)|RS1(a)|RS2(b)|RS3(c)|RD(d));
26#define AES_DROUND01_L(a,b,c,d) \
27 .word (F3F(2, 0x19, 6)|RS1(a)|RS2(b)|RS3(c)|RD(d));
28#define AES_DROUND23_L(a,b,c,d) \
29 .word (F3F(2, 0x19, 7)|RS1(a)|RS2(b)|RS3(c)|RD(d));
30#define AES_KEXPAND1(a,b,c,d) \
31 .word (F3F(2, 0x19, 8)|RS1(a)|RS2(b)|IMM5(c)|RD(d));
32#define AES_KEXPAND0(a,b,c) \
33 .word (F3F(2, 0x36, 0x130)|RS1(a)|RS2(b)|RD(c));
34#define AES_KEXPAND2(a,b,c) \
35 .word (F3F(2, 0x36, 0x131)|RS1(a)|RS2(b)|RD(c));
36
37#define MOVXTOD_G3_F4 \
38 .word 0x89b02303;
39#define MOVXTOD_G7_F6 \
40 .word 0x8db02307;
41#define MOVXTOD_G3_F0 \
42 .word 0x81b02303;
43#define MOVXTOD_G7_F2 \
44 .word 0x85b02307;
45#define MOVXTOD_O0_F0 \
46 .word 0x81b02308;
47#define MOVXTOD_O1_F2 \
48 .word 0x85b02309;
49
50#define ENCRYPT_TWO_ROUNDS(KEY_BASE, I0, I1, T0, T1) \
51 AES_EROUND01(KEY_BASE + 0, I0, I1, T0) \
52 AES_EROUND23(KEY_BASE + 2, I0, I1, T1) \
53 AES_EROUND01(KEY_BASE + 4, T0, T1, I0) \
54 AES_EROUND23(KEY_BASE + 6, T0, T1, I1)
55
56#define ENCRYPT_TWO_ROUNDS_LAST(KEY_BASE, I0, I1, T0, T1) \
57 AES_EROUND01(KEY_BASE + 0, I0, I1, T0) \
58 AES_EROUND23(KEY_BASE + 2, I0, I1, T1) \
59 AES_EROUND01_L(KEY_BASE + 4, T0, T1, I0) \
60 AES_EROUND23_L(KEY_BASE + 6, T0, T1, I1)
61
62 /* 10 rounds */
63#define ENCRYPT_128(KEY_BASE, I0, I1, T0, T1) \
64 ENCRYPT_TWO_ROUNDS(KEY_BASE + 0, I0, I1, T0, T1) \
65 ENCRYPT_TWO_ROUNDS(KEY_BASE + 8, I0, I1, T0, T1) \
66 ENCRYPT_TWO_ROUNDS(KEY_BASE + 16, I0, I1, T0, T1) \
67 ENCRYPT_TWO_ROUNDS(KEY_BASE + 24, I0, I1, T0, T1) \
68 ENCRYPT_TWO_ROUNDS_LAST(KEY_BASE + 32, I0, I1, T0, T1)
69
70 /* 12 rounds */
71#define ENCRYPT_192(KEY_BASE, I0, I1, T0, T1) \
72 ENCRYPT_TWO_ROUNDS(KEY_BASE + 0, I0, I1, T0, T1) \
73 ENCRYPT_TWO_ROUNDS(KEY_BASE + 8, I0, I1, T0, T1) \
74 ENCRYPT_TWO_ROUNDS(KEY_BASE + 16, I0, I1, T0, T1) \
75 ENCRYPT_TWO_ROUNDS(KEY_BASE + 24, I0, I1, T0, T1) \
76 ENCRYPT_TWO_ROUNDS(KEY_BASE + 32, I0, I1, T0, T1) \
77 ENCRYPT_TWO_ROUNDS_LAST(KEY_BASE + 40, I0, I1, T0, T1)
78
79 /* 14 rounds */
80#define ENCRYPT_256(KEY_BASE, I0, I1, T0, T1) \
81 ENCRYPT_TWO_ROUNDS(KEY_BASE + 0, I0, I1, T0, T1) \
82 ENCRYPT_TWO_ROUNDS(KEY_BASE + 8, I0, I1, T0, T1) \
83 ENCRYPT_TWO_ROUNDS(KEY_BASE + 16, I0, I1, T0, T1) \
84 ENCRYPT_TWO_ROUNDS(KEY_BASE + 24, I0, I1, T0, T1) \
85 ENCRYPT_TWO_ROUNDS(KEY_BASE + 32, I0, I1, T0, T1) \
86 ENCRYPT_TWO_ROUNDS(KEY_BASE + 40, I0, I1, T0, T1) \
87 ENCRYPT_TWO_ROUNDS_LAST(KEY_BASE + 48, I0, I1, T0, T1)
88
89#define DECRYPT_TWO_ROUNDS(KEY_TOP, I0, I1, T0, T1) \
90 AES_DROUND23(KEY_TOP - 2, I0, I1, T1) \
91 AES_DROUND01(KEY_TOP - 4, I0, I1, T0) \
92 AES_DROUND23(KEY_TOP - 6, T0, T1, I1) \
93 AES_DROUND01(KEY_TOP - 8, T0, T1, I0)
94
95#define DECRYPT_TWO_ROUNDS_LAST(KEY_TOP, I0, I1, T0, T1) \
96 AES_DROUND23(KEY_TOP - 2, I0, I1, T1) \
97 AES_DROUND01(KEY_TOP - 4, I0, I1, T0) \
98 AES_DROUND23_L(KEY_TOP - 6, T0, T1, I1) \
99 AES_DROUND01_L(KEY_TOP - 8, T0, T1, I0)
100
101 /* 10 rounds */
102#define DECRYPT_128(KEY_TOP, I0, I1, T0, T1) \
103 DECRYPT_TWO_ROUNDS(KEY_TOP - 0, I0, I1, T0, T1) \
104 DECRYPT_TWO_ROUNDS(KEY_TOP - 8, I0, I1, T0, T1) \
105 DECRYPT_TWO_ROUNDS(KEY_TOP - 16, I0, I1, T0, T1) \
106 DECRYPT_TWO_ROUNDS(KEY_TOP - 24, I0, I1, T0, T1) \
107 DECRYPT_TWO_ROUNDS_LAST(KEY_TOP - 32, I0, I1, T0, T1)
108
109 /* 12 rounds */
110#define DECRYPT_192(KEY_TOP, I0, I1, T0, T1) \
111 DECRYPT_TWO_ROUNDS(KEY_TOP - 0, I0, I1, T0, T1) \
112 DECRYPT_TWO_ROUNDS(KEY_TOP - 8, I0, I1, T0, T1) \
113 DECRYPT_TWO_ROUNDS(KEY_TOP - 16, I0, I1, T0, T1) \
114 DECRYPT_TWO_ROUNDS(KEY_TOP - 24, I0, I1, T0, T1) \
115 DECRYPT_TWO_ROUNDS(KEY_TOP - 32, I0, I1, T0, T1) \
116 DECRYPT_TWO_ROUNDS_LAST(KEY_TOP - 40, I0, I1, T0, T1)
117
118 /* 14 rounds */
119#define DECRYPT_256(KEY_TOP, I0, I1, T0, T1) \
120 DECRYPT_TWO_ROUNDS(KEY_TOP - 0, I0, I1, T0, T1) \
121 DECRYPT_TWO_ROUNDS(KEY_TOP - 8, I0, I1, T0, T1) \
122 DECRYPT_TWO_ROUNDS(KEY_TOP - 16, I0, I1, T0, T1) \
123 DECRYPT_TWO_ROUNDS(KEY_TOP - 24, I0, I1, T0, T1) \
124 DECRYPT_TWO_ROUNDS(KEY_TOP - 32, I0, I1, T0, T1) \
125 DECRYPT_TWO_ROUNDS(KEY_TOP - 40, I0, I1, T0, T1) \
126 DECRYPT_TWO_ROUNDS_LAST(KEY_TOP - 48, I0, I1, T0, T1)
127
128ENTRY(aes_sparc64_key_expand)
129 /* %o0=input_key, %o1=output_key, %o2=key_len */
130 VISEntry
131 ld [%o0 + 0x00], %f0
132 ld [%o0 + 0x04], %f1
133 ld [%o0 + 0x08], %f2
134 ld [%o0 + 0x0c], %f3
135
136 std %f0, [%o1 + 0x00]
137 std %f2, [%o1 + 0x08]
138 add %o1, 0x10, %o1
139
140 cmp %o2, 24
141 bl 2f
142 nop
143
144 be 1f
145 nop
146
147 /* 256-bit key expansion */
148 ld [%o0 + 0x10], %f4
149 ld [%o0 + 0x14], %f5
150 ld [%o0 + 0x18], %f6
151 ld [%o0 + 0x1c], %f7
152
153 std %f4, [%o1 + 0x00]
154 std %f6, [%o1 + 0x08]
155 add %o1, 0x10, %o1
156
157 AES_KEXPAND1(0, 6, 0x0, 8)
158 AES_KEXPAND2(2, 8, 10)
159 AES_KEXPAND0(4, 10, 12)
160 AES_KEXPAND2(6, 12, 14)
161 AES_KEXPAND1(8, 14, 0x1, 16)
162 AES_KEXPAND2(10, 16, 18)
163 AES_KEXPAND0(12, 18, 20)
164 AES_KEXPAND2(14, 20, 22)
165 AES_KEXPAND1(16, 22, 0x2, 24)
166 AES_KEXPAND2(18, 24, 26)
167 AES_KEXPAND0(20, 26, 28)
168 AES_KEXPAND2(22, 28, 30)
169 AES_KEXPAND1(24, 30, 0x3, 32)
170 AES_KEXPAND2(26, 32, 34)
171 AES_KEXPAND0(28, 34, 36)
172 AES_KEXPAND2(30, 36, 38)
173 AES_KEXPAND1(32, 38, 0x4, 40)
174 AES_KEXPAND2(34, 40, 42)
175 AES_KEXPAND0(36, 42, 44)
176 AES_KEXPAND2(38, 44, 46)
177 AES_KEXPAND1(40, 46, 0x5, 48)
178 AES_KEXPAND2(42, 48, 50)
179 AES_KEXPAND0(44, 50, 52)
180 AES_KEXPAND2(46, 52, 54)
181 AES_KEXPAND1(48, 54, 0x6, 56)
182 AES_KEXPAND2(50, 56, 58)
183
184 std %f8, [%o1 + 0x00]
185 std %f10, [%o1 + 0x08]
186 std %f12, [%o1 + 0x10]
187 std %f14, [%o1 + 0x18]
188 std %f16, [%o1 + 0x20]
189 std %f18, [%o1 + 0x28]
190 std %f20, [%o1 + 0x30]
191 std %f22, [%o1 + 0x38]
192 std %f24, [%o1 + 0x40]
193 std %f26, [%o1 + 0x48]
194 std %f28, [%o1 + 0x50]
195 std %f30, [%o1 + 0x58]
196 std %f32, [%o1 + 0x60]
197 std %f34, [%o1 + 0x68]
198 std %f36, [%o1 + 0x70]
199 std %f38, [%o1 + 0x78]
200 std %f40, [%o1 + 0x80]
201 std %f42, [%o1 + 0x88]
202 std %f44, [%o1 + 0x90]
203 std %f46, [%o1 + 0x98]
204 std %f48, [%o1 + 0xa0]
205 std %f50, [%o1 + 0xa8]
206 std %f52, [%o1 + 0xb0]
207 std %f54, [%o1 + 0xb8]
208 std %f56, [%o1 + 0xc0]
209 ba,pt %xcc, 80f
210 std %f58, [%o1 + 0xc8]
211
2121:
213 /* 192-bit key expansion */
214 ld [%o0 + 0x10], %f4
215 ld [%o0 + 0x14], %f5
216
217 std %f4, [%o1 + 0x00]
218 add %o1, 0x08, %o1
219
220 AES_KEXPAND1(0, 4, 0x0, 6)
221 AES_KEXPAND2(2, 6, 8)
222 AES_KEXPAND2(4, 8, 10)
223 AES_KEXPAND1(6, 10, 0x1, 12)
224 AES_KEXPAND2(8, 12, 14)
225 AES_KEXPAND2(10, 14, 16)
226 AES_KEXPAND1(12, 16, 0x2, 18)
227 AES_KEXPAND2(14, 18, 20)
228 AES_KEXPAND2(16, 20, 22)
229 AES_KEXPAND1(18, 22, 0x3, 24)
230 AES_KEXPAND2(20, 24, 26)
231 AES_KEXPAND2(22, 26, 28)
232 AES_KEXPAND1(24, 28, 0x4, 30)
233 AES_KEXPAND2(26, 30, 32)
234 AES_KEXPAND2(28, 32, 34)
235 AES_KEXPAND1(30, 34, 0x5, 36)
236 AES_KEXPAND2(32, 36, 38)
237 AES_KEXPAND2(34, 38, 40)
238 AES_KEXPAND1(36, 40, 0x6, 42)
239 AES_KEXPAND2(38, 42, 44)
240 AES_KEXPAND2(40, 44, 46)
241 AES_KEXPAND1(42, 46, 0x7, 48)
242 AES_KEXPAND2(44, 48, 50)
243
244 std %f6, [%o1 + 0x00]
245 std %f8, [%o1 + 0x08]
246 std %f10, [%o1 + 0x10]
247 std %f12, [%o1 + 0x18]
248 std %f14, [%o1 + 0x20]
249 std %f16, [%o1 + 0x28]
250 std %f18, [%o1 + 0x30]
251 std %f20, [%o1 + 0x38]
252 std %f22, [%o1 + 0x40]
253 std %f24, [%o1 + 0x48]
254 std %f26, [%o1 + 0x50]
255 std %f28, [%o1 + 0x58]
256 std %f30, [%o1 + 0x60]
257 std %f32, [%o1 + 0x68]
258 std %f34, [%o1 + 0x70]
259 std %f36, [%o1 + 0x78]
260 std %f38, [%o1 + 0x80]
261 std %f40, [%o1 + 0x88]
262 std %f42, [%o1 + 0x90]
263 std %f44, [%o1 + 0x98]
264 std %f46, [%o1 + 0xa0]
265 std %f48, [%o1 + 0xa8]
266 ba,pt %xcc, 80f
267 std %f50, [%o1 + 0xb0]
268
2692:
270 /* 128-bit key expansion */
271 AES_KEXPAND1(0, 2, 0x0, 4)
272 AES_KEXPAND2(2, 4, 6)
273 AES_KEXPAND1(4, 6, 0x1, 8)
274 AES_KEXPAND2(6, 8, 10)
275 AES_KEXPAND1(8, 10, 0x2, 12)
276 AES_KEXPAND2(10, 12, 14)
277 AES_KEXPAND1(12, 14, 0x3, 16)
278 AES_KEXPAND2(14, 16, 18)
279 AES_KEXPAND1(16, 18, 0x4, 20)
280 AES_KEXPAND2(18, 20, 22)
281 AES_KEXPAND1(20, 22, 0x5, 24)
282 AES_KEXPAND2(22, 24, 26)
283 AES_KEXPAND1(24, 26, 0x6, 28)
284 AES_KEXPAND2(26, 28, 30)
285 AES_KEXPAND1(28, 30, 0x7, 32)
286 AES_KEXPAND2(30, 32, 34)
287 AES_KEXPAND1(32, 34, 0x8, 36)
288 AES_KEXPAND2(34, 36, 38)
289 AES_KEXPAND1(36, 38, 0x9, 40)
290 AES_KEXPAND2(38, 40, 42)
291
292 std %f4, [%o1 + 0x00]
293 std %f6, [%o1 + 0x08]
294 std %f8, [%o1 + 0x10]
295 std %f10, [%o1 + 0x18]
296 std %f12, [%o1 + 0x20]
297 std %f14, [%o1 + 0x28]
298 std %f16, [%o1 + 0x30]
299 std %f18, [%o1 + 0x38]
300 std %f20, [%o1 + 0x40]
301 std %f22, [%o1 + 0x48]
302 std %f24, [%o1 + 0x50]
303 std %f26, [%o1 + 0x58]
304 std %f28, [%o1 + 0x60]
305 std %f30, [%o1 + 0x68]
306 std %f32, [%o1 + 0x70]
307 std %f34, [%o1 + 0x78]
308 std %f36, [%o1 + 0x80]
309 std %f38, [%o1 + 0x88]
310 std %f40, [%o1 + 0x90]
311 std %f42, [%o1 + 0x98]
31280:
313 retl
314 VISExit
315ENDPROC(aes_sparc64_key_expand)
316
317ENTRY(aes_sparc64_encrypt)
318 /* %o0=key, %o1=input, %o2=output, %o3=key_len */
319 VISEntry
320 ld [%o1 + 0x00], %f4
321 ld [%o1 + 0x04], %f5
322 ld [%o1 + 0x08], %f6
323 ld [%o1 + 0x0c], %f7
324
325 ldd [%o0 + 0x00], %f8
326 ldd [%o0 + 0x08], %f10
327 cmp %o3, 24
328 fxor %f8, %f4, %f4
329 bl 2f
330 fxor %f10, %f6, %f6
331
332 be 1f
333 ldd [%o0 + 0x10], %f8
334
335 ldd [%o0 + 0x18], %f10
336 ldd [%o0 + 0x20], %f12
337 ldd [%o0 + 0x28], %f14
338 add %o0, 0x20, %o0
339
340 ENCRYPT_TWO_ROUNDS(8, 4, 6, 0, 2)
341
342 ldd [%o0 + 0x10], %f8
343
3441:
345 ldd [%o0 + 0x18], %f10
346 ldd [%o0 + 0x20], %f12
347 ldd [%o0 + 0x28], %f14
348 add %o0, 0x20, %o0
349
350 ENCRYPT_TWO_ROUNDS(8, 4, 6, 0, 2)
351
3522:
353 ldd [%o0 + 0x10], %f12
354 ldd [%o0 + 0x18], %f14
355 ldd [%o0 + 0x20], %f16
356 ldd [%o0 + 0x28], %f18
357 ldd [%o0 + 0x30], %f20
358 ldd [%o0 + 0x38], %f22
359 ldd [%o0 + 0x40], %f24
360 ldd [%o0 + 0x48], %f26
361 ldd [%o0 + 0x50], %f28
362 ldd [%o0 + 0x58], %f30
363 ldd [%o0 + 0x60], %f32
364 ldd [%o0 + 0x68], %f34
365 ldd [%o0 + 0x70], %f36
366 ldd [%o0 + 0x78], %f38
367 ldd [%o0 + 0x80], %f40
368 ldd [%o0 + 0x88], %f42
369 ldd [%o0 + 0x90], %f44
370 ldd [%o0 + 0x98], %f46
371 ldd [%o0 + 0xa0], %f48
372 ldd [%o0 + 0xa8], %f50
373
374
375 ENCRYPT_128(12, 4, 6, 0, 2)
376
377 st %f4, [%o2 + 0x00]
378 st %f5, [%o2 + 0x04]
379 st %f6, [%o2 + 0x08]
380 st %f7, [%o2 + 0x0c]
381
382 retl
383 VISExit
384ENDPROC(aes_sparc64_encrypt)
385
386ENTRY(aes_sparc64_decrypt)
387 /* %o0=key, %o1=input, %o2=output, %o3=key_len, %o4=exp_key_len */
388 VISEntry
389 ld [%o1 + 0x00], %f4
390 add %o0, %o4, %o0
391 ld [%o1 + 0x04], %f5
392 ld [%o1 + 0x08], %f6
393 ld [%o1 + 0x0c], %f7
394
395 ldd [%o0 - 0x08], %f8
396 ldd [%o0 - 0x10], %f10
397
398 cmp %o3, 24
399 fxor %f10, %f4, %f4
400 bl 2f
401 fxor %f8, %f6, %f6
402
403 be 1f
404 ldd [%o0 - 0x30], %f8
405
406 ldd [%o0 - 0x28], %f10
407 ldd [%o0 - 0x20], %f12
408 ldd [%o0 - 0x18], %f14
409 sub %o0, 0x20, %o0
410
411 DECRYPT_TWO_ROUNDS(16, 4, 6, 0, 2)
412
413 ldd [%o0 - 0x30], %f8
4141:
415 ldd [%o0 - 0x28], %f10
416 ldd [%o0 - 0x20], %f12
417 ldd [%o0 - 0x18], %f14
418 sub %o0, 0x20, %o0
419
420 DECRYPT_TWO_ROUNDS(16, 4, 6, 0, 2)
4212:
422 ldd [%o0 - 0xb0], %f12
423 ldd [%o0 - 0xa8], %f14
424 ldd [%o0 - 0xa0], %f16
425 ldd [%o0 - 0x98], %f18
426 ldd [%o0 - 0x90], %f20
427 ldd [%o0 - 0x88], %f22
428 ldd [%o0 - 0x80], %f24
429 ldd [%o0 - 0x78], %f26
430 ldd [%o0 - 0x70], %f28
431 ldd [%o0 - 0x68], %f30
432 ldd [%o0 - 0x60], %f32
433 ldd [%o0 - 0x58], %f34
434 ldd [%o0 - 0x50], %f36
435 ldd [%o0 - 0x48], %f38
436 ldd [%o0 - 0x40], %f40
437 ldd [%o0 - 0x38], %f42
438 ldd [%o0 - 0x30], %f44
439 ldd [%o0 - 0x28], %f46
440 ldd [%o0 - 0x20], %f48
441 ldd [%o0 - 0x18], %f50
442
443 DECRYPT_128(52, 4, 6, 0, 2)
444
445 st %f4, [%o2 + 0x00]
446 st %f5, [%o2 + 0x04]
447 st %f6, [%o2 + 0x08]
448 st %f7, [%o2 + 0x0c]
449
450 retl
451 VISExit
452ENDPROC(aes_sparc64_decrypt)
453
454ENTRY(aes_sparc64_load_decrypt_keys)
455 /* %o0=key */
456 ba,pt %xcc, aes_sparc64_load_encrypt_keys
457 sub %o0, 0x10, %o0
458ENDPROC(aes_sparc64_load_decrypt_keys)
459
460ENTRY(aes_sparc64_load_encrypt_keys)
461 /* %o0=key */
462 VISEntry
463 ldd [%o0 + 0x10], %f8
464 ldd [%o0 + 0x18], %f10
465 ldd [%o0 + 0x20], %f12
466 ldd [%o0 + 0x28], %f14
467 ldd [%o0 + 0x30], %f16
468 ldd [%o0 + 0x38], %f18
469 ldd [%o0 + 0x40], %f20
470 ldd [%o0 + 0x48], %f22
471 ldd [%o0 + 0x50], %f24
472 ldd [%o0 + 0x58], %f26
473 ldd [%o0 + 0x60], %f28
474 ldd [%o0 + 0x68], %f30
475 ldd [%o0 + 0x70], %f32
476 ldd [%o0 + 0x78], %f34
477 ldd [%o0 + 0x80], %f36
478 ldd [%o0 + 0x88], %f38
479 ldd [%o0 + 0x90], %f40
480 ldd [%o0 + 0x98], %f42
481 ldd [%o0 + 0xa0], %f44
482 ldd [%o0 + 0xa8], %f46
483 ldd [%o0 + 0xb0], %f48
484 ldd [%o0 + 0xb8], %f50
485 ldd [%o0 + 0xc0], %f52
486 ldd [%o0 + 0xc8], %f54
487 ldd [%o0 + 0xd0], %f56
488 ldd [%o0 + 0xd8], %f58
489 ldd [%o0 + 0xe0], %f60
490 retl
491 ldd [%o0 + 0xe8], %f62
492ENDPROC(aes_sparc64_load_encrypt_keys)
493
494ENTRY(aes_sparc64_ecb_encrypt)
495 /* %o0=key, %o1=input, %o2=output, %o3=key_len, %o4=len */
496 ldx [%o0 + 0x00], %g1
497 ldx [%o0 + 0x08], %g2
498 cmp %o3, 24
499 bl 2f
500 nop
501 be 1f
502 nop
503
5040:
505 /* 256-bit key */
506 ldx [%o1 + 0x00], %g3
507 ldx [%o1 + 0x08], %g7
508 add %o1, 0x10, %o1
509 xor %g1, %g3, %g3
510 xor %g2, %g7, %g7
511 MOVXTOD_G3_F4
512 MOVXTOD_G7_F6
513
514 ENCRYPT_256(8, 4, 6, 0, 2)
515
516 std %f4, [%o2 + 0x00]
517 std %f6, [%o2 + 0x08]
518 subcc %o4, 0x10, %o4
519 bne,pt %xcc, 0b
520 add %o2, 0x10, %o2
521
522 retl
523 nop
524
5251:
526 /* 192-bit key */
527 ldx [%o1 + 0x00], %g3
528 ldx [%o1 + 0x08], %g7
529 add %o1, 0x10, %o1
530 xor %g1, %g3, %g3
531 xor %g2, %g7, %g7
532 MOVXTOD_G3_F4
533 MOVXTOD_G7_F6
534
535 ENCRYPT_192(8, 4, 6, 0, 2)
536
537 std %f4, [%o2 + 0x00]
538 std %f6, [%o2 + 0x08]
539 subcc %o4, 0x10, %o4
540 bne,pt %xcc, 1b
541 add %o2, 0x10, %o2
542
543 retl
544 nop
545
5462:
547 /* 128-bit key */
548 ldx [%o1 + 0x00], %g3
549 ldx [%o1 + 0x08], %g7
550 add %o1, 0x10, %o1
551 xor %g1, %g3, %g3
552 xor %g2, %g7, %g7
553 MOVXTOD_G3_F4
554 MOVXTOD_G7_F6
555
556 ENCRYPT_128(8, 4, 6, 0, 2)
557
558 std %f4, [%o2 + 0x00]
559 std %f6, [%o2 + 0x08]
560 subcc %o4, 0x10, %o4
561 bne,pt %xcc, 2b
562 add %o2, 0x10, %o2
563
564 retl
565 nop
566ENDPROC(aes_sparc64_ecb_encrypt)
567
568ENTRY(aes_sparc64_ecb_decrypt)
569 /* %o0=&key[key_len], %o1=input, %o2=output, %o3=key_len, %o4=len, %o5=iv */
570 ldx [%o0 - 0x10], %g1
571 ldx [%o0 - 0x08], %g2
572 cmp %o3, 24
573 bl 2f
574 nop
575 be 1f
576 nop
577
5780:
579 /* 256-bit key */
580 ldx [%o1 + 0x00], %g3
581 ldx [%o1 + 0x08], %g7
582 add %o1, 0x10, %o1
583 xor %g1, %g3, %g3
584 xor %g2, %g7, %g7
585 MOVXTOD_G3_F4
586 MOVXTOD_G7_F6
587
588 DECRYPT_256(64, 4, 6, 0, 2)
589
590 std %f4, [%o2 + 0x00]
591 std %f6, [%o2 + 0x08]
592 subcc %o4, 0x10, %o4
593 bne,pt %xcc, 0b
594 add %o2, 0x10, %o2
595
596 retl
597 nop
598
5991:
600 /* 192-bit key */
601 ldx [%o1 + 0x00], %g3
602 ldx [%o1 + 0x08], %g7
603 add %o1, 0x10, %o1
604 xor %g1, %g3, %g3
605 xor %g2, %g7, %g7
606 MOVXTOD_G3_F4
607 MOVXTOD_G7_F6
608
609 DECRYPT_192(56, 4, 6, 0, 2)
610
611 std %f4, [%o2 + 0x00]
612 std %f6, [%o2 + 0x08]
613 subcc %o4, 0x10, %o4
614 bne,pt %xcc, 1b
615 add %o2, 0x10, %o2
616
617 retl
618 nop
619
6202:
621 /* 128-bit key */
622 ldx [%o1 + 0x00], %g3
623 ldx [%o1 + 0x08], %g7
624 add %o1, 0x10, %o1
625 xor %g1, %g3, %g3
626 xor %g2, %g7, %g7
627 MOVXTOD_G3_F4
628 MOVXTOD_G7_F6
629
630 DECRYPT_128(48, 4, 6, 0, 2)
631
632 std %f4, [%o2 + 0x00]
633 std %f6, [%o2 + 0x08]
634 subcc %o4, 0x10, %o4
635 bne,pt %xcc, 2b
636 add %o2, 0x10, %o2
637
638 retl
639 nop
640ENDPROC(aes_sparc64_ecb_decrypt)
641
642ENTRY(aes_sparc64_cbc_encrypt)
643 /* %o0=key, %o1=input, %o2=output, %o3=key_len, %o4=len */
644 ldd [%o5 + 0x00], %f4
645 ldd [%o5 + 0x08], %f6
646 ldx [%o0 + 0x00], %g1
647 ldx [%o0 + 0x08], %g2
648 cmp %o3, 24
649 bl 2f
650 nop
651 be 1f
652 nop
653
6540:
655 /* 256-bit key */
656 ldx [%o1 + 0x00], %g3
657 ldx [%o1 + 0x08], %g7
658 add %o1, 0x10, %o1
659 xor %g1, %g3, %g3
660 xor %g2, %g7, %g7
661 MOVXTOD_G3_F0
662 MOVXTOD_G7_F2
663 fxor %f4, %f0, %f4
664 fxor %f6, %f2, %f6
665
666 ENCRYPT_256(8, 4, 6, 0, 2)
667
668 std %f4, [%o2 + 0x00]
669 std %f6, [%o2 + 0x08]
670 subcc %o4, 0x10, %o4
671 bne,pt %xcc, 0b
672 add %o2, 0x10, %o2
673
674 std %f4, [%o5 + 0x00]
675 std %f6, [%o5 + 0x08]
676
677 retl
678 nop
679
6801:
681 /* 192-bit key */
682 ldx [%o1 + 0x00], %g3
683 ldx [%o1 + 0x08], %g7
684 add %o1, 0x10, %o1
685 xor %g1, %g3, %g3
686 xor %g2, %g7, %g7
687 MOVXTOD_G3_F0
688 MOVXTOD_G7_F2
689 fxor %f4, %f0, %f4
690 fxor %f6, %f2, %f6
691
692 ENCRYPT_192(8, 4, 6, 0, 2)
693
694 std %f4, [%o2 + 0x00]
695 std %f6, [%o2 + 0x08]
696 subcc %o4, 0x10, %o4
697 bne,pt %xcc, 1b
698 add %o2, 0x10, %o2
699
700 std %f4, [%o5 + 0x00]
701 std %f6, [%o5 + 0x08]
702
703 retl
704 nop
705
7062:
707 /* 128-bit key */
708 ldx [%o1 + 0x00], %g3
709 ldx [%o1 + 0x08], %g7
710 add %o1, 0x10, %o1
711 xor %g1, %g3, %g3
712 xor %g2, %g7, %g7
713 MOVXTOD_G3_F0
714 MOVXTOD_G7_F2
715 fxor %f4, %f0, %f4
716 fxor %f6, %f2, %f6
717
718 ENCRYPT_128(8, 4, 6, 0, 2)
719
720 std %f4, [%o2 + 0x00]
721 std %f6, [%o2 + 0x08]
722 subcc %o4, 0x10, %o4
723 bne,pt %xcc, 2b
724 add %o2, 0x10, %o2
725
726 std %f4, [%o5 + 0x00]
727 std %f6, [%o5 + 0x08]
728
729 retl
730 nop
731ENDPROC(aes_sparc64_cbc_encrypt)
732
733ENTRY(aes_sparc64_cbc_decrypt)
734 /* %o0=&key[key_len], %o1=key_len, %o2=input, %o3=output, %o4=len, %o5=iv */
735 ldx [%o0 - 0x10], %g1
736 ldx [%o0 - 0x08], %g2
737 cmp %o1, 24
738 ldx [%o5 + 0x00], %o0
739 bl 2f
740 ldx [%o5 + 0x08], %o1
741 be 1f
742 nop
743
7440:
745 /* 256-bit key */
746 ldx [%o2 + 0x00], %g3
747 ldx [%o2 + 0x08], %g7
748 add %o2, 0x10, %o2
749 xor %g1, %g3, %g3
750 xor %g2, %g7, %g7
751 MOVXTOD_G3_F4
752 MOVXTOD_G7_F6
753
754 DECRYPT_256(64, 4, 6, 0, 2)
755
756 MOVXTOD_O0_F0
757 MOVXTOD_O1_F2
758 xor %g1, %g3, %o0
759 xor %g2, %g7, %o1
760 fxor %f4, %f0, %f4
761 fxor %f6, %f2, %f6
762
763 std %f4, [%o3 + 0x00]
764 std %f6, [%o3 + 0x08]
765 subcc %o4, 0x10, %o4
766 bne,pt %xcc, 0b
767 add %o3, 0x10, %o3
768
769 stx %o0, [%o5 + 0x00]
770 stx %o1, [%o5 + 0x08]
771
772 retl
773 nop
774
7751:
776 /* 192-bit key */
777 ldx [%o2 + 0x00], %g3
778 ldx [%o2 + 0x08], %g7
779 add %o2, 0x10, %o2
780 xor %g1, %g3, %g3
781 xor %g2, %g7, %g7
782 MOVXTOD_G3_F4
783 MOVXTOD_G7_F6
784
785 DECRYPT_192(56, 4, 6, 0, 2)
786
787 MOVXTOD_O0_F0
788 MOVXTOD_O1_F2
789 xor %g1, %g3, %o0
790 xor %g2, %g7, %o1
791 fxor %f4, %f0, %f4
792 fxor %f6, %f2, %f6
793
794 std %f4, [%o3 + 0x00]
795 std %f6, [%o3 + 0x08]
796 subcc %o4, 0x10, %o4
797 bne,pt %xcc, 1b
798 add %o3, 0x10, %o3
799
800 stx %o0, [%o5 + 0x00]
801 stx %o1, [%o5 + 0x08]
802
803 retl
804 nop
805
8062:
807 /* 128-bit key */
808 ldx [%o2 + 0x00], %g3
809 ldx [%o2 + 0x08], %g7
810 add %o2, 0x10, %o2
811 xor %g1, %g3, %g3
812 xor %g2, %g7, %g7
813 MOVXTOD_G3_F4
814 MOVXTOD_G7_F6
815
816 DECRYPT_128(48, 4, 6, 0, 2)
817
818 MOVXTOD_O0_F0
819 MOVXTOD_O1_F2
820 xor %g1, %g3, %o0
821 xor %g2, %g7, %o1
822 fxor %f4, %f0, %f4
823 fxor %f6, %f2, %f6
824
825 std %f4, [%o3 + 0x00]
826 std %f6, [%o3 + 0x08]
827 subcc %o4, 0x10, %o4
828 bne,pt %xcc, 2b
829 add %o3, 0x10, %o3
830
831 stx %o0, [%o5 + 0x00]
832 stx %o1, [%o5 + 0x08]
833
834 retl
835 nop
836ENDPROC(aes_sparc64_cbc_decrypt)
diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c
new file mode 100644
index 000000000000..a87c5fa76e20
--- /dev/null
+++ b/arch/sparc/crypto/aes_glue.c
@@ -0,0 +1,323 @@
1/* Glue code for AES encryption optimized for sparc64 crypto opcodes.
2 *
3 * This is based largely upon arch/x86/crypto/aesni-intel_glue.c
4 *
5 * Copyright (C) 2008, Intel Corp.
6 * Author: Huang Ying <ying.huang@intel.com>
7 *
8 * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD
9 * interface for 64-bit kernels.
10 * Authors: Adrian Hoban <adrian.hoban@intel.com>
11 * Gabriele Paoloni <gabriele.paoloni@intel.com>
12 * Tadeusz Struk (tadeusz.struk@intel.com)
13 * Aidan O'Mahony (aidan.o.mahony@intel.com)
14 * Copyright (c) 2010, Intel Corporation.
15 */
16
17#include <linux/crypto.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/mm.h>
21#include <linux/types.h>
22#include <crypto/algapi.h>
23#include <crypto/aes.h>
24
25#include <asm/fpumacro.h>
26#include <asm/pstate.h>
27#include <asm/elf.h>
28
29struct crypto_sparc64_aes_ctx {
30 u64 key[AES_MAX_KEYLENGTH / sizeof(u64)];
31 u32 key_length;
32 u32 expanded_key_length;
33};
34
35extern void aes_sparc64_key_expand(const u32 *in_key, u64 *output_key,
36 unsigned int key_len);
37
38static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
39 unsigned int key_len)
40{
41 struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
42 u32 *flags = &tfm->crt_flags;
43
44 switch (key_len) {
45 case AES_KEYSIZE_128:
46 ctx->expanded_key_length = 0xb0;
47 break;
48
49 case AES_KEYSIZE_192:
50 ctx->expanded_key_length = 0xd0;
51 break;
52
53 case AES_KEYSIZE_256:
54 ctx->expanded_key_length = 0xf0;
55 break;
56
57 default:
58 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
59 return -EINVAL;
60 }
61
62 aes_sparc64_key_expand((const u32 *)in_key, &ctx->key[0], key_len);
63 ctx->key_length = key_len;
64
65 return 0;
66}
67
68extern void aes_sparc64_encrypt(const u64 *key, const u32 *input,
69 u32 *output, unsigned int key_len);
70
71static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
72{
73 struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
74
75 aes_sparc64_encrypt(&ctx->key[0], (const u32 *) src,
76 (u32 *) dst, ctx->key_length);
77}
78
79extern void aes_sparc64_decrypt(const u64 *key, const u32 *input,
80 u32 *output, unsigned int key_len,
81 unsigned int expanded_key_len);
82
83static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
84{
85 struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
86
87 aes_sparc64_decrypt(&ctx->key[0], (const u32 *) src,
88 (u32 *) dst, ctx->key_length,
89 ctx->expanded_key_length);
90}
91
92extern void aes_sparc64_load_encrypt_keys(u64 *key);
93extern void aes_sparc64_load_decrypt_keys(u64 *key);
94
95#define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1))
96
97extern void aes_sparc64_ecb_encrypt(u64 *key, const u32 *input, u32 *output,
98 unsigned int key_len, unsigned int len);
99
100static int ecb_encrypt(struct blkcipher_desc *desc,
101 struct scatterlist *dst, struct scatterlist *src,
102 unsigned int nbytes)
103{
104 struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
105 struct blkcipher_walk walk;
106 int err;
107
108 blkcipher_walk_init(&walk, dst, src, nbytes);
109 err = blkcipher_walk_virt(desc, &walk);
110
111 aes_sparc64_load_encrypt_keys(&ctx->key[0]);
112 while ((nbytes = walk.nbytes)) {
113 unsigned int block_len = nbytes & AES_BLOCK_MASK;
114
115 if (likely(block_len)) {
116 aes_sparc64_ecb_encrypt(&ctx->key[0],
117 (const u32 *)walk.src.virt.addr,
118 (u32 *) walk.dst.virt.addr,
119 ctx->key_length, block_len);
120 }
121 nbytes &= AES_BLOCK_SIZE - 1;
122 err = blkcipher_walk_done(desc, &walk, nbytes);
123 }
124 fprs_write(0);
125 return err;
126}
127
128extern void aes_sparc64_ecb_decrypt(u64 *ekey, const u32 *input, u32 *output,
129 unsigned int key_len, unsigned int len);
130
131static int ecb_decrypt(struct blkcipher_desc *desc,
132 struct scatterlist *dst, struct scatterlist *src,
133 unsigned int nbytes)
134{
135 struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
136 struct blkcipher_walk walk;
137 u64 *key_end;
138 int err;
139
140 blkcipher_walk_init(&walk, dst, src, nbytes);
141 err = blkcipher_walk_virt(desc, &walk);
142
143 aes_sparc64_load_decrypt_keys(&ctx->key[0]);
144 key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)];
145 while ((nbytes = walk.nbytes)) {
146 unsigned int block_len = nbytes & AES_BLOCK_MASK;
147
148 aes_sparc64_ecb_decrypt(key_end, (const u32 *) walk.src.virt.addr,
149 (u32 *) walk.dst.virt.addr, ctx->key_length,
150 block_len);
151 nbytes &= AES_BLOCK_SIZE - 1;
152 err = blkcipher_walk_done(desc, &walk, nbytes);
153 }
154 fprs_write(0);
155
156 return err;
157}
158
159extern void aes_sparc64_cbc_encrypt(u64 *key, const u32 *input, u32 *output,
160 unsigned int key_len, unsigned int len,
161 u64 *iv);
162
163static int cbc_encrypt(struct blkcipher_desc *desc,
164 struct scatterlist *dst, struct scatterlist *src,
165 unsigned int nbytes)
166{
167 struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
168 struct blkcipher_walk walk;
169 int err;
170
171 blkcipher_walk_init(&walk, dst, src, nbytes);
172 err = blkcipher_walk_virt(desc, &walk);
173
174 aes_sparc64_load_encrypt_keys(&ctx->key[0]);
175 while ((nbytes = walk.nbytes)) {
176 unsigned int block_len = nbytes & AES_BLOCK_MASK;
177
178 if (likely(block_len)) {
179 aes_sparc64_cbc_encrypt(&ctx->key[0],
180 (const u32 *)walk.src.virt.addr,
181 (u32 *) walk.dst.virt.addr,
182 ctx->key_length, block_len,
183 (u64 *) walk.iv);
184 }
185 nbytes &= AES_BLOCK_SIZE - 1;
186 err = blkcipher_walk_done(desc, &walk, nbytes);
187 }
188 fprs_write(0);
189 return err;
190}
191
192extern void aes_sparc64_cbc_decrypt(u64 *ekey, unsigned int key_len,
193 const u32 *input, u32 *output,
194 unsigned int len, u64 *iv);
195
196static int cbc_decrypt(struct blkcipher_desc *desc,
197 struct scatterlist *dst, struct scatterlist *src,
198 unsigned int nbytes)
199{
200 struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
201 struct blkcipher_walk walk;
202 u64 *key_end;
203 int err;
204
205 blkcipher_walk_init(&walk, dst, src, nbytes);
206 err = blkcipher_walk_virt(desc, &walk);
207
208 aes_sparc64_load_decrypt_keys(&ctx->key[0]);
209 key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)];
210 while ((nbytes = walk.nbytes)) {
211 unsigned int block_len = nbytes & AES_BLOCK_MASK;
212
213 aes_sparc64_cbc_decrypt(key_end, ctx->key_length,
214 (const u32 *) walk.src.virt.addr,
215 (u32 *) walk.dst.virt.addr,
216 block_len, (u64 *) walk.iv);
217 nbytes &= AES_BLOCK_SIZE - 1;
218 err = blkcipher_walk_done(desc, &walk, nbytes);
219 }
220 fprs_write(0);
221
222 return err;
223}
224
225static struct crypto_alg algs[] = { {
226 .cra_name = "aes",
227 .cra_driver_name = "aes-sparc64",
228 .cra_priority = 150,
229 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
230 .cra_blocksize = AES_BLOCK_SIZE,
231 .cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx),
232 .cra_alignmask = 3,
233 .cra_module = THIS_MODULE,
234 .cra_u = {
235 .cipher = {
236 .cia_min_keysize = AES_MIN_KEY_SIZE,
237 .cia_max_keysize = AES_MAX_KEY_SIZE,
238 .cia_setkey = aes_set_key,
239 .cia_encrypt = aes_encrypt,
240 .cia_decrypt = aes_decrypt
241 }
242 }
243}, {
244 .cra_name = "ecb(aes)",
245 .cra_driver_name = "ecb-aes-sparc64",
246 .cra_priority = 150,
247 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
248 .cra_blocksize = AES_BLOCK_SIZE,
249 .cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx),
250 .cra_alignmask = 7,
251 .cra_type = &crypto_blkcipher_type,
252 .cra_module = THIS_MODULE,
253 .cra_u = {
254 .blkcipher = {
255 .min_keysize = AES_MIN_KEY_SIZE,
256 .max_keysize = AES_MAX_KEY_SIZE,
257 .setkey = aes_set_key,
258 .encrypt = ecb_encrypt,
259 .decrypt = ecb_decrypt,
260 },
261 },
262}, {
263 .cra_name = "cbc(aes)",
264 .cra_driver_name = "cbc-aes-sparc64",
265 .cra_priority = 150,
266 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
267 .cra_blocksize = AES_BLOCK_SIZE,
268 .cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx),
269 .cra_alignmask = 7,
270 .cra_type = &crypto_blkcipher_type,
271 .cra_module = THIS_MODULE,
272 .cra_u = {
273 .blkcipher = {
274 .min_keysize = AES_MIN_KEY_SIZE,
275 .max_keysize = AES_MAX_KEY_SIZE,
276 .setkey = aes_set_key,
277 .encrypt = cbc_encrypt,
278 .decrypt = cbc_decrypt,
279 },
280 },
281} };
282
283static bool __init sparc64_has_aes_opcode(void)
284{
285 unsigned long cfr;
286
287 if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
288 return false;
289
290 __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
291 if (!(cfr & CFR_AES))
292 return false;
293
294 return true;
295}
296
297static int __init aes_sparc64_mod_init(void)
298{
299 int i;
300
301 for (i = 0; i < ARRAY_SIZE(algs); i++)
302 INIT_LIST_HEAD(&algs[i].cra_list);
303
304 if (sparc64_has_aes_opcode()) {
305 pr_info("Using sparc64 aes opcodes optimized AES implementation\n");
306 return crypto_register_algs(algs, ARRAY_SIZE(algs));
307 }
308 pr_info("sparc64 aes opcodes not available.\n");
309 return -ENODEV;
310}
311
312static void __exit aes_sparc64_mod_fini(void)
313{
314 crypto_unregister_algs(algs, ARRAY_SIZE(algs));
315}
316
317module_init(aes_sparc64_mod_init);
318module_exit(aes_sparc64_mod_fini);
319
320MODULE_LICENSE("GPL");
321MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated");
322
323MODULE_ALIAS("aes");