18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci#ifndef __NX_H__ 48c2ecf20Sopenharmony_ci#define __NX_H__ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <crypto/ctr.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#define NX_NAME "nx-crypto" 98c2ecf20Sopenharmony_ci#define NX_STRING "IBM Power7+ Nest Accelerator Crypto Driver" 108c2ecf20Sopenharmony_ci#define NX_VERSION "1.0" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* a scatterlist in the format PHYP is expecting */ 138c2ecf20Sopenharmony_cistruct nx_sg { 148c2ecf20Sopenharmony_ci u64 addr; 158c2ecf20Sopenharmony_ci u32 rsvd; 168c2ecf20Sopenharmony_ci u32 len; 178c2ecf20Sopenharmony_ci} __attribute((packed)); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define NX_PAGE_SIZE (4096) 208c2ecf20Sopenharmony_ci#define NX_MAX_SG_ENTRIES (NX_PAGE_SIZE/(sizeof(struct nx_sg))) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cienum nx_status { 238c2ecf20Sopenharmony_ci NX_DISABLED, 248c2ecf20Sopenharmony_ci NX_WAITING, 258c2ecf20Sopenharmony_ci NX_OKAY 268c2ecf20Sopenharmony_ci}; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/* msc_triplet and max_sync_cop are used only to assist in parsing the 298c2ecf20Sopenharmony_ci * openFirmware property */ 308c2ecf20Sopenharmony_cistruct msc_triplet { 318c2ecf20Sopenharmony_ci u32 keybitlen; 328c2ecf20Sopenharmony_ci u32 databytelen; 338c2ecf20Sopenharmony_ci u32 sglen; 348c2ecf20Sopenharmony_ci} __packed; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistruct max_sync_cop { 378c2ecf20Sopenharmony_ci u32 fc; 388c2ecf20Sopenharmony_ci u32 mode; 398c2ecf20Sopenharmony_ci u32 triplets; 408c2ecf20Sopenharmony_ci struct msc_triplet trip[]; 418c2ecf20Sopenharmony_ci} __packed; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistruct alg_props { 448c2ecf20Sopenharmony_ci u32 databytelen; 458c2ecf20Sopenharmony_ci u32 sglen; 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#define NX_OF_FLAG_MAXSGLEN_SET (1) 498c2ecf20Sopenharmony_ci#define NX_OF_FLAG_STATUS_SET (2) 508c2ecf20Sopenharmony_ci#define NX_OF_FLAG_MAXSYNCCOP_SET (4) 518c2ecf20Sopenharmony_ci#define NX_OF_FLAG_MASK_READY (NX_OF_FLAG_MAXSGLEN_SET | \ 528c2ecf20Sopenharmony_ci NX_OF_FLAG_STATUS_SET | \ 538c2ecf20Sopenharmony_ci NX_OF_FLAG_MAXSYNCCOP_SET) 548c2ecf20Sopenharmony_cistruct nx_of { 558c2ecf20Sopenharmony_ci u32 flags; 568c2ecf20Sopenharmony_ci u32 max_sg_len; 578c2ecf20Sopenharmony_ci enum nx_status status; 588c2ecf20Sopenharmony_ci struct alg_props ap[NX_MAX_FC][NX_MAX_MODE][3]; 598c2ecf20Sopenharmony_ci}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistruct nx_stats { 628c2ecf20Sopenharmony_ci atomic_t aes_ops; 638c2ecf20Sopenharmony_ci atomic64_t aes_bytes; 648c2ecf20Sopenharmony_ci atomic_t sha256_ops; 658c2ecf20Sopenharmony_ci atomic64_t sha256_bytes; 668c2ecf20Sopenharmony_ci atomic_t sha512_ops; 678c2ecf20Sopenharmony_ci atomic64_t sha512_bytes; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci atomic_t sync_ops; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci atomic_t errors; 728c2ecf20Sopenharmony_ci atomic_t last_error; 738c2ecf20Sopenharmony_ci atomic_t last_error_pid; 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistruct nx_crypto_driver { 778c2ecf20Sopenharmony_ci struct nx_stats stats; 788c2ecf20Sopenharmony_ci struct nx_of of; 798c2ecf20Sopenharmony_ci struct vio_dev *viodev; 808c2ecf20Sopenharmony_ci struct vio_driver viodriver; 818c2ecf20Sopenharmony_ci struct dentry *dfs_root; 828c2ecf20Sopenharmony_ci}; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#define NX_GCM4106_NONCE_LEN (4) 858c2ecf20Sopenharmony_ci#define NX_GCM_CTR_OFFSET (12) 868c2ecf20Sopenharmony_cistruct nx_gcm_rctx { 878c2ecf20Sopenharmony_ci u8 iv[16]; 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistruct nx_gcm_priv { 918c2ecf20Sopenharmony_ci u8 iauth_tag[16]; 928c2ecf20Sopenharmony_ci u8 nonce[NX_GCM4106_NONCE_LEN]; 938c2ecf20Sopenharmony_ci}; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci#define NX_CCM_AES_KEY_LEN (16) 968c2ecf20Sopenharmony_ci#define NX_CCM4309_AES_KEY_LEN (19) 978c2ecf20Sopenharmony_ci#define NX_CCM4309_NONCE_LEN (3) 988c2ecf20Sopenharmony_cistruct nx_ccm_rctx { 998c2ecf20Sopenharmony_ci u8 iv[16]; 1008c2ecf20Sopenharmony_ci}; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistruct nx_ccm_priv { 1038c2ecf20Sopenharmony_ci u8 b0[16]; 1048c2ecf20Sopenharmony_ci u8 iauth_tag[16]; 1058c2ecf20Sopenharmony_ci u8 oauth_tag[16]; 1068c2ecf20Sopenharmony_ci u8 nonce[NX_CCM4309_NONCE_LEN]; 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistruct nx_xcbc_priv { 1108c2ecf20Sopenharmony_ci u8 key[16]; 1118c2ecf20Sopenharmony_ci}; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistruct nx_ctr_priv { 1148c2ecf20Sopenharmony_ci u8 nonce[CTR_RFC3686_NONCE_SIZE]; 1158c2ecf20Sopenharmony_ci}; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistruct nx_crypto_ctx { 1188c2ecf20Sopenharmony_ci spinlock_t lock; /* synchronize access to the context */ 1198c2ecf20Sopenharmony_ci void *kmem; /* unaligned, kmalloc'd buffer */ 1208c2ecf20Sopenharmony_ci size_t kmem_len; /* length of kmem */ 1218c2ecf20Sopenharmony_ci struct nx_csbcpb *csbcpb; /* aligned page given to phyp @ hcall time */ 1228c2ecf20Sopenharmony_ci struct vio_pfo_op op; /* operation struct with hcall parameters */ 1238c2ecf20Sopenharmony_ci struct nx_csbcpb *csbcpb_aead; /* secondary csbcpb used by AEAD algs */ 1248c2ecf20Sopenharmony_ci struct vio_pfo_op op_aead;/* operation struct for csbcpb_aead */ 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci struct nx_sg *in_sg; /* aligned pointer into kmem to an sg list */ 1278c2ecf20Sopenharmony_ci struct nx_sg *out_sg; /* aligned pointer into kmem to an sg list */ 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci struct alg_props *ap; /* pointer into props based on our key size */ 1308c2ecf20Sopenharmony_ci struct alg_props props[3];/* openFirmware properties for requests */ 1318c2ecf20Sopenharmony_ci struct nx_stats *stats; /* pointer into an nx_crypto_driver for stats 1328c2ecf20Sopenharmony_ci reporting */ 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci union { 1358c2ecf20Sopenharmony_ci struct nx_gcm_priv gcm; 1368c2ecf20Sopenharmony_ci struct nx_ccm_priv ccm; 1378c2ecf20Sopenharmony_ci struct nx_xcbc_priv xcbc; 1388c2ecf20Sopenharmony_ci struct nx_ctr_priv ctr; 1398c2ecf20Sopenharmony_ci } priv; 1408c2ecf20Sopenharmony_ci}; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistruct crypto_aead; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci/* prototypes */ 1458c2ecf20Sopenharmony_ciint nx_crypto_ctx_aes_ccm_init(struct crypto_aead *tfm); 1468c2ecf20Sopenharmony_ciint nx_crypto_ctx_aes_gcm_init(struct crypto_aead *tfm); 1478c2ecf20Sopenharmony_ciint nx_crypto_ctx_aes_xcbc_init(struct crypto_tfm *tfm); 1488c2ecf20Sopenharmony_ciint nx_crypto_ctx_aes_ctr_init(struct crypto_skcipher *tfm); 1498c2ecf20Sopenharmony_ciint nx_crypto_ctx_aes_cbc_init(struct crypto_skcipher *tfm); 1508c2ecf20Sopenharmony_ciint nx_crypto_ctx_aes_ecb_init(struct crypto_skcipher *tfm); 1518c2ecf20Sopenharmony_ciint nx_crypto_ctx_sha_init(struct crypto_tfm *tfm); 1528c2ecf20Sopenharmony_civoid nx_crypto_ctx_exit(struct crypto_tfm *tfm); 1538c2ecf20Sopenharmony_civoid nx_crypto_ctx_skcipher_exit(struct crypto_skcipher *tfm); 1548c2ecf20Sopenharmony_civoid nx_crypto_ctx_aead_exit(struct crypto_aead *tfm); 1558c2ecf20Sopenharmony_civoid nx_ctx_init(struct nx_crypto_ctx *nx_ctx, unsigned int function); 1568c2ecf20Sopenharmony_ciint nx_hcall_sync(struct nx_crypto_ctx *ctx, struct vio_pfo_op *op, 1578c2ecf20Sopenharmony_ci u32 may_sleep); 1588c2ecf20Sopenharmony_cistruct nx_sg *nx_build_sg_list(struct nx_sg *, u8 *, unsigned int *, u32); 1598c2ecf20Sopenharmony_ciint nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx, const u8 *iv, 1608c2ecf20Sopenharmony_ci struct scatterlist *dst, struct scatterlist *src, 1618c2ecf20Sopenharmony_ci unsigned int *nbytes, unsigned int offset, u8 *oiv); 1628c2ecf20Sopenharmony_cistruct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int, 1638c2ecf20Sopenharmony_ci struct scatterlist *, unsigned int, 1648c2ecf20Sopenharmony_ci unsigned int *); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 1678c2ecf20Sopenharmony_ci#define NX_DEBUGFS_INIT(drv) nx_debugfs_init(drv) 1688c2ecf20Sopenharmony_ci#define NX_DEBUGFS_FINI(drv) nx_debugfs_fini(drv) 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_civoid nx_debugfs_init(struct nx_crypto_driver *); 1718c2ecf20Sopenharmony_civoid nx_debugfs_fini(struct nx_crypto_driver *); 1728c2ecf20Sopenharmony_ci#else 1738c2ecf20Sopenharmony_ci#define NX_DEBUGFS_INIT(drv) do {} while (0) 1748c2ecf20Sopenharmony_ci#define NX_DEBUGFS_FINI(drv) do {} while (0) 1758c2ecf20Sopenharmony_ci#endif 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci#define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL) 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ciextern struct skcipher_alg nx_cbc_aes_alg; 1808c2ecf20Sopenharmony_ciextern struct skcipher_alg nx_ecb_aes_alg; 1818c2ecf20Sopenharmony_ciextern struct aead_alg nx_gcm_aes_alg; 1828c2ecf20Sopenharmony_ciextern struct aead_alg nx_gcm4106_aes_alg; 1838c2ecf20Sopenharmony_ciextern struct skcipher_alg nx_ctr3686_aes_alg; 1848c2ecf20Sopenharmony_ciextern struct aead_alg nx_ccm_aes_alg; 1858c2ecf20Sopenharmony_ciextern struct aead_alg nx_ccm4309_aes_alg; 1868c2ecf20Sopenharmony_ciextern struct shash_alg nx_shash_aes_xcbc_alg; 1878c2ecf20Sopenharmony_ciextern struct shash_alg nx_shash_sha512_alg; 1888c2ecf20Sopenharmony_ciextern struct shash_alg nx_shash_sha256_alg; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ciextern struct nx_crypto_driver nx_driver; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci#define SCATTERWALK_TO_SG 1 1938c2ecf20Sopenharmony_ci#define SCATTERWALK_FROM_SG 0 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci#endif 196