libceph: switch ceph_x_decrypt() to ceph_crypt()
authorIlya Dryomov <idryomov@gmail.com>
Fri, 2 Dec 2016 15:35:08 +0000 (16:35 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 12 Dec 2016 22:09:19 +0000 (23:09 +0100)
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Sage Weil <sage@redhat.com>
net/ceph/auth_x.c

index a13ce443073b41ad06552e04b81bb0453a147309..b216131915e74a2c160623bb045f8ac0e3971927 100644 (file)
@@ -69,32 +69,28 @@ static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf,
        return sizeof(u32) + ciphertext_len;
 }
 
-static int ceph_x_decrypt(struct ceph_crypto_key *secret,
-                         void **p, void *end, void **obuf, size_t olen)
+static int ceph_x_decrypt(struct ceph_crypto_key *secret, void **p, void *end)
 {
-       struct ceph_x_encrypt_header head;
-       size_t head_len = sizeof(head);
-       int len, ret;
-
-       len = ceph_decode_32(p);
-       if (*p + len > end)
-               return -EINVAL;
+       struct ceph_x_encrypt_header *hdr = *p + sizeof(u32);
+       int ciphertext_len, plaintext_len;
+       int ret;
 
-       dout("ceph_x_decrypt len %d\n", len);
-       if (*obuf == NULL) {
-               *obuf = kmalloc(len, GFP_NOFS);
-               if (!*obuf)
-                       return -ENOMEM;
-               olen = len;
-       }
+       ceph_decode_32_safe(p, end, ciphertext_len, e_inval);
+       ceph_decode_need(p, end, ciphertext_len, e_inval);
 
-       ret = ceph_decrypt2(secret, &head, &head_len, *obuf, &olen, *p, len);
+       ret = ceph_crypt(secret, false, *p, end - *p, ciphertext_len,
+                        &plaintext_len);
        if (ret)
                return ret;
-       if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC)
+
+       if (hdr->struct_v != 1 || le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC)
                return -EPERM;
-       *p += len;
-       return olen;
+
+       *p += ciphertext_len;
+       return plaintext_len - sizeof(struct ceph_x_encrypt_header);
+
+e_inval:
+       return -EINVAL;
 }
 
 /*
@@ -149,12 +145,10 @@ static int process_one_ticket(struct ceph_auth_client *ac,
        int type;
        u8 tkt_struct_v, blob_struct_v;
        struct ceph_x_ticket_handler *th;
-       void *dbuf = NULL;
        void *dp, *dend;
        int dlen;
        char is_enc;
        struct timespec validity;
-       void *ticket_buf = NULL;
        void *tp, *tpend;
        void **ptp;
        struct ceph_crypto_key new_session_key;
@@ -179,14 +173,12 @@ static int process_one_ticket(struct ceph_auth_client *ac,
        }
 
        /* blob for me */
-       dlen = ceph_x_decrypt(secret, p, end, &dbuf, 0);
-       if (dlen <= 0) {
-               ret = dlen;
+       dp = *p + ceph_x_encrypt_offset();
+       ret = ceph_x_decrypt(secret, p, end);
+       if (ret < 0)
                goto out;
-       }
-       dout(" decrypted %d bytes\n", dlen);
-       dp = dbuf;
-       dend = dp + dlen;
+       dout(" decrypted %d bytes\n", ret);
+       dend = dp + ret;
 
        tkt_struct_v = ceph_decode_8(&dp);
        if (tkt_struct_v != 1)
@@ -207,15 +199,13 @@ static int process_one_ticket(struct ceph_auth_client *ac,
        ceph_decode_8_safe(p, end, is_enc, bad);
        if (is_enc) {
                /* encrypted */
-               dout(" encrypted ticket\n");
-               dlen = ceph_x_decrypt(&th->session_key, p, end, &ticket_buf, 0);
-               if (dlen < 0) {
-                       ret = dlen;
+               tp = *p + ceph_x_encrypt_offset();
+               ret = ceph_x_decrypt(&th->session_key, p, end);
+               if (ret < 0)
                        goto out;
-               }
-               tp = ticket_buf;
+               dout(" encrypted ticket, decrypted %d bytes\n", ret);
                ptp = &tp;
-               tpend = *ptp + dlen;
+               tpend = tp + ret;
        } else {
                /* unencrypted */
                ptp = p;
@@ -246,8 +236,6 @@ static int process_one_ticket(struct ceph_auth_client *ac,
        xi->have_keys |= th->service;
 
 out:
-       kfree(ticket_buf);
-       kfree(dbuf);
        return ret;
 
 bad:
@@ -638,24 +626,22 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
                                          struct ceph_authorizer *a, size_t len)
 {
        struct ceph_x_authorizer *au = (void *)a;
-       int ret = 0;
-       struct ceph_x_authorize_reply reply;
-       void *preply = &reply;
        void *p = au->enc_buf;
+       struct ceph_x_authorize_reply *reply = p + ceph_x_encrypt_offset();
+       int ret;
 
-       ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN,
-                            &preply, sizeof(reply));
+       ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN);
        if (ret < 0)
                return ret;
-       if (ret != sizeof(reply))
+       if (ret != sizeof(*reply))
                return -EPERM;
 
-       if (au->nonce + 1 != le64_to_cpu(reply.nonce_plus_one))
+       if (au->nonce + 1 != le64_to_cpu(reply->nonce_plus_one))
                ret = -EPERM;
        else
                ret = 0;
        dout("verify_authorizer_reply nonce %llx got %llx ret %d\n",
-            au->nonce, le64_to_cpu(reply.nonce_plus_one), ret);
+            au->nonce, le64_to_cpu(reply->nonce_plus_one), ret);
        return ret;
 }