diff options
author | David S. Miller <davem@davemloft.net> | 2012-08-26 01:37:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-08-26 01:37:23 -0400 |
commit | c5aac2df6577636ef526d87ec6d92796a190b27f (patch) | |
tree | 8dbd4f06b3aa08f776d173938adacb98fd79dac5 /arch/sparc/crypto | |
parent | 442a7c40b1dac78588abfe8ed4c97e4bb8b36e73 (diff) |
sparc64: Add DES driver making use of the new des opcodes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/crypto')
-rw-r--r-- | arch/sparc/crypto/Makefile | 2 | ||||
-rw-r--r-- | arch/sparc/crypto/des_asm.S | 439 | ||||
-rw-r--r-- | arch/sparc/crypto/des_glue.c | 525 |
3 files changed, 966 insertions, 0 deletions
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile index c6ca94181f45..dd999c6c8609 100644 --- a/arch/sparc/crypto/Makefile +++ b/arch/sparc/crypto/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_CRYPTO_SHA512_SPARC64) += sha512-sparc64.o | |||
8 | obj-$(CONFIG_CRYPTO_MD5_SPARC64) += md5-sparc64.o | 8 | obj-$(CONFIG_CRYPTO_MD5_SPARC64) += md5-sparc64.o |
9 | 9 | ||
10 | obj-$(CONFIG_CRYPTO_AES_SPARC64) += aes-sparc64.o | 10 | obj-$(CONFIG_CRYPTO_AES_SPARC64) += aes-sparc64.o |
11 | obj-$(CONFIG_CRYPTO_DES_SPARC64) += des-sparc64.o | ||
11 | 12 | ||
12 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o | 13 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o |
13 | 14 | ||
@@ -17,5 +18,6 @@ sha512-sparc64-y := sha512_asm.o sha512_glue.o | |||
17 | md5-sparc64-y := md5_asm.o md5_glue.o | 18 | md5-sparc64-y := md5_asm.o md5_glue.o |
18 | 19 | ||
19 | aes-sparc64-y := aes_asm.o aes_glue.o | 20 | aes-sparc64-y := aes_asm.o aes_glue.o |
21 | des-sparc64-y := des_asm.o des_glue.o | ||
20 | 22 | ||
21 | crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o | 23 | crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o |
diff --git a/arch/sparc/crypto/des_asm.S b/arch/sparc/crypto/des_asm.S new file mode 100644 index 000000000000..589481e53d07 --- /dev/null +++ b/arch/sparc/crypto/des_asm.S | |||
@@ -0,0 +1,439 @@ | |||
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) << 0) | ||
13 | |||
14 | #define DES_IP(a,b) \ | ||
15 | .word (F3F(2, 0x36, 0x134)|RS1(a)|RD(b)); | ||
16 | #define DES_IIP(a,b) \ | ||
17 | .word (F3F(2, 0x36, 0x135)|RS1(a)|RD(b)); | ||
18 | #define DES_KEXPAND(a,b,c) \ | ||
19 | .word (F3F(2, 0x36, 0x136)|RS1(a)|IMM5(b)|RD(c)); | ||
20 | #define DES_ROUND(a,b,c,d) \ | ||
21 | .word (F3F(2, 0x19, 0x009)|RS1(a)|RS2(b)|RS3(c)|RD(d)); | ||
22 | |||
23 | #define MOVXTOD_G1_F60 \ | ||
24 | .word 0xbbb02301 | ||
25 | #define MOVXTOD_G1_F62 \ | ||
26 | .word 0xbfb02301 | ||
27 | |||
28 | .align 32 | ||
29 | ENTRY(des_sparc64_key_expand) | ||
30 | /* %o0=input_key, %o1=output_key */ | ||
31 | VISEntryHalf | ||
32 | ld [%o0 + 0x00], %f0 | ||
33 | ld [%o0 + 0x04], %f1 | ||
34 | DES_KEXPAND(0, 0, 0) | ||
35 | DES_KEXPAND(0, 1, 2) | ||
36 | DES_KEXPAND(2, 3, 6) | ||
37 | DES_KEXPAND(2, 2, 4) | ||
38 | DES_KEXPAND(6, 3, 10) | ||
39 | DES_KEXPAND(6, 2, 8) | ||
40 | DES_KEXPAND(10, 3, 14) | ||
41 | DES_KEXPAND(10, 2, 12) | ||
42 | DES_KEXPAND(14, 1, 16) | ||
43 | DES_KEXPAND(16, 3, 20) | ||
44 | DES_KEXPAND(16, 2, 18) | ||
45 | DES_KEXPAND(20, 3, 24) | ||
46 | DES_KEXPAND(20, 2, 22) | ||
47 | DES_KEXPAND(24, 3, 28) | ||
48 | DES_KEXPAND(24, 2, 26) | ||
49 | DES_KEXPAND(28, 1, 30) | ||
50 | std %f0, [%o1 + 0x00] | ||
51 | std %f2, [%o1 + 0x08] | ||
52 | std %f4, [%o1 + 0x10] | ||
53 | std %f6, [%o1 + 0x18] | ||
54 | std %f8, [%o1 + 0x20] | ||
55 | std %f10, [%o1 + 0x28] | ||
56 | std %f12, [%o1 + 0x30] | ||
57 | std %f14, [%o1 + 0x38] | ||
58 | std %f16, [%o1 + 0x40] | ||
59 | std %f18, [%o1 + 0x48] | ||
60 | std %f20, [%o1 + 0x50] | ||
61 | std %f22, [%o1 + 0x58] | ||
62 | std %f24, [%o1 + 0x60] | ||
63 | std %f26, [%o1 + 0x68] | ||
64 | std %f28, [%o1 + 0x70] | ||
65 | std %f30, [%o1 + 0x78] | ||
66 | retl | ||
67 | VISExitHalf | ||
68 | ENDPROC(des_sparc64_key_expand) | ||
69 | |||
70 | .align 32 | ||
71 | ENTRY(des_sparc64_crypt) | ||
72 | /* %o0=key, %o1=input, %o2=output */ | ||
73 | VISEntry | ||
74 | ldd [%o1 + 0x00], %f32 | ||
75 | ldd [%o0 + 0x00], %f0 | ||
76 | ldd [%o0 + 0x08], %f2 | ||
77 | ldd [%o0 + 0x10], %f4 | ||
78 | ldd [%o0 + 0x18], %f6 | ||
79 | ldd [%o0 + 0x20], %f8 | ||
80 | ldd [%o0 + 0x28], %f10 | ||
81 | ldd [%o0 + 0x30], %f12 | ||
82 | ldd [%o0 + 0x38], %f14 | ||
83 | ldd [%o0 + 0x40], %f16 | ||
84 | ldd [%o0 + 0x48], %f18 | ||
85 | ldd [%o0 + 0x50], %f20 | ||
86 | ldd [%o0 + 0x58], %f22 | ||
87 | ldd [%o0 + 0x60], %f24 | ||
88 | ldd [%o0 + 0x68], %f26 | ||
89 | ldd [%o0 + 0x70], %f28 | ||
90 | ldd [%o0 + 0x78], %f30 | ||
91 | DES_IP(32, 32) | ||
92 | DES_ROUND(0, 2, 32, 32) | ||
93 | DES_ROUND(4, 6, 32, 32) | ||
94 | DES_ROUND(8, 10, 32, 32) | ||
95 | DES_ROUND(12, 14, 32, 32) | ||
96 | DES_ROUND(16, 18, 32, 32) | ||
97 | DES_ROUND(20, 22, 32, 32) | ||
98 | DES_ROUND(24, 26, 32, 32) | ||
99 | DES_ROUND(28, 30, 32, 32) | ||
100 | DES_IIP(32, 32) | ||
101 | std %f32, [%o2 + 0x00] | ||
102 | retl | ||
103 | VISExit | ||
104 | ENDPROC(des_sparc64_crypt) | ||
105 | |||
106 | .align 32 | ||
107 | ENTRY(des_sparc64_load_keys) | ||
108 | /* %o0=key */ | ||
109 | VISEntry | ||
110 | ldd [%o0 + 0x00], %f0 | ||
111 | ldd [%o0 + 0x08], %f2 | ||
112 | ldd [%o0 + 0x10], %f4 | ||
113 | ldd [%o0 + 0x18], %f6 | ||
114 | ldd [%o0 + 0x20], %f8 | ||
115 | ldd [%o0 + 0x28], %f10 | ||
116 | ldd [%o0 + 0x30], %f12 | ||
117 | ldd [%o0 + 0x38], %f14 | ||
118 | ldd [%o0 + 0x40], %f16 | ||
119 | ldd [%o0 + 0x48], %f18 | ||
120 | ldd [%o0 + 0x50], %f20 | ||
121 | ldd [%o0 + 0x58], %f22 | ||
122 | ldd [%o0 + 0x60], %f24 | ||
123 | ldd [%o0 + 0x68], %f26 | ||
124 | ldd [%o0 + 0x70], %f28 | ||
125 | retl | ||
126 | ldd [%o0 + 0x78], %f30 | ||
127 | ENDPROC(des_sparc64_load_keys) | ||
128 | |||
129 | .align 32 | ||
130 | ENTRY(des_sparc64_ecb_crypt) | ||
131 | /* %o0=input, %o1=output, %o2=len */ | ||
132 | 1: ldd [%o0 + 0x00], %f32 | ||
133 | add %o0, 0x08, %o0 | ||
134 | DES_IP(32, 32) | ||
135 | DES_ROUND(0, 2, 32, 32) | ||
136 | DES_ROUND(4, 6, 32, 32) | ||
137 | DES_ROUND(8, 10, 32, 32) | ||
138 | DES_ROUND(12, 14, 32, 32) | ||
139 | DES_ROUND(16, 18, 32, 32) | ||
140 | DES_ROUND(20, 22, 32, 32) | ||
141 | DES_ROUND(24, 26, 32, 32) | ||
142 | DES_ROUND(28, 30, 32, 32) | ||
143 | DES_IIP(32, 32) | ||
144 | std %f32, [%o1 + 0x00] | ||
145 | subcc %o2, 0x08, %o2 | ||
146 | bne,pt %icc, 1b | ||
147 | add %o1, 0x08, %o1 | ||
148 | retl | ||
149 | nop | ||
150 | ENDPROC(des_sparc64_ecb_crypt) | ||
151 | |||
152 | .align 32 | ||
153 | ENTRY(des_sparc64_cbc_encrypt) | ||
154 | /* %o0=input, %o1=output, %o2=len, %o3=IV */ | ||
155 | ldd [%o3 + 0x00], %f32 | ||
156 | 1: ldd [%o0 + 0x00], %f34 | ||
157 | fxor %f32, %f34, %f32 | ||
158 | DES_IP(32, 32) | ||
159 | DES_ROUND(0, 2, 32, 32) | ||
160 | DES_ROUND(4, 6, 32, 32) | ||
161 | DES_ROUND(8, 10, 32, 32) | ||
162 | DES_ROUND(12, 14, 32, 32) | ||
163 | DES_ROUND(16, 18, 32, 32) | ||
164 | DES_ROUND(20, 22, 32, 32) | ||
165 | DES_ROUND(24, 26, 32, 32) | ||
166 | DES_ROUND(28, 30, 32, 32) | ||
167 | DES_IIP(32, 32) | ||
168 | std %f32, [%o1 + 0x00] | ||
169 | add %o0, 0x08, %o0 | ||
170 | subcc %o2, 0x08, %o2 | ||
171 | bne,pt %icc, 1b | ||
172 | add %o1, 0x08, %o1 | ||
173 | retl | ||
174 | std %f32, [%o3 + 0x00] | ||
175 | ENDPROC(des_sparc64_cbc_encrypt) | ||
176 | |||
177 | .align 32 | ||
178 | ENTRY(des_sparc64_cbc_decrypt) | ||
179 | /* %o0=input, %o1=output, %o2=len, %o3=IV */ | ||
180 | ldd [%o3 + 0x00], %f34 | ||
181 | 1: ldd [%o0 + 0x00], %f36 | ||
182 | DES_IP(36, 32) | ||
183 | DES_ROUND(0, 2, 32, 32) | ||
184 | DES_ROUND(4, 6, 32, 32) | ||
185 | DES_ROUND(8, 10, 32, 32) | ||
186 | DES_ROUND(12, 14, 32, 32) | ||
187 | DES_ROUND(16, 18, 32, 32) | ||
188 | DES_ROUND(20, 22, 32, 32) | ||
189 | DES_ROUND(24, 26, 32, 32) | ||
190 | DES_ROUND(28, 30, 32, 32) | ||
191 | DES_IIP(32, 32) | ||
192 | fxor %f32, %f34, %f32 | ||
193 | std %f32, [%o1 + 0x00] | ||
194 | add %o0, 0x08, %o0 | ||
195 | subcc %o2, 0x08, %o2 | ||
196 | bne,pt %icc, 1b | ||
197 | add %o1, 0x08, %o1 | ||
198 | retl | ||
199 | std %f36, [%o3 + 0x00] | ||
200 | ENDPROC(des_sparc64_cbc_decrypt) | ||
201 | |||
202 | .align 32 | ||
203 | ENTRY(des3_ede_sparc64_crypt) | ||
204 | /* %o0=key, %o1=input, %o2=output */ | ||
205 | VISEntry | ||
206 | ldd [%o1 + 0x00], %f32 | ||
207 | ldd [%o0 + 0x00], %f0 | ||
208 | ldd [%o0 + 0x08], %f2 | ||
209 | ldd [%o0 + 0x10], %f4 | ||
210 | ldd [%o0 + 0x18], %f6 | ||
211 | ldd [%o0 + 0x20], %f8 | ||
212 | ldd [%o0 + 0x28], %f10 | ||
213 | ldd [%o0 + 0x30], %f12 | ||
214 | ldd [%o0 + 0x38], %f14 | ||
215 | ldd [%o0 + 0x40], %f16 | ||
216 | ldd [%o0 + 0x48], %f18 | ||
217 | ldd [%o0 + 0x50], %f20 | ||
218 | ldd [%o0 + 0x58], %f22 | ||
219 | ldd [%o0 + 0x60], %f24 | ||
220 | ldd [%o0 + 0x68], %f26 | ||
221 | ldd [%o0 + 0x70], %f28 | ||
222 | ldd [%o0 + 0x78], %f30 | ||
223 | DES_IP(32, 32) | ||
224 | DES_ROUND(0, 2, 32, 32) | ||
225 | ldd [%o0 + 0x80], %f0 | ||
226 | ldd [%o0 + 0x88], %f2 | ||
227 | DES_ROUND(4, 6, 32, 32) | ||
228 | ldd [%o0 + 0x90], %f4 | ||
229 | ldd [%o0 + 0x98], %f6 | ||
230 | DES_ROUND(8, 10, 32, 32) | ||
231 | ldd [%o0 + 0xa0], %f8 | ||
232 | ldd [%o0 + 0xa8], %f10 | ||
233 | DES_ROUND(12, 14, 32, 32) | ||
234 | ldd [%o0 + 0xb0], %f12 | ||
235 | ldd [%o0 + 0xb8], %f14 | ||
236 | DES_ROUND(16, 18, 32, 32) | ||
237 | ldd [%o0 + 0xc0], %f16 | ||
238 | ldd [%o0 + 0xc8], %f18 | ||
239 | DES_ROUND(20, 22, 32, 32) | ||
240 | ldd [%o0 + 0xd0], %f20 | ||
241 | ldd [%o0 + 0xd8], %f22 | ||
242 | DES_ROUND(24, 26, 32, 32) | ||
243 | ldd [%o0 + 0xe0], %f24 | ||
244 | ldd [%o0 + 0xe8], %f26 | ||
245 | DES_ROUND(28, 30, 32, 32) | ||
246 | ldd [%o0 + 0xf0], %f28 | ||
247 | ldd [%o0 + 0xf8], %f30 | ||
248 | DES_IIP(32, 32) | ||
249 | DES_IP(32, 32) | ||
250 | DES_ROUND(0, 2, 32, 32) | ||
251 | ldd [%o0 + 0x100], %f0 | ||
252 | ldd [%o0 + 0x108], %f2 | ||
253 | DES_ROUND(4, 6, 32, 32) | ||
254 | ldd [%o0 + 0x110], %f4 | ||
255 | ldd [%o0 + 0x118], %f6 | ||
256 | DES_ROUND(8, 10, 32, 32) | ||
257 | ldd [%o0 + 0x120], %f8 | ||
258 | ldd [%o0 + 0x128], %f10 | ||
259 | DES_ROUND(12, 14, 32, 32) | ||
260 | ldd [%o0 + 0x130], %f12 | ||
261 | ldd [%o0 + 0x138], %f14 | ||
262 | DES_ROUND(16, 18, 32, 32) | ||
263 | ldd [%o0 + 0x140], %f16 | ||
264 | ldd [%o0 + 0x148], %f18 | ||
265 | DES_ROUND(20, 22, 32, 32) | ||
266 | ldd [%o0 + 0x150], %f20 | ||
267 | ldd [%o0 + 0x158], %f22 | ||
268 | DES_ROUND(24, 26, 32, 32) | ||
269 | ldd [%o0 + 0x160], %f24 | ||
270 | ldd [%o0 + 0x168], %f26 | ||
271 | DES_ROUND(28, 30, 32, 32) | ||
272 | ldd [%o0 + 0x170], %f28 | ||
273 | ldd [%o0 + 0x178], %f30 | ||
274 | DES_IIP(32, 32) | ||
275 | DES_IP(32, 32) | ||
276 | DES_ROUND(0, 2, 32, 32) | ||
277 | DES_ROUND(4, 6, 32, 32) | ||
278 | DES_ROUND(8, 10, 32, 32) | ||
279 | DES_ROUND(12, 14, 32, 32) | ||
280 | DES_ROUND(16, 18, 32, 32) | ||
281 | DES_ROUND(20, 22, 32, 32) | ||
282 | DES_ROUND(24, 26, 32, 32) | ||
283 | DES_ROUND(28, 30, 32, 32) | ||
284 | DES_IIP(32, 32) | ||
285 | |||
286 | std %f32, [%o2 + 0x00] | ||
287 | retl | ||
288 | VISExit | ||
289 | ENDPROC(des3_ede_sparc64_crypt) | ||
290 | |||
291 | .align 32 | ||
292 | ENTRY(des3_ede_sparc64_load_keys) | ||
293 | /* %o0=key */ | ||
294 | VISEntry | ||
295 | ldd [%o0 + 0x00], %f0 | ||
296 | ldd [%o0 + 0x08], %f2 | ||
297 | ldd [%o0 + 0x10], %f4 | ||
298 | ldd [%o0 + 0x18], %f6 | ||
299 | ldd [%o0 + 0x20], %f8 | ||
300 | ldd [%o0 + 0x28], %f10 | ||
301 | ldd [%o0 + 0x30], %f12 | ||
302 | ldd [%o0 + 0x38], %f14 | ||
303 | ldd [%o0 + 0x40], %f16 | ||
304 | ldd [%o0 + 0x48], %f18 | ||
305 | ldd [%o0 + 0x50], %f20 | ||
306 | ldd [%o0 + 0x58], %f22 | ||
307 | ldd [%o0 + 0x60], %f24 | ||
308 | ldd [%o0 + 0x68], %f26 | ||
309 | ldd [%o0 + 0x70], %f28 | ||
310 | ldd [%o0 + 0x78], %f30 | ||
311 | ldd [%o0 + 0x80], %f32 | ||
312 | ldd [%o0 + 0x88], %f34 | ||
313 | ldd [%o0 + 0x90], %f36 | ||
314 | ldd [%o0 + 0x98], %f38 | ||
315 | ldd [%o0 + 0xa0], %f40 | ||
316 | ldd [%o0 + 0xa8], %f42 | ||
317 | ldd [%o0 + 0xb0], %f44 | ||
318 | ldd [%o0 + 0xb8], %f46 | ||
319 | ldd [%o0 + 0xc0], %f48 | ||
320 | ldd [%o0 + 0xc8], %f50 | ||
321 | ldd [%o0 + 0xd0], %f52 | ||
322 | ldd [%o0 + 0xd8], %f54 | ||
323 | ldd [%o0 + 0xe0], %f56 | ||
324 | retl | ||
325 | ldd [%o0 + 0xe8], %f58 | ||
326 | ENDPROC(des3_ede_sparc64_load_keys) | ||
327 | |||
328 | #define DES3_LOOP_BODY(X) \ | ||
329 | DES_IP(X, X) \ | ||
330 | DES_ROUND(0, 2, X, X) \ | ||
331 | DES_ROUND(4, 6, X, X) \ | ||
332 | DES_ROUND(8, 10, X, X) \ | ||
333 | DES_ROUND(12, 14, X, X) \ | ||
334 | DES_ROUND(16, 18, X, X) \ | ||
335 | ldd [%o0 + 0xf0], %f16; \ | ||
336 | ldd [%o0 + 0xf8], %f18; \ | ||
337 | DES_ROUND(20, 22, X, X) \ | ||
338 | ldd [%o0 + 0x100], %f20; \ | ||
339 | ldd [%o0 + 0x108], %f22; \ | ||
340 | DES_ROUND(24, 26, X, X) \ | ||
341 | ldd [%o0 + 0x110], %f24; \ | ||
342 | ldd [%o0 + 0x118], %f26; \ | ||
343 | DES_ROUND(28, 30, X, X) \ | ||
344 | ldd [%o0 + 0x120], %f28; \ | ||
345 | ldd [%o0 + 0x128], %f30; \ | ||
346 | DES_IIP(X, X) \ | ||
347 | DES_IP(X, X) \ | ||
348 | DES_ROUND(32, 34, X, X) \ | ||
349 | ldd [%o0 + 0x130], %f0; \ | ||
350 | ldd [%o0 + 0x138], %f2; \ | ||
351 | DES_ROUND(36, 38, X, X) \ | ||
352 | ldd [%o0 + 0x140], %f4; \ | ||
353 | ldd [%o0 + 0x148], %f6; \ | ||
354 | DES_ROUND(40, 42, X, X) \ | ||
355 | ldd [%o0 + 0x150], %f8; \ | ||
356 | ldd [%o0 + 0x158], %f10; \ | ||
357 | DES_ROUND(44, 46, X, X) \ | ||
358 | ldd [%o0 + 0x160], %f12; \ | ||
359 | ldd [%o0 + 0x168], %f14; \ | ||
360 | DES_ROUND(48, 50, X, X) \ | ||
361 | DES_ROUND(52, 54, X, X) \ | ||
362 | DES_ROUND(56, 58, X, X) \ | ||
363 | DES_ROUND(16, 18, X, X) \ | ||
364 | ldd [%o0 + 0x170], %f16; \ | ||
365 | ldd [%o0 + 0x178], %f18; \ | ||
366 | DES_IIP(X, X) \ | ||
367 | DES_IP(X, X) \ | ||
368 | DES_ROUND(20, 22, X, X) \ | ||
369 | ldd [%o0 + 0x50], %f20; \ | ||
370 | ldd [%o0 + 0x58], %f22; \ | ||
371 | DES_ROUND(24, 26, X, X) \ | ||
372 | ldd [%o0 + 0x60], %f24; \ | ||
373 | ldd [%o0 + 0x68], %f26; \ | ||
374 | DES_ROUND(28, 30, X, X) \ | ||
375 | ldd [%o0 + 0x70], %f28; \ | ||
376 | ldd [%o0 + 0x78], %f30; \ | ||
377 | DES_ROUND(0, 2, X, X) \ | ||
378 | ldd [%o0 + 0x00], %f0; \ | ||
379 | ldd [%o0 + 0x08], %f2; \ | ||
380 | DES_ROUND(4, 6, X, X) \ | ||
381 | ldd [%o0 + 0x10], %f4; \ | ||
382 | ldd [%o0 + 0x18], %f6; \ | ||
383 | DES_ROUND(8, 10, X, X) \ | ||
384 | ldd [%o0 + 0x20], %f8; \ | ||
385 | ldd [%o0 + 0x28], %f10; \ | ||
386 | DES_ROUND(12, 14, X, X) \ | ||
387 | ldd [%o0 + 0x30], %f12; \ | ||
388 | ldd [%o0 + 0x38], %f14; \ | ||
389 | DES_ROUND(16, 18, X, X) \ | ||
390 | ldd [%o0 + 0x40], %f16; \ | ||
391 | ldd [%o0 + 0x48], %f18; \ | ||
392 | DES_IIP(X, X) | ||
393 | |||
394 | .align 32 | ||
395 | ENTRY(des3_ede_sparc64_ecb_crypt) | ||
396 | /* %o0=key, %o1=input, %o2=output, %o3=len */ | ||
397 | 1: ldd [%o1 + 0x00], %f60 | ||
398 | DES3_LOOP_BODY(60) | ||
399 | std %f60, [%o2 + 0x00] | ||
400 | subcc %o3, 0x08, %o3 | ||
401 | bne,pt %icc, 1b | ||
402 | add %o2, 0x08, %o2 | ||
403 | retl | ||
404 | nop | ||
405 | ENDPROC(des3_ede_sparc64_ecb_crypt) | ||
406 | |||
407 | .align 32 | ||
408 | ENTRY(des3_ede_sparc64_cbc_encrypt) | ||
409 | /* %o0=key, %o1=input, %o2=output, %o3=len, %o4=IV */ | ||
410 | ldd [%o4 + 0x00], %f60 | ||
411 | 1: ldd [%o1 + 0x00], %f62 | ||
412 | fxor %f60, %f62, %f60 | ||
413 | DES3_LOOP_BODY(60) | ||
414 | std %f60, [%o2 + 0x00] | ||
415 | add %o1, 0x08, %o1 | ||
416 | subcc %o3, 0x08, %o3 | ||
417 | bne,pt %icc, 1b | ||
418 | add %o2, 0x08, %o2 | ||
419 | retl | ||
420 | std %f60, [%o4 + 0x00] | ||
421 | ENDPROC(des3_ede_sparc64_cbc_encrypt) | ||
422 | |||
423 | .align 32 | ||
424 | ENTRY(des3_ede_sparc64_cbc_decrypt) | ||
425 | /* %o0=key, %o1=input, %o2=output, %o3=len, %o4=IV */ | ||
426 | ldd [%o4 + 0x00], %f62 | ||
427 | 1: ldx [%o1 + 0x00], %g1 | ||
428 | MOVXTOD_G1_F60 | ||
429 | DES3_LOOP_BODY(60) | ||
430 | fxor %f62, %f60, %f60 | ||
431 | MOVXTOD_G1_F62 | ||
432 | std %f60, [%o2 + 0x00] | ||
433 | add %o1, 0x08, %o1 | ||
434 | subcc %o3, 0x08, %o3 | ||
435 | bne,pt %icc, 1b | ||
436 | add %o2, 0x08, %o2 | ||
437 | retl | ||
438 | stx %g1, [%o4 + 0x00] | ||
439 | ENDPROC(des3_ede_sparc64_cbc_decrypt) | ||
diff --git a/arch/sparc/crypto/des_glue.c b/arch/sparc/crypto/des_glue.c new file mode 100644 index 000000000000..5ec0309e48c0 --- /dev/null +++ b/arch/sparc/crypto/des_glue.c | |||
@@ -0,0 +1,525 @@ | |||
1 | /* Glue code for DES encryption optimized for sparc64 crypto opcodes. | ||
2 | * | ||
3 | * Copyright (C) 2012 David S. Miller <davem@davemloft.net> | ||
4 | */ | ||
5 | |||
6 | #include <linux/crypto.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/mm.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <crypto/algapi.h> | ||
12 | #include <crypto/des.h> | ||
13 | |||
14 | #include <asm/fpumacro.h> | ||
15 | #include <asm/pstate.h> | ||
16 | #include <asm/elf.h> | ||
17 | |||
18 | struct des_sparc64_ctx { | ||
19 | u64 encrypt_expkey[DES_EXPKEY_WORDS / 2]; | ||
20 | u64 decrypt_expkey[DES_EXPKEY_WORDS / 2]; | ||
21 | }; | ||
22 | |||
23 | struct des3_ede_sparc64_ctx { | ||
24 | u64 encrypt_expkey[DES3_EDE_EXPKEY_WORDS / 2]; | ||
25 | u64 decrypt_expkey[DES3_EDE_EXPKEY_WORDS / 2]; | ||
26 | }; | ||
27 | |||
28 | static void encrypt_to_decrypt(u64 *d, const u64 *e) | ||
29 | { | ||
30 | const u64 *s = e + (DES_EXPKEY_WORDS / 2) - 1; | ||
31 | int i; | ||
32 | |||
33 | for (i = 0; i < DES_EXPKEY_WORDS / 2; i++) | ||
34 | *d++ = *s--; | ||
35 | } | ||
36 | |||
37 | extern void des_sparc64_key_expand(const u32 *input_key, u64 *key); | ||
38 | |||
39 | static int des_set_key(struct crypto_tfm *tfm, const u8 *key, | ||
40 | unsigned int keylen) | ||
41 | { | ||
42 | struct des_sparc64_ctx *dctx = crypto_tfm_ctx(tfm); | ||
43 | u32 *flags = &tfm->crt_flags; | ||
44 | u32 tmp[DES_EXPKEY_WORDS]; | ||
45 | int ret; | ||
46 | |||
47 | /* Even though we have special instructions for key expansion, | ||
48 | * we call des_ekey() so that we don't have to write our own | ||
49 | * weak key detection code. | ||
50 | */ | ||
51 | ret = des_ekey(tmp, key); | ||
52 | if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { | ||
53 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | |||
57 | des_sparc64_key_expand((const u32 *) key, &dctx->encrypt_expkey[0]); | ||
58 | encrypt_to_decrypt(&dctx->decrypt_expkey[0], &dctx->encrypt_expkey[0]); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | extern void des_sparc64_crypt(const u64 *key, const u64 *input, | ||
64 | u64 *output); | ||
65 | |||
66 | static void des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
67 | { | ||
68 | struct des_sparc64_ctx *ctx = crypto_tfm_ctx(tfm); | ||
69 | const u64 *K = ctx->encrypt_expkey; | ||
70 | |||
71 | des_sparc64_crypt(K, (const u64 *) src, (u64 *) dst); | ||
72 | } | ||
73 | |||
74 | static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
75 | { | ||
76 | struct des_sparc64_ctx *ctx = crypto_tfm_ctx(tfm); | ||
77 | const u64 *K = ctx->decrypt_expkey; | ||
78 | |||
79 | des_sparc64_crypt(K, (const u64 *) src, (u64 *) dst); | ||
80 | } | ||
81 | |||
82 | extern void des_sparc64_load_keys(const u64 *key); | ||
83 | |||
84 | extern void des_sparc64_ecb_crypt(const u64 *input, u64 *output, | ||
85 | unsigned int len); | ||
86 | |||
87 | #define DES_BLOCK_MASK (~(DES_BLOCK_SIZE - 1)) | ||
88 | |||
89 | static int __ecb_crypt(struct blkcipher_desc *desc, | ||
90 | struct scatterlist *dst, struct scatterlist *src, | ||
91 | unsigned int nbytes, bool encrypt) | ||
92 | { | ||
93 | struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
94 | struct blkcipher_walk walk; | ||
95 | int err; | ||
96 | |||
97 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
98 | err = blkcipher_walk_virt(desc, &walk); | ||
99 | |||
100 | if (encrypt) | ||
101 | des_sparc64_load_keys(&ctx->encrypt_expkey[0]); | ||
102 | else | ||
103 | des_sparc64_load_keys(&ctx->decrypt_expkey[0]); | ||
104 | while ((nbytes = walk.nbytes)) { | ||
105 | unsigned int block_len = nbytes & DES_BLOCK_MASK; | ||
106 | |||
107 | if (likely(block_len)) { | ||
108 | des_sparc64_ecb_crypt((const u64 *)walk.src.virt.addr, | ||
109 | (u64 *) walk.dst.virt.addr, | ||
110 | block_len); | ||
111 | } | ||
112 | nbytes &= DES_BLOCK_SIZE - 1; | ||
113 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
114 | } | ||
115 | fprs_write(0); | ||
116 | return err; | ||
117 | } | ||
118 | |||
119 | static int ecb_encrypt(struct blkcipher_desc *desc, | ||
120 | struct scatterlist *dst, struct scatterlist *src, | ||
121 | unsigned int nbytes) | ||
122 | { | ||
123 | return __ecb_crypt(desc, dst, src, nbytes, true); | ||
124 | } | ||
125 | |||
126 | static int ecb_decrypt(struct blkcipher_desc *desc, | ||
127 | struct scatterlist *dst, struct scatterlist *src, | ||
128 | unsigned int nbytes) | ||
129 | { | ||
130 | return __ecb_crypt(desc, dst, src, nbytes, false); | ||
131 | } | ||
132 | |||
133 | extern void des_sparc64_cbc_encrypt(const u64 *input, u64 *output, | ||
134 | unsigned int len, u64 *iv); | ||
135 | |||
136 | static int cbc_encrypt(struct blkcipher_desc *desc, | ||
137 | struct scatterlist *dst, struct scatterlist *src, | ||
138 | unsigned int nbytes) | ||
139 | { | ||
140 | struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
141 | struct blkcipher_walk walk; | ||
142 | int err; | ||
143 | |||
144 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
145 | err = blkcipher_walk_virt(desc, &walk); | ||
146 | |||
147 | des_sparc64_load_keys(&ctx->encrypt_expkey[0]); | ||
148 | while ((nbytes = walk.nbytes)) { | ||
149 | unsigned int block_len = nbytes & DES_BLOCK_MASK; | ||
150 | |||
151 | if (likely(block_len)) { | ||
152 | des_sparc64_cbc_encrypt((const u64 *)walk.src.virt.addr, | ||
153 | (u64 *) walk.dst.virt.addr, | ||
154 | block_len, (u64 *) walk.iv); | ||
155 | } | ||
156 | nbytes &= DES_BLOCK_SIZE - 1; | ||
157 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
158 | } | ||
159 | fprs_write(0); | ||
160 | return err; | ||
161 | } | ||
162 | |||
163 | extern void des_sparc64_cbc_decrypt(const u64 *input, u64 *output, | ||
164 | unsigned int len, u64 *iv); | ||
165 | |||
166 | static int cbc_decrypt(struct blkcipher_desc *desc, | ||
167 | struct scatterlist *dst, struct scatterlist *src, | ||
168 | unsigned int nbytes) | ||
169 | { | ||
170 | struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
171 | struct blkcipher_walk walk; | ||
172 | int err; | ||
173 | |||
174 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
175 | err = blkcipher_walk_virt(desc, &walk); | ||
176 | |||
177 | des_sparc64_load_keys(&ctx->decrypt_expkey[0]); | ||
178 | while ((nbytes = walk.nbytes)) { | ||
179 | unsigned int block_len = nbytes & DES_BLOCK_MASK; | ||
180 | |||
181 | if (likely(block_len)) { | ||
182 | des_sparc64_cbc_decrypt((const u64 *)walk.src.virt.addr, | ||
183 | (u64 *) walk.dst.virt.addr, | ||
184 | block_len, (u64 *) walk.iv); | ||
185 | } | ||
186 | nbytes &= DES_BLOCK_SIZE - 1; | ||
187 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
188 | } | ||
189 | fprs_write(0); | ||
190 | return err; | ||
191 | } | ||
192 | |||
193 | static int des3_ede_set_key(struct crypto_tfm *tfm, const u8 *key, | ||
194 | unsigned int keylen) | ||
195 | { | ||
196 | struct des3_ede_sparc64_ctx *dctx = crypto_tfm_ctx(tfm); | ||
197 | const u32 *K = (const u32 *)key; | ||
198 | u32 *flags = &tfm->crt_flags; | ||
199 | u64 k1[DES_EXPKEY_WORDS / 2]; | ||
200 | u64 k2[DES_EXPKEY_WORDS / 2]; | ||
201 | u64 k3[DES_EXPKEY_WORDS / 2]; | ||
202 | |||
203 | if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) || | ||
204 | !((K[2] ^ K[4]) | (K[3] ^ K[5]))) && | ||
205 | (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { | ||
206 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; | ||
207 | return -EINVAL; | ||
208 | } | ||
209 | |||
210 | des_sparc64_key_expand((const u32 *)key, k1); | ||
211 | key += DES_KEY_SIZE; | ||
212 | des_sparc64_key_expand((const u32 *)key, k2); | ||
213 | key += DES_KEY_SIZE; | ||
214 | des_sparc64_key_expand((const u32 *)key, k3); | ||
215 | |||
216 | memcpy(&dctx->encrypt_expkey[0], &k1[0], sizeof(k1)); | ||
217 | encrypt_to_decrypt(&dctx->encrypt_expkey[DES_EXPKEY_WORDS / 2], &k2[0]); | ||
218 | memcpy(&dctx->encrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2], | ||
219 | &k3[0], sizeof(k3)); | ||
220 | |||
221 | encrypt_to_decrypt(&dctx->decrypt_expkey[0], &k3[0]); | ||
222 | memcpy(&dctx->decrypt_expkey[DES_EXPKEY_WORDS / 2], | ||
223 | &k2[0], sizeof(k2)); | ||
224 | encrypt_to_decrypt(&dctx->decrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2], | ||
225 | &k1[0]); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | extern void des3_ede_sparc64_crypt(const u64 *key, const u64 *input, | ||
231 | u64 *output); | ||
232 | |||
233 | static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
234 | { | ||
235 | struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm); | ||
236 | const u64 *K = ctx->encrypt_expkey; | ||
237 | |||
238 | des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst); | ||
239 | } | ||
240 | |||
241 | static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
242 | { | ||
243 | struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm); | ||
244 | const u64 *K = ctx->decrypt_expkey; | ||
245 | |||
246 | des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst); | ||
247 | } | ||
248 | |||
249 | extern void des3_ede_sparc64_load_keys(const u64 *key); | ||
250 | |||
251 | extern void des3_ede_sparc64_ecb_crypt(const u64 *expkey, const u64 *input, | ||
252 | u64 *output, unsigned int len); | ||
253 | |||
254 | static int __ecb3_crypt(struct blkcipher_desc *desc, | ||
255 | struct scatterlist *dst, struct scatterlist *src, | ||
256 | unsigned int nbytes, bool encrypt) | ||
257 | { | ||
258 | struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
259 | struct blkcipher_walk walk; | ||
260 | const u64 *K; | ||
261 | int err; | ||
262 | |||
263 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
264 | err = blkcipher_walk_virt(desc, &walk); | ||
265 | |||
266 | if (encrypt) | ||
267 | K = &ctx->encrypt_expkey[0]; | ||
268 | else | ||
269 | K = &ctx->decrypt_expkey[0]; | ||
270 | des3_ede_sparc64_load_keys(K); | ||
271 | while ((nbytes = walk.nbytes)) { | ||
272 | unsigned int block_len = nbytes & DES_BLOCK_MASK; | ||
273 | |||
274 | if (likely(block_len)) { | ||
275 | const u64 *src64 = (const u64 *)walk.src.virt.addr; | ||
276 | des3_ede_sparc64_ecb_crypt(K, src64, | ||
277 | (u64 *) walk.dst.virt.addr, | ||
278 | block_len); | ||
279 | } | ||
280 | nbytes &= DES_BLOCK_SIZE - 1; | ||
281 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
282 | } | ||
283 | fprs_write(0); | ||
284 | return err; | ||
285 | } | ||
286 | |||
287 | static int ecb3_encrypt(struct blkcipher_desc *desc, | ||
288 | struct scatterlist *dst, struct scatterlist *src, | ||
289 | unsigned int nbytes) | ||
290 | { | ||
291 | return __ecb3_crypt(desc, dst, src, nbytes, true); | ||
292 | } | ||
293 | |||
294 | static int ecb3_decrypt(struct blkcipher_desc *desc, | ||
295 | struct scatterlist *dst, struct scatterlist *src, | ||
296 | unsigned int nbytes) | ||
297 | { | ||
298 | return __ecb3_crypt(desc, dst, src, nbytes, false); | ||
299 | } | ||
300 | |||
301 | extern void des3_ede_sparc64_cbc_encrypt(const u64 *expkey, const u64 *input, | ||
302 | u64 *output, unsigned int len, | ||
303 | u64 *iv); | ||
304 | |||
305 | static int cbc3_encrypt(struct blkcipher_desc *desc, | ||
306 | struct scatterlist *dst, struct scatterlist *src, | ||
307 | unsigned int nbytes) | ||
308 | { | ||
309 | struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
310 | struct blkcipher_walk walk; | ||
311 | const u64 *K; | ||
312 | int err; | ||
313 | |||
314 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
315 | err = blkcipher_walk_virt(desc, &walk); | ||
316 | |||
317 | K = &ctx->encrypt_expkey[0]; | ||
318 | des3_ede_sparc64_load_keys(K); | ||
319 | while ((nbytes = walk.nbytes)) { | ||
320 | unsigned int block_len = nbytes & DES_BLOCK_MASK; | ||
321 | |||
322 | if (likely(block_len)) { | ||
323 | const u64 *src64 = (const u64 *)walk.src.virt.addr; | ||
324 | des3_ede_sparc64_cbc_encrypt(K, src64, | ||
325 | (u64 *) walk.dst.virt.addr, | ||
326 | block_len, | ||
327 | (u64 *) walk.iv); | ||
328 | } | ||
329 | nbytes &= DES_BLOCK_SIZE - 1; | ||
330 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
331 | } | ||
332 | fprs_write(0); | ||
333 | return err; | ||
334 | } | ||
335 | |||
336 | extern void des3_ede_sparc64_cbc_decrypt(const u64 *expkey, const u64 *input, | ||
337 | u64 *output, unsigned int len, | ||
338 | u64 *iv); | ||
339 | |||
340 | static int cbc3_decrypt(struct blkcipher_desc *desc, | ||
341 | struct scatterlist *dst, struct scatterlist *src, | ||
342 | unsigned int nbytes) | ||
343 | { | ||
344 | struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
345 | struct blkcipher_walk walk; | ||
346 | const u64 *K; | ||
347 | int err; | ||
348 | |||
349 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
350 | err = blkcipher_walk_virt(desc, &walk); | ||
351 | |||
352 | K = &ctx->decrypt_expkey[0]; | ||
353 | des3_ede_sparc64_load_keys(K); | ||
354 | while ((nbytes = walk.nbytes)) { | ||
355 | unsigned int block_len = nbytes & DES_BLOCK_MASK; | ||
356 | |||
357 | if (likely(block_len)) { | ||
358 | const u64 *src64 = (const u64 *)walk.src.virt.addr; | ||
359 | des3_ede_sparc64_cbc_decrypt(K, src64, | ||
360 | (u64 *) walk.dst.virt.addr, | ||
361 | block_len, | ||
362 | (u64 *) walk.iv); | ||
363 | } | ||
364 | nbytes &= DES_BLOCK_SIZE - 1; | ||
365 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
366 | } | ||
367 | fprs_write(0); | ||
368 | return err; | ||
369 | } | ||
370 | |||
371 | static struct crypto_alg algs[] = { { | ||
372 | .cra_name = "des", | ||
373 | .cra_driver_name = "des-sparc64", | ||
374 | .cra_priority = 150, | ||
375 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
376 | .cra_blocksize = DES_BLOCK_SIZE, | ||
377 | .cra_ctxsize = sizeof(struct des_sparc64_ctx), | ||
378 | .cra_alignmask = 7, | ||
379 | .cra_module = THIS_MODULE, | ||
380 | .cra_u = { | ||
381 | .cipher = { | ||
382 | .cia_min_keysize = DES_KEY_SIZE, | ||
383 | .cia_max_keysize = DES_KEY_SIZE, | ||
384 | .cia_setkey = des_set_key, | ||
385 | .cia_encrypt = des_encrypt, | ||
386 | .cia_decrypt = des_decrypt | ||
387 | } | ||
388 | } | ||
389 | }, { | ||
390 | .cra_name = "ecb(des)", | ||
391 | .cra_driver_name = "ecb-des-sparc64", | ||
392 | .cra_priority = 150, | ||
393 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
394 | .cra_blocksize = DES_BLOCK_SIZE, | ||
395 | .cra_ctxsize = sizeof(struct des_sparc64_ctx), | ||
396 | .cra_alignmask = 7, | ||
397 | .cra_type = &crypto_blkcipher_type, | ||
398 | .cra_module = THIS_MODULE, | ||
399 | .cra_u = { | ||
400 | .blkcipher = { | ||
401 | .min_keysize = DES_KEY_SIZE, | ||
402 | .max_keysize = DES_KEY_SIZE, | ||
403 | .setkey = des_set_key, | ||
404 | .encrypt = ecb_encrypt, | ||
405 | .decrypt = ecb_decrypt, | ||
406 | }, | ||
407 | }, | ||
408 | }, { | ||
409 | .cra_name = "cbc(des)", | ||
410 | .cra_driver_name = "cbc-des-sparc64", | ||
411 | .cra_priority = 150, | ||
412 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
413 | .cra_blocksize = DES_BLOCK_SIZE, | ||
414 | .cra_ctxsize = sizeof(struct des_sparc64_ctx), | ||
415 | .cra_alignmask = 7, | ||
416 | .cra_type = &crypto_blkcipher_type, | ||
417 | .cra_module = THIS_MODULE, | ||
418 | .cra_u = { | ||
419 | .blkcipher = { | ||
420 | .min_keysize = DES_KEY_SIZE, | ||
421 | .max_keysize = DES_KEY_SIZE, | ||
422 | .setkey = des_set_key, | ||
423 | .encrypt = cbc_encrypt, | ||
424 | .decrypt = cbc_decrypt, | ||
425 | }, | ||
426 | }, | ||
427 | }, { | ||
428 | .cra_name = "des3_ede", | ||
429 | .cra_driver_name = "des3_ede-sparc64", | ||
430 | .cra_priority = 150, | ||
431 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
432 | .cra_blocksize = DES3_EDE_BLOCK_SIZE, | ||
433 | .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx), | ||
434 | .cra_alignmask = 7, | ||
435 | .cra_module = THIS_MODULE, | ||
436 | .cra_u = { | ||
437 | .cipher = { | ||
438 | .cia_min_keysize = DES3_EDE_KEY_SIZE, | ||
439 | .cia_max_keysize = DES3_EDE_KEY_SIZE, | ||
440 | .cia_setkey = des3_ede_set_key, | ||
441 | .cia_encrypt = des3_ede_encrypt, | ||
442 | .cia_decrypt = des3_ede_decrypt | ||
443 | } | ||
444 | } | ||
445 | }, { | ||
446 | .cra_name = "ecb(des3_ede)", | ||
447 | .cra_driver_name = "ecb-des3_ede-sparc64", | ||
448 | .cra_priority = 150, | ||
449 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
450 | .cra_blocksize = DES3_EDE_BLOCK_SIZE, | ||
451 | .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx), | ||
452 | .cra_alignmask = 7, | ||
453 | .cra_type = &crypto_blkcipher_type, | ||
454 | .cra_module = THIS_MODULE, | ||
455 | .cra_u = { | ||
456 | .blkcipher = { | ||
457 | .min_keysize = DES3_EDE_KEY_SIZE, | ||
458 | .max_keysize = DES3_EDE_KEY_SIZE, | ||
459 | .setkey = des3_ede_set_key, | ||
460 | .encrypt = ecb3_encrypt, | ||
461 | .decrypt = ecb3_decrypt, | ||
462 | }, | ||
463 | }, | ||
464 | }, { | ||
465 | .cra_name = "cbc(des3_ede)", | ||
466 | .cra_driver_name = "cbc-des3_ede-sparc64", | ||
467 | .cra_priority = 150, | ||
468 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
469 | .cra_blocksize = DES3_EDE_BLOCK_SIZE, | ||
470 | .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx), | ||
471 | .cra_alignmask = 7, | ||
472 | .cra_type = &crypto_blkcipher_type, | ||
473 | .cra_module = THIS_MODULE, | ||
474 | .cra_u = { | ||
475 | .blkcipher = { | ||
476 | .min_keysize = DES3_EDE_KEY_SIZE, | ||
477 | .max_keysize = DES3_EDE_KEY_SIZE, | ||
478 | .setkey = des3_ede_set_key, | ||
479 | .encrypt = cbc3_encrypt, | ||
480 | .decrypt = cbc3_decrypt, | ||
481 | }, | ||
482 | }, | ||
483 | } }; | ||
484 | |||
485 | static bool __init sparc64_has_des_opcode(void) | ||
486 | { | ||
487 | unsigned long cfr; | ||
488 | |||
489 | if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO)) | ||
490 | return false; | ||
491 | |||
492 | __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr)); | ||
493 | if (!(cfr & CFR_DES)) | ||
494 | return false; | ||
495 | |||
496 | return true; | ||
497 | } | ||
498 | |||
499 | static int __init des_sparc64_mod_init(void) | ||
500 | { | ||
501 | int i; | ||
502 | |||
503 | for (i = 0; i < ARRAY_SIZE(algs); i++) | ||
504 | INIT_LIST_HEAD(&algs[i].cra_list); | ||
505 | |||
506 | if (sparc64_has_des_opcode()) { | ||
507 | pr_info("Using sparc64 des opcodes optimized DES implementation\n"); | ||
508 | return crypto_register_algs(algs, ARRAY_SIZE(algs)); | ||
509 | } | ||
510 | pr_info("sparc64 des opcodes not available.\n"); | ||
511 | return -ENODEV; | ||
512 | } | ||
513 | |||
514 | static void __exit des_sparc64_mod_fini(void) | ||
515 | { | ||
516 | crypto_unregister_algs(algs, ARRAY_SIZE(algs)); | ||
517 | } | ||
518 | |||
519 | module_init(des_sparc64_mod_init); | ||
520 | module_exit(des_sparc64_mod_fini); | ||
521 | |||
522 | MODULE_LICENSE("GPL"); | ||
523 | MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); | ||
524 | |||
525 | MODULE_ALIAS("des"); | ||