0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef _ASM_S390_CPACF_H
0012 #define _ASM_S390_CPACF_H
0013
0014 #include <asm/facility.h>
0015
0016
0017
0018
0019 #define CPACF_KMAC 0xb91e
0020 #define CPACF_KM 0xb92e
0021 #define CPACF_KMC 0xb92f
0022 #define CPACF_KIMD 0xb93e
0023 #define CPACF_KLMD 0xb93f
0024 #define CPACF_PCKMO 0xb928
0025 #define CPACF_KMF 0xb92a
0026 #define CPACF_KMO 0xb92b
0027 #define CPACF_PCC 0xb92c
0028 #define CPACF_KMCTR 0xb92d
0029 #define CPACF_PRNO 0xb93c
0030 #define CPACF_KMA 0xb929
0031 #define CPACF_KDSA 0xb93a
0032
0033
0034
0035
0036 #define CPACF_ENCRYPT 0x00
0037 #define CPACF_DECRYPT 0x80
0038
0039
0040
0041
0042 #define CPACF_KM_QUERY 0x00
0043 #define CPACF_KM_DEA 0x01
0044 #define CPACF_KM_TDEA_128 0x02
0045 #define CPACF_KM_TDEA_192 0x03
0046 #define CPACF_KM_AES_128 0x12
0047 #define CPACF_KM_AES_192 0x13
0048 #define CPACF_KM_AES_256 0x14
0049 #define CPACF_KM_PAES_128 0x1a
0050 #define CPACF_KM_PAES_192 0x1b
0051 #define CPACF_KM_PAES_256 0x1c
0052 #define CPACF_KM_XTS_128 0x32
0053 #define CPACF_KM_XTS_256 0x34
0054 #define CPACF_KM_PXTS_128 0x3a
0055 #define CPACF_KM_PXTS_256 0x3c
0056
0057
0058
0059
0060
0061 #define CPACF_KMC_QUERY 0x00
0062 #define CPACF_KMC_DEA 0x01
0063 #define CPACF_KMC_TDEA_128 0x02
0064 #define CPACF_KMC_TDEA_192 0x03
0065 #define CPACF_KMC_AES_128 0x12
0066 #define CPACF_KMC_AES_192 0x13
0067 #define CPACF_KMC_AES_256 0x14
0068 #define CPACF_KMC_PAES_128 0x1a
0069 #define CPACF_KMC_PAES_192 0x1b
0070 #define CPACF_KMC_PAES_256 0x1c
0071 #define CPACF_KMC_PRNG 0x43
0072
0073
0074
0075
0076
0077 #define CPACF_KMCTR_QUERY 0x00
0078 #define CPACF_KMCTR_DEA 0x01
0079 #define CPACF_KMCTR_TDEA_128 0x02
0080 #define CPACF_KMCTR_TDEA_192 0x03
0081 #define CPACF_KMCTR_AES_128 0x12
0082 #define CPACF_KMCTR_AES_192 0x13
0083 #define CPACF_KMCTR_AES_256 0x14
0084 #define CPACF_KMCTR_PAES_128 0x1a
0085 #define CPACF_KMCTR_PAES_192 0x1b
0086 #define CPACF_KMCTR_PAES_256 0x1c
0087
0088
0089
0090
0091
0092 #define CPACF_KIMD_QUERY 0x00
0093 #define CPACF_KIMD_SHA_1 0x01
0094 #define CPACF_KIMD_SHA_256 0x02
0095 #define CPACF_KIMD_SHA_512 0x03
0096 #define CPACF_KIMD_SHA3_224 0x20
0097 #define CPACF_KIMD_SHA3_256 0x21
0098 #define CPACF_KIMD_SHA3_384 0x22
0099 #define CPACF_KIMD_SHA3_512 0x23
0100 #define CPACF_KIMD_GHASH 0x41
0101
0102
0103
0104
0105
0106 #define CPACF_KLMD_QUERY 0x00
0107 #define CPACF_KLMD_SHA_1 0x01
0108 #define CPACF_KLMD_SHA_256 0x02
0109 #define CPACF_KLMD_SHA_512 0x03
0110 #define CPACF_KLMD_SHA3_224 0x20
0111 #define CPACF_KLMD_SHA3_256 0x21
0112 #define CPACF_KLMD_SHA3_384 0x22
0113 #define CPACF_KLMD_SHA3_512 0x23
0114
0115
0116
0117
0118
0119 #define CPACF_KMAC_QUERY 0x00
0120 #define CPACF_KMAC_DEA 0x01
0121 #define CPACF_KMAC_TDEA_128 0x02
0122 #define CPACF_KMAC_TDEA_192 0x03
0123
0124
0125
0126
0127
0128 #define CPACF_PCKMO_QUERY 0x00
0129 #define CPACF_PCKMO_ENC_DES_KEY 0x01
0130 #define CPACF_PCKMO_ENC_TDES_128_KEY 0x02
0131 #define CPACF_PCKMO_ENC_TDES_192_KEY 0x03
0132 #define CPACF_PCKMO_ENC_AES_128_KEY 0x12
0133 #define CPACF_PCKMO_ENC_AES_192_KEY 0x13
0134 #define CPACF_PCKMO_ENC_AES_256_KEY 0x14
0135
0136
0137
0138
0139
0140 #define CPACF_PRNO_QUERY 0x00
0141 #define CPACF_PRNO_SHA512_DRNG_GEN 0x03
0142 #define CPACF_PRNO_SHA512_DRNG_SEED 0x83
0143 #define CPACF_PRNO_TRNG_Q_R2C_RATIO 0x70
0144 #define CPACF_PRNO_TRNG 0x72
0145
0146
0147
0148
0149
0150 #define CPACF_KMA_QUERY 0x00
0151 #define CPACF_KMA_GCM_AES_128 0x12
0152 #define CPACF_KMA_GCM_AES_192 0x13
0153 #define CPACF_KMA_GCM_AES_256 0x14
0154
0155
0156
0157
0158 #define CPACF_KMA_LPC 0x100
0159 #define CPACF_KMA_LAAD 0x200
0160 #define CPACF_KMA_HS 0x400
0161
0162 typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174 static __always_inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
0175 {
0176 asm volatile(
0177 " lghi 0,0\n"
0178 " lgr 1,%[mask]\n"
0179 " spm 0\n"
0180
0181 "0: .insn rrf,%[opc] << 16,2,4,6,0\n"
0182 " brc 1,0b\n"
0183 : "=m" (*mask)
0184 : [mask] "d" ((unsigned long)mask), [opc] "i" (opcode)
0185 : "cc", "0", "1");
0186 }
0187
0188 static __always_inline int __cpacf_check_opcode(unsigned int opcode)
0189 {
0190 switch (opcode) {
0191 case CPACF_KMAC:
0192 case CPACF_KM:
0193 case CPACF_KMC:
0194 case CPACF_KIMD:
0195 case CPACF_KLMD:
0196 return test_facility(17);
0197 case CPACF_PCKMO:
0198 return test_facility(76);
0199 case CPACF_KMF:
0200 case CPACF_KMO:
0201 case CPACF_PCC:
0202 case CPACF_KMCTR:
0203 return test_facility(77);
0204 case CPACF_PRNO:
0205 return test_facility(57);
0206 case CPACF_KMA:
0207 return test_facility(146);
0208 default:
0209 BUG();
0210 }
0211 }
0212
0213 static __always_inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
0214 {
0215 if (__cpacf_check_opcode(opcode)) {
0216 __cpacf_query(opcode, mask);
0217 return 1;
0218 }
0219 memset(mask, 0, sizeof(*mask));
0220 return 0;
0221 }
0222
0223 static inline int cpacf_test_func(cpacf_mask_t *mask, unsigned int func)
0224 {
0225 return (mask->bytes[func >> 3] & (0x80 >> (func & 7))) != 0;
0226 }
0227
0228 static __always_inline int cpacf_query_func(unsigned int opcode, unsigned int func)
0229 {
0230 cpacf_mask_t mask;
0231
0232 if (cpacf_query(opcode, &mask))
0233 return cpacf_test_func(&mask, func);
0234 return 0;
0235 }
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 static inline int cpacf_km(unsigned long func, void *param,
0249 u8 *dest, const u8 *src, long src_len)
0250 {
0251 union register_pair d, s;
0252
0253 d.even = (unsigned long)dest;
0254 s.even = (unsigned long)src;
0255 s.odd = (unsigned long)src_len;
0256 asm volatile(
0257 " lgr 0,%[fc]\n"
0258 " lgr 1,%[pba]\n"
0259 "0: .insn rre,%[opc] << 16,%[dst],%[src]\n"
0260 " brc 1,0b\n"
0261 : [src] "+&d" (s.pair), [dst] "+&d" (d.pair)
0262 : [fc] "d" (func), [pba] "d" ((unsigned long)param),
0263 [opc] "i" (CPACF_KM)
0264 : "cc", "memory", "0", "1");
0265
0266 return src_len - s.odd;
0267 }
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 static inline int cpacf_kmc(unsigned long func, void *param,
0281 u8 *dest, const u8 *src, long src_len)
0282 {
0283 union register_pair d, s;
0284
0285 d.even = (unsigned long)dest;
0286 s.even = (unsigned long)src;
0287 s.odd = (unsigned long)src_len;
0288 asm volatile(
0289 " lgr 0,%[fc]\n"
0290 " lgr 1,%[pba]\n"
0291 "0: .insn rre,%[opc] << 16,%[dst],%[src]\n"
0292 " brc 1,0b\n"
0293 : [src] "+&d" (s.pair), [dst] "+&d" (d.pair)
0294 : [fc] "d" (func), [pba] "d" ((unsigned long)param),
0295 [opc] "i" (CPACF_KMC)
0296 : "cc", "memory", "0", "1");
0297
0298 return src_len - s.odd;
0299 }
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309 static inline void cpacf_kimd(unsigned long func, void *param,
0310 const u8 *src, long src_len)
0311 {
0312 union register_pair s;
0313
0314 s.even = (unsigned long)src;
0315 s.odd = (unsigned long)src_len;
0316 asm volatile(
0317 " lgr 0,%[fc]\n"
0318 " lgr 1,%[pba]\n"
0319 "0: .insn rre,%[opc] << 16,0,%[src]\n"
0320 " brc 1,0b\n"
0321 : [src] "+&d" (s.pair)
0322 : [fc] "d" (func), [pba] "d" ((unsigned long)(param)),
0323 [opc] "i" (CPACF_KIMD)
0324 : "cc", "memory", "0", "1");
0325 }
0326
0327
0328
0329
0330
0331
0332
0333
0334 static inline void cpacf_klmd(unsigned long func, void *param,
0335 const u8 *src, long src_len)
0336 {
0337 union register_pair s;
0338
0339 s.even = (unsigned long)src;
0340 s.odd = (unsigned long)src_len;
0341 asm volatile(
0342 " lgr 0,%[fc]\n"
0343 " lgr 1,%[pba]\n"
0344 "0: .insn rre,%[opc] << 16,0,%[src]\n"
0345 " brc 1,0b\n"
0346 : [src] "+&d" (s.pair)
0347 : [fc] "d" (func), [pba] "d" ((unsigned long)param),
0348 [opc] "i" (CPACF_KLMD)
0349 : "cc", "memory", "0", "1");
0350 }
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362 static inline int cpacf_kmac(unsigned long func, void *param,
0363 const u8 *src, long src_len)
0364 {
0365 union register_pair s;
0366
0367 s.even = (unsigned long)src;
0368 s.odd = (unsigned long)src_len;
0369 asm volatile(
0370 " lgr 0,%[fc]\n"
0371 " lgr 1,%[pba]\n"
0372 "0: .insn rre,%[opc] << 16,0,%[src]\n"
0373 " brc 1,0b\n"
0374 : [src] "+&d" (s.pair)
0375 : [fc] "d" (func), [pba] "d" ((unsigned long)param),
0376 [opc] "i" (CPACF_KMAC)
0377 : "cc", "memory", "0", "1");
0378
0379 return src_len - s.odd;
0380 }
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 static inline int cpacf_kmctr(unsigned long func, void *param, u8 *dest,
0395 const u8 *src, long src_len, u8 *counter)
0396 {
0397 union register_pair d, s, c;
0398
0399 d.even = (unsigned long)dest;
0400 s.even = (unsigned long)src;
0401 s.odd = (unsigned long)src_len;
0402 c.even = (unsigned long)counter;
0403 asm volatile(
0404 " lgr 0,%[fc]\n"
0405 " lgr 1,%[pba]\n"
0406 "0: .insn rrf,%[opc] << 16,%[dst],%[src],%[ctr],0\n"
0407 " brc 1,0b\n"
0408 : [src] "+&d" (s.pair), [dst] "+&d" (d.pair),
0409 [ctr] "+&d" (c.pair)
0410 : [fc] "d" (func), [pba] "d" ((unsigned long)param),
0411 [opc] "i" (CPACF_KMCTR)
0412 : "cc", "memory", "0", "1");
0413
0414 return src_len - s.odd;
0415 }
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427 static inline void cpacf_prno(unsigned long func, void *param,
0428 u8 *dest, unsigned long dest_len,
0429 const u8 *seed, unsigned long seed_len)
0430 {
0431 union register_pair d, s;
0432
0433 d.even = (unsigned long)dest;
0434 d.odd = (unsigned long)dest_len;
0435 s.even = (unsigned long)seed;
0436 s.odd = (unsigned long)seed_len;
0437 asm volatile (
0438 " lgr 0,%[fc]\n"
0439 " lgr 1,%[pba]\n"
0440 "0: .insn rre,%[opc] << 16,%[dst],%[seed]\n"
0441 " brc 1,0b\n"
0442 : [dst] "+&d" (d.pair)
0443 : [fc] "d" (func), [pba] "d" ((unsigned long)param),
0444 [seed] "d" (s.pair), [opc] "i" (CPACF_PRNO)
0445 : "cc", "memory", "0", "1");
0446 }
0447
0448
0449
0450
0451
0452
0453
0454
0455 static inline void cpacf_trng(u8 *ucbuf, unsigned long ucbuf_len,
0456 u8 *cbuf, unsigned long cbuf_len)
0457 {
0458 union register_pair u, c;
0459
0460 u.even = (unsigned long)ucbuf;
0461 u.odd = (unsigned long)ucbuf_len;
0462 c.even = (unsigned long)cbuf;
0463 c.odd = (unsigned long)cbuf_len;
0464 asm volatile (
0465 " lghi 0,%[fc]\n"
0466 "0: .insn rre,%[opc] << 16,%[ucbuf],%[cbuf]\n"
0467 " brc 1,0b\n"
0468 : [ucbuf] "+&d" (u.pair), [cbuf] "+&d" (c.pair)
0469 : [fc] "K" (CPACF_PRNO_TRNG), [opc] "i" (CPACF_PRNO)
0470 : "cc", "memory", "0");
0471 }
0472
0473
0474
0475
0476
0477
0478
0479 static inline void cpacf_pcc(unsigned long func, void *param)
0480 {
0481 asm volatile(
0482 " lgr 0,%[fc]\n"
0483 " lgr 1,%[pba]\n"
0484 "0: .insn rre,%[opc] << 16,0,0\n"
0485 " brc 1,0b\n"
0486 :
0487 : [fc] "d" (func), [pba] "d" ((unsigned long)param),
0488 [opc] "i" (CPACF_PCC)
0489 : "cc", "memory", "0", "1");
0490 }
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500 static inline void cpacf_pckmo(long func, void *param)
0501 {
0502 asm volatile(
0503 " lgr 0,%[fc]\n"
0504 " lgr 1,%[pba]\n"
0505 " .insn rre,%[opc] << 16,0,0\n"
0506 :
0507 : [fc] "d" (func), [pba] "d" ((unsigned long)param),
0508 [opc] "i" (CPACF_PCKMO)
0509 : "cc", "memory", "0", "1");
0510 }
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523 static inline void cpacf_kma(unsigned long func, void *param, u8 *dest,
0524 const u8 *src, unsigned long src_len,
0525 const u8 *aad, unsigned long aad_len)
0526 {
0527 union register_pair d, s, a;
0528
0529 d.even = (unsigned long)dest;
0530 s.even = (unsigned long)src;
0531 s.odd = (unsigned long)src_len;
0532 a.even = (unsigned long)aad;
0533 a.odd = (unsigned long)aad_len;
0534 asm volatile(
0535 " lgr 0,%[fc]\n"
0536 " lgr 1,%[pba]\n"
0537 "0: .insn rrf,%[opc] << 16,%[dst],%[src],%[aad],0\n"
0538 " brc 1,0b\n"
0539 : [dst] "+&d" (d.pair), [src] "+&d" (s.pair),
0540 [aad] "+&d" (a.pair)
0541 : [fc] "d" (func), [pba] "d" ((unsigned long)param),
0542 [opc] "i" (CPACF_KMA)
0543 : "cc", "memory", "0", "1");
0544 }
0545
0546 #endif