1
2
3
4
5
6
7
8
9
10#ifndef _ASM_S390_CPACF_H
11#define _ASM_S390_CPACF_H
12
13#include <asm/facility.h>
14
15
16
17
18#define CPACF_KMAC 0xb91e
19#define CPACF_KM 0xb92e
20#define CPACF_KMC 0xb92f
21#define CPACF_KIMD 0xb93e
22#define CPACF_KLMD 0xb93f
23#define CPACF_PCKMO 0xb928
24#define CPACF_KMF 0xb92a
25#define CPACF_KMO 0xb92b
26#define CPACF_PCC 0xb92c
27#define CPACF_KMCTR 0xb92d
28#define CPACF_PRNO 0xb93c
29#define CPACF_KMA 0xb929
30
31
32
33
34#define CPACF_ENCRYPT 0x00
35#define CPACF_DECRYPT 0x80
36
37
38
39
40#define CPACF_KM_QUERY 0x00
41#define CPACF_KM_DEA 0x01
42#define CPACF_KM_TDEA_128 0x02
43#define CPACF_KM_TDEA_192 0x03
44#define CPACF_KM_AES_128 0x12
45#define CPACF_KM_AES_192 0x13
46#define CPACF_KM_AES_256 0x14
47#define CPACF_KM_PAES_128 0x1a
48#define CPACF_KM_PAES_192 0x1b
49#define CPACF_KM_PAES_256 0x1c
50#define CPACF_KM_XTS_128 0x32
51#define CPACF_KM_XTS_256 0x34
52#define CPACF_KM_PXTS_128 0x3a
53#define CPACF_KM_PXTS_256 0x3c
54
55
56
57
58
59#define CPACF_KMC_QUERY 0x00
60#define CPACF_KMC_DEA 0x01
61#define CPACF_KMC_TDEA_128 0x02
62#define CPACF_KMC_TDEA_192 0x03
63#define CPACF_KMC_AES_128 0x12
64#define CPACF_KMC_AES_192 0x13
65#define CPACF_KMC_AES_256 0x14
66#define CPACF_KMC_PAES_128 0x1a
67#define CPACF_KMC_PAES_192 0x1b
68#define CPACF_KMC_PAES_256 0x1c
69#define CPACF_KMC_PRNG 0x43
70
71
72
73
74
75#define CPACF_KMCTR_QUERY 0x00
76#define CPACF_KMCTR_DEA 0x01
77#define CPACF_KMCTR_TDEA_128 0x02
78#define CPACF_KMCTR_TDEA_192 0x03
79#define CPACF_KMCTR_AES_128 0x12
80#define CPACF_KMCTR_AES_192 0x13
81#define CPACF_KMCTR_AES_256 0x14
82#define CPACF_KMCTR_PAES_128 0x1a
83#define CPACF_KMCTR_PAES_192 0x1b
84#define CPACF_KMCTR_PAES_256 0x1c
85
86
87
88
89
90#define CPACF_KIMD_QUERY 0x00
91#define CPACF_KIMD_SHA_1 0x01
92#define CPACF_KIMD_SHA_256 0x02
93#define CPACF_KIMD_SHA_512 0x03
94#define CPACF_KIMD_GHASH 0x41
95
96
97
98
99
100#define CPACF_KLMD_QUERY 0x00
101#define CPACF_KLMD_SHA_1 0x01
102#define CPACF_KLMD_SHA_256 0x02
103#define CPACF_KLMD_SHA_512 0x03
104
105
106
107
108
109#define CPACF_KMAC_QUERY 0x00
110#define CPACF_KMAC_DEA 0x01
111#define CPACF_KMAC_TDEA_128 0x02
112#define CPACF_KMAC_TDEA_192 0x03
113
114
115
116
117
118#define CPACF_PCKMO_QUERY 0x00
119#define CPACF_PCKMO_ENC_DES_KEY 0x01
120#define CPACF_PCKMO_ENC_TDES_128_KEY 0x02
121#define CPACF_PCKMO_ENC_TDES_192_KEY 0x03
122#define CPACF_PCKMO_ENC_AES_128_KEY 0x12
123#define CPACF_PCKMO_ENC_AES_192_KEY 0x13
124#define CPACF_PCKMO_ENC_AES_256_KEY 0x14
125
126
127
128
129
130#define CPACF_PRNO_QUERY 0x00
131#define CPACF_PRNO_SHA512_DRNG_GEN 0x03
132#define CPACF_PRNO_SHA512_DRNG_SEED 0x83
133#define CPACF_PRNO_TRNG_Q_R2C_RATIO 0x70
134#define CPACF_PRNO_TRNG 0x72
135
136typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
137
138
139
140
141
142
143
144
145
146
147
148static inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
149{
150 register unsigned long r0 asm("0") = 0;
151 register unsigned long r1 asm("1") = (unsigned long) mask;
152
153 asm volatile(
154 " spm 0\n"
155
156 "0: .insn rrf,%[opc] << 16,2,4,6,0\n"
157 " brc 1,0b\n"
158 : "=m" (*mask)
159 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (opcode)
160 : "cc");
161}
162
163static inline int __cpacf_check_opcode(unsigned int opcode)
164{
165 switch (opcode) {
166 case CPACF_KMAC:
167 case CPACF_KM:
168 case CPACF_KMC:
169 case CPACF_KIMD:
170 case CPACF_KLMD:
171 return test_facility(17);
172 case CPACF_PCKMO:
173 return test_facility(76);
174 case CPACF_KMF:
175 case CPACF_KMO:
176 case CPACF_PCC:
177 case CPACF_KMCTR:
178 return test_facility(77);
179 case CPACF_PRNO:
180 return test_facility(57);
181 default:
182 BUG();
183 }
184}
185
186static inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
187{
188 if (__cpacf_check_opcode(opcode)) {
189 __cpacf_query(opcode, mask);
190 return 1;
191 }
192 memset(mask, 0, sizeof(*mask));
193 return 0;
194}
195
196static inline int cpacf_test_func(cpacf_mask_t *mask, unsigned int func)
197{
198 return (mask->bytes[func >> 3] & (0x80 >> (func & 7))) != 0;
199}
200
201static inline int cpacf_query_func(unsigned int opcode, unsigned int func)
202{
203 cpacf_mask_t mask;
204
205 if (cpacf_query(opcode, &mask))
206 return cpacf_test_func(&mask, func);
207 return 0;
208}
209
210
211
212
213
214
215
216
217
218
219
220
221static inline int cpacf_km(unsigned long func, void *param,
222 u8 *dest, const u8 *src, long src_len)
223{
224 register unsigned long r0 asm("0") = (unsigned long) func;
225 register unsigned long r1 asm("1") = (unsigned long) param;
226 register unsigned long r2 asm("2") = (unsigned long) src;
227 register unsigned long r3 asm("3") = (unsigned long) src_len;
228 register unsigned long r4 asm("4") = (unsigned long) dest;
229
230 asm volatile(
231 "0: .insn rre,%[opc] << 16,%[dst],%[src]\n"
232 " brc 1,0b\n"
233 : [src] "+a" (r2), [len] "+d" (r3), [dst] "+a" (r4)
234 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KM)
235 : "cc", "memory");
236
237 return src_len - r3;
238}
239
240
241
242
243
244
245
246
247
248
249
250
251static inline int cpacf_kmc(unsigned long func, void *param,
252 u8 *dest, const u8 *src, long src_len)
253{
254 register unsigned long r0 asm("0") = (unsigned long) func;
255 register unsigned long r1 asm("1") = (unsigned long) param;
256 register unsigned long r2 asm("2") = (unsigned long) src;
257 register unsigned long r3 asm("3") = (unsigned long) src_len;
258 register unsigned long r4 asm("4") = (unsigned long) dest;
259
260 asm volatile(
261 "0: .insn rre,%[opc] << 16,%[dst],%[src]\n"
262 " brc 1,0b\n"
263 : [src] "+a" (r2), [len] "+d" (r3), [dst] "+a" (r4)
264 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMC)
265 : "cc", "memory");
266
267 return src_len - r3;
268}
269
270
271
272
273
274
275
276
277
278static inline void cpacf_kimd(unsigned long func, void *param,
279 const u8 *src, long src_len)
280{
281 register unsigned long r0 asm("0") = (unsigned long) func;
282 register unsigned long r1 asm("1") = (unsigned long) param;
283 register unsigned long r2 asm("2") = (unsigned long) src;
284 register unsigned long r3 asm("3") = (unsigned long) src_len;
285
286 asm volatile(
287 "0: .insn rre,%[opc] << 16,0,%[src]\n"
288 " brc 1,0b\n"
289 : [src] "+a" (r2), [len] "+d" (r3)
290 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KIMD)
291 : "cc", "memory");
292}
293
294
295
296
297
298
299
300
301static inline void cpacf_klmd(unsigned long func, void *param,
302 const u8 *src, long src_len)
303{
304 register unsigned long r0 asm("0") = (unsigned long) func;
305 register unsigned long r1 asm("1") = (unsigned long) param;
306 register unsigned long r2 asm("2") = (unsigned long) src;
307 register unsigned long r3 asm("3") = (unsigned long) src_len;
308
309 asm volatile(
310 "0: .insn rre,%[opc] << 16,0,%[src]\n"
311 " brc 1,0b\n"
312 : [src] "+a" (r2), [len] "+d" (r3)
313 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KLMD)
314 : "cc", "memory");
315}
316
317
318
319
320
321
322
323
324
325
326
327static inline int cpacf_kmac(unsigned long func, void *param,
328 const u8 *src, long src_len)
329{
330 register unsigned long r0 asm("0") = (unsigned long) func;
331 register unsigned long r1 asm("1") = (unsigned long) param;
332 register unsigned long r2 asm("2") = (unsigned long) src;
333 register unsigned long r3 asm("3") = (unsigned long) src_len;
334
335 asm volatile(
336 "0: .insn rre,%[opc] << 16,0,%[src]\n"
337 " brc 1,0b\n"
338 : [src] "+a" (r2), [len] "+d" (r3)
339 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMAC)
340 : "cc", "memory");
341
342 return src_len - r3;
343}
344
345
346
347
348
349
350
351
352
353
354
355
356
357static inline int cpacf_kmctr(unsigned long func, void *param, u8 *dest,
358 const u8 *src, long src_len, u8 *counter)
359{
360 register unsigned long r0 asm("0") = (unsigned long) func;
361 register unsigned long r1 asm("1") = (unsigned long) param;
362 register unsigned long r2 asm("2") = (unsigned long) src;
363 register unsigned long r3 asm("3") = (unsigned long) src_len;
364 register unsigned long r4 asm("4") = (unsigned long) dest;
365 register unsigned long r6 asm("6") = (unsigned long) counter;
366
367 asm volatile(
368 "0: .insn rrf,%[opc] << 16,%[dst],%[src],%[ctr],0\n"
369 " brc 1,0b\n"
370 : [src] "+a" (r2), [len] "+d" (r3),
371 [dst] "+a" (r4), [ctr] "+a" (r6)
372 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMCTR)
373 : "cc", "memory");
374
375 return src_len - r3;
376}
377
378
379
380
381
382
383
384
385
386
387
388static inline void cpacf_prno(unsigned long func, void *param,
389 u8 *dest, unsigned long dest_len,
390 const u8 *seed, unsigned long seed_len)
391{
392 register unsigned long r0 asm("0") = (unsigned long) func;
393 register unsigned long r1 asm("1") = (unsigned long) param;
394 register unsigned long r2 asm("2") = (unsigned long) dest;
395 register unsigned long r3 asm("3") = (unsigned long) dest_len;
396 register unsigned long r4 asm("4") = (unsigned long) seed;
397 register unsigned long r5 asm("5") = (unsigned long) seed_len;
398
399 asm volatile (
400 "0: .insn rre,%[opc] << 16,%[dst],%[seed]\n"
401 " brc 1,0b\n"
402 : [dst] "+a" (r2), [dlen] "+d" (r3)
403 : [fc] "d" (r0), [pba] "a" (r1),
404 [seed] "a" (r4), [slen] "d" (r5), [opc] "i" (CPACF_PRNO)
405 : "cc", "memory");
406}
407
408
409
410
411
412
413
414
415static inline void cpacf_trng(u8 *ucbuf, unsigned long ucbuf_len,
416 u8 *cbuf, unsigned long cbuf_len)
417{
418 register unsigned long r0 asm("0") = (unsigned long) CPACF_PRNO_TRNG;
419 register unsigned long r2 asm("2") = (unsigned long) ucbuf;
420 register unsigned long r3 asm("3") = (unsigned long) ucbuf_len;
421 register unsigned long r4 asm("4") = (unsigned long) cbuf;
422 register unsigned long r5 asm("5") = (unsigned long) cbuf_len;
423
424 asm volatile (
425 "0: .insn rre,%[opc] << 16,%[ucbuf],%[cbuf]\n"
426 " brc 1,0b\n"
427 : [ucbuf] "+a" (r2), [ucbuflen] "+d" (r3),
428 [cbuf] "+a" (r4), [cbuflen] "+d" (r5)
429 : [fc] "d" (r0), [opc] "i" (CPACF_PRNO)
430 : "cc", "memory");
431}
432
433
434
435
436
437
438
439static inline void cpacf_pcc(unsigned long func, void *param)
440{
441 register unsigned long r0 asm("0") = (unsigned long) func;
442 register unsigned long r1 asm("1") = (unsigned long) param;
443
444 asm volatile(
445 "0: .insn rre,%[opc] << 16,0,0\n"
446 " brc 1,0b\n"
447 :
448 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_PCC)
449 : "cc", "memory");
450}
451
452
453
454
455
456
457
458
459
460static inline void cpacf_pckmo(long func, void *param)
461{
462 register unsigned long r0 asm("0") = (unsigned long) func;
463 register unsigned long r1 asm("1") = (unsigned long) param;
464
465 asm volatile(
466 " .insn rre,%[opc] << 16,0,0\n"
467 :
468 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_PCKMO)
469 : "cc", "memory");
470}
471
472#endif
473