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