18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * CP Assist for Cryptographic Functions (CPACF)
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2003, 2017
68c2ecf20Sopenharmony_ci * Author(s): Thomas Spatzier
78c2ecf20Sopenharmony_ci *	      Jan Glauber
88c2ecf20Sopenharmony_ci *	      Harald Freudenberger (freude@de.ibm.com)
98c2ecf20Sopenharmony_ci *	      Martin Schwidefsky <schwidefsky@de.ibm.com>
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci#ifndef _ASM_S390_CPACF_H
128c2ecf20Sopenharmony_ci#define _ASM_S390_CPACF_H
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <asm/facility.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci/*
178c2ecf20Sopenharmony_ci * Instruction opcodes for the CPACF instructions
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_ci#define CPACF_KMAC		0xb91e		/* MSA	*/
208c2ecf20Sopenharmony_ci#define CPACF_KM		0xb92e		/* MSA	*/
218c2ecf20Sopenharmony_ci#define CPACF_KMC		0xb92f		/* MSA	*/
228c2ecf20Sopenharmony_ci#define CPACF_KIMD		0xb93e		/* MSA	*/
238c2ecf20Sopenharmony_ci#define CPACF_KLMD		0xb93f		/* MSA	*/
248c2ecf20Sopenharmony_ci#define CPACF_PCKMO		0xb928		/* MSA3 */
258c2ecf20Sopenharmony_ci#define CPACF_KMF		0xb92a		/* MSA4 */
268c2ecf20Sopenharmony_ci#define CPACF_KMO		0xb92b		/* MSA4 */
278c2ecf20Sopenharmony_ci#define CPACF_PCC		0xb92c		/* MSA4 */
288c2ecf20Sopenharmony_ci#define CPACF_KMCTR		0xb92d		/* MSA4 */
298c2ecf20Sopenharmony_ci#define CPACF_PRNO		0xb93c		/* MSA5 */
308c2ecf20Sopenharmony_ci#define CPACF_KMA		0xb929		/* MSA8 */
318c2ecf20Sopenharmony_ci#define CPACF_KDSA		0xb93a		/* MSA9 */
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/*
348c2ecf20Sopenharmony_ci * En/decryption modifier bits
358c2ecf20Sopenharmony_ci */
368c2ecf20Sopenharmony_ci#define CPACF_ENCRYPT		0x00
378c2ecf20Sopenharmony_ci#define CPACF_DECRYPT		0x80
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci/*
408c2ecf20Sopenharmony_ci * Function codes for the KM (CIPHER MESSAGE) instruction
418c2ecf20Sopenharmony_ci */
428c2ecf20Sopenharmony_ci#define CPACF_KM_QUERY		0x00
438c2ecf20Sopenharmony_ci#define CPACF_KM_DEA		0x01
448c2ecf20Sopenharmony_ci#define CPACF_KM_TDEA_128	0x02
458c2ecf20Sopenharmony_ci#define CPACF_KM_TDEA_192	0x03
468c2ecf20Sopenharmony_ci#define CPACF_KM_AES_128	0x12
478c2ecf20Sopenharmony_ci#define CPACF_KM_AES_192	0x13
488c2ecf20Sopenharmony_ci#define CPACF_KM_AES_256	0x14
498c2ecf20Sopenharmony_ci#define CPACF_KM_PAES_128	0x1a
508c2ecf20Sopenharmony_ci#define CPACF_KM_PAES_192	0x1b
518c2ecf20Sopenharmony_ci#define CPACF_KM_PAES_256	0x1c
528c2ecf20Sopenharmony_ci#define CPACF_KM_XTS_128	0x32
538c2ecf20Sopenharmony_ci#define CPACF_KM_XTS_256	0x34
548c2ecf20Sopenharmony_ci#define CPACF_KM_PXTS_128	0x3a
558c2ecf20Sopenharmony_ci#define CPACF_KM_PXTS_256	0x3c
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci/*
588c2ecf20Sopenharmony_ci * Function codes for the KMC (CIPHER MESSAGE WITH CHAINING)
598c2ecf20Sopenharmony_ci * instruction
608c2ecf20Sopenharmony_ci */
618c2ecf20Sopenharmony_ci#define CPACF_KMC_QUERY		0x00
628c2ecf20Sopenharmony_ci#define CPACF_KMC_DEA		0x01
638c2ecf20Sopenharmony_ci#define CPACF_KMC_TDEA_128	0x02
648c2ecf20Sopenharmony_ci#define CPACF_KMC_TDEA_192	0x03
658c2ecf20Sopenharmony_ci#define CPACF_KMC_AES_128	0x12
668c2ecf20Sopenharmony_ci#define CPACF_KMC_AES_192	0x13
678c2ecf20Sopenharmony_ci#define CPACF_KMC_AES_256	0x14
688c2ecf20Sopenharmony_ci#define CPACF_KMC_PAES_128	0x1a
698c2ecf20Sopenharmony_ci#define CPACF_KMC_PAES_192	0x1b
708c2ecf20Sopenharmony_ci#define CPACF_KMC_PAES_256	0x1c
718c2ecf20Sopenharmony_ci#define CPACF_KMC_PRNG		0x43
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/*
748c2ecf20Sopenharmony_ci * Function codes for the KMCTR (CIPHER MESSAGE WITH COUNTER)
758c2ecf20Sopenharmony_ci * instruction
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_ci#define CPACF_KMCTR_QUERY	0x00
788c2ecf20Sopenharmony_ci#define CPACF_KMCTR_DEA		0x01
798c2ecf20Sopenharmony_ci#define CPACF_KMCTR_TDEA_128	0x02
808c2ecf20Sopenharmony_ci#define CPACF_KMCTR_TDEA_192	0x03
818c2ecf20Sopenharmony_ci#define CPACF_KMCTR_AES_128	0x12
828c2ecf20Sopenharmony_ci#define CPACF_KMCTR_AES_192	0x13
838c2ecf20Sopenharmony_ci#define CPACF_KMCTR_AES_256	0x14
848c2ecf20Sopenharmony_ci#define CPACF_KMCTR_PAES_128	0x1a
858c2ecf20Sopenharmony_ci#define CPACF_KMCTR_PAES_192	0x1b
868c2ecf20Sopenharmony_ci#define CPACF_KMCTR_PAES_256	0x1c
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci/*
898c2ecf20Sopenharmony_ci * Function codes for the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
908c2ecf20Sopenharmony_ci * instruction
918c2ecf20Sopenharmony_ci */
928c2ecf20Sopenharmony_ci#define CPACF_KIMD_QUERY	0x00
938c2ecf20Sopenharmony_ci#define CPACF_KIMD_SHA_1	0x01
948c2ecf20Sopenharmony_ci#define CPACF_KIMD_SHA_256	0x02
958c2ecf20Sopenharmony_ci#define CPACF_KIMD_SHA_512	0x03
968c2ecf20Sopenharmony_ci#define CPACF_KIMD_SHA3_224	0x20
978c2ecf20Sopenharmony_ci#define CPACF_KIMD_SHA3_256	0x21
988c2ecf20Sopenharmony_ci#define CPACF_KIMD_SHA3_384	0x22
998c2ecf20Sopenharmony_ci#define CPACF_KIMD_SHA3_512	0x23
1008c2ecf20Sopenharmony_ci#define CPACF_KIMD_GHASH	0x41
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/*
1038c2ecf20Sopenharmony_ci * Function codes for the KLMD (COMPUTE LAST MESSAGE DIGEST)
1048c2ecf20Sopenharmony_ci * instruction
1058c2ecf20Sopenharmony_ci */
1068c2ecf20Sopenharmony_ci#define CPACF_KLMD_QUERY	0x00
1078c2ecf20Sopenharmony_ci#define CPACF_KLMD_SHA_1	0x01
1088c2ecf20Sopenharmony_ci#define CPACF_KLMD_SHA_256	0x02
1098c2ecf20Sopenharmony_ci#define CPACF_KLMD_SHA_512	0x03
1108c2ecf20Sopenharmony_ci#define CPACF_KLMD_SHA3_224	0x20
1118c2ecf20Sopenharmony_ci#define CPACF_KLMD_SHA3_256	0x21
1128c2ecf20Sopenharmony_ci#define CPACF_KLMD_SHA3_384	0x22
1138c2ecf20Sopenharmony_ci#define CPACF_KLMD_SHA3_512	0x23
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci/*
1168c2ecf20Sopenharmony_ci * function codes for the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
1178c2ecf20Sopenharmony_ci * instruction
1188c2ecf20Sopenharmony_ci */
1198c2ecf20Sopenharmony_ci#define CPACF_KMAC_QUERY	0x00
1208c2ecf20Sopenharmony_ci#define CPACF_KMAC_DEA		0x01
1218c2ecf20Sopenharmony_ci#define CPACF_KMAC_TDEA_128	0x02
1228c2ecf20Sopenharmony_ci#define CPACF_KMAC_TDEA_192	0x03
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci/*
1258c2ecf20Sopenharmony_ci * Function codes for the PCKMO (PERFORM CRYPTOGRAPHIC KEY MANAGEMENT)
1268c2ecf20Sopenharmony_ci * instruction
1278c2ecf20Sopenharmony_ci */
1288c2ecf20Sopenharmony_ci#define CPACF_PCKMO_QUERY		0x00
1298c2ecf20Sopenharmony_ci#define CPACF_PCKMO_ENC_DES_KEY		0x01
1308c2ecf20Sopenharmony_ci#define CPACF_PCKMO_ENC_TDES_128_KEY	0x02
1318c2ecf20Sopenharmony_ci#define CPACF_PCKMO_ENC_TDES_192_KEY	0x03
1328c2ecf20Sopenharmony_ci#define CPACF_PCKMO_ENC_AES_128_KEY	0x12
1338c2ecf20Sopenharmony_ci#define CPACF_PCKMO_ENC_AES_192_KEY	0x13
1348c2ecf20Sopenharmony_ci#define CPACF_PCKMO_ENC_AES_256_KEY	0x14
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/*
1378c2ecf20Sopenharmony_ci * Function codes for the PRNO (PERFORM RANDOM NUMBER OPERATION)
1388c2ecf20Sopenharmony_ci * instruction
1398c2ecf20Sopenharmony_ci */
1408c2ecf20Sopenharmony_ci#define CPACF_PRNO_QUERY		0x00
1418c2ecf20Sopenharmony_ci#define CPACF_PRNO_SHA512_DRNG_GEN	0x03
1428c2ecf20Sopenharmony_ci#define CPACF_PRNO_SHA512_DRNG_SEED	0x83
1438c2ecf20Sopenharmony_ci#define CPACF_PRNO_TRNG_Q_R2C_RATIO	0x70
1448c2ecf20Sopenharmony_ci#define CPACF_PRNO_TRNG			0x72
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci/*
1478c2ecf20Sopenharmony_ci * Function codes for the KMA (CIPHER MESSAGE WITH AUTHENTICATION)
1488c2ecf20Sopenharmony_ci * instruction
1498c2ecf20Sopenharmony_ci */
1508c2ecf20Sopenharmony_ci#define CPACF_KMA_QUERY		0x00
1518c2ecf20Sopenharmony_ci#define CPACF_KMA_GCM_AES_128	0x12
1528c2ecf20Sopenharmony_ci#define CPACF_KMA_GCM_AES_192	0x13
1538c2ecf20Sopenharmony_ci#define CPACF_KMA_GCM_AES_256	0x14
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci/*
1568c2ecf20Sopenharmony_ci * Flags for the KMA (CIPHER MESSAGE WITH AUTHENTICATION) instruction
1578c2ecf20Sopenharmony_ci */
1588c2ecf20Sopenharmony_ci#define CPACF_KMA_LPC	0x100	/* Last-Plaintext/Ciphertext */
1598c2ecf20Sopenharmony_ci#define CPACF_KMA_LAAD	0x200	/* Last-AAD */
1608c2ecf20Sopenharmony_ci#define CPACF_KMA_HS	0x400	/* Hash-subkey Supplied */
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_citypedef struct { unsigned char bytes[16]; } cpacf_mask_t;
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci/**
1658c2ecf20Sopenharmony_ci * cpacf_query() - check if a specific CPACF function is available
1668c2ecf20Sopenharmony_ci * @opcode: the opcode of the crypto instruction
1678c2ecf20Sopenharmony_ci * @func: the function code to test for
1688c2ecf20Sopenharmony_ci *
1698c2ecf20Sopenharmony_ci * Executes the query function for the given crypto instruction @opcode
1708c2ecf20Sopenharmony_ci * and checks if @func is available
1718c2ecf20Sopenharmony_ci *
1728c2ecf20Sopenharmony_ci * Returns 1 if @func is available for @opcode, 0 otherwise
1738c2ecf20Sopenharmony_ci */
1748c2ecf20Sopenharmony_cistatic __always_inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = 0;	/* query function */
1778c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) mask;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci	asm volatile(
1808c2ecf20Sopenharmony_ci		"	spm 0\n" /* pckmo doesn't change the cc */
1818c2ecf20Sopenharmony_ci		/* Parameter regs are ignored, but must be nonzero and unique */
1828c2ecf20Sopenharmony_ci		"0:	.insn	rrf,%[opc] << 16,2,4,6,0\n"
1838c2ecf20Sopenharmony_ci		"	brc	1,0b\n"	/* handle partial completion */
1848c2ecf20Sopenharmony_ci		: "=m" (*mask)
1858c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (opcode)
1868c2ecf20Sopenharmony_ci		: "cc");
1878c2ecf20Sopenharmony_ci}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_cistatic __always_inline int __cpacf_check_opcode(unsigned int opcode)
1908c2ecf20Sopenharmony_ci{
1918c2ecf20Sopenharmony_ci	switch (opcode) {
1928c2ecf20Sopenharmony_ci	case CPACF_KMAC:
1938c2ecf20Sopenharmony_ci	case CPACF_KM:
1948c2ecf20Sopenharmony_ci	case CPACF_KMC:
1958c2ecf20Sopenharmony_ci	case CPACF_KIMD:
1968c2ecf20Sopenharmony_ci	case CPACF_KLMD:
1978c2ecf20Sopenharmony_ci		return test_facility(17);	/* check for MSA */
1988c2ecf20Sopenharmony_ci	case CPACF_PCKMO:
1998c2ecf20Sopenharmony_ci		return test_facility(76);	/* check for MSA3 */
2008c2ecf20Sopenharmony_ci	case CPACF_KMF:
2018c2ecf20Sopenharmony_ci	case CPACF_KMO:
2028c2ecf20Sopenharmony_ci	case CPACF_PCC:
2038c2ecf20Sopenharmony_ci	case CPACF_KMCTR:
2048c2ecf20Sopenharmony_ci		return test_facility(77);	/* check for MSA4 */
2058c2ecf20Sopenharmony_ci	case CPACF_PRNO:
2068c2ecf20Sopenharmony_ci		return test_facility(57);	/* check for MSA5 */
2078c2ecf20Sopenharmony_ci	case CPACF_KMA:
2088c2ecf20Sopenharmony_ci		return test_facility(146);	/* check for MSA8 */
2098c2ecf20Sopenharmony_ci	default:
2108c2ecf20Sopenharmony_ci		BUG();
2118c2ecf20Sopenharmony_ci	}
2128c2ecf20Sopenharmony_ci}
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_cistatic __always_inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
2158c2ecf20Sopenharmony_ci{
2168c2ecf20Sopenharmony_ci	if (__cpacf_check_opcode(opcode)) {
2178c2ecf20Sopenharmony_ci		__cpacf_query(opcode, mask);
2188c2ecf20Sopenharmony_ci		return 1;
2198c2ecf20Sopenharmony_ci	}
2208c2ecf20Sopenharmony_ci	memset(mask, 0, sizeof(*mask));
2218c2ecf20Sopenharmony_ci	return 0;
2228c2ecf20Sopenharmony_ci}
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_cistatic inline int cpacf_test_func(cpacf_mask_t *mask, unsigned int func)
2258c2ecf20Sopenharmony_ci{
2268c2ecf20Sopenharmony_ci	return (mask->bytes[func >> 3] & (0x80 >> (func & 7))) != 0;
2278c2ecf20Sopenharmony_ci}
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_cistatic __always_inline int cpacf_query_func(unsigned int opcode, unsigned int func)
2308c2ecf20Sopenharmony_ci{
2318c2ecf20Sopenharmony_ci	cpacf_mask_t mask;
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	if (cpacf_query(opcode, &mask))
2348c2ecf20Sopenharmony_ci		return cpacf_test_func(&mask, func);
2358c2ecf20Sopenharmony_ci	return 0;
2368c2ecf20Sopenharmony_ci}
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci/**
2398c2ecf20Sopenharmony_ci * cpacf_km() - executes the KM (CIPHER MESSAGE) instruction
2408c2ecf20Sopenharmony_ci * @func: the function code passed to KM; see CPACF_KM_xxx defines
2418c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
2428c2ecf20Sopenharmony_ci * @dest: address of destination memory area
2438c2ecf20Sopenharmony_ci * @src: address of source memory area
2448c2ecf20Sopenharmony_ci * @src_len: length of src operand in bytes
2458c2ecf20Sopenharmony_ci *
2468c2ecf20Sopenharmony_ci * Returns 0 for the query func, number of processed bytes for
2478c2ecf20Sopenharmony_ci * encryption/decryption funcs
2488c2ecf20Sopenharmony_ci */
2498c2ecf20Sopenharmony_cistatic inline int cpacf_km(unsigned long func, void *param,
2508c2ecf20Sopenharmony_ci			   u8 *dest, const u8 *src, long src_len)
2518c2ecf20Sopenharmony_ci{
2528c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
2538c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
2548c2ecf20Sopenharmony_ci	register unsigned long r2 asm("2") = (unsigned long) src;
2558c2ecf20Sopenharmony_ci	register unsigned long r3 asm("3") = (unsigned long) src_len;
2568c2ecf20Sopenharmony_ci	register unsigned long r4 asm("4") = (unsigned long) dest;
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	asm volatile(
2598c2ecf20Sopenharmony_ci		"0:	.insn	rre,%[opc] << 16,%[dst],%[src]\n"
2608c2ecf20Sopenharmony_ci		"	brc	1,0b\n" /* handle partial completion */
2618c2ecf20Sopenharmony_ci		: [src] "+a" (r2), [len] "+d" (r3), [dst] "+a" (r4)
2628c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KM)
2638c2ecf20Sopenharmony_ci		: "cc", "memory");
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	return src_len - r3;
2668c2ecf20Sopenharmony_ci}
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci/**
2698c2ecf20Sopenharmony_ci * cpacf_kmc() - executes the KMC (CIPHER MESSAGE WITH CHAINING) instruction
2708c2ecf20Sopenharmony_ci * @func: the function code passed to KM; see CPACF_KMC_xxx defines
2718c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
2728c2ecf20Sopenharmony_ci * @dest: address of destination memory area
2738c2ecf20Sopenharmony_ci * @src: address of source memory area
2748c2ecf20Sopenharmony_ci * @src_len: length of src operand in bytes
2758c2ecf20Sopenharmony_ci *
2768c2ecf20Sopenharmony_ci * Returns 0 for the query func, number of processed bytes for
2778c2ecf20Sopenharmony_ci * encryption/decryption funcs
2788c2ecf20Sopenharmony_ci */
2798c2ecf20Sopenharmony_cistatic inline int cpacf_kmc(unsigned long func, void *param,
2808c2ecf20Sopenharmony_ci			    u8 *dest, const u8 *src, long src_len)
2818c2ecf20Sopenharmony_ci{
2828c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
2838c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
2848c2ecf20Sopenharmony_ci	register unsigned long r2 asm("2") = (unsigned long) src;
2858c2ecf20Sopenharmony_ci	register unsigned long r3 asm("3") = (unsigned long) src_len;
2868c2ecf20Sopenharmony_ci	register unsigned long r4 asm("4") = (unsigned long) dest;
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci	asm volatile(
2898c2ecf20Sopenharmony_ci		"0:	.insn	rre,%[opc] << 16,%[dst],%[src]\n"
2908c2ecf20Sopenharmony_ci		"	brc	1,0b\n" /* handle partial completion */
2918c2ecf20Sopenharmony_ci		: [src] "+a" (r2), [len] "+d" (r3), [dst] "+a" (r4)
2928c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMC)
2938c2ecf20Sopenharmony_ci		: "cc", "memory");
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	return src_len - r3;
2968c2ecf20Sopenharmony_ci}
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci/**
2998c2ecf20Sopenharmony_ci * cpacf_kimd() - executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
3008c2ecf20Sopenharmony_ci *		  instruction
3018c2ecf20Sopenharmony_ci * @func: the function code passed to KM; see CPACF_KIMD_xxx defines
3028c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
3038c2ecf20Sopenharmony_ci * @src: address of source memory area
3048c2ecf20Sopenharmony_ci * @src_len: length of src operand in bytes
3058c2ecf20Sopenharmony_ci */
3068c2ecf20Sopenharmony_cistatic inline void cpacf_kimd(unsigned long func, void *param,
3078c2ecf20Sopenharmony_ci			      const u8 *src, long src_len)
3088c2ecf20Sopenharmony_ci{
3098c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
3108c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
3118c2ecf20Sopenharmony_ci	register unsigned long r2 asm("2") = (unsigned long) src;
3128c2ecf20Sopenharmony_ci	register unsigned long r3 asm("3") = (unsigned long) src_len;
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci	asm volatile(
3158c2ecf20Sopenharmony_ci		"0:	.insn	rre,%[opc] << 16,0,%[src]\n"
3168c2ecf20Sopenharmony_ci		"	brc	1,0b\n" /* handle partial completion */
3178c2ecf20Sopenharmony_ci		: [src] "+a" (r2), [len] "+d" (r3)
3188c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KIMD)
3198c2ecf20Sopenharmony_ci		: "cc", "memory");
3208c2ecf20Sopenharmony_ci}
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci/**
3238c2ecf20Sopenharmony_ci * cpacf_klmd() - executes the KLMD (COMPUTE LAST MESSAGE DIGEST) instruction
3248c2ecf20Sopenharmony_ci * @func: the function code passed to KM; see CPACF_KLMD_xxx defines
3258c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
3268c2ecf20Sopenharmony_ci * @src: address of source memory area
3278c2ecf20Sopenharmony_ci * @src_len: length of src operand in bytes
3288c2ecf20Sopenharmony_ci */
3298c2ecf20Sopenharmony_cistatic inline void cpacf_klmd(unsigned long func, void *param,
3308c2ecf20Sopenharmony_ci			      const u8 *src, long src_len)
3318c2ecf20Sopenharmony_ci{
3328c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
3338c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
3348c2ecf20Sopenharmony_ci	register unsigned long r2 asm("2") = (unsigned long) src;
3358c2ecf20Sopenharmony_ci	register unsigned long r3 asm("3") = (unsigned long) src_len;
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci	asm volatile(
3388c2ecf20Sopenharmony_ci		"0:	.insn	rre,%[opc] << 16,0,%[src]\n"
3398c2ecf20Sopenharmony_ci		"	brc	1,0b\n" /* handle partial completion */
3408c2ecf20Sopenharmony_ci		: [src] "+a" (r2), [len] "+d" (r3)
3418c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KLMD)
3428c2ecf20Sopenharmony_ci		: "cc", "memory");
3438c2ecf20Sopenharmony_ci}
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci/**
3468c2ecf20Sopenharmony_ci * cpacf_kmac() - executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
3478c2ecf20Sopenharmony_ci *		  instruction
3488c2ecf20Sopenharmony_ci * @func: the function code passed to KM; see CPACF_KMAC_xxx defines
3498c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
3508c2ecf20Sopenharmony_ci * @src: address of source memory area
3518c2ecf20Sopenharmony_ci * @src_len: length of src operand in bytes
3528c2ecf20Sopenharmony_ci *
3538c2ecf20Sopenharmony_ci * Returns 0 for the query func, number of processed bytes for digest funcs
3548c2ecf20Sopenharmony_ci */
3558c2ecf20Sopenharmony_cistatic inline int cpacf_kmac(unsigned long func, void *param,
3568c2ecf20Sopenharmony_ci			     const u8 *src, long src_len)
3578c2ecf20Sopenharmony_ci{
3588c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
3598c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
3608c2ecf20Sopenharmony_ci	register unsigned long r2 asm("2") = (unsigned long) src;
3618c2ecf20Sopenharmony_ci	register unsigned long r3 asm("3") = (unsigned long) src_len;
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci	asm volatile(
3648c2ecf20Sopenharmony_ci		"0:	.insn	rre,%[opc] << 16,0,%[src]\n"
3658c2ecf20Sopenharmony_ci		"	brc	1,0b\n" /* handle partial completion */
3668c2ecf20Sopenharmony_ci		: [src] "+a" (r2), [len] "+d" (r3)
3678c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMAC)
3688c2ecf20Sopenharmony_ci		: "cc", "memory");
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci	return src_len - r3;
3718c2ecf20Sopenharmony_ci}
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci/**
3748c2ecf20Sopenharmony_ci * cpacf_kmctr() - executes the KMCTR (CIPHER MESSAGE WITH COUNTER) instruction
3758c2ecf20Sopenharmony_ci * @func: the function code passed to KMCTR; see CPACF_KMCTR_xxx defines
3768c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
3778c2ecf20Sopenharmony_ci * @dest: address of destination memory area
3788c2ecf20Sopenharmony_ci * @src: address of source memory area
3798c2ecf20Sopenharmony_ci * @src_len: length of src operand in bytes
3808c2ecf20Sopenharmony_ci * @counter: address of counter value
3818c2ecf20Sopenharmony_ci *
3828c2ecf20Sopenharmony_ci * Returns 0 for the query func, number of processed bytes for
3838c2ecf20Sopenharmony_ci * encryption/decryption funcs
3848c2ecf20Sopenharmony_ci */
3858c2ecf20Sopenharmony_cistatic inline int cpacf_kmctr(unsigned long func, void *param, u8 *dest,
3868c2ecf20Sopenharmony_ci			      const u8 *src, long src_len, u8 *counter)
3878c2ecf20Sopenharmony_ci{
3888c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
3898c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
3908c2ecf20Sopenharmony_ci	register unsigned long r2 asm("2") = (unsigned long) src;
3918c2ecf20Sopenharmony_ci	register unsigned long r3 asm("3") = (unsigned long) src_len;
3928c2ecf20Sopenharmony_ci	register unsigned long r4 asm("4") = (unsigned long) dest;
3938c2ecf20Sopenharmony_ci	register unsigned long r6 asm("6") = (unsigned long) counter;
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci	asm volatile(
3968c2ecf20Sopenharmony_ci		"0:	.insn	rrf,%[opc] << 16,%[dst],%[src],%[ctr],0\n"
3978c2ecf20Sopenharmony_ci		"	brc	1,0b\n" /* handle partial completion */
3988c2ecf20Sopenharmony_ci		: [src] "+a" (r2), [len] "+d" (r3),
3998c2ecf20Sopenharmony_ci		  [dst] "+a" (r4), [ctr] "+a" (r6)
4008c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMCTR)
4018c2ecf20Sopenharmony_ci		: "cc", "memory");
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci	return src_len - r3;
4048c2ecf20Sopenharmony_ci}
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci/**
4078c2ecf20Sopenharmony_ci * cpacf_prno() - executes the PRNO (PERFORM RANDOM NUMBER OPERATION)
4088c2ecf20Sopenharmony_ci *		  instruction
4098c2ecf20Sopenharmony_ci * @func: the function code passed to PRNO; see CPACF_PRNO_xxx defines
4108c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
4118c2ecf20Sopenharmony_ci * @dest: address of destination memory area
4128c2ecf20Sopenharmony_ci * @dest_len: size of destination memory area in bytes
4138c2ecf20Sopenharmony_ci * @seed: address of seed data
4148c2ecf20Sopenharmony_ci * @seed_len: size of seed data in bytes
4158c2ecf20Sopenharmony_ci */
4168c2ecf20Sopenharmony_cistatic inline void cpacf_prno(unsigned long func, void *param,
4178c2ecf20Sopenharmony_ci			      u8 *dest, unsigned long dest_len,
4188c2ecf20Sopenharmony_ci			      const u8 *seed, unsigned long seed_len)
4198c2ecf20Sopenharmony_ci{
4208c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
4218c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
4228c2ecf20Sopenharmony_ci	register unsigned long r2 asm("2") = (unsigned long) dest;
4238c2ecf20Sopenharmony_ci	register unsigned long r3 asm("3") = (unsigned long) dest_len;
4248c2ecf20Sopenharmony_ci	register unsigned long r4 asm("4") = (unsigned long) seed;
4258c2ecf20Sopenharmony_ci	register unsigned long r5 asm("5") = (unsigned long) seed_len;
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	asm volatile (
4288c2ecf20Sopenharmony_ci		"0:	.insn	rre,%[opc] << 16,%[dst],%[seed]\n"
4298c2ecf20Sopenharmony_ci		"	brc	1,0b\n"	  /* handle partial completion */
4308c2ecf20Sopenharmony_ci		: [dst] "+a" (r2), [dlen] "+d" (r3)
4318c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1),
4328c2ecf20Sopenharmony_ci		  [seed] "a" (r4), [slen] "d" (r5), [opc] "i" (CPACF_PRNO)
4338c2ecf20Sopenharmony_ci		: "cc", "memory");
4348c2ecf20Sopenharmony_ci}
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci/**
4378c2ecf20Sopenharmony_ci * cpacf_trng() - executes the TRNG subfunction of the PRNO instruction
4388c2ecf20Sopenharmony_ci * @ucbuf: buffer for unconditioned data
4398c2ecf20Sopenharmony_ci * @ucbuf_len: amount of unconditioned data to fetch in bytes
4408c2ecf20Sopenharmony_ci * @cbuf: buffer for conditioned data
4418c2ecf20Sopenharmony_ci * @cbuf_len: amount of conditioned data to fetch in bytes
4428c2ecf20Sopenharmony_ci */
4438c2ecf20Sopenharmony_cistatic inline void cpacf_trng(u8 *ucbuf, unsigned long ucbuf_len,
4448c2ecf20Sopenharmony_ci			      u8 *cbuf, unsigned long cbuf_len)
4458c2ecf20Sopenharmony_ci{
4468c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) CPACF_PRNO_TRNG;
4478c2ecf20Sopenharmony_ci	register unsigned long r2 asm("2") = (unsigned long) ucbuf;
4488c2ecf20Sopenharmony_ci	register unsigned long r3 asm("3") = (unsigned long) ucbuf_len;
4498c2ecf20Sopenharmony_ci	register unsigned long r4 asm("4") = (unsigned long) cbuf;
4508c2ecf20Sopenharmony_ci	register unsigned long r5 asm("5") = (unsigned long) cbuf_len;
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_ci	asm volatile (
4538c2ecf20Sopenharmony_ci		"0:	.insn	rre,%[opc] << 16,%[ucbuf],%[cbuf]\n"
4548c2ecf20Sopenharmony_ci		"	brc	1,0b\n"	  /* handle partial completion */
4558c2ecf20Sopenharmony_ci		: [ucbuf] "+a" (r2), [ucbuflen] "+d" (r3),
4568c2ecf20Sopenharmony_ci		  [cbuf] "+a" (r4), [cbuflen] "+d" (r5)
4578c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [opc] "i" (CPACF_PRNO)
4588c2ecf20Sopenharmony_ci		: "cc", "memory");
4598c2ecf20Sopenharmony_ci}
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci/**
4628c2ecf20Sopenharmony_ci * cpacf_pcc() - executes the PCC (PERFORM CRYPTOGRAPHIC COMPUTATION)
4638c2ecf20Sopenharmony_ci *		 instruction
4648c2ecf20Sopenharmony_ci * @func: the function code passed to PCC; see CPACF_KM_xxx defines
4658c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
4668c2ecf20Sopenharmony_ci */
4678c2ecf20Sopenharmony_cistatic inline void cpacf_pcc(unsigned long func, void *param)
4688c2ecf20Sopenharmony_ci{
4698c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
4708c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci	asm volatile(
4738c2ecf20Sopenharmony_ci		"0:	.insn	rre,%[opc] << 16,0,0\n" /* PCC opcode */
4748c2ecf20Sopenharmony_ci		"	brc	1,0b\n" /* handle partial completion */
4758c2ecf20Sopenharmony_ci		:
4768c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_PCC)
4778c2ecf20Sopenharmony_ci		: "cc", "memory");
4788c2ecf20Sopenharmony_ci}
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci/**
4818c2ecf20Sopenharmony_ci * cpacf_pckmo() - executes the PCKMO (PERFORM CRYPTOGRAPHIC KEY
4828c2ecf20Sopenharmony_ci *		  MANAGEMENT) instruction
4838c2ecf20Sopenharmony_ci * @func: the function code passed to PCKMO; see CPACF_PCKMO_xxx defines
4848c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
4858c2ecf20Sopenharmony_ci *
4868c2ecf20Sopenharmony_ci * Returns 0.
4878c2ecf20Sopenharmony_ci */
4888c2ecf20Sopenharmony_cistatic inline void cpacf_pckmo(long func, void *param)
4898c2ecf20Sopenharmony_ci{
4908c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
4918c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci	asm volatile(
4948c2ecf20Sopenharmony_ci		"       .insn   rre,%[opc] << 16,0,0\n" /* PCKMO opcode */
4958c2ecf20Sopenharmony_ci		:
4968c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_PCKMO)
4978c2ecf20Sopenharmony_ci		: "cc", "memory");
4988c2ecf20Sopenharmony_ci}
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_ci/**
5018c2ecf20Sopenharmony_ci * cpacf_kma() - executes the KMA (CIPHER MESSAGE WITH AUTHENTICATION)
5028c2ecf20Sopenharmony_ci *		 instruction
5038c2ecf20Sopenharmony_ci * @func: the function code passed to KMA; see CPACF_KMA_xxx defines
5048c2ecf20Sopenharmony_ci * @param: address of parameter block; see POP for details on each func
5058c2ecf20Sopenharmony_ci * @dest: address of destination memory area
5068c2ecf20Sopenharmony_ci * @src: address of source memory area
5078c2ecf20Sopenharmony_ci * @src_len: length of src operand in bytes
5088c2ecf20Sopenharmony_ci * @aad: address of additional authenticated data memory area
5098c2ecf20Sopenharmony_ci * @aad_len: length of aad operand in bytes
5108c2ecf20Sopenharmony_ci */
5118c2ecf20Sopenharmony_cistatic inline void cpacf_kma(unsigned long func, void *param, u8 *dest,
5128c2ecf20Sopenharmony_ci			     const u8 *src, unsigned long src_len,
5138c2ecf20Sopenharmony_ci			     const u8 *aad, unsigned long aad_len)
5148c2ecf20Sopenharmony_ci{
5158c2ecf20Sopenharmony_ci	register unsigned long r0 asm("0") = (unsigned long) func;
5168c2ecf20Sopenharmony_ci	register unsigned long r1 asm("1") = (unsigned long) param;
5178c2ecf20Sopenharmony_ci	register unsigned long r2 asm("2") = (unsigned long) src;
5188c2ecf20Sopenharmony_ci	register unsigned long r3 asm("3") = (unsigned long) src_len;
5198c2ecf20Sopenharmony_ci	register unsigned long r4 asm("4") = (unsigned long) aad;
5208c2ecf20Sopenharmony_ci	register unsigned long r5 asm("5") = (unsigned long) aad_len;
5218c2ecf20Sopenharmony_ci	register unsigned long r6 asm("6") = (unsigned long) dest;
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci	asm volatile(
5248c2ecf20Sopenharmony_ci		"0:	.insn	rrf,%[opc] << 16,%[dst],%[src],%[aad],0\n"
5258c2ecf20Sopenharmony_ci		"	brc	1,0b\n"	/* handle partial completion */
5268c2ecf20Sopenharmony_ci		: [dst] "+a" (r6), [src] "+a" (r2), [slen] "+d" (r3),
5278c2ecf20Sopenharmony_ci		  [aad] "+a" (r4), [alen] "+d" (r5)
5288c2ecf20Sopenharmony_ci		: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KMA)
5298c2ecf20Sopenharmony_ci		: "cc", "memory");
5308c2ecf20Sopenharmony_ci}
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_ci#endif	/* _ASM_S390_CPACF_H */
533