1*c7d4d259SMartin Schwidefsky /* 2*c7d4d259SMartin Schwidefsky * CP Assist for Cryptographic Functions (CPACF) 3*c7d4d259SMartin Schwidefsky * 4*c7d4d259SMartin Schwidefsky * Copyright IBM Corp. 2003, 2016 5*c7d4d259SMartin Schwidefsky * Author(s): Thomas Spatzier 6*c7d4d259SMartin Schwidefsky * Jan Glauber 7*c7d4d259SMartin Schwidefsky * Harald Freudenberger (freude@de.ibm.com) 8*c7d4d259SMartin Schwidefsky * Martin Schwidefsky <schwidefsky@de.ibm.com> 9*c7d4d259SMartin Schwidefsky */ 10*c7d4d259SMartin Schwidefsky #ifndef _ASM_S390_CPACF_H 11*c7d4d259SMartin Schwidefsky #define _ASM_S390_CPACF_H 12*c7d4d259SMartin Schwidefsky 13*c7d4d259SMartin Schwidefsky #include <asm/facility.h> 14*c7d4d259SMartin Schwidefsky 15*c7d4d259SMartin Schwidefsky /* 16*c7d4d259SMartin Schwidefsky * Instruction opcodes for the CPACF instructions 17*c7d4d259SMartin Schwidefsky */ 18*c7d4d259SMartin Schwidefsky #define CPACF_KMAC 0xb91e /* MSA */ 19*c7d4d259SMartin Schwidefsky #define CPACF_KM 0xb92e /* MSA */ 20*c7d4d259SMartin Schwidefsky #define CPACF_KMC 0xb92f /* MSA */ 21*c7d4d259SMartin Schwidefsky #define CPACF_KIMD 0xb93e /* MSA */ 22*c7d4d259SMartin Schwidefsky #define CPACF_KLMD 0xb93f /* MSA */ 23*c7d4d259SMartin Schwidefsky #define CPACF_PCC 0xb92c /* MSA4 */ 24*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR 0xb92d /* MSA4 */ 25*c7d4d259SMartin Schwidefsky #define CPACF_PPNO 0xb93c /* MSA5 */ 26*c7d4d259SMartin Schwidefsky 27*c7d4d259SMartin Schwidefsky /* 28*c7d4d259SMartin Schwidefsky * Function codes for the KM (CIPHER MESSAGE) 29*c7d4d259SMartin Schwidefsky * instruction (0x80 is the decipher modifier bit) 30*c7d4d259SMartin Schwidefsky */ 31*c7d4d259SMartin Schwidefsky #define CPACF_KM_QUERY 0x00 32*c7d4d259SMartin Schwidefsky #define CPACF_KM_DEA_ENC 0x01 33*c7d4d259SMartin Schwidefsky #define CPACF_KM_DEA_DEC 0x81 34*c7d4d259SMartin Schwidefsky #define CPACF_KM_TDEA_128_ENC 0x02 35*c7d4d259SMartin Schwidefsky #define CPACF_KM_TDEA_128_DEC 0x82 36*c7d4d259SMartin Schwidefsky #define CPACF_KM_TDEA_192_ENC 0x03 37*c7d4d259SMartin Schwidefsky #define CPACF_KM_TDEA_192_DEC 0x83 38*c7d4d259SMartin Schwidefsky #define CPACF_KM_AES_128_ENC 0x12 39*c7d4d259SMartin Schwidefsky #define CPACF_KM_AES_128_DEC 0x92 40*c7d4d259SMartin Schwidefsky #define CPACF_KM_AES_192_ENC 0x13 41*c7d4d259SMartin Schwidefsky #define CPACF_KM_AES_192_DEC 0x93 42*c7d4d259SMartin Schwidefsky #define CPACF_KM_AES_256_ENC 0x14 43*c7d4d259SMartin Schwidefsky #define CPACF_KM_AES_256_DEC 0x94 44*c7d4d259SMartin Schwidefsky #define CPACF_KM_XTS_128_ENC 0x32 45*c7d4d259SMartin Schwidefsky #define CPACF_KM_XTS_128_DEC 0xb2 46*c7d4d259SMartin Schwidefsky #define CPACF_KM_XTS_256_ENC 0x34 47*c7d4d259SMartin Schwidefsky #define CPACF_KM_XTS_256_DEC 0xb4 48*c7d4d259SMartin Schwidefsky 49*c7d4d259SMartin Schwidefsky /* 50*c7d4d259SMartin Schwidefsky * Function codes for the KMC (CIPHER MESSAGE WITH CHAINING) 51*c7d4d259SMartin Schwidefsky * instruction (0x80 is the decipher modifier bit) 52*c7d4d259SMartin Schwidefsky */ 53*c7d4d259SMartin Schwidefsky #define CPACF_KMC_QUERY 0x00 54*c7d4d259SMartin Schwidefsky #define CPACF_KMC_DEA_ENC 0x01 55*c7d4d259SMartin Schwidefsky #define CPACF_KMC_DEA_DEC 0x81 56*c7d4d259SMartin Schwidefsky #define CPACF_KMC_TDEA_128_ENC 0x02 57*c7d4d259SMartin Schwidefsky #define CPACF_KMC_TDEA_128_DEC 0x82 58*c7d4d259SMartin Schwidefsky #define CPACF_KMC_TDEA_192_ENC 0x03 59*c7d4d259SMartin Schwidefsky #define CPACF_KMC_TDEA_192_DEC 0x83 60*c7d4d259SMartin Schwidefsky #define CPACF_KMC_AES_128_ENC 0x12 61*c7d4d259SMartin Schwidefsky #define CPACF_KMC_AES_128_DEC 0x92 62*c7d4d259SMartin Schwidefsky #define CPACF_KMC_AES_192_ENC 0x13 63*c7d4d259SMartin Schwidefsky #define CPACF_KMC_AES_192_DEC 0x93 64*c7d4d259SMartin Schwidefsky #define CPACF_KMC_AES_256_ENC 0x14 65*c7d4d259SMartin Schwidefsky #define CPACF_KMC_AES_256_DEC 0x94 66*c7d4d259SMartin Schwidefsky #define CPACF_KMC_PRNG 0x43 67*c7d4d259SMartin Schwidefsky 68*c7d4d259SMartin Schwidefsky /* 69*c7d4d259SMartin Schwidefsky * Function codes for the KMCTR (CIPHER MESSAGE WITH COUNTER) 70*c7d4d259SMartin Schwidefsky * instruction (0x80 is the decipher modifier bit) 71*c7d4d259SMartin Schwidefsky */ 72*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_QUERY 0x00 73*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_DEA_ENC 0x01 74*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_DEA_DEC 0x81 75*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_TDEA_128_ENC 0x02 76*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_TDEA_128_DEC 0x82 77*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_TDEA_192_ENC 0x03 78*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_TDEA_192_DEC 0x83 79*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_AES_128_ENC 0x12 80*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_AES_128_DEC 0x92 81*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_AES_192_ENC 0x13 82*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_AES_192_DEC 0x93 83*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_AES_256_ENC 0x14 84*c7d4d259SMartin Schwidefsky #define CPACF_KMCTR_AES_256_DEC 0x94 85*c7d4d259SMartin Schwidefsky 86*c7d4d259SMartin Schwidefsky /* 87*c7d4d259SMartin Schwidefsky * Function codes for the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) 88*c7d4d259SMartin Schwidefsky * instruction (0x80 is the decipher modifier bit) 89*c7d4d259SMartin Schwidefsky */ 90*c7d4d259SMartin Schwidefsky #define CPACF_KIMD_QUERY 0x00 91*c7d4d259SMartin Schwidefsky #define CPACF_KIMD_SHA_1 0x01 92*c7d4d259SMartin Schwidefsky #define CPACF_KIMD_SHA_256 0x02 93*c7d4d259SMartin Schwidefsky #define CPACF_KIMD_SHA_512 0x03 94*c7d4d259SMartin Schwidefsky #define CPACF_KIMD_GHASH 0x41 95*c7d4d259SMartin Schwidefsky 96*c7d4d259SMartin Schwidefsky /* 97*c7d4d259SMartin Schwidefsky * Function codes for the KLMD (COMPUTE LAST MESSAGE DIGEST) 98*c7d4d259SMartin Schwidefsky * instruction (0x80 is the decipher modifier bit) 99*c7d4d259SMartin Schwidefsky */ 100*c7d4d259SMartin Schwidefsky #define CPACF_KLMD_QUERY 0x00 101*c7d4d259SMartin Schwidefsky #define CPACF_KLMD_SHA_1 0x01 102*c7d4d259SMartin Schwidefsky #define CPACF_KLMD_SHA_256 0x02 103*c7d4d259SMartin Schwidefsky #define CPACF_KLMD_SHA_512 0x03 104*c7d4d259SMartin Schwidefsky 105*c7d4d259SMartin Schwidefsky /* 106*c7d4d259SMartin Schwidefsky * function codes for the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) 107*c7d4d259SMartin Schwidefsky * instruction (0x80 is the decipher modifier bit) 108*c7d4d259SMartin Schwidefsky */ 109*c7d4d259SMartin Schwidefsky #define CPACF_KMAC_QUERY 0x00 110*c7d4d259SMartin Schwidefsky #define CPACF_KMAC_DEA 0x01 111*c7d4d259SMartin Schwidefsky #define CPACF_KMAC_TDEA_128 0x02 112*c7d4d259SMartin Schwidefsky #define CPACF_KMAC_TDEA_192 0x03 113*c7d4d259SMartin Schwidefsky 114*c7d4d259SMartin Schwidefsky /* 115*c7d4d259SMartin Schwidefsky * Function codes for the PPNO (PERFORM PSEUDORANDOM NUMBER OPERATION) 116*c7d4d259SMartin Schwidefsky * instruction (0x80 is the decipher modifier bit) 117*c7d4d259SMartin Schwidefsky */ 118*c7d4d259SMartin Schwidefsky #define CPACF_PPNO_QUERY 0x00 119*c7d4d259SMartin Schwidefsky #define CPACF_PPNO_SHA512_DRNG_GEN 0x03 120*c7d4d259SMartin Schwidefsky #define CPACF_PPNO_SHA512_DRNG_SEED 0x83 121*c7d4d259SMartin Schwidefsky 122*c7d4d259SMartin Schwidefsky /** 123*c7d4d259SMartin Schwidefsky * cpacf_query() - check if a specific CPACF function is available 124*c7d4d259SMartin Schwidefsky * @opcode: the opcode of the crypto instruction 125*c7d4d259SMartin Schwidefsky * @func: the function code to test for 126*c7d4d259SMartin Schwidefsky * 127*c7d4d259SMartin Schwidefsky * Executes the query function for the given crypto instruction @opcode 128*c7d4d259SMartin Schwidefsky * and checks if @func is available 129*c7d4d259SMartin Schwidefsky * 130*c7d4d259SMartin Schwidefsky * Returns 1 if @func is available for @opcode, 0 otherwise 131*c7d4d259SMartin Schwidefsky */ 132*c7d4d259SMartin Schwidefsky static inline void __cpacf_query(unsigned int opcode, unsigned char *status) 133*c7d4d259SMartin Schwidefsky { 134*c7d4d259SMartin Schwidefsky typedef struct { unsigned char _[16]; } status_type; 135*c7d4d259SMartin Schwidefsky register unsigned long r0 asm("0") = 0; /* query function */ 136*c7d4d259SMartin Schwidefsky register unsigned long r1 asm("1") = (unsigned long) status; 137*c7d4d259SMartin Schwidefsky 138*c7d4d259SMartin Schwidefsky asm volatile( 139*c7d4d259SMartin Schwidefsky /* Parameter registers are ignored, but may not be 0 */ 140*c7d4d259SMartin Schwidefsky "0: .insn rrf,%[opc] << 16,2,2,2,0\n" 141*c7d4d259SMartin Schwidefsky " brc 1,0b\n" /* handle partial completion */ 142*c7d4d259SMartin Schwidefsky : "=m" (*(status_type *) status) 143*c7d4d259SMartin Schwidefsky : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (opcode) 144*c7d4d259SMartin Schwidefsky : "cc"); 145*c7d4d259SMartin Schwidefsky } 146*c7d4d259SMartin Schwidefsky 147*c7d4d259SMartin Schwidefsky static inline int cpacf_query(unsigned int opcode, unsigned int func) 148*c7d4d259SMartin Schwidefsky { 149*c7d4d259SMartin Schwidefsky unsigned char status[16]; 150*c7d4d259SMartin Schwidefsky 151*c7d4d259SMartin Schwidefsky switch (opcode) { 152*c7d4d259SMartin Schwidefsky case CPACF_KMAC: 153*c7d4d259SMartin Schwidefsky case CPACF_KM: 154*c7d4d259SMartin Schwidefsky case CPACF_KMC: 155*c7d4d259SMartin Schwidefsky case CPACF_KIMD: 156*c7d4d259SMartin Schwidefsky case CPACF_KLMD: 157*c7d4d259SMartin Schwidefsky if (!test_facility(17)) /* check for MSA */ 158*c7d4d259SMartin Schwidefsky return 0; 159*c7d4d259SMartin Schwidefsky break; 160*c7d4d259SMartin Schwidefsky case CPACF_PCC: 161*c7d4d259SMartin Schwidefsky case CPACF_KMCTR: 162*c7d4d259SMartin Schwidefsky if (!test_facility(77)) /* check for MSA4 */ 163*c7d4d259SMartin Schwidefsky return 0; 164*c7d4d259SMartin Schwidefsky break; 165*c7d4d259SMartin Schwidefsky case CPACF_PPNO: 166*c7d4d259SMartin Schwidefsky if (!test_facility(57)) /* check for MSA5 */ 167*c7d4d259SMartin Schwidefsky return 0; 168*c7d4d259SMartin Schwidefsky break; 169*c7d4d259SMartin Schwidefsky default: 170*c7d4d259SMartin Schwidefsky BUG(); 171*c7d4d259SMartin Schwidefsky } 172*c7d4d259SMartin Schwidefsky __cpacf_query(opcode, status); 173*c7d4d259SMartin Schwidefsky return (status[func >> 3] & (0x80 >> (func & 7))) != 0; 174*c7d4d259SMartin Schwidefsky } 175*c7d4d259SMartin Schwidefsky 176*c7d4d259SMartin Schwidefsky /** 177*c7d4d259SMartin Schwidefsky * cpacf_km() - executes the KM (CIPHER MESSAGE) instruction 178*c7d4d259SMartin Schwidefsky * @func: the function code passed to KM; see CPACF_KM_xxx defines 179*c7d4d259SMartin Schwidefsky * @param: address of parameter block; see POP for details on each func 180*c7d4d259SMartin Schwidefsky * @dest: address of destination memory area 181*c7d4d259SMartin Schwidefsky * @src: address of source memory area 182*c7d4d259SMartin Schwidefsky * @src_len: length of src operand in bytes 183*c7d4d259SMartin Schwidefsky * 184*c7d4d259SMartin Schwidefsky * Returns 0 for the query func, number of processed bytes for 185*c7d4d259SMartin Schwidefsky * encryption/decryption funcs 186*c7d4d259SMartin Schwidefsky */ 187*c7d4d259SMartin Schwidefsky static inline int cpacf_km(long func, void *param, 188*c7d4d259SMartin Schwidefsky u8 *dest, const u8 *src, long src_len) 189*c7d4d259SMartin Schwidefsky { 190*c7d4d259SMartin Schwidefsky register unsigned long r0 asm("0") = (unsigned long) func; 191*c7d4d259SMartin Schwidefsky register unsigned long r1 asm("1") = (unsigned long) param; 192*c7d4d259SMartin Schwidefsky register unsigned long r2 asm("2") = (unsigned long) src; 193*c7d4d259SMartin Schwidefsky register unsigned long r3 asm("3") = (unsigned long) src_len; 194*c7d4d259SMartin Schwidefsky register unsigned long r4 asm("4") = (unsigned long) dest; 195*c7d4d259SMartin Schwidefsky 196*c7d4d259SMartin Schwidefsky asm volatile( 197*c7d4d259SMartin Schwidefsky "0: .insn rre,%[opc] << 16,%[dst],%[src]\n" 198*c7d4d259SMartin Schwidefsky " brc 1,0b\n" /* handle partial completion */ 199*c7d4d259SMartin Schwidefsky : [src] "+a" (r2), [len] "+d" (r3), [dst] "+a" (r4) 200*c7d4d259SMartin Schwidefsky : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KM) 201*c7d4d259SMartin Schwidefsky : "cc", "memory"); 202*c7d4d259SMartin Schwidefsky 203*c7d4d259SMartin Schwidefsky return src_len - r3; 204*c7d4d259SMartin Schwidefsky } 205*c7d4d259SMartin Schwidefsky 206*c7d4d259SMartin Schwidefsky /** 207*c7d4d259SMartin Schwidefsky * cpacf_kmc() - executes the KMC (CIPHER MESSAGE WITH CHAINING) instruction 208*c7d4d259SMartin Schwidefsky * @func: the function code passed to KM; see CPACF_KMC_xxx defines 209*c7d4d259SMartin Schwidefsky * @param: address of parameter block; see POP for details on each func 210*c7d4d259SMartin Schwidefsky * @dest: address of destination memory area 211*c7d4d259SMartin Schwidefsky * @src: address of source memory area 212*c7d4d259SMartin Schwidefsky * @src_len: length of src operand in bytes 213*c7d4d259SMartin Schwidefsky * 214*c7d4d259SMartin Schwidefsky * Returns 0 for the query func, number of processed bytes for 215*c7d4d259SMartin Schwidefsky * encryption/decryption funcs 216*c7d4d259SMartin Schwidefsky */ 217*c7d4d259SMartin Schwidefsky static inline int cpacf_kmc(long func, void *param, 218*c7d4d259SMartin Schwidefsky u8 *dest, const u8 *src, long src_len) 219*c7d4d259SMartin Schwidefsky { 220*c7d4d259SMartin Schwidefsky register unsigned long r0 asm("0") = (unsigned long) func; 221*c7d4d259SMartin Schwidefsky register unsigned long r1 asm("1") = (unsigned long) param; 222*c7d4d259SMartin Schwidefsky register unsigned long r2 asm("2") = (unsigned long) src; 223*c7d4d259SMartin Schwidefsky register unsigned long r3 asm("3") = (unsigned long) src_len; 224*c7d4d259SMartin Schwidefsky register unsigned long r4 asm("4") = (unsigned long) dest; 225*c7d4d259SMartin Schwidefsky 226*c7d4d259SMartin Schwidefsky asm volatile( 227*c7d4d259SMartin Schwidefsky "0: .insn rre,%[opc] << 16,%[dst],%[src]\n" 228*c7d4d259SMartin Schwidefsky " brc 1,0b\n" /* handle partial completion */ 229*c7d4d259SMartin Schwidefsky : [src] "+a" (r2), [len] "+d" (r3), [dst] "+a" (r4) 230*c7d4d259SMartin Schwidefsky : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMC) 231*c7d4d259SMartin Schwidefsky : "cc", "memory"); 232*c7d4d259SMartin Schwidefsky 233*c7d4d259SMartin Schwidefsky return src_len - r3; 234*c7d4d259SMartin Schwidefsky } 235*c7d4d259SMartin Schwidefsky 236*c7d4d259SMartin Schwidefsky /** 237*c7d4d259SMartin Schwidefsky * cpacf_kimd() - executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) 238*c7d4d259SMartin Schwidefsky * instruction 239*c7d4d259SMartin Schwidefsky * @func: the function code passed to KM; see CPACF_KIMD_xxx defines 240*c7d4d259SMartin Schwidefsky * @param: address of parameter block; see POP for details on each func 241*c7d4d259SMartin Schwidefsky * @src: address of source memory area 242*c7d4d259SMartin Schwidefsky * @src_len: length of src operand in bytes 243*c7d4d259SMartin Schwidefsky * 244*c7d4d259SMartin Schwidefsky * Returns 0 for the query func, number of processed bytes for digest funcs 245*c7d4d259SMartin Schwidefsky */ 246*c7d4d259SMartin Schwidefsky static inline int cpacf_kimd(long func, void *param, 247*c7d4d259SMartin Schwidefsky const u8 *src, long src_len) 248*c7d4d259SMartin Schwidefsky { 249*c7d4d259SMartin Schwidefsky register unsigned long r0 asm("0") = (unsigned long) func; 250*c7d4d259SMartin Schwidefsky register unsigned long r1 asm("1") = (unsigned long) param; 251*c7d4d259SMartin Schwidefsky register unsigned long r2 asm("2") = (unsigned long) src; 252*c7d4d259SMartin Schwidefsky register unsigned long r3 asm("3") = (unsigned long) src_len; 253*c7d4d259SMartin Schwidefsky 254*c7d4d259SMartin Schwidefsky asm volatile( 255*c7d4d259SMartin Schwidefsky "0: .insn rre,%[opc] << 16,0,%[src]\n" 256*c7d4d259SMartin Schwidefsky " brc 1,0b\n" /* handle partial completion */ 257*c7d4d259SMartin Schwidefsky : [src] "+a" (r2), [len] "+d" (r3) 258*c7d4d259SMartin Schwidefsky : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KIMD) 259*c7d4d259SMartin Schwidefsky : "cc", "memory"); 260*c7d4d259SMartin Schwidefsky 261*c7d4d259SMartin Schwidefsky return src_len - r3; 262*c7d4d259SMartin Schwidefsky } 263*c7d4d259SMartin Schwidefsky 264*c7d4d259SMartin Schwidefsky /** 265*c7d4d259SMartin Schwidefsky * cpacf_klmd() - executes the KLMD (COMPUTE LAST MESSAGE DIGEST) instruction 266*c7d4d259SMartin Schwidefsky * @func: the function code passed to KM; see CPACF_KLMD_xxx defines 267*c7d4d259SMartin Schwidefsky * @param: address of parameter block; see POP for details on each func 268*c7d4d259SMartin Schwidefsky * @src: address of source memory area 269*c7d4d259SMartin Schwidefsky * @src_len: length of src operand in bytes 270*c7d4d259SMartin Schwidefsky * 271*c7d4d259SMartin Schwidefsky * Returns 0 for the query func, number of processed bytes for digest funcs 272*c7d4d259SMartin Schwidefsky */ 273*c7d4d259SMartin Schwidefsky static inline int cpacf_klmd(long func, void *param, 274*c7d4d259SMartin Schwidefsky const u8 *src, long src_len) 275*c7d4d259SMartin Schwidefsky { 276*c7d4d259SMartin Schwidefsky register unsigned long r0 asm("0") = (unsigned long) func; 277*c7d4d259SMartin Schwidefsky register unsigned long r1 asm("1") = (unsigned long) param; 278*c7d4d259SMartin Schwidefsky register unsigned long r2 asm("2") = (unsigned long) src; 279*c7d4d259SMartin Schwidefsky register unsigned long r3 asm("3") = (unsigned long) src_len; 280*c7d4d259SMartin Schwidefsky 281*c7d4d259SMartin Schwidefsky asm volatile( 282*c7d4d259SMartin Schwidefsky "0: .insn rre,%[opc] << 16,0,%[src]\n" 283*c7d4d259SMartin Schwidefsky " brc 1,0b\n" /* handle partial completion */ 284*c7d4d259SMartin Schwidefsky : [src] "+a" (r2), [len] "+d" (r3) 285*c7d4d259SMartin Schwidefsky : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KLMD) 286*c7d4d259SMartin Schwidefsky : "cc", "memory"); 287*c7d4d259SMartin Schwidefsky 288*c7d4d259SMartin Schwidefsky return src_len - r3; 289*c7d4d259SMartin Schwidefsky } 290*c7d4d259SMartin Schwidefsky 291*c7d4d259SMartin Schwidefsky /** 292*c7d4d259SMartin Schwidefsky * cpacf_kmac() - executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) 293*c7d4d259SMartin Schwidefsky * instruction 294*c7d4d259SMartin Schwidefsky * @func: the function code passed to KM; see CPACF_KMAC_xxx defines 295*c7d4d259SMartin Schwidefsky * @param: address of parameter block; see POP for details on each func 296*c7d4d259SMartin Schwidefsky * @src: address of source memory area 297*c7d4d259SMartin Schwidefsky * @src_len: length of src operand in bytes 298*c7d4d259SMartin Schwidefsky * 299*c7d4d259SMartin Schwidefsky * Returns 0 for the query func, number of processed bytes for digest funcs 300*c7d4d259SMartin Schwidefsky */ 301*c7d4d259SMartin Schwidefsky static inline int cpacf_kmac(long func, void *param, 302*c7d4d259SMartin Schwidefsky const u8 *src, long src_len) 303*c7d4d259SMartin Schwidefsky { 304*c7d4d259SMartin Schwidefsky register unsigned long r0 asm("0") = (unsigned long) func; 305*c7d4d259SMartin Schwidefsky register unsigned long r1 asm("1") = (unsigned long) param; 306*c7d4d259SMartin Schwidefsky register unsigned long r2 asm("2") = (unsigned long) src; 307*c7d4d259SMartin Schwidefsky register unsigned long r3 asm("3") = (unsigned long) src_len; 308*c7d4d259SMartin Schwidefsky 309*c7d4d259SMartin Schwidefsky asm volatile( 310*c7d4d259SMartin Schwidefsky "0: .insn rre,%[opc] << 16,0,%[src]\n" 311*c7d4d259SMartin Schwidefsky " brc 1,0b\n" /* handle partial completion */ 312*c7d4d259SMartin Schwidefsky : [src] "+a" (r2), [len] "+d" (r3) 313*c7d4d259SMartin Schwidefsky : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMAC) 314*c7d4d259SMartin Schwidefsky : "cc", "memory"); 315*c7d4d259SMartin Schwidefsky 316*c7d4d259SMartin Schwidefsky return src_len - r3; 317*c7d4d259SMartin Schwidefsky } 318*c7d4d259SMartin Schwidefsky 319*c7d4d259SMartin Schwidefsky /** 320*c7d4d259SMartin Schwidefsky * cpacf_kmctr() - executes the KMCTR (CIPHER MESSAGE WITH COUNTER) instruction 321*c7d4d259SMartin Schwidefsky * @func: the function code passed to KMCTR; see CPACF_KMCTR_xxx defines 322*c7d4d259SMartin Schwidefsky * @param: address of parameter block; see POP for details on each func 323*c7d4d259SMartin Schwidefsky * @dest: address of destination memory area 324*c7d4d259SMartin Schwidefsky * @src: address of source memory area 325*c7d4d259SMartin Schwidefsky * @src_len: length of src operand in bytes 326*c7d4d259SMartin Schwidefsky * @counter: address of counter value 327*c7d4d259SMartin Schwidefsky * 328*c7d4d259SMartin Schwidefsky * Returns 0 for the query func, number of processed bytes for 329*c7d4d259SMartin Schwidefsky * encryption/decryption funcs 330*c7d4d259SMartin Schwidefsky */ 331*c7d4d259SMartin Schwidefsky static inline int cpacf_kmctr(long func, void *param, u8 *dest, 332*c7d4d259SMartin Schwidefsky const u8 *src, long src_len, u8 *counter) 333*c7d4d259SMartin Schwidefsky { 334*c7d4d259SMartin Schwidefsky register unsigned long r0 asm("0") = (unsigned long) func; 335*c7d4d259SMartin Schwidefsky register unsigned long r1 asm("1") = (unsigned long) param; 336*c7d4d259SMartin Schwidefsky register unsigned long r2 asm("2") = (unsigned long) src; 337*c7d4d259SMartin Schwidefsky register unsigned long r3 asm("3") = (unsigned long) src_len; 338*c7d4d259SMartin Schwidefsky register unsigned long r4 asm("4") = (unsigned long) dest; 339*c7d4d259SMartin Schwidefsky register unsigned long r6 asm("6") = (unsigned long) counter; 340*c7d4d259SMartin Schwidefsky 341*c7d4d259SMartin Schwidefsky asm volatile( 342*c7d4d259SMartin Schwidefsky "0: .insn rrf,%[opc] << 16,%[dst],%[src],%[ctr],0\n" 343*c7d4d259SMartin Schwidefsky " brc 1,0b\n" /* handle partial completion */ 344*c7d4d259SMartin Schwidefsky : [src] "+a" (r2), [len] "+d" (r3), 345*c7d4d259SMartin Schwidefsky [dst] "+a" (r4), [ctr] "+a" (r6) 346*c7d4d259SMartin Schwidefsky : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMCTR) 347*c7d4d259SMartin Schwidefsky : "cc", "memory"); 348*c7d4d259SMartin Schwidefsky 349*c7d4d259SMartin Schwidefsky return src_len - r3; 350*c7d4d259SMartin Schwidefsky } 351*c7d4d259SMartin Schwidefsky 352*c7d4d259SMartin Schwidefsky /** 353*c7d4d259SMartin Schwidefsky * cpacf_ppno() - executes the PPNO (PERFORM PSEUDORANDOM NUMBER OPERATION) 354*c7d4d259SMartin Schwidefsky * instruction 355*c7d4d259SMartin Schwidefsky * @func: the function code passed to PPNO; see CPACF_PPNO_xxx defines 356*c7d4d259SMartin Schwidefsky * @param: address of parameter block; see POP for details on each func 357*c7d4d259SMartin Schwidefsky * @dest: address of destination memory area 358*c7d4d259SMartin Schwidefsky * @dest_len: size of destination memory area in bytes 359*c7d4d259SMartin Schwidefsky * @seed: address of seed data 360*c7d4d259SMartin Schwidefsky * @seed_len: size of seed data in bytes 361*c7d4d259SMartin Schwidefsky * 362*c7d4d259SMartin Schwidefsky * Returns 0 for the query func, number of random bytes stored in 363*c7d4d259SMartin Schwidefsky * dest buffer for generate function 364*c7d4d259SMartin Schwidefsky */ 365*c7d4d259SMartin Schwidefsky static inline int cpacf_ppno(long func, void *param, 366*c7d4d259SMartin Schwidefsky u8 *dest, long dest_len, 367*c7d4d259SMartin Schwidefsky const u8 *seed, long seed_len) 368*c7d4d259SMartin Schwidefsky { 369*c7d4d259SMartin Schwidefsky register unsigned long r0 asm("0") = (unsigned long) func; 370*c7d4d259SMartin Schwidefsky register unsigned long r1 asm("1") = (unsigned long) param; 371*c7d4d259SMartin Schwidefsky register unsigned long r2 asm("2") = (unsigned long) dest; 372*c7d4d259SMartin Schwidefsky register unsigned long r3 asm("3") = (unsigned long) dest_len; 373*c7d4d259SMartin Schwidefsky register unsigned long r4 asm("4") = (unsigned long) seed; 374*c7d4d259SMartin Schwidefsky register unsigned long r5 asm("5") = (unsigned long) seed_len; 375*c7d4d259SMartin Schwidefsky 376*c7d4d259SMartin Schwidefsky asm volatile ( 377*c7d4d259SMartin Schwidefsky "0: .insn rre,%[opc] << 16,%[dst],%[seed]\n" 378*c7d4d259SMartin Schwidefsky " brc 1,0b\n" /* handle partial completion */ 379*c7d4d259SMartin Schwidefsky : [dst] "+a" (r2), [dlen] "+d" (r3) 380*c7d4d259SMartin Schwidefsky : [fc] "d" (r0), [pba] "a" (r1), 381*c7d4d259SMartin Schwidefsky [seed] "a" (r4), [slen] "d" (r5), [opc] "i" (CPACF_PPNO) 382*c7d4d259SMartin Schwidefsky : "cc", "memory"); 383*c7d4d259SMartin Schwidefsky 384*c7d4d259SMartin Schwidefsky return dest_len - r3; 385*c7d4d259SMartin Schwidefsky } 386*c7d4d259SMartin Schwidefsky 387*c7d4d259SMartin Schwidefsky /** 388*c7d4d259SMartin Schwidefsky * cpacf_pcc() - executes the PCC (PERFORM CRYPTOGRAPHIC COMPUTATION) 389*c7d4d259SMartin Schwidefsky * instruction 390*c7d4d259SMartin Schwidefsky * @func: the function code passed to PCC; see CPACF_KM_xxx defines 391*c7d4d259SMartin Schwidefsky * @param: address of parameter block; see POP for details on each func 392*c7d4d259SMartin Schwidefsky * 393*c7d4d259SMartin Schwidefsky * Returns 0. 394*c7d4d259SMartin Schwidefsky */ 395*c7d4d259SMartin Schwidefsky static inline int cpacf_pcc(long func, void *param) 396*c7d4d259SMartin Schwidefsky { 397*c7d4d259SMartin Schwidefsky register unsigned long r0 asm("0") = (unsigned long) func; 398*c7d4d259SMartin Schwidefsky register unsigned long r1 asm("1") = (unsigned long) param; 399*c7d4d259SMartin Schwidefsky 400*c7d4d259SMartin Schwidefsky asm volatile( 401*c7d4d259SMartin Schwidefsky "0: .insn rre,%[opc] << 16,0,0\n" /* PCC opcode */ 402*c7d4d259SMartin Schwidefsky " brc 1,0b\n" /* handle partial completion */ 403*c7d4d259SMartin Schwidefsky : 404*c7d4d259SMartin Schwidefsky : [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_PCC) 405*c7d4d259SMartin Schwidefsky : "cc", "memory"); 406*c7d4d259SMartin Schwidefsky 407*c7d4d259SMartin Schwidefsky return 0; 408*c7d4d259SMartin Schwidefsky } 409*c7d4d259SMartin Schwidefsky 410*c7d4d259SMartin Schwidefsky #endif /* _ASM_S390_CPACF_H */ 411