diff options
Diffstat (limited to 'arch/s390/crypto/crypt_z990.h')
-rw-r--r-- | arch/s390/crypto/crypt_z990.h | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/arch/s390/crypto/crypt_z990.h b/arch/s390/crypto/crypt_z990.h new file mode 100644 index 000000000000..4df660b99e5a --- /dev/null +++ b/arch/s390/crypto/crypt_z990.h | |||
@@ -0,0 +1,374 @@ | |||
1 | /* | ||
2 | * Cryptographic API. | ||
3 | * | ||
4 | * Support for z990 cryptographic instructions. | ||
5 | * | ||
6 | * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation | ||
7 | * Author(s): Thomas Spatzier (tspat@de.ibm.com) | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
12 | * any later version. | ||
13 | * | ||
14 | */ | ||
15 | #ifndef _CRYPTO_ARCH_S390_CRYPT_Z990_H | ||
16 | #define _CRYPTO_ARCH_S390_CRYPT_Z990_H | ||
17 | |||
18 | #include <asm/errno.h> | ||
19 | |||
20 | #define CRYPT_Z990_OP_MASK 0xFF00 | ||
21 | #define CRYPT_Z990_FUNC_MASK 0x00FF | ||
22 | |||
23 | |||
24 | /*z990 cryptographic operations*/ | ||
25 | enum crypt_z990_operations { | ||
26 | CRYPT_Z990_KM = 0x0100, | ||
27 | CRYPT_Z990_KMC = 0x0200, | ||
28 | CRYPT_Z990_KIMD = 0x0300, | ||
29 | CRYPT_Z990_KLMD = 0x0400, | ||
30 | CRYPT_Z990_KMAC = 0x0500 | ||
31 | }; | ||
32 | |||
33 | /*function codes for KM (CIPHER MESSAGE) instruction*/ | ||
34 | enum crypt_z990_km_func { | ||
35 | KM_QUERY = CRYPT_Z990_KM | 0, | ||
36 | KM_DEA_ENCRYPT = CRYPT_Z990_KM | 1, | ||
37 | KM_DEA_DECRYPT = CRYPT_Z990_KM | 1 | 0x80, //modifier bit->decipher | ||
38 | KM_TDEA_128_ENCRYPT = CRYPT_Z990_KM | 2, | ||
39 | KM_TDEA_128_DECRYPT = CRYPT_Z990_KM | 2 | 0x80, | ||
40 | KM_TDEA_192_ENCRYPT = CRYPT_Z990_KM | 3, | ||
41 | KM_TDEA_192_DECRYPT = CRYPT_Z990_KM | 3 | 0x80, | ||
42 | }; | ||
43 | |||
44 | /*function codes for KMC (CIPHER MESSAGE WITH CHAINING) instruction*/ | ||
45 | enum crypt_z990_kmc_func { | ||
46 | KMC_QUERY = CRYPT_Z990_KMC | 0, | ||
47 | KMC_DEA_ENCRYPT = CRYPT_Z990_KMC | 1, | ||
48 | KMC_DEA_DECRYPT = CRYPT_Z990_KMC | 1 | 0x80, //modifier bit->decipher | ||
49 | KMC_TDEA_128_ENCRYPT = CRYPT_Z990_KMC | 2, | ||
50 | KMC_TDEA_128_DECRYPT = CRYPT_Z990_KMC | 2 | 0x80, | ||
51 | KMC_TDEA_192_ENCRYPT = CRYPT_Z990_KMC | 3, | ||
52 | KMC_TDEA_192_DECRYPT = CRYPT_Z990_KMC | 3 | 0x80, | ||
53 | }; | ||
54 | |||
55 | /*function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) instruction*/ | ||
56 | enum crypt_z990_kimd_func { | ||
57 | KIMD_QUERY = CRYPT_Z990_KIMD | 0, | ||
58 | KIMD_SHA_1 = CRYPT_Z990_KIMD | 1, | ||
59 | }; | ||
60 | |||
61 | /*function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) instruction*/ | ||
62 | enum crypt_z990_klmd_func { | ||
63 | KLMD_QUERY = CRYPT_Z990_KLMD | 0, | ||
64 | KLMD_SHA_1 = CRYPT_Z990_KLMD | 1, | ||
65 | }; | ||
66 | |||
67 | /*function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) instruction*/ | ||
68 | enum crypt_z990_kmac_func { | ||
69 | KMAC_QUERY = CRYPT_Z990_KMAC | 0, | ||
70 | KMAC_DEA = CRYPT_Z990_KMAC | 1, | ||
71 | KMAC_TDEA_128 = CRYPT_Z990_KMAC | 2, | ||
72 | KMAC_TDEA_192 = CRYPT_Z990_KMAC | 3 | ||
73 | }; | ||
74 | |||
75 | /*status word for z990 crypto instructions' QUERY functions*/ | ||
76 | struct crypt_z990_query_status { | ||
77 | u64 high; | ||
78 | u64 low; | ||
79 | }; | ||
80 | |||
81 | /* | ||
82 | * Standard fixup and ex_table sections for crypt_z990 inline functions. | ||
83 | * label 0: the z990 crypto operation | ||
84 | * label 1: just after 1 to catch illegal operation exception on non-z990 | ||
85 | * label 6: the return point after fixup | ||
86 | * label 7: set error value if exception _in_ crypto operation | ||
87 | * label 8: set error value if illegal operation exception | ||
88 | * [ret] is the variable to receive the error code | ||
89 | * [ERR] is the error code value | ||
90 | */ | ||
91 | #ifndef __s390x__ | ||
92 | #define __crypt_z990_fixup \ | ||
93 | ".section .fixup,\"ax\" \n" \ | ||
94 | "7: lhi %0,%h[e1] \n" \ | ||
95 | " bras 1,9f \n" \ | ||
96 | " .long 6b \n" \ | ||
97 | "8: lhi %0,%h[e2] \n" \ | ||
98 | " bras 1,9f \n" \ | ||
99 | " .long 6b \n" \ | ||
100 | "9: l 1,0(1) \n" \ | ||
101 | " br 1 \n" \ | ||
102 | ".previous \n" \ | ||
103 | ".section __ex_table,\"a\" \n" \ | ||
104 | " .align 4 \n" \ | ||
105 | " .long 0b,7b \n" \ | ||
106 | " .long 1b,8b \n" \ | ||
107 | ".previous" | ||
108 | #else /* __s390x__ */ | ||
109 | #define __crypt_z990_fixup \ | ||
110 | ".section .fixup,\"ax\" \n" \ | ||
111 | "7: lhi %0,%h[e1] \n" \ | ||
112 | " jg 6b \n" \ | ||
113 | "8: lhi %0,%h[e2] \n" \ | ||
114 | " jg 6b \n" \ | ||
115 | ".previous\n" \ | ||
116 | ".section __ex_table,\"a\" \n" \ | ||
117 | " .align 8 \n" \ | ||
118 | " .quad 0b,7b \n" \ | ||
119 | " .quad 1b,8b \n" \ | ||
120 | ".previous" | ||
121 | #endif /* __s390x__ */ | ||
122 | |||
123 | /* | ||
124 | * Standard code for setting the result of z990 crypto instructions. | ||
125 | * %0: the register which will receive the result | ||
126 | * [result]: the register containing the result (e.g. second operand length | ||
127 | * to compute number of processed bytes]. | ||
128 | */ | ||
129 | #ifndef __s390x__ | ||
130 | #define __crypt_z990_set_result \ | ||
131 | " lr %0,%[result] \n" | ||
132 | #else /* __s390x__ */ | ||
133 | #define __crypt_z990_set_result \ | ||
134 | " lgr %0,%[result] \n" | ||
135 | #endif | ||
136 | |||
137 | /* | ||
138 | * Executes the KM (CIPHER MESSAGE) operation of the z990 CPU. | ||
139 | * @param func: the function code passed to KM; see crypt_z990_km_func | ||
140 | * @param param: address of parameter block; see POP for details on each func | ||
141 | * @param dest: address of destination memory area | ||
142 | * @param src: address of source memory area | ||
143 | * @param src_len: length of src operand in bytes | ||
144 | * @returns < zero for failure, 0 for the query func, number of processed bytes | ||
145 | * for encryption/decryption funcs | ||
146 | */ | ||
147 | static inline int | ||
148 | crypt_z990_km(long func, void* param, u8* dest, const u8* src, long src_len) | ||
149 | { | ||
150 | register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; | ||
151 | register void* __param asm("1") = param; | ||
152 | register u8* __dest asm("4") = dest; | ||
153 | register const u8* __src asm("2") = src; | ||
154 | register long __src_len asm("3") = src_len; | ||
155 | int ret; | ||
156 | |||
157 | ret = 0; | ||
158 | __asm__ __volatile__ ( | ||
159 | "0: .insn rre,0xB92E0000,%1,%2 \n" //KM opcode | ||
160 | "1: brc 1,0b \n" //handle partial completion | ||
161 | __crypt_z990_set_result | ||
162 | "6: \n" | ||
163 | __crypt_z990_fixup | ||
164 | : "+d" (ret), "+a" (__dest), "+a" (__src), | ||
165 | [result] "+d" (__src_len) | ||
166 | : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), | ||
167 | "a" (__param) | ||
168 | : "cc", "memory" | ||
169 | ); | ||
170 | if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){ | ||
171 | ret = src_len - ret; | ||
172 | } | ||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the z990 CPU. | ||
178 | * @param func: the function code passed to KM; see crypt_z990_kmc_func | ||
179 | * @param param: address of parameter block; see POP for details on each func | ||
180 | * @param dest: address of destination memory area | ||
181 | * @param src: address of source memory area | ||
182 | * @param src_len: length of src operand in bytes | ||
183 | * @returns < zero for failure, 0 for the query func, number of processed bytes | ||
184 | * for encryption/decryption funcs | ||
185 | */ | ||
186 | static inline int | ||
187 | crypt_z990_kmc(long func, void* param, u8* dest, const u8* src, long src_len) | ||
188 | { | ||
189 | register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; | ||
190 | register void* __param asm("1") = param; | ||
191 | register u8* __dest asm("4") = dest; | ||
192 | register const u8* __src asm("2") = src; | ||
193 | register long __src_len asm("3") = src_len; | ||
194 | int ret; | ||
195 | |||
196 | ret = 0; | ||
197 | __asm__ __volatile__ ( | ||
198 | "0: .insn rre,0xB92F0000,%1,%2 \n" //KMC opcode | ||
199 | "1: brc 1,0b \n" //handle partial completion | ||
200 | __crypt_z990_set_result | ||
201 | "6: \n" | ||
202 | __crypt_z990_fixup | ||
203 | : "+d" (ret), "+a" (__dest), "+a" (__src), | ||
204 | [result] "+d" (__src_len) | ||
205 | : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), | ||
206 | "a" (__param) | ||
207 | : "cc", "memory" | ||
208 | ); | ||
209 | if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){ | ||
210 | ret = src_len - ret; | ||
211 | } | ||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | /* | ||
216 | * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation | ||
217 | * of the z990 CPU. | ||
218 | * @param func: the function code passed to KM; see crypt_z990_kimd_func | ||
219 | * @param param: address of parameter block; see POP for details on each func | ||
220 | * @param src: address of source memory area | ||
221 | * @param src_len: length of src operand in bytes | ||
222 | * @returns < zero for failure, 0 for the query func, number of processed bytes | ||
223 | * for digest funcs | ||
224 | */ | ||
225 | static inline int | ||
226 | crypt_z990_kimd(long func, void* param, const u8* src, long src_len) | ||
227 | { | ||
228 | register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; | ||
229 | register void* __param asm("1") = param; | ||
230 | register const u8* __src asm("2") = src; | ||
231 | register long __src_len asm("3") = src_len; | ||
232 | int ret; | ||
233 | |||
234 | ret = 0; | ||
235 | __asm__ __volatile__ ( | ||
236 | "0: .insn rre,0xB93E0000,%1,%1 \n" //KIMD opcode | ||
237 | "1: brc 1,0b \n" /*handle partical completion of kimd*/ | ||
238 | __crypt_z990_set_result | ||
239 | "6: \n" | ||
240 | __crypt_z990_fixup | ||
241 | : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) | ||
242 | : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), | ||
243 | "a" (__param) | ||
244 | : "cc", "memory" | ||
245 | ); | ||
246 | if (ret >= 0 && (func & CRYPT_Z990_FUNC_MASK)){ | ||
247 | ret = src_len - ret; | ||
248 | } | ||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the z990 CPU. | ||
254 | * @param func: the function code passed to KM; see crypt_z990_klmd_func | ||
255 | * @param param: address of parameter block; see POP for details on each func | ||
256 | * @param src: address of source memory area | ||
257 | * @param src_len: length of src operand in bytes | ||
258 | * @returns < zero for failure, 0 for the query func, number of processed bytes | ||
259 | * for digest funcs | ||
260 | */ | ||
261 | static inline int | ||
262 | crypt_z990_klmd(long func, void* param, const u8* src, long src_len) | ||
263 | { | ||
264 | register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; | ||
265 | register void* __param asm("1") = param; | ||
266 | register const u8* __src asm("2") = src; | ||
267 | register long __src_len asm("3") = src_len; | ||
268 | int ret; | ||
269 | |||
270 | ret = 0; | ||
271 | __asm__ __volatile__ ( | ||
272 | "0: .insn rre,0xB93F0000,%1,%1 \n" //KLMD opcode | ||
273 | "1: brc 1,0b \n" /*handle partical completion of klmd*/ | ||
274 | __crypt_z990_set_result | ||
275 | "6: \n" | ||
276 | __crypt_z990_fixup | ||
277 | : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) | ||
278 | : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), | ||
279 | "a" (__param) | ||
280 | : "cc", "memory" | ||
281 | ); | ||
282 | if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){ | ||
283 | ret = src_len - ret; | ||
284 | } | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation | ||
290 | * of the z990 CPU. | ||
291 | * @param func: the function code passed to KM; see crypt_z990_klmd_func | ||
292 | * @param param: address of parameter block; see POP for details on each func | ||
293 | * @param src: address of source memory area | ||
294 | * @param src_len: length of src operand in bytes | ||
295 | * @returns < zero for failure, 0 for the query func, number of processed bytes | ||
296 | * for digest funcs | ||
297 | */ | ||
298 | static inline int | ||
299 | crypt_z990_kmac(long func, void* param, const u8* src, long src_len) | ||
300 | { | ||
301 | register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; | ||
302 | register void* __param asm("1") = param; | ||
303 | register const u8* __src asm("2") = src; | ||
304 | register long __src_len asm("3") = src_len; | ||
305 | int ret; | ||
306 | |||
307 | ret = 0; | ||
308 | __asm__ __volatile__ ( | ||
309 | "0: .insn rre,0xB91E0000,%5,%5 \n" //KMAC opcode | ||
310 | "1: brc 1,0b \n" /*handle partical completion of klmd*/ | ||
311 | __crypt_z990_set_result | ||
312 | "6: \n" | ||
313 | __crypt_z990_fixup | ||
314 | : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) | ||
315 | : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), | ||
316 | "a" (__param) | ||
317 | : "cc", "memory" | ||
318 | ); | ||
319 | if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){ | ||
320 | ret = src_len - ret; | ||
321 | } | ||
322 | return ret; | ||
323 | } | ||
324 | |||
325 | /** | ||
326 | * Tests if a specific z990 crypto function is implemented on the machine. | ||
327 | * @param func: the function code of the specific function; 0 if op in general | ||
328 | * @return 1 if func available; 0 if func or op in general not available | ||
329 | */ | ||
330 | static inline int | ||
331 | crypt_z990_func_available(int func) | ||
332 | { | ||
333 | int ret; | ||
334 | |||
335 | struct crypt_z990_query_status status = { | ||
336 | .high = 0, | ||
337 | .low = 0 | ||
338 | }; | ||
339 | switch (func & CRYPT_Z990_OP_MASK){ | ||
340 | case CRYPT_Z990_KM: | ||
341 | ret = crypt_z990_km(KM_QUERY, &status, NULL, NULL, 0); | ||
342 | break; | ||
343 | case CRYPT_Z990_KMC: | ||
344 | ret = crypt_z990_kmc(KMC_QUERY, &status, NULL, NULL, 0); | ||
345 | break; | ||
346 | case CRYPT_Z990_KIMD: | ||
347 | ret = crypt_z990_kimd(KIMD_QUERY, &status, NULL, 0); | ||
348 | break; | ||
349 | case CRYPT_Z990_KLMD: | ||
350 | ret = crypt_z990_klmd(KLMD_QUERY, &status, NULL, 0); | ||
351 | break; | ||
352 | case CRYPT_Z990_KMAC: | ||
353 | ret = crypt_z990_kmac(KMAC_QUERY, &status, NULL, 0); | ||
354 | break; | ||
355 | default: | ||
356 | ret = 0; | ||
357 | return ret; | ||
358 | } | ||
359 | if (ret >= 0){ | ||
360 | func &= CRYPT_Z990_FUNC_MASK; | ||
361 | func &= 0x7f; //mask modifier bit | ||
362 | if (func < 64){ | ||
363 | ret = (status.high >> (64 - func - 1)) & 0x1; | ||
364 | } else { | ||
365 | ret = (status.low >> (128 - func - 1)) & 0x1; | ||
366 | } | ||
367 | } else { | ||
368 | ret = 0; | ||
369 | } | ||
370 | return ret; | ||
371 | } | ||
372 | |||
373 | |||
374 | #endif // _CRYPTO_ARCH_S390_CRYPT_Z990_H | ||