[S390] Inline assembly cleanup.
[linux-2.6.git] / arch / s390 / crypto / crypt_s390.h
1 /*
2  * Cryptographic API.
3  *
4  * Support for s390 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_S390_H
16 #define _CRYPTO_ARCH_S390_CRYPT_S390_H
17
18 #include <asm/errno.h>
19
20 #define CRYPT_S390_OP_MASK 0xFF00
21 #define CRYPT_S390_FUNC_MASK 0x00FF
22
23 #define CRYPT_S390_PRIORITY 300
24 #define CRYPT_S390_COMPOSITE_PRIORITY 400
25
26 /* s930 cryptographic operations */
27 enum crypt_s390_operations {
28         CRYPT_S390_KM   = 0x0100,
29         CRYPT_S390_KMC  = 0x0200,
30         CRYPT_S390_KIMD = 0x0300,
31         CRYPT_S390_KLMD = 0x0400,
32         CRYPT_S390_KMAC = 0x0500
33 };
34
35 /* function codes for KM (CIPHER MESSAGE) instruction
36  * 0x80 is the decipher modifier bit
37  */
38 enum crypt_s390_km_func {
39         KM_QUERY            = CRYPT_S390_KM | 0x0,
40         KM_DEA_ENCRYPT      = CRYPT_S390_KM | 0x1,
41         KM_DEA_DECRYPT      = CRYPT_S390_KM | 0x1 | 0x80,
42         KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2,
43         KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80,
44         KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3,
45         KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80,
46         KM_AES_128_ENCRYPT  = CRYPT_S390_KM | 0x12,
47         KM_AES_128_DECRYPT  = CRYPT_S390_KM | 0x12 | 0x80,
48         KM_AES_192_ENCRYPT  = CRYPT_S390_KM | 0x13,
49         KM_AES_192_DECRYPT  = CRYPT_S390_KM | 0x13 | 0x80,
50         KM_AES_256_ENCRYPT  = CRYPT_S390_KM | 0x14,
51         KM_AES_256_DECRYPT  = CRYPT_S390_KM | 0x14 | 0x80,
52 };
53
54 /* function codes for KMC (CIPHER MESSAGE WITH CHAINING)
55  * instruction
56  */
57 enum crypt_s390_kmc_func {
58         KMC_QUERY            = CRYPT_S390_KMC | 0x0,
59         KMC_DEA_ENCRYPT      = CRYPT_S390_KMC | 0x1,
60         KMC_DEA_DECRYPT      = CRYPT_S390_KMC | 0x1 | 0x80,
61         KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2,
62         KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80,
63         KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3,
64         KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80,
65         KMC_AES_128_ENCRYPT  = CRYPT_S390_KMC | 0x12,
66         KMC_AES_128_DECRYPT  = CRYPT_S390_KMC | 0x12 | 0x80,
67         KMC_AES_192_ENCRYPT  = CRYPT_S390_KMC | 0x13,
68         KMC_AES_192_DECRYPT  = CRYPT_S390_KMC | 0x13 | 0x80,
69         KMC_AES_256_ENCRYPT  = CRYPT_S390_KMC | 0x14,
70         KMC_AES_256_DECRYPT  = CRYPT_S390_KMC | 0x14 | 0x80,
71 };
72
73 /* function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
74  * instruction
75  */
76 enum crypt_s390_kimd_func {
77         KIMD_QUERY   = CRYPT_S390_KIMD | 0,
78         KIMD_SHA_1   = CRYPT_S390_KIMD | 1,
79         KIMD_SHA_256 = CRYPT_S390_KIMD | 2,
80 };
81
82 /* function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
83  * instruction
84  */
85 enum crypt_s390_klmd_func {
86         KLMD_QUERY   = CRYPT_S390_KLMD | 0,
87         KLMD_SHA_1   = CRYPT_S390_KLMD | 1,
88         KLMD_SHA_256 = CRYPT_S390_KLMD | 2,
89 };
90
91 /* function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
92  * instruction
93  */
94 enum crypt_s390_kmac_func {
95         KMAC_QUERY    = CRYPT_S390_KMAC | 0,
96         KMAC_DEA      = CRYPT_S390_KMAC | 1,
97         KMAC_TDEA_128 = CRYPT_S390_KMAC | 2,
98         KMAC_TDEA_192 = CRYPT_S390_KMAC | 3
99 };
100
101 /* status word for s390 crypto instructions' QUERY functions */
102 struct crypt_s390_query_status {
103         u64 high;
104         u64 low;
105 };
106
107 /*
108  * Executes the KM (CIPHER MESSAGE) operation of the CPU.
109  * @param func: the function code passed to KM; see crypt_s390_km_func
110  * @param param: address of parameter block; see POP for details on each func
111  * @param dest: address of destination memory area
112  * @param src: address of source memory area
113  * @param src_len: length of src operand in bytes
114  * @returns < zero for failure, 0 for the query func, number of processed bytes
115  *      for encryption/decryption funcs
116  */
117 static inline int
118 crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
119 {
120         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
121         register void* __param asm("1") = param;
122         register const u8* __src asm("2") = src;
123         register long __src_len asm("3") = src_len;
124         register u8* __dest asm("4") = dest;
125         int ret;
126
127         asm volatile(
128                 "0:     .insn   rre,0xb92e0000,%3,%1 \n" /* KM opcode */
129                 "1:     brc     1,0b \n" /* handle partial completion */
130                 "       ahi     %0,%h7\n"
131                 "2:     ahi     %0,%h8\n"
132                 "3:\n"
133                 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
134                 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
135                 : "d" (__func), "a" (__param), "0" (-EFAULT),
136                   "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
137         if (ret < 0)
138                 return ret;
139         return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
140 }
141
142 /*
143  * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
144  * @param func: the function code passed to KM; see crypt_s390_kmc_func
145  * @param param: address of parameter block; see POP for details on each func
146  * @param dest: address of destination memory area
147  * @param src: address of source memory area
148  * @param src_len: length of src operand in bytes
149  * @returns < zero for failure, 0 for the query func, number of processed bytes
150  *      for encryption/decryption funcs
151  */
152 static inline int
153 crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
154 {
155         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
156         register void* __param asm("1") = param;
157         register const u8* __src asm("2") = src;
158         register long __src_len asm("3") = src_len;
159         register u8* __dest asm("4") = dest;
160         int ret;
161
162         asm volatile(
163                 "0:     .insn   rre,0xb92f0000,%3,%1 \n" /* KMC opcode */
164                 "1:     brc     1,0b \n" /* handle partial completion */
165                 "       ahi     %0,%h7\n"
166                 "2:     ahi     %0,%h8\n"
167                 "3:\n"
168                 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
169                 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
170                 : "d" (__func), "a" (__param), "0" (-EFAULT),
171                   "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
172         if (ret < 0)
173                 return ret;
174         return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
175 }
176
177 /*
178  * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
179  * of the CPU.
180  * @param func: the function code passed to KM; see crypt_s390_kimd_func
181  * @param param: address of parameter block; see POP for details on each func
182  * @param src: address of source memory area
183  * @param src_len: length of src operand in bytes
184  * @returns < zero for failure, 0 for the query func, number of processed bytes
185  *      for digest funcs
186  */
187 static inline int
188 crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
189 {
190         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
191         register void* __param asm("1") = param;
192         register const u8* __src asm("2") = src;
193         register long __src_len asm("3") = src_len;
194         int ret;
195
196         asm volatile(
197                 "0:     .insn   rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */
198                 "1:     brc     1,0b \n" /* handle partial completion */
199                 "       ahi     %0,%h6\n"
200                 "2:     ahi     %0,%h7\n"
201                 "3:\n"
202                 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
203                 : "=d" (ret), "+a" (__src), "+d" (__src_len)
204                 : "d" (__func), "a" (__param), "0" (-EFAULT),
205                   "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
206         if (ret < 0)
207                 return ret;
208         return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
209 }
210
211 /*
212  * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
213  * @param func: the function code passed to KM; see crypt_s390_klmd_func
214  * @param param: address of parameter block; see POP for details on each func
215  * @param src: address of source memory area
216  * @param src_len: length of src operand in bytes
217  * @returns < zero for failure, 0 for the query func, number of processed bytes
218  *      for digest funcs
219  */
220 static inline int
221 crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
222 {
223         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
224         register void* __param asm("1") = param;
225         register const u8* __src asm("2") = src;
226         register long __src_len asm("3") = src_len;
227         int ret;
228
229         asm volatile(
230                 "0:     .insn   rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */
231                 "1:     brc     1,0b \n" /* handle partial completion */
232                 "       ahi     %0,%h6\n"
233                 "2:     ahi     %0,%h7\n"
234                 "3:\n"
235                 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
236                 : "=d" (ret), "+a" (__src), "+d" (__src_len)
237                 : "d" (__func), "a" (__param), "0" (-EFAULT),
238                   "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
239         if (ret < 0)
240                 return ret;
241         return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
242 }
243
244 /*
245  * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
246  * of the CPU.
247  * @param func: the function code passed to KM; see crypt_s390_klmd_func
248  * @param param: address of parameter block; see POP for details on each func
249  * @param src: address of source memory area
250  * @param src_len: length of src operand in bytes
251  * @returns < zero for failure, 0 for the query func, number of processed bytes
252  *      for digest funcs
253  */
254 static inline int
255 crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
256 {
257         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
258         register void* __param asm("1") = param;
259         register const u8* __src asm("2") = src;
260         register long __src_len asm("3") = src_len;
261         int ret;
262
263         asm volatile(
264                 "0:     .insn   rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */
265                 "1:     brc     1,0b \n" /* handle partial completion */
266                 "       ahi     %0,%h6\n"
267                 "2:     ahi     %0,%h7\n"
268                 "3:\n"
269                 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
270                 : "=d" (ret), "+a" (__src), "+d" (__src_len)
271                 : "d" (__func), "a" (__param), "0" (-EFAULT),
272                   "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
273         if (ret < 0)
274                 return ret;
275         return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
276 }
277
278 /**
279  * Tests if a specific crypto function is implemented on the machine.
280  * @param func: the function code of the specific function; 0 if op in general
281  * @return      1 if func available; 0 if func or op in general not available
282  */
283 static inline int
284 crypt_s390_func_available(int func)
285 {
286         int ret;
287
288         struct crypt_s390_query_status status = {
289                 .high = 0,
290                 .low = 0
291         };
292         switch (func & CRYPT_S390_OP_MASK){
293                 case CRYPT_S390_KM:
294                         ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
295                         break;
296                 case CRYPT_S390_KMC:
297                         ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
298                         break;
299                 case CRYPT_S390_KIMD:
300                         ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
301                         break;
302                 case CRYPT_S390_KLMD:
303                         ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
304                         break;
305                 case CRYPT_S390_KMAC:
306                         ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
307                         break;
308                 default:
309                         ret = 0;
310                         return ret;
311         }
312         if (ret >= 0){
313                 func &= CRYPT_S390_FUNC_MASK;
314                 func &= 0x7f; //mask modifier bit
315                 if (func < 64){
316                         ret = (status.high >> (64 - func - 1)) & 0x1;
317                 } else {
318                         ret = (status.low >> (128 - func - 1)) & 0x1;
319                 }
320         } else {
321                 ret = 0;
322         }
323         return ret;
324 }
325
326 #endif // _CRYPTO_ARCH_S390_CRYPT_S390_H