diff options
author | David S. Miller <davem@davemloft.net> | 2012-08-28 15:05:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-08-28 23:51:24 -0400 |
commit | 81658ad0d92306ceb271994b90cd49ffde10eeda (patch) | |
tree | 8765d2fffb62a3e22752644ff329b9aec166a3eb /arch/sparc/crypto | |
parent | 3705665069944e003b7316ba31b44558864a00de (diff) |
sparc64: Add CAMELLIA driver making use of the new camellia 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/camellia_asm.S | 583 | ||||
-rw-r--r-- | arch/sparc/crypto/camellia_glue.c | 318 |
3 files changed, 903 insertions, 0 deletions
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile index dd999c6c8609..5d469d81761f 100644 --- a/arch/sparc/crypto/Makefile +++ b/arch/sparc/crypto/Makefile | |||
@@ -9,6 +9,7 @@ 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 | obj-$(CONFIG_CRYPTO_DES_SPARC64) += des-sparc64.o |
12 | obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o | ||
12 | 13 | ||
13 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o | 14 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o |
14 | 15 | ||
@@ -19,5 +20,6 @@ md5-sparc64-y := md5_asm.o md5_glue.o | |||
19 | 20 | ||
20 | aes-sparc64-y := aes_asm.o aes_glue.o | 21 | aes-sparc64-y := aes_asm.o aes_glue.o |
21 | des-sparc64-y := des_asm.o des_glue.o | 22 | des-sparc64-y := des_asm.o des_glue.o |
23 | camellia-sparc64-y := camellia_asm.o camellia_glue.o | ||
22 | 24 | ||
23 | crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o | 25 | crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o |
diff --git a/arch/sparc/crypto/camellia_asm.S b/arch/sparc/crypto/camellia_asm.S new file mode 100644 index 000000000000..b0ddb5bcfe5f --- /dev/null +++ b/arch/sparc/crypto/camellia_asm.S | |||
@@ -0,0 +1,583 @@ | |||
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 CAMELLIA_F(a,b,c,d) \ | ||
15 | .word (F3F(2, 0x19, 0x00c)|RS1(a)|RS2(b)|RS3(c)|RD(d)); | ||
16 | #define CAMELLIA_FL(a,b,c) \ | ||
17 | .word (F3F(2, 0x36, 0x13c)|RS1(a)|RS2(b)|RD(c)); | ||
18 | #define CAMELLIA_FLI(a,b,c) \ | ||
19 | .word (F3F(2, 0x36, 0x13d)|RS1(a)|RS2(b)|RD(c)); | ||
20 | |||
21 | #define MOVDTOX_F0_O4 \ | ||
22 | .word 0x99b02200 | ||
23 | #define MOVDTOX_F2_O5 \ | ||
24 | .word 0x9bb02202 | ||
25 | |||
26 | #define CAMELLIA_6ROUNDS(KEY_BASE, I0, I1) \ | ||
27 | CAMELLIA_F(KEY_BASE + 0, I1, I0, I1) \ | ||
28 | CAMELLIA_F(KEY_BASE + 2, I0, I1, I0) \ | ||
29 | CAMELLIA_F(KEY_BASE + 4, I1, I0, I1) \ | ||
30 | CAMELLIA_F(KEY_BASE + 6, I0, I1, I0) \ | ||
31 | CAMELLIA_F(KEY_BASE + 8, I1, I0, I1) \ | ||
32 | CAMELLIA_F(KEY_BASE + 10, I0, I1, I0) | ||
33 | |||
34 | #define CAMELLIA_6ROUNDS_FL_FLI(KEY_BASE, I0, I1) \ | ||
35 | CAMELLIA_6ROUNDS(KEY_BASE, I0, I1) \ | ||
36 | CAMELLIA_FL(KEY_BASE + 12, I0, I0) \ | ||
37 | CAMELLIA_FLI(KEY_BASE + 14, I1, I1) | ||
38 | |||
39 | .data | ||
40 | |||
41 | .align 8 | ||
42 | SIGMA: .xword 0xA09E667F3BCC908B | ||
43 | .xword 0xB67AE8584CAA73B2 | ||
44 | .xword 0xC6EF372FE94F82BE | ||
45 | .xword 0x54FF53A5F1D36F1C | ||
46 | .xword 0x10E527FADE682D1D | ||
47 | .xword 0xB05688C2B3E6C1FD | ||
48 | |||
49 | .text | ||
50 | |||
51 | .align 32 | ||
52 | ENTRY(camellia_sparc64_key_expand) | ||
53 | /* %o0=in_key, %o1=out_key, %o2=key_len */ | ||
54 | VISEntry | ||
55 | ld [%o0 + 0x00], %f0 ! i0, k[0] | ||
56 | ld [%o0 + 0x04], %f1 ! i1, k[1] | ||
57 | ld [%o0 + 0x08], %f2 ! i2, k[2] | ||
58 | ld [%o0 + 0x0c], %f3 ! i3, k[3] | ||
59 | std %f0, [%o1 + 0x00] ! k[0, 1] | ||
60 | fsrc2 %f0, %f28 | ||
61 | std %f2, [%o1 + 0x08] ! k[2, 3] | ||
62 | cmp %o2, 16 | ||
63 | be 10f | ||
64 | fsrc2 %f2, %f30 | ||
65 | |||
66 | ld [%o0 + 0x10], %f0 | ||
67 | ld [%o0 + 0x14], %f1 | ||
68 | std %f0, [%o1 + 0x20] ! k[8, 9] | ||
69 | cmp %o2, 24 | ||
70 | fone %f10 | ||
71 | be,a 1f | ||
72 | fxor %f10, %f0, %f2 | ||
73 | ld [%o0 + 0x18], %f2 | ||
74 | ld [%o0 + 0x1c], %f3 | ||
75 | 1: | ||
76 | std %f2, [%o1 + 0x28] ! k[10, 11] | ||
77 | fxor %f28, %f0, %f0 | ||
78 | fxor %f30, %f2, %f2 | ||
79 | |||
80 | 10: | ||
81 | sethi %hi(SIGMA), %g3 | ||
82 | or %g3, %lo(SIGMA), %g3 | ||
83 | ldd [%g3 + 0x00], %f16 | ||
84 | ldd [%g3 + 0x08], %f18 | ||
85 | ldd [%g3 + 0x10], %f20 | ||
86 | ldd [%g3 + 0x18], %f22 | ||
87 | ldd [%g3 + 0x20], %f24 | ||
88 | ldd [%g3 + 0x28], %f26 | ||
89 | CAMELLIA_F(16, 2, 0, 2) | ||
90 | CAMELLIA_F(18, 0, 2, 0) | ||
91 | fxor %f28, %f0, %f0 | ||
92 | fxor %f30, %f2, %f2 | ||
93 | CAMELLIA_F(20, 2, 0, 2) | ||
94 | CAMELLIA_F(22, 0, 2, 0) | ||
95 | |||
96 | #define ROTL128(S01, S23, TMP1, TMP2, N) \ | ||
97 | srlx S01, (64 - N), TMP1; \ | ||
98 | sllx S01, N, S01; \ | ||
99 | srlx S23, (64 - N), TMP2; \ | ||
100 | sllx S23, N, S23; \ | ||
101 | or S01, TMP2, S01; \ | ||
102 | or S23, TMP1, S23 | ||
103 | |||
104 | cmp %o2, 16 | ||
105 | bne 1f | ||
106 | nop | ||
107 | /* 128-bit key */ | ||
108 | std %f0, [%o1 + 0x10] ! k[ 4, 5] | ||
109 | std %f2, [%o1 + 0x18] ! k[ 6, 7] | ||
110 | MOVDTOX_F0_O4 | ||
111 | MOVDTOX_F2_O5 | ||
112 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
113 | stx %o4, [%o1 + 0x30] ! k[12, 13] | ||
114 | stx %o5, [%o1 + 0x38] ! k[14, 15] | ||
115 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
116 | stx %o4, [%o1 + 0x40] ! k[16, 17] | ||
117 | stx %o5, [%o1 + 0x48] ! k[18, 19] | ||
118 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
119 | stx %o4, [%o1 + 0x60] ! k[24, 25] | ||
120 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
121 | stx %o4, [%o1 + 0x70] ! k[28, 29] | ||
122 | stx %o5, [%o1 + 0x78] ! k[30, 31] | ||
123 | ROTL128(%o4, %o5, %g2, %g3, 34) | ||
124 | stx %o4, [%o1 + 0xa0] ! k[40, 41] | ||
125 | stx %o5, [%o1 + 0xa8] ! k[42, 43] | ||
126 | ROTL128(%o4, %o5, %g2, %g3, 17) | ||
127 | stx %o4, [%o1 + 0xc0] ! k[48, 49] | ||
128 | stx %o5, [%o1 + 0xc8] ! k[50, 51] | ||
129 | |||
130 | ldx [%o1 + 0x00], %o4 ! k[ 0, 1] | ||
131 | ldx [%o1 + 0x08], %o5 ! k[ 2, 3] | ||
132 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
133 | stx %o4, [%o1 + 0x20] ! k[ 8, 9] | ||
134 | stx %o5, [%o1 + 0x28] ! k[10, 11] | ||
135 | ROTL128(%o4, %o5, %g2, %g3, 30) | ||
136 | stx %o4, [%o1 + 0x50] ! k[20, 21] | ||
137 | stx %o5, [%o1 + 0x58] ! k[22, 23] | ||
138 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
139 | stx %o5, [%o1 + 0x68] ! k[26, 27] | ||
140 | ROTL128(%o4, %o5, %g2, %g3, 17) | ||
141 | stx %o4, [%o1 + 0x80] ! k[32, 33] | ||
142 | stx %o5, [%o1 + 0x88] ! k[34, 35] | ||
143 | ROTL128(%o4, %o5, %g2, %g3, 17) | ||
144 | stx %o4, [%o1 + 0x90] ! k[36, 37] | ||
145 | stx %o5, [%o1 + 0x98] ! k[38, 39] | ||
146 | ROTL128(%o4, %o5, %g2, %g3, 17) | ||
147 | stx %o4, [%o1 + 0xb0] ! k[44, 45] | ||
148 | stx %o5, [%o1 + 0xb8] ! k[46, 47] | ||
149 | |||
150 | ba,pt %xcc, 2f | ||
151 | mov (3 * 16 * 4), %o0 | ||
152 | |||
153 | 1: | ||
154 | /* 192-bit or 256-bit key */ | ||
155 | std %f0, [%o1 + 0x30] ! k[12, 13] | ||
156 | std %f2, [%o1 + 0x38] ! k[14, 15] | ||
157 | ldd [%o1 + 0x20], %f4 ! k[ 8, 9] | ||
158 | ldd [%o1 + 0x28], %f6 ! k[10, 11] | ||
159 | fxor %f0, %f4, %f0 | ||
160 | fxor %f2, %f6, %f2 | ||
161 | CAMELLIA_F(24, 2, 0, 2) | ||
162 | CAMELLIA_F(26, 0, 2, 0) | ||
163 | std %f0, [%o1 + 0x10] ! k[ 4, 5] | ||
164 | std %f2, [%o1 + 0x18] ! k[ 6, 7] | ||
165 | MOVDTOX_F0_O4 | ||
166 | MOVDTOX_F2_O5 | ||
167 | ROTL128(%o4, %o5, %g2, %g3, 30) | ||
168 | stx %o4, [%o1 + 0x50] ! k[20, 21] | ||
169 | stx %o5, [%o1 + 0x58] ! k[22, 23] | ||
170 | ROTL128(%o4, %o5, %g2, %g3, 30) | ||
171 | stx %o4, [%o1 + 0xa0] ! k[40, 41] | ||
172 | stx %o5, [%o1 + 0xa8] ! k[42, 43] | ||
173 | ROTL128(%o4, %o5, %g2, %g3, 51) | ||
174 | stx %o4, [%o1 + 0x100] ! k[64, 65] | ||
175 | stx %o5, [%o1 + 0x108] ! k[66, 67] | ||
176 | ldx [%o1 + 0x20], %o4 ! k[ 8, 9] | ||
177 | ldx [%o1 + 0x28], %o5 ! k[10, 11] | ||
178 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
179 | stx %o4, [%o1 + 0x20] ! k[ 8, 9] | ||
180 | stx %o5, [%o1 + 0x28] ! k[10, 11] | ||
181 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
182 | stx %o4, [%o1 + 0x40] ! k[16, 17] | ||
183 | stx %o5, [%o1 + 0x48] ! k[18, 19] | ||
184 | ROTL128(%o4, %o5, %g2, %g3, 30) | ||
185 | stx %o4, [%o1 + 0x90] ! k[36, 37] | ||
186 | stx %o5, [%o1 + 0x98] ! k[38, 39] | ||
187 | ROTL128(%o4, %o5, %g2, %g3, 34) | ||
188 | stx %o4, [%o1 + 0xd0] ! k[52, 53] | ||
189 | stx %o5, [%o1 + 0xd8] ! k[54, 55] | ||
190 | ldx [%o1 + 0x30], %o4 ! k[12, 13] | ||
191 | ldx [%o1 + 0x38], %o5 ! k[14, 15] | ||
192 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
193 | stx %o4, [%o1 + 0x30] ! k[12, 13] | ||
194 | stx %o5, [%o1 + 0x38] ! k[14, 15] | ||
195 | ROTL128(%o4, %o5, %g2, %g3, 30) | ||
196 | stx %o4, [%o1 + 0x70] ! k[28, 29] | ||
197 | stx %o5, [%o1 + 0x78] ! k[30, 31] | ||
198 | srlx %o4, 32, %g2 | ||
199 | srlx %o5, 32, %g3 | ||
200 | stw %o4, [%o1 + 0xc0] ! k[48] | ||
201 | stw %g3, [%o1 + 0xc4] ! k[49] | ||
202 | stw %o5, [%o1 + 0xc8] ! k[50] | ||
203 | stw %g2, [%o1 + 0xcc] ! k[51] | ||
204 | ROTL128(%o4, %o5, %g2, %g3, 49) | ||
205 | stx %o4, [%o1 + 0xe0] ! k[56, 57] | ||
206 | stx %o5, [%o1 + 0xe8] ! k[58, 59] | ||
207 | ldx [%o1 + 0x00], %o4 ! k[ 0, 1] | ||
208 | ldx [%o1 + 0x08], %o5 ! k[ 2, 3] | ||
209 | ROTL128(%o4, %o5, %g2, %g3, 45) | ||
210 | stx %o4, [%o1 + 0x60] ! k[24, 25] | ||
211 | stx %o5, [%o1 + 0x68] ! k[26, 27] | ||
212 | ROTL128(%o4, %o5, %g2, %g3, 15) | ||
213 | stx %o4, [%o1 + 0x80] ! k[32, 33] | ||
214 | stx %o5, [%o1 + 0x88] ! k[34, 35] | ||
215 | ROTL128(%o4, %o5, %g2, %g3, 17) | ||
216 | stx %o4, [%o1 + 0xb0] ! k[44, 45] | ||
217 | stx %o5, [%o1 + 0xb8] ! k[46, 47] | ||
218 | ROTL128(%o4, %o5, %g2, %g3, 34) | ||
219 | stx %o4, [%o1 + 0xf0] ! k[60, 61] | ||
220 | stx %o5, [%o1 + 0xf8] ! k[62, 63] | ||
221 | mov (4 * 16 * 4), %o0 | ||
222 | 2: | ||
223 | add %o1, %o0, %o1 | ||
224 | ldd [%o1 + 0x00], %f0 | ||
225 | ldd [%o1 + 0x08], %f2 | ||
226 | std %f0, [%o3 + 0x00] | ||
227 | std %f2, [%o3 + 0x08] | ||
228 | add %o3, 0x10, %o3 | ||
229 | 1: | ||
230 | sub %o1, (16 * 4), %o1 | ||
231 | ldd [%o1 + 0x38], %f0 | ||
232 | ldd [%o1 + 0x30], %f2 | ||
233 | ldd [%o1 + 0x28], %f4 | ||
234 | ldd [%o1 + 0x20], %f6 | ||
235 | ldd [%o1 + 0x18], %f8 | ||
236 | ldd [%o1 + 0x10], %f10 | ||
237 | std %f0, [%o3 + 0x00] | ||
238 | std %f2, [%o3 + 0x08] | ||
239 | std %f4, [%o3 + 0x10] | ||
240 | std %f6, [%o3 + 0x18] | ||
241 | std %f8, [%o3 + 0x20] | ||
242 | std %f10, [%o3 + 0x28] | ||
243 | |||
244 | ldd [%o1 + 0x08], %f0 | ||
245 | ldd [%o1 + 0x00], %f2 | ||
246 | std %f0, [%o3 + 0x30] | ||
247 | std %f2, [%o3 + 0x38] | ||
248 | subcc %o0, (16 * 4), %o0 | ||
249 | bne,pt %icc, 1b | ||
250 | add %o3, (16 * 4), %o3 | ||
251 | |||
252 | std %f2, [%o3 - 0x10] | ||
253 | std %f0, [%o3 - 0x08] | ||
254 | |||
255 | retl | ||
256 | VISExit | ||
257 | ENDPROC(camellia_sparc64_key_expand) | ||
258 | |||
259 | .align 32 | ||
260 | ENTRY(camellia_sparc64_crypt) | ||
261 | /* %o0=key, %o1=input, %o2=output, %o3=key_len */ | ||
262 | VISEntry | ||
263 | |||
264 | ld [%o1 + 0x00], %f0 | ||
265 | ld [%o1 + 0x04], %f1 | ||
266 | ld [%o1 + 0x08], %f2 | ||
267 | ld [%o1 + 0x0c], %f3 | ||
268 | |||
269 | ldd [%o0 + 0x00], %f4 | ||
270 | ldd [%o0 + 0x08], %f6 | ||
271 | |||
272 | cmp %o3, 16 | ||
273 | fxor %f4, %f0, %f0 | ||
274 | be 1f | ||
275 | fxor %f6, %f2, %f2 | ||
276 | |||
277 | ldd [%o0 + 0x10], %f8 | ||
278 | ldd [%o0 + 0x18], %f10 | ||
279 | ldd [%o0 + 0x20], %f12 | ||
280 | ldd [%o0 + 0x28], %f14 | ||
281 | ldd [%o0 + 0x30], %f16 | ||
282 | ldd [%o0 + 0x38], %f18 | ||
283 | ldd [%o0 + 0x40], %f20 | ||
284 | ldd [%o0 + 0x48], %f22 | ||
285 | add %o0, 0x40, %o0 | ||
286 | |||
287 | CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2) | ||
288 | |||
289 | 1: | ||
290 | ldd [%o0 + 0x10], %f8 | ||
291 | ldd [%o0 + 0x18], %f10 | ||
292 | ldd [%o0 + 0x20], %f12 | ||
293 | ldd [%o0 + 0x28], %f14 | ||
294 | ldd [%o0 + 0x30], %f16 | ||
295 | ldd [%o0 + 0x38], %f18 | ||
296 | ldd [%o0 + 0x40], %f20 | ||
297 | ldd [%o0 + 0x48], %f22 | ||
298 | ldd [%o0 + 0x50], %f24 | ||
299 | ldd [%o0 + 0x58], %f26 | ||
300 | ldd [%o0 + 0x60], %f28 | ||
301 | ldd [%o0 + 0x68], %f30 | ||
302 | ldd [%o0 + 0x70], %f32 | ||
303 | ldd [%o0 + 0x78], %f34 | ||
304 | ldd [%o0 + 0x80], %f36 | ||
305 | ldd [%o0 + 0x88], %f38 | ||
306 | ldd [%o0 + 0x90], %f40 | ||
307 | ldd [%o0 + 0x98], %f42 | ||
308 | ldd [%o0 + 0xa0], %f44 | ||
309 | ldd [%o0 + 0xa8], %f46 | ||
310 | ldd [%o0 + 0xb0], %f48 | ||
311 | ldd [%o0 + 0xb8], %f50 | ||
312 | ldd [%o0 + 0xc0], %f52 | ||
313 | ldd [%o0 + 0xc8], %f54 | ||
314 | |||
315 | CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2) | ||
316 | CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2) | ||
317 | CAMELLIA_6ROUNDS(40, 0, 2) | ||
318 | fxor %f52, %f2, %f2 | ||
319 | fxor %f54, %f0, %f0 | ||
320 | |||
321 | st %f2, [%o2 + 0x00] | ||
322 | st %f3, [%o2 + 0x04] | ||
323 | st %f0, [%o2 + 0x08] | ||
324 | st %f1, [%o2 + 0x0c] | ||
325 | |||
326 | retl | ||
327 | VISExit | ||
328 | ENDPROC(camellia_sparc64_crypt) | ||
329 | |||
330 | .align 32 | ||
331 | ENTRY(camellia_sparc64_load_keys) | ||
332 | /* %o0=key, %o1=key_len */ | ||
333 | VISEntry | ||
334 | ldd [%o0 + 0x00], %f4 | ||
335 | ldd [%o0 + 0x08], %f6 | ||
336 | ldd [%o0 + 0x10], %f8 | ||
337 | ldd [%o0 + 0x18], %f10 | ||
338 | ldd [%o0 + 0x20], %f12 | ||
339 | ldd [%o0 + 0x28], %f14 | ||
340 | ldd [%o0 + 0x30], %f16 | ||
341 | ldd [%o0 + 0x38], %f18 | ||
342 | ldd [%o0 + 0x40], %f20 | ||
343 | ldd [%o0 + 0x48], %f22 | ||
344 | ldd [%o0 + 0x50], %f24 | ||
345 | ldd [%o0 + 0x58], %f26 | ||
346 | ldd [%o0 + 0x60], %f28 | ||
347 | ldd [%o0 + 0x68], %f30 | ||
348 | ldd [%o0 + 0x70], %f32 | ||
349 | ldd [%o0 + 0x78], %f34 | ||
350 | ldd [%o0 + 0x80], %f36 | ||
351 | ldd [%o0 + 0x88], %f38 | ||
352 | ldd [%o0 + 0x90], %f40 | ||
353 | ldd [%o0 + 0x98], %f42 | ||
354 | ldd [%o0 + 0xa0], %f44 | ||
355 | ldd [%o0 + 0xa8], %f46 | ||
356 | ldd [%o0 + 0xb0], %f48 | ||
357 | ldd [%o0 + 0xb8], %f50 | ||
358 | ldd [%o0 + 0xc0], %f52 | ||
359 | retl | ||
360 | ldd [%o0 + 0xc8], %f54 | ||
361 | ENDPROC(camellia_sparc64_load_keys) | ||
362 | |||
363 | .align 32 | ||
364 | ENTRY(camellia_sparc64_ecb_crypt_3_grand_rounds) | ||
365 | /* %o0=input, %o1=output, %o2=len, %o3=key */ | ||
366 | 1: ldd [%o0 + 0x00], %f0 | ||
367 | ldd [%o0 + 0x08], %f2 | ||
368 | add %o0, 0x10, %o0 | ||
369 | fxor %f4, %f0, %f0 | ||
370 | fxor %f6, %f2, %f2 | ||
371 | CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2) | ||
372 | CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2) | ||
373 | CAMELLIA_6ROUNDS(40, 0, 2) | ||
374 | fxor %f52, %f2, %f2 | ||
375 | fxor %f54, %f0, %f0 | ||
376 | std %f2, [%o1 + 0x00] | ||
377 | std %f0, [%o1 + 0x08] | ||
378 | subcc %o2, 0x10, %o2 | ||
379 | bne,pt %icc, 1b | ||
380 | add %o1, 0x10, %o1 | ||
381 | retl | ||
382 | nop | ||
383 | ENDPROC(camellia_sparc64_ecb_crypt_3_grand_rounds) | ||
384 | |||
385 | .align 32 | ||
386 | ENTRY(camellia_sparc64_ecb_crypt_4_grand_rounds) | ||
387 | /* %o0=input, %o1=output, %o2=len, %o3=key */ | ||
388 | 1: ldd [%o0 + 0x00], %f0 | ||
389 | ldd [%o0 + 0x08], %f2 | ||
390 | add %o0, 0x10, %o0 | ||
391 | fxor %f4, %f0, %f0 | ||
392 | fxor %f6, %f2, %f2 | ||
393 | CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2) | ||
394 | ldd [%o3 + 0xd0], %f8 | ||
395 | ldd [%o3 + 0xd8], %f10 | ||
396 | ldd [%o3 + 0xe0], %f12 | ||
397 | ldd [%o3 + 0xe8], %f14 | ||
398 | ldd [%o3 + 0xf0], %f16 | ||
399 | ldd [%o3 + 0xf8], %f18 | ||
400 | ldd [%o3 + 0x100], %f20 | ||
401 | ldd [%o3 + 0x108], %f22 | ||
402 | CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2) | ||
403 | CAMELLIA_6ROUNDS_FL_FLI(40, 0, 2) | ||
404 | CAMELLIA_F(8, 2, 0, 2) | ||
405 | CAMELLIA_F(10, 0, 2, 0) | ||
406 | ldd [%o3 + 0x10], %f8 | ||
407 | ldd [%o3 + 0x18], %f10 | ||
408 | CAMELLIA_F(12, 2, 0, 2) | ||
409 | CAMELLIA_F(14, 0, 2, 0) | ||
410 | ldd [%o3 + 0x20], %f12 | ||
411 | ldd [%o3 + 0x28], %f14 | ||
412 | CAMELLIA_F(16, 2, 0, 2) | ||
413 | CAMELLIA_F(18, 0, 2, 0) | ||
414 | ldd [%o3 + 0x30], %f16 | ||
415 | ldd [%o3 + 0x38], %f18 | ||
416 | fxor %f20, %f2, %f2 | ||
417 | fxor %f22, %f0, %f0 | ||
418 | ldd [%o3 + 0x40], %f20 | ||
419 | ldd [%o3 + 0x48], %f22 | ||
420 | std %f2, [%o1 + 0x00] | ||
421 | std %f0, [%o1 + 0x08] | ||
422 | subcc %o2, 0x10, %o2 | ||
423 | bne,pt %icc, 1b | ||
424 | add %o1, 0x10, %o1 | ||
425 | retl | ||
426 | nop | ||
427 | ENDPROC(camellia_sparc64_ecb_crypt_4_grand_rounds) | ||
428 | |||
429 | .align 32 | ||
430 | ENTRY(camellia_sparc64_cbc_encrypt_3_grand_rounds) | ||
431 | /* %o0=input, %o1=output, %o2=len, %o3=key, %o4=IV */ | ||
432 | ldd [%o4 + 0x00], %f60 | ||
433 | ldd [%o4 + 0x08], %f62 | ||
434 | 1: ldd [%o0 + 0x00], %f0 | ||
435 | ldd [%o0 + 0x08], %f2 | ||
436 | add %o0, 0x10, %o0 | ||
437 | fxor %f60, %f0, %f0 | ||
438 | fxor %f62, %f2, %f2 | ||
439 | fxor %f4, %f0, %f0 | ||
440 | fxor %f6, %f2, %f2 | ||
441 | CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2) | ||
442 | CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2) | ||
443 | CAMELLIA_6ROUNDS(40, 0, 2) | ||
444 | fxor %f52, %f2, %f60 | ||
445 | fxor %f54, %f0, %f62 | ||
446 | std %f60, [%o1 + 0x00] | ||
447 | std %f62, [%o1 + 0x08] | ||
448 | subcc %o2, 0x10, %o2 | ||
449 | bne,pt %icc, 1b | ||
450 | add %o1, 0x10, %o1 | ||
451 | std %f60, [%o4 + 0x00] | ||
452 | retl | ||
453 | std %f62, [%o4 + 0x08] | ||
454 | ENDPROC(camellia_sparc64_cbc_encrypt_3_grand_rounds) | ||
455 | |||
456 | .align 32 | ||
457 | ENTRY(camellia_sparc64_cbc_encrypt_4_grand_rounds) | ||
458 | /* %o0=input, %o1=output, %o2=len, %o3=key, %o4=IV */ | ||
459 | ldd [%o4 + 0x00], %f60 | ||
460 | ldd [%o4 + 0x08], %f62 | ||
461 | 1: ldd [%o0 + 0x00], %f0 | ||
462 | ldd [%o0 + 0x08], %f2 | ||
463 | add %o0, 0x10, %o0 | ||
464 | fxor %f60, %f0, %f0 | ||
465 | fxor %f62, %f2, %f2 | ||
466 | fxor %f4, %f0, %f0 | ||
467 | fxor %f6, %f2, %f2 | ||
468 | CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2) | ||
469 | ldd [%o3 + 0xd0], %f8 | ||
470 | ldd [%o3 + 0xd8], %f10 | ||
471 | ldd [%o3 + 0xe0], %f12 | ||
472 | ldd [%o3 + 0xe8], %f14 | ||
473 | ldd [%o3 + 0xf0], %f16 | ||
474 | ldd [%o3 + 0xf8], %f18 | ||
475 | ldd [%o3 + 0x100], %f20 | ||
476 | ldd [%o3 + 0x108], %f22 | ||
477 | CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2) | ||
478 | CAMELLIA_6ROUNDS_FL_FLI(40, 0, 2) | ||
479 | CAMELLIA_F(8, 2, 0, 2) | ||
480 | CAMELLIA_F(10, 0, 2, 0) | ||
481 | ldd [%o3 + 0x10], %f8 | ||
482 | ldd [%o3 + 0x18], %f10 | ||
483 | CAMELLIA_F(12, 2, 0, 2) | ||
484 | CAMELLIA_F(14, 0, 2, 0) | ||
485 | ldd [%o3 + 0x20], %f12 | ||
486 | ldd [%o3 + 0x28], %f14 | ||
487 | CAMELLIA_F(16, 2, 0, 2) | ||
488 | CAMELLIA_F(18, 0, 2, 0) | ||
489 | ldd [%o3 + 0x30], %f16 | ||
490 | ldd [%o3 + 0x38], %f18 | ||
491 | fxor %f20, %f2, %f60 | ||
492 | fxor %f22, %f0, %f62 | ||
493 | ldd [%o3 + 0x40], %f20 | ||
494 | ldd [%o3 + 0x48], %f22 | ||
495 | std %f60, [%o1 + 0x00] | ||
496 | std %f62, [%o1 + 0x08] | ||
497 | subcc %o2, 0x10, %o2 | ||
498 | bne,pt %icc, 1b | ||
499 | add %o1, 0x10, %o1 | ||
500 | std %f60, [%o4 + 0x00] | ||
501 | retl | ||
502 | std %f62, [%o4 + 0x08] | ||
503 | ENDPROC(camellia_sparc64_cbc_encrypt_4_grand_rounds) | ||
504 | |||
505 | .align 32 | ||
506 | ENTRY(camellia_sparc64_cbc_decrypt_3_grand_rounds) | ||
507 | /* %o0=input, %o1=output, %o2=len, %o3=key, %o4=IV */ | ||
508 | ldd [%o4 + 0x00], %f60 | ||
509 | ldd [%o4 + 0x08], %f62 | ||
510 | 1: ldd [%o0 + 0x00], %f56 | ||
511 | ldd [%o0 + 0x08], %f58 | ||
512 | add %o0, 0x10, %o0 | ||
513 | fxor %f4, %f56, %f0 | ||
514 | fxor %f6, %f58, %f2 | ||
515 | CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2) | ||
516 | CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2) | ||
517 | CAMELLIA_6ROUNDS(40, 0, 2) | ||
518 | fxor %f52, %f2, %f2 | ||
519 | fxor %f54, %f0, %f0 | ||
520 | fxor %f60, %f2, %f2 | ||
521 | fxor %f62, %f0, %f0 | ||
522 | fsrc2 %f56, %f60 | ||
523 | fsrc2 %f58, %f62 | ||
524 | std %f2, [%o1 + 0x00] | ||
525 | std %f0, [%o1 + 0x08] | ||
526 | subcc %o2, 0x10, %o2 | ||
527 | bne,pt %icc, 1b | ||
528 | add %o1, 0x10, %o1 | ||
529 | std %f60, [%o4 + 0x00] | ||
530 | retl | ||
531 | std %f62, [%o4 + 0x08] | ||
532 | ENDPROC(camellia_sparc64_cbc_decrypt_3_grand_rounds) | ||
533 | |||
534 | .align 32 | ||
535 | ENTRY(camellia_sparc64_cbc_decrypt_4_grand_rounds) | ||
536 | /* %o0=input, %o1=output, %o2=len, %o3=key, %o4=IV */ | ||
537 | ldd [%o4 + 0x00], %f60 | ||
538 | ldd [%o4 + 0x08], %f62 | ||
539 | 1: ldd [%o0 + 0x00], %f56 | ||
540 | ldd [%o0 + 0x08], %f58 | ||
541 | add %o0, 0x10, %o0 | ||
542 | fxor %f4, %f56, %f0 | ||
543 | fxor %f6, %f58, %f2 | ||
544 | CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2) | ||
545 | ldd [%o3 + 0xd0], %f8 | ||
546 | ldd [%o3 + 0xd8], %f10 | ||
547 | ldd [%o3 + 0xe0], %f12 | ||
548 | ldd [%o3 + 0xe8], %f14 | ||
549 | ldd [%o3 + 0xf0], %f16 | ||
550 | ldd [%o3 + 0xf8], %f18 | ||
551 | ldd [%o3 + 0x100], %f20 | ||
552 | ldd [%o3 + 0x108], %f22 | ||
553 | CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2) | ||
554 | CAMELLIA_6ROUNDS_FL_FLI(40, 0, 2) | ||
555 | CAMELLIA_F(8, 2, 0, 2) | ||
556 | CAMELLIA_F(10, 0, 2, 0) | ||
557 | ldd [%o3 + 0x10], %f8 | ||
558 | ldd [%o3 + 0x18], %f10 | ||
559 | CAMELLIA_F(12, 2, 0, 2) | ||
560 | CAMELLIA_F(14, 0, 2, 0) | ||
561 | ldd [%o3 + 0x20], %f12 | ||
562 | ldd [%o3 + 0x28], %f14 | ||
563 | CAMELLIA_F(16, 2, 0, 2) | ||
564 | CAMELLIA_F(18, 0, 2, 0) | ||
565 | ldd [%o3 + 0x30], %f16 | ||
566 | ldd [%o3 + 0x38], %f18 | ||
567 | fxor %f20, %f2, %f2 | ||
568 | fxor %f22, %f0, %f0 | ||
569 | ldd [%o3 + 0x40], %f20 | ||
570 | ldd [%o3 + 0x48], %f22 | ||
571 | fxor %f60, %f2, %f2 | ||
572 | fxor %f62, %f0, %f0 | ||
573 | fsrc2 %f56, %f60 | ||
574 | fsrc2 %f58, %f62 | ||
575 | std %f2, [%o1 + 0x00] | ||
576 | std %f0, [%o1 + 0x08] | ||
577 | subcc %o2, 0x10, %o2 | ||
578 | bne,pt %icc, 1b | ||
579 | add %o1, 0x10, %o1 | ||
580 | std %f60, [%o4 + 0x00] | ||
581 | retl | ||
582 | std %f62, [%o4 + 0x08] | ||
583 | ENDPROC(camellia_sparc64_cbc_decrypt_4_grand_rounds) | ||
diff --git a/arch/sparc/crypto/camellia_glue.c b/arch/sparc/crypto/camellia_glue.c new file mode 100644 index 000000000000..c258cc550a6b --- /dev/null +++ b/arch/sparc/crypto/camellia_glue.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* Glue code for CAMELLIA 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 | |||
13 | #include <asm/fpumacro.h> | ||
14 | #include <asm/pstate.h> | ||
15 | #include <asm/elf.h> | ||
16 | |||
17 | #define CAMELLIA_MIN_KEY_SIZE 16 | ||
18 | #define CAMELLIA_MAX_KEY_SIZE 32 | ||
19 | #define CAMELLIA_BLOCK_SIZE 16 | ||
20 | #define CAMELLIA_TABLE_BYTE_LEN 272 | ||
21 | |||
22 | struct camellia_sparc64_ctx { | ||
23 | u64 encrypt_key[CAMELLIA_TABLE_BYTE_LEN / sizeof(u64)]; | ||
24 | u64 decrypt_key[CAMELLIA_TABLE_BYTE_LEN / sizeof(u64)]; | ||
25 | int key_len; | ||
26 | }; | ||
27 | |||
28 | extern void camellia_sparc64_key_expand(const u32 *in_key, u64 *encrypt_key, | ||
29 | unsigned int key_len, u64 *decrypt_key); | ||
30 | |||
31 | static int camellia_set_key(struct crypto_tfm *tfm, const u8 *_in_key, | ||
32 | unsigned int key_len) | ||
33 | { | ||
34 | struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm); | ||
35 | const u32 *in_key = (const u32 *) _in_key; | ||
36 | u32 *flags = &tfm->crt_flags; | ||
37 | |||
38 | if (key_len != 16 && key_len != 24 && key_len != 32) { | ||
39 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
40 | return -EINVAL; | ||
41 | } | ||
42 | |||
43 | ctx->key_len = key_len; | ||
44 | |||
45 | camellia_sparc64_key_expand(in_key, &ctx->encrypt_key[0], | ||
46 | key_len, &ctx->decrypt_key[0]); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | extern void camellia_sparc64_crypt(const u64 *key, const u32 *input, | ||
51 | u32 *output, unsigned int key_len); | ||
52 | |||
53 | static void camellia_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
54 | { | ||
55 | struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm); | ||
56 | |||
57 | camellia_sparc64_crypt(&ctx->encrypt_key[0], | ||
58 | (const u32 *) src, | ||
59 | (u32 *) dst, ctx->key_len); | ||
60 | } | ||
61 | |||
62 | static void camellia_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
63 | { | ||
64 | struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm); | ||
65 | |||
66 | camellia_sparc64_crypt(&ctx->decrypt_key[0], | ||
67 | (const u32 *) src, | ||
68 | (u32 *) dst, ctx->key_len); | ||
69 | } | ||
70 | |||
71 | extern void camellia_sparc64_load_keys(const u64 *key, unsigned int key_len); | ||
72 | |||
73 | typedef void ecb_crypt_op(const u64 *input, u64 *output, unsigned int len, | ||
74 | const u64 *key); | ||
75 | |||
76 | extern ecb_crypt_op camellia_sparc64_ecb_crypt_3_grand_rounds; | ||
77 | extern ecb_crypt_op camellia_sparc64_ecb_crypt_4_grand_rounds; | ||
78 | |||
79 | #define CAMELLIA_BLOCK_MASK (~(CAMELLIA_BLOCK_SIZE - 1)) | ||
80 | |||
81 | static int __ecb_crypt(struct blkcipher_desc *desc, | ||
82 | struct scatterlist *dst, struct scatterlist *src, | ||
83 | unsigned int nbytes, bool encrypt) | ||
84 | { | ||
85 | struct camellia_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
86 | struct blkcipher_walk walk; | ||
87 | ecb_crypt_op *op; | ||
88 | const u64 *key; | ||
89 | int err; | ||
90 | |||
91 | op = camellia_sparc64_ecb_crypt_3_grand_rounds; | ||
92 | if (ctx->key_len != 16) | ||
93 | op = camellia_sparc64_ecb_crypt_4_grand_rounds; | ||
94 | |||
95 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
96 | err = blkcipher_walk_virt(desc, &walk); | ||
97 | |||
98 | if (encrypt) | ||
99 | key = &ctx->encrypt_key[0]; | ||
100 | else | ||
101 | key = &ctx->decrypt_key[0]; | ||
102 | camellia_sparc64_load_keys(key, ctx->key_len); | ||
103 | while ((nbytes = walk.nbytes)) { | ||
104 | unsigned int block_len = nbytes & CAMELLIA_BLOCK_MASK; | ||
105 | |||
106 | if (likely(block_len)) { | ||
107 | const u64 *src64; | ||
108 | u64 *dst64; | ||
109 | |||
110 | src64 = (const u64 *)walk.src.virt.addr; | ||
111 | dst64 = (u64 *) walk.dst.virt.addr; | ||
112 | op(src64, dst64, block_len, key); | ||
113 | } | ||
114 | nbytes &= CAMELLIA_BLOCK_SIZE - 1; | ||
115 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
116 | } | ||
117 | fprs_write(0); | ||
118 | return err; | ||
119 | } | ||
120 | |||
121 | static int ecb_encrypt(struct blkcipher_desc *desc, | ||
122 | struct scatterlist *dst, struct scatterlist *src, | ||
123 | unsigned int nbytes) | ||
124 | { | ||
125 | return __ecb_crypt(desc, dst, src, nbytes, true); | ||
126 | } | ||
127 | |||
128 | static int ecb_decrypt(struct blkcipher_desc *desc, | ||
129 | struct scatterlist *dst, struct scatterlist *src, | ||
130 | unsigned int nbytes) | ||
131 | { | ||
132 | return __ecb_crypt(desc, dst, src, nbytes, false); | ||
133 | } | ||
134 | |||
135 | typedef void cbc_crypt_op(const u64 *input, u64 *output, unsigned int len, | ||
136 | const u64 *key, u64 *iv); | ||
137 | |||
138 | extern cbc_crypt_op camellia_sparc64_cbc_encrypt_3_grand_rounds; | ||
139 | extern cbc_crypt_op camellia_sparc64_cbc_encrypt_4_grand_rounds; | ||
140 | extern cbc_crypt_op camellia_sparc64_cbc_decrypt_3_grand_rounds; | ||
141 | extern cbc_crypt_op camellia_sparc64_cbc_decrypt_4_grand_rounds; | ||
142 | |||
143 | static int cbc_encrypt(struct blkcipher_desc *desc, | ||
144 | struct scatterlist *dst, struct scatterlist *src, | ||
145 | unsigned int nbytes) | ||
146 | { | ||
147 | struct camellia_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
148 | struct blkcipher_walk walk; | ||
149 | cbc_crypt_op *op; | ||
150 | const u64 *key; | ||
151 | int err; | ||
152 | |||
153 | op = camellia_sparc64_cbc_encrypt_3_grand_rounds; | ||
154 | if (ctx->key_len != 16) | ||
155 | op = camellia_sparc64_cbc_encrypt_4_grand_rounds; | ||
156 | |||
157 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
158 | err = blkcipher_walk_virt(desc, &walk); | ||
159 | |||
160 | key = &ctx->encrypt_key[0]; | ||
161 | camellia_sparc64_load_keys(key, ctx->key_len); | ||
162 | while ((nbytes = walk.nbytes)) { | ||
163 | unsigned int block_len = nbytes & CAMELLIA_BLOCK_MASK; | ||
164 | |||
165 | if (likely(block_len)) { | ||
166 | const u64 *src64; | ||
167 | u64 *dst64; | ||
168 | |||
169 | src64 = (const u64 *)walk.src.virt.addr; | ||
170 | dst64 = (u64 *) walk.dst.virt.addr; | ||
171 | op(src64, dst64, block_len, key, | ||
172 | (u64 *) walk.iv); | ||
173 | } | ||
174 | nbytes &= CAMELLIA_BLOCK_SIZE - 1; | ||
175 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
176 | } | ||
177 | fprs_write(0); | ||
178 | return err; | ||
179 | } | ||
180 | |||
181 | static int cbc_decrypt(struct blkcipher_desc *desc, | ||
182 | struct scatterlist *dst, struct scatterlist *src, | ||
183 | unsigned int nbytes) | ||
184 | { | ||
185 | struct camellia_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
186 | struct blkcipher_walk walk; | ||
187 | cbc_crypt_op *op; | ||
188 | const u64 *key; | ||
189 | int err; | ||
190 | |||
191 | op = camellia_sparc64_cbc_decrypt_3_grand_rounds; | ||
192 | if (ctx->key_len != 16) | ||
193 | op = camellia_sparc64_cbc_decrypt_4_grand_rounds; | ||
194 | |||
195 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
196 | err = blkcipher_walk_virt(desc, &walk); | ||
197 | |||
198 | key = &ctx->decrypt_key[0]; | ||
199 | camellia_sparc64_load_keys(key, ctx->key_len); | ||
200 | while ((nbytes = walk.nbytes)) { | ||
201 | unsigned int block_len = nbytes & CAMELLIA_BLOCK_MASK; | ||
202 | |||
203 | if (likely(block_len)) { | ||
204 | const u64 *src64; | ||
205 | u64 *dst64; | ||
206 | |||
207 | src64 = (const u64 *)walk.src.virt.addr; | ||
208 | dst64 = (u64 *) walk.dst.virt.addr; | ||
209 | op(src64, dst64, block_len, key, | ||
210 | (u64 *) walk.iv); | ||
211 | } | ||
212 | nbytes &= CAMELLIA_BLOCK_SIZE - 1; | ||
213 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
214 | } | ||
215 | fprs_write(0); | ||
216 | return err; | ||
217 | } | ||
218 | |||
219 | static struct crypto_alg algs[] = { { | ||
220 | .cra_name = "camellia", | ||
221 | .cra_driver_name = "camellia-sparc64", | ||
222 | .cra_priority = 150, | ||
223 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
224 | .cra_blocksize = CAMELLIA_BLOCK_SIZE, | ||
225 | .cra_ctxsize = sizeof(struct camellia_sparc64_ctx), | ||
226 | .cra_alignmask = 3, | ||
227 | .cra_module = THIS_MODULE, | ||
228 | .cra_u = { | ||
229 | .cipher = { | ||
230 | .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE, | ||
231 | .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE, | ||
232 | .cia_setkey = camellia_set_key, | ||
233 | .cia_encrypt = camellia_encrypt, | ||
234 | .cia_decrypt = camellia_decrypt | ||
235 | } | ||
236 | } | ||
237 | }, { | ||
238 | .cra_name = "ecb(camellia)", | ||
239 | .cra_driver_name = "ecb-camellia-sparc64", | ||
240 | .cra_priority = 150, | ||
241 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
242 | .cra_blocksize = CAMELLIA_BLOCK_SIZE, | ||
243 | .cra_ctxsize = sizeof(struct camellia_sparc64_ctx), | ||
244 | .cra_alignmask = 7, | ||
245 | .cra_type = &crypto_blkcipher_type, | ||
246 | .cra_module = THIS_MODULE, | ||
247 | .cra_u = { | ||
248 | .blkcipher = { | ||
249 | .min_keysize = CAMELLIA_MIN_KEY_SIZE, | ||
250 | .max_keysize = CAMELLIA_MAX_KEY_SIZE, | ||
251 | .setkey = camellia_set_key, | ||
252 | .encrypt = ecb_encrypt, | ||
253 | .decrypt = ecb_decrypt, | ||
254 | }, | ||
255 | }, | ||
256 | }, { | ||
257 | .cra_name = "cbc(camellia)", | ||
258 | .cra_driver_name = "cbc-camellia-sparc64", | ||
259 | .cra_priority = 150, | ||
260 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
261 | .cra_blocksize = CAMELLIA_BLOCK_SIZE, | ||
262 | .cra_ctxsize = sizeof(struct camellia_sparc64_ctx), | ||
263 | .cra_alignmask = 7, | ||
264 | .cra_type = &crypto_blkcipher_type, | ||
265 | .cra_module = THIS_MODULE, | ||
266 | .cra_u = { | ||
267 | .blkcipher = { | ||
268 | .min_keysize = CAMELLIA_MIN_KEY_SIZE, | ||
269 | .max_keysize = CAMELLIA_MAX_KEY_SIZE, | ||
270 | .setkey = camellia_set_key, | ||
271 | .encrypt = cbc_encrypt, | ||
272 | .decrypt = cbc_decrypt, | ||
273 | }, | ||
274 | }, | ||
275 | } | ||
276 | }; | ||
277 | |||
278 | static bool __init sparc64_has_camellia_opcode(void) | ||
279 | { | ||
280 | unsigned long cfr; | ||
281 | |||
282 | if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO)) | ||
283 | return false; | ||
284 | |||
285 | __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr)); | ||
286 | if (!(cfr & CFR_CAMELLIA)) | ||
287 | return false; | ||
288 | |||
289 | return true; | ||
290 | } | ||
291 | |||
292 | static int __init camellia_sparc64_mod_init(void) | ||
293 | { | ||
294 | int i; | ||
295 | |||
296 | for (i = 0; i < ARRAY_SIZE(algs); i++) | ||
297 | INIT_LIST_HEAD(&algs[i].cra_list); | ||
298 | |||
299 | if (sparc64_has_camellia_opcode()) { | ||
300 | pr_info("Using sparc64 camellia opcodes optimized CAMELLIA implementation\n"); | ||
301 | return crypto_register_algs(algs, ARRAY_SIZE(algs)); | ||
302 | } | ||
303 | pr_info("sparc64 camellia opcodes not available.\n"); | ||
304 | return -ENODEV; | ||
305 | } | ||
306 | |||
307 | static void __exit camellia_sparc64_mod_fini(void) | ||
308 | { | ||
309 | crypto_unregister_algs(algs, ARRAY_SIZE(algs)); | ||
310 | } | ||
311 | |||
312 | module_init(camellia_sparc64_mod_init); | ||
313 | module_exit(camellia_sparc64_mod_fini); | ||
314 | |||
315 | MODULE_LICENSE("GPL"); | ||
316 | MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); | ||
317 | |||
318 | MODULE_ALIAS("aes"); | ||