aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--crypto/Kconfig28
4 files changed, 1191 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");
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4cb1ab04168f..49f867b2025d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -624,6 +624,34 @@ config CRYPTO_AES_NI_INTEL
624 ECB, CBC, LRW, PCBC, XTS. The 64 bit version has additional 624 ECB, CBC, LRW, PCBC, XTS. The 64 bit version has additional
625 acceleration for CTR. 625 acceleration for CTR.
626 626
627config CRYPTO_AES_SPARC64
628 tristate "AES cipher algorithms (SPARC64)"
629 depends on SPARC64
630 select CRYPTO_CRYPTD
631 select CRYPTO_ALGAPI
632 help
633 Use SPARC64 crypto opcodes for AES algorithm.
634
635 AES cipher algorithms (FIPS-197). AES uses the Rijndael
636 algorithm.
637
638 Rijndael appears to be consistently a very good performer in
639 both hardware and software across a wide range of computing
640 environments regardless of its use in feedback or non-feedback
641 modes. Its key setup time is excellent, and its key agility is
642 good. Rijndael's very low memory requirements make it very well
643 suited for restricted-space environments, in which it also
644 demonstrates excellent performance. Rijndael's operations are
645 among the easiest to defend against power and timing attacks.
646
647 The AES specifies three key sizes: 128, 192 and 256 bits
648
649 See <http://csrc.nist.gov/encryption/aes/> for more information.
650
651 In addition to AES cipher algorithm support, the acceleration
652 for some popular block cipher mode is supported too, including
653 ECB and CBC.
654
627config CRYPTO_ANUBIS 655config CRYPTO_ANUBIS
628 tristate "Anubis cipher algorithm" 656 tristate "Anubis cipher algorithm"
629 select CRYPTO_ALGAPI 657 select CRYPTO_ALGAPI