162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#ifndef __NX_H__
462306a36Sopenharmony_ci#define __NX_H__
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <crypto/ctr.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#define NX_NAME		"nx-crypto"
962306a36Sopenharmony_ci#define NX_STRING	"IBM Power7+ Nest Accelerator Crypto Driver"
1062306a36Sopenharmony_ci#define NX_VERSION	"1.0"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/* a scatterlist in the format PHYP is expecting */
1362306a36Sopenharmony_cistruct nx_sg {
1462306a36Sopenharmony_ci	u64 addr;
1562306a36Sopenharmony_ci	u32 rsvd;
1662306a36Sopenharmony_ci	u32 len;
1762306a36Sopenharmony_ci} __attribute((packed));
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define NX_PAGE_SIZE		(4096)
2062306a36Sopenharmony_ci#define NX_MAX_SG_ENTRIES	(NX_PAGE_SIZE/(sizeof(struct nx_sg)))
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cienum nx_status {
2362306a36Sopenharmony_ci	NX_DISABLED,
2462306a36Sopenharmony_ci	NX_WAITING,
2562306a36Sopenharmony_ci	NX_OKAY
2662306a36Sopenharmony_ci};
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* msc_triplet and max_sync_cop are used only to assist in parsing the
2962306a36Sopenharmony_ci * openFirmware property */
3062306a36Sopenharmony_cistruct msc_triplet {
3162306a36Sopenharmony_ci	u32 keybitlen;
3262306a36Sopenharmony_ci	u32 databytelen;
3362306a36Sopenharmony_ci	u32 sglen;
3462306a36Sopenharmony_ci} __packed;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistruct max_sync_cop {
3762306a36Sopenharmony_ci	u32 fc;
3862306a36Sopenharmony_ci	u32 mode;
3962306a36Sopenharmony_ci	u32 triplets;
4062306a36Sopenharmony_ci	struct msc_triplet trip[];
4162306a36Sopenharmony_ci} __packed;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistruct alg_props {
4462306a36Sopenharmony_ci	u32 databytelen;
4562306a36Sopenharmony_ci	u32 sglen;
4662306a36Sopenharmony_ci};
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define NX_OF_FLAG_MAXSGLEN_SET		(1)
4962306a36Sopenharmony_ci#define NX_OF_FLAG_STATUS_SET		(2)
5062306a36Sopenharmony_ci#define NX_OF_FLAG_MAXSYNCCOP_SET	(4)
5162306a36Sopenharmony_ci#define NX_OF_FLAG_MASK_READY		(NX_OF_FLAG_MAXSGLEN_SET | \
5262306a36Sopenharmony_ci					 NX_OF_FLAG_STATUS_SET |   \
5362306a36Sopenharmony_ci					 NX_OF_FLAG_MAXSYNCCOP_SET)
5462306a36Sopenharmony_cistruct nx_of {
5562306a36Sopenharmony_ci	u32 flags;
5662306a36Sopenharmony_ci	u32 max_sg_len;
5762306a36Sopenharmony_ci	enum nx_status status;
5862306a36Sopenharmony_ci	struct alg_props ap[NX_MAX_FC][NX_MAX_MODE][3];
5962306a36Sopenharmony_ci};
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistruct nx_stats {
6262306a36Sopenharmony_ci	atomic_t aes_ops;
6362306a36Sopenharmony_ci	atomic64_t aes_bytes;
6462306a36Sopenharmony_ci	atomic_t sha256_ops;
6562306a36Sopenharmony_ci	atomic64_t sha256_bytes;
6662306a36Sopenharmony_ci	atomic_t sha512_ops;
6762306a36Sopenharmony_ci	atomic64_t sha512_bytes;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	atomic_t sync_ops;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	atomic_t errors;
7262306a36Sopenharmony_ci	atomic_t last_error;
7362306a36Sopenharmony_ci	atomic_t last_error_pid;
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_cistruct nx_crypto_driver {
7762306a36Sopenharmony_ci	struct nx_stats    stats;
7862306a36Sopenharmony_ci	struct nx_of       of;
7962306a36Sopenharmony_ci	struct vio_dev    *viodev;
8062306a36Sopenharmony_ci	struct vio_driver  viodriver;
8162306a36Sopenharmony_ci	struct dentry     *dfs_root;
8262306a36Sopenharmony_ci};
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci#define NX_GCM4106_NONCE_LEN		(4)
8562306a36Sopenharmony_ci#define NX_GCM_CTR_OFFSET		(12)
8662306a36Sopenharmony_cistruct nx_gcm_rctx {
8762306a36Sopenharmony_ci	u8 iv[16];
8862306a36Sopenharmony_ci};
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cistruct nx_gcm_priv {
9162306a36Sopenharmony_ci	u8 iauth_tag[16];
9262306a36Sopenharmony_ci	u8 nonce[NX_GCM4106_NONCE_LEN];
9362306a36Sopenharmony_ci};
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci#define NX_CCM_AES_KEY_LEN		(16)
9662306a36Sopenharmony_ci#define NX_CCM4309_AES_KEY_LEN		(19)
9762306a36Sopenharmony_ci#define NX_CCM4309_NONCE_LEN		(3)
9862306a36Sopenharmony_cistruct nx_ccm_rctx {
9962306a36Sopenharmony_ci	u8 iv[16];
10062306a36Sopenharmony_ci};
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_cistruct nx_ccm_priv {
10362306a36Sopenharmony_ci	u8 b0[16];
10462306a36Sopenharmony_ci	u8 iauth_tag[16];
10562306a36Sopenharmony_ci	u8 oauth_tag[16];
10662306a36Sopenharmony_ci	u8 nonce[NX_CCM4309_NONCE_LEN];
10762306a36Sopenharmony_ci};
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_cistruct nx_xcbc_priv {
11062306a36Sopenharmony_ci	u8 key[16];
11162306a36Sopenharmony_ci};
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_cistruct nx_ctr_priv {
11462306a36Sopenharmony_ci	u8 nonce[CTR_RFC3686_NONCE_SIZE];
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistruct nx_crypto_ctx {
11862306a36Sopenharmony_ci	spinlock_t lock;	  /* synchronize access to the context */
11962306a36Sopenharmony_ci	void *kmem;		  /* unaligned, kmalloc'd buffer */
12062306a36Sopenharmony_ci	size_t kmem_len;	  /* length of kmem */
12162306a36Sopenharmony_ci	struct nx_csbcpb *csbcpb; /* aligned page given to phyp @ hcall time */
12262306a36Sopenharmony_ci	struct vio_pfo_op op;     /* operation struct with hcall parameters */
12362306a36Sopenharmony_ci	struct nx_csbcpb *csbcpb_aead; /* secondary csbcpb used by AEAD algs */
12462306a36Sopenharmony_ci	struct vio_pfo_op op_aead;/* operation struct for csbcpb_aead */
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	struct nx_sg *in_sg;      /* aligned pointer into kmem to an sg list */
12762306a36Sopenharmony_ci	struct nx_sg *out_sg;     /* aligned pointer into kmem to an sg list */
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	struct alg_props *ap;	  /* pointer into props based on our key size */
13062306a36Sopenharmony_ci	struct alg_props props[3];/* openFirmware properties for requests */
13162306a36Sopenharmony_ci	struct nx_stats *stats;   /* pointer into an nx_crypto_driver for stats
13262306a36Sopenharmony_ci				     reporting */
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	union {
13562306a36Sopenharmony_ci		struct nx_gcm_priv gcm;
13662306a36Sopenharmony_ci		struct nx_ccm_priv ccm;
13762306a36Sopenharmony_ci		struct nx_xcbc_priv xcbc;
13862306a36Sopenharmony_ci		struct nx_ctr_priv ctr;
13962306a36Sopenharmony_ci	} priv;
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistruct crypto_aead;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci/* prototypes */
14562306a36Sopenharmony_ciint nx_crypto_ctx_aes_ccm_init(struct crypto_aead *tfm);
14662306a36Sopenharmony_ciint nx_crypto_ctx_aes_gcm_init(struct crypto_aead *tfm);
14762306a36Sopenharmony_ciint nx_crypto_ctx_aes_xcbc_init(struct crypto_tfm *tfm);
14862306a36Sopenharmony_ciint nx_crypto_ctx_aes_ctr_init(struct crypto_skcipher *tfm);
14962306a36Sopenharmony_ciint nx_crypto_ctx_aes_cbc_init(struct crypto_skcipher *tfm);
15062306a36Sopenharmony_ciint nx_crypto_ctx_aes_ecb_init(struct crypto_skcipher *tfm);
15162306a36Sopenharmony_ciint nx_crypto_ctx_sha_init(struct crypto_tfm *tfm);
15262306a36Sopenharmony_civoid nx_crypto_ctx_exit(struct crypto_tfm *tfm);
15362306a36Sopenharmony_civoid nx_crypto_ctx_skcipher_exit(struct crypto_skcipher *tfm);
15462306a36Sopenharmony_civoid nx_crypto_ctx_aead_exit(struct crypto_aead *tfm);
15562306a36Sopenharmony_civoid nx_ctx_init(struct nx_crypto_ctx *nx_ctx, unsigned int function);
15662306a36Sopenharmony_ciint nx_hcall_sync(struct nx_crypto_ctx *ctx, struct vio_pfo_op *op,
15762306a36Sopenharmony_ci		  u32 may_sleep);
15862306a36Sopenharmony_cistruct nx_sg *nx_build_sg_list(struct nx_sg *, u8 *, unsigned int *, u32);
15962306a36Sopenharmony_ciint nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx, const u8 *iv,
16062306a36Sopenharmony_ci		      struct scatterlist *dst, struct scatterlist *src,
16162306a36Sopenharmony_ci		      unsigned int *nbytes, unsigned int offset, u8 *oiv);
16262306a36Sopenharmony_cistruct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int,
16362306a36Sopenharmony_ci				struct scatterlist *, unsigned int,
16462306a36Sopenharmony_ci				unsigned int *);
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
16762306a36Sopenharmony_ci#define NX_DEBUGFS_INIT(drv)	nx_debugfs_init(drv)
16862306a36Sopenharmony_ci#define NX_DEBUGFS_FINI(drv)	nx_debugfs_fini(drv)
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_civoid nx_debugfs_init(struct nx_crypto_driver *);
17162306a36Sopenharmony_civoid nx_debugfs_fini(struct nx_crypto_driver *);
17262306a36Sopenharmony_ci#else
17362306a36Sopenharmony_ci#define NX_DEBUGFS_INIT(drv)	do {} while (0)
17462306a36Sopenharmony_ci#define NX_DEBUGFS_FINI(drv)	do {} while (0)
17562306a36Sopenharmony_ci#endif
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci#define NX_PAGE_NUM(x)		((u64)(x) & 0xfffffffffffff000ULL)
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ciextern struct skcipher_alg nx_cbc_aes_alg;
18062306a36Sopenharmony_ciextern struct skcipher_alg nx_ecb_aes_alg;
18162306a36Sopenharmony_ciextern struct aead_alg nx_gcm_aes_alg;
18262306a36Sopenharmony_ciextern struct aead_alg nx_gcm4106_aes_alg;
18362306a36Sopenharmony_ciextern struct skcipher_alg nx_ctr3686_aes_alg;
18462306a36Sopenharmony_ciextern struct aead_alg nx_ccm_aes_alg;
18562306a36Sopenharmony_ciextern struct aead_alg nx_ccm4309_aes_alg;
18662306a36Sopenharmony_ciextern struct shash_alg nx_shash_aes_xcbc_alg;
18762306a36Sopenharmony_ciextern struct shash_alg nx_shash_sha512_alg;
18862306a36Sopenharmony_ciextern struct shash_alg nx_shash_sha256_alg;
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciextern struct nx_crypto_driver nx_driver;
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci#define SCATTERWALK_TO_SG	1
19362306a36Sopenharmony_ci#define SCATTERWALK_FROM_SG	0
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci#endif
196