All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: Herbert Xu <herbert@gondor.apana.org.au>
Cc: David Miller <davem@davemloft.net>, netdev@vger.kernel.org
Subject: Re: [PATCH 1/9] AF_RXRPC: Add blkcipher accessors for using kernel data directly
Date: Tue, 03 Apr 2007 14:52:53 +0100	[thread overview]
Message-ID: <19944.1175608373@redhat.com> (raw)
In-Reply-To: <20070403035019.GA4798@gondor.apana.org.au>

Herbert Xu <herbert@gondor.apana.org.au> wrote:

> Would it be possible to just use the existing scatterlist interface
> for now? We can simplify it later when things settle down.

I'll apply the attached patch for now and drop the bypass patch.  It's a bit
messy, but it does let me use the sg-list interface.

Note that it does paste stack space into sg-list elements, which I think
should be okay, and it asks the compiler to get it appropriately aligned bits
of stack.

David

diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index b3bd399..1eaf529 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -111,8 +111,11 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
 {
 	struct rxrpc_key_payload *payload;
 	struct blkcipher_desc desc;
+	struct scatterlist sg[2];
 	struct rxrpc_crypt iv;
-	__be32 tmpbuf[4];
+	struct {
+		__be32 x[4];
+	} tmpbuf __attribute__((aligned(16))); /* must all be in same page */
 
 	_enter("");
 
@@ -126,16 +129,18 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
 	desc.info = iv.x;
 	desc.flags = 0;
 
-	tmpbuf[0] = conn->epoch;
-	tmpbuf[1] = conn->cid;
-	tmpbuf[2] = 0;
-	tmpbuf[3] = htonl(conn->security_ix);
+	tmpbuf.x[0] = conn->epoch;
+	tmpbuf.x[1] = conn->cid;
+	tmpbuf.x[2] = 0;
+	tmpbuf.x[3] = htonl(conn->security_ix);
 
-	crypto_blkcipher_encrypt_kernel_iv(&desc, (void *) tmpbuf,
-					   (void *) tmpbuf, sizeof(tmpbuf));
+	memset(sg, 0, sizeof(sg));
+	sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf));
+	sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf));
+	crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
-	memcpy(&conn->csum_iv, &tmpbuf[2], sizeof(conn->csum_iv));
-	ASSERTCMP(conn->csum_iv.n[0], ==, tmpbuf[2]);
+	memcpy(&conn->csum_iv, &tmpbuf.x[2], sizeof(conn->csum_iv));
+	ASSERTCMP(conn->csum_iv.n[0], ==, tmpbuf.x[2]);
 
 	_leave("");
 }
@@ -151,10 +156,11 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
 	struct rxrpc_skb_priv *sp;
 	struct blkcipher_desc desc;
 	struct rxrpc_crypt iv;
+	struct scatterlist sg[2];
 	struct {
 		struct rxkad_level1_hdr hdr;
 		__be32	first;	/* first four bytes of data and padding */
-	} buf;
+	} tmpbuf __attribute__((aligned(8))); /* must all be in same page */
 	u16 check;
 
 	sp = rxrpc_skb(skb);
@@ -164,8 +170,8 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
 	check = ntohl(sp->hdr.seq ^ sp->hdr.callNumber);
 	data_size |= (u32) check << 16;
 
-	buf.hdr.data_size = htonl(data_size);
-	memcpy(&buf.first, sechdr + 4, sizeof(buf.first));
+	tmpbuf.hdr.data_size = htonl(data_size);
+	memcpy(&tmpbuf.first, sechdr + 4, sizeof(tmpbuf.first));
 
 	/* start the encryption afresh */
 	memset(&iv, 0, sizeof(iv));
@@ -173,10 +179,12 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
 	desc.info = iv.x;
 	desc.flags = 0;
 
-	crypto_blkcipher_encrypt_kernel_iv(&desc, (void *) &buf,
-					   (void *) &buf, sizeof(buf));
+	memset(sg, 0, sizeof(sg));
+	sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf));
+	sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf));
+	crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
-	memcpy(sechdr, &buf, sizeof(buf));
+	memcpy(sechdr, &tmpbuf, sizeof(tmpbuf));
 
 	_leave(" = 0");
 	return 0;
@@ -191,7 +199,8 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
 					void *sechdr)
 {
 	const struct rxrpc_key_payload *payload;
-	struct rxkad_level2_hdr rxkhdr;
+	struct rxkad_level2_hdr rxkhdr
+		__attribute__((aligned(8))); /* must be all on one page */
 	struct rxrpc_skb_priv *sp;
 	struct blkcipher_desc desc;
 	struct rxrpc_crypt iv;
@@ -217,8 +226,10 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
 	desc.info = iv.x;
 	desc.flags = 0;
 
-	crypto_blkcipher_encrypt_kernel_iv(&desc, (void *) sechdr,
-					   (void *) &rxkhdr, sizeof(rxkhdr));
+	memset(sg, 0, sizeof(sg[0]) * 2);
+	sg_set_buf(&sg[0], sechdr, sizeof(rxkhdr));
+	sg_set_buf(&sg[1], &rxkhdr, sizeof(rxkhdr));
+	crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(rxkhdr));
 
 	/* we want to encrypt the skbuff in-place */
 	nsg = skb_cow_data(skb, 0, &trailer);
@@ -246,7 +257,11 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
 	struct rxrpc_skb_priv *sp;
 	struct blkcipher_desc desc;
 	struct rxrpc_crypt iv;
-	__be32 tmpbuf[2], x;
+	struct scatterlist sg[2];
+	struct {
+		__be32 x[2];
+	} tmpbuf __attribute__((aligned(8))); /* must all be in same page */
+	__be32 x;
 	int ret;
 
 	sp = rxrpc_skb(skb);
@@ -271,13 +286,15 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
 	/* calculate the security checksum */
 	x = htonl(call->channel << (32 - RXRPC_CIDSHIFT));
 	x |= sp->hdr.seq & __constant_cpu_to_be32(0x3fffffff);
-	tmpbuf[0] = sp->hdr.callNumber;
-	tmpbuf[1] = x;
+	tmpbuf.x[0] = sp->hdr.callNumber;
+	tmpbuf.x[1] = x;
 
-	crypto_blkcipher_encrypt_kernel_iv(&desc, (void *) tmpbuf,
-					   (void *) tmpbuf, sizeof(tmpbuf));
+	memset(&sg, 0, sizeof(sg));
+	sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf));
+	sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf));
+	crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
-	x = ntohl(tmpbuf[1]);
+	x = ntohl(tmpbuf.x[1]);
 	x = (x >> 16) & 0xffff;
 	if (x == 0)
 		x = 1; /* zero checksums are not permitted */
@@ -468,7 +485,11 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
 	struct blkcipher_desc desc;
 	struct rxrpc_skb_priv *sp;
 	struct rxrpc_crypt iv;
-	__be32 tmpbuf[2], x;
+	struct scatterlist sg[2];
+	struct {
+		__be32 x[2];
+	} tmpbuf __attribute__((aligned(8))); /* must all be in same page */
+	__be32 x;
 	__be16 cksum;
 	int ret;
 
@@ -496,13 +517,15 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
 	/* validate the security checksum */
 	x = htonl(call->channel << (32 - RXRPC_CIDSHIFT));
 	x |= sp->hdr.seq & __constant_cpu_to_be32(0x3fffffff);
-	tmpbuf[0] = call->call_id;
-	tmpbuf[1] = x;
+	tmpbuf.x[0] = call->call_id;
+	tmpbuf.x[1] = x;
 
-	crypto_blkcipher_encrypt_kernel_iv(&desc, (void *) tmpbuf,
-					   (void *) tmpbuf, sizeof(tmpbuf));
+	memset(&sg, 0, sizeof(sg));
+	sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf));
+	sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf));
+	crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
-	x = ntohl(tmpbuf[1]);
+	x = ntohl(tmpbuf.x[1]);
 	x = (x >> 16) & 0xffff;
 	if (x == 0)
 		x = 1; /* zero checksums are not permitted */
@@ -661,6 +684,25 @@ static void rxkad_calc_response_checksum(struct rxkad_response *response)
 }
 
 /*
+ * load a scatterlist with a potentially split-page buffer
+ */
+static void rxkad_sg_set_buf2(struct scatterlist sg[2],
+			      void *buf, size_t buflen)
+{
+
+	memset(sg, 0, sizeof(sg));
+
+	sg_set_buf(&sg[0], buf, buflen);
+	if (sg[0].offset + buflen > PAGE_SIZE) {
+		/* the buffer was split over two pages */
+		sg[0].length = PAGE_SIZE - sg[0].offset;
+		sg_set_buf(&sg[1], buf + sg[0].length, buflen - sg[0].length);
+	}
+
+	ASSERTCMP(sg[0].length + sg[1].length, ==, buflen);
+}
+
+/*
  * encrypt the response packet
  */
 static void rxkad_encrypt_response(struct rxrpc_connection *conn,
@@ -669,6 +711,7 @@ static void rxkad_encrypt_response(struct rxrpc_connection *conn,
 {
 	struct blkcipher_desc desc;
 	struct rxrpc_crypt iv;
+	struct scatterlist ssg[2], dsg[2];
 
 	/* continue encrypting from where we left off */
 	memcpy(&iv, s2->session_key, sizeof(iv));
@@ -676,10 +719,9 @@ static void rxkad_encrypt_response(struct rxrpc_connection *conn,
 	desc.info = iv.x;
 	desc.flags = 0;
 
-	crypto_blkcipher_encrypt_kernel_iv(&desc,
-					   (void *) &resp->encrypted,
-					   (void *) &resp->encrypted,
-					   sizeof(resp->encrypted));
+	rxkad_sg_set_buf2(ssg, &resp->encrypted, sizeof(resp->encrypted));
+	memcpy(dsg, ssg, sizeof(dsg));
+	crypto_blkcipher_encrypt_iv(&desc, dsg, ssg, sizeof(resp->encrypted));
 }
 
 /*
@@ -691,7 +733,8 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
 {
 	const struct rxrpc_key_payload *payload;
 	struct rxkad_challenge challenge;
-	struct rxkad_response resp;
+	struct rxkad_response resp
+		__attribute__((aligned(8))); /* must be aligned for crypto */
 	struct rxrpc_skb_priv *sp;
 	u32 version, nonce, min_level, abort_code;
 	int ret;
@@ -773,6 +816,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
 {
 	struct blkcipher_desc desc;
 	struct rxrpc_crypt iv, key;
+	struct scatterlist ssg[1], dsg[1];
 	struct in_addr addr;
 	unsigned life;
 	time_t issue, now;
@@ -797,6 +841,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
 	}
 
 	ASSERT(conn->server_key->payload.data != NULL);
+	ASSERTCMP((unsigned long) ticket & 7UL, ==, 0);
 
 	memcpy(&iv, &conn->server_key->type_data, sizeof(iv));
 
@@ -804,7 +849,9 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
 	desc.info = iv.x;
 	desc.flags = 0;
 
-	crypto_blkcipher_decrypt_kernel_iv(&desc, ticket, ticket, ticket_len);
+	sg_init_one(&ssg[0], ticket, ticket_len);
+	memcpy(dsg, ssg, sizeof(dsg));
+	crypto_blkcipher_decrypt_iv(&desc, dsg, ssg, ticket_len);
 
 	p = ticket;
 	end = p + ticket_len;
@@ -913,6 +960,7 @@ static void rxkad_decrypt_response(struct rxrpc_connection *conn,
 				   const struct rxrpc_crypt *session_key)
 {
 	struct blkcipher_desc desc;
+	struct scatterlist ssg[2], dsg[2];
 	struct rxrpc_crypt iv;
 
 	_enter(",,%08x%08x",
@@ -930,10 +978,9 @@ static void rxkad_decrypt_response(struct rxrpc_connection *conn,
 	desc.info = iv.x;
 	desc.flags = 0;
 
-	crypto_blkcipher_decrypt_kernel_iv(&desc,
-					   (void *) &resp->encrypted,
-					   (void *) &resp->encrypted,
-					   sizeof(resp->encrypted));
+	rxkad_sg_set_buf2(ssg, &resp->encrypted, sizeof(resp->encrypted));
+	memcpy(dsg, ssg, sizeof(dsg));
+	crypto_blkcipher_decrypt_iv(&desc, dsg, ssg, sizeof(resp->encrypted));
 	mutex_unlock(&rxkad_ci_mutex);
 
 	_leave("");
@@ -946,7 +993,8 @@ static int rxkad_verify_response(struct rxrpc_connection *conn,
 				 struct sk_buff *skb,
 				 u32 *_abort_code)
 {
-	struct rxkad_response response;
+	struct rxkad_response response
+		__attribute__((aligned(8))); /* must be aligned for crypto */
 	struct rxrpc_skb_priv *sp;
 	struct rxrpc_crypt session_key;
 	time_t expiry;

  reply	other threads:[~2007-04-03 13:53 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-02 22:44 [PATCH 0/9] AF_RXRPC socket family and AFS rewrite David Howells
2007-04-02 22:44 ` [PATCH 1/9] AF_RXRPC: Add blkcipher accessors for using kernel data directly David Howells
2007-04-03  3:22   ` David Miller
2007-04-03  3:50     ` Herbert Xu
2007-04-03 13:52       ` David Howells [this message]
2007-04-03 21:37         ` Herbert Xu
2007-04-02 22:45 ` [PATCH 2/9] AF_RXRPC: Move generic skbuff stuff from XFRM code to generic code David Howells
2007-04-03  3:20   ` David Miller
2007-04-02 22:45 ` [PATCH 3/9] AF_RXRPC: Make it possible to merely try to cancel timers and delayed work David Howells
2007-04-02 22:45 ` [PATCH 4/9] AF_RXRPC: Key facility changes for AF_RXRPC David Howells
2007-04-02 22:45 ` [PATCH 7/9] AF_RXRPC: Add an interface to the AF_RXRPC module for the AFS filesystem to use David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=19944.1175608373@redhat.com \
    --to=dhowells@redhat.com \
    --cc=davem@davemloft.net \
    --cc=herbert@gondor.apana.org.au \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.