Commit f4bdf3d6 authored by David Howells's avatar David Howells

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
...@@ -236,10 +236,7 @@ struct rxrpc_security { ...@@ -236,10 +236,7 @@ struct rxrpc_security {
/* impose security on a packet */ /* impose security on a packet */
int (*secure_packet)(struct rxrpc_call *, int (*secure_packet)(struct rxrpc_call *, struct sk_buff *, size_t);
struct sk_buff *,
size_t,
void *);
/* verify the security on a received packet */ /* verify the security on a received packet */
int (*verify_packet)(struct rxrpc_call *, struct sk_buff *, int (*verify_packet)(struct rxrpc_call *, struct sk_buff *,
......
...@@ -14,10 +14,8 @@ static int none_init_connection_security(struct rxrpc_connection *conn, ...@@ -14,10 +14,8 @@ static int none_init_connection_security(struct rxrpc_connection *conn,
return 0; return 0;
} }
static int none_secure_packet(struct rxrpc_call *call, static int none_secure_packet(struct rxrpc_call *call, struct sk_buff *skb,
struct sk_buff *skb, size_t data_size)
size_t data_size,
void *sechdr)
{ {
return 0; return 0;
} }
......
...@@ -230,9 +230,7 @@ static void rxkad_free_call_crypto(struct rxrpc_call *call) ...@@ -230,9 +230,7 @@ static void rxkad_free_call_crypto(struct rxrpc_call *call)
* partially encrypt a packet (level 1 security) * partially encrypt a packet (level 1 security)
*/ */
static int rxkad_secure_packet_auth(const struct rxrpc_call *call, static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
struct sk_buff *skb, struct sk_buff *skb, u32 data_size,
u32 data_size,
void *sechdr,
struct skcipher_request *req) struct skcipher_request *req)
{ {
struct rxrpc_skb_priv *sp = rxrpc_skb(skb); struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
...@@ -247,12 +245,12 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call, ...@@ -247,12 +245,12 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
data_size |= (u32)check << 16; data_size |= (u32)check << 16;
hdr.data_size = htonl(data_size); hdr.data_size = htonl(data_size);
memcpy(sechdr, &hdr, sizeof(hdr)); memcpy(skb->head, &hdr, sizeof(hdr));
/* start the encryption afresh */ /* start the encryption afresh */
memset(&iv, 0, sizeof(iv)); 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_sync_tfm(req, call->conn->cipher);
skcipher_request_set_callback(req, 0, NULL, NULL); skcipher_request_set_callback(req, 0, NULL, NULL);
skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x); 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, ...@@ -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, static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
struct sk_buff *skb, struct sk_buff *skb,
u32 data_size, u32 data_size,
void *sechdr,
struct skcipher_request *req) struct skcipher_request *req)
{ {
const struct rxrpc_key_token *token; const struct rxrpc_key_token *token;
...@@ -289,13 +286,13 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, ...@@ -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.data_size = htonl(data_size | (u32)check << 16);
rxkhdr.checksum = 0; rxkhdr.checksum = 0;
memcpy(sechdr, &rxkhdr, sizeof(rxkhdr)); memcpy(skb->head, &rxkhdr, sizeof(rxkhdr));
/* encrypt from the session key */ /* encrypt from the session key */
token = call->conn->params.key->payload.data[0]; token = call->conn->params.key->payload.data[0];
memcpy(&iv, token->kad->session_key, sizeof(iv)); 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_sync_tfm(req, call->conn->cipher);
skcipher_request_set_callback(req, 0, NULL, NULL); skcipher_request_set_callback(req, 0, NULL, NULL);
skcipher_request_set_crypt(req, &sg[0], &sg[0], sizeof(rxkhdr), iv.x); 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, ...@@ -310,7 +307,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
len &= ~(call->conn->size_align - 1); len &= ~(call->conn->size_align - 1);
sg_init_table(sg, ARRAY_SIZE(sg)); 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)) if (unlikely(err < 0))
goto out; goto out;
skcipher_request_set_crypt(req, sg, sg, len, iv.x); 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, ...@@ -329,8 +326,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
*/ */
static int rxkad_secure_packet(struct rxrpc_call *call, static int rxkad_secure_packet(struct rxrpc_call *call,
struct sk_buff *skb, struct sk_buff *skb,
size_t data_size, size_t data_size)
void *sechdr)
{ {
struct rxrpc_skb_priv *sp; struct rxrpc_skb_priv *sp;
struct skcipher_request *req; struct skcipher_request *req;
...@@ -383,12 +379,10 @@ static int rxkad_secure_packet(struct rxrpc_call *call, ...@@ -383,12 +379,10 @@ static int rxkad_secure_packet(struct rxrpc_call *call,
ret = 0; ret = 0;
break; break;
case RXRPC_SECURITY_AUTH: case RXRPC_SECURITY_AUTH:
ret = rxkad_secure_packet_auth(call, skb, data_size, sechdr, ret = rxkad_secure_packet_auth(call, skb, data_size, req);
req);
break; break;
case RXRPC_SECURITY_ENCRYPT: case RXRPC_SECURITY_ENCRYPT:
ret = rxkad_secure_packet_encrypt(call, skb, data_size, ret = rxkad_secure_packet_encrypt(call, skb, data_size, req);
sechdr, req);
break; break;
default: default:
ret = -EPERM; ret = -EPERM;
......
...@@ -372,8 +372,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, ...@@ -372,8 +372,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
ASSERTCMP(skb->mark, ==, 0); ASSERTCMP(skb->mark, ==, 0);
_debug("HS: %u", call->conn->security_size); _debug("HS: %u", call->conn->security_size);
skb_reserve(skb, call->conn->security_size); __skb_put(skb, call->conn->security_size);
skb->len += call->conn->security_size;
sp->remain = chunk; sp->remain = chunk;
if (sp->remain > skb_tailroom(skb)) if (sp->remain > skb_tailroom(skb))
...@@ -446,8 +445,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, ...@@ -446,8 +445,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
call->tx_winsize) call->tx_winsize)
sp->hdr.flags |= RXRPC_MORE_PACKETS; sp->hdr.flags |= RXRPC_MORE_PACKETS;
ret = call->security->secure_packet( ret = call->security->secure_packet(call, skb, skb->mark);
call, skb, skb->mark, skb->head);
if (ret < 0) if (ret < 0)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment