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