xref: /titanic_52/usr/src/uts/common/sys/crypto/dca.h (revision 436935a13231964207120b7e50a063b53b8e579c)
188f8b78aSgm89044 /*
288f8b78aSgm89044  * CDDL HEADER START
388f8b78aSgm89044  *
488f8b78aSgm89044  * The contents of this file are subject to the terms of the
588f8b78aSgm89044  * Common Development and Distribution License (the "License").
688f8b78aSgm89044  * You may not use this file except in compliance with the License.
788f8b78aSgm89044  *
888f8b78aSgm89044  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
988f8b78aSgm89044  * or http://www.opensolaris.org/os/licensing.
1088f8b78aSgm89044  * See the License for the specific language governing permissions
1188f8b78aSgm89044  * and limitations under the License.
1288f8b78aSgm89044  *
1388f8b78aSgm89044  * When distributing Covered Code, include this CDDL HEADER in each
1488f8b78aSgm89044  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1588f8b78aSgm89044  * If applicable, add the following below this CDDL HEADER, with the
1688f8b78aSgm89044  * fields enclosed by brackets "[]" replaced with your own identifying
1788f8b78aSgm89044  * information: Portions Copyright [yyyy] [name of copyright owner]
1888f8b78aSgm89044  *
1988f8b78aSgm89044  * CDDL HEADER END
2088f8b78aSgm89044  */
2188f8b78aSgm89044 
2288f8b78aSgm89044 /*
23*436935a1SVladimir Kotal  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2488f8b78aSgm89044  * Use is subject to license terms.
2588f8b78aSgm89044  */
2688f8b78aSgm89044 
2788f8b78aSgm89044 #ifndef	_SYS_CRYPTO_DCA_H
2888f8b78aSgm89044 #define	_SYS_CRYPTO_DCA_H
2988f8b78aSgm89044 
3088f8b78aSgm89044 #ifdef	__cplusplus
3188f8b78aSgm89044 extern "C" {
3288f8b78aSgm89044 #endif
3388f8b78aSgm89044 
3488f8b78aSgm89044 #include <sys/types.h>
3588f8b78aSgm89044 #include <sys/varargs.h>
3688f8b78aSgm89044 
3788f8b78aSgm89044 #include <sys/crypto/spi.h>
3888f8b78aSgm89044 
3988f8b78aSgm89044 /*
4088f8b78aSgm89044  * Deimos - cryptographic acceleration based upon Broadcom 582x.
4188f8b78aSgm89044  *
4288f8b78aSgm89044  * Note: Everything in this file is private to the Deimos device
4388f8b78aSgm89044  *	 driver!  Do not include this in any other file.
4488f8b78aSgm89044  */
4588f8b78aSgm89044 
4688f8b78aSgm89044 #define	DRIVER			"dca"
4788f8b78aSgm89044 #define	DCA_MANUFACTURER_ID	"SUNWdca"
4888f8b78aSgm89044 
4988f8b78aSgm89044 #ifdef _KERNEL
5088f8b78aSgm89044 
5188f8b78aSgm89044 /*
5288f8b78aSgm89044  * Tunables.
5388f8b78aSgm89044  */
5488f8b78aSgm89044 #define	MCR1LOWATER	16	/* these numbers favor overall throughput */
5588f8b78aSgm89044 #define	MCR1HIWATER	24
5688f8b78aSgm89044 #define	MCR1MAXREQS	8
5788f8b78aSgm89044 #define	MCR2LOWATER	16
5888f8b78aSgm89044 #define	MCR2HIWATER	24
5988f8b78aSgm89044 #define	MCR2MAXREQS	4
6088f8b78aSgm89044 #define	MAXMCR		2	/* there are 2 mcrs */
6188f8b78aSgm89044 #define	MAXREQSPERMCR	16	/* there are 4 subunits serviced by MCR2 */
6288f8b78aSgm89044 #define	MAXFRAGS	6	/* Limit on the number of fragments */
6388f8b78aSgm89044 #define	MAXWORK		6	/* How many work structures to preallocate */
6488f8b78aSgm89044 
6588f8b78aSgm89044 /*
6688f8b78aSgm89044  * These are constants.  Do not change them.
6788f8b78aSgm89044  */
6888f8b78aSgm89044 #if defined(i386) || defined(__i386) || defined(__amd64)
6988f8b78aSgm89044 #define	MAXPACKET	0xefff	/* rootnex INT_MAX_BUF hack. */
7088f8b78aSgm89044 #else
7188f8b78aSgm89044 #define	MAXPACKET	0xffff	/* Max size of a packet or fragment */
7288f8b78aSgm89044 #endif
7388f8b78aSgm89044 #define	DESBLOCK	8	/* Size of a DES or 3DES block */
7488f8b78aSgm89044 #define	DSAPARTLEN	20	/* Size of fixed DSA parts (r, s, q, x, v) */
7588f8b78aSgm89044 #define	DSASIGLEN	40	/* Size of a DSA signature */
7688f8b78aSgm89044 #define	SHA1LEN		20	/* Size of a SHA1 hash */
7788f8b78aSgm89044 #define	SECOND		1000000	/* One second in usec */
7888f8b78aSgm89044 #define	MSEC		1000	/* One millisecond in usec */
7988f8b78aSgm89044 #define	DES_KEYSIZE	8
8088f8b78aSgm89044 #define	DES_IV_LEN	8
8188f8b78aSgm89044 #define	DES3_KEYSIZE	(3 * DES_KEYSIZE)
8288f8b78aSgm89044 
8388f8b78aSgm89044 /*
8488f8b78aSgm89044  * Mechanism info structure passed to KCF during registration.
8588f8b78aSgm89044  */
8688f8b78aSgm89044 
8788f8b78aSgm89044 #define	MD5_HMAC_BLOCK_SIZE	64	/* MD5-HMAC block size */
8888f8b78aSgm89044 #define	MD5_HMAC_MIN_KEY_LEN	1	/* MD5-HMAC min key length in bytes */
8988f8b78aSgm89044 #define	MD5_HMAC_MAX_KEY_LEN	64	/* MD5-HMAC max key length in bytes */
9088f8b78aSgm89044 
9188f8b78aSgm89044 #define	SHA1_HMAC_BLOCK_SIZE	64	/* SHA1-HMAC block size */
9288f8b78aSgm89044 #define	SHA1_HMAC_MIN_KEY_LEN	1	/* SHA1-HMAC min key length in bytes */
9388f8b78aSgm89044 #define	SHA1_HMAC_MAX_KEY_LEN	64	/* SHA1-HMAC max key length in bytes */
9488f8b78aSgm89044 
9588f8b78aSgm89044 #define	DES_KEY_LEN		8	/* DES key length in bytes */
96*436935a1SVladimir Kotal #define	DES3_MIN_KEY_LEN	16	/* 3DES min key length in bytes */
97*436935a1SVladimir Kotal #define	DES3_MAX_KEY_LEN	24	/* 3DES max key length in bytes */
9888f8b78aSgm89044 
9988f8b78aSgm89044 #define	DSA_MIN_KEY_LEN		64	/* DSA min key length in bytes */
10088f8b78aSgm89044 #define	DSA_MAX_KEY_LEN		128	/* DSA max key length in bytes */
10188f8b78aSgm89044 
10288f8b78aSgm89044 #define	RSA_MIN_KEY_LEN		32	/* RSA min key length in bytes */
10388f8b78aSgm89044 #define	RSA_MAX_KEY_LEN		256	/* RSA max key length in bytes */
10488f8b78aSgm89044 
10588f8b78aSgm89044 /*
10688f8b78aSgm89044  * RSA implementation.
10788f8b78aSgm89044  */
10888f8b78aSgm89044 
10988f8b78aSgm89044 #define	DCA_RSA_ENC	0
11088f8b78aSgm89044 #define	DCA_RSA_DEC	1
11188f8b78aSgm89044 #define	DCA_RSA_SIGN	2
11288f8b78aSgm89044 #define	DCA_RSA_VRFY	3
11388f8b78aSgm89044 #define	DCA_RSA_SIGNR	4
11488f8b78aSgm89044 #define	DCA_RSA_VRFYR	5
11588f8b78aSgm89044 
11688f8b78aSgm89044 /*
11788f8b78aSgm89044  * DSA implementation.
11888f8b78aSgm89044  */
11988f8b78aSgm89044 
12088f8b78aSgm89044 #define	DCA_DSA_SIGN	0
12188f8b78aSgm89044 #define	DCA_DSA_VRFY	1
12288f8b78aSgm89044 
12388f8b78aSgm89044 /*
12488f8b78aSgm89044  * FMA eclass index definitions. Note that this enum must be consistent
12588f8b78aSgm89044  * with the dca_fma_eclass_sca1000 and dca_fma_eclass_sca500 string arrays.
12688f8b78aSgm89044  */
12788f8b78aSgm89044 typedef enum dca_fma_eclass {
12888f8b78aSgm89044 	DCA_FM_ECLASS_HW_DEVICE = 0,
12988f8b78aSgm89044 	DCA_FM_ECLASS_HW_TIMEOUT,
13088f8b78aSgm89044 	DCA_FM_ECLASS_NONE
13188f8b78aSgm89044 } dca_fma_eclass_t;
13288f8b78aSgm89044 
13388f8b78aSgm89044 /*
13488f8b78aSgm89044  * Forward typedefs.
13588f8b78aSgm89044  */
13688f8b78aSgm89044 typedef struct dca dca_t;
13788f8b78aSgm89044 typedef struct dca_chain dca_chain_t;
13888f8b78aSgm89044 typedef struct dca_listnode dca_listnode_t;
13988f8b78aSgm89044 typedef struct dca_worklist dca_worklist_t;
14088f8b78aSgm89044 typedef struct dca_work dca_work_t;
14188f8b78aSgm89044 typedef struct dca_request dca_request_t;
14288f8b78aSgm89044 typedef struct dca_stat dca_stat_t;
14388f8b78aSgm89044 typedef struct dca_cookie dca_cookie_t;
14488f8b78aSgm89044 typedef struct dca_device dca_device_t;
14588f8b78aSgm89044 
14688f8b78aSgm89044 /*
14788f8b78aSgm89044  * This structure is used to identify a specific board.
14888f8b78aSgm89044  */
14988f8b78aSgm89044 struct dca_device {
15088f8b78aSgm89044 	ushort_t		dd_vendor_id;
15188f8b78aSgm89044 	ushort_t		dd_device_id;
15288f8b78aSgm89044 	char			*dd_model;
15388f8b78aSgm89044 };
15488f8b78aSgm89044 
15588f8b78aSgm89044 /*
15688f8b78aSgm89044  * Structure representing a node in a DMA chain.  (Broadcom calls
15788f8b78aSgm89044  * these "Data Buffer Chain Entries".)
15888f8b78aSgm89044  *
15988f8b78aSgm89044  * note, this structure must be a multiple of sizeof (intptr_t)
16088f8b78aSgm89044  */
16188f8b78aSgm89044 struct dca_chain {
16288f8b78aSgm89044 	/* the descriptor */
16388f8b78aSgm89044 	caddr_t			dc_desc_kaddr;
16488f8b78aSgm89044 	/* and the buffer to which it points */
16588f8b78aSgm89044 	size_t			dc_buffer_length;
16688f8b78aSgm89044 	ddi_dma_handle_t	dc_buffer_dmah;
16788f8b78aSgm89044 	caddr_t			dc_buffer_kaddr;
16888f8b78aSgm89044 	/* physical addresses */
16988f8b78aSgm89044 	uint32_t		dc_desc_paddr;
17088f8b78aSgm89044 	uint32_t		dc_buffer_paddr;
17188f8b78aSgm89044 	uint32_t		dc_next_paddr;
17288f8b78aSgm89044 };
17388f8b78aSgm89044 
17488f8b78aSgm89044 /*
17588f8b78aSgm89044  * Linked-list linkage.
17688f8b78aSgm89044  */
17788f8b78aSgm89044 struct dca_listnode {
17888f8b78aSgm89044 	dca_listnode_t		*dl_next;
17988f8b78aSgm89044 	dca_listnode_t		*dl_prev;
18088f8b78aSgm89044 	dca_listnode_t		*dl_next2;
18188f8b78aSgm89044 	dca_listnode_t		*dl_prev2;
18288f8b78aSgm89044 };
18388f8b78aSgm89044 
18488f8b78aSgm89044 typedef enum dca_mech_type {
18588f8b78aSgm89044 	DES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_DES_CBC */
18688f8b78aSgm89044 	DES3_CBC_MECH_INFO_TYPE,	/* SUN_CKM_DES3_CBC */
18788f8b78aSgm89044 	DSA_MECH_INFO_TYPE,		/* SUN_CKM_DSA */
18888f8b78aSgm89044 	RSA_X_509_MECH_INFO_TYPE,	/* SUN_CKM_RSA_X_509 */
18988f8b78aSgm89044 	RSA_PKCS_MECH_INFO_TYPE		/* SUN_CKM_RSA_PKCS */
19088f8b78aSgm89044 } dca_mech_type_t;
19188f8b78aSgm89044 
19288f8b78aSgm89044 #define	SUN_CKM_DSA			"CKM_DSA"
19388f8b78aSgm89044 
19488f8b78aSgm89044 struct dca_rng {
19588f8b78aSgm89044 	uint32_t		dr_chunklen;
19688f8b78aSgm89044 };
19788f8b78aSgm89044 
19888f8b78aSgm89044 union dca_parameters {
19988f8b78aSgm89044 	struct dca_rng		dp_rng;
20088f8b78aSgm89044 };
20188f8b78aSgm89044 
20288f8b78aSgm89044 typedef struct dca_ctx {
20388f8b78aSgm89044 	/*
20488f8b78aSgm89044 	 * The following are context fields for Deimos 2.0.
20588f8b78aSgm89044 	 */
20688f8b78aSgm89044 	crypto_mech_type_t	ctx_cm_type;	/* Mechanism type */
20788f8b78aSgm89044 	int			mode;		/* Mode of operation */
20888f8b78aSgm89044 	int 			atomic;		/* Boolean */
20988f8b78aSgm89044 
21088f8b78aSgm89044 	/* Fields for RSA and DSA */
21188f8b78aSgm89044 	uchar_t			*mod;		/* RSA modulus */
21288f8b78aSgm89044 	unsigned		modlen;		/* RSA modulus length */
21388f8b78aSgm89044 	unsigned		pqfix;		/* RSA flag */
21488f8b78aSgm89044 
21588f8b78aSgm89044 	/* Fields for DES and 3DES */
21688f8b78aSgm89044 	uint32_t		iv[2];
21788f8b78aSgm89044 	uint32_t		key[6];
21888f8b78aSgm89044 	int			residlen;
21988f8b78aSgm89044 	uchar_t			resid[DESBLOCK];
22088f8b78aSgm89044 	int			activeresidlen;
22188f8b78aSgm89044 	uchar_t			activeresid[DESBLOCK];
22288f8b78aSgm89044 	crypto_data_t		in_dup;		/* input data duplicate */
22388f8b78aSgm89044 } dca_ctx_t;
22488f8b78aSgm89044 
22588f8b78aSgm89044 /*
22688f8b78aSgm89044  * Work structure.  One of these per actual job submitted to an MCR.
22788f8b78aSgm89044  * Contains everything we need to submit the job, and everything we
22888f8b78aSgm89044  * need to notify caller and release resources when the completion
22988f8b78aSgm89044  * interrupt comes.
23088f8b78aSgm89044  */
23188f8b78aSgm89044 struct dca_request {
23288f8b78aSgm89044 	dca_listnode_t		dr_linkage;
23388f8b78aSgm89044 	uint16_t		dr_pkt_length;
23488f8b78aSgm89044 	crypto_req_handle_t	dr_kcf_req;
23588f8b78aSgm89044 	dca_t			*dr_dca;
23688f8b78aSgm89044 	dca_worklist_t		*dr_wlp;
23788f8b78aSgm89044 	/*
23888f8b78aSgm89044 	 * Consumer's I/O buffers.
23988f8b78aSgm89044 	 */
24088f8b78aSgm89044 	crypto_data_t		*dr_in;
24188f8b78aSgm89044 	crypto_data_t		*dr_out;
24288f8b78aSgm89044 	dca_ctx_t		dr_ctx;
24388f8b78aSgm89044 	/*
24488f8b78aSgm89044 	 * Chains and DMA structures.
24588f8b78aSgm89044 	 */
24688f8b78aSgm89044 	size_t			dr_dma_size;
24788f8b78aSgm89044 	uint32_t		dr_ctx_paddr;
24888f8b78aSgm89044 	caddr_t			dr_ctx_kaddr;
24988f8b78aSgm89044 	ddi_acc_handle_t	dr_ctx_acch;
25088f8b78aSgm89044 	ddi_dma_handle_t	dr_ctx_dmah;
25188f8b78aSgm89044 	/*
25288f8b78aSgm89044 	 * Scratch input buffer.
25388f8b78aSgm89044 	 */
25488f8b78aSgm89044 	ddi_acc_handle_t	dr_ibuf_acch;
25588f8b78aSgm89044 	ddi_dma_handle_t	dr_ibuf_dmah;
25688f8b78aSgm89044 	caddr_t			dr_ibuf_kaddr;
25788f8b78aSgm89044 	uint32_t		dr_ibuf_paddr;
25888f8b78aSgm89044 
25988f8b78aSgm89044 	/*
26088f8b78aSgm89044 	 * Scratch output buffer.
26188f8b78aSgm89044 	 */
26288f8b78aSgm89044 	ddi_acc_handle_t	dr_obuf_acch;
26388f8b78aSgm89044 	ddi_dma_handle_t	dr_obuf_dmah;
26488f8b78aSgm89044 	caddr_t			dr_obuf_kaddr;
26588f8b78aSgm89044 	uint32_t		dr_obuf_paddr;
26688f8b78aSgm89044 
26788f8b78aSgm89044 	/*
26888f8b78aSgm89044 	 * Values to program MCR with.
26988f8b78aSgm89044 	 */
27088f8b78aSgm89044 	uint32_t		dr_in_paddr;
27188f8b78aSgm89044 	uint32_t		dr_out_paddr;
27288f8b78aSgm89044 	uint32_t		dr_in_next;
27388f8b78aSgm89044 	uint32_t		dr_out_next;
27488f8b78aSgm89044 	uint16_t		dr_in_len;
27588f8b78aSgm89044 	uint16_t		dr_out_len;
27688f8b78aSgm89044 	/*
27788f8b78aSgm89044 	 * Callback.
27888f8b78aSgm89044 	 */
27988f8b78aSgm89044 	void			(*dr_callback)(dca_request_t *, int);
28088f8b78aSgm89044 	/*
28188f8b78aSgm89044 	 * Other stuff.
28288f8b78aSgm89044 	 */
28388f8b78aSgm89044 	uint32_t		dr_flags;
28488f8b78aSgm89044 	/*
28588f8b78aSgm89044 	 * Algorithm specific parameters.
28688f8b78aSgm89044 	 */
28788f8b78aSgm89044 	void			*dr_context;
28888f8b78aSgm89044 	union dca_parameters	dr_param;
28988f8b78aSgm89044 	/*
29088f8b78aSgm89044 	 * Statistics.
29188f8b78aSgm89044 	 */
29288f8b78aSgm89044 	int			dr_job_stat;
29388f8b78aSgm89044 	int			dr_byte_stat;
29488f8b78aSgm89044 
29588f8b78aSgm89044 	/* Pre-mapped input and output data buffer chain support */
29688f8b78aSgm89044 	dca_chain_t		dr_ibuf_head;
29788f8b78aSgm89044 	dca_chain_t		dr_obuf_head;
29888f8b78aSgm89044 
29988f8b78aSgm89044 	/*
30088f8b78aSgm89044 	 * User buffers are mapped to DMA handles dynamically. The physically
30188f8b78aSgm89044 	 * contigous blocks ( >= a page) are built into a data buffer chain.
30288f8b78aSgm89044 	 */
30388f8b78aSgm89044 	dca_chain_t		dr_chain_in_head;
30488f8b78aSgm89044 	ddi_dma_handle_t	dr_chain_in_dmah;
30588f8b78aSgm89044 
30688f8b78aSgm89044 	dca_chain_t		dr_chain_out_head;
30788f8b78aSgm89044 	ddi_dma_handle_t	dr_chain_out_dmah;
30888f8b78aSgm89044 
30988f8b78aSgm89044 	/* Offset in the context page for storing dynamic buffer chains */
31088f8b78aSgm89044 	int			dr_offset;
31188f8b78aSgm89044 
31288f8b78aSgm89044 	/* Destroy this request if true */
31388f8b78aSgm89044 	int			destroy;
31488f8b78aSgm89044 };
31588f8b78aSgm89044 
31688f8b78aSgm89044 /*
31788f8b78aSgm89044  * Request flags (dca_request_t.dr_flags).
31888f8b78aSgm89044  */
31988f8b78aSgm89044 #define	DR_INPLACE		0x002
32088f8b78aSgm89044 #define	DR_SCATTER		0x004
32188f8b78aSgm89044 #define	DR_GATHER		0x008
32288f8b78aSgm89044 #define	DR_NOCACHE		0x020
32388f8b78aSgm89044 #define	DR_ENCRYPT		0x040
32488f8b78aSgm89044 #define	DR_DECRYPT		0x080
32588f8b78aSgm89044 #define	DR_TRIPLE		0x100	/* triple DES vs. single DES */
32688f8b78aSgm89044 #define	DR_ATOMIC		0x200	/* for atomic operation */
32788f8b78aSgm89044 
32888f8b78aSgm89044 struct dca_work {
32988f8b78aSgm89044 	dca_listnode_t		dw_linkage;
33088f8b78aSgm89044 	dca_worklist_t		*dw_wlp;
33188f8b78aSgm89044 
33288f8b78aSgm89044 	/* DMA access to the MCR and context */
33388f8b78aSgm89044 	ddi_acc_handle_t	dw_mcr_acch;
33488f8b78aSgm89044 	ddi_dma_handle_t	dw_mcr_dmah;
33588f8b78aSgm89044 	caddr_t			dw_mcr_kaddr;
33688f8b78aSgm89044 	uint32_t		dw_mcr_paddr;
33788f8b78aSgm89044 
33888f8b78aSgm89044 	dca_request_t		*dw_reqs[MAXREQSPERMCR];
33988f8b78aSgm89044 	clock_t			dw_lbolt;
34088f8b78aSgm89044 };
34188f8b78aSgm89044 
34288f8b78aSgm89044 /*
34388f8b78aSgm89044  * MCRs.
34488f8b78aSgm89044  */
34588f8b78aSgm89044 #define	MCR1			0x1
34688f8b78aSgm89044 #define	MCR2			0x2
34788f8b78aSgm89044 
34888f8b78aSgm89044 struct dca_worklist {
34988f8b78aSgm89044 	dca_t			*dwl_dca;
35088f8b78aSgm89044 	crypto_kcf_provider_handle_t	dwl_prov;
35188f8b78aSgm89044 	char			dwl_name[16];
35288f8b78aSgm89044 	int			dwl_mcr;
35388f8b78aSgm89044 	kmutex_t		dwl_lock;
3543383b6ddSqs148142 	kmutex_t		dwl_freelock;
35588f8b78aSgm89044 	kmutex_t		dwl_freereqslock;
35688f8b78aSgm89044 	kcondvar_t		dwl_cv;
35788f8b78aSgm89044 	dca_listnode_t		dwl_freereqs;	/* available requests */
35888f8b78aSgm89044 	dca_listnode_t		dwl_waitq;	/* requests arrive here */
35988f8b78aSgm89044 	dca_listnode_t		dwl_freework;	/* available work structures */
36088f8b78aSgm89044 	dca_listnode_t		dwl_runq;	/* work structs sent to chip */
36188f8b78aSgm89044 	timeout_id_t		dwl_schedtid;
36288f8b78aSgm89044 	clock_t			dwl_lastsubmit;
36388f8b78aSgm89044 	int			dwl_count;
36488f8b78aSgm89044 	int			dwl_busy;
36588f8b78aSgm89044 	int			dwl_lowater;
36688f8b78aSgm89044 	int			dwl_hiwater;
36788f8b78aSgm89044 	int			dwl_reqspermcr;
36888f8b78aSgm89044 	int			dwl_drain;	/* for DR (suspend) */
36988f8b78aSgm89044 	/* Kstats */
37088f8b78aSgm89044 	u_longlong_t		dwl_submit;
37188f8b78aSgm89044 	u_longlong_t		dwl_flowctl;
37288f8b78aSgm89044 };
37388f8b78aSgm89044 
37488f8b78aSgm89044 /*
37588f8b78aSgm89044  * Operations for MCR1 (bulk stuff).
37688f8b78aSgm89044  */
37788f8b78aSgm89044 #define	CMD_IPSEC		0x0	/* IPsec packet processing */
37888f8b78aSgm89044 #define	CMD_SSLMAC		0x1	/* SSL HMAC processing */
37988f8b78aSgm89044 #define	CMD_TLSMAC		0x2	/* TLS HMAC processing */
38088f8b78aSgm89044 #define	CMD_3DES		0x3	/* SSL/TLS/raw 3DES processing */
38188f8b78aSgm89044 #define	CMD_RC4			0x4	/* ARCFOUR procesing */
38288f8b78aSgm89044 #define	CMD_PUREHASH		0x5	/* Pure MD5/SHA1 hash processing */
38388f8b78aSgm89044 
38488f8b78aSgm89044 /*
38588f8b78aSgm89044  * Operations for MCR2 (key stuff).
38688f8b78aSgm89044  */
38788f8b78aSgm89044 #define	CMD_DHPUBLIC		0x1	/* DH public key generation */
38888f8b78aSgm89044 #define	CMD_DHSHARED		0x2	/* DH shared secret generation */
38988f8b78aSgm89044 #define	CMD_RSAPUBLIC		0x3	/* RSA public key operation */
39088f8b78aSgm89044 #define	CMD_RSAPRIVATE		0x4	/* RSA private key operation (CRT) */
39188f8b78aSgm89044 #define	CMD_DSASIGN		0x5	/* DSA signing operation */
39288f8b78aSgm89044 #define	CMD_DSAVERIFY		0x6	/* DSA verification operation */
39388f8b78aSgm89044 #define	CMD_RNGDIRECT		0x41	/* Direct access to the RNG */
39488f8b78aSgm89044 #define	CMD_RNGSHA1		0x42	/* RNG output processed by SHA1 */
39588f8b78aSgm89044 #define	CMD_MODADD		0x43	/* Modular add */
39688f8b78aSgm89044 #define	CMD_MODSUB		0x44	/* Moduler subtract */
39788f8b78aSgm89044 #define	CMD_MODMUL		0x45	/* Modular multiply */
39888f8b78aSgm89044 #define	CMD_MODREM		0x46	/* Modular remainder */
39988f8b78aSgm89044 #define	CMD_MODEXP		0x47	/* Modular exponentiation */
40088f8b78aSgm89044 #define	CMD_MODINV		0x48	/* Modular inverse */
40188f8b78aSgm89044 
40288f8b78aSgm89044 /*
40388f8b78aSgm89044  * Kstats.
40488f8b78aSgm89044  */
40588f8b78aSgm89044 #define	DS_3DESJOBS		0
40688f8b78aSgm89044 #define	DS_3DESBYTES		1
40788f8b78aSgm89044 #define	DS_RSAPUBLIC		2
40888f8b78aSgm89044 #define	DS_RSAPRIVATE		3
40988f8b78aSgm89044 #define	DS_DSASIGN		4
41088f8b78aSgm89044 #define	DS_DSAVERIFY		5
41188f8b78aSgm89044 #define	DS_RNGJOBS		6
41288f8b78aSgm89044 #define	DS_RNGBYTES		7
41388f8b78aSgm89044 #define	DS_RNGSHA1JOBS		8
41488f8b78aSgm89044 #define	DS_RNGSHA1BYTES		9
41588f8b78aSgm89044 #define	DS_MAX			10
41688f8b78aSgm89044 
41788f8b78aSgm89044 #if 0
41888f8b78aSgm89044 /*
41988f8b78aSgm89044  * note that when reenabling any of these stats, DS_MAX will need to
42088f8b78aSgm89044  * be adjusted.
42188f8b78aSgm89044  */
42288f8b78aSgm89044 #define	DS_RC4JOBS		11
42388f8b78aSgm89044 #define	DS_RC4BYTES		12
42488f8b78aSgm89044 #define	DS_DHPUBLIC		13
42588f8b78aSgm89044 #define	DS_DHSECRET		14
42688f8b78aSgm89044 #endif
42788f8b78aSgm89044 
42888f8b78aSgm89044 struct dca_stat {
42988f8b78aSgm89044 	kstat_named_t		ds_status;
43088f8b78aSgm89044 	kstat_named_t		ds_algs[DS_MAX];
43188f8b78aSgm89044 	struct {
43288f8b78aSgm89044 		kstat_named_t	ds_submit;
43388f8b78aSgm89044 		kstat_named_t	ds_flowctl;
43488f8b78aSgm89044 		kstat_named_t	ds_lowater;
43588f8b78aSgm89044 		kstat_named_t	ds_hiwater;
43688f8b78aSgm89044 		kstat_named_t	ds_maxreqs;
43788f8b78aSgm89044 	}			ds_mcr[MAXMCR];
43888f8b78aSgm89044 };
43988f8b78aSgm89044 
44088f8b78aSgm89044 /*
44188f8b78aSgm89044  * Blocking structure for ioctls.
44288f8b78aSgm89044  */
44388f8b78aSgm89044 struct dca_cookie {
44488f8b78aSgm89044 	kmutex_t		dc_mx;
44588f8b78aSgm89044 	kcondvar_t		dc_cv;
44688f8b78aSgm89044 	int			dc_outstanding;
44788f8b78aSgm89044 	int			dc_status;
44888f8b78aSgm89044 };
44988f8b78aSgm89044 
45088f8b78aSgm89044 /*
45188f8b78aSgm89044  * Per instance structure.
45288f8b78aSgm89044  */
45388f8b78aSgm89044 struct dca {
45488f8b78aSgm89044 	dev_info_t		*dca_dip;
45588f8b78aSgm89044 	kmutex_t		dca_intrlock;
45688f8b78aSgm89044 	caddr_t			dca_regs;
45788f8b78aSgm89044 	ddi_acc_handle_t	dca_regs_handle;
45888f8b78aSgm89044 	ddi_iblock_cookie_t	dca_icookie;
45988f8b78aSgm89044 	timeout_id_t		dca_jobtid;
46088f8b78aSgm89044 	ulong_t			dca_pagesize;
46188f8b78aSgm89044 	unsigned		dca_flags;	/* dev state flags */
46288f8b78aSgm89044 
46388f8b78aSgm89044 	/*
46488f8b78aSgm89044 	 * Work requests.
46588f8b78aSgm89044 	 */
46688f8b78aSgm89044 	dca_worklist_t		dca_worklist[MAXMCR];
46788f8b78aSgm89044 
46888f8b78aSgm89044 	/*
46988f8b78aSgm89044 	 * hardware model
47088f8b78aSgm89044 	 */
47188f8b78aSgm89044 	char			*dca_model;
4723383b6ddSqs148142 	ushort_t		dca_devid;
47388f8b78aSgm89044 
47488f8b78aSgm89044 	/*
47588f8b78aSgm89044 	 * Kstats.  There is no standard for what standards
47688f8b78aSgm89044 	 * Cryptographic Providers should supply, so we're
47788f8b78aSgm89044 	 * making them up for now.
47888f8b78aSgm89044 	 */
47988f8b78aSgm89044 	kstat_t			*dca_ksp;
48088f8b78aSgm89044 	kstat_t			*dca_intrstats;
48188f8b78aSgm89044 	u_longlong_t		dca_stats[DS_MAX];
48288f8b78aSgm89044 
48388f8b78aSgm89044 	/* For the local random number pool used internally by the dca driver */
48488f8b78aSgm89044 	char 			*dca_buf1;
48588f8b78aSgm89044 	char 			*dca_buf2;
48688f8b78aSgm89044 	char 			*dca_buf_ptr;
48788f8b78aSgm89044 	int 			dca_index;
48888f8b78aSgm89044 	uint32_t 		dca_random_filling;
48988f8b78aSgm89044 	kmutex_t 		dca_random_lock;
49088f8b78aSgm89044 
49188f8b78aSgm89044 	/* FMA capabilities */
49288f8b78aSgm89044 	int			fm_capabilities;	/* FMA capabilities */
49388f8b78aSgm89044 
49488f8b78aSgm89044 	kmutex_t		dca_ctx_list_lock;
49588f8b78aSgm89044 	dca_listnode_t		dca_ctx_list;
49688f8b78aSgm89044 };
49788f8b78aSgm89044 
49888f8b78aSgm89044 /*
49988f8b78aSgm89044  * Device flags (dca_t.dca_flags)
50088f8b78aSgm89044  */
50188f8b78aSgm89044 #define	DCA_FAILED		0x1
50288f8b78aSgm89044 #define	DCA_POWERMGMT		0x4
50388f8b78aSgm89044 #define	DCA_RNGSHA1		0x8
50488f8b78aSgm89044 
50588f8b78aSgm89044 #define	KIOIP(dca)		KSTAT_INTR_PTR((dca)->dca_intrstats)
50688f8b78aSgm89044 
50788f8b78aSgm89044 /*
50888f8b78aSgm89044  * Scatter/gather checks.
50988f8b78aSgm89044  */
51088f8b78aSgm89044 typedef enum dca_sg_param {
51188f8b78aSgm89044 	DCA_SG_CONTIG = 1,
51288f8b78aSgm89044 	DCA_SG_WALIGN,
51388f8b78aSgm89044 	DCA_SG_PALIGN
51488f8b78aSgm89044 } dca_sg_param_t;
51588f8b78aSgm89044 
51688f8b78aSgm89044 #define	FALSE		0
51788f8b78aSgm89044 #define	TRUE		1
51888f8b78aSgm89044 
51988f8b78aSgm89044 /*
52088f8b78aSgm89044  * PCI configuration registers.
52188f8b78aSgm89044  */
52288f8b78aSgm89044 #define	PCI_VENID		0x00	/* vendor id, 16 bits */
52388f8b78aSgm89044 #define	PCI_DEVID		0x02	/* device id, 16 bits */
52488f8b78aSgm89044 #define	PCI_COMM		0x04	/* command, 16 bits */
52588f8b78aSgm89044 #define	PCI_STATUS		0x06	/* status, 16 bits */
52688f8b78aSgm89044 #define	PCI_REVID		0x08	/* revision id, 8 bits */
52788f8b78aSgm89044 #define	PCI_PROGCLASS		0x09	/* programming class, 8 bits */
52888f8b78aSgm89044 #define	PCI_SUBCLASS		0x0A	/* subclass, 8 bits */
52988f8b78aSgm89044 #define	PCI_CACHELINESZ		0x0C	/* cache line size, 8 bits */
53088f8b78aSgm89044 #define	PCI_LATTMR		0x0D	/* latency timer, 8 bits */
53188f8b78aSgm89044 #define	PCI_BIST		0x0F	/* builtin-self-test, 8 bits */
53288f8b78aSgm89044 #define	PCI_SUBVENID		0x2C	/* subsystem vendor id, 16 bits */
53388f8b78aSgm89044 #define	PCI_SUBSYSID		0x2E	/* subsystem id, 16 bits */
53488f8b78aSgm89044 #define	PCI_MINGNT		0x3E	/* min grant for burst, 8 bits */
53588f8b78aSgm89044 #define	PCI_MAXLAT		0x3F	/* maximum grant for burst, 8 bits */
53688f8b78aSgm89044 #define	PCI_TRDYTO		0x40	/* TRDY timeout, 8 bits */
53788f8b78aSgm89044 #define	PCI_RETRIES		0x41	/* retries bus will perform, 8 bits */
53888f8b78aSgm89044 
53988f8b78aSgm89044 /*
54088f8b78aSgm89044  * PCI configuration register bit values.
54188f8b78aSgm89044  */
54288f8b78aSgm89044 #define	PCICOMM_FBBE		0x0200	/* fast back-to-back enable */
54388f8b78aSgm89044 #define	PCICOMM_SEE		0x0100	/* system error enable */
54488f8b78aSgm89044 #define	PCICOMM_PEE		0x0040	/* parity error enable */
54588f8b78aSgm89044 #define	PCICOMM_MWIE		0x0010	/* memory write & invalidate enable */
54688f8b78aSgm89044 #define	PCICOMM_BME		0x0004	/* bus master enable */
54788f8b78aSgm89044 #define	PCICOMM_MAE		0x0002	/* memory access enable */
54888f8b78aSgm89044 
54988f8b78aSgm89044 #define	PCISTAT_PERR		0x8000	/* parity error detected */
55088f8b78aSgm89044 #define	PCISTAT_SERR		0x4000	/* system error detected */
55188f8b78aSgm89044 #define	PCISTAT_MABRT		0x2000	/* master abort detected */
55288f8b78aSgm89044 #define	PCISTAT_TABRT		0x1000	/* target abort detected */
55388f8b78aSgm89044 #define	PCISTAT_TABRTS		0x0800	/* target abort signaled */
55488f8b78aSgm89044 #define	PCISTAT_PARITY		0x0100	/* data parity error detected */
55588f8b78aSgm89044 
55688f8b78aSgm89044 #define	PCIREVID_DOMESTIC	0x01	/* domestic version */
55788f8b78aSgm89044 #define	PCIREVID_EXPORT		0xE1	/* export version */
55888f8b78aSgm89044 
55988f8b78aSgm89044 /* Note: 5820 errata: BIST feature does not work */
56088f8b78aSgm89044 #define	PCIBIST_CAP		0x80	/* BIST capable */
56188f8b78aSgm89044 #define	PCIBIST_START		0x40	/* start BIST test */
56288f8b78aSgm89044 #define	PCIBIST_ERRMASK		0x0F	/* mask of BIST error codes */
56388f8b78aSgm89044 
56488f8b78aSgm89044 /*
56588f8b78aSgm89044  * Command and Status Registers.
56688f8b78aSgm89044  */
56788f8b78aSgm89044 #define	CSR_MCR1		0x00	/* pointer to MCR1 (bulk) */
56888f8b78aSgm89044 #define	CSR_DMACTL		0x04	/* DMA control */
56988f8b78aSgm89044 #define	CSR_DMASTAT		0x08	/* DMA status */
57088f8b78aSgm89044 #define	CSR_DMAEA		0x0C	/* DMA error address */
57188f8b78aSgm89044 #define	CSR_MCR2		0x10	/* pointer to MCR2 (exponentiator) */
57288f8b78aSgm89044 
57388f8b78aSgm89044 /*
57488f8b78aSgm89044  * Command and status register bits.
57588f8b78aSgm89044  */
57688f8b78aSgm89044 #define	DMACTL_RESET		0x80000000U	/* reset the chip */
57788f8b78aSgm89044 #define	DMACTL_MCR2IE		0x40000000U	/* MCR2 interrupt enable */
57888f8b78aSgm89044 #define	DMACTL_MCR1IE		0x20000000U	/* MCR1 interrupt enable */
57988f8b78aSgm89044 #define	DMACTL_OFM		0x10000000U	/* output fragment mode */
58088f8b78aSgm89044 #define	DMACTL_BE32		0x08000000U	/* 32-bit big endian mode */
58188f8b78aSgm89044 #define	DMACTL_BE64		0x04000000U	/* 64-bit big endian mode */
58288f8b78aSgm89044 #define	DMACTL_EIE		0x02000000U	/* error interrupt enable */
58388f8b78aSgm89044 #define	DMACTL_RNGMASK		0x01800000U	/* RNG mode mask */
58488f8b78aSgm89044 #define	DMACTL_RNG1		0x00000000U	/* 1 RNG bit per cycle */
58588f8b78aSgm89044 #define	DMACTL_RNG4		0x00800000U	/* 1 RNG bit per 4 cycles */
58688f8b78aSgm89044 #define	DMACTL_RNG8		0x01000000U	/* 1 RNG bit per 8 cycles */
58788f8b78aSgm89044 #define	DMACTL_RNG16		0x01800000U	/* 1 RNG bit per 16 cycles */
58888f8b78aSgm89044 #define	DMACTL_MODNORM		0x00400000U	/* s/w modulus normalization */
5893383b6ddSqs148142 #define	DMACTL_RD256		0x00020000U	/* 256 byte read DMA size */
59088f8b78aSgm89044 #define	DMACTL_FRAGMASK		0x0000FFFFU	/* output fragment size */
59188f8b78aSgm89044 
59288f8b78aSgm89044 #define	DMASTAT_MAIP		0x80000000U	/* master access in progress */
59388f8b78aSgm89044 #define	DMASTAT_MCR1FULL	0x40000000U	/* MCR1 is full */
59488f8b78aSgm89044 #define	DMASTAT_MCR1INT		0x20000000U	/* MCR1 interrupted */
59588f8b78aSgm89044 #define	DMASTAT_ERRINT		0x10000000U	/* error interrupted */
59688f8b78aSgm89044 #define	DMASTAT_MCR2FULL	0x08000000U	/* MCR2 is full */
59788f8b78aSgm89044 #define	DMASTAT_MCR2INT		0x04000000U	/* MCR2 interrupted */
59888f8b78aSgm89044 #define	DMASTAT_INTERRUPTS	0x34000000U	/* all interrupts */
59988f8b78aSgm89044 
60088f8b78aSgm89044 /*
60188f8b78aSgm89044  * Offsets of things relative to an MCR.
60288f8b78aSgm89044  */
60388f8b78aSgm89044 #define	MCR_COUNT	0	/* 16 bits */
60488f8b78aSgm89044 #define	MCR_FLAGS	2	/* 16 bits */
60588f8b78aSgm89044 #define	MCR_CTXADDR	4	/* 32 bits */
60688f8b78aSgm89044 
60788f8b78aSgm89044 /*
60888f8b78aSgm89044  * Basis for size (should be optimized by constant folding):
60988f8b78aSgm89044  *	4 bytes for flags and #packets.
61088f8b78aSgm89044  *	for each packet:
61188f8b78aSgm89044  *		2 descriptors (DESC_SIZE)
61288f8b78aSgm89044  *		4 bytes for context address
61388f8b78aSgm89044  *		4 bytes for packet length and reserved
61488f8b78aSgm89044  */
61588f8b78aSgm89044 #define	MCR_SIZE	(4 + MAXREQSPERMCR * ((2 * DESC_SIZE) + 8))
61688f8b78aSgm89044 
61788f8b78aSgm89044 /*
61888f8b78aSgm89044  * MCR flags.
61988f8b78aSgm89044  */
62088f8b78aSgm89044 #define	MCRFLAG_FINISHED	0x0001		/* MCR processing complete */
62188f8b78aSgm89044 #define	MCRFLAG_ERROR		0x0002		/* set if an error occured */
62288f8b78aSgm89044 #define	MCRFLAG_ERRORMASK	0xff00		/* error code bits */
62388f8b78aSgm89044 
62488f8b78aSgm89044 /*
62588f8b78aSgm89044  * Fields within a descriptor (data buffer chain).
62688f8b78aSgm89044  */
62788f8b78aSgm89044 #define	DESC_BUFADDR	0	/* 32 bits */
62888f8b78aSgm89044 #define	DESC_NEXT	4	/* 32 bits */
62988f8b78aSgm89044 #define	DESC_LENGTH	8	/* 16 bits */
63088f8b78aSgm89044 #define	DESC_RSVD	10	/* 16 bits */
63188f8b78aSgm89044 #define	DESC_SIZE	16	/* ROUNDUP(12, 16) - descriptor size (bytes) */
63288f8b78aSgm89044 
63388f8b78aSgm89044 /*
63488f8b78aSgm89044  * Offsets of fields within context structures, see Broadcom spec.
63588f8b78aSgm89044  */
63688f8b78aSgm89044 #define	CTX_LENGTH		0	/* 16 bits */
63788f8b78aSgm89044 #define	CTX_CMD			2	/* 16 bits */
63888f8b78aSgm89044 #define	CTX_MAXLENGTH		768	/* max size of ctx, fits anything */
63988f8b78aSgm89044 
64088f8b78aSgm89044 #define	CTX_3DESDIRECTION	4	/* 16 bits */
64188f8b78aSgm89044 #define	CTX_3DESKEY1HI		8	/* 32 bits */
64288f8b78aSgm89044 #define	CTX_3DESKEY1LO		12	/* 32 bits */
64388f8b78aSgm89044 #define	CTX_3DESKEY2HI		16	/* 32 bits */
64488f8b78aSgm89044 #define	CTX_3DESKEY2LO		20	/* 32 bits */
64588f8b78aSgm89044 #define	CTX_3DESKEY3HI		24	/* 32 bits */
64688f8b78aSgm89044 #define	CTX_3DESKEY3LO		28	/* 32 bits */
64788f8b78aSgm89044 #define	CTX_3DESIVHI		32	/* 32 bits */
64888f8b78aSgm89044 #define	CTX_3DESIVLO		36	/* 32 bits */
64988f8b78aSgm89044 
65088f8b78aSgm89044 #define	CTX_IPSECFLAGS		4	/* 16 bits */
65188f8b78aSgm89044 #define	CTX_IPSECOFFSET		6	/* 16 bits */
65288f8b78aSgm89044 #define	CTX_IPSECKEY1HI		8	/* 32 bits */
65388f8b78aSgm89044 #define	CTX_IPSECKEY1LO		12	/* 32 bits */
65488f8b78aSgm89044 #define	CTX_IPSECKEY2HI		16	/* 32 bits */
65588f8b78aSgm89044 #define	CTX_IPSECKEY2LO		20	/* 32 bits */
65688f8b78aSgm89044 #define	CTX_IPSECKEY3HI		24	/* 32 bits */
65788f8b78aSgm89044 #define	CTX_IPSECKEY3LO		28	/* 32 bits */
65888f8b78aSgm89044 #define	CTX_IPSECIVHI		32	/* 32 bits */
65988f8b78aSgm89044 #define	CTX_IPSECIVLO		36	/* 32 bits */
66088f8b78aSgm89044 #define	CTX_IPSECHMACINNER1	40	/* 32 bits */
66188f8b78aSgm89044 #define	CTX_IPSECHMACINNER2	44	/* 32 bits */
66288f8b78aSgm89044 #define	CTX_IPSECHMACINNER3	48	/* 32 bits */
66388f8b78aSgm89044 #define	CTX_IPSECHMACINNER4	52	/* 32 bits */
66488f8b78aSgm89044 #define	CTX_IPSECHMACINNER5	56	/* 32 bits */
66588f8b78aSgm89044 #define	CTX_IPSECHMACOUTER1	60	/* 32 bits */
66688f8b78aSgm89044 #define	CTX_IPSECHMACOUTER2	64	/* 32 bits */
66788f8b78aSgm89044 #define	CTX_IPSECHMACOUTER3	68	/* 32 bits */
66888f8b78aSgm89044 #define	CTX_IPSECHMACOUTER4	72	/* 32 bits */
66988f8b78aSgm89044 #define	CTX_IPSECHMACOUTER5	76	/* 32 bits */
67088f8b78aSgm89044 
67188f8b78aSgm89044 #define	CTX_RSAEXPLEN		4	/* 16 bits */
67288f8b78aSgm89044 #define	CTX_RSAMODLEN		6	/* 16 bits */
67388f8b78aSgm89044 #define	CTX_RSABIGNUMS		8	/* variable length */
67488f8b78aSgm89044 #define	CTX_RSAQLEN		4	/* 16 bits */
67588f8b78aSgm89044 #define	CTX_RSAPLEN		6	/* 16 bits */
67688f8b78aSgm89044 
67788f8b78aSgm89044 #define	CTX_DSAMSGTYPE		4	/* 16 bits */
67888f8b78aSgm89044 #define	CTX_DSARSVD		6	/* 16 bits */
67988f8b78aSgm89044 #define	CTX_DSARNG		8	/* 16 bits */
68088f8b78aSgm89044 #define	CTX_DSAPLEN		10	/* 16 bits */
68188f8b78aSgm89044 #define	CTX_DSABIGNUMS		12	/* variable length */
68288f8b78aSgm89044 
68388f8b78aSgm89044 /*
68488f8b78aSgm89044  * Values for specific operations.
68588f8b78aSgm89044  */
68688f8b78aSgm89044 #define	CTX_RNG_LENGTH		64	/* context length for RNG (64 min) */
68788f8b78aSgm89044 #define	CTX_3DES_LENGTH		64	/* context length for 3DES (64 min) */
68888f8b78aSgm89044 #define	CTX_3DES_DECRYPT	0x4000	/* perform decryption */
68988f8b78aSgm89044 #define	CTX_3DES_ENCRYPT	0x0000	/* perform encryption */
69088f8b78aSgm89044 #define	CTX_IPSEC_LENGTH	80	/* context length for IPsec */
69188f8b78aSgm89044 #define	CTX_IPSEC_ENCRYPT	0x8000	/* perform encryption */
69288f8b78aSgm89044 #define	CTX_IPSEC_DECRYPT	0xc000	/* perform decryption */
69388f8b78aSgm89044 #define	CTX_IPSEC_HMAC_MD5	0x1000	/* HMAC-MD5 authentication */
69488f8b78aSgm89044 #define	CTX_IPSEC_HMAC_SHA1	0x2000	/* HMAC-MD5 authentication */
69588f8b78aSgm89044 #define	CTX_DSAMSGTYPE_SHA1	0	/* Message is SHA1 */
69688f8b78aSgm89044 #define	CTX_DSAMSGTYPE_TEXT	1	/* Generate SHA1 hash first */
69788f8b78aSgm89044 #define	CTX_DSARNG_GEN		1	/* Generate random k */
69888f8b78aSgm89044 #define	CTX_DSARNG_SUPPLY	0	/* Random k is supplied */
69988f8b78aSgm89044 
70088f8b78aSgm89044 /*
70188f8b78aSgm89044  * Macros to access fields within the MCR.  Note that this includes the
70288f8b78aSgm89044  * context fields as well, since the context is just offset from the
70388f8b78aSgm89044  * base of the MCR.
70488f8b78aSgm89044  */
70588f8b78aSgm89044 
70688f8b78aSgm89044 #define	PUTMCR32(work, reg, val)	\
70788f8b78aSgm89044 	ddi_put32(work->dw_mcr_acch,	\
70888f8b78aSgm89044 	(uint32_t *)(work->dw_mcr_kaddr + reg), val)
70988f8b78aSgm89044 
71088f8b78aSgm89044 #define	PUTMCR16(work, reg, val)	\
71188f8b78aSgm89044 	ddi_put16(work->dw_mcr_acch,	\
71288f8b78aSgm89044 	(uint16_t *)(work->dw_mcr_kaddr + reg), val)
71388f8b78aSgm89044 
71488f8b78aSgm89044 #define	GETMCR32(work, reg)	\
71588f8b78aSgm89044 	ddi_get32(work->dw_mcr_acch, (uint32_t *)(work->dw_mcr_kaddr + reg))
71688f8b78aSgm89044 
71788f8b78aSgm89044 #define	GETMCR16(work, reg)	\
71888f8b78aSgm89044 	ddi_get16(work->dw_mcr_acch, (uint16_t *)(work->dw_mcr_kaddr + reg))
71988f8b78aSgm89044 
72088f8b78aSgm89044 #define	PUTDESC32(req, dc_desc_kaddr, reg, val)	\
72188f8b78aSgm89044 	ddi_put32(req->dr_ctx_acch,	\
72288f8b78aSgm89044 	(uint32_t *)(dc_desc_kaddr + reg), val)
72388f8b78aSgm89044 
72488f8b78aSgm89044 #define	PUTDESC16(req, dc_desc_kaddr, reg, val)	\
72588f8b78aSgm89044 	ddi_put16(req->dr_ctx_acch,	\
72688f8b78aSgm89044 	(uint16_t *)(dc_desc_kaddr + reg), val)
72788f8b78aSgm89044 
72888f8b78aSgm89044 /* XXX: define the GET forms for descriptors only if needed */
72988f8b78aSgm89044 
73088f8b78aSgm89044 #define	PUTCTX32(req, reg, val)	\
73188f8b78aSgm89044 	ddi_put32(req->dr_ctx_acch,	\
73288f8b78aSgm89044 	(uint32_t *)(req->dr_ctx_kaddr + reg), val)
73388f8b78aSgm89044 
73488f8b78aSgm89044 #define	PUTCTX16(req, reg, val)	\
73588f8b78aSgm89044 	ddi_put16(req->dr_ctx_acch,	\
73688f8b78aSgm89044 	(uint16_t *)(req->dr_ctx_kaddr + reg), val)
73788f8b78aSgm89044 
73888f8b78aSgm89044 #define	CTXBCOPY(req, src, dst, count)	\
73988f8b78aSgm89044 	ddi_rep_put8(req->dr_ctx_acch, (uchar_t *)src, (uchar_t *)dst, count, \
74088f8b78aSgm89044 	DDI_DEV_AUTOINCR)
74188f8b78aSgm89044 
74288f8b78aSgm89044 /*
74388f8b78aSgm89044  * Register access.
74488f8b78aSgm89044  */
74588f8b78aSgm89044 #define	GETCSR(dca, reg)	\
74688f8b78aSgm89044 	ddi_get32(dca->dca_regs_handle, (uint_t *)(dca->dca_regs + reg))
74788f8b78aSgm89044 
74888f8b78aSgm89044 #define	PUTCSR(dca, reg, val)	\
74988f8b78aSgm89044 	ddi_put32(dca->dca_regs_handle, (uint_t *)(dca->dca_regs + reg), val)
75088f8b78aSgm89044 
75188f8b78aSgm89044 #define	SETBIT(dca, reg, val)	\
75288f8b78aSgm89044 	PUTCSR(dca, reg, GETCSR(dca, reg) | val)
75388f8b78aSgm89044 
75488f8b78aSgm89044 #define	CLRBIT(dca, reg, val)	\
75588f8b78aSgm89044 	PUTCSR(dca, reg, GETCSR(dca, reg) & ~val)
75688f8b78aSgm89044 
75788f8b78aSgm89044 /*
75888f8b78aSgm89044  * Used to guarantee alignment.
75988f8b78aSgm89044  */
76088f8b78aSgm89044 #define	ROUNDUP(a, n)	(((a) + ((n) - 1)) & ~((n) - 1))
76188f8b78aSgm89044 #define	ROUNDDOWN(a, n)	(((a) & ~((n) - 1)))
76288f8b78aSgm89044 #define	HIDBLWORD(x)	(((x) & 0xffffffff00000000ULL) >> 32)
76388f8b78aSgm89044 #define	LODBLWORD(x)	((x) & 0xffffffffULL)
76488f8b78aSgm89044 
76588f8b78aSgm89044 /*
76688f8b78aSgm89044  * Driver hardening related.
76788f8b78aSgm89044  */
76888f8b78aSgm89044 #define	CHECK_REGS(dca)	ddi_check_acc_handle(dca->dca_regs_handle)
76988f8b78aSgm89044 
77088f8b78aSgm89044 /*
77188f8b78aSgm89044  * Other utility macros.
77288f8b78aSgm89044  */
77388f8b78aSgm89044 #define	QEMPTY(q)	((q)->dl_next == (q))
77488f8b78aSgm89044 #define	BITS2BYTES(b)	((b) >> 3)
77588f8b78aSgm89044 #define	WORKLIST(dca, mcr)	(&((dca)->dca_worklist[mcr - 1]))
77688f8b78aSgm89044 
77788f8b78aSgm89044 /*
77888f8b78aSgm89044  * Debug stuff.
77988f8b78aSgm89044  */
78088f8b78aSgm89044 #ifdef	DEBUG
78188f8b78aSgm89044 #define	DWARN		0x0001
78288f8b78aSgm89044 #define	DPCI		0x0002
78388f8b78aSgm89044 #define	DINTR		0x0004
78488f8b78aSgm89044 #define	DSTART		0x0008
78588f8b78aSgm89044 #define	DRECLAIM	0x0010
78688f8b78aSgm89044 #define	DCHATTY		0x0020
78788f8b78aSgm89044 #define	DMOD		0x0040	/* _init/_fini/_info/attach/detach */
78888f8b78aSgm89044 #define	DENTRY		0x0080	/* crypto routine entry/exit points */
78988f8b78aSgm89044 
79088f8b78aSgm89044 void	dca_dprintf(dca_t *, int, const char *, ...);
79188f8b78aSgm89044 #define	DBG	dca_dprintf
79288f8b78aSgm89044 #else
79388f8b78aSgm89044 #define	DBG(dca, lvl, ...)
79488f8b78aSgm89044 #endif
79588f8b78aSgm89044 
79688f8b78aSgm89044 /*
79788f8b78aSgm89044  * Some pkcs#11 defines as there are no pkcs#11 header files included.
79888f8b78aSgm89044  */
79988f8b78aSgm89044 #define	CKO_PUBLIC_KEY		0x00000002
80088f8b78aSgm89044 #define	CKO_PRIVATE_KEY		0x00000003
80188f8b78aSgm89044 
80288f8b78aSgm89044 #define	CKA_CLASS		0x00000000
80388f8b78aSgm89044 #define	CKA_VALUE		0x00000011
80488f8b78aSgm89044 #define	CKA_KEY_TYPE		0x00000100
80588f8b78aSgm89044 #define	CKA_MODULUS		0x00000120
80688f8b78aSgm89044 #define	CKA_PUBLIC_EXPONENT	0x00000122
80788f8b78aSgm89044 #define	CKA_PRIVATE_EXPONENT	0x00000123
80888f8b78aSgm89044 #define	CKA_PRIME_1		0x00000124
80988f8b78aSgm89044 #define	CKA_PRIME_2		0x00000125
81088f8b78aSgm89044 #define	CKA_EXPONENT_1		0x00000126
81188f8b78aSgm89044 #define	CKA_EXPONENT_2		0x00000127
81288f8b78aSgm89044 #define	CKA_COEFFICIENT		0x00000128
81388f8b78aSgm89044 #define	CKA_PRIME		0x00000130
81488f8b78aSgm89044 #define	CKA_SUBPRIME		0x00000131
81588f8b78aSgm89044 #define	CKA_BASE		0x00000132
81688f8b78aSgm89044 /*
81788f8b78aSgm89044  * Driver globals.
81888f8b78aSgm89044  */
81988f8b78aSgm89044 extern int	dca_mindma;
82088f8b78aSgm89044 extern int	dca_hardening;
82188f8b78aSgm89044 
82288f8b78aSgm89044 /*
82388f8b78aSgm89044  * Prototypes.
82488f8b78aSgm89044  */
82588f8b78aSgm89044 
82688f8b78aSgm89044 /*
82788f8b78aSgm89044  * dca_debug.c
82888f8b78aSgm89044  */
82988f8b78aSgm89044 void	dca_error(dca_t *, const char *, ...);
83088f8b78aSgm89044 void	dca_diperror(dev_info_t *, const char *, ...);
83188f8b78aSgm89044 void	dca_dipverror(dev_info_t *, const char *, va_list);
83288f8b78aSgm89044 /*
83388f8b78aSgm89044  * dca_3des.c
83488f8b78aSgm89044  */
83588f8b78aSgm89044 int	dca_3desctxinit(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
83688f8b78aSgm89044     int, int);
83788f8b78aSgm89044 int	dca_3des(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
83888f8b78aSgm89044     crypto_req_handle_t, int);
83988f8b78aSgm89044 int	dca_3desupdate(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
84088f8b78aSgm89044     crypto_req_handle_t, int);
84188f8b78aSgm89044 int	dca_3desfinal(crypto_ctx_t *, crypto_data_t *, int);
84288f8b78aSgm89044 int	dca_3desatomic(crypto_provider_handle_t, crypto_session_id_t,
84388f8b78aSgm89044     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
84488f8b78aSgm89044     int, crypto_req_handle_t, int);
84588f8b78aSgm89044 void	dca_3desctxfree(void *);
84688f8b78aSgm89044 
84788f8b78aSgm89044 /*
84888f8b78aSgm89044  * dca_rsa.c
84988f8b78aSgm89044  */
85088f8b78aSgm89044 int	dca_rsastart(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
85188f8b78aSgm89044     crypto_req_handle_t, int);
85288f8b78aSgm89044 int	dca_rsainit(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *, int);
85388f8b78aSgm89044 void	dca_rsactxfree(void *);
85488f8b78aSgm89044 int	dca_rsaatomic(crypto_provider_handle_t, crypto_session_id_t,
85588f8b78aSgm89044     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
85688f8b78aSgm89044     int, crypto_req_handle_t, int);
85788f8b78aSgm89044 
85888f8b78aSgm89044 /*
85988f8b78aSgm89044  * dca_dsa.c
86088f8b78aSgm89044  */
86188f8b78aSgm89044 int	dca_dsa_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
86288f8b78aSgm89044     crypto_req_handle_t);
86388f8b78aSgm89044 int	dca_dsa_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
86488f8b78aSgm89044     crypto_req_handle_t);
86588f8b78aSgm89044 int	dca_dsainit(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *, int,
86688f8b78aSgm89044     int);
86788f8b78aSgm89044 void	dca_dsactxfree(void *);
86888f8b78aSgm89044 int	dca_dsaatomic(crypto_provider_handle_t, crypto_session_id_t,
86988f8b78aSgm89044     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
87088f8b78aSgm89044     int, crypto_req_handle_t, int);
87188f8b78aSgm89044 
87288f8b78aSgm89044 /*
87388f8b78aSgm89044  * dca_rng.c
87488f8b78aSgm89044  */
87588f8b78aSgm89044 int	dca_rng(dca_t *, uchar_t *, size_t len, crypto_req_handle_t);
87688f8b78aSgm89044 int	dca_random_buffer(dca_t *dca, caddr_t buf, int len);
87788f8b78aSgm89044 int	dca_random_init();
87888f8b78aSgm89044 void	dca_random_fini();
87988f8b78aSgm89044 
88088f8b78aSgm89044 /*
88188f8b78aSgm89044  * dca_kstat.c
88288f8b78aSgm89044  */
88388f8b78aSgm89044 void	dca_ksinit(dca_t *);
88488f8b78aSgm89044 /*
88588f8b78aSgm89044  * dca.c
88688f8b78aSgm89044  */
88788f8b78aSgm89044 void	dca_rmqueue(dca_listnode_t *);
88888f8b78aSgm89044 dca_request_t *dca_getreq(dca_t *, int, int);
88988f8b78aSgm89044 void	dca_freereq(dca_request_t *);
89088f8b78aSgm89044 int	dca_bindchains(dca_request_t *, size_t, size_t);
89188f8b78aSgm89044 int	dca_unbindchains(dca_request_t *);
89288f8b78aSgm89044 int	dca_start(dca_t *, dca_request_t *, int, int);
89388f8b78aSgm89044 void	dca_done(dca_request_t *, int);
89488f8b78aSgm89044 void	dca_destroyreq(dca_request_t *);
89588f8b78aSgm89044 int	dca_length(crypto_data_t *);
89688f8b78aSgm89044 int	dca_gather(crypto_data_t *, char *, int, int);
89788f8b78aSgm89044 int	dca_resid_gather(crypto_data_t *, char *, int *, char *, int);
89888f8b78aSgm89044 int	dca_scatter(const char *, crypto_data_t *, int, int);
89988f8b78aSgm89044 int	dca_bcmp_reverse(const void *s1, const void *s2, size_t n);
90088f8b78aSgm89044 int	dca_dupcrypto(crypto_data_t *, crypto_data_t *);
90188f8b78aSgm89044 int	dca_verifyio(crypto_data_t *, crypto_data_t *);
90288f8b78aSgm89044 int	dca_getbufbytes(crypto_data_t *, size_t, int, uchar_t *);
90388f8b78aSgm89044 int	dca_sgcheck(dca_t *, crypto_data_t *, dca_sg_param_t);
90488f8b78aSgm89044 crypto_object_attribute_t *
90588f8b78aSgm89044 	dca_get_key_attr(crypto_key_t *);
90688f8b78aSgm89044 int	dca_attr_lookup_uint32(crypto_object_attribute_t *, uint_t, uint64_t,
90788f8b78aSgm89044 	    uint32_t *);
90888f8b78aSgm89044 int	dca_attr_lookup_uint8_array(crypto_object_attribute_t *, uint_t,
90988f8b78aSgm89044 	    uint64_t, void **, unsigned int *);
91088f8b78aSgm89044 crypto_object_attribute_t *
91188f8b78aSgm89044 	dca_find_attribute(crypto_object_attribute_t *, uint_t, uint64_t);
91288f8b78aSgm89044 caddr_t	dca_bufdaddr(crypto_data_t *);
91388f8b78aSgm89044 void	dca_rcoalesce(dca_request_t *, int);
91488f8b78aSgm89044 void	dca_runcoalesce(dca_request_t *);
91588f8b78aSgm89044 int	dca_bitlen(unsigned char *, int);
91688f8b78aSgm89044 uint16_t dca_padhalf(int);
91788f8b78aSgm89044 uint16_t dca_padfull(int);
91888f8b78aSgm89044 void	dca_reverse(void *, void *, int, int);
91988f8b78aSgm89044 int	dca_numcmp(caddr_t, int, caddr_t, int);
92088f8b78aSgm89044 int dca_check_dma_handle(dca_t *dca, ddi_dma_handle_t handle,
92188f8b78aSgm89044 	dca_fma_eclass_t eclass_index);
92288f8b78aSgm89044 int dca_free_context(crypto_ctx_t *ctx);
92388f8b78aSgm89044 
92488f8b78aSgm89044 #endif	/* _KERNEL */
92588f8b78aSgm89044 
92688f8b78aSgm89044 #ifdef	__cplusplus
92788f8b78aSgm89044 }
92888f8b78aSgm89044 #endif
92988f8b78aSgm89044 
93088f8b78aSgm89044 #endif	/* _SYS_CRYPTO_DCA_H */
931