aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSabrina Dubroca <sd@queasysnail.net>2018-09-12 11:44:42 -0400
committerDavid S. Miller <davem@davemloft.net>2018-09-13 15:03:47 -0400
commit86029d10af18381814881d6cce2dd6872163b59f (patch)
treeca14c5fa1d55c1b5833e225571ed0aee777715cb
parent7cba09c6d5bc73ebbd25a353742d9ddb7a713b95 (diff)
tls: zero the crypto information from tls_context before freeing
This contains key material in crypto_send_aes_gcm_128 and crypto_recv_aes_gcm_128. Introduce union tls_crypto_context, and replace the two identical unions directly embedded in struct tls_context with it. We can then use this union to clean up the memory in the new tls_ctx_free() function. Fixes: 3c4d7559159b ("tls: kernel TLS support") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/tls.h19
-rw-r--r--net/tls/tls_device.c6
-rw-r--r--net/tls/tls_device_fallback.c2
-rw-r--r--net/tls/tls_main.c20
-rw-r--r--net/tls/tls_sw.c8
5 files changed, 32 insertions, 23 deletions
diff --git a/include/net/tls.h b/include/net/tls.h
index d5c683e8bb22..0a769cf2f5f3 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -171,15 +171,14 @@ struct cipher_context {
171 char *rec_seq; 171 char *rec_seq;
172}; 172};
173 173
174union tls_crypto_context {
175 struct tls_crypto_info info;
176 struct tls12_crypto_info_aes_gcm_128 aes_gcm_128;
177};
178
174struct tls_context { 179struct tls_context {
175 union { 180 union tls_crypto_context crypto_send;
176 struct tls_crypto_info crypto_send; 181 union tls_crypto_context crypto_recv;
177 struct tls12_crypto_info_aes_gcm_128 crypto_send_aes_gcm_128;
178 };
179 union {
180 struct tls_crypto_info crypto_recv;
181 struct tls12_crypto_info_aes_gcm_128 crypto_recv_aes_gcm_128;
182 };
183 182
184 struct list_head list; 183 struct list_head list;
185 struct net_device *netdev; 184 struct net_device *netdev;
@@ -367,8 +366,8 @@ static inline void tls_fill_prepend(struct tls_context *ctx,
367 * size KTLS_DTLS_HEADER_SIZE + KTLS_DTLS_NONCE_EXPLICIT_SIZE 366 * size KTLS_DTLS_HEADER_SIZE + KTLS_DTLS_NONCE_EXPLICIT_SIZE
368 */ 367 */
369 buf[0] = record_type; 368 buf[0] = record_type;
370 buf[1] = TLS_VERSION_MINOR(ctx->crypto_send.version); 369 buf[1] = TLS_VERSION_MINOR(ctx->crypto_send.info.version);
371 buf[2] = TLS_VERSION_MAJOR(ctx->crypto_send.version); 370 buf[2] = TLS_VERSION_MAJOR(ctx->crypto_send.info.version);
372 /* we can use IV for nonce explicit according to spec */ 371 /* we can use IV for nonce explicit according to spec */
373 buf[3] = pkt_len >> 8; 372 buf[3] = pkt_len >> 8;
374 buf[4] = pkt_len & 0xFF; 373 buf[4] = pkt_len & 0xFF;
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
index 292742e50bfa..961b07d4d41c 100644
--- a/net/tls/tls_device.c
+++ b/net/tls/tls_device.c
@@ -686,7 +686,7 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
686 goto free_marker_record; 686 goto free_marker_record;
687 } 687 }
688 688
689 crypto_info = &ctx->crypto_send; 689 crypto_info = &ctx->crypto_send.info;
690 switch (crypto_info->cipher_type) { 690 switch (crypto_info->cipher_type) {
691 case TLS_CIPHER_AES_GCM_128: 691 case TLS_CIPHER_AES_GCM_128:
692 nonce_size = TLS_CIPHER_AES_GCM_128_IV_SIZE; 692 nonce_size = TLS_CIPHER_AES_GCM_128_IV_SIZE;
@@ -780,7 +780,7 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
780 780
781 ctx->priv_ctx_tx = offload_ctx; 781 ctx->priv_ctx_tx = offload_ctx;
782 rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_TX, 782 rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_TX,
783 &ctx->crypto_send, 783 &ctx->crypto_send.info,
784 tcp_sk(sk)->write_seq); 784 tcp_sk(sk)->write_seq);
785 if (rc) 785 if (rc)
786 goto release_netdev; 786 goto release_netdev;
@@ -862,7 +862,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx)
862 goto release_ctx; 862 goto release_ctx;
863 863
864 rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_RX, 864 rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_RX,
865 &ctx->crypto_recv, 865 &ctx->crypto_recv.info,
866 tcp_sk(sk)->copied_seq); 866 tcp_sk(sk)->copied_seq);
867 if (rc) { 867 if (rc) {
868 pr_err_ratelimited("%s: The netdev has refused to offload this socket\n", 868 pr_err_ratelimited("%s: The netdev has refused to offload this socket\n",
diff --git a/net/tls/tls_device_fallback.c b/net/tls/tls_device_fallback.c
index 6102169239d1..450a6dbc5a88 100644
--- a/net/tls/tls_device_fallback.c
+++ b/net/tls/tls_device_fallback.c
@@ -320,7 +320,7 @@ static struct sk_buff *tls_enc_skb(struct tls_context *tls_ctx,
320 goto free_req; 320 goto free_req;
321 321
322 iv = buf; 322 iv = buf;
323 memcpy(iv, tls_ctx->crypto_send_aes_gcm_128.salt, 323 memcpy(iv, tls_ctx->crypto_send.aes_gcm_128.salt,
324 TLS_CIPHER_AES_GCM_128_SALT_SIZE); 324 TLS_CIPHER_AES_GCM_128_SALT_SIZE);
325 aad = buf + TLS_CIPHER_AES_GCM_128_SALT_SIZE + 325 aad = buf + TLS_CIPHER_AES_GCM_128_SALT_SIZE +
326 TLS_CIPHER_AES_GCM_128_IV_SIZE; 326 TLS_CIPHER_AES_GCM_128_IV_SIZE;
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index 180b6640e531..737b3865be1b 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -241,6 +241,16 @@ static void tls_write_space(struct sock *sk)
241 ctx->sk_write_space(sk); 241 ctx->sk_write_space(sk);
242} 242}
243 243
244static void tls_ctx_free(struct tls_context *ctx)
245{
246 if (!ctx)
247 return;
248
249 memzero_explicit(&ctx->crypto_send, sizeof(ctx->crypto_send));
250 memzero_explicit(&ctx->crypto_recv, sizeof(ctx->crypto_recv));
251 kfree(ctx);
252}
253
244static void tls_sk_proto_close(struct sock *sk, long timeout) 254static void tls_sk_proto_close(struct sock *sk, long timeout)
245{ 255{
246 struct tls_context *ctx = tls_get_ctx(sk); 256 struct tls_context *ctx = tls_get_ctx(sk);
@@ -294,7 +304,7 @@ static void tls_sk_proto_close(struct sock *sk, long timeout)
294#else 304#else
295 { 305 {
296#endif 306#endif
297 kfree(ctx); 307 tls_ctx_free(ctx);
298 ctx = NULL; 308 ctx = NULL;
299 } 309 }
300 310
@@ -305,7 +315,7 @@ skip_tx_cleanup:
305 * for sk->sk_prot->unhash [tls_hw_unhash] 315 * for sk->sk_prot->unhash [tls_hw_unhash]
306 */ 316 */
307 if (free_ctx) 317 if (free_ctx)
308 kfree(ctx); 318 tls_ctx_free(ctx);
309} 319}
310 320
311static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval, 321static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval,
@@ -330,7 +340,7 @@ static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval,
330 } 340 }
331 341
332 /* get user crypto info */ 342 /* get user crypto info */
333 crypto_info = &ctx->crypto_send; 343 crypto_info = &ctx->crypto_send.info;
334 344
335 if (!TLS_CRYPTO_INFO_READY(crypto_info)) { 345 if (!TLS_CRYPTO_INFO_READY(crypto_info)) {
336 rc = -EBUSY; 346 rc = -EBUSY;
@@ -417,9 +427,9 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
417 } 427 }
418 428
419 if (tx) 429 if (tx)
420 crypto_info = &ctx->crypto_send; 430 crypto_info = &ctx->crypto_send.info;
421 else 431 else
422 crypto_info = &ctx->crypto_recv; 432 crypto_info = &ctx->crypto_recv.info;
423 433
424 /* Currently we don't support set crypto info more than one time */ 434 /* Currently we don't support set crypto info more than one time */
425 if (TLS_CRYPTO_INFO_READY(crypto_info)) { 435 if (TLS_CRYPTO_INFO_READY(crypto_info)) {
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index f29b7c49cbf2..9e918489f4fb 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -1055,8 +1055,8 @@ static int tls_read_size(struct strparser *strp, struct sk_buff *skb)
1055 goto read_failure; 1055 goto read_failure;
1056 } 1056 }
1057 1057
1058 if (header[1] != TLS_VERSION_MINOR(tls_ctx->crypto_recv.version) || 1058 if (header[1] != TLS_VERSION_MINOR(tls_ctx->crypto_recv.info.version) ||
1059 header[2] != TLS_VERSION_MAJOR(tls_ctx->crypto_recv.version)) { 1059 header[2] != TLS_VERSION_MAJOR(tls_ctx->crypto_recv.info.version)) {
1060 ret = -EINVAL; 1060 ret = -EINVAL;
1061 goto read_failure; 1061 goto read_failure;
1062 } 1062 }
@@ -1180,12 +1180,12 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
1180 1180
1181 if (tx) { 1181 if (tx) {
1182 crypto_init_wait(&sw_ctx_tx->async_wait); 1182 crypto_init_wait(&sw_ctx_tx->async_wait);
1183 crypto_info = &ctx->crypto_send; 1183 crypto_info = &ctx->crypto_send.info;
1184 cctx = &ctx->tx; 1184 cctx = &ctx->tx;
1185 aead = &sw_ctx_tx->aead_send; 1185 aead = &sw_ctx_tx->aead_send;
1186 } else { 1186 } else {
1187 crypto_init_wait(&sw_ctx_rx->async_wait); 1187 crypto_init_wait(&sw_ctx_rx->async_wait);
1188 crypto_info = &ctx->crypto_recv; 1188 crypto_info = &ctx->crypto_recv.info;
1189 cctx = &ctx->rx; 1189 cctx = &ctx->rx;
1190 aead = &sw_ctx_rx->aead_recv; 1190 aead = &sw_ctx_rx->aead_recv;
1191 } 1191 }