Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/s390/crypto/crypt_s390.h
10817 views
1
/*
2
* Cryptographic API.
3
*
4
* Support for s390 cryptographic instructions.
5
*
6
* Copyright IBM Corp. 2003,2007
7
* Author(s): Thomas Spatzier
8
* Jan Glauber ([email protected])
9
*
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
24
#define CRYPT_S390_PRIORITY 300
25
#define CRYPT_S390_COMPOSITE_PRIORITY 400
26
27
#define CRYPT_S390_MSA 0x1
28
#define CRYPT_S390_MSA3 0x2
29
#define CRYPT_S390_MSA4 0x4
30
31
/* s390 cryptographic operations */
32
enum 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
CRYPT_S390_KMCTR = 0x0600
39
};
40
41
/*
42
* function codes for KM (CIPHER MESSAGE) instruction
43
* 0x80 is the decipher modifier bit
44
*/
45
enum crypt_s390_km_func {
46
KM_QUERY = CRYPT_S390_KM | 0x0,
47
KM_DEA_ENCRYPT = CRYPT_S390_KM | 0x1,
48
KM_DEA_DECRYPT = CRYPT_S390_KM | 0x1 | 0x80,
49
KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2,
50
KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80,
51
KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3,
52
KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80,
53
KM_AES_128_ENCRYPT = CRYPT_S390_KM | 0x12,
54
KM_AES_128_DECRYPT = CRYPT_S390_KM | 0x12 | 0x80,
55
KM_AES_192_ENCRYPT = CRYPT_S390_KM | 0x13,
56
KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80,
57
KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14,
58
KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80,
59
KM_XTS_128_ENCRYPT = CRYPT_S390_KM | 0x32,
60
KM_XTS_128_DECRYPT = CRYPT_S390_KM | 0x32 | 0x80,
61
KM_XTS_256_ENCRYPT = CRYPT_S390_KM | 0x34,
62
KM_XTS_256_DECRYPT = CRYPT_S390_KM | 0x34 | 0x80,
63
};
64
65
/*
66
* function codes for KMC (CIPHER MESSAGE WITH CHAINING)
67
* instruction
68
*/
69
enum crypt_s390_kmc_func {
70
KMC_QUERY = CRYPT_S390_KMC | 0x0,
71
KMC_DEA_ENCRYPT = CRYPT_S390_KMC | 0x1,
72
KMC_DEA_DECRYPT = CRYPT_S390_KMC | 0x1 | 0x80,
73
KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2,
74
KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80,
75
KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3,
76
KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80,
77
KMC_AES_128_ENCRYPT = CRYPT_S390_KMC | 0x12,
78
KMC_AES_128_DECRYPT = CRYPT_S390_KMC | 0x12 | 0x80,
79
KMC_AES_192_ENCRYPT = CRYPT_S390_KMC | 0x13,
80
KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80,
81
KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14,
82
KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80,
83
KMC_PRNG = CRYPT_S390_KMC | 0x43,
84
};
85
86
/*
87
* function codes for KMCTR (CIPHER MESSAGE WITH COUNTER)
88
* instruction
89
*/
90
enum crypt_s390_kmctr_func {
91
KMCTR_QUERY = CRYPT_S390_KMCTR | 0x0,
92
KMCTR_DEA_ENCRYPT = CRYPT_S390_KMCTR | 0x1,
93
KMCTR_DEA_DECRYPT = CRYPT_S390_KMCTR | 0x1 | 0x80,
94
KMCTR_TDEA_128_ENCRYPT = CRYPT_S390_KMCTR | 0x2,
95
KMCTR_TDEA_128_DECRYPT = CRYPT_S390_KMCTR | 0x2 | 0x80,
96
KMCTR_TDEA_192_ENCRYPT = CRYPT_S390_KMCTR | 0x3,
97
KMCTR_TDEA_192_DECRYPT = CRYPT_S390_KMCTR | 0x3 | 0x80,
98
KMCTR_AES_128_ENCRYPT = CRYPT_S390_KMCTR | 0x12,
99
KMCTR_AES_128_DECRYPT = CRYPT_S390_KMCTR | 0x12 | 0x80,
100
KMCTR_AES_192_ENCRYPT = CRYPT_S390_KMCTR | 0x13,
101
KMCTR_AES_192_DECRYPT = CRYPT_S390_KMCTR | 0x13 | 0x80,
102
KMCTR_AES_256_ENCRYPT = CRYPT_S390_KMCTR | 0x14,
103
KMCTR_AES_256_DECRYPT = CRYPT_S390_KMCTR | 0x14 | 0x80,
104
};
105
106
/*
107
* function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
108
* instruction
109
*/
110
enum crypt_s390_kimd_func {
111
KIMD_QUERY = CRYPT_S390_KIMD | 0,
112
KIMD_SHA_1 = CRYPT_S390_KIMD | 1,
113
KIMD_SHA_256 = CRYPT_S390_KIMD | 2,
114
KIMD_SHA_512 = CRYPT_S390_KIMD | 3,
115
KIMD_GHASH = CRYPT_S390_KIMD | 65,
116
};
117
118
/*
119
* function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
120
* instruction
121
*/
122
enum crypt_s390_klmd_func {
123
KLMD_QUERY = CRYPT_S390_KLMD | 0,
124
KLMD_SHA_1 = CRYPT_S390_KLMD | 1,
125
KLMD_SHA_256 = CRYPT_S390_KLMD | 2,
126
KLMD_SHA_512 = CRYPT_S390_KLMD | 3,
127
};
128
129
/*
130
* function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
131
* instruction
132
*/
133
enum crypt_s390_kmac_func {
134
KMAC_QUERY = CRYPT_S390_KMAC | 0,
135
KMAC_DEA = CRYPT_S390_KMAC | 1,
136
KMAC_TDEA_128 = CRYPT_S390_KMAC | 2,
137
KMAC_TDEA_192 = CRYPT_S390_KMAC | 3
138
};
139
140
/**
141
* crypt_s390_km:
142
* @func: the function code passed to KM; see crypt_s390_km_func
143
* @param: address of parameter block; see POP for details on each func
144
* @dest: address of destination memory area
145
* @src: address of source memory area
146
* @src_len: length of src operand in bytes
147
*
148
* Executes the KM (CIPHER MESSAGE) operation of the CPU.
149
*
150
* Returns -1 for failure, 0 for the query func, number of processed
151
* bytes for encryption/decryption funcs
152
*/
153
static inline int crypt_s390_km(long func, void *param,
154
u8 *dest, const u8 *src, long src_len)
155
{
156
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
157
register void *__param asm("1") = param;
158
register const u8 *__src asm("2") = src;
159
register long __src_len asm("3") = src_len;
160
register u8 *__dest asm("4") = dest;
161
int ret;
162
163
asm volatile(
164
"0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */
165
"1: brc 1,0b \n" /* handle partial completion */
166
" la %0,0\n"
167
"2:\n"
168
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
169
: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
170
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
171
if (ret < 0)
172
return ret;
173
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
174
}
175
176
/**
177
* crypt_s390_kmc:
178
* @func: the function code passed to KM; see crypt_s390_kmc_func
179
* @param: address of parameter block; see POP for details on each func
180
* @dest: address of destination memory area
181
* @src: address of source memory area
182
* @src_len: length of src operand in bytes
183
*
184
* Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
185
*
186
* Returns -1 for failure, 0 for the query func, number of processed
187
* bytes for encryption/decryption funcs
188
*/
189
static inline int crypt_s390_kmc(long func, void *param,
190
u8 *dest, const u8 *src, long src_len)
191
{
192
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
193
register void *__param asm("1") = param;
194
register const u8 *__src asm("2") = src;
195
register long __src_len asm("3") = src_len;
196
register u8 *__dest asm("4") = dest;
197
int ret;
198
199
asm volatile(
200
"0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */
201
"1: brc 1,0b \n" /* handle partial completion */
202
" la %0,0\n"
203
"2:\n"
204
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
205
: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
206
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
207
if (ret < 0)
208
return ret;
209
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
210
}
211
212
/**
213
* crypt_s390_kimd:
214
* @func: the function code passed to KM; see crypt_s390_kimd_func
215
* @param: address of parameter block; see POP for details on each func
216
* @src: address of source memory area
217
* @src_len: length of src operand in bytes
218
*
219
* Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
220
* of the CPU.
221
*
222
* Returns -1 for failure, 0 for the query func, number of processed
223
* bytes for digest funcs
224
*/
225
static inline int crypt_s390_kimd(long func, void *param,
226
const u8 *src, long src_len)
227
{
228
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
229
register void *__param asm("1") = param;
230
register const u8 *__src asm("2") = src;
231
register long __src_len asm("3") = src_len;
232
int ret;
233
234
asm volatile(
235
"0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */
236
"1: brc 1,0b \n" /* handle partial completion */
237
" la %0,0\n"
238
"2:\n"
239
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
240
: "=d" (ret), "+a" (__src), "+d" (__src_len)
241
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
242
if (ret < 0)
243
return ret;
244
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
245
}
246
247
/**
248
* crypt_s390_klmd:
249
* @func: the function code passed to KM; see crypt_s390_klmd_func
250
* @param: address of parameter block; see POP for details on each func
251
* @src: address of source memory area
252
* @src_len: length of src operand in bytes
253
*
254
* Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
255
*
256
* Returns -1 for failure, 0 for the query func, number of processed
257
* bytes for digest funcs
258
*/
259
static inline int crypt_s390_klmd(long func, void *param,
260
const u8 *src, long src_len)
261
{
262
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
263
register void *__param asm("1") = param;
264
register const u8 *__src asm("2") = src;
265
register long __src_len asm("3") = src_len;
266
int ret;
267
268
asm volatile(
269
"0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */
270
"1: brc 1,0b \n" /* handle partial completion */
271
" la %0,0\n"
272
"2:\n"
273
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
274
: "=d" (ret), "+a" (__src), "+d" (__src_len)
275
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
276
if (ret < 0)
277
return ret;
278
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
279
}
280
281
/**
282
* crypt_s390_kmac:
283
* @func: the function code passed to KM; see crypt_s390_klmd_func
284
* @param: address of parameter block; see POP for details on each func
285
* @src: address of source memory area
286
* @src_len: length of src operand in bytes
287
*
288
* Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
289
* of the CPU.
290
*
291
* Returns -1 for failure, 0 for the query func, number of processed
292
* bytes for digest funcs
293
*/
294
static inline int crypt_s390_kmac(long func, void *param,
295
const u8 *src, long src_len)
296
{
297
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
298
register void *__param asm("1") = param;
299
register const u8 *__src asm("2") = src;
300
register long __src_len asm("3") = src_len;
301
int ret;
302
303
asm volatile(
304
"0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */
305
"1: brc 1,0b \n" /* handle partial completion */
306
" la %0,0\n"
307
"2:\n"
308
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
309
: "=d" (ret), "+a" (__src), "+d" (__src_len)
310
: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
311
if (ret < 0)
312
return ret;
313
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
314
}
315
316
/**
317
* crypt_s390_kmctr:
318
* @func: the function code passed to KMCTR; see crypt_s390_kmctr_func
319
* @param: address of parameter block; see POP for details on each func
320
* @dest: address of destination memory area
321
* @src: address of source memory area
322
* @src_len: length of src operand in bytes
323
* @counter: address of counter value
324
*
325
* Executes the KMCTR (CIPHER MESSAGE WITH COUNTER) operation of the CPU.
326
*
327
* Returns -1 for failure, 0 for the query func, number of processed
328
* bytes for encryption/decryption funcs
329
*/
330
static inline int crypt_s390_kmctr(long func, void *param, u8 *dest,
331
const u8 *src, long src_len, u8 *counter)
332
{
333
register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
334
register void *__param asm("1") = param;
335
register const u8 *__src asm("2") = src;
336
register long __src_len asm("3") = src_len;
337
register u8 *__dest asm("4") = dest;
338
register u8 *__ctr asm("6") = counter;
339
int ret = -1;
340
341
asm volatile(
342
"0: .insn rrf,0xb92d0000,%3,%1,%4,0 \n" /* KMCTR opcode */
343
"1: brc 1,0b \n" /* handle partial completion */
344
" la %0,0\n"
345
"2:\n"
346
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
347
: "+d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest),
348
"+a" (__ctr)
349
: "d" (__func), "a" (__param) : "cc", "memory");
350
if (ret < 0)
351
return ret;
352
return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
353
}
354
355
/**
356
* crypt_s390_func_available:
357
* @func: the function code of the specific function; 0 if op in general
358
*
359
* Tests if a specific crypto function is implemented on the machine.
360
*
361
* Returns 1 if func available; 0 if func or op in general not available
362
*/
363
static inline int crypt_s390_func_available(int func,
364
unsigned int facility_mask)
365
{
366
unsigned char status[16];
367
int ret;
368
369
if (facility_mask & CRYPT_S390_MSA && !test_facility(17))
370
return 0;
371
if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76))
372
return 0;
373
if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77))
374
return 0;
375
376
switch (func & CRYPT_S390_OP_MASK) {
377
case CRYPT_S390_KM:
378
ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
379
break;
380
case CRYPT_S390_KMC:
381
ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
382
break;
383
case CRYPT_S390_KIMD:
384
ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
385
break;
386
case CRYPT_S390_KLMD:
387
ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
388
break;
389
case CRYPT_S390_KMAC:
390
ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
391
break;
392
case CRYPT_S390_KMCTR:
393
ret = crypt_s390_kmctr(KMCTR_QUERY, &status, NULL, NULL, 0,
394
NULL);
395
break;
396
default:
397
return 0;
398
}
399
if (ret < 0)
400
return 0;
401
func &= CRYPT_S390_FUNC_MASK;
402
func &= 0x7f; /* mask modifier bit */
403
return (status[func >> 3] & (0x80 >> (func & 7))) != 0;
404
}
405
406
/**
407
* crypt_s390_pcc:
408
* @func: the function code passed to KM; see crypt_s390_km_func
409
* @param: address of parameter block; see POP for details on each func
410
*
411
* Executes the PCC (PERFORM CRYPTOGRAPHIC COMPUTATION) operation of the CPU.
412
*
413
* Returns -1 for failure, 0 for success.
414
*/
415
static inline int crypt_s390_pcc(long func, void *param)
416
{
417
register long __func asm("0") = func & 0x7f; /* encrypt or decrypt */
418
register void *__param asm("1") = param;
419
int ret = -1;
420
421
asm volatile(
422
"0: .insn rre,0xb92c0000,0,0 \n" /* PCC opcode */
423
"1: brc 1,0b \n" /* handle partial completion */
424
" la %0,0\n"
425
"2:\n"
426
EX_TABLE(0b,2b) EX_TABLE(1b,2b)
427
: "+d" (ret)
428
: "d" (__func), "a" (__param) : "cc", "memory");
429
return ret;
430
}
431
432
433
#endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */
434
435