--- /dev/null
+From 864db9295b06837d11a260e5dacf99a3fdf6bce2 Mon Sep 17 00:00:00 2001
+From: Paul Donohue <linux-kernel@PaulSD.com>
+Date: Mon, 28 Nov 2016 20:11:25 -0800
+Subject: Input: ALPS - fix TrackStick support for SS5 hardware
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Paul Donohue <linux-kernel@PaulSD.com>
+
+commit 864db9295b06837d11a260e5dacf99a3fdf6bce2 upstream.
+
+The current Alps SS5 (SS4 v2) code generates bogus TouchPad events when
+TrackStick packets are processed.
+
+This causes the xorg synaptics driver to print
+"unable to find touch point 0" and
+"BUG: triggered 'if (priv->num_active_touches > priv->num_slots)'"
+messages. It also causes unexpected TouchPad button release and re-click
+event sequences if the TrackStick is moved while holding a TouchPad
+button.
+
+This commit corrects the problem by adjusting alps_process_packet_ss4_v2()
+so that it only sends TrackStick reports when processing TrackStick
+packets.
+
+Reviewed-by: Pali Rohár <pali.rohar@gmail.com>
+Signed-off-by: Paul Donohue <linux-kernel@PaulSD.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/mouse/alps.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/input/mouse/alps.c
++++ b/drivers/input/mouse/alps.c
+@@ -1346,6 +1346,18 @@ static void alps_process_packet_ss4_v2(s
+
+ priv->multi_packet = 0;
+
++ /* Report trackstick */
++ if (alps_get_pkt_id_ss4_v2(packet) == SS4_PACKET_ID_STICK) {
++ if (priv->flags & ALPS_DUALPOINT) {
++ input_report_key(dev2, BTN_LEFT, f->ts_left);
++ input_report_key(dev2, BTN_RIGHT, f->ts_right);
++ input_report_key(dev2, BTN_MIDDLE, f->ts_middle);
++ input_sync(dev2);
++ }
++ return;
++ }
++
++ /* Report touchpad */
+ alps_report_mt_data(psmouse, (f->fingers <= 4) ? f->fingers : 4);
+
+ input_mt_report_finger_count(dev, f->fingers);
+@@ -1356,13 +1368,6 @@ static void alps_process_packet_ss4_v2(s
+
+ input_report_abs(dev, ABS_PRESSURE, f->pressure);
+ input_sync(dev);
+-
+- if (priv->flags & ALPS_DUALPOINT) {
+- input_report_key(dev2, BTN_LEFT, f->ts_left);
+- input_report_key(dev2, BTN_RIGHT, f->ts_right);
+- input_report_key(dev2, BTN_MIDDLE, f->ts_middle);
+- input_sync(dev2);
+- }
+ }
+
+ static bool alps_is_valid_package_ss4_v2(struct psmouse *psmouse)
--- /dev/null
+From 36721ece1e84a25130c4befb930509b3f96de020 Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 2 Dec 2016 16:35:06 +0100
+Subject: libceph: ceph_x_encrypt_buflen() takes in_len
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 36721ece1e84a25130c4befb930509b3f96de020 upstream.
+
+Pass what's going to be encrypted - that's msg_b, not ticket_blob.
+ceph_x_encrypt_buflen() returns the upper bound, so this doesn't change
+the maxlen calculation, but makes it a bit clearer.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/auth_x.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -308,8 +308,8 @@ static int ceph_x_build_authorizer(struc
+ if (ret)
+ goto out_au;
+
+- maxlen = sizeof(*msg_a) + sizeof(msg_b) +
+- ceph_x_encrypt_buflen(ticket_blob_len);
++ maxlen = sizeof(*msg_a) + ticket_blob_len +
++ ceph_x_encrypt_buflen(sizeof(msg_b));
+ dout(" need len %d\n", maxlen);
+ if (au->buf && au->buf->alloc_len < maxlen) {
+ ceph_buffer_put(au->buf);
+@@ -350,11 +350,12 @@ static int ceph_x_build_authorizer(struc
+ p, end - p);
+ if (ret < 0)
+ goto out_au;
++
+ p += ret;
++ WARN_ON(p > end);
+ au->buf->vec.iov_len = p - au->buf->vec.iov_base;
+ dout(" built authorizer nonce %llx len %d\n", au->nonce,
+ (int)au->buf->vec.iov_len);
+- BUG_ON(au->buf->vec.iov_len > maxlen);
+ return 0;
+
+ out_au:
--- /dev/null
+From a45f795c65b479b4ba107b6ccde29b896d51ee98 Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 2 Dec 2016 16:35:07 +0100
+Subject: libceph: introduce ceph_crypt() for in-place en/decryption
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit a45f795c65b479b4ba107b6ccde29b896d51ee98 upstream.
+
+Starting with 4.9, kernel stacks may be vmalloced and therefore not
+guaranteed to be physically contiguous; the new CONFIG_VMAP_STACK
+option is enabled by default on x86. This makes it invalid to use
+on-stack buffers with the crypto scatterlist API, as sg_set_buf()
+expects a logical address and won't work with vmalloced addresses.
+
+There isn't a different (e.g. kvec-based) crypto API we could switch
+net/ceph/crypto.c to and the current scatterlist.h API isn't getting
+updated to accommodate this use case. Allocating a new header and
+padding for each operation is a non-starter, so do the en/decryption
+in-place on a single pre-assembled (header + data + padding) heap
+buffer. This is explicitly supported by the crypto API:
+
+ "... the caller may provide the same scatter/gather list for the
+ plaintext and cipher text. After the completion of the cipher
+ operation, the plaintext data is replaced with the ciphertext data
+ in case of an encryption and vice versa for a decryption."
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/crypto.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ net/ceph/crypto.h | 2 +
+ 2 files changed, 89 insertions(+)
+
+--- a/net/ceph/crypto.c
++++ b/net/ceph/crypto.c
+@@ -526,6 +526,93 @@ int ceph_encrypt2(struct ceph_crypto_key
+ }
+ }
+
++static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt,
++ void *buf, int buf_len, int in_len, int *pout_len)
++{
++ struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher();
++ SKCIPHER_REQUEST_ON_STACK(req, tfm);
++ struct sg_table sgt;
++ struct scatterlist prealloc_sg;
++ char iv[AES_BLOCK_SIZE];
++ int pad_byte = AES_BLOCK_SIZE - (in_len & (AES_BLOCK_SIZE - 1));
++ int crypt_len = encrypt ? in_len + pad_byte : in_len;
++ int ret;
++
++ if (IS_ERR(tfm))
++ return PTR_ERR(tfm);
++
++ WARN_ON(crypt_len > buf_len);
++ if (encrypt)
++ memset(buf + in_len, pad_byte, pad_byte);
++ ret = setup_sgtable(&sgt, &prealloc_sg, buf, crypt_len);
++ if (ret)
++ goto out_tfm;
++
++ crypto_skcipher_setkey((void *)tfm, key->key, key->len);
++ memcpy(iv, aes_iv, AES_BLOCK_SIZE);
++
++ skcipher_request_set_tfm(req, tfm);
++ skcipher_request_set_callback(req, 0, NULL, NULL);
++ skcipher_request_set_crypt(req, sgt.sgl, sgt.sgl, crypt_len, iv);
++
++ /*
++ print_hex_dump(KERN_ERR, "key: ", DUMP_PREFIX_NONE, 16, 1,
++ key->key, key->len, 1);
++ print_hex_dump(KERN_ERR, " in: ", DUMP_PREFIX_NONE, 16, 1,
++ buf, crypt_len, 1);
++ */
++ if (encrypt)
++ ret = crypto_skcipher_encrypt(req);
++ else
++ ret = crypto_skcipher_decrypt(req);
++ skcipher_request_zero(req);
++ if (ret) {
++ pr_err("%s %scrypt failed: %d\n", __func__,
++ encrypt ? "en" : "de", ret);
++ goto out_sgt;
++ }
++ /*
++ print_hex_dump(KERN_ERR, "out: ", DUMP_PREFIX_NONE, 16, 1,
++ buf, crypt_len, 1);
++ */
++
++ if (encrypt) {
++ *pout_len = crypt_len;
++ } else {
++ pad_byte = *(char *)(buf + in_len - 1);
++ if (pad_byte > 0 && pad_byte <= AES_BLOCK_SIZE &&
++ in_len >= pad_byte) {
++ *pout_len = in_len - pad_byte;
++ } else {
++ pr_err("%s got bad padding %d on in_len %d\n",
++ __func__, pad_byte, in_len);
++ ret = -EPERM;
++ goto out_sgt;
++ }
++ }
++
++out_sgt:
++ teardown_sgtable(&sgt);
++out_tfm:
++ crypto_free_skcipher(tfm);
++ return ret;
++}
++
++int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt,
++ void *buf, int buf_len, int in_len, int *pout_len)
++{
++ switch (key->type) {
++ case CEPH_CRYPTO_NONE:
++ *pout_len = in_len;
++ return 0;
++ case CEPH_CRYPTO_AES:
++ return ceph_aes_crypt(key, encrypt, buf, buf_len, in_len,
++ pout_len);
++ default:
++ return -ENOTSUPP;
++ }
++}
++
+ static int ceph_key_preparse(struct key_preparsed_payload *prep)
+ {
+ struct ceph_crypto_key *ckey;
+--- a/net/ceph/crypto.h
++++ b/net/ceph/crypto.h
+@@ -43,6 +43,8 @@ int ceph_encrypt2(struct ceph_crypto_key
+ void *dst, size_t *dst_len,
+ const void *src1, size_t src1_len,
+ const void *src2, size_t src2_len);
++int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt,
++ void *buf, int buf_len, int in_len, int *pout_len);
+ int ceph_crypto_init(void);
+ void ceph_crypto_shutdown(void);
+
--- /dev/null
+From 55d9cc834f933698fc864f0d36f3cca533d30a8d Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 2 Dec 2016 16:35:07 +0100
+Subject: libceph: introduce ceph_x_encrypt_offset()
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 55d9cc834f933698fc864f0d36f3cca533d30a8d upstream.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/auth_x.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -39,10 +39,14 @@ static int ceph_x_should_authenticate(st
+ return need != 0;
+ }
+
++static int ceph_x_encrypt_offset(void)
++{
++ return sizeof(u32) + sizeof(struct ceph_x_encrypt_header);
++}
++
+ static int ceph_x_encrypt_buflen(int ilen)
+ {
+- return sizeof(struct ceph_x_encrypt_header) + ilen + 16 +
+- sizeof(u32);
++ return ceph_x_encrypt_offset() + ilen + 16;
+ }
+
+ static int ceph_x_encrypt(struct ceph_crypto_key *secret,
--- /dev/null
+From 462e650451c577d15eeb4d883d70fa9e4e529fad Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 2 Dec 2016 16:35:06 +0100
+Subject: libceph: old_key in process_one_ticket() is redundant
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 462e650451c577d15eeb4d883d70fa9e4e529fad upstream.
+
+Since commit 0a990e709356 ("ceph: clean up service ticket decoding"),
+th->session_key isn't assigned until everything is decoded.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/auth_x.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -148,7 +148,6 @@ static int process_one_ticket(struct cep
+ int dlen;
+ char is_enc;
+ struct timespec validity;
+- struct ceph_crypto_key old_key;
+ void *ticket_buf = NULL;
+ void *tp, *tpend;
+ void **ptp;
+@@ -187,7 +186,6 @@ static int process_one_ticket(struct cep
+ if (tkt_struct_v != 1)
+ goto bad;
+
+- memcpy(&old_key, &th->session_key, sizeof(old_key));
+ ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
+ if (ret)
+ goto out;
+@@ -204,7 +202,7 @@ static int process_one_ticket(struct cep
+ if (is_enc) {
+ /* encrypted */
+ dout(" encrypted ticket\n");
+- dlen = ceph_x_decrypt(&old_key, p, end, &ticket_buf, 0);
++ dlen = ceph_x_decrypt(&th->session_key, p, end, &ticket_buf, 0);
+ if (dlen < 0) {
+ ret = dlen;
+ goto out;
--- /dev/null
+From 2b1e1a7cd0a615d57455567a549f9965023321b5 Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 2 Dec 2016 16:35:08 +0100
+Subject: libceph: remove now unused ceph_*{en,de}crypt*() functions
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 2b1e1a7cd0a615d57455567a549f9965023321b5 upstream.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/crypto.c | 369 ------------------------------------------------------
+ net/ceph/crypto.h | 14 --
+ 2 files changed, 383 deletions(-)
+
+--- a/net/ceph/crypto.c
++++ b/net/ceph/crypto.c
+@@ -157,375 +157,6 @@ static void teardown_sgtable(struct sg_t
+ sg_free_table(sgt);
+ }
+
+-static int ceph_aes_encrypt(const void *key, int key_len,
+- void *dst, size_t *dst_len,
+- const void *src, size_t src_len)
+-{
+- struct scatterlist sg_in[2], prealloc_sg;
+- struct sg_table sg_out;
+- struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher();
+- SKCIPHER_REQUEST_ON_STACK(req, tfm);
+- int ret;
+- char iv[AES_BLOCK_SIZE];
+- size_t zero_padding = (0x10 - (src_len & 0x0f));
+- char pad[16];
+-
+- if (IS_ERR(tfm))
+- return PTR_ERR(tfm);
+-
+- memset(pad, zero_padding, zero_padding);
+-
+- *dst_len = src_len + zero_padding;
+-
+- sg_init_table(sg_in, 2);
+- sg_set_buf(&sg_in[0], src, src_len);
+- sg_set_buf(&sg_in[1], pad, zero_padding);
+- ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len);
+- if (ret)
+- goto out_tfm;
+-
+- crypto_skcipher_setkey((void *)tfm, key, key_len);
+- memcpy(iv, aes_iv, AES_BLOCK_SIZE);
+-
+- skcipher_request_set_tfm(req, tfm);
+- skcipher_request_set_callback(req, 0, NULL, NULL);
+- skcipher_request_set_crypt(req, sg_in, sg_out.sgl,
+- src_len + zero_padding, iv);
+-
+- /*
+- print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
+- key, key_len, 1);
+- print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
+- src, src_len, 1);
+- print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
+- pad, zero_padding, 1);
+- */
+- ret = crypto_skcipher_encrypt(req);
+- skcipher_request_zero(req);
+- if (ret < 0) {
+- pr_err("ceph_aes_crypt failed %d\n", ret);
+- goto out_sg;
+- }
+- /*
+- print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
+- dst, *dst_len, 1);
+- */
+-
+-out_sg:
+- teardown_sgtable(&sg_out);
+-out_tfm:
+- crypto_free_skcipher(tfm);
+- return ret;
+-}
+-
+-static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
+- size_t *dst_len,
+- const void *src1, size_t src1_len,
+- const void *src2, size_t src2_len)
+-{
+- struct scatterlist sg_in[3], prealloc_sg;
+- struct sg_table sg_out;
+- struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher();
+- SKCIPHER_REQUEST_ON_STACK(req, tfm);
+- int ret;
+- char iv[AES_BLOCK_SIZE];
+- size_t zero_padding = (0x10 - ((src1_len + src2_len) & 0x0f));
+- char pad[16];
+-
+- if (IS_ERR(tfm))
+- return PTR_ERR(tfm);
+-
+- memset(pad, zero_padding, zero_padding);
+-
+- *dst_len = src1_len + src2_len + zero_padding;
+-
+- sg_init_table(sg_in, 3);
+- sg_set_buf(&sg_in[0], src1, src1_len);
+- sg_set_buf(&sg_in[1], src2, src2_len);
+- sg_set_buf(&sg_in[2], pad, zero_padding);
+- ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len);
+- if (ret)
+- goto out_tfm;
+-
+- crypto_skcipher_setkey((void *)tfm, key, key_len);
+- memcpy(iv, aes_iv, AES_BLOCK_SIZE);
+-
+- skcipher_request_set_tfm(req, tfm);
+- skcipher_request_set_callback(req, 0, NULL, NULL);
+- skcipher_request_set_crypt(req, sg_in, sg_out.sgl,
+- src1_len + src2_len + zero_padding, iv);
+-
+- /*
+- print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
+- key, key_len, 1);
+- print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
+- src1, src1_len, 1);
+- print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
+- src2, src2_len, 1);
+- print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
+- pad, zero_padding, 1);
+- */
+- ret = crypto_skcipher_encrypt(req);
+- skcipher_request_zero(req);
+- if (ret < 0) {
+- pr_err("ceph_aes_crypt2 failed %d\n", ret);
+- goto out_sg;
+- }
+- /*
+- print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
+- dst, *dst_len, 1);
+- */
+-
+-out_sg:
+- teardown_sgtable(&sg_out);
+-out_tfm:
+- crypto_free_skcipher(tfm);
+- return ret;
+-}
+-
+-static int ceph_aes_decrypt(const void *key, int key_len,
+- void *dst, size_t *dst_len,
+- const void *src, size_t src_len)
+-{
+- struct sg_table sg_in;
+- struct scatterlist sg_out[2], prealloc_sg;
+- struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher();
+- SKCIPHER_REQUEST_ON_STACK(req, tfm);
+- char pad[16];
+- char iv[AES_BLOCK_SIZE];
+- int ret;
+- int last_byte;
+-
+- if (IS_ERR(tfm))
+- return PTR_ERR(tfm);
+-
+- sg_init_table(sg_out, 2);
+- sg_set_buf(&sg_out[0], dst, *dst_len);
+- sg_set_buf(&sg_out[1], pad, sizeof(pad));
+- ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len);
+- if (ret)
+- goto out_tfm;
+-
+- crypto_skcipher_setkey((void *)tfm, key, key_len);
+- memcpy(iv, aes_iv, AES_BLOCK_SIZE);
+-
+- skcipher_request_set_tfm(req, tfm);
+- skcipher_request_set_callback(req, 0, NULL, NULL);
+- skcipher_request_set_crypt(req, sg_in.sgl, sg_out,
+- src_len, iv);
+-
+- /*
+- print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
+- key, key_len, 1);
+- print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
+- src, src_len, 1);
+- */
+- ret = crypto_skcipher_decrypt(req);
+- skcipher_request_zero(req);
+- if (ret < 0) {
+- pr_err("ceph_aes_decrypt failed %d\n", ret);
+- goto out_sg;
+- }
+-
+- if (src_len <= *dst_len)
+- last_byte = ((char *)dst)[src_len - 1];
+- else
+- last_byte = pad[src_len - *dst_len - 1];
+- if (last_byte <= 16 && src_len >= last_byte) {
+- *dst_len = src_len - last_byte;
+- } else {
+- pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
+- last_byte, (int)src_len);
+- return -EPERM; /* bad padding */
+- }
+- /*
+- print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
+- dst, *dst_len, 1);
+- */
+-
+-out_sg:
+- teardown_sgtable(&sg_in);
+-out_tfm:
+- crypto_free_skcipher(tfm);
+- return ret;
+-}
+-
+-static int ceph_aes_decrypt2(const void *key, int key_len,
+- void *dst1, size_t *dst1_len,
+- void *dst2, size_t *dst2_len,
+- const void *src, size_t src_len)
+-{
+- struct sg_table sg_in;
+- struct scatterlist sg_out[3], prealloc_sg;
+- struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher();
+- SKCIPHER_REQUEST_ON_STACK(req, tfm);
+- char pad[16];
+- char iv[AES_BLOCK_SIZE];
+- int ret;
+- int last_byte;
+-
+- if (IS_ERR(tfm))
+- return PTR_ERR(tfm);
+-
+- sg_init_table(sg_out, 3);
+- sg_set_buf(&sg_out[0], dst1, *dst1_len);
+- sg_set_buf(&sg_out[1], dst2, *dst2_len);
+- sg_set_buf(&sg_out[2], pad, sizeof(pad));
+- ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len);
+- if (ret)
+- goto out_tfm;
+-
+- crypto_skcipher_setkey((void *)tfm, key, key_len);
+- memcpy(iv, aes_iv, AES_BLOCK_SIZE);
+-
+- skcipher_request_set_tfm(req, tfm);
+- skcipher_request_set_callback(req, 0, NULL, NULL);
+- skcipher_request_set_crypt(req, sg_in.sgl, sg_out,
+- src_len, iv);
+-
+- /*
+- print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
+- key, key_len, 1);
+- print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
+- src, src_len, 1);
+- */
+- ret = crypto_skcipher_decrypt(req);
+- skcipher_request_zero(req);
+- if (ret < 0) {
+- pr_err("ceph_aes_decrypt failed %d\n", ret);
+- goto out_sg;
+- }
+-
+- if (src_len <= *dst1_len)
+- last_byte = ((char *)dst1)[src_len - 1];
+- else if (src_len <= *dst1_len + *dst2_len)
+- last_byte = ((char *)dst2)[src_len - *dst1_len - 1];
+- else
+- last_byte = pad[src_len - *dst1_len - *dst2_len - 1];
+- if (last_byte <= 16 && src_len >= last_byte) {
+- src_len -= last_byte;
+- } else {
+- pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
+- last_byte, (int)src_len);
+- return -EPERM; /* bad padding */
+- }
+-
+- if (src_len < *dst1_len) {
+- *dst1_len = src_len;
+- *dst2_len = 0;
+- } else {
+- *dst2_len = src_len - *dst1_len;
+- }
+- /*
+- print_hex_dump(KERN_ERR, "dec out1: ", DUMP_PREFIX_NONE, 16, 1,
+- dst1, *dst1_len, 1);
+- print_hex_dump(KERN_ERR, "dec out2: ", DUMP_PREFIX_NONE, 16, 1,
+- dst2, *dst2_len, 1);
+- */
+-
+-out_sg:
+- teardown_sgtable(&sg_in);
+-out_tfm:
+- crypto_free_skcipher(tfm);
+- return ret;
+-}
+-
+-
+-int ceph_decrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+- const void *src, size_t src_len)
+-{
+- switch (secret->type) {
+- case CEPH_CRYPTO_NONE:
+- if (*dst_len < src_len)
+- return -ERANGE;
+- memcpy(dst, src, src_len);
+- *dst_len = src_len;
+- return 0;
+-
+- case CEPH_CRYPTO_AES:
+- return ceph_aes_decrypt(secret->key, secret->len, dst,
+- dst_len, src, src_len);
+-
+- default:
+- return -EINVAL;
+- }
+-}
+-
+-int ceph_decrypt2(struct ceph_crypto_key *secret,
+- void *dst1, size_t *dst1_len,
+- void *dst2, size_t *dst2_len,
+- const void *src, size_t src_len)
+-{
+- size_t t;
+-
+- switch (secret->type) {
+- case CEPH_CRYPTO_NONE:
+- if (*dst1_len + *dst2_len < src_len)
+- return -ERANGE;
+- t = min(*dst1_len, src_len);
+- memcpy(dst1, src, t);
+- *dst1_len = t;
+- src += t;
+- src_len -= t;
+- if (src_len) {
+- t = min(*dst2_len, src_len);
+- memcpy(dst2, src, t);
+- *dst2_len = t;
+- }
+- return 0;
+-
+- case CEPH_CRYPTO_AES:
+- return ceph_aes_decrypt2(secret->key, secret->len,
+- dst1, dst1_len, dst2, dst2_len,
+- src, src_len);
+-
+- default:
+- return -EINVAL;
+- }
+-}
+-
+-int ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+- const void *src, size_t src_len)
+-{
+- switch (secret->type) {
+- case CEPH_CRYPTO_NONE:
+- if (*dst_len < src_len)
+- return -ERANGE;
+- memcpy(dst, src, src_len);
+- *dst_len = src_len;
+- return 0;
+-
+- case CEPH_CRYPTO_AES:
+- return ceph_aes_encrypt(secret->key, secret->len, dst,
+- dst_len, src, src_len);
+-
+- default:
+- return -EINVAL;
+- }
+-}
+-
+-int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+- const void *src1, size_t src1_len,
+- const void *src2, size_t src2_len)
+-{
+- switch (secret->type) {
+- case CEPH_CRYPTO_NONE:
+- if (*dst_len < src1_len + src2_len)
+- return -ERANGE;
+- memcpy(dst, src1, src1_len);
+- memcpy(dst + src1_len, src2, src2_len);
+- *dst_len = src1_len + src2_len;
+- return 0;
+-
+- case CEPH_CRYPTO_AES:
+- return ceph_aes_encrypt2(secret->key, secret->len, dst, dst_len,
+- src1, src1_len, src2, src2_len);
+-
+- default:
+- return -EINVAL;
+- }
+-}
+-
+ static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt,
+ void *buf, int buf_len, int in_len, int *pout_len)
+ {
+--- a/net/ceph/crypto.h
++++ b/net/ceph/crypto.h
+@@ -29,20 +29,6 @@ int ceph_crypto_key_decode(struct ceph_c
+ int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *in);
+
+ /* crypto.c */
+-int ceph_decrypt(struct ceph_crypto_key *secret,
+- void *dst, size_t *dst_len,
+- const void *src, size_t src_len);
+-int ceph_encrypt(struct ceph_crypto_key *secret,
+- void *dst, size_t *dst_len,
+- const void *src, size_t src_len);
+-int ceph_decrypt2(struct ceph_crypto_key *secret,
+- void *dst1, size_t *dst1_len,
+- void *dst2, size_t *dst2_len,
+- const void *src, size_t src_len);
+-int ceph_encrypt2(struct ceph_crypto_key *secret,
+- void *dst, size_t *dst_len,
+- const void *src1, size_t src1_len,
+- const void *src2, size_t src2_len);
+ int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt,
+ void *buf, int buf_len, int in_len, int *pout_len);
+ int ceph_crypto_init(void);
--- /dev/null
+From 7882a26d2e2e520099e2961d5e2e870f8e4172dc Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 2 Dec 2016 16:35:07 +0100
+Subject: libceph: rename and align ceph_x_authorizer::reply_buf
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 7882a26d2e2e520099e2961d5e2e870f8e4172dc upstream.
+
+It's going to be used as a temporary buffer for in-place en/decryption
+with ceph_crypt() instead of on-stack buffers, so rename to enc_buf.
+Ensure alignment to avoid GFP_ATOMIC allocations in the crypto stack.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/auth_x.c | 10 +++++-----
+ net/ceph/auth_x.h | 3 ++-
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -603,8 +603,8 @@ static int ceph_x_create_authorizer(
+ auth->authorizer = (struct ceph_authorizer *) au;
+ auth->authorizer_buf = au->buf->vec.iov_base;
+ auth->authorizer_buf_len = au->buf->vec.iov_len;
+- auth->authorizer_reply_buf = au->reply_buf;
+- auth->authorizer_reply_buf_len = sizeof (au->reply_buf);
++ auth->authorizer_reply_buf = au->enc_buf;
++ auth->authorizer_reply_buf_len = CEPHX_AU_ENC_BUF_LEN;
+ auth->sign_message = ac->ops->sign_message;
+ auth->check_message_signature = ac->ops->check_message_signature;
+
+@@ -638,10 +638,10 @@ static int ceph_x_verify_authorizer_repl
+ int ret = 0;
+ struct ceph_x_authorize_reply reply;
+ void *preply = &reply;
+- void *p = au->reply_buf;
+- void *end = p + sizeof(au->reply_buf);
++ void *p = au->enc_buf;
+
+- ret = ceph_x_decrypt(&au->session_key, &p, end, &preply, sizeof(reply));
++ ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN,
++ &preply, sizeof(reply));
+ if (ret < 0)
+ return ret;
+ if (ret != sizeof(reply))
+--- a/net/ceph/auth_x.h
++++ b/net/ceph/auth_x.h
+@@ -24,6 +24,7 @@ struct ceph_x_ticket_handler {
+ unsigned long renew_after, expires;
+ };
+
++#define CEPHX_AU_ENC_BUF_LEN 128 /* big enough for encrypted blob */
+
+ struct ceph_x_authorizer {
+ struct ceph_authorizer base;
+@@ -32,7 +33,7 @@ struct ceph_x_authorizer {
+ unsigned int service;
+ u64 nonce;
+ u64 secret_id;
+- char reply_buf[128]; /* big enough for encrypted blob */
++ char enc_buf[CEPHX_AU_ENC_BUF_LEN] __aligned(8);
+ };
+
+ struct ceph_x_info {
--- /dev/null
+From e15fd0a11db00fc7f470a9fc804657ec3f6d04a5 Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 2 Dec 2016 16:35:08 +0100
+Subject: libceph: switch ceph_x_decrypt() to ceph_crypt()
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit e15fd0a11db00fc7f470a9fc804657ec3f6d04a5 upstream.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/auth_x.c | 78 ++++++++++++++++++++++--------------------------------
+ 1 file changed, 32 insertions(+), 46 deletions(-)
+
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -69,32 +69,28 @@ static int ceph_x_encrypt(struct ceph_cr
+ 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 cep
+ 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 cep
+ }
+
+ /* 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 cep
+ 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 cep
+ xi->have_keys |= th->service;
+
+ out:
+- kfree(ticket_buf);
+- kfree(dbuf);
+ return ret;
+
+ bad:
+@@ -638,24 +626,22 @@ static int ceph_x_verify_authorizer_repl
+ 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;
+ }
+
--- /dev/null
+From d03857c63bb036edff0aa7a107276360173aca4e Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 2 Dec 2016 16:35:07 +0100
+Subject: libceph: switch ceph_x_encrypt() to ceph_crypt()
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit d03857c63bb036edff0aa7a107276360173aca4e upstream.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/auth_x.c | 71 ++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 37 insertions(+), 34 deletions(-)
+
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -49,22 +49,24 @@ static int ceph_x_encrypt_buflen(int ile
+ return ceph_x_encrypt_offset() + ilen + 16;
+ }
+
+-static int ceph_x_encrypt(struct ceph_crypto_key *secret,
+- void *ibuf, int ilen, void *obuf, size_t olen)
++static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf,
++ int buf_len, int plaintext_len)
+ {
+- struct ceph_x_encrypt_header head = {
+- .struct_v = 1,
+- .magic = cpu_to_le64(CEPHX_ENC_MAGIC)
+- };
+- size_t len = olen - sizeof(u32);
++ struct ceph_x_encrypt_header *hdr = buf + sizeof(u32);
++ int ciphertext_len;
+ int ret;
+
+- ret = ceph_encrypt2(secret, obuf + sizeof(u32), &len,
+- &head, sizeof(head), ibuf, ilen);
++ hdr->struct_v = 1;
++ hdr->magic = cpu_to_le64(CEPHX_ENC_MAGIC);
++
++ ret = ceph_crypt(secret, true, buf + sizeof(u32), buf_len - sizeof(u32),
++ plaintext_len + sizeof(struct ceph_x_encrypt_header),
++ &ciphertext_len);
+ if (ret)
+ return ret;
+- ceph_encode_32(&obuf, len);
+- return len + sizeof(u32);
++
++ ceph_encode_32(&buf, ciphertext_len);
++ return sizeof(u32) + ciphertext_len;
+ }
+
+ static int ceph_x_decrypt(struct ceph_crypto_key *secret,
+@@ -296,7 +298,7 @@ static int ceph_x_build_authorizer(struc
+ {
+ int maxlen;
+ struct ceph_x_authorize_a *msg_a;
+- struct ceph_x_authorize_b msg_b;
++ struct ceph_x_authorize_b *msg_b;
+ void *p, *end;
+ int ret;
+ int ticket_blob_len =
+@@ -311,7 +313,7 @@ static int ceph_x_build_authorizer(struc
+ goto out_au;
+
+ maxlen = sizeof(*msg_a) + ticket_blob_len +
+- ceph_x_encrypt_buflen(sizeof(msg_b));
++ ceph_x_encrypt_buflen(sizeof(*msg_b));
+ dout(" need len %d\n", maxlen);
+ if (au->buf && au->buf->alloc_len < maxlen) {
+ ceph_buffer_put(au->buf);
+@@ -345,11 +347,11 @@ static int ceph_x_build_authorizer(struc
+ p += ticket_blob_len;
+ end = au->buf->vec.iov_base + au->buf->vec.iov_len;
+
++ msg_b = p + ceph_x_encrypt_offset();
++ msg_b->struct_v = 1;
+ get_random_bytes(&au->nonce, sizeof(au->nonce));
+- msg_b.struct_v = 1;
+- msg_b.nonce = cpu_to_le64(au->nonce);
+- ret = ceph_x_encrypt(&au->session_key, &msg_b, sizeof(msg_b),
+- p, end - p);
++ msg_b->nonce = cpu_to_le64(au->nonce);
++ ret = ceph_x_encrypt(&au->session_key, p, end - p, sizeof(*msg_b));
+ if (ret < 0)
+ goto out_au;
+
+@@ -455,8 +457,9 @@ static int ceph_x_build_request(struct c
+ if (need & CEPH_ENTITY_TYPE_AUTH) {
+ struct ceph_x_authenticate *auth = (void *)(head + 1);
+ void *p = auth + 1;
+- struct ceph_x_challenge_blob tmp;
+- char tmp_enc[40];
++ void *enc_buf = xi->auth_authorizer.enc_buf;
++ struct ceph_x_challenge_blob *blob = enc_buf +
++ ceph_x_encrypt_offset();
+ u64 *u;
+
+ if (p > end)
+@@ -467,16 +470,16 @@ static int ceph_x_build_request(struct c
+
+ /* encrypt and hash */
+ get_random_bytes(&auth->client_challenge, sizeof(u64));
+- tmp.client_challenge = auth->client_challenge;
+- tmp.server_challenge = cpu_to_le64(xi->server_challenge);
+- ret = ceph_x_encrypt(&xi->secret, &tmp, sizeof(tmp),
+- tmp_enc, sizeof(tmp_enc));
++ blob->client_challenge = auth->client_challenge;
++ blob->server_challenge = cpu_to_le64(xi->server_challenge);
++ ret = ceph_x_encrypt(&xi->secret, enc_buf, CEPHX_AU_ENC_BUF_LEN,
++ sizeof(*blob));
+ if (ret < 0)
+ return ret;
+
+ auth->struct_v = 1;
+ auth->key = 0;
+- for (u = (u64 *)tmp_enc; u + 1 <= (u64 *)(tmp_enc + ret); u++)
++ for (u = (u64 *)enc_buf; u + 1 <= (u64 *)(enc_buf + ret); u++)
+ auth->key ^= *(__le64 *)u;
+ dout(" server_challenge %llx client_challenge %llx key %llx\n",
+ xi->server_challenge, le64_to_cpu(auth->client_challenge),
+@@ -710,27 +713,27 @@ static void ceph_x_invalidate_authorizer
+ static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg,
+ __le64 *psig)
+ {
+- char tmp_enc[40];
++ void *enc_buf = au->enc_buf;
+ struct {
+ __le32 len;
+ __le32 header_crc;
+ __le32 front_crc;
+ __le32 middle_crc;
+ __le32 data_crc;
+- } __packed sigblock;
++ } __packed *sigblock = enc_buf + ceph_x_encrypt_offset();
+ int ret;
+
+- sigblock.len = cpu_to_le32(4*sizeof(u32));
+- sigblock.header_crc = msg->hdr.crc;
+- sigblock.front_crc = msg->footer.front_crc;
+- sigblock.middle_crc = msg->footer.middle_crc;
+- sigblock.data_crc = msg->footer.data_crc;
+- ret = ceph_x_encrypt(&au->session_key, &sigblock, sizeof(sigblock),
+- tmp_enc, sizeof(tmp_enc));
++ sigblock->len = cpu_to_le32(4*sizeof(u32));
++ sigblock->header_crc = msg->hdr.crc;
++ sigblock->front_crc = msg->footer.front_crc;
++ sigblock->middle_crc = msg->footer.middle_crc;
++ sigblock->data_crc = msg->footer.data_crc;
++ ret = ceph_x_encrypt(&au->session_key, enc_buf, CEPHX_AU_ENC_BUF_LEN,
++ sizeof(*sigblock));
+ if (ret < 0)
+ return ret;
+
+- *psig = *(__le64 *)(tmp_enc + sizeof(u32));
++ *psig = *(__le64 *)(enc_buf + sizeof(u32));
+ return 0;
+ }
+
--- /dev/null
+From 4eb4517ce7c9c573b6c823de403aeccb40018cfc Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 2 Dec 2016 16:35:07 +0100
+Subject: libceph: tweak calcu_signature() a little
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 4eb4517ce7c9c573b6c823de403aeccb40018cfc upstream.
+
+- replace an ad-hoc array with a struct
+- rename to calc_signature() for consistency
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/auth_x.c | 43 ++++++++++++++++++++++++++++---------------
+ 1 file changed, 28 insertions(+), 15 deletions(-)
+
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -707,35 +707,48 @@ static void ceph_x_invalidate_authorizer
+ invalidate_ticket(ac, CEPH_ENTITY_TYPE_AUTH);
+ }
+
+-static int calcu_signature(struct ceph_x_authorizer *au,
+- struct ceph_msg *msg, __le64 *sig)
++static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg,
++ __le64 *psig)
+ {
+- int ret;
+ char tmp_enc[40];
+- __le32 tmp[5] = {
+- cpu_to_le32(16), msg->hdr.crc, msg->footer.front_crc,
+- msg->footer.middle_crc, msg->footer.data_crc,
+- };
+- ret = ceph_x_encrypt(&au->session_key, &tmp, sizeof(tmp),
++ struct {
++ __le32 len;
++ __le32 header_crc;
++ __le32 front_crc;
++ __le32 middle_crc;
++ __le32 data_crc;
++ } __packed sigblock;
++ int ret;
++
++ sigblock.len = cpu_to_le32(4*sizeof(u32));
++ sigblock.header_crc = msg->hdr.crc;
++ sigblock.front_crc = msg->footer.front_crc;
++ sigblock.middle_crc = msg->footer.middle_crc;
++ sigblock.data_crc = msg->footer.data_crc;
++ ret = ceph_x_encrypt(&au->session_key, &sigblock, sizeof(sigblock),
+ tmp_enc, sizeof(tmp_enc));
+ if (ret < 0)
+ return ret;
+- *sig = *(__le64*)(tmp_enc + 4);
++
++ *psig = *(__le64 *)(tmp_enc + sizeof(u32));
+ return 0;
+ }
+
+ static int ceph_x_sign_message(struct ceph_auth_handshake *auth,
+ struct ceph_msg *msg)
+ {
++ __le64 sig;
+ int ret;
+
+ if (ceph_test_opt(from_msgr(msg->con->msgr), NOMSGSIGN))
+ return 0;
+
+- ret = calcu_signature((struct ceph_x_authorizer *)auth->authorizer,
+- msg, &msg->footer.sig);
+- if (ret < 0)
++ ret = calc_signature((struct ceph_x_authorizer *)auth->authorizer,
++ msg, &sig);
++ if (ret)
+ return ret;
++
++ msg->footer.sig = sig;
+ msg->footer.flags |= CEPH_MSG_FOOTER_SIGNED;
+ return 0;
+ }
+@@ -749,9 +762,9 @@ static int ceph_x_check_message_signatur
+ if (ceph_test_opt(from_msgr(msg->con->msgr), NOMSGSIGN))
+ return 0;
+
+- ret = calcu_signature((struct ceph_x_authorizer *)auth->authorizer,
+- msg, &sig_check);
+- if (ret < 0)
++ ret = calc_signature((struct ceph_x_authorizer *)auth->authorizer,
++ msg, &sig_check);
++ if (ret)
+ return ret;
+ if (sig_check == msg->footer.sig)
+ return 0;
arm64-ptrace-preserve-previous-registers-for-short-regset-write-3.patch
arm64-ptrace-avoid-uninitialised-struct-padding-in-fpr_set.patch
arm64-ptrace-reject-attempts-to-set-incomplete-hardware-breakpoint-fields.patch
+input-alps-fix-trackstick-support-for-ss5-hardware.patch
+libceph-ceph_x_encrypt_buflen-takes-in_len.patch
+libceph-old_key-in-process_one_ticket-is-redundant.patch
+libceph-introduce-ceph_x_encrypt_offset.patch
+libceph-introduce-ceph_crypt-for-in-place-en-decryption.patch
+libceph-rename-and-align-ceph_x_authorizer-reply_buf.patch
+libceph-tweak-calcu_signature-a-little.patch
+libceph-switch-ceph_x_encrypt-to-ceph_crypt.patch
+libceph-switch-ceph_x_decrypt-to-ceph_crypt.patch
+libceph-remove-now-unused-ceph_-en-de-crypt-functions.patch