diff options
author | David S. Miller <davem@davemloft.net> | 2012-08-21 06:58:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-08-22 17:29:33 -0400 |
commit | 9bf4852d3d195f771503d5be547ac940b0b3472a (patch) | |
tree | 63508c354ec0f085afd253c204f320af7c53c451 /arch/sparc | |
parent | fa4dfedcc23a589f953750de54eebf986336fa70 (diff) |
sparc64: Add AES driver making use of the new aes opcodes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/crypto/Makefile | 4 | ||||
-rw-r--r-- | arch/sparc/crypto/aes_asm.S | 836 | ||||
-rw-r--r-- | arch/sparc/crypto/aes_glue.c | 323 |
3 files changed, 1163 insertions, 0 deletions
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile index 535669828d47..5034324fdd46 100644 --- a/arch/sparc/crypto/Makefile +++ b/arch/sparc/crypto/Makefile | |||
@@ -7,7 +7,11 @@ obj-$(CONFIG_CRYPTO_SHA256_SPARC64) += sha256-sparc64.o | |||
7 | obj-$(CONFIG_CRYPTO_SHA512_SPARC64) += sha512-sparc64.o | 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 | ||
11 | |||
10 | sha1-sparc64-y := sha1_asm.o sha1_glue.o | 12 | sha1-sparc64-y := sha1_asm.o sha1_glue.o |
11 | sha256-sparc64-y := sha256_asm.o sha256_glue.o | 13 | sha256-sparc64-y := sha256_asm.o sha256_glue.o |
12 | sha512-sparc64-y := sha512_asm.o sha512_glue.o | 14 | sha512-sparc64-y := sha512_asm.o sha512_glue.o |
13 | md5-sparc64-y := md5_asm.o md5_glue.o | 15 | md5-sparc64-y := md5_asm.o md5_glue.o |
16 | |||
17 | aes-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 | |||
128 | ENTRY(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 | |||
212 | 1: | ||
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 | |||
269 | 2: | ||
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] | ||
312 | 80: | ||
313 | retl | ||
314 | VISExit | ||
315 | ENDPROC(aes_sparc64_key_expand) | ||
316 | |||
317 | ENTRY(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 | |||
344 | 1: | ||
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 | |||
352 | 2: | ||
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 | ||
384 | ENDPROC(aes_sparc64_encrypt) | ||
385 | |||
386 | ENTRY(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 | ||
414 | 1: | ||
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) | ||
421 | 2: | ||
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 | ||
452 | ENDPROC(aes_sparc64_decrypt) | ||
453 | |||
454 | ENTRY(aes_sparc64_load_decrypt_keys) | ||
455 | /* %o0=key */ | ||
456 | ba,pt %xcc, aes_sparc64_load_encrypt_keys | ||
457 | sub %o0, 0x10, %o0 | ||
458 | ENDPROC(aes_sparc64_load_decrypt_keys) | ||
459 | |||
460 | ENTRY(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 | ||
492 | ENDPROC(aes_sparc64_load_encrypt_keys) | ||
493 | |||
494 | ENTRY(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 | |||
504 | 0: | ||
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 | |||
525 | 1: | ||
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 | |||
546 | 2: | ||
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 | ||
566 | ENDPROC(aes_sparc64_ecb_encrypt) | ||
567 | |||
568 | ENTRY(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 | |||
578 | 0: | ||
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 | |||
599 | 1: | ||
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 | |||
620 | 2: | ||
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 | ||
640 | ENDPROC(aes_sparc64_ecb_decrypt) | ||
641 | |||
642 | ENTRY(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 | |||
654 | 0: | ||
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 | |||
680 | 1: | ||
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 | |||
706 | 2: | ||
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 | ||
731 | ENDPROC(aes_sparc64_cbc_encrypt) | ||
732 | |||
733 | ENTRY(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 | |||
744 | 0: | ||
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 | |||
775 | 1: | ||
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 | |||
806 | 2: | ||
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 | ||
836 | ENDPROC(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 | |||
29 | struct crypto_sparc64_aes_ctx { | ||
30 | u64 key[AES_MAX_KEYLENGTH / sizeof(u64)]; | ||
31 | u32 key_length; | ||
32 | u32 expanded_key_length; | ||
33 | }; | ||
34 | |||
35 | extern void aes_sparc64_key_expand(const u32 *in_key, u64 *output_key, | ||
36 | unsigned int key_len); | ||
37 | |||
38 | static 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 | |||
68 | extern void aes_sparc64_encrypt(const u64 *key, const u32 *input, | ||
69 | u32 *output, unsigned int key_len); | ||
70 | |||
71 | static 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 | |||
79 | extern void aes_sparc64_decrypt(const u64 *key, const u32 *input, | ||
80 | u32 *output, unsigned int key_len, | ||
81 | unsigned int expanded_key_len); | ||
82 | |||
83 | static 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 | |||
92 | extern void aes_sparc64_load_encrypt_keys(u64 *key); | ||
93 | extern void aes_sparc64_load_decrypt_keys(u64 *key); | ||
94 | |||
95 | #define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1)) | ||
96 | |||
97 | extern void aes_sparc64_ecb_encrypt(u64 *key, const u32 *input, u32 *output, | ||
98 | unsigned int key_len, unsigned int len); | ||
99 | |||
100 | static 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 | |||
128 | extern void aes_sparc64_ecb_decrypt(u64 *ekey, const u32 *input, u32 *output, | ||
129 | unsigned int key_len, unsigned int len); | ||
130 | |||
131 | static 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 | |||
159 | extern void aes_sparc64_cbc_encrypt(u64 *key, const u32 *input, u32 *output, | ||
160 | unsigned int key_len, unsigned int len, | ||
161 | u64 *iv); | ||
162 | |||
163 | static 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 | |||
192 | extern void aes_sparc64_cbc_decrypt(u64 *ekey, unsigned int key_len, | ||
193 | const u32 *input, u32 *output, | ||
194 | unsigned int len, u64 *iv); | ||
195 | |||
196 | static 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 | |||
225 | static 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 | |||
283 | static 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 | |||
297 | static 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 | |||
312 | static void __exit aes_sparc64_mod_fini(void) | ||
313 | { | ||
314 | crypto_unregister_algs(algs, ARRAY_SIZE(algs)); | ||
315 | } | ||
316 | |||
317 | module_init(aes_sparc64_mod_init); | ||
318 | module_exit(aes_sparc64_mod_fini); | ||
319 | |||
320 | MODULE_LICENSE("GPL"); | ||
321 | MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); | ||
322 | |||
323 | MODULE_ALIAS("aes"); | ||