All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] wip-crypto
@ 2016-12-12 20:48 Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 01/15] libceph: ceph_x_encrypt_buflen() takes in_len Ilya Dryomov
                   ` (15 more replies)
  0 siblings, 16 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

Hello,

This branch started as a rewrite of ceph_*{en,de}crypt*() functions to
cope with the new CONFIG_VMAP_STACK config option, but later expanded
to include fixes for two other issues:

- in-place en/decryption (patches 1-9)
- useless cipher context creation on every request (patches 10-11)
- authorize reply verification (patches 13-14)

Thanks,

                Ilya


Ilya Dryomov (15):
  libceph: ceph_x_encrypt_buflen() takes in_len
  libceph: old_key in process_one_ticket() is redundant
  libceph: introduce ceph_x_encrypt_offset()
  libceph: introduce ceph_crypt() for in-place en/decryption
  libceph: rename and align ceph_x_authorizer::reply_buf
  libceph: tweak calcu_signature() a little
  libceph: switch ceph_x_encrypt() to ceph_crypt()
  libceph: switch ceph_x_decrypt() to ceph_crypt()
  libceph: remove now unused ceph_*{en,de}crypt*() functions
  libceph: uninline ceph_crypto_key_destroy()
  libceph: stop allocating a new cipher on every crypto request
  libceph: no need for GFP_NOFS in ceph_monc_init()
  libceph: verify authorize reply on connect
  libceph: drop len argument of *verify_authorizer_reply()
  libceph: no need to drop con->mutex for ->get_authorizer()

 fs/ceph/mds_client.c           |   4 +-
 include/linux/ceph/auth.h      |   5 +-
 include/linux/ceph/messenger.h |   2 +-
 net/ceph/auth.c                |   4 +-
 net/ceph/auth_x.c              | 197 +++++++++---------
 net/ceph/auth_x.h              |   3 +-
 net/ceph/crypto.c              | 461 ++++++++++-------------------------------
 net/ceph/crypto.h              |  26 +--
 net/ceph/messenger.c           |  19 +-
 net/ceph/mon_client.c          |  12 +-
 net/ceph/osd_client.c          |   4 +-
 11 files changed, 246 insertions(+), 491 deletions(-)

-- 
2.4.3


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 01/15] libceph: ceph_x_encrypt_buflen() takes in_len
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 02/15] libceph: old_key in process_one_ticket() is redundant Ilya Dryomov
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

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>
---
 net/ceph/auth_x.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index a0905f04bd13..4d14dc8c7746 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -308,8 +308,8 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
 	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(struct ceph_auth_client *ac,
 			     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:
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 02/15] libceph: old_key in process_one_ticket() is redundant
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 01/15] libceph: ceph_x_encrypt_buflen() takes in_len Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 03/15] libceph: introduce ceph_x_encrypt_offset() Ilya Dryomov
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

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>
---
 net/ceph/auth_x.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 4d14dc8c7746..28bde937d58a 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -148,7 +148,6 @@ static int process_one_ticket(struct ceph_auth_client *ac,
 	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 ceph_auth_client *ac,
 	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 ceph_auth_client *ac,
 	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;
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 03/15] libceph: introduce ceph_x_encrypt_offset()
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 01/15] libceph: ceph_x_encrypt_buflen() takes in_len Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 02/15] libceph: old_key in process_one_ticket() is redundant Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 04/15] libceph: introduce ceph_crypt() for in-place en/decryption Ilya Dryomov
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/auth_x.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 28bde937d58a..de30c585c2a2 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -39,10 +39,14 @@ static int ceph_x_should_authenticate(struct ceph_auth_client *ac)
 	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,
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 04/15] libceph: introduce ceph_crypt() for in-place en/decryption
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (2 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 03/15] libceph: introduce ceph_x_encrypt_offset() Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 21:11   ` Sage Weil
  2016-12-12 20:48 ` [PATCH 05/15] libceph: rename and align ceph_x_authorizer::reply_buf Ilya Dryomov
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

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>
---
 net/ceph/crypto.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 net/ceph/crypto.h |  2 ++
 2 files changed, 89 insertions(+)

diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index db2847ac5f12..32099c5c4c75 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -526,6 +526,93 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
 	}
 }
 
+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;
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index 2e9cab09f37b..73da34e8c62e 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -43,6 +43,8 @@ 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);
 void ceph_crypto_shutdown(void);
 
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 05/15] libceph: rename and align ceph_x_authorizer::reply_buf
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (3 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 04/15] libceph: introduce ceph_crypt() for in-place en/decryption Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 06/15] libceph: tweak calcu_signature() a little Ilya Dryomov
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

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>
---
 net/ceph/auth_x.c | 10 +++++-----
 net/ceph/auth_x.h |  3 ++-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index de30c585c2a2..ef1423294517 100644
--- 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_reply(struct ceph_auth_client *ac,
 	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))
diff --git a/net/ceph/auth_x.h b/net/ceph/auth_x.h
index 21a5af904bae..48e9ad41bd2a 100644
--- 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 {
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 06/15] libceph: tweak calcu_signature() a little
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (4 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 05/15] libceph: rename and align ceph_x_authorizer::reply_buf Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 07/15] libceph: switch ceph_x_encrypt() to ceph_crypt() Ilya Dryomov
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

- replace an ad-hoc array with a struct
- rename to calc_signature() for consistency

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/auth_x.c | 43 ++++++++++++++++++++++++++++---------------
 1 file changed, 28 insertions(+), 15 deletions(-)

diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index ef1423294517..78c1675b0df7 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -707,35 +707,48 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
 	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_signature(struct ceph_auth_handshake *auth,
 	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;
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 07/15] libceph: switch ceph_x_encrypt() to ceph_crypt()
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (5 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 06/15] libceph: tweak calcu_signature() a little Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 08/15] libceph: switch ceph_x_decrypt() " Ilya Dryomov
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/auth_x.c | 71 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 37 insertions(+), 34 deletions(-)

diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 78c1675b0df7..a13ce443073b 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -49,22 +49,24 @@ static int ceph_x_encrypt_buflen(int ilen)
 	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(struct ceph_auth_client *ac,
 {
 	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(struct ceph_auth_client *ac,
 		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(struct ceph_auth_client *ac,
 	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 ceph_auth_client *ac,
 	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 ceph_auth_client *ac,
 
 		/* 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(struct ceph_auth_client *ac,
 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;
 }
 
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 08/15] libceph: switch ceph_x_decrypt() to ceph_crypt()
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (6 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 07/15] libceph: switch ceph_x_encrypt() to ceph_crypt() Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 09/15] libceph: remove now unused ceph_*{en,de}crypt*() functions Ilya Dryomov
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/auth_x.c | 78 +++++++++++++++++++++++--------------------------------
 1 file changed, 32 insertions(+), 46 deletions(-)

diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index a13ce443073b..b216131915e7 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -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;
 }
 
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 09/15] libceph: remove now unused ceph_*{en,de}crypt*() functions
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (7 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 08/15] libceph: switch ceph_x_decrypt() " Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 10/15] libceph: uninline ceph_crypto_key_destroy() Ilya Dryomov
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/crypto.c | 369 ------------------------------------------------------
 net/ceph/crypto.h |  14 ---
 2 files changed, 383 deletions(-)

diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 32099c5c4c75..38936e1fd644 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -157,375 +157,6 @@ static void teardown_sgtable(struct sg_table *sgt)
 		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)
 {
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index 73da34e8c62e..c33bcafd3829 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -29,20 +29,6 @@ int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end);
 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);
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 10/15] libceph: uninline ceph_crypto_key_destroy()
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (8 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 09/15] libceph: remove now unused ceph_*{en,de}crypt*() functions Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 11/15] libceph: stop allocating a new cipher on every crypto request Ilya Dryomov
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/crypto.c | 8 ++++++++
 net/ceph/crypto.h | 9 +--------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 38936e1fd644..c4d8f68e0b18 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -80,6 +80,14 @@ int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
 	return 0;
 }
 
+void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
+{
+	if (key) {
+		kfree(key->key);
+		key->key = NULL;
+	}
+}
+
 static struct crypto_skcipher *ceph_crypto_alloc_cipher(void)
 {
 	return crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index c33bcafd3829..c4211590b721 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -14,19 +14,12 @@ struct ceph_crypto_key {
 	void *key;
 };
 
-static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
-{
-	if (key) {
-		kfree(key->key);
-		key->key = NULL;
-	}
-}
-
 int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
 			  const struct ceph_crypto_key *src);
 int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end);
 int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end);
 int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *in);
+void ceph_crypto_key_destroy(struct ceph_crypto_key *key);
 
 /* crypto.c */
 int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt,
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 11/15] libceph: stop allocating a new cipher on every crypto request
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (9 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 10/15] libceph: uninline ceph_crypto_key_destroy() Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 12/15] libceph: no need for GFP_NOFS in ceph_monc_init() Ilya Dryomov
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

This is useless and more importantly not allowed on the writeback path,
because crypto_alloc_skcipher() allocates memory with GFP_KERNEL, which
can recurse back into the filesystem:

    kworker/9:3     D ffff92303f318180     0 20732      2 0x00000080
    Workqueue: ceph-msgr ceph_con_workfn [libceph]
     ffff923035dd4480 ffff923038f8a0c0 0000000000000001 000000009eb27318
     ffff92269eb28000 ffff92269eb27338 ffff923036b145ac ffff923035dd4480
     00000000ffffffff ffff923036b145b0 ffffffff951eb4e1 ffff923036b145a8
    Call Trace:
     [<ffffffff951eb4e1>] ? schedule+0x31/0x80
     [<ffffffff951eb77a>] ? schedule_preempt_disabled+0xa/0x10
     [<ffffffff951ed1f4>] ? __mutex_lock_slowpath+0xb4/0x130
     [<ffffffff951ed28b>] ? mutex_lock+0x1b/0x30
     [<ffffffffc0a974b3>] ? xfs_reclaim_inodes_ag+0x233/0x2d0 [xfs]
     [<ffffffff94d92ba5>] ? move_active_pages_to_lru+0x125/0x270
     [<ffffffff94f2b985>] ? radix_tree_gang_lookup_tag+0xc5/0x1c0
     [<ffffffff94dad0f3>] ? __list_lru_walk_one.isra.3+0x33/0x120
     [<ffffffffc0a98331>] ? xfs_reclaim_inodes_nr+0x31/0x40 [xfs]
     [<ffffffff94e05bfe>] ? super_cache_scan+0x17e/0x190
     [<ffffffff94d919f3>] ? shrink_slab.part.38+0x1e3/0x3d0
     [<ffffffff94d9616a>] ? shrink_node+0x10a/0x320
     [<ffffffff94d96474>] ? do_try_to_free_pages+0xf4/0x350
     [<ffffffff94d967ba>] ? try_to_free_pages+0xea/0x1b0
     [<ffffffff94d863bd>] ? __alloc_pages_nodemask+0x61d/0xe60
     [<ffffffff94ddf42d>] ? cache_grow_begin+0x9d/0x560
     [<ffffffff94ddfb88>] ? fallback_alloc+0x148/0x1c0
     [<ffffffff94ed84e7>] ? __crypto_alloc_tfm+0x37/0x130
     [<ffffffff94de09db>] ? __kmalloc+0x1eb/0x580
     [<ffffffffc09fe2db>] ? crush_choose_firstn+0x3eb/0x470 [libceph]
     [<ffffffff94ed84e7>] ? __crypto_alloc_tfm+0x37/0x130
     [<ffffffff94ed9c19>] ? crypto_spawn_tfm+0x39/0x60
     [<ffffffffc08b30a3>] ? crypto_cbc_init_tfm+0x23/0x40 [cbc]
     [<ffffffff94ed857c>] ? __crypto_alloc_tfm+0xcc/0x130
     [<ffffffff94edcc23>] ? crypto_skcipher_init_tfm+0x113/0x180
     [<ffffffff94ed7cc3>] ? crypto_create_tfm+0x43/0xb0
     [<ffffffff94ed83b0>] ? crypto_larval_lookup+0x150/0x150
     [<ffffffff94ed7da2>] ? crypto_alloc_tfm+0x72/0x120
     [<ffffffffc0a01dd7>] ? ceph_aes_encrypt2+0x67/0x400 [libceph]
     [<ffffffffc09fd264>] ? ceph_pg_to_up_acting_osds+0x84/0x5b0 [libceph]
     [<ffffffff950d40a0>] ? release_sock+0x40/0x90
     [<ffffffff95139f94>] ? tcp_recvmsg+0x4b4/0xae0
     [<ffffffffc0a02714>] ? ceph_encrypt2+0x54/0xc0 [libceph]
     [<ffffffffc0a02b4d>] ? ceph_x_encrypt+0x5d/0x90 [libceph]
     [<ffffffffc0a02bdf>] ? calcu_signature+0x5f/0x90 [libceph]
     [<ffffffffc0a02ef5>] ? ceph_x_sign_message+0x35/0x50 [libceph]
     [<ffffffffc09e948c>] ? prepare_write_message_footer+0x5c/0xa0 [libceph]
     [<ffffffffc09ecd18>] ? ceph_con_workfn+0x2258/0x2dd0 [libceph]
     [<ffffffffc09e9903>] ? queue_con_delay+0x33/0xd0 [libceph]
     [<ffffffffc09f68ed>] ? __submit_request+0x20d/0x2f0 [libceph]
     [<ffffffffc09f6ef8>] ? ceph_osdc_start_request+0x28/0x30 [libceph]
     [<ffffffffc0b52603>] ? rbd_queue_workfn+0x2f3/0x350 [rbd]
     [<ffffffff94c94ec0>] ? process_one_work+0x160/0x410
     [<ffffffff94c951bd>] ? worker_thread+0x4d/0x480
     [<ffffffff94c95170>] ? process_one_work+0x410/0x410
     [<ffffffff94c9af8d>] ? kthread+0xcd/0xf0
     [<ffffffff951efb2f>] ? ret_from_fork+0x1f/0x40
     [<ffffffff94c9aec0>] ? kthread_create_on_node+0x190/0x190

Allocating the cipher along with the key fixes the issue - as long the
key doesn't change, a single cipher context can be used concurrently in
multiple requests.

We still can't take that GFP_KERNEL allocation though.  Both
ceph_crypto_key_clone() and ceph_crypto_key_decode() are called from
GFP_NOFS context, so resort to memalloc_noio_{save,restore}() here.

Reported-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/crypto.c | 85 +++++++++++++++++++++++++++++++++++++++----------------
 net/ceph/crypto.h |  1 +
 2 files changed, 61 insertions(+), 25 deletions(-)

diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index c4d8f68e0b18..3949ce70be07 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -13,14 +13,60 @@
 #include <linux/ceph/decode.h>
 #include "crypto.h"
 
+/*
+ * Set ->key and ->tfm.  The rest of the key should be filled in before
+ * this function is called.
+ */
+static int set_secret(struct ceph_crypto_key *key, void *buf)
+{
+	unsigned int noio_flag;
+	int ret;
+
+	key->key = NULL;
+	key->tfm = NULL;
+
+	switch (key->type) {
+	case CEPH_CRYPTO_NONE:
+		return 0; /* nothing to do */
+	case CEPH_CRYPTO_AES:
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	WARN_ON(!key->len);
+	key->key = kmemdup(buf, key->len, GFP_NOIO);
+	if (!key->key) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* crypto_alloc_skcipher() allocates with GFP_KERNEL */
+	noio_flag = memalloc_noio_save();
+	key->tfm = crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
+	memalloc_noio_restore(noio_flag);
+	if (IS_ERR(key->tfm)) {
+		ret = PTR_ERR(key->tfm);
+		key->tfm = NULL;
+		goto fail;
+	}
+
+	ret = crypto_skcipher_setkey(key->tfm, key->key, key->len);
+	if (ret)
+		goto fail;
+
+	return 0;
+
+fail:
+	ceph_crypto_key_destroy(key);
+	return ret;
+}
+
 int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
 			  const struct ceph_crypto_key *src)
 {
 	memcpy(dst, src, sizeof(struct ceph_crypto_key));
-	dst->key = kmemdup(src->key, src->len, GFP_NOFS);
-	if (!dst->key)
-		return -ENOMEM;
-	return 0;
+	return set_secret(dst, src->key);
 }
 
 int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
@@ -37,16 +83,16 @@ int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
 
 int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
 {
+	int ret;
+
 	ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
 	key->type = ceph_decode_16(p);
 	ceph_decode_copy(p, &key->created, sizeof(key->created));
 	key->len = ceph_decode_16(p);
 	ceph_decode_need(p, end, key->len, bad);
-	key->key = kmalloc(key->len, GFP_NOFS);
-	if (!key->key)
-		return -ENOMEM;
-	ceph_decode_copy(p, key->key, key->len);
-	return 0;
+	ret = set_secret(key, *p);
+	*p += key->len;
+	return ret;
 
 bad:
 	dout("failed to decode crypto key\n");
@@ -85,14 +131,11 @@ void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
 	if (key) {
 		kfree(key->key);
 		key->key = NULL;
+		crypto_free_skcipher(key->tfm);
+		key->tfm = NULL;
 	}
 }
 
-static struct crypto_skcipher *ceph_crypto_alloc_cipher(void)
-{
-	return crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
-}
-
 static const u8 *aes_iv = (u8 *)CEPH_AES_IV;
 
 /*
@@ -168,8 +211,7 @@ static void teardown_sgtable(struct sg_table *sgt)
 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);
+	SKCIPHER_REQUEST_ON_STACK(req, key->tfm);
 	struct sg_table sgt;
 	struct scatterlist prealloc_sg;
 	char iv[AES_BLOCK_SIZE];
@@ -177,20 +219,15 @@ static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt,
 	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;
+		return ret;
 
-	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_tfm(req, key->tfm);
 	skcipher_request_set_callback(req, 0, NULL, NULL);
 	skcipher_request_set_crypt(req, sgt.sgl, sgt.sgl, crypt_len, iv);
 
@@ -232,8 +269,6 @@ static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt,
 
 out_sgt:
 	teardown_sgtable(&sgt);
-out_tfm:
-	crypto_free_skcipher(tfm);
 	return ret;
 }
 
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index c4211590b721..58d83aa7740f 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -12,6 +12,7 @@ struct ceph_crypto_key {
 	struct ceph_timespec created;
 	int len;
 	void *key;
+	struct crypto_skcipher *tfm;
 };
 
 int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 12/15] libceph: no need for GFP_NOFS in ceph_monc_init()
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (10 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 11/15] libceph: stop allocating a new cipher on every crypto request Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 13/15] libceph: verify authorize reply on connect Ilya Dryomov
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

It's called during inital setup, when everything should be allocated
with GFP_KERNEL.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/mon_client.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index a8effc8b7280..29a0ef351c5e 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -1028,21 +1028,21 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
 	err = -ENOMEM;
 	monc->m_subscribe_ack = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE_ACK,
 				     sizeof(struct ceph_mon_subscribe_ack),
-				     GFP_NOFS, true);
+				     GFP_KERNEL, true);
 	if (!monc->m_subscribe_ack)
 		goto out_auth;
 
-	monc->m_subscribe = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 128, GFP_NOFS,
-					 true);
+	monc->m_subscribe = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 128,
+					 GFP_KERNEL, true);
 	if (!monc->m_subscribe)
 		goto out_subscribe_ack;
 
-	monc->m_auth_reply = ceph_msg_new(CEPH_MSG_AUTH_REPLY, 4096, GFP_NOFS,
-					  true);
+	monc->m_auth_reply = ceph_msg_new(CEPH_MSG_AUTH_REPLY, 4096,
+					  GFP_KERNEL, true);
 	if (!monc->m_auth_reply)
 		goto out_subscribe;
 
-	monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, GFP_NOFS, true);
+	monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, GFP_KERNEL, true);
 	monc->pending_auth = 0;
 	if (!monc->m_auth)
 		goto out_auth_reply;
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 13/15] libceph: verify authorize reply on connect
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (11 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 12/15] libceph: no need for GFP_NOFS in ceph_monc_init() Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:48 ` [PATCH 14/15] libceph: drop len argument of *verify_authorizer_reply() Ilya Dryomov
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

After sending an authorizer (ceph_x_authorize_a + ceph_x_authorize_b),
the client gets back a ceph_x_authorize_reply, which it is supposed to
verify to ensure the authenticity and protect against replay attacks.
The code for doing this is there (ceph_x_verify_authorizer_reply(),
ceph_auth_verify_authorizer_reply() + plumbing), but it is never
invoked by the the messenger.

AFAICT this goes back to 2009, when ceph authentication protocols
support was added to the kernel client in 4e7a5dcd1bba ("ceph:
negotiate authentication protocol; implement AUTH_NONE protocol").

The second param of ceph_connection_operations::verify_authorizer_reply
is unused all the way down.  Pass 0 to facilitate backporting, and kill
it in the next commit.

Cc: stable@vger.kernel.org
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/messenger.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index a5502898ea33..2efb335deada 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -2027,6 +2027,19 @@ static int process_connect(struct ceph_connection *con)
 
 	dout("process_connect on %p tag %d\n", con, (int)con->in_tag);
 
+	if (con->auth_reply_buf) {
+		/*
+		 * Any connection that defines ->get_authorizer()
+		 * should also define ->verify_authorizer_reply().
+		 * See get_connect_authorizer().
+		 */
+		ret = con->ops->verify_authorizer_reply(con, 0);
+		if (ret < 0) {
+			con->error_msg = "bad authorize reply";
+			return ret;
+		}
+	}
+
 	switch (con->in_reply.tag) {
 	case CEPH_MSGR_TAG_FEATURES:
 		pr_err("%s%lld %s feature set mismatch,"
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 14/15] libceph: drop len argument of *verify_authorizer_reply()
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (12 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 13/15] libceph: verify authorize reply on connect Ilya Dryomov
@ 2016-12-12 20:48 ` Ilya Dryomov
  2016-12-12 20:49 ` [PATCH 15/15] libceph: no need to drop con->mutex for ->get_authorizer() Ilya Dryomov
  2016-12-12 22:04 ` [PATCH 00/15] wip-crypto Sage Weil
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:48 UTC (permalink / raw)
  To: ceph-devel

The length of the reply is protocol-dependent - for cephx it's
ceph_x_authorize_reply.  Nothing sensible can be passed from the
messenger layer anyway.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 fs/ceph/mds_client.c           | 4 ++--
 include/linux/ceph/auth.h      | 5 ++---
 include/linux/ceph/messenger.h | 2 +-
 net/ceph/auth.c                | 4 ++--
 net/ceph/auth_x.c              | 2 +-
 net/ceph/messenger.c           | 2 +-
 net/ceph/osd_client.c          | 4 ++--
 7 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 815acd1a56d4..bf4d3d26850c 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -3943,13 +3943,13 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
 }
 
 
-static int verify_authorizer_reply(struct ceph_connection *con, int len)
+static int verify_authorizer_reply(struct ceph_connection *con)
 {
 	struct ceph_mds_session *s = con->private;
 	struct ceph_mds_client *mdsc = s->s_mdsc;
 	struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;
 
-	return ceph_auth_verify_authorizer_reply(ac, s->s_auth.authorizer, len);
+	return ceph_auth_verify_authorizer_reply(ac, s->s_auth.authorizer);
 }
 
 static int invalidate_authorizer(struct ceph_connection *con)
diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h
index 374bb1c4ef52..a6747789fe5c 100644
--- a/include/linux/ceph/auth.h
+++ b/include/linux/ceph/auth.h
@@ -64,7 +64,7 @@ struct ceph_auth_client_ops {
 	int (*update_authorizer)(struct ceph_auth_client *ac, int peer_type,
 				 struct ceph_auth_handshake *auth);
 	int (*verify_authorizer_reply)(struct ceph_auth_client *ac,
-				       struct ceph_authorizer *a, size_t len);
+				       struct ceph_authorizer *a);
 	void (*invalidate_authorizer)(struct ceph_auth_client *ac,
 				      int peer_type);
 
@@ -118,8 +118,7 @@ extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac,
 				       int peer_type,
 				       struct ceph_auth_handshake *a);
 extern int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
-					     struct ceph_authorizer *a,
-					     size_t len);
+					     struct ceph_authorizer *a);
 extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac,
 					    int peer_type);
 
diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h
index 8dbd7879fdc6..531f2d882bd9 100644
--- a/include/linux/ceph/messenger.h
+++ b/include/linux/ceph/messenger.h
@@ -30,7 +30,7 @@ struct ceph_connection_operations {
 	struct ceph_auth_handshake *(*get_authorizer) (
 				struct ceph_connection *con,
 			       int *proto, int force_new);
-	int (*verify_authorizer_reply) (struct ceph_connection *con, int len);
+	int (*verify_authorizer_reply) (struct ceph_connection *con);
 	int (*invalidate_authorizer)(struct ceph_connection *con);
 
 	/* there was some error on the socket (disconnect, whatever) */
diff --git a/net/ceph/auth.c b/net/ceph/auth.c
index c822b3ae1bd3..48bb8d95195b 100644
--- a/net/ceph/auth.c
+++ b/net/ceph/auth.c
@@ -315,13 +315,13 @@ int ceph_auth_update_authorizer(struct ceph_auth_client *ac,
 EXPORT_SYMBOL(ceph_auth_update_authorizer);
 
 int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
-				      struct ceph_authorizer *a, size_t len)
+				      struct ceph_authorizer *a)
 {
 	int ret = 0;
 
 	mutex_lock(&ac->mutex);
 	if (ac->ops && ac->ops->verify_authorizer_reply)
-		ret = ac->ops->verify_authorizer_reply(ac, a, len);
+		ret = ac->ops->verify_authorizer_reply(ac, a);
 	mutex_unlock(&ac->mutex);
 	return ret;
 }
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index b216131915e7..2034fb926670 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -623,7 +623,7 @@ static int ceph_x_update_authorizer(
 }
 
 static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
-					  struct ceph_authorizer *a, size_t len)
+					  struct ceph_authorizer *a)
 {
 	struct ceph_x_authorizer *au = (void *)a;
 	void *p = au->enc_buf;
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 2efb335deada..dba380429a05 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -2033,7 +2033,7 @@ static int process_connect(struct ceph_connection *con)
 		 * should also define ->verify_authorizer_reply().
 		 * See get_connect_authorizer().
 		 */
-		ret = con->ops->verify_authorizer_reply(con, 0);
+		ret = con->ops->verify_authorizer_reply(con);
 		if (ret < 0) {
 			con->error_msg = "bad authorize reply";
 			return ret;
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index e6ae15bc41b7..5d812a26f05a 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -4478,13 +4478,13 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
 }
 
 
-static int verify_authorizer_reply(struct ceph_connection *con, int len)
+static int verify_authorizer_reply(struct ceph_connection *con)
 {
 	struct ceph_osd *o = con->private;
 	struct ceph_osd_client *osdc = o->o_osdc;
 	struct ceph_auth_client *ac = osdc->client->monc.auth;
 
-	return ceph_auth_verify_authorizer_reply(ac, o->o_auth.authorizer, len);
+	return ceph_auth_verify_authorizer_reply(ac, o->o_auth.authorizer);
 }
 
 static int invalidate_authorizer(struct ceph_connection *con)
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 15/15] libceph: no need to drop con->mutex for ->get_authorizer()
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (13 preceding siblings ...)
  2016-12-12 20:48 ` [PATCH 14/15] libceph: drop len argument of *verify_authorizer_reply() Ilya Dryomov
@ 2016-12-12 20:49 ` Ilya Dryomov
  2016-12-12 22:04 ` [PATCH 00/15] wip-crypto Sage Weil
  15 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 20:49 UTC (permalink / raw)
  To: ceph-devel

->get_authorizer(), ->verify_authorizer_reply(), ->sign_message() and
->check_message_signature() shouldn't be doing anything with or on the
connection (like closing it or sending messages).

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 net/ceph/messenger.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index dba380429a05..770c52701efa 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -1393,15 +1393,9 @@ static struct ceph_auth_handshake *get_connect_authorizer(struct ceph_connection
 		return NULL;
 	}
 
-	/* Can't hold the mutex while getting authorizer */
-	mutex_unlock(&con->mutex);
 	auth = con->ops->get_authorizer(con, auth_proto, con->auth_retry);
-	mutex_lock(&con->mutex);
-
 	if (IS_ERR(auth))
 		return auth;
-	if (con->state != CON_STATE_NEGOTIATING)
-		return ERR_PTR(-EAGAIN);
 
 	con->auth_reply_buf = auth->authorizer_reply_buf;
 	con->auth_reply_buf_len = auth->authorizer_reply_buf_len;
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 04/15] libceph: introduce ceph_crypt() for in-place en/decryption
  2016-12-12 20:48 ` [PATCH 04/15] libceph: introduce ceph_crypt() for in-place en/decryption Ilya Dryomov
@ 2016-12-12 21:11   ` Sage Weil
  2016-12-12 21:15     ` Ilya Dryomov
  0 siblings, 1 reply; 19+ messages in thread
From: Sage Weil @ 2016-12-12 21:11 UTC (permalink / raw)
  To: Ilya Dryomov; +Cc: ceph-devel

On Mon, 12 Dec 2016, Ilya Dryomov wrote:
> 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>
> ---
>  net/ceph/crypto.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  net/ceph/crypto.h |  2 ++
>  2 files changed, 89 insertions(+)
> 
> diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
> index db2847ac5f12..32099c5c4c75 100644
> --- a/net/ceph/crypto.c
> +++ b/net/ceph/crypto.c
> @@ -526,6 +526,93 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
>  	}
>  }
>  
> +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));

nit: pad_bytes?

> +	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;
> diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
> index 2e9cab09f37b..73da34e8c62e 100644
> --- a/net/ceph/crypto.h
> +++ b/net/ceph/crypto.h
> @@ -43,6 +43,8 @@ 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);
>  void ceph_crypto_shutdown(void);
>  
> -- 
> 2.4.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 04/15] libceph: introduce ceph_crypt() for in-place en/decryption
  2016-12-12 21:11   ` Sage Weil
@ 2016-12-12 21:15     ` Ilya Dryomov
  0 siblings, 0 replies; 19+ messages in thread
From: Ilya Dryomov @ 2016-12-12 21:15 UTC (permalink / raw)
  To: Sage Weil; +Cc: Ceph Development

On Mon, Dec 12, 2016 at 10:11 PM, Sage Weil <sage@newdream.net> wrote:
> On Mon, 12 Dec 2016, Ilya Dryomov wrote:
>> 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>
>> ---
>>  net/ceph/crypto.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  net/ceph/crypto.h |  2 ++
>>  2 files changed, 89 insertions(+)
>>
>> diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
>> index db2847ac5f12..32099c5c4c75 100644
>> --- a/net/ceph/crypto.c
>> +++ b/net/ceph/crypto.c
>> @@ -526,6 +526,93 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
>>       }
>>  }
>>
>> +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));
>
> nit: pad_bytes?

It's also used as a PKCS7 pad *byte*

>
>> +     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);

here, so I went with byte.

Thanks,

                Ilya

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 00/15] wip-crypto
  2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
                   ` (14 preceding siblings ...)
  2016-12-12 20:49 ` [PATCH 15/15] libceph: no need to drop con->mutex for ->get_authorizer() Ilya Dryomov
@ 2016-12-12 22:04 ` Sage Weil
  15 siblings, 0 replies; 19+ messages in thread
From: Sage Weil @ 2016-12-12 22:04 UTC (permalink / raw)
  To: Ilya Dryomov; +Cc: ceph-devel

On Mon, 12 Dec 2016, Ilya Dryomov wrote:
> Hello,
> 
> This branch started as a rewrite of ceph_*{en,de}crypt*() functions to
> cope with the new CONFIG_VMAP_STACK config option, but later expanded
> to include fixes for two other issues:
> 
> - in-place en/decryption (patches 1-9)
> - useless cipher context creation on every request (patches 10-11)
> - authorize reply verification (patches 13-14)
> 
> Thanks,
> 
>                 Ilya
> 
> 
> Ilya Dryomov (15):
>   libceph: ceph_x_encrypt_buflen() takes in_len
>   libceph: old_key in process_one_ticket() is redundant
>   libceph: introduce ceph_x_encrypt_offset()
>   libceph: introduce ceph_crypt() for in-place en/decryption
>   libceph: rename and align ceph_x_authorizer::reply_buf
>   libceph: tweak calcu_signature() a little
>   libceph: switch ceph_x_encrypt() to ceph_crypt()
>   libceph: switch ceph_x_decrypt() to ceph_crypt()
>   libceph: remove now unused ceph_*{en,de}crypt*() functions
>   libceph: uninline ceph_crypto_key_destroy()
>   libceph: stop allocating a new cipher on every crypto request
>   libceph: no need for GFP_NOFS in ceph_monc_init()
>   libceph: verify authorize reply on connect
>   libceph: drop len argument of *verify_authorizer_reply()
>   libceph: no need to drop con->mutex for ->get_authorizer()

Reviewed-by: Sage Weil <sage@redhat.com>

> 
>  fs/ceph/mds_client.c           |   4 +-
>  include/linux/ceph/auth.h      |   5 +-
>  include/linux/ceph/messenger.h |   2 +-
>  net/ceph/auth.c                |   4 +-
>  net/ceph/auth_x.c              | 197 +++++++++---------
>  net/ceph/auth_x.h              |   3 +-
>  net/ceph/crypto.c              | 461 ++++++++++-------------------------------
>  net/ceph/crypto.h              |  26 +--
>  net/ceph/messenger.c           |  19 +-
>  net/ceph/mon_client.c          |  12 +-
>  net/ceph/osd_client.c          |   4 +-
>  11 files changed, 246 insertions(+), 491 deletions(-)
> 
> -- 
> 2.4.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2016-12-12 22:04 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-12 20:48 [PATCH 00/15] wip-crypto Ilya Dryomov
2016-12-12 20:48 ` [PATCH 01/15] libceph: ceph_x_encrypt_buflen() takes in_len Ilya Dryomov
2016-12-12 20:48 ` [PATCH 02/15] libceph: old_key in process_one_ticket() is redundant Ilya Dryomov
2016-12-12 20:48 ` [PATCH 03/15] libceph: introduce ceph_x_encrypt_offset() Ilya Dryomov
2016-12-12 20:48 ` [PATCH 04/15] libceph: introduce ceph_crypt() for in-place en/decryption Ilya Dryomov
2016-12-12 21:11   ` Sage Weil
2016-12-12 21:15     ` Ilya Dryomov
2016-12-12 20:48 ` [PATCH 05/15] libceph: rename and align ceph_x_authorizer::reply_buf Ilya Dryomov
2016-12-12 20:48 ` [PATCH 06/15] libceph: tweak calcu_signature() a little Ilya Dryomov
2016-12-12 20:48 ` [PATCH 07/15] libceph: switch ceph_x_encrypt() to ceph_crypt() Ilya Dryomov
2016-12-12 20:48 ` [PATCH 08/15] libceph: switch ceph_x_decrypt() " Ilya Dryomov
2016-12-12 20:48 ` [PATCH 09/15] libceph: remove now unused ceph_*{en,de}crypt*() functions Ilya Dryomov
2016-12-12 20:48 ` [PATCH 10/15] libceph: uninline ceph_crypto_key_destroy() Ilya Dryomov
2016-12-12 20:48 ` [PATCH 11/15] libceph: stop allocating a new cipher on every crypto request Ilya Dryomov
2016-12-12 20:48 ` [PATCH 12/15] libceph: no need for GFP_NOFS in ceph_monc_init() Ilya Dryomov
2016-12-12 20:48 ` [PATCH 13/15] libceph: verify authorize reply on connect Ilya Dryomov
2016-12-12 20:48 ` [PATCH 14/15] libceph: drop len argument of *verify_authorizer_reply() Ilya Dryomov
2016-12-12 20:49 ` [PATCH 15/15] libceph: no need to drop con->mutex for ->get_authorizer() Ilya Dryomov
2016-12-12 22:04 ` [PATCH 00/15] wip-crypto Sage Weil

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.