blob: 4b8c96cab252d9c80083d396855abfc089f8961d [file] [log] [blame]
Jan Glauberc1e26e12006-01-06 00:19:17 -08001/*
2 * Cryptographic API.
3 *
4 * Support for s390 cryptographic instructions.
5 *
Jan Glauber86aa9fc2007-02-05 21:18:14 +01006 * Copyright IBM Corp. 2003,2007
7 * Author(s): Thomas Spatzier
8 * Jan Glauber (jan.glauber@de.ibm.com)
Jan Glauberc1e26e12006-01-06 00:19:17 -08009 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 */
16#ifndef _CRYPTO_ARCH_S390_CRYPT_S390_H
17#define _CRYPTO_ARCH_S390_CRYPT_S390_H
18
19#include <asm/errno.h>
20
21#define CRYPT_S390_OP_MASK 0xFF00
22#define CRYPT_S390_FUNC_MASK 0x00FF
23
Herbert Xu65b75c32006-08-21 21:18:50 +100024#define CRYPT_S390_PRIORITY 300
Herbert Xua9e62fa2006-08-21 21:39:24 +100025#define CRYPT_S390_COMPOSITE_PRIORITY 400
Herbert Xu65b75c32006-08-21 21:18:50 +100026
Jan Glauber1822bc92011-04-19 21:29:14 +020027#define CRYPT_S390_MSA 0x1
28#define CRYPT_S390_MSA3 0x2
29#define CRYPT_S390_MSA4 0x4
30
Ralph Wuerthnerbccdbdc2007-07-10 11:24:08 +020031/* s390 cryptographic operations */
Jan Glauberc1e26e12006-01-06 00:19:17 -080032enum crypt_s390_operations {
33 CRYPT_S390_KM = 0x0100,
34 CRYPT_S390_KMC = 0x0200,
35 CRYPT_S390_KIMD = 0x0300,
36 CRYPT_S390_KLMD = 0x0400,
37 CRYPT_S390_KMAC = 0x0500
38};
39
Jan Glauber86aa9fc2007-02-05 21:18:14 +010040/*
41 * function codes for KM (CIPHER MESSAGE) instruction
Jan Glauberc1e26e12006-01-06 00:19:17 -080042 * 0x80 is the decipher modifier bit
43 */
44enum crypt_s390_km_func {
Jan Glauberbf754ae2006-01-06 00:19:18 -080045 KM_QUERY = CRYPT_S390_KM | 0x0,
46 KM_DEA_ENCRYPT = CRYPT_S390_KM | 0x1,
47 KM_DEA_DECRYPT = CRYPT_S390_KM | 0x1 | 0x80,
48 KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2,
49 KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80,
50 KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3,
51 KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80,
52 KM_AES_128_ENCRYPT = CRYPT_S390_KM | 0x12,
53 KM_AES_128_DECRYPT = CRYPT_S390_KM | 0x12 | 0x80,
54 KM_AES_192_ENCRYPT = CRYPT_S390_KM | 0x13,
55 KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80,
56 KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14,
57 KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80,
Jan Glauberc1e26e12006-01-06 00:19:17 -080058};
59
Jan Glauber86aa9fc2007-02-05 21:18:14 +010060/*
61 * function codes for KMC (CIPHER MESSAGE WITH CHAINING)
Jan Glauberc1e26e12006-01-06 00:19:17 -080062 * instruction
63 */
64enum crypt_s390_kmc_func {
Jan Glauberbf754ae2006-01-06 00:19:18 -080065 KMC_QUERY = CRYPT_S390_KMC | 0x0,
66 KMC_DEA_ENCRYPT = CRYPT_S390_KMC | 0x1,
67 KMC_DEA_DECRYPT = CRYPT_S390_KMC | 0x1 | 0x80,
68 KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2,
69 KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80,
70 KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3,
71 KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80,
72 KMC_AES_128_ENCRYPT = CRYPT_S390_KMC | 0x12,
73 KMC_AES_128_DECRYPT = CRYPT_S390_KMC | 0x12 | 0x80,
74 KMC_AES_192_ENCRYPT = CRYPT_S390_KMC | 0x13,
75 KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80,
76 KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14,
77 KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80,
Jan Glauber1b278292007-02-05 21:18:22 +010078 KMC_PRNG = CRYPT_S390_KMC | 0x43,
Jan Glauberc1e26e12006-01-06 00:19:17 -080079};
80
Jan Glauber86aa9fc2007-02-05 21:18:14 +010081/*
82 * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
Jan Glauberc1e26e12006-01-06 00:19:17 -080083 * instruction
84 */
85enum crypt_s390_kimd_func {
86 KIMD_QUERY = CRYPT_S390_KIMD | 0,
87 KIMD_SHA_1 = CRYPT_S390_KIMD | 1,
Jan Glauber0a497c172006-01-06 00:19:18 -080088 KIMD_SHA_256 = CRYPT_S390_KIMD | 2,
Jan Glauber291dc7c2008-03-06 19:52:00 +080089 KIMD_SHA_512 = CRYPT_S390_KIMD | 3,
Jan Glauberc1e26e12006-01-06 00:19:17 -080090};
91
Jan Glauber86aa9fc2007-02-05 21:18:14 +010092/*
93 * function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
Jan Glauberc1e26e12006-01-06 00:19:17 -080094 * instruction
95 */
96enum crypt_s390_klmd_func {
97 KLMD_QUERY = CRYPT_S390_KLMD | 0,
98 KLMD_SHA_1 = CRYPT_S390_KLMD | 1,
Jan Glauber0a497c172006-01-06 00:19:18 -080099 KLMD_SHA_256 = CRYPT_S390_KLMD | 2,
Jan Glauber291dc7c2008-03-06 19:52:00 +0800100 KLMD_SHA_512 = CRYPT_S390_KLMD | 3,
Jan Glauberc1e26e12006-01-06 00:19:17 -0800101};
102
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100103/*
104 * function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
Jan Glauberc1e26e12006-01-06 00:19:17 -0800105 * instruction
106 */
107enum crypt_s390_kmac_func {
108 KMAC_QUERY = CRYPT_S390_KMAC | 0,
109 KMAC_DEA = CRYPT_S390_KMAC | 1,
110 KMAC_TDEA_128 = CRYPT_S390_KMAC | 2,
111 KMAC_TDEA_192 = CRYPT_S390_KMAC | 3
112};
113
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100114/**
115 * crypt_s390_km:
116 * @func: the function code passed to KM; see crypt_s390_km_func
117 * @param: address of parameter block; see POP for details on each func
118 * @dest: address of destination memory area
119 * @src: address of source memory area
120 * @src_len: length of src operand in bytes
121 *
Jan Glauberc1e26e12006-01-06 00:19:17 -0800122 * Executes the KM (CIPHER MESSAGE) operation of the CPU.
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100123 *
124 * Returns -1 for failure, 0 for the query func, number of processed
125 * bytes for encryption/decryption funcs
Jan Glauberc1e26e12006-01-06 00:19:17 -0800126 */
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100127static inline int crypt_s390_km(long func, void *param,
128 u8 *dest, const u8 *src, long src_len)
Jan Glauberc1e26e12006-01-06 00:19:17 -0800129{
130 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100131 register void *__param asm("1") = param;
132 register const u8 *__src asm("2") = src;
Jan Glauberc1e26e12006-01-06 00:19:17 -0800133 register long __src_len asm("3") = src_len;
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100134 register u8 *__dest asm("4") = dest;
Jan Glauberc1e26e12006-01-06 00:19:17 -0800135 int ret;
136
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +0200137 asm volatile(
138 "0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */
Jan Glauberc1e26e12006-01-06 00:19:17 -0800139 "1: brc 1,0b \n" /* handle partial completion */
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100140 " la %0,0\n"
141 "2:\n"
142 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +0200143 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100144 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
Martin Schwidefsky94c12cc2006-09-28 16:56:43 +0200145 if (ret < 0)
146 return ret;
147 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
Jan Glauberc1e26e12006-01-06 00:19:17 -0800148}
149
150/**
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100151 * crypt_s390_kmc:
152 * @func: the function code passed to KM; see crypt_s390_kmc_func
153 * @param: address of parameter block; see POP for details on each func
154 * @dest: address of destination memory area
155 * @src: address of source memory area
156 * @src_len: length of src operand in bytes
157 *
158 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
159 *
160 * Returns -1 for failure, 0 for the query func, number of processed
161 * bytes for encryption/decryption funcs
Jan Glauberc1e26e12006-01-06 00:19:17 -0800162 */
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100163static inline int crypt_s390_kmc(long func, void *param,
164 u8 *dest, const u8 *src, long src_len)
Jan Glauberc1e26e12006-01-06 00:19:17 -0800165{
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100166 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
167 register void *__param asm("1") = param;
168 register const u8 *__src asm("2") = src;
169 register long __src_len asm("3") = src_len;
170 register u8 *__dest asm("4") = dest;
Jan Glauberc1e26e12006-01-06 00:19:17 -0800171 int ret;
172
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100173 asm volatile(
174 "0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */
175 "1: brc 1,0b \n" /* handle partial completion */
176 " la %0,0\n"
177 "2:\n"
178 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
179 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
180 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
181 if (ret < 0)
182 return ret;
183 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
Jan Glauberc1e26e12006-01-06 00:19:17 -0800184}
185
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100186/**
187 * crypt_s390_kimd:
188 * @func: the function code passed to KM; see crypt_s390_kimd_func
189 * @param: address of parameter block; see POP for details on each func
190 * @src: address of source memory area
191 * @src_len: length of src operand in bytes
192 *
193 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
194 * of the CPU.
195 *
196 * Returns -1 for failure, 0 for the query func, number of processed
197 * bytes for digest funcs
198 */
199static inline int crypt_s390_kimd(long func, void *param,
200 const u8 *src, long src_len)
201{
202 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
203 register void *__param asm("1") = param;
204 register const u8 *__src asm("2") = src;
205 register long __src_len asm("3") = src_len;
206 int ret;
207
208 asm volatile(
209 "0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */
210 "1: brc 1,0b \n" /* handle partial completion */
211 " la %0,0\n"
212 "2:\n"
213 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
214 : "=d" (ret), "+a" (__src), "+d" (__src_len)
215 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
216 if (ret < 0)
217 return ret;
218 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
219}
220
221/**
222 * crypt_s390_klmd:
223 * @func: the function code passed to KM; see crypt_s390_klmd_func
224 * @param: address of parameter block; see POP for details on each func
225 * @src: address of source memory area
226 * @src_len: length of src operand in bytes
227 *
228 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
229 *
230 * Returns -1 for failure, 0 for the query func, number of processed
231 * bytes for digest funcs
232 */
233static inline int crypt_s390_klmd(long func, void *param,
234 const u8 *src, long src_len)
235{
236 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
237 register void *__param asm("1") = param;
238 register const u8 *__src asm("2") = src;
239 register long __src_len asm("3") = src_len;
240 int ret;
241
242 asm volatile(
243 "0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */
244 "1: brc 1,0b \n" /* handle partial completion */
245 " la %0,0\n"
246 "2:\n"
247 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
248 : "=d" (ret), "+a" (__src), "+d" (__src_len)
249 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
250 if (ret < 0)
251 return ret;
252 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
253}
254
255/**
256 * crypt_s390_kmac:
257 * @func: the function code passed to KM; see crypt_s390_klmd_func
258 * @param: address of parameter block; see POP for details on each func
259 * @src: address of source memory area
260 * @src_len: length of src operand in bytes
261 *
262 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
263 * of the CPU.
264 *
265 * Returns -1 for failure, 0 for the query func, number of processed
266 * bytes for digest funcs
267 */
268static inline int crypt_s390_kmac(long func, void *param,
269 const u8 *src, long src_len)
270{
271 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
272 register void *__param asm("1") = param;
273 register const u8 *__src asm("2") = src;
274 register long __src_len asm("3") = src_len;
275 int ret;
276
277 asm volatile(
278 "0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */
279 "1: brc 1,0b \n" /* handle partial completion */
280 " la %0,0\n"
281 "2:\n"
282 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
283 : "=d" (ret), "+a" (__src), "+d" (__src_len)
284 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
285 if (ret < 0)
286 return ret;
287 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
288}
289
290/**
291 * crypt_s390_func_available:
292 * @func: the function code of the specific function; 0 if op in general
293 *
294 * Tests if a specific crypto function is implemented on the machine.
295 *
296 * Returns 1 if func available; 0 if func or op in general not available
297 */
Jan Glauber1822bc92011-04-19 21:29:14 +0200298static inline int crypt_s390_func_available(int func,
299 unsigned int facility_mask)
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100300{
301 unsigned char status[16];
302 int ret;
303
Jan Glauber1822bc92011-04-19 21:29:14 +0200304 if (facility_mask & CRYPT_S390_MSA && !test_facility(17))
305 return 0;
306 if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76))
307 return 0;
308 if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77))
Jan Glaubera72f0db2008-07-12 15:42:11 +0800309 return 0;
310
Jan Glauber86aa9fc2007-02-05 21:18:14 +0100311 switch (func & CRYPT_S390_OP_MASK) {
312 case CRYPT_S390_KM:
313 ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
314 break;
315 case CRYPT_S390_KMC:
316 ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
317 break;
318 case CRYPT_S390_KIMD:
319 ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
320 break;
321 case CRYPT_S390_KLMD:
322 ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
323 break;
324 case CRYPT_S390_KMAC:
325 ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
326 break;
327 default:
328 return 0;
329 }
330 if (ret < 0)
331 return 0;
332 func &= CRYPT_S390_FUNC_MASK;
333 func &= 0x7f; /* mask modifier bit */
334 return (status[func >> 3] & (0x80 >> (func & 7))) != 0;
335}
336
337#endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */