efd836c2e4a6cf0726a55dcad3c77bdca40a202f
[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  * Standard fixup and ex_table sections for crypt_s390 inline functions.
109  * label 0: the s390 crypto operation
110  * label 1: just after 1 to catch illegal operation exception
111  *          (unsupported model)
112  * label 6: the return point after fixup
113  * label 7: set error value if exception _in_ crypto operation
114  * label 8: set error value if illegal operation exception
115  * [ret] is the variable to receive the error code
116  * [ERR] is the error code value
117  */
118 #ifndef CONFIG_64BIT
119 #define __crypt_s390_fixup \
120         ".section .fixup,\"ax\" \n"     \
121         "7:     lhi     %0,%h[e1] \n"   \
122         "       bras    1,9f \n"        \
123         "       .long   6b \n"          \
124         "8:     lhi     %0,%h[e2] \n"   \
125         "       bras    1,9f \n"        \
126         "       .long   6b \n"          \
127         "9:     l       1,0(1) \n"      \
128         "       br      1 \n"           \
129         ".previous \n"                  \
130         ".section __ex_table,\"a\" \n"  \
131         "       .align  4 \n"           \
132         "       .long   0b,7b \n"       \
133         "       .long   1b,8b \n"       \
134         ".previous"
135 #else /* CONFIG_64BIT */
136 #define __crypt_s390_fixup \
137         ".section .fixup,\"ax\" \n"     \
138         "7:     lhi     %0,%h[e1] \n"   \
139         "       jg      6b \n"          \
140         "8:     lhi     %0,%h[e2] \n"   \
141         "       jg      6b \n"          \
142         ".previous\n"                   \
143         ".section __ex_table,\"a\" \n"  \
144         "       .align  8 \n"           \
145         "       .quad   0b,7b \n"       \
146         "       .quad   1b,8b \n"       \
147         ".previous"
148 #endif /* CONFIG_64BIT */
149
150 /*
151  * Standard code for setting the result of s390 crypto instructions.
152  * %0: the register which will receive the result
153  * [result]: the register containing the result (e.g. second operand length
154  * to compute number of processed bytes].
155  */
156 #ifndef CONFIG_64BIT
157 #define __crypt_s390_set_result \
158         "       lr      %0,%[result] \n"
159 #else /* CONFIG_64BIT */
160 #define __crypt_s390_set_result \
161         "       lgr     %0,%[result] \n"
162 #endif
163
164 /*
165  * Executes the KM (CIPHER MESSAGE) operation of the CPU.
166  * @param func: the function code passed to KM; see crypt_s390_km_func
167  * @param param: address of parameter block; see POP for details on each func
168  * @param dest: address of destination memory area
169  * @param src: address of source memory area
170  * @param src_len: length of src operand in bytes
171  * @returns < zero for failure, 0 for the query func, number of processed bytes
172  *      for encryption/decryption funcs
173  */
174 static inline int
175 crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
176 {
177         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
178         register void* __param asm("1") = param;
179         register u8* __dest asm("4") = dest;
180         register const u8* __src asm("2") = src;
181         register long __src_len asm("3") = src_len;
182         int ret;
183
184         ret = 0;
185         __asm__ __volatile__ (
186                 "0:     .insn   rre,0xB92E0000,%1,%2 \n" /* KM opcode */
187                 "1:     brc     1,0b \n" /* handle partial completion */
188                 __crypt_s390_set_result
189                 "6:     \n"
190                 __crypt_s390_fixup
191                 : "+d" (ret), "+a" (__dest), "+a" (__src),
192                   [result] "+d" (__src_len)
193                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
194                   "a" (__param)
195                 : "cc", "memory"
196         );
197         if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
198                 ret = src_len - ret;
199         }
200         return ret;
201 }
202
203 /*
204  * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
205  * @param func: the function code passed to KM; see crypt_s390_kmc_func
206  * @param param: address of parameter block; see POP for details on each func
207  * @param dest: address of destination memory area
208  * @param src: address of source memory area
209  * @param src_len: length of src operand in bytes
210  * @returns < zero for failure, 0 for the query func, number of processed bytes
211  *      for encryption/decryption funcs
212  */
213 static inline int
214 crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
215 {
216         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
217         register void* __param asm("1") = param;
218         register u8* __dest asm("4") = dest;
219         register const u8* __src asm("2") = src;
220         register long __src_len asm("3") = src_len;
221         int ret;
222
223         ret = 0;
224         __asm__ __volatile__ (
225                 "0:     .insn   rre,0xB92F0000,%1,%2 \n" /* KMC opcode */
226                 "1:     brc     1,0b \n" /* handle partial completion */
227                 __crypt_s390_set_result
228                 "6:     \n"
229                 __crypt_s390_fixup
230                 : "+d" (ret), "+a" (__dest), "+a" (__src),
231                   [result] "+d" (__src_len)
232                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
233                   "a" (__param)
234                 : "cc", "memory"
235         );
236         if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
237                 ret = src_len - ret;
238         }
239         return ret;
240 }
241
242 /*
243  * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
244  * of the CPU.
245  * @param func: the function code passed to KM; see crypt_s390_kimd_func
246  * @param param: address of parameter block; see POP for details on each func
247  * @param src: address of source memory area
248  * @param src_len: length of src operand in bytes
249  * @returns < zero for failure, 0 for the query func, number of processed bytes
250  *      for digest funcs
251  */
252 static inline int
253 crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
254 {
255         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
256         register void* __param asm("1") = param;
257         register const u8* __src asm("2") = src;
258         register long __src_len asm("3") = src_len;
259         int ret;
260
261         ret = 0;
262         __asm__ __volatile__ (
263                 "0:     .insn   rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */
264                 "1:     brc     1,0b \n" /* handle partical completion */
265                 __crypt_s390_set_result
266                 "6:     \n"
267                 __crypt_s390_fixup
268                 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
269                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
270                   "a" (__param)
271                 : "cc", "memory"
272         );
273         if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){
274                 ret = src_len - ret;
275         }
276         return ret;
277 }
278
279 /*
280  * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
281  * @param func: the function code passed to KM; see crypt_s390_klmd_func
282  * @param param: address of parameter block; see POP for details on each func
283  * @param src: address of source memory area
284  * @param src_len: length of src operand in bytes
285  * @returns < zero for failure, 0 for the query func, number of processed bytes
286  *      for digest funcs
287  */
288 static inline int
289 crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
290 {
291         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
292         register void* __param asm("1") = param;
293         register const u8* __src asm("2") = src;
294         register long __src_len asm("3") = src_len;
295         int ret;
296
297         ret = 0;
298         __asm__ __volatile__ (
299                 "0:     .insn   rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */
300                 "1:     brc     1,0b \n" /* handle partical completion */
301                 __crypt_s390_set_result
302                 "6:     \n"
303                 __crypt_s390_fixup
304                 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
305                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
306                   "a" (__param)
307                 : "cc", "memory"
308         );
309         if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
310                 ret = src_len - ret;
311         }
312         return ret;
313 }
314
315 /*
316  * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
317  * of the CPU.
318  * @param func: the function code passed to KM; see crypt_s390_klmd_func
319  * @param param: address of parameter block; see POP for details on each func
320  * @param src: address of source memory area
321  * @param src_len: length of src operand in bytes
322  * @returns < zero for failure, 0 for the query func, number of processed bytes
323  *      for digest funcs
324  */
325 static inline int
326 crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
327 {
328         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
329         register void* __param asm("1") = param;
330         register const u8* __src asm("2") = src;
331         register long __src_len asm("3") = src_len;
332         int ret;
333
334         ret = 0;
335         __asm__ __volatile__ (
336                 "0:     .insn   rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */
337                 "1:     brc     1,0b \n" /* handle partical completion */
338                 __crypt_s390_set_result
339                 "6:     \n"
340                 __crypt_s390_fixup
341                 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
342                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
343                   "a" (__param)
344                 : "cc", "memory"
345         );
346         if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
347                 ret = src_len - ret;
348         }
349         return ret;
350 }
351
352 /**
353  * Tests if a specific crypto function is implemented on the machine.
354  * @param func: the function code of the specific function; 0 if op in general
355  * @return      1 if func available; 0 if func or op in general not available
356  */
357 static inline int
358 crypt_s390_func_available(int func)
359 {
360         int ret;
361
362         struct crypt_s390_query_status status = {
363                 .high = 0,
364                 .low = 0
365         };
366         switch (func & CRYPT_S390_OP_MASK){
367                 case CRYPT_S390_KM:
368                         ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
369                         break;
370                 case CRYPT_S390_KMC:
371                         ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
372                         break;
373                 case CRYPT_S390_KIMD:
374                         ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
375                         break;
376                 case CRYPT_S390_KLMD:
377                         ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
378                         break;
379                 case CRYPT_S390_KMAC:
380                         ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
381                         break;
382                 default:
383                         ret = 0;
384                         return ret;
385         }
386         if (ret >= 0){
387                 func &= CRYPT_S390_FUNC_MASK;
388                 func &= 0x7f; //mask modifier bit
389                 if (func < 64){
390                         ret = (status.high >> (64 - func - 1)) & 0x1;
391                 } else {
392                         ret = (status.low >> (128 - func - 1)) & 0x1;
393                 }
394         } else {
395                 ret = 0;
396         }
397         return ret;
398 }
399
400 #endif // _CRYPTO_ARCH_S390_CRYPT_S390_H