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_GHASH 0x41
97
98
99
100
101
102#define CPACF_KLMD_QUERY 0x00
103#define CPACF_KLMD_SHA_1 0x01
104#define CPACF_KLMD_SHA_256 0x02
105#define CPACF_KLMD_SHA_512 0x03
106
107
108
109
110
111#define CPACF_KMAC_QUERY 0x00
112#define CPACF_KMAC_DEA 0x01
113#define CPACF_KMAC_TDEA_128 0x02
114#define CPACF_KMAC_TDEA_192 0x03
115
116
117
118
119
120#define CPACF_PCKMO_QUERY 0x00
121#define CPACF_PCKMO_ENC_DES_KEY 0x01
122#define CPACF_PCKMO_ENC_TDES_128_KEY 0x02
123#define CPACF_PCKMO_ENC_TDES_192_KEY 0x03
124#define CPACF_PCKMO_ENC_AES_128_KEY 0x12
125#define CPACF_PCKMO_ENC_AES_192_KEY 0x13
126#define CPACF_PCKMO_ENC_AES_256_KEY 0x14
127
128
129
130
131
132#define CPACF_PRNO_QUERY 0x00
133#define CPACF_PRNO_SHA512_DRNG_GEN 0x03
134#define CPACF_PRNO_SHA512_DRNG_SEED 0x83
135#define CPACF_PRNO_TRNG_Q_R2C_RATIO 0x70
136#define CPACF_PRNO_TRNG 0x72
137
138
139
140
141
142#define CPACF_KMA_QUERY 0x00
143#define CPACF_KMA_GCM_AES_128 0x12
144#define CPACF_KMA_GCM_AES_192 0x13
145#define CPACF_KMA_GCM_AES_256 0x14
146
147
148
149
150#define CPACF_KMA_LPC 0x100
151#define CPACF_KMA_LAAD 0x200
152#define CPACF_KMA_HS 0x400
153
154typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
155
156
157
158
159
160
161
162
163
164
165
166static inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
167{
168 register unsigned long r0 asm("0") = 0;
169 register unsigned long r1 asm("1") = (unsigned long) mask;
170
171 asm volatile(
172 " spm 0\n"
173
174 "0: .insn rrf,%[opc] << 16,2,4,6,0\n"
175 " brc 1,0b\n"
176 : "=m" (*mask)
177 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (opcode)
178 : "cc");
179}
180
181static __always_inline int __cpacf_check_opcode(unsigned int opcode)
182{
183 switch (opcode) {
184 case CPACF_KMAC:
185 case CPACF_KM:
186 case CPACF_KMC:
187 case CPACF_KIMD:
188 case CPACF_KLMD:
189 return test_facility(17);
190 case CPACF_PCKMO:
191 return test_facility(76);
192 case CPACF_KMF:
193 case CPACF_KMO:
194 case CPACF_PCC:
195 case CPACF_KMCTR:
196 return test_facility(77);
197 case CPACF_PRNO:
198 return test_facility(57);
199 case CPACF_KMA:
200 return test_facility(146);
201 default:
202 BUG();
203 }
204}
205
206static __always_inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
207{
208 if (__cpacf_check_opcode(opcode)) {
209 __cpacf_query(opcode, mask);
210 return 1;
211 }
212 memset(mask, 0, sizeof(*mask));
213 return 0;
214}
215
216static inline int cpacf_test_func(cpacf_mask_t *mask, unsigned int func)
217{
218 return (mask->bytes[func >> 3] & (0x80 >> (func & 7))) != 0;
219}
220
221static __always_inline int cpacf_query_func(unsigned int opcode, unsigned int func)
222{
223 cpacf_mask_t mask;
224
225 if (cpacf_query(opcode, &mask))
226 return cpacf_test_func(&mask, func);
227 return 0;
228}
229
230
231
232
233
234
235
236
237
238
239
240
241static inline int cpacf_km(unsigned long func, void *param,
242 u8 *dest, const u8 *src, long src_len)
243{
244 register unsigned long r0 asm("0") = (unsigned long) func;
245 register unsigned long r1 asm("1") = (unsigned long) param;
246 register unsigned long r2 asm("2") = (unsigned long) src;
247 register unsigned long r3 asm("3") = (unsigned long) src_len;
248 register unsigned long r4 asm("4") = (unsigned long) dest;
249
250 asm volatile(
251 "0: .insn rre,%[opc] << 16,%[dst],%[src]\n"
252 " brc 1,0b\n"
253 : [src] "+a" (r2), [len] "+d" (r3), [dst] "+a" (r4)
254 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KM)
255 : "cc", "memory");
256
257 return src_len - r3;
258}
259
260
261
262
263
264
265
266
267
268
269
270
271static inline int cpacf_kmc(unsigned long func, void *param,
272 u8 *dest, const u8 *src, long src_len)
273{
274 register unsigned long r0 asm("0") = (unsigned long) func;
275 register unsigned long r1 asm("1") = (unsigned long) param;
276 register unsigned long r2 asm("2") = (unsigned long) src;
277 register unsigned long r3 asm("3") = (unsigned long) src_len;
278 register unsigned long r4 asm("4") = (unsigned long) dest;
279
280 asm volatile(
281 "0: .insn rre,%[opc] << 16,%[dst],%[src]\n"
282 " brc 1,0b\n"
283 : [src] "+a" (r2), [len] "+d" (r3), [dst] "+a" (r4)
284 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMC)
285 : "cc", "memory");
286
287 return src_len - r3;
288}
289
290
291
292
293
294
295
296
297
298static inline void cpacf_kimd(unsigned long func, void *param,
299 const u8 *src, long src_len)
300{
301 register unsigned long r0 asm("0") = (unsigned long) func;
302 register unsigned long r1 asm("1") = (unsigned long) param;
303 register unsigned long r2 asm("2") = (unsigned long) src;
304 register unsigned long r3 asm("3") = (unsigned long) src_len;
305
306 asm volatile(
307 "0: .insn rre,%[opc] << 16,0,%[src]\n"
308 " brc 1,0b\n"
309 : [src] "+a" (r2), [len] "+d" (r3)
310 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KIMD)
311 : "cc", "memory");
312}
313
314
315
316
317
318
319
320
321static inline void cpacf_klmd(unsigned long func, void *param,
322 const u8 *src, long src_len)
323{
324 register unsigned long r0 asm("0") = (unsigned long) func;
325 register unsigned long r1 asm("1") = (unsigned long) param;
326 register unsigned long r2 asm("2") = (unsigned long) src;
327 register unsigned long r3 asm("3") = (unsigned long) src_len;
328
329 asm volatile(
330 "0: .insn rre,%[opc] << 16,0,%[src]\n"
331 " brc 1,0b\n"
332 : [src] "+a" (r2), [len] "+d" (r3)
333 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KLMD)
334 : "cc", "memory");
335}
336
337
338
339
340
341
342
343
344
345
346
347static inline int cpacf_kmac(unsigned long func, void *param,
348 const u8 *src, long src_len)
349{
350 register unsigned long r0 asm("0") = (unsigned long) func;
351 register unsigned long r1 asm("1") = (unsigned long) param;
352 register unsigned long r2 asm("2") = (unsigned long) src;
353 register unsigned long r3 asm("3") = (unsigned long) src_len;
354
355 asm volatile(
356 "0: .insn rre,%[opc] << 16,0,%[src]\n"
357 " brc 1,0b\n"
358 : [src] "+a" (r2), [len] "+d" (r3)
359 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMAC)
360 : "cc", "memory");
361
362 return src_len - r3;
363}
364
365
366
367
368
369
370
371
372
373
374
375
376
377static inline int cpacf_kmctr(unsigned long func, void *param, u8 *dest,
378 const u8 *src, long src_len, u8 *counter)
379{
380 register unsigned long r0 asm("0") = (unsigned long) func;
381 register unsigned long r1 asm("1") = (unsigned long) param;
382 register unsigned long r2 asm("2") = (unsigned long) src;
383 register unsigned long r3 asm("3") = (unsigned long) src_len;
384 register unsigned long r4 asm("4") = (unsigned long) dest;
385 register unsigned long r6 asm("6") = (unsigned long) counter;
386
387 asm volatile(
388 "0: .insn rrf,%[opc] << 16,%[dst],%[src],%[ctr],0\n"
389 " brc 1,0b\n"
390 : [src] "+a" (r2), [len] "+d" (r3),
391 [dst] "+a" (r4), [ctr] "+a" (r6)
392 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMCTR)
393 : "cc", "memory");
394
395 return src_len - r3;
396}
397
398
399
400
401
402
403
404
405
406
407
408static inline void cpacf_prno(unsigned long func, void *param,
409 u8 *dest, unsigned long dest_len,
410 const u8 *seed, unsigned long seed_len)
411{
412 register unsigned long r0 asm("0") = (unsigned long) func;
413 register unsigned long r1 asm("1") = (unsigned long) param;
414 register unsigned long r2 asm("2") = (unsigned long) dest;
415 register unsigned long r3 asm("3") = (unsigned long) dest_len;
416 register unsigned long r4 asm("4") = (unsigned long) seed;
417 register unsigned long r5 asm("5") = (unsigned long) seed_len;
418
419 asm volatile (
420 "0: .insn rre,%[opc] << 16,%[dst],%[seed]\n"
421 " brc 1,0b\n"
422 : [dst] "+a" (r2), [dlen] "+d" (r3)
423 : [fc] "d" (r0), [pba] "a" (r1),
424 [seed] "a" (r4), [slen] "d" (r5), [opc] "i" (CPACF_PRNO)
425 : "cc", "memory");
426}
427
428
429
430
431
432
433
434
435static inline void cpacf_trng(u8 *ucbuf, unsigned long ucbuf_len,
436 u8 *cbuf, unsigned long cbuf_len)
437{
438 register unsigned long r0 asm("0") = (unsigned long) CPACF_PRNO_TRNG;
439 register unsigned long r2 asm("2") = (unsigned long) ucbuf;
440 register unsigned long r3 asm("3") = (unsigned long) ucbuf_len;
441 register unsigned long r4 asm("4") = (unsigned long) cbuf;
442 register unsigned long r5 asm("5") = (unsigned long) cbuf_len;
443
444 asm volatile (
445 "0: .insn rre,%[opc] << 16,%[ucbuf],%[cbuf]\n"
446 " brc 1,0b\n"
447 : [ucbuf] "+a" (r2), [ucbuflen] "+d" (r3),
448 [cbuf] "+a" (r4), [cbuflen] "+d" (r5)
449 : [fc] "d" (r0), [opc] "i" (CPACF_PRNO)
450 : "cc", "memory");
451}
452
453
454
455
456
457
458
459static inline void cpacf_pcc(unsigned long func, void *param)
460{
461 register unsigned long r0 asm("0") = (unsigned long) func;
462 register unsigned long r1 asm("1") = (unsigned long) param;
463
464 asm volatile(
465 "0: .insn rre,%[opc] << 16,0,0\n"
466 " brc 1,0b\n"
467 :
468 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_PCC)
469 : "cc", "memory");
470}
471
472
473
474
475
476
477
478
479
480static inline void cpacf_pckmo(long func, void *param)
481{
482 register unsigned long r0 asm("0") = (unsigned long) func;
483 register unsigned long r1 asm("1") = (unsigned long) param;
484
485 asm volatile(
486 " .insn rre,%[opc] << 16,0,0\n"
487 :
488 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_PCKMO)
489 : "cc", "memory");
490}
491
492
493
494
495
496
497
498
499
500
501
502
503static inline void cpacf_kma(unsigned long func, void *param, u8 *dest,
504 const u8 *src, unsigned long src_len,
505 const u8 *aad, unsigned long aad_len)
506{
507 register unsigned long r0 asm("0") = (unsigned long) func;
508 register unsigned long r1 asm("1") = (unsigned long) param;
509 register unsigned long r2 asm("2") = (unsigned long) src;
510 register unsigned long r3 asm("3") = (unsigned long) src_len;
511 register unsigned long r4 asm("4") = (unsigned long) aad;
512 register unsigned long r5 asm("5") = (unsigned long) aad_len;
513 register unsigned long r6 asm("6") = (unsigned long) dest;
514
515 asm volatile(
516 "0: .insn rrf,%[opc] << 16,%[dst],%[src],%[aad],0\n"
517 " brc 1,0b\n"
518 : [dst] "+a" (r6), [src] "+a" (r2), [slen] "+d" (r3),
519 [aad] "+a" (r4), [alen] "+d" (r5)
520 : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMA)
521 : "cc", "memory");
522}
523
524#endif
525