1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 *  Copyright IBM Corp. 2001, 2012
4 *  Author(s): Robert Burroughs
5 *	       Eric Rossman (edrossma@us.ibm.com)
6 *
7 *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
8 *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
9 *  MSGTYPE restruct:		  Holger Dengler <hd@linux.vnet.ibm.com>
10 */
11
12#ifndef _ZCRYPT_MSGTYPE6_H_
13#define _ZCRYPT_MSGTYPE6_H_
14
15#include <asm/zcrypt.h>
16
17#define MSGTYPE06_NAME			"zcrypt_msgtype6"
18#define MSGTYPE06_VARIANT_DEFAULT	0
19#define MSGTYPE06_VARIANT_NORNG		1
20#define MSGTYPE06_VARIANT_EP11		2
21
22/**
23 * The type 6 message family is associated with CEXxC/CEXxP cards.
24 *
25 * It contains a message header followed by a CPRB, both of which
26 * are described below.
27 *
28 * Note that all reserved fields must be zeroes.
29 */
30struct type6_hdr {
31	unsigned char reserved1;	/* 0x00				*/
32	unsigned char type;		/* 0x06				*/
33	unsigned char reserved2[2];	/* 0x0000			*/
34	unsigned char right[4];		/* 0x00000000			*/
35	unsigned char reserved3[2];	/* 0x0000			*/
36	unsigned char reserved4[2];	/* 0x0000			*/
37	unsigned char apfs[4];		/* 0x00000000			*/
38	unsigned int  offset1;		/* 0x00000058 (offset to CPRB)	*/
39	unsigned int  offset2;		/* 0x00000000			*/
40	unsigned int  offset3;		/* 0x00000000			*/
41	unsigned int  offset4;		/* 0x00000000			*/
42	unsigned char agent_id[16];	/* 0x4341000000000000		*/
43					/* 0x0000000000000000		*/
44	unsigned char rqid[2];		/* rqid.  internal to 603	*/
45	unsigned char reserved5[2];	/* 0x0000			*/
46	unsigned char function_code[2];	/* for PKD, 0x5044 (ascii 'PD')	*/
47	unsigned char reserved6[2];	/* 0x0000			*/
48	unsigned int  tocardlen1;	/* (request CPRB len + 3) & -4	*/
49	unsigned int  tocardlen2;	/* db len 0x00000000 for PKD	*/
50	unsigned int  tocardlen3;	/* 0x00000000			*/
51	unsigned int  tocardlen4;	/* 0x00000000			*/
52	unsigned int  fromcardlen1;	/* response buffer length	*/
53	unsigned int  fromcardlen2;	/* db len 0x00000000 for PKD	*/
54	unsigned int  fromcardlen3;	/* 0x00000000			*/
55	unsigned int  fromcardlen4;	/* 0x00000000			*/
56} __packed;
57
58/**
59 * The type 86 message family is associated with CEXxC/CEXxP cards.
60 *
61 * It contains a message header followed by a CPRB.  The CPRB is
62 * the same as the request CPRB, which is described above.
63 *
64 * If format is 1, an error condition exists and no data beyond
65 * the 8-byte message header is of interest.
66 *
67 * The non-error message is shown below.
68 *
69 * Note that all reserved fields must be zeroes.
70 */
71struct type86_hdr {
72	unsigned char reserved1;	/* 0x00				*/
73	unsigned char type;		/* 0x86				*/
74	unsigned char format;		/* 0x01 (error) or 0x02 (ok)	*/
75	unsigned char reserved2;	/* 0x00				*/
76	unsigned char reply_code;	/* reply code (see above)	*/
77	unsigned char reserved3[3];	/* 0x000000			*/
78} __packed;
79
80#define TYPE86_RSP_CODE 0x86
81#define TYPE87_RSP_CODE 0x87
82#define TYPE86_FMT2	0x02
83
84struct type86_fmt2_ext {
85	unsigned char	  reserved[4];	/* 0x00000000			*/
86	unsigned char	  apfs[4];	/* final status			*/
87	unsigned int	  count1;	/* length of CPRB + parameters	*/
88	unsigned int	  offset1;	/* offset to CPRB		*/
89	unsigned int	  count2;	/* 0x00000000			*/
90	unsigned int	  offset2;	/* db offset 0x00000000 for PKD	*/
91	unsigned int	  count3;	/* 0x00000000			*/
92	unsigned int	  offset3;	/* 0x00000000			*/
93	unsigned int	  count4;	/* 0x00000000			*/
94	unsigned int	  offset4;	/* 0x00000000			*/
95} __packed;
96
97int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
98		    struct ap_message *ap_msg,
99		    unsigned int *fc, unsigned short **dom);
100int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
101		     struct ap_message *ap_msg,
102		     unsigned int *fc, unsigned int *dom);
103int prep_rng_ap_msg(struct ap_message *ap_msg,
104		    int *fc, unsigned int *dom);
105
106#define LOW	10
107#define MEDIUM	100
108#define HIGH	500
109
110int speed_idx_cca(int);
111int speed_idx_ep11(int);
112
113/**
114 * Prepare a type6 CPRB message for random number generation
115 *
116 * @ap_dev: AP device pointer
117 * @ap_msg: pointer to AP message
118 */
119static inline void rng_type6cprb_msgx(struct ap_message *ap_msg,
120				      unsigned int random_number_length,
121				      unsigned int *domain)
122{
123	struct {
124		struct type6_hdr hdr;
125		struct CPRBX cprbx;
126		char function_code[2];
127		short int rule_length;
128		char rule[8];
129		short int verb_length;
130		short int key_length;
131	} __packed * msg = ap_msg->msg;
132	static struct type6_hdr static_type6_hdrX = {
133		.type		= 0x06,
134		.offset1	= 0x00000058,
135		.agent_id	= {'C', 'A'},
136		.function_code	= {'R', 'L'},
137		.tocardlen1	= sizeof(*msg) - sizeof(msg->hdr),
138		.fromcardlen1	= sizeof(*msg) - sizeof(msg->hdr),
139	};
140	static struct CPRBX local_cprbx = {
141		.cprb_len	= 0x00dc,
142		.cprb_ver_id	= 0x02,
143		.func_id	= {0x54, 0x32},
144		.req_parml	= sizeof(*msg) - sizeof(msg->hdr) -
145				  sizeof(msg->cprbx),
146		.rpl_msgbl	= sizeof(*msg) - sizeof(msg->hdr),
147	};
148
149	msg->hdr = static_type6_hdrX;
150	msg->hdr.fromcardlen2 = random_number_length;
151	msg->cprbx = local_cprbx;
152	msg->cprbx.rpl_datal = random_number_length;
153	memcpy(msg->function_code, msg->hdr.function_code, 0x02);
154	msg->rule_length = 0x0a;
155	memcpy(msg->rule, "RANDOM  ", 8);
156	msg->verb_length = 0x02;
157	msg->key_length = 0x02;
158	ap_msg->len = sizeof(*msg);
159	*domain = (unsigned short)msg->cprbx.domain;
160}
161
162void zcrypt_msgtype6_init(void);
163void zcrypt_msgtype6_exit(void);
164
165#endif /* _ZCRYPT_MSGTYPE6_H_ */
166