Greg Kroah-Hartman | b244131 | 2017-11-01 15:07:57 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 2 | |
| 3 | #ifndef __NX_H__ |
| 4 | #define __NX_H__ |
| 5 | |
Herbert Xu | 030f4e9 | 2015-07-07 17:30:25 +0800 | [diff] [blame] | 6 | #include <crypto/ctr.h> |
| 7 | |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 8 | #define NX_NAME "nx-crypto" |
| 9 | #define NX_STRING "IBM Power7+ Nest Accelerator Crypto Driver" |
| 10 | #define NX_VERSION "1.0" |
| 11 | |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 12 | /* a scatterlist in the format PHYP is expecting */ |
| 13 | struct nx_sg { |
| 14 | u64 addr; |
| 15 | u32 rsvd; |
| 16 | u32 len; |
| 17 | } __attribute((packed)); |
| 18 | |
| 19 | #define NX_PAGE_SIZE (4096) |
| 20 | #define NX_MAX_SG_ENTRIES (NX_PAGE_SIZE/(sizeof(struct nx_sg))) |
| 21 | |
| 22 | enum nx_status { |
| 23 | NX_DISABLED, |
| 24 | NX_WAITING, |
| 25 | NX_OKAY |
| 26 | }; |
| 27 | |
| 28 | /* msc_triplet and max_sync_cop are used only to assist in parsing the |
| 29 | * openFirmware property */ |
| 30 | struct msc_triplet { |
| 31 | u32 keybitlen; |
| 32 | u32 databytelen; |
| 33 | u32 sglen; |
| 34 | } __packed; |
| 35 | |
| 36 | struct max_sync_cop { |
| 37 | u32 fc; |
| 38 | u32 mode; |
| 39 | u32 triplets; |
Gustavo A. R. Silva | 5a8a076 | 2020-02-24 10:21:00 -0600 | [diff] [blame] | 40 | struct msc_triplet trip[]; |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 41 | } __packed; |
| 42 | |
| 43 | struct alg_props { |
| 44 | u32 databytelen; |
| 45 | u32 sglen; |
| 46 | }; |
| 47 | |
| 48 | #define NX_OF_FLAG_MAXSGLEN_SET (1) |
| 49 | #define NX_OF_FLAG_STATUS_SET (2) |
| 50 | #define NX_OF_FLAG_MAXSYNCCOP_SET (4) |
| 51 | #define NX_OF_FLAG_MASK_READY (NX_OF_FLAG_MAXSGLEN_SET | \ |
| 52 | NX_OF_FLAG_STATUS_SET | \ |
| 53 | NX_OF_FLAG_MAXSYNCCOP_SET) |
| 54 | struct nx_of { |
| 55 | u32 flags; |
| 56 | u32 max_sg_len; |
| 57 | enum nx_status status; |
| 58 | struct alg_props ap[NX_MAX_FC][NX_MAX_MODE][3]; |
| 59 | }; |
| 60 | |
| 61 | struct nx_stats { |
| 62 | atomic_t aes_ops; |
| 63 | atomic64_t aes_bytes; |
| 64 | atomic_t sha256_ops; |
| 65 | atomic64_t sha256_bytes; |
| 66 | atomic_t sha512_ops; |
| 67 | atomic64_t sha512_bytes; |
| 68 | |
| 69 | atomic_t sync_ops; |
| 70 | |
| 71 | atomic_t errors; |
| 72 | atomic_t last_error; |
| 73 | atomic_t last_error_pid; |
| 74 | }; |
| 75 | |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 76 | struct nx_crypto_driver { |
| 77 | struct nx_stats stats; |
| 78 | struct nx_of of; |
| 79 | struct vio_dev *viodev; |
| 80 | struct vio_driver viodriver; |
Greg Kroah-Hartman | 576d152 | 2019-06-14 16:29:04 +0200 | [diff] [blame] | 81 | struct dentry *dfs_root; |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 82 | }; |
| 83 | |
| 84 | #define NX_GCM4106_NONCE_LEN (4) |
| 85 | #define NX_GCM_CTR_OFFSET (12) |
Herbert Xu | 030f4e9 | 2015-07-07 17:30:25 +0800 | [diff] [blame] | 86 | struct nx_gcm_rctx { |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 87 | u8 iv[16]; |
Herbert Xu | 030f4e9 | 2015-07-07 17:30:25 +0800 | [diff] [blame] | 88 | }; |
| 89 | |
| 90 | struct nx_gcm_priv { |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 91 | u8 iauth_tag[16]; |
| 92 | u8 nonce[NX_GCM4106_NONCE_LEN]; |
| 93 | }; |
| 94 | |
| 95 | #define NX_CCM_AES_KEY_LEN (16) |
| 96 | #define NX_CCM4309_AES_KEY_LEN (19) |
| 97 | #define NX_CCM4309_NONCE_LEN (3) |
Herbert Xu | 030f4e9 | 2015-07-07 17:30:25 +0800 | [diff] [blame] | 98 | struct nx_ccm_rctx { |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 99 | u8 iv[16]; |
Herbert Xu | 030f4e9 | 2015-07-07 17:30:25 +0800 | [diff] [blame] | 100 | }; |
| 101 | |
| 102 | struct nx_ccm_priv { |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 103 | u8 b0[16]; |
| 104 | u8 iauth_tag[16]; |
| 105 | u8 oauth_tag[16]; |
| 106 | u8 nonce[NX_CCM4309_NONCE_LEN]; |
| 107 | }; |
| 108 | |
| 109 | struct nx_xcbc_priv { |
| 110 | u8 key[16]; |
| 111 | }; |
| 112 | |
| 113 | struct nx_ctr_priv { |
Herbert Xu | 030f4e9 | 2015-07-07 17:30:25 +0800 | [diff] [blame] | 114 | u8 nonce[CTR_RFC3686_NONCE_SIZE]; |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 115 | }; |
| 116 | |
| 117 | struct nx_crypto_ctx { |
Marcelo Cerri | c849163 | 2013-08-12 18:49:37 -0300 | [diff] [blame] | 118 | spinlock_t lock; /* synchronize access to the context */ |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 119 | void *kmem; /* unaligned, kmalloc'd buffer */ |
| 120 | size_t kmem_len; /* length of kmem */ |
| 121 | struct nx_csbcpb *csbcpb; /* aligned page given to phyp @ hcall time */ |
| 122 | struct vio_pfo_op op; /* operation struct with hcall parameters */ |
| 123 | struct nx_csbcpb *csbcpb_aead; /* secondary csbcpb used by AEAD algs */ |
| 124 | struct vio_pfo_op op_aead;/* operation struct for csbcpb_aead */ |
| 125 | |
| 126 | struct nx_sg *in_sg; /* aligned pointer into kmem to an sg list */ |
| 127 | struct nx_sg *out_sg; /* aligned pointer into kmem to an sg list */ |
| 128 | |
| 129 | struct alg_props *ap; /* pointer into props based on our key size */ |
| 130 | struct alg_props props[3];/* openFirmware properties for requests */ |
| 131 | struct nx_stats *stats; /* pointer into an nx_crypto_driver for stats |
| 132 | reporting */ |
| 133 | |
| 134 | union { |
| 135 | struct nx_gcm_priv gcm; |
| 136 | struct nx_ccm_priv ccm; |
| 137 | struct nx_xcbc_priv xcbc; |
| 138 | struct nx_ctr_priv ctr; |
| 139 | } priv; |
| 140 | }; |
| 141 | |
Herbert Xu | 9129c26 | 2015-08-17 18:04:17 +0800 | [diff] [blame] | 142 | struct crypto_aead; |
| 143 | |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 144 | /* prototypes */ |
Herbert Xu | cc81565 | 2015-07-14 16:53:21 +0800 | [diff] [blame] | 145 | int nx_crypto_ctx_aes_ccm_init(struct crypto_aead *tfm); |
Herbert Xu | 201f28f | 2015-06-16 13:54:21 +0800 | [diff] [blame] | 146 | int nx_crypto_ctx_aes_gcm_init(struct crypto_aead *tfm); |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 147 | int nx_crypto_ctx_aes_xcbc_init(struct crypto_tfm *tfm); |
Eric Biggers | 4ba8029 | 2019-10-12 21:39:18 -0700 | [diff] [blame] | 148 | int nx_crypto_ctx_aes_ctr_init(struct crypto_skcipher *tfm); |
Eric Biggers | c1e9c38 | 2019-10-12 21:39:17 -0700 | [diff] [blame] | 149 | int nx_crypto_ctx_aes_cbc_init(struct crypto_skcipher *tfm); |
Eric Biggers | bfd9efd | 2019-10-12 21:39:16 -0700 | [diff] [blame] | 150 | int nx_crypto_ctx_aes_ecb_init(struct crypto_skcipher *tfm); |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 151 | int nx_crypto_ctx_sha_init(struct crypto_tfm *tfm); |
| 152 | void nx_crypto_ctx_exit(struct crypto_tfm *tfm); |
Eric Biggers | bfd9efd | 2019-10-12 21:39:16 -0700 | [diff] [blame] | 153 | void nx_crypto_ctx_skcipher_exit(struct crypto_skcipher *tfm); |
Herbert Xu | 201f28f | 2015-06-16 13:54:21 +0800 | [diff] [blame] | 154 | void nx_crypto_ctx_aead_exit(struct crypto_aead *tfm); |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 155 | void nx_ctx_init(struct nx_crypto_ctx *nx_ctx, unsigned int function); |
| 156 | int nx_hcall_sync(struct nx_crypto_ctx *ctx, struct vio_pfo_op *op, |
| 157 | u32 may_sleep); |
Leonidas S. Barbosa | f129430 | 2014-10-28 15:50:45 -0200 | [diff] [blame] | 158 | struct nx_sg *nx_build_sg_list(struct nx_sg *, u8 *, unsigned int *, u32); |
Eric Biggers | 7740bd5 | 2019-10-12 21:39:15 -0700 | [diff] [blame] | 159 | int nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx, const u8 *iv, |
| 160 | struct scatterlist *dst, struct scatterlist *src, |
| 161 | unsigned int *nbytes, unsigned int offset, u8 *oiv); |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 162 | struct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int, |
| 163 | struct scatterlist *, unsigned int, |
Leonidas S. Barbosa | f129430 | 2014-10-28 15:50:45 -0200 | [diff] [blame] | 164 | unsigned int *); |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 165 | |
| 166 | #ifdef CONFIG_DEBUG_FS |
| 167 | #define NX_DEBUGFS_INIT(drv) nx_debugfs_init(drv) |
| 168 | #define NX_DEBUGFS_FINI(drv) nx_debugfs_fini(drv) |
| 169 | |
Greg Kroah-Hartman | 576d152 | 2019-06-14 16:29:04 +0200 | [diff] [blame] | 170 | void nx_debugfs_init(struct nx_crypto_driver *); |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 171 | void nx_debugfs_fini(struct nx_crypto_driver *); |
| 172 | #else |
| 173 | #define NX_DEBUGFS_INIT(drv) (0) |
| 174 | #define NX_DEBUGFS_FINI(drv) (0) |
| 175 | #endif |
| 176 | |
| 177 | #define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL) |
| 178 | |
Eric Biggers | c1e9c38 | 2019-10-12 21:39:17 -0700 | [diff] [blame] | 179 | extern struct skcipher_alg nx_cbc_aes_alg; |
Eric Biggers | bfd9efd | 2019-10-12 21:39:16 -0700 | [diff] [blame] | 180 | extern struct skcipher_alg nx_ecb_aes_alg; |
Herbert Xu | 201f28f | 2015-06-16 13:54:21 +0800 | [diff] [blame] | 181 | extern struct aead_alg nx_gcm_aes_alg; |
| 182 | extern struct aead_alg nx_gcm4106_aes_alg; |
Eric Biggers | 4ba8029 | 2019-10-12 21:39:18 -0700 | [diff] [blame] | 183 | extern struct skcipher_alg nx_ctr3686_aes_alg; |
Herbert Xu | cc81565 | 2015-07-14 16:53:21 +0800 | [diff] [blame] | 184 | extern struct aead_alg nx_ccm_aes_alg; |
| 185 | extern struct aead_alg nx_ccm4309_aes_alg; |
Kent Yoder | ae0222b | 2012-05-14 10:59:38 +0000 | [diff] [blame] | 186 | extern struct shash_alg nx_shash_aes_xcbc_alg; |
| 187 | extern struct shash_alg nx_shash_sha512_alg; |
| 188 | extern struct shash_alg nx_shash_sha256_alg; |
| 189 | |
| 190 | extern struct nx_crypto_driver nx_driver; |
| 191 | |
| 192 | #define SCATTERWALK_TO_SG 1 |
| 193 | #define SCATTERWALK_FROM_SG 0 |
| 194 | |
| 195 | #endif |