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