]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Cryptographic API. | |
3 | * | |
c1e26e1e | 4 | * Support for s390 cryptographic instructions. |
1da177e4 | 5 | * |
57127645 | 6 | * Copyright IBM Corp. 2003, 2015 |
86aa9fc2 JG |
7 | * Author(s): Thomas Spatzier |
8 | * Jan Glauber (jan.glauber@de.ibm.com) | |
57127645 | 9 | * Harald Freudenberger (freude@de.ibm.com) |
1da177e4 LT |
10 | * |
11 | * This program is free software; you can redistribute it and/or modify it | |
12 | * under the terms of the GNU General Public License as published by the Free | |
13 | * Software Foundation; either version 2 of the License, or (at your option) | |
14 | * any later version. | |
15 | * | |
16 | */ | |
c1e26e1e JG |
17 | #ifndef _CRYPTO_ARCH_S390_CRYPT_S390_H |
18 | #define _CRYPTO_ARCH_S390_CRYPT_S390_H | |
1da177e4 LT |
19 | |
20 | #include <asm/errno.h> | |
a0616cde | 21 | #include <asm/facility.h> |
1da177e4 | 22 | |
c1e26e1e JG |
23 | #define CRYPT_S390_OP_MASK 0xFF00 |
24 | #define CRYPT_S390_FUNC_MASK 0x00FF | |
1da177e4 | 25 | |
65b75c36 | 26 | #define CRYPT_S390_PRIORITY 300 |
a9e62fad | 27 | #define CRYPT_S390_COMPOSITE_PRIORITY 400 |
65b75c36 | 28 | |
1822bc90 JG |
29 | #define CRYPT_S390_MSA 0x1 |
30 | #define CRYPT_S390_MSA3 0x2 | |
31 | #define CRYPT_S390_MSA4 0x4 | |
57127645 | 32 | #define CRYPT_S390_MSA5 0x8 |
1822bc90 | 33 | |
bccdbdc9 | 34 | /* s390 cryptographic operations */ |
c1e26e1e | 35 | enum crypt_s390_operations { |
57127645 HF |
36 | CRYPT_S390_KM = 0x0100, |
37 | CRYPT_S390_KMC = 0x0200, | |
38 | CRYPT_S390_KIMD = 0x0300, | |
39 | CRYPT_S390_KLMD = 0x0400, | |
40 | CRYPT_S390_KMAC = 0x0500, | |
41 | CRYPT_S390_KMCTR = 0x0600, | |
42 | CRYPT_S390_PPNO = 0x0700 | |
1da177e4 LT |
43 | }; |
44 | ||
86aa9fc2 JG |
45 | /* |
46 | * function codes for KM (CIPHER MESSAGE) instruction | |
c1e26e1e JG |
47 | * 0x80 is the decipher modifier bit |
48 | */ | |
49 | enum crypt_s390_km_func { | |
bf754ae8 JG |
50 | KM_QUERY = CRYPT_S390_KM | 0x0, |
51 | KM_DEA_ENCRYPT = CRYPT_S390_KM | 0x1, | |
52 | KM_DEA_DECRYPT = CRYPT_S390_KM | 0x1 | 0x80, | |
53 | KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2, | |
54 | KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80, | |
55 | KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3, | |
56 | KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80, | |
57 | KM_AES_128_ENCRYPT = CRYPT_S390_KM | 0x12, | |
58 | KM_AES_128_DECRYPT = CRYPT_S390_KM | 0x12 | 0x80, | |
59 | KM_AES_192_ENCRYPT = CRYPT_S390_KM | 0x13, | |
60 | KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80, | |
61 | KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14, | |
62 | KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80, | |
99d97222 GS |
63 | KM_XTS_128_ENCRYPT = CRYPT_S390_KM | 0x32, |
64 | KM_XTS_128_DECRYPT = CRYPT_S390_KM | 0x32 | 0x80, | |
65 | KM_XTS_256_ENCRYPT = CRYPT_S390_KM | 0x34, | |
66 | KM_XTS_256_DECRYPT = CRYPT_S390_KM | 0x34 | 0x80, | |
1da177e4 LT |
67 | }; |
68 | ||
86aa9fc2 JG |
69 | /* |
70 | * function codes for KMC (CIPHER MESSAGE WITH CHAINING) | |
c1e26e1e JG |
71 | * instruction |
72 | */ | |
73 | enum crypt_s390_kmc_func { | |
bf754ae8 JG |
74 | KMC_QUERY = CRYPT_S390_KMC | 0x0, |
75 | KMC_DEA_ENCRYPT = CRYPT_S390_KMC | 0x1, | |
76 | KMC_DEA_DECRYPT = CRYPT_S390_KMC | 0x1 | 0x80, | |
77 | KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2, | |
78 | KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80, | |
79 | KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3, | |
80 | KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80, | |
81 | KMC_AES_128_ENCRYPT = CRYPT_S390_KMC | 0x12, | |
82 | KMC_AES_128_DECRYPT = CRYPT_S390_KMC | 0x12 | 0x80, | |
83 | KMC_AES_192_ENCRYPT = CRYPT_S390_KMC | 0x13, | |
84 | KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80, | |
85 | KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14, | |
86 | KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80, | |
1b278294 | 87 | KMC_PRNG = CRYPT_S390_KMC | 0x43, |
1da177e4 LT |
88 | }; |
89 | ||
0200f3ec GS |
90 | /* |
91 | * function codes for KMCTR (CIPHER MESSAGE WITH COUNTER) | |
92 | * instruction | |
93 | */ | |
94 | enum crypt_s390_kmctr_func { | |
95 | KMCTR_QUERY = CRYPT_S390_KMCTR | 0x0, | |
96 | KMCTR_DEA_ENCRYPT = CRYPT_S390_KMCTR | 0x1, | |
97 | KMCTR_DEA_DECRYPT = CRYPT_S390_KMCTR | 0x1 | 0x80, | |
98 | KMCTR_TDEA_128_ENCRYPT = CRYPT_S390_KMCTR | 0x2, | |
99 | KMCTR_TDEA_128_DECRYPT = CRYPT_S390_KMCTR | 0x2 | 0x80, | |
100 | KMCTR_TDEA_192_ENCRYPT = CRYPT_S390_KMCTR | 0x3, | |
101 | KMCTR_TDEA_192_DECRYPT = CRYPT_S390_KMCTR | 0x3 | 0x80, | |
102 | KMCTR_AES_128_ENCRYPT = CRYPT_S390_KMCTR | 0x12, | |
103 | KMCTR_AES_128_DECRYPT = CRYPT_S390_KMCTR | 0x12 | 0x80, | |
104 | KMCTR_AES_192_ENCRYPT = CRYPT_S390_KMCTR | 0x13, | |
105 | KMCTR_AES_192_DECRYPT = CRYPT_S390_KMCTR | 0x13 | 0x80, | |
106 | KMCTR_AES_256_ENCRYPT = CRYPT_S390_KMCTR | 0x14, | |
107 | KMCTR_AES_256_DECRYPT = CRYPT_S390_KMCTR | 0x14 | 0x80, | |
108 | }; | |
109 | ||
86aa9fc2 JG |
110 | /* |
111 | * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) | |
c1e26e1e JG |
112 | * instruction |
113 | */ | |
114 | enum crypt_s390_kimd_func { | |
115 | KIMD_QUERY = CRYPT_S390_KIMD | 0, | |
116 | KIMD_SHA_1 = CRYPT_S390_KIMD | 1, | |
0a497c17 | 117 | KIMD_SHA_256 = CRYPT_S390_KIMD | 2, |
291dc7c0 | 118 | KIMD_SHA_512 = CRYPT_S390_KIMD | 3, |
df1309ce | 119 | KIMD_GHASH = CRYPT_S390_KIMD | 65, |
1da177e4 LT |
120 | }; |
121 | ||
86aa9fc2 JG |
122 | /* |
123 | * function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) | |
c1e26e1e JG |
124 | * instruction |
125 | */ | |
126 | enum crypt_s390_klmd_func { | |
127 | KLMD_QUERY = CRYPT_S390_KLMD | 0, | |
128 | KLMD_SHA_1 = CRYPT_S390_KLMD | 1, | |
0a497c17 | 129 | KLMD_SHA_256 = CRYPT_S390_KLMD | 2, |
291dc7c0 | 130 | KLMD_SHA_512 = CRYPT_S390_KLMD | 3, |
1da177e4 LT |
131 | }; |
132 | ||
86aa9fc2 JG |
133 | /* |
134 | * function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) | |
c1e26e1e JG |
135 | * instruction |
136 | */ | |
137 | enum crypt_s390_kmac_func { | |
138 | KMAC_QUERY = CRYPT_S390_KMAC | 0, | |
139 | KMAC_DEA = CRYPT_S390_KMAC | 1, | |
140 | KMAC_TDEA_128 = CRYPT_S390_KMAC | 2, | |
141 | KMAC_TDEA_192 = CRYPT_S390_KMAC | 3 | |
1da177e4 LT |
142 | }; |
143 | ||
57127645 HF |
144 | /* |
145 | * function codes for PPNO (PERFORM PSEUDORANDOM NUMBER | |
146 | * OPERATION) instruction | |
147 | */ | |
148 | enum crypt_s390_ppno_func { | |
149 | PPNO_QUERY = CRYPT_S390_PPNO | 0, | |
150 | PPNO_SHA512_DRNG_GEN = CRYPT_S390_PPNO | 3, | |
151 | PPNO_SHA512_DRNG_SEED = CRYPT_S390_PPNO | 0x83 | |
152 | }; | |
153 | ||
86aa9fc2 JG |
154 | /** |
155 | * crypt_s390_km: | |
156 | * @func: the function code passed to KM; see crypt_s390_km_func | |
157 | * @param: address of parameter block; see POP for details on each func | |
158 | * @dest: address of destination memory area | |
159 | * @src: address of source memory area | |
160 | * @src_len: length of src operand in bytes | |
161 | * | |
c1e26e1e | 162 | * Executes the KM (CIPHER MESSAGE) operation of the CPU. |
86aa9fc2 JG |
163 | * |
164 | * Returns -1 for failure, 0 for the query func, number of processed | |
165 | * bytes for encryption/decryption funcs | |
1da177e4 | 166 | */ |
86aa9fc2 JG |
167 | static inline int crypt_s390_km(long func, void *param, |
168 | u8 *dest, const u8 *src, long src_len) | |
1da177e4 | 169 | { |
c1e26e1e | 170 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; |
86aa9fc2 JG |
171 | register void *__param asm("1") = param; |
172 | register const u8 *__src asm("2") = src; | |
1da177e4 | 173 | register long __src_len asm("3") = src_len; |
86aa9fc2 | 174 | register u8 *__dest asm("4") = dest; |
1da177e4 LT |
175 | int ret; |
176 | ||
94c12cc7 | 177 | asm volatile( |
57127645 HF |
178 | "0: .insn rre,0xb92e0000,%3,%1\n" /* KM opcode */ |
179 | "1: brc 1,0b\n" /* handle partial completion */ | |
86aa9fc2 JG |
180 | " la %0,0\n" |
181 | "2:\n" | |
57127645 | 182 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
94c12cc7 | 183 | : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) |
86aa9fc2 | 184 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
94c12cc7 MS |
185 | if (ret < 0) |
186 | return ret; | |
187 | return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; | |
1da177e4 LT |
188 | } |
189 | ||
86aa9fc2 JG |
190 | /** |
191 | * crypt_s390_kmc: | |
192 | * @func: the function code passed to KM; see crypt_s390_kmc_func | |
193 | * @param: address of parameter block; see POP for details on each func | |
194 | * @dest: address of destination memory area | |
195 | * @src: address of source memory area | |
196 | * @src_len: length of src operand in bytes | |
197 | * | |
c1e26e1e | 198 | * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU. |
86aa9fc2 JG |
199 | * |
200 | * Returns -1 for failure, 0 for the query func, number of processed | |
201 | * bytes for encryption/decryption funcs | |
1da177e4 | 202 | */ |
86aa9fc2 JG |
203 | static inline int crypt_s390_kmc(long func, void *param, |
204 | u8 *dest, const u8 *src, long src_len) | |
1da177e4 | 205 | { |
c1e26e1e | 206 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; |
86aa9fc2 JG |
207 | register void *__param asm("1") = param; |
208 | register const u8 *__src asm("2") = src; | |
1da177e4 | 209 | register long __src_len asm("3") = src_len; |
86aa9fc2 | 210 | register u8 *__dest asm("4") = dest; |
1da177e4 LT |
211 | int ret; |
212 | ||
94c12cc7 | 213 | asm volatile( |
57127645 HF |
214 | "0: .insn rre,0xb92f0000,%3,%1\n" /* KMC opcode */ |
215 | "1: brc 1,0b\n" /* handle partial completion */ | |
86aa9fc2 JG |
216 | " la %0,0\n" |
217 | "2:\n" | |
57127645 | 218 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
94c12cc7 | 219 | : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) |
86aa9fc2 | 220 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
94c12cc7 MS |
221 | if (ret < 0) |
222 | return ret; | |
223 | return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; | |
1da177e4 LT |
224 | } |
225 | ||
86aa9fc2 JG |
226 | /** |
227 | * crypt_s390_kimd: | |
228 | * @func: the function code passed to KM; see crypt_s390_kimd_func | |
229 | * @param: address of parameter block; see POP for details on each func | |
230 | * @src: address of source memory area | |
231 | * @src_len: length of src operand in bytes | |
232 | * | |
1da177e4 | 233 | * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation |
c1e26e1e | 234 | * of the CPU. |
86aa9fc2 JG |
235 | * |
236 | * Returns -1 for failure, 0 for the query func, number of processed | |
237 | * bytes for digest funcs | |
1da177e4 | 238 | */ |
86aa9fc2 JG |
239 | static inline int crypt_s390_kimd(long func, void *param, |
240 | const u8 *src, long src_len) | |
1da177e4 | 241 | { |
c1e26e1e | 242 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; |
86aa9fc2 JG |
243 | register void *__param asm("1") = param; |
244 | register const u8 *__src asm("2") = src; | |
1da177e4 LT |
245 | register long __src_len asm("3") = src_len; |
246 | int ret; | |
247 | ||
94c12cc7 | 248 | asm volatile( |
57127645 HF |
249 | "0: .insn rre,0xb93e0000,%1,%1\n" /* KIMD opcode */ |
250 | "1: brc 1,0b\n" /* handle partial completion */ | |
86aa9fc2 JG |
251 | " la %0,0\n" |
252 | "2:\n" | |
57127645 | 253 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
94c12cc7 | 254 | : "=d" (ret), "+a" (__src), "+d" (__src_len) |
86aa9fc2 | 255 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
94c12cc7 MS |
256 | if (ret < 0) |
257 | return ret; | |
258 | return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; | |
1da177e4 LT |
259 | } |
260 | ||
86aa9fc2 JG |
261 | /** |
262 | * crypt_s390_klmd: | |
263 | * @func: the function code passed to KM; see crypt_s390_klmd_func | |
264 | * @param: address of parameter block; see POP for details on each func | |
265 | * @src: address of source memory area | |
266 | * @src_len: length of src operand in bytes | |
267 | * | |
c1e26e1e | 268 | * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU. |
86aa9fc2 JG |
269 | * |
270 | * Returns -1 for failure, 0 for the query func, number of processed | |
271 | * bytes for digest funcs | |
1da177e4 | 272 | */ |
86aa9fc2 JG |
273 | static inline int crypt_s390_klmd(long func, void *param, |
274 | const u8 *src, long src_len) | |
1da177e4 | 275 | { |
c1e26e1e | 276 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; |
86aa9fc2 JG |
277 | register void *__param asm("1") = param; |
278 | register const u8 *__src asm("2") = src; | |
1da177e4 LT |
279 | register long __src_len asm("3") = src_len; |
280 | int ret; | |
281 | ||
94c12cc7 | 282 | asm volatile( |
57127645 HF |
283 | "0: .insn rre,0xb93f0000,%1,%1\n" /* KLMD opcode */ |
284 | "1: brc 1,0b\n" /* handle partial completion */ | |
86aa9fc2 JG |
285 | " la %0,0\n" |
286 | "2:\n" | |
57127645 | 287 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
94c12cc7 | 288 | : "=d" (ret), "+a" (__src), "+d" (__src_len) |
86aa9fc2 | 289 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
94c12cc7 MS |
290 | if (ret < 0) |
291 | return ret; | |
292 | return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; | |
1da177e4 LT |
293 | } |
294 | ||
86aa9fc2 JG |
295 | /** |
296 | * crypt_s390_kmac: | |
297 | * @func: the function code passed to KM; see crypt_s390_klmd_func | |
298 | * @param: address of parameter block; see POP for details on each func | |
299 | * @src: address of source memory area | |
300 | * @src_len: length of src operand in bytes | |
301 | * | |
1da177e4 | 302 | * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation |
c1e26e1e | 303 | * of the CPU. |
86aa9fc2 JG |
304 | * |
305 | * Returns -1 for failure, 0 for the query func, number of processed | |
306 | * bytes for digest funcs | |
1da177e4 | 307 | */ |
86aa9fc2 JG |
308 | static inline int crypt_s390_kmac(long func, void *param, |
309 | const u8 *src, long src_len) | |
1da177e4 | 310 | { |
c1e26e1e | 311 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; |
86aa9fc2 JG |
312 | register void *__param asm("1") = param; |
313 | register const u8 *__src asm("2") = src; | |
1da177e4 LT |
314 | register long __src_len asm("3") = src_len; |
315 | int ret; | |
316 | ||
94c12cc7 | 317 | asm volatile( |
57127645 HF |
318 | "0: .insn rre,0xb91e0000,%1,%1\n" /* KLAC opcode */ |
319 | "1: brc 1,0b\n" /* handle partial completion */ | |
86aa9fc2 JG |
320 | " la %0,0\n" |
321 | "2:\n" | |
57127645 | 322 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
94c12cc7 | 323 | : "=d" (ret), "+a" (__src), "+d" (__src_len) |
86aa9fc2 | 324 | : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory"); |
94c12cc7 MS |
325 | if (ret < 0) |
326 | return ret; | |
327 | return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; | |
1da177e4 LT |
328 | } |
329 | ||
0200f3ec GS |
330 | /** |
331 | * crypt_s390_kmctr: | |
332 | * @func: the function code passed to KMCTR; see crypt_s390_kmctr_func | |
333 | * @param: address of parameter block; see POP for details on each func | |
334 | * @dest: address of destination memory area | |
335 | * @src: address of source memory area | |
336 | * @src_len: length of src operand in bytes | |
337 | * @counter: address of counter value | |
338 | * | |
339 | * Executes the KMCTR (CIPHER MESSAGE WITH COUNTER) operation of the CPU. | |
340 | * | |
341 | * Returns -1 for failure, 0 for the query func, number of processed | |
342 | * bytes for encryption/decryption funcs | |
343 | */ | |
344 | static inline int crypt_s390_kmctr(long func, void *param, u8 *dest, | |
345 | const u8 *src, long src_len, u8 *counter) | |
346 | { | |
347 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; | |
348 | register void *__param asm("1") = param; | |
349 | register const u8 *__src asm("2") = src; | |
350 | register long __src_len asm("3") = src_len; | |
351 | register u8 *__dest asm("4") = dest; | |
352 | register u8 *__ctr asm("6") = counter; | |
353 | int ret = -1; | |
354 | ||
355 | asm volatile( | |
57127645 HF |
356 | "0: .insn rrf,0xb92d0000,%3,%1,%4,0\n" /* KMCTR opcode */ |
357 | "1: brc 1,0b\n" /* handle partial completion */ | |
0200f3ec GS |
358 | " la %0,0\n" |
359 | "2:\n" | |
57127645 | 360 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
0200f3ec GS |
361 | : "+d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest), |
362 | "+a" (__ctr) | |
363 | : "d" (__func), "a" (__param) : "cc", "memory"); | |
364 | if (ret < 0) | |
365 | return ret; | |
366 | return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; | |
367 | } | |
368 | ||
57127645 HF |
369 | /** |
370 | * crypt_s390_ppno: | |
371 | * @func: the function code passed to PPNO; see crypt_s390_ppno_func | |
372 | * @param: address of parameter block; see POP for details on each func | |
373 | * @dest: address of destination memory area | |
374 | * @dest_len: size of destination memory area in bytes | |
375 | * @seed: address of seed data | |
376 | * @seed_len: size of seed data in bytes | |
377 | * | |
378 | * Executes the PPNO (PERFORM PSEUDORANDOM NUMBER OPERATION) | |
379 | * operation of the CPU. | |
380 | * | |
381 | * Returns -1 for failure, 0 for the query func, number of random | |
382 | * bytes stored in dest buffer for generate function | |
383 | */ | |
384 | static inline int crypt_s390_ppno(long func, void *param, | |
385 | u8 *dest, long dest_len, | |
386 | const u8 *seed, long seed_len) | |
387 | { | |
388 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; | |
389 | register void *__param asm("1") = param; /* param block (240 bytes) */ | |
390 | register u8 *__dest asm("2") = dest; /* buf for recv random bytes */ | |
391 | register long __dest_len asm("3") = dest_len; /* requested random bytes */ | |
392 | register const u8 *__seed asm("4") = seed; /* buf with seed data */ | |
393 | register long __seed_len asm("5") = seed_len; /* bytes in seed buf */ | |
394 | int ret = -1; | |
395 | ||
396 | asm volatile ( | |
397 | "0: .insn rre,0xb93c0000,%1,%5\n" /* PPNO opcode */ | |
398 | "1: brc 1,0b\n" /* handle partial completion */ | |
399 | " la %0,0\n" | |
400 | "2:\n" | |
401 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) | |
402 | : "+d" (ret), "+a"(__dest), "+d"(__dest_len) | |
403 | : "d"(__func), "a"(__param), "a"(__seed), "d"(__seed_len) | |
404 | : "cc", "memory"); | |
405 | if (ret < 0) | |
406 | return ret; | |
407 | return (func & CRYPT_S390_FUNC_MASK) ? dest_len - __dest_len : 0; | |
408 | } | |
409 | ||
1da177e4 | 410 | /** |
86aa9fc2 JG |
411 | * crypt_s390_func_available: |
412 | * @func: the function code of the specific function; 0 if op in general | |
413 | * | |
c1e26e1e | 414 | * Tests if a specific crypto function is implemented on the machine. |
86aa9fc2 JG |
415 | * |
416 | * Returns 1 if func available; 0 if func or op in general not available | |
1da177e4 | 417 | */ |
1822bc90 JG |
418 | static inline int crypt_s390_func_available(int func, |
419 | unsigned int facility_mask) | |
1da177e4 | 420 | { |
86aa9fc2 | 421 | unsigned char status[16]; |
1da177e4 LT |
422 | int ret; |
423 | ||
1822bc90 JG |
424 | if (facility_mask & CRYPT_S390_MSA && !test_facility(17)) |
425 | return 0; | |
86cd741b | 426 | if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76)) |
1822bc90 | 427 | return 0; |
86cd741b | 428 | if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77)) |
a72f0dbf | 429 | return 0; |
57127645 HF |
430 | if (facility_mask & CRYPT_S390_MSA5 && !test_facility(57)) |
431 | return 0; | |
432 | ||
86aa9fc2 JG |
433 | switch (func & CRYPT_S390_OP_MASK) { |
434 | case CRYPT_S390_KM: | |
435 | ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); | |
436 | break; | |
437 | case CRYPT_S390_KMC: | |
438 | ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0); | |
439 | break; | |
440 | case CRYPT_S390_KIMD: | |
441 | ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0); | |
442 | break; | |
443 | case CRYPT_S390_KLMD: | |
444 | ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0); | |
445 | break; | |
446 | case CRYPT_S390_KMAC: | |
447 | ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); | |
448 | break; | |
0200f3ec | 449 | case CRYPT_S390_KMCTR: |
57127645 HF |
450 | ret = crypt_s390_kmctr(KMCTR_QUERY, &status, |
451 | NULL, NULL, 0, NULL); | |
452 | break; | |
453 | case CRYPT_S390_PPNO: | |
454 | ret = crypt_s390_ppno(PPNO_QUERY, &status, | |
455 | NULL, 0, NULL, 0); | |
0200f3ec | 456 | break; |
86aa9fc2 JG |
457 | default: |
458 | return 0; | |
1da177e4 | 459 | } |
86aa9fc2 JG |
460 | if (ret < 0) |
461 | return 0; | |
462 | func &= CRYPT_S390_FUNC_MASK; | |
463 | func &= 0x7f; /* mask modifier bit */ | |
464 | return (status[func >> 3] & (0x80 >> (func & 7))) != 0; | |
1da177e4 LT |
465 | } |
466 | ||
99d97222 GS |
467 | /** |
468 | * crypt_s390_pcc: | |
469 | * @func: the function code passed to KM; see crypt_s390_km_func | |
470 | * @param: address of parameter block; see POP for details on each func | |
471 | * | |
472 | * Executes the PCC (PERFORM CRYPTOGRAPHIC COMPUTATION) operation of the CPU. | |
473 | * | |
474 | * Returns -1 for failure, 0 for success. | |
475 | */ | |
476 | static inline int crypt_s390_pcc(long func, void *param) | |
477 | { | |
478 | register long __func asm("0") = func & 0x7f; /* encrypt or decrypt */ | |
479 | register void *__param asm("1") = param; | |
480 | int ret = -1; | |
481 | ||
482 | asm volatile( | |
57127645 HF |
483 | "0: .insn rre,0xb92c0000,0,0\n" /* PCC opcode */ |
484 | "1: brc 1,0b\n" /* handle partial completion */ | |
99d97222 GS |
485 | " la %0,0\n" |
486 | "2:\n" | |
57127645 | 487 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) |
99d97222 GS |
488 | : "+d" (ret) |
489 | : "d" (__func), "a" (__param) : "cc", "memory"); | |
490 | return ret; | |
491 | } | |
492 | ||
86aa9fc2 | 493 | #endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ |