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