Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 #include <linux/ceph/ceph_debug.h>
0004 
0005 #include <linux/err.h>
0006 #include <linux/scatterlist.h>
0007 #include <linux/sched.h>
0008 #include <linux/slab.h>
0009 #include <crypto/aes.h>
0010 #include <crypto/skcipher.h>
0011 #include <linux/key-type.h>
0012 #include <linux/sched/mm.h>
0013 
0014 #include <keys/ceph-type.h>
0015 #include <keys/user-type.h>
0016 #include <linux/ceph/decode.h>
0017 #include "crypto.h"
0018 
0019 /*
0020  * Set ->key and ->tfm.  The rest of the key should be filled in before
0021  * this function is called.
0022  */
0023 static int set_secret(struct ceph_crypto_key *key, void *buf)
0024 {
0025     unsigned int noio_flag;
0026     int ret;
0027 
0028     key->key = NULL;
0029     key->tfm = NULL;
0030 
0031     switch (key->type) {
0032     case CEPH_CRYPTO_NONE:
0033         return 0; /* nothing to do */
0034     case CEPH_CRYPTO_AES:
0035         break;
0036     default:
0037         return -ENOTSUPP;
0038     }
0039 
0040     if (!key->len)
0041         return -EINVAL;
0042 
0043     key->key = kmemdup(buf, key->len, GFP_NOIO);
0044     if (!key->key) {
0045         ret = -ENOMEM;
0046         goto fail;
0047     }
0048 
0049     /* crypto_alloc_sync_skcipher() allocates with GFP_KERNEL */
0050     noio_flag = memalloc_noio_save();
0051     key->tfm = crypto_alloc_sync_skcipher("cbc(aes)", 0, 0);
0052     memalloc_noio_restore(noio_flag);
0053     if (IS_ERR(key->tfm)) {
0054         ret = PTR_ERR(key->tfm);
0055         key->tfm = NULL;
0056         goto fail;
0057     }
0058 
0059     ret = crypto_sync_skcipher_setkey(key->tfm, key->key, key->len);
0060     if (ret)
0061         goto fail;
0062 
0063     return 0;
0064 
0065 fail:
0066     ceph_crypto_key_destroy(key);
0067     return ret;
0068 }
0069 
0070 int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
0071               const struct ceph_crypto_key *src)
0072 {
0073     memcpy(dst, src, sizeof(struct ceph_crypto_key));
0074     return set_secret(dst, src->key);
0075 }
0076 
0077 int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
0078 {
0079     if (*p + sizeof(u16) + sizeof(key->created) +
0080         sizeof(u16) + key->len > end)
0081         return -ERANGE;
0082     ceph_encode_16(p, key->type);
0083     ceph_encode_copy(p, &key->created, sizeof(key->created));
0084     ceph_encode_16(p, key->len);
0085     ceph_encode_copy(p, key->key, key->len);
0086     return 0;
0087 }
0088 
0089 int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
0090 {
0091     int ret;
0092 
0093     ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
0094     key->type = ceph_decode_16(p);
0095     ceph_decode_copy(p, &key->created, sizeof(key->created));
0096     key->len = ceph_decode_16(p);
0097     ceph_decode_need(p, end, key->len, bad);
0098     ret = set_secret(key, *p);
0099     memzero_explicit(*p, key->len);
0100     *p += key->len;
0101     return ret;
0102 
0103 bad:
0104     dout("failed to decode crypto key\n");
0105     return -EINVAL;
0106 }
0107 
0108 int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
0109 {
0110     int inlen = strlen(inkey);
0111     int blen = inlen * 3 / 4;
0112     void *buf, *p;
0113     int ret;
0114 
0115     dout("crypto_key_unarmor %s\n", inkey);
0116     buf = kmalloc(blen, GFP_NOFS);
0117     if (!buf)
0118         return -ENOMEM;
0119     blen = ceph_unarmor(buf, inkey, inkey+inlen);
0120     if (blen < 0) {
0121         kfree(buf);
0122         return blen;
0123     }
0124 
0125     p = buf;
0126     ret = ceph_crypto_key_decode(key, &p, p + blen);
0127     kfree(buf);
0128     if (ret)
0129         return ret;
0130     dout("crypto_key_unarmor key %p type %d len %d\n", key,
0131          key->type, key->len);
0132     return 0;
0133 }
0134 
0135 void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
0136 {
0137     if (key) {
0138         kfree_sensitive(key->key);
0139         key->key = NULL;
0140         if (key->tfm) {
0141             crypto_free_sync_skcipher(key->tfm);
0142             key->tfm = NULL;
0143         }
0144     }
0145 }
0146 
0147 static const u8 *aes_iv = (u8 *)CEPH_AES_IV;
0148 
0149 /*
0150  * Should be used for buffers allocated with kvmalloc().
0151  * Currently these are encrypt out-buffer (ceph_buffer) and decrypt
0152  * in-buffer (msg front).
0153  *
0154  * Dispose of @sgt with teardown_sgtable().
0155  *
0156  * @prealloc_sg is to avoid memory allocation inside sg_alloc_table()
0157  * in cases where a single sg is sufficient.  No attempt to reduce the
0158  * number of sgs by squeezing physically contiguous pages together is
0159  * made though, for simplicity.
0160  */
0161 static int setup_sgtable(struct sg_table *sgt, struct scatterlist *prealloc_sg,
0162              const void *buf, unsigned int buf_len)
0163 {
0164     struct scatterlist *sg;
0165     const bool is_vmalloc = is_vmalloc_addr(buf);
0166     unsigned int off = offset_in_page(buf);
0167     unsigned int chunk_cnt = 1;
0168     unsigned int chunk_len = PAGE_ALIGN(off + buf_len);
0169     int i;
0170     int ret;
0171 
0172     if (buf_len == 0) {
0173         memset(sgt, 0, sizeof(*sgt));
0174         return -EINVAL;
0175     }
0176 
0177     if (is_vmalloc) {
0178         chunk_cnt = chunk_len >> PAGE_SHIFT;
0179         chunk_len = PAGE_SIZE;
0180     }
0181 
0182     if (chunk_cnt > 1) {
0183         ret = sg_alloc_table(sgt, chunk_cnt, GFP_NOFS);
0184         if (ret)
0185             return ret;
0186     } else {
0187         WARN_ON(chunk_cnt != 1);
0188         sg_init_table(prealloc_sg, 1);
0189         sgt->sgl = prealloc_sg;
0190         sgt->nents = sgt->orig_nents = 1;
0191     }
0192 
0193     for_each_sg(sgt->sgl, sg, sgt->orig_nents, i) {
0194         struct page *page;
0195         unsigned int len = min(chunk_len - off, buf_len);
0196 
0197         if (is_vmalloc)
0198             page = vmalloc_to_page(buf);
0199         else
0200             page = virt_to_page(buf);
0201 
0202         sg_set_page(sg, page, len, off);
0203 
0204         off = 0;
0205         buf += len;
0206         buf_len -= len;
0207     }
0208     WARN_ON(buf_len != 0);
0209 
0210     return 0;
0211 }
0212 
0213 static void teardown_sgtable(struct sg_table *sgt)
0214 {
0215     if (sgt->orig_nents > 1)
0216         sg_free_table(sgt);
0217 }
0218 
0219 static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt,
0220               void *buf, int buf_len, int in_len, int *pout_len)
0221 {
0222     SYNC_SKCIPHER_REQUEST_ON_STACK(req, key->tfm);
0223     struct sg_table sgt;
0224     struct scatterlist prealloc_sg;
0225     char iv[AES_BLOCK_SIZE] __aligned(8);
0226     int pad_byte = AES_BLOCK_SIZE - (in_len & (AES_BLOCK_SIZE - 1));
0227     int crypt_len = encrypt ? in_len + pad_byte : in_len;
0228     int ret;
0229 
0230     WARN_ON(crypt_len > buf_len);
0231     if (encrypt)
0232         memset(buf + in_len, pad_byte, pad_byte);
0233     ret = setup_sgtable(&sgt, &prealloc_sg, buf, crypt_len);
0234     if (ret)
0235         return ret;
0236 
0237     memcpy(iv, aes_iv, AES_BLOCK_SIZE);
0238     skcipher_request_set_sync_tfm(req, key->tfm);
0239     skcipher_request_set_callback(req, 0, NULL, NULL);
0240     skcipher_request_set_crypt(req, sgt.sgl, sgt.sgl, crypt_len, iv);
0241 
0242     /*
0243     print_hex_dump(KERN_ERR, "key: ", DUMP_PREFIX_NONE, 16, 1,
0244                key->key, key->len, 1);
0245     print_hex_dump(KERN_ERR, " in: ", DUMP_PREFIX_NONE, 16, 1,
0246                buf, crypt_len, 1);
0247     */
0248     if (encrypt)
0249         ret = crypto_skcipher_encrypt(req);
0250     else
0251         ret = crypto_skcipher_decrypt(req);
0252     skcipher_request_zero(req);
0253     if (ret) {
0254         pr_err("%s %scrypt failed: %d\n", __func__,
0255                encrypt ? "en" : "de", ret);
0256         goto out_sgt;
0257     }
0258     /*
0259     print_hex_dump(KERN_ERR, "out: ", DUMP_PREFIX_NONE, 16, 1,
0260                buf, crypt_len, 1);
0261     */
0262 
0263     if (encrypt) {
0264         *pout_len = crypt_len;
0265     } else {
0266         pad_byte = *(char *)(buf + in_len - 1);
0267         if (pad_byte > 0 && pad_byte <= AES_BLOCK_SIZE &&
0268             in_len >= pad_byte) {
0269             *pout_len = in_len - pad_byte;
0270         } else {
0271             pr_err("%s got bad padding %d on in_len %d\n",
0272                    __func__, pad_byte, in_len);
0273             ret = -EPERM;
0274             goto out_sgt;
0275         }
0276     }
0277 
0278 out_sgt:
0279     teardown_sgtable(&sgt);
0280     return ret;
0281 }
0282 
0283 int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt,
0284            void *buf, int buf_len, int in_len, int *pout_len)
0285 {
0286     switch (key->type) {
0287     case CEPH_CRYPTO_NONE:
0288         *pout_len = in_len;
0289         return 0;
0290     case CEPH_CRYPTO_AES:
0291         return ceph_aes_crypt(key, encrypt, buf, buf_len, in_len,
0292                       pout_len);
0293     default:
0294         return -ENOTSUPP;
0295     }
0296 }
0297 
0298 static int ceph_key_preparse(struct key_preparsed_payload *prep)
0299 {
0300     struct ceph_crypto_key *ckey;
0301     size_t datalen = prep->datalen;
0302     int ret;
0303     void *p;
0304 
0305     ret = -EINVAL;
0306     if (datalen <= 0 || datalen > 32767 || !prep->data)
0307         goto err;
0308 
0309     ret = -ENOMEM;
0310     ckey = kmalloc(sizeof(*ckey), GFP_KERNEL);
0311     if (!ckey)
0312         goto err;
0313 
0314     /* TODO ceph_crypto_key_decode should really take const input */
0315     p = (void *)prep->data;
0316     ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->data+datalen);
0317     if (ret < 0)
0318         goto err_ckey;
0319 
0320     prep->payload.data[0] = ckey;
0321     prep->quotalen = datalen;
0322     return 0;
0323 
0324 err_ckey:
0325     kfree(ckey);
0326 err:
0327     return ret;
0328 }
0329 
0330 static void ceph_key_free_preparse(struct key_preparsed_payload *prep)
0331 {
0332     struct ceph_crypto_key *ckey = prep->payload.data[0];
0333     ceph_crypto_key_destroy(ckey);
0334     kfree(ckey);
0335 }
0336 
0337 static void ceph_key_destroy(struct key *key)
0338 {
0339     struct ceph_crypto_key *ckey = key->payload.data[0];
0340 
0341     ceph_crypto_key_destroy(ckey);
0342     kfree(ckey);
0343 }
0344 
0345 struct key_type key_type_ceph = {
0346     .name       = "ceph",
0347     .preparse   = ceph_key_preparse,
0348     .free_preparse  = ceph_key_free_preparse,
0349     .instantiate    = generic_key_instantiate,
0350     .destroy    = ceph_key_destroy,
0351 };
0352 
0353 int __init ceph_crypto_init(void)
0354 {
0355     return register_key_type(&key_type_ceph);
0356 }
0357 
0358 void ceph_crypto_shutdown(void)
0359 {
0360     unregister_key_type(&key_type_ceph);
0361 }