1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/ceph/ceph_debug.h> 4 5 #include <linux/err.h> 6 #include <linux/scatterlist.h> 7 #include <linux/sched.h> 8 #include <linux/slab.h> 9 #include <crypto/aes.h> 10 #include <crypto/skcipher.h> 11 #include <linux/key-type.h> 12 #include <linux/sched/mm.h> 13 14 #include <keys/ceph-type.h> 15 #include <keys/user-type.h> 16 #include <linux/ceph/decode.h> 17 #include "crypto.h" 18 19 /* 20 * Set ->key and ->tfm. The rest of the key should be filled in before 21 * this function is called. 22 */ 23 static int set_secret(struct ceph_crypto_key *key, void *buf) 24 { 25 unsigned int noio_flag; 26 int ret; 27 28 key->key = NULL; 29 key->tfm = NULL; 30 31 switch (key->type) { 32 case CEPH_CRYPTO_NONE: 33 return 0; /* nothing to do */ 34 case CEPH_CRYPTO_AES: 35 break; 36 default: 37 return -ENOTSUPP; 38 } 39 40 if (!key->len) 41 return -EINVAL; 42 43 key->key = kmemdup(buf, key->len, GFP_NOIO); 44 if (!key->key) { 45 ret = -ENOMEM; 46 goto fail; 47 } 48 49 /* crypto_alloc_sync_skcipher() allocates with GFP_KERNEL */ 50 noio_flag = memalloc_noio_save(); 51 key->tfm = crypto_alloc_sync_skcipher("cbc(aes)", 0, 0); 52 memalloc_noio_restore(noio_flag); 53 if (IS_ERR(key->tfm)) { 54 ret = PTR_ERR(key->tfm); 55 key->tfm = NULL; 56 goto fail; 57 } 58 59 ret = crypto_sync_skcipher_setkey(key->tfm, key->key, key->len); 60 if (ret) 61 goto fail; 62 63 return 0; 64 65 fail: 66 ceph_crypto_key_destroy(key); 67 return ret; 68 } 69 70 int ceph_crypto_key_clone(struct ceph_crypto_key *dst, 71 const struct ceph_crypto_key *src) 72 { 73 memcpy(dst, src, sizeof(struct ceph_crypto_key)); 74 return set_secret(dst, src->key); 75 } 76 77 int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end) 78 { 79 int ret; 80 81 ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad); 82 key->type = ceph_decode_16(p); 83 ceph_decode_copy(p, &key->created, sizeof(key->created)); 84 key->len = ceph_decode_16(p); 85 ceph_decode_need(p, end, key->len, bad); 86 ret = set_secret(key, *p); 87 memzero_explicit(*p, key->len); 88 *p += key->len; 89 return ret; 90 91 bad: 92 dout("failed to decode crypto key\n"); 93 return -EINVAL; 94 } 95 96 int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey) 97 { 98 int inlen = strlen(inkey); 99 int blen = inlen * 3 / 4; 100 void *buf, *p; 101 int ret; 102 103 dout("crypto_key_unarmor %s\n", inkey); 104 buf = kmalloc(blen, GFP_NOFS); 105 if (!buf) 106 return -ENOMEM; 107 blen = ceph_unarmor(buf, inkey, inkey+inlen); 108 if (blen < 0) { 109 kfree(buf); 110 return blen; 111 } 112 113 p = buf; 114 ret = ceph_crypto_key_decode(key, &p, p + blen); 115 kfree(buf); 116 if (ret) 117 return ret; 118 dout("crypto_key_unarmor key %p type %d len %d\n", key, 119 key->type, key->len); 120 return 0; 121 } 122 123 void ceph_crypto_key_destroy(struct ceph_crypto_key *key) 124 { 125 if (key) { 126 kfree_sensitive(key->key); 127 key->key = NULL; 128 if (key->tfm) { 129 crypto_free_sync_skcipher(key->tfm); 130 key->tfm = NULL; 131 } 132 } 133 } 134 135 static const u8 *aes_iv = (u8 *)CEPH_AES_IV; 136 137 /* 138 * Should be used for buffers allocated with kvmalloc(). 139 * Currently these are encrypt out-buffer (ceph_buffer) and decrypt 140 * in-buffer (msg front). 141 * 142 * Dispose of @sgt with teardown_sgtable(). 143 * 144 * @prealloc_sg is to avoid memory allocation inside sg_alloc_table() 145 * in cases where a single sg is sufficient. No attempt to reduce the 146 * number of sgs by squeezing physically contiguous pages together is 147 * made though, for simplicity. 148 */ 149 static int setup_sgtable(struct sg_table *sgt, struct scatterlist *prealloc_sg, 150 const void *buf, unsigned int buf_len) 151 { 152 struct scatterlist *sg; 153 const bool is_vmalloc = is_vmalloc_addr(buf); 154 unsigned int off = offset_in_page(buf); 155 unsigned int chunk_cnt = 1; 156 unsigned int chunk_len = PAGE_ALIGN(off + buf_len); 157 int i; 158 int ret; 159 160 if (buf_len == 0) { 161 memset(sgt, 0, sizeof(*sgt)); 162 return -EINVAL; 163 } 164 165 if (is_vmalloc) { 166 chunk_cnt = chunk_len >> PAGE_SHIFT; 167 chunk_len = PAGE_SIZE; 168 } 169 170 if (chunk_cnt > 1) { 171 ret = sg_alloc_table(sgt, chunk_cnt, GFP_NOFS); 172 if (ret) 173 return ret; 174 } else { 175 WARN_ON(chunk_cnt != 1); 176 sg_init_table(prealloc_sg, 1); 177 sgt->sgl = prealloc_sg; 178 sgt->nents = sgt->orig_nents = 1; 179 } 180 181 for_each_sg(sgt->sgl, sg, sgt->orig_nents, i) { 182 struct page *page; 183 unsigned int len = min(chunk_len - off, buf_len); 184 185 if (is_vmalloc) 186 page = vmalloc_to_page(buf); 187 else 188 page = virt_to_page(buf); 189 190 sg_set_page(sg, page, len, off); 191 192 off = 0; 193 buf += len; 194 buf_len -= len; 195 } 196 WARN_ON(buf_len != 0); 197 198 return 0; 199 } 200 201 static void teardown_sgtable(struct sg_table *sgt) 202 { 203 if (sgt->orig_nents > 1) 204 sg_free_table(sgt); 205 } 206 207 static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt, 208 void *buf, int buf_len, int in_len, int *pout_len) 209 { 210 SYNC_SKCIPHER_REQUEST_ON_STACK(req, key->tfm); 211 struct sg_table sgt; 212 struct scatterlist prealloc_sg; 213 char iv[AES_BLOCK_SIZE] __aligned(8); 214 int pad_byte = AES_BLOCK_SIZE - (in_len & (AES_BLOCK_SIZE - 1)); 215 int crypt_len = encrypt ? in_len + pad_byte : in_len; 216 int ret; 217 218 WARN_ON(crypt_len > buf_len); 219 if (encrypt) 220 memset(buf + in_len, pad_byte, pad_byte); 221 ret = setup_sgtable(&sgt, &prealloc_sg, buf, crypt_len); 222 if (ret) 223 return ret; 224 225 memcpy(iv, aes_iv, AES_BLOCK_SIZE); 226 skcipher_request_set_sync_tfm(req, key->tfm); 227 skcipher_request_set_callback(req, 0, NULL, NULL); 228 skcipher_request_set_crypt(req, sgt.sgl, sgt.sgl, crypt_len, iv); 229 230 /* 231 print_hex_dump(KERN_ERR, "key: ", DUMP_PREFIX_NONE, 16, 1, 232 key->key, key->len, 1); 233 print_hex_dump(KERN_ERR, " in: ", DUMP_PREFIX_NONE, 16, 1, 234 buf, crypt_len, 1); 235 */ 236 if (encrypt) 237 ret = crypto_skcipher_encrypt(req); 238 else 239 ret = crypto_skcipher_decrypt(req); 240 skcipher_request_zero(req); 241 if (ret) { 242 pr_err("%s %scrypt failed: %d\n", __func__, 243 encrypt ? "en" : "de", ret); 244 goto out_sgt; 245 } 246 /* 247 print_hex_dump(KERN_ERR, "out: ", DUMP_PREFIX_NONE, 16, 1, 248 buf, crypt_len, 1); 249 */ 250 251 if (encrypt) { 252 *pout_len = crypt_len; 253 } else { 254 pad_byte = *(char *)(buf + in_len - 1); 255 if (pad_byte > 0 && pad_byte <= AES_BLOCK_SIZE && 256 in_len >= pad_byte) { 257 *pout_len = in_len - pad_byte; 258 } else { 259 pr_err("%s got bad padding %d on in_len %d\n", 260 __func__, pad_byte, in_len); 261 ret = -EPERM; 262 goto out_sgt; 263 } 264 } 265 266 out_sgt: 267 teardown_sgtable(&sgt); 268 return ret; 269 } 270 271 int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, 272 void *buf, int buf_len, int in_len, int *pout_len) 273 { 274 switch (key->type) { 275 case CEPH_CRYPTO_NONE: 276 *pout_len = in_len; 277 return 0; 278 case CEPH_CRYPTO_AES: 279 return ceph_aes_crypt(key, encrypt, buf, buf_len, in_len, 280 pout_len); 281 default: 282 return -ENOTSUPP; 283 } 284 } 285 286 static int ceph_key_preparse(struct key_preparsed_payload *prep) 287 { 288 struct ceph_crypto_key *ckey; 289 size_t datalen = prep->datalen; 290 int ret; 291 void *p; 292 293 ret = -EINVAL; 294 if (datalen <= 0 || datalen > 32767 || !prep->data) 295 goto err; 296 297 ret = -ENOMEM; 298 ckey = kmalloc(sizeof(*ckey), GFP_KERNEL); 299 if (!ckey) 300 goto err; 301 302 /* TODO ceph_crypto_key_decode should really take const input */ 303 p = (void *)prep->data; 304 ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->data+datalen); 305 if (ret < 0) 306 goto err_ckey; 307 308 prep->payload.data[0] = ckey; 309 prep->quotalen = datalen; 310 return 0; 311 312 err_ckey: 313 kfree(ckey); 314 err: 315 return ret; 316 } 317 318 static void ceph_key_free_preparse(struct key_preparsed_payload *prep) 319 { 320 struct ceph_crypto_key *ckey = prep->payload.data[0]; 321 ceph_crypto_key_destroy(ckey); 322 kfree(ckey); 323 } 324 325 static void ceph_key_destroy(struct key *key) 326 { 327 struct ceph_crypto_key *ckey = key->payload.data[0]; 328 329 ceph_crypto_key_destroy(ckey); 330 kfree(ckey); 331 } 332 333 struct key_type key_type_ceph = { 334 .name = "ceph", 335 .preparse = ceph_key_preparse, 336 .free_preparse = ceph_key_free_preparse, 337 .instantiate = generic_key_instantiate, 338 .destroy = ceph_key_destroy, 339 }; 340 341 int __init ceph_crypto_init(void) 342 { 343 return register_key_type(&key_type_ceph); 344 } 345 346 void ceph_crypto_shutdown(void) 347 { 348 unregister_key_type(&key_type_ceph); 349 } 350