Commit 521bb304 authored by David Howells's avatar David Howells

rxrpc: Organise connection security to use a union

Organise the security information in the rxrpc_connection struct to use a
union to allow for different data for different security classes.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent f4bdf3d6
...@@ -448,9 +448,15 @@ struct rxrpc_connection { ...@@ -448,9 +448,15 @@ struct rxrpc_connection {
struct list_head proc_link; /* link in procfs list */ struct list_head proc_link; /* link in procfs list */
struct list_head link; /* link in master connection list */ struct list_head link; /* link in master connection list */
struct sk_buff_head rx_queue; /* received conn-level packets */ struct sk_buff_head rx_queue; /* received conn-level packets */
const struct rxrpc_security *security; /* applied security module */ const struct rxrpc_security *security; /* applied security module */
union {
struct {
struct crypto_sync_skcipher *cipher; /* encryption handle */ struct crypto_sync_skcipher *cipher; /* encryption handle */
struct rxrpc_crypt csum_iv; /* packet checksum base */ struct rxrpc_crypt csum_iv; /* packet checksum base */
u32 nonce; /* response re-use preventer */
} rxkad;
};
unsigned long flags; unsigned long flags;
unsigned long events; unsigned long events;
unsigned long idle_timestamp; /* Time at which last became idle */ unsigned long idle_timestamp; /* Time at which last became idle */
...@@ -460,7 +466,6 @@ struct rxrpc_connection { ...@@ -460,7 +466,6 @@ struct rxrpc_connection {
int debug_id; /* debug ID for printks */ int debug_id; /* debug ID for printks */
atomic_t serial; /* packet serial number counter */ atomic_t serial; /* packet serial number counter */
unsigned int hi_serial; /* highest serial number received */ unsigned int hi_serial; /* highest serial number received */
u32 security_nonce; /* response re-use preventer */
u32 service_id; /* Service ID, possibly upgraded */ u32 service_id; /* Service ID, possibly upgraded */
u8 size_align; /* data size alignment (for security) */ u8 size_align; /* data size alignment (for security) */
u8 security_size; /* security header size */ u8 security_size; /* security header size */
......
...@@ -137,7 +137,7 @@ static int rxkad_init_connection_security(struct rxrpc_connection *conn, ...@@ -137,7 +137,7 @@ static int rxkad_init_connection_security(struct rxrpc_connection *conn,
if (ret < 0) if (ret < 0)
goto error_ci; goto error_ci;
conn->cipher = ci; conn->rxkad.cipher = ci;
return 0; return 0;
error_ci: error_ci:
...@@ -191,7 +191,7 @@ static int rxkad_prime_packet_security(struct rxrpc_connection *conn, ...@@ -191,7 +191,7 @@ static int rxkad_prime_packet_security(struct rxrpc_connection *conn,
crypto_skcipher_encrypt(req); crypto_skcipher_encrypt(req);
skcipher_request_free(req); skcipher_request_free(req);
memcpy(&conn->csum_iv, tmpbuf + 2, sizeof(conn->csum_iv)); memcpy(&conn->rxkad.csum_iv, tmpbuf + 2, sizeof(conn->rxkad.csum_iv));
kfree(tmpbuf); kfree(tmpbuf);
_leave(" = 0"); _leave(" = 0");
return 0; return 0;
...@@ -203,7 +203,7 @@ static int rxkad_prime_packet_security(struct rxrpc_connection *conn, ...@@ -203,7 +203,7 @@ static int rxkad_prime_packet_security(struct rxrpc_connection *conn,
*/ */
static struct skcipher_request *rxkad_get_call_crypto(struct rxrpc_call *call) static struct skcipher_request *rxkad_get_call_crypto(struct rxrpc_call *call)
{ {
struct crypto_skcipher *tfm = &call->conn->cipher->base; struct crypto_skcipher *tfm = &call->conn->rxkad.cipher->base;
struct skcipher_request *cipher_req = call->cipher_req; struct skcipher_request *cipher_req = call->cipher_req;
if (!cipher_req) { if (!cipher_req) {
...@@ -251,7 +251,7 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call, ...@@ -251,7 +251,7 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
memset(&iv, 0, sizeof(iv)); memset(&iv, 0, sizeof(iv));
sg_init_one(&sg, skb->head, 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->rxkad.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);
crypto_skcipher_encrypt(req); crypto_skcipher_encrypt(req);
...@@ -293,7 +293,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, ...@@ -293,7 +293,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
memcpy(&iv, token->kad->session_key, sizeof(iv)); memcpy(&iv, token->kad->session_key, sizeof(iv));
sg_init_one(&sg[0], skb->head, 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->rxkad.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);
crypto_skcipher_encrypt(req); crypto_skcipher_encrypt(req);
...@@ -341,7 +341,7 @@ static int rxkad_secure_packet(struct rxrpc_call *call, ...@@ -341,7 +341,7 @@ static int rxkad_secure_packet(struct rxrpc_call *call,
call->debug_id, key_serial(call->conn->params.key), call->debug_id, key_serial(call->conn->params.key),
sp->hdr.seq, data_size); sp->hdr.seq, data_size);
if (!call->conn->cipher) if (!call->conn->rxkad.cipher)
return 0; return 0;
ret = key_validate(call->conn->params.key); ret = key_validate(call->conn->params.key);
...@@ -353,7 +353,7 @@ static int rxkad_secure_packet(struct rxrpc_call *call, ...@@ -353,7 +353,7 @@ static int rxkad_secure_packet(struct rxrpc_call *call,
return -ENOMEM; return -ENOMEM;
/* continue encrypting from where we left off */ /* continue encrypting from where we left off */
memcpy(&iv, call->conn->csum_iv.x, sizeof(iv)); memcpy(&iv, call->conn->rxkad.csum_iv.x, sizeof(iv));
/* calculate the security checksum */ /* calculate the security checksum */
x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT); x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT);
...@@ -362,7 +362,7 @@ static int rxkad_secure_packet(struct rxrpc_call *call, ...@@ -362,7 +362,7 @@ static int rxkad_secure_packet(struct rxrpc_call *call,
call->crypto_buf[1] = htonl(x); call->crypto_buf[1] = htonl(x);
sg_init_one(&sg, call->crypto_buf, 8); sg_init_one(&sg, call->crypto_buf, 8);
skcipher_request_set_sync_tfm(req, call->conn->cipher); skcipher_request_set_sync_tfm(req, call->conn->rxkad.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);
crypto_skcipher_encrypt(req); crypto_skcipher_encrypt(req);
...@@ -428,7 +428,7 @@ static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -428,7 +428,7 @@ static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,
/* start the decryption afresh */ /* start the decryption afresh */
memset(&iv, 0, sizeof(iv)); memset(&iv, 0, sizeof(iv));
skcipher_request_set_sync_tfm(req, call->conn->cipher); skcipher_request_set_sync_tfm(req, call->conn->rxkad.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);
crypto_skcipher_decrypt(req); crypto_skcipher_decrypt(req);
...@@ -520,7 +520,7 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -520,7 +520,7 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb,
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));
skcipher_request_set_sync_tfm(req, call->conn->cipher); skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher);
skcipher_request_set_callback(req, 0, NULL, NULL); skcipher_request_set_callback(req, 0, NULL, NULL);
skcipher_request_set_crypt(req, sg, sg, len, iv.x); skcipher_request_set_crypt(req, sg, sg, len, iv.x);
crypto_skcipher_decrypt(req); crypto_skcipher_decrypt(req);
...@@ -586,7 +586,7 @@ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -586,7 +586,7 @@ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,
_enter("{%d{%x}},{#%u}", _enter("{%d{%x}},{#%u}",
call->debug_id, key_serial(call->conn->params.key), seq); call->debug_id, key_serial(call->conn->params.key), seq);
if (!call->conn->cipher) if (!call->conn->rxkad.cipher)
return 0; return 0;
req = rxkad_get_call_crypto(call); req = rxkad_get_call_crypto(call);
...@@ -594,7 +594,7 @@ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -594,7 +594,7 @@ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,
return -ENOMEM; return -ENOMEM;
/* continue encrypting from where we left off */ /* continue encrypting from where we left off */
memcpy(&iv, call->conn->csum_iv.x, sizeof(iv)); memcpy(&iv, call->conn->rxkad.csum_iv.x, sizeof(iv));
/* validate the security checksum */ /* validate the security checksum */
x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT); x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT);
...@@ -603,7 +603,7 @@ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -603,7 +603,7 @@ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,
call->crypto_buf[1] = htonl(x); call->crypto_buf[1] = htonl(x);
sg_init_one(&sg, call->crypto_buf, 8); sg_init_one(&sg, call->crypto_buf, 8);
skcipher_request_set_sync_tfm(req, call->conn->cipher); skcipher_request_set_sync_tfm(req, call->conn->rxkad.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);
crypto_skcipher_encrypt(req); crypto_skcipher_encrypt(req);
...@@ -698,10 +698,10 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn) ...@@ -698,10 +698,10 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn)
_enter("{%d}", conn->debug_id); _enter("{%d}", conn->debug_id);
get_random_bytes(&conn->security_nonce, sizeof(conn->security_nonce)); get_random_bytes(&conn->rxkad.nonce, sizeof(conn->rxkad.nonce));
challenge.version = htonl(2); challenge.version = htonl(2);
challenge.nonce = htonl(conn->security_nonce); challenge.nonce = htonl(conn->rxkad.nonce);
challenge.min_level = htonl(0); challenge.min_level = htonl(0);
challenge.__padding = 0; challenge.__padding = 0;
...@@ -829,7 +829,7 @@ static int rxkad_encrypt_response(struct rxrpc_connection *conn, ...@@ -829,7 +829,7 @@ static int rxkad_encrypt_response(struct rxrpc_connection *conn,
struct rxrpc_crypt iv; struct rxrpc_crypt iv;
struct scatterlist sg[1]; struct scatterlist sg[1];
req = skcipher_request_alloc(&conn->cipher->base, GFP_NOFS); req = skcipher_request_alloc(&conn->rxkad.cipher->base, GFP_NOFS);
if (!req) if (!req)
return -ENOMEM; return -ENOMEM;
...@@ -838,7 +838,7 @@ static int rxkad_encrypt_response(struct rxrpc_connection *conn, ...@@ -838,7 +838,7 @@ static int rxkad_encrypt_response(struct rxrpc_connection *conn,
sg_init_table(sg, 1); sg_init_table(sg, 1);
sg_set_buf(sg, &resp->encrypted, sizeof(resp->encrypted)); sg_set_buf(sg, &resp->encrypted, sizeof(resp->encrypted));
skcipher_request_set_sync_tfm(req, conn->cipher); skcipher_request_set_sync_tfm(req, conn->rxkad.cipher);
skcipher_request_set_callback(req, 0, NULL, NULL); skcipher_request_set_callback(req, 0, NULL, NULL);
skcipher_request_set_crypt(req, sg, sg, sizeof(resp->encrypted), iv.x); skcipher_request_set_crypt(req, sg, sg, sizeof(resp->encrypted), iv.x);
crypto_skcipher_encrypt(req); crypto_skcipher_encrypt(req);
...@@ -1249,7 +1249,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn, ...@@ -1249,7 +1249,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn,
eproto = tracepoint_string("rxkad_rsp_seq"); eproto = tracepoint_string("rxkad_rsp_seq");
abort_code = RXKADOUTOFSEQUENCE; abort_code = RXKADOUTOFSEQUENCE;
if (ntohl(response->encrypted.inc_nonce) != conn->security_nonce + 1) if (ntohl(response->encrypted.inc_nonce) != conn->rxkad.nonce + 1)
goto protocol_error_free; goto protocol_error_free;
eproto = tracepoint_string("rxkad_rsp_level"); eproto = tracepoint_string("rxkad_rsp_level");
...@@ -1302,8 +1302,8 @@ static void rxkad_clear(struct rxrpc_connection *conn) ...@@ -1302,8 +1302,8 @@ static void rxkad_clear(struct rxrpc_connection *conn)
{ {
_enter(""); _enter("");
if (conn->cipher) if (conn->rxkad.cipher)
crypto_free_sync_skcipher(conn->cipher); crypto_free_sync_skcipher(conn->rxkad.cipher);
} }
/* /*
......
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