xref: /linux/arch/s390/include/asm/cpacf.h (revision c7d4d259b7477866376435155eb0ccdaee880677)
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