Commit f4bdf3d6 authored by David Howells's avatar David Howells
Browse files

rxrpc: Don't reserve security header in Tx DATA skbuff



Insert the security header into the skbuff representing a DATA packet to be
transmitted rather than using skb_reserve() when the packet is allocated.
This makes it easier to apply crypto that spans the security header and the
data, particularly in the upcoming RxGK class where we have a common
encrypt-and-checksum function that is used in a number of circumstances.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 8d47a43c
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -236,10 +236,7 @@ struct rxrpc_security {


	/* impose security on a packet */
	int (*secure_packet)(struct rxrpc_call *,
			     struct sk_buff *,
			     size_t,
			     void *);
	int (*secure_packet)(struct rxrpc_call *, struct sk_buff *, size_t);

	/* verify the security on a received packet */
	int (*verify_packet)(struct rxrpc_call *, struct sk_buff *,
+2 −4
Original line number Diff line number Diff line
@@ -14,10 +14,8 @@ static int none_init_connection_security(struct rxrpc_connection *conn,
	return 0;
}

static int none_secure_packet(struct rxrpc_call *call,
			      struct sk_buff *skb,
			      size_t data_size,
			      void *sechdr)
static int none_secure_packet(struct rxrpc_call *call, struct sk_buff *skb,
			      size_t data_size)
{
	return 0;
}
+9 −15
Original line number Diff line number Diff line
@@ -230,9 +230,7 @@ static void rxkad_free_call_crypto(struct rxrpc_call *call)
 * partially encrypt a packet (level 1 security)
 */
static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
				    struct sk_buff *skb,
				    u32 data_size,
				    void *sechdr,
				    struct sk_buff *skb, u32 data_size,
				    struct skcipher_request *req)
{
	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
@@ -247,12 +245,12 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
	data_size |= (u32)check << 16;

	hdr.data_size = htonl(data_size);
	memcpy(sechdr, &hdr, sizeof(hdr));
	memcpy(skb->head, &hdr, sizeof(hdr));

	/* start the encryption afresh */
	memset(&iv, 0, sizeof(iv));

	sg_init_one(&sg, sechdr, 8);
	sg_init_one(&sg, skb->head, 8);
	skcipher_request_set_sync_tfm(req, call->conn->cipher);
	skcipher_request_set_callback(req, 0, NULL, NULL);
	skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
@@ -269,7 +267,6 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
				       struct sk_buff *skb,
				       u32 data_size,
				       void *sechdr,
				       struct skcipher_request *req)
{
	const struct rxrpc_key_token *token;
@@ -289,13 +286,13 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,

	rxkhdr.data_size = htonl(data_size | (u32)check << 16);
	rxkhdr.checksum = 0;
	memcpy(sechdr, &rxkhdr, sizeof(rxkhdr));
	memcpy(skb->head, &rxkhdr, sizeof(rxkhdr));

	/* encrypt from the session key */
	token = call->conn->params.key->payload.data[0];
	memcpy(&iv, token->kad->session_key, sizeof(iv));

	sg_init_one(&sg[0], sechdr, sizeof(rxkhdr));
	sg_init_one(&sg[0], skb->head, sizeof(rxkhdr));
	skcipher_request_set_sync_tfm(req, call->conn->cipher);
	skcipher_request_set_callback(req, 0, NULL, NULL);
	skcipher_request_set_crypt(req, &sg[0], &sg[0], sizeof(rxkhdr), iv.x);
@@ -310,7 +307,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
	len &= ~(call->conn->size_align - 1);

	sg_init_table(sg, ARRAY_SIZE(sg));
	err = skb_to_sgvec(skb, sg, 0, len);
	err = skb_to_sgvec(skb, sg, 8, len);
	if (unlikely(err < 0))
		goto out;
	skcipher_request_set_crypt(req, sg, sg, len, iv.x);
@@ -329,8 +326,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
 */
static int rxkad_secure_packet(struct rxrpc_call *call,
			       struct sk_buff *skb,
			       size_t data_size,
			       void *sechdr)
			       size_t data_size)
{
	struct rxrpc_skb_priv *sp;
	struct skcipher_request	*req;
@@ -383,12 +379,10 @@ static int rxkad_secure_packet(struct rxrpc_call *call,
		ret = 0;
		break;
	case RXRPC_SECURITY_AUTH:
		ret = rxkad_secure_packet_auth(call, skb, data_size, sechdr,
					       req);
		ret = rxkad_secure_packet_auth(call, skb, data_size, req);
		break;
	case RXRPC_SECURITY_ENCRYPT:
		ret = rxkad_secure_packet_encrypt(call, skb, data_size,
						  sechdr, req);
		ret = rxkad_secure_packet_encrypt(call, skb, data_size, req);
		break;
	default:
		ret = -EPERM;
+2 −4
Original line number Diff line number Diff line
@@ -372,8 +372,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
			ASSERTCMP(skb->mark, ==, 0);

			_debug("HS: %u", call->conn->security_size);
			skb_reserve(skb, call->conn->security_size);
			skb->len += call->conn->security_size;
			__skb_put(skb, call->conn->security_size);

			sp->remain = chunk;
			if (sp->remain > skb_tailroom(skb))
@@ -446,8 +445,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
				 call->tx_winsize)
				sp->hdr.flags |= RXRPC_MORE_PACKETS;

			ret = call->security->secure_packet(
				call, skb, skb->mark, skb->head);
			ret = call->security->secure_packet(call, skb, skb->mark);
			if (ret < 0)
				goto out;