]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - arch/s390/crypto/crypt_s390.h
[PATCH] s390: add oprofile callgraph support
[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 /* s930 cryptographic operations */
24 enum crypt_s390_operations {
25         CRYPT_S390_KM   = 0x0100,
26         CRYPT_S390_KMC  = 0x0200,
27         CRYPT_S390_KIMD = 0x0300,
28         CRYPT_S390_KLMD = 0x0400,
29         CRYPT_S390_KMAC = 0x0500
30 };
31
32 /* function codes for KM (CIPHER MESSAGE) instruction
33  * 0x80 is the decipher modifier bit
34  */
35 enum crypt_s390_km_func {
36         KM_QUERY            = CRYPT_S390_KM | 0,
37         KM_DEA_ENCRYPT      = CRYPT_S390_KM | 1,
38         KM_DEA_DECRYPT      = CRYPT_S390_KM | 1 | 0x80,
39         KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 2,
40         KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 2 | 0x80,
41         KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 3,
42         KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 3 | 0x80,
43 };
44
45 /* function codes for KMC (CIPHER MESSAGE WITH CHAINING)
46  * instruction
47  */
48 enum crypt_s390_kmc_func {
49         KMC_QUERY            = CRYPT_S390_KMC | 0,
50         KMC_DEA_ENCRYPT      = CRYPT_S390_KMC | 1,
51         KMC_DEA_DECRYPT      = CRYPT_S390_KMC | 1 | 0x80,
52         KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 2,
53         KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 2 | 0x80,
54         KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 3,
55         KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 3 | 0x80,
56 };
57
58 /* function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
59  * instruction
60  */
61 enum crypt_s390_kimd_func {
62         KIMD_QUERY   = CRYPT_S390_KIMD | 0,
63         KIMD_SHA_1   = CRYPT_S390_KIMD | 1,
64 };
65
66 /* function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
67  * instruction
68  */
69 enum crypt_s390_klmd_func {
70         KLMD_QUERY   = CRYPT_S390_KLMD | 0,
71         KLMD_SHA_1   = CRYPT_S390_KLMD | 1,
72 };
73
74 /* function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
75  * instruction
76  */
77 enum crypt_s390_kmac_func {
78         KMAC_QUERY    = CRYPT_S390_KMAC | 0,
79         KMAC_DEA      = CRYPT_S390_KMAC | 1,
80         KMAC_TDEA_128 = CRYPT_S390_KMAC | 2,
81         KMAC_TDEA_192 = CRYPT_S390_KMAC | 3
82 };
83
84 /* status word for s390 crypto instructions' QUERY functions */
85 struct crypt_s390_query_status {
86         u64 high;
87         u64 low;
88 };
89
90 /*
91  * Standard fixup and ex_table sections for crypt_s390 inline functions.
92  * label 0: the s390 crypto operation
93  * label 1: just after 1 to catch illegal operation exception
94  *          (unsupported model)
95  * label 6: the return point after fixup
96  * label 7: set error value if exception _in_ crypto operation
97  * label 8: set error value if illegal operation exception
98  * [ret] is the variable to receive the error code
99  * [ERR] is the error code value
100  */
101 #ifndef __s390x__
102 #define __crypt_s390_fixup \
103         ".section .fixup,\"ax\" \n"     \
104         "7:     lhi     %0,%h[e1] \n"   \
105         "       bras    1,9f \n"        \
106         "       .long   6b \n"          \
107         "8:     lhi     %0,%h[e2] \n"   \
108         "       bras    1,9f \n"        \
109         "       .long   6b \n"          \
110         "9:     l       1,0(1) \n"      \
111         "       br      1 \n"           \
112         ".previous \n"                  \
113         ".section __ex_table,\"a\" \n"  \
114         "       .align  4 \n"           \
115         "       .long   0b,7b \n"       \
116         "       .long   1b,8b \n"       \
117         ".previous"
118 #else /* __s390x__ */
119 #define __crypt_s390_fixup \
120         ".section .fixup,\"ax\" \n"     \
121         "7:     lhi     %0,%h[e1] \n"   \
122         "       jg      6b \n"          \
123         "8:     lhi     %0,%h[e2] \n"   \
124         "       jg      6b \n"          \
125         ".previous\n"                   \
126         ".section __ex_table,\"a\" \n"  \
127         "       .align  8 \n"           \
128         "       .quad   0b,7b \n"       \
129         "       .quad   1b,8b \n"       \
130         ".previous"
131 #endif /* __s390x__ */
132
133 /*
134  * Standard code for setting the result of s390 crypto instructions.
135  * %0: the register which will receive the result
136  * [result]: the register containing the result (e.g. second operand length
137  * to compute number of processed bytes].
138  */
139 #ifndef __s390x__
140 #define __crypt_s390_set_result \
141         "       lr      %0,%[result] \n"
142 #else /* __s390x__ */
143 #define __crypt_s390_set_result \
144         "       lgr     %0,%[result] \n"
145 #endif
146
147 /*
148  * Executes the KM (CIPHER MESSAGE) operation of the CPU.
149  * @param func: the function code passed to KM; see crypt_s390_km_func
150  * @param param: address of parameter block; see POP for details on each func
151  * @param dest: address of destination memory area
152  * @param src: address of source memory area
153  * @param src_len: length of src operand in bytes
154  * @returns < zero for failure, 0 for the query func, number of processed bytes
155  *      for encryption/decryption funcs
156  */
157 static inline int
158 crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
159 {
160         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
161         register void* __param asm("1") = param;
162         register u8* __dest asm("4") = dest;
163         register const u8* __src asm("2") = src;
164         register long __src_len asm("3") = src_len;
165         int ret;
166
167         ret = 0;
168         __asm__ __volatile__ (
169                 "0:     .insn   rre,0xB92E0000,%1,%2 \n" /* KM opcode */
170                 "1:     brc     1,0b \n" /* handle partial completion */
171                 __crypt_s390_set_result
172                 "6:     \n"
173                 __crypt_s390_fixup
174                 : "+d" (ret), "+a" (__dest), "+a" (__src),
175                   [result] "+d" (__src_len)
176                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
177                   "a" (__param)
178                 : "cc", "memory"
179         );
180         if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
181                 ret = src_len - ret;
182         }
183         return ret;
184 }
185
186 /*
187  * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
188  * @param func: the function code passed to KM; see crypt_s390_kmc_func
189  * @param param: address of parameter block; see POP for details on each func
190  * @param dest: address of destination memory area
191  * @param src: address of source memory area
192  * @param src_len: length of src operand in bytes
193  * @returns < zero for failure, 0 for the query func, number of processed bytes
194  *      for encryption/decryption funcs
195  */
196 static inline int
197 crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
198 {
199         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
200         register void* __param asm("1") = param;
201         register u8* __dest asm("4") = dest;
202         register const u8* __src asm("2") = src;
203         register long __src_len asm("3") = src_len;
204         int ret;
205
206         ret = 0;
207         __asm__ __volatile__ (
208                 "0:     .insn   rre,0xB92F0000,%1,%2 \n" /* KMC opcode */
209                 "1:     brc     1,0b \n" /* handle partial completion */
210                 __crypt_s390_set_result
211                 "6:     \n"
212                 __crypt_s390_fixup
213                 : "+d" (ret), "+a" (__dest), "+a" (__src),
214                   [result] "+d" (__src_len)
215                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
216                   "a" (__param)
217                 : "cc", "memory"
218         );
219         if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
220                 ret = src_len - ret;
221         }
222         return ret;
223 }
224
225 /*
226  * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
227  * of the CPU.
228  * @param func: the function code passed to KM; see crypt_s390_kimd_func
229  * @param param: address of parameter block; see POP for details on each func
230  * @param src: address of source memory area
231  * @param src_len: length of src operand in bytes
232  * @returns < zero for failure, 0 for the query func, number of processed bytes
233  *      for digest funcs
234  */
235 static inline int
236 crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
237 {
238         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
239         register void* __param asm("1") = param;
240         register const u8* __src asm("2") = src;
241         register long __src_len asm("3") = src_len;
242         int ret;
243
244         ret = 0;
245         __asm__ __volatile__ (
246                 "0:     .insn   rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */
247                 "1:     brc     1,0b \n" /* handle partical completion */
248                 __crypt_s390_set_result
249                 "6:     \n"
250                 __crypt_s390_fixup
251                 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
252                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
253                   "a" (__param)
254                 : "cc", "memory"
255         );
256         if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){
257                 ret = src_len - ret;
258         }
259         return ret;
260 }
261
262 /*
263  * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
264  * @param func: the function code passed to KM; see crypt_s390_klmd_func
265  * @param param: address of parameter block; see POP for details on each func
266  * @param src: address of source memory area
267  * @param src_len: length of src operand in bytes
268  * @returns < zero for failure, 0 for the query func, number of processed bytes
269  *      for digest funcs
270  */
271 static inline int
272 crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
273 {
274         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
275         register void* __param asm("1") = param;
276         register const u8* __src asm("2") = src;
277         register long __src_len asm("3") = src_len;
278         int ret;
279
280         ret = 0;
281         __asm__ __volatile__ (
282                 "0:     .insn   rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */
283                 "1:     brc     1,0b \n" /* handle partical completion */
284                 __crypt_s390_set_result
285                 "6:     \n"
286                 __crypt_s390_fixup
287                 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
288                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
289                   "a" (__param)
290                 : "cc", "memory"
291         );
292         if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
293                 ret = src_len - ret;
294         }
295         return ret;
296 }
297
298 /*
299  * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
300  * of the CPU.
301  * @param func: the function code passed to KM; see crypt_s390_klmd_func
302  * @param param: address of parameter block; see POP for details on each func
303  * @param src: address of source memory area
304  * @param src_len: length of src operand in bytes
305  * @returns < zero for failure, 0 for the query func, number of processed bytes
306  *      for digest funcs
307  */
308 static inline int
309 crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
310 {
311         register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
312         register void* __param asm("1") = param;
313         register const u8* __src asm("2") = src;
314         register long __src_len asm("3") = src_len;
315         int ret;
316
317         ret = 0;
318         __asm__ __volatile__ (
319                 "0:     .insn   rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */
320                 "1:     brc     1,0b \n" /* handle partical completion */
321                 __crypt_s390_set_result
322                 "6:     \n"
323                 __crypt_s390_fixup
324                 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
325                 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
326                   "a" (__param)
327                 : "cc", "memory"
328         );
329         if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
330                 ret = src_len - ret;
331         }
332         return ret;
333 }
334
335 /**
336  * Tests if a specific crypto function is implemented on the machine.
337  * @param func: the function code of the specific function; 0 if op in general
338  * @return      1 if func available; 0 if func or op in general not available
339  */
340 static inline int
341 crypt_s390_func_available(int func)
342 {
343         int ret;
344
345         struct crypt_s390_query_status status = {
346                 .high = 0,
347                 .low = 0
348         };
349         switch (func & CRYPT_S390_OP_MASK){
350                 case CRYPT_S390_KM:
351                         ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
352                         break;
353                 case CRYPT_S390_KMC:
354                         ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
355                         break;
356                 case CRYPT_S390_KIMD:
357                         ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
358                         break;
359                 case CRYPT_S390_KLMD:
360                         ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
361                         break;
362                 case CRYPT_S390_KMAC:
363                         ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
364                         break;
365                 default:
366                         ret = 0;
367                         return ret;
368         }
369         if (ret >= 0){
370                 func &= CRYPT_S390_FUNC_MASK;
371                 func &= 0x7f; //mask modifier bit
372                 if (func < 64){
373                         ret = (status.high >> (64 - func - 1)) & 0x1;
374                 } else {
375                         ret = (status.low >> (128 - func - 1)) & 0x1;
376                 }
377         } else {
378                 ret = 0;
379         }
380         return ret;
381 }
382
383 #endif // _CRYPTO_ARCH_S390_CRYPT_S390_H