Skip to content

Commit fb99bce

Browse files
Dave Watsondavem330
authored andcommitted
net: tls: Support 256 bit keys
Wire up support for 256 bit keys from the setsockopt to the crypto framework Signed-off-by: Dave Watson <davejwatson@fb.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent d3a5fd3 commit fb99bce

File tree

5 files changed

+137
-7
lines changed

5 files changed

+137
-7
lines changed

include/net/tls.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,10 @@ struct cipher_context {
206206

207207
union tls_crypto_context {
208208
struct tls_crypto_info info;
209-
struct tls12_crypto_info_aes_gcm_128 aes_gcm_128;
209+
union {
210+
struct tls12_crypto_info_aes_gcm_128 aes_gcm_128;
211+
struct tls12_crypto_info_aes_gcm_256 aes_gcm_256;
212+
};
210213
};
211214

212215
struct tls_context {

include/uapi/linux/tls.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@
5959
#define TLS_CIPHER_AES_GCM_128_TAG_SIZE 16
6060
#define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8
6161

62+
#define TLS_CIPHER_AES_GCM_256 52
63+
#define TLS_CIPHER_AES_GCM_256_IV_SIZE 8
64+
#define TLS_CIPHER_AES_GCM_256_KEY_SIZE 32
65+
#define TLS_CIPHER_AES_GCM_256_SALT_SIZE 4
66+
#define TLS_CIPHER_AES_GCM_256_TAG_SIZE 16
67+
#define TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE 8
68+
6269
#define TLS_SET_RECORD_TYPE 1
6370
#define TLS_GET_RECORD_TYPE 2
6471

@@ -75,4 +82,12 @@ struct tls12_crypto_info_aes_gcm_128 {
7582
unsigned char rec_seq[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
7683
};
7784

85+
struct tls12_crypto_info_aes_gcm_256 {
86+
struct tls_crypto_info info;
87+
unsigned char iv[TLS_CIPHER_AES_GCM_256_IV_SIZE];
88+
unsigned char key[TLS_CIPHER_AES_GCM_256_KEY_SIZE];
89+
unsigned char salt[TLS_CIPHER_AES_GCM_256_SALT_SIZE];
90+
unsigned char rec_seq[TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE];
91+
};
92+
7893
#endif /* _UAPI_LINUX_TLS_H */

net/tls/tls_main.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,30 @@ static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval,
372372
rc = -EFAULT;
373373
break;
374374
}
375+
case TLS_CIPHER_AES_GCM_256: {
376+
struct tls12_crypto_info_aes_gcm_256 *
377+
crypto_info_aes_gcm_256 =
378+
container_of(crypto_info,
379+
struct tls12_crypto_info_aes_gcm_256,
380+
info);
381+
382+
if (len != sizeof(*crypto_info_aes_gcm_256)) {
383+
rc = -EINVAL;
384+
goto out;
385+
}
386+
lock_sock(sk);
387+
memcpy(crypto_info_aes_gcm_256->iv,
388+
ctx->tx.iv + TLS_CIPHER_AES_GCM_256_SALT_SIZE,
389+
TLS_CIPHER_AES_GCM_256_IV_SIZE);
390+
memcpy(crypto_info_aes_gcm_256->rec_seq, ctx->tx.rec_seq,
391+
TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
392+
release_sock(sk);
393+
if (copy_to_user(optval,
394+
crypto_info_aes_gcm_256,
395+
sizeof(*crypto_info_aes_gcm_256)))
396+
rc = -EFAULT;
397+
break;
398+
}
375399
default:
376400
rc = -EINVAL;
377401
}
@@ -412,6 +436,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
412436
{
413437
struct tls_crypto_info *crypto_info;
414438
struct tls_context *ctx = tls_get_ctx(sk);
439+
size_t optsize;
415440
int rc = 0;
416441
int conf;
417442

@@ -444,8 +469,12 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
444469
}
445470

446471
switch (crypto_info->cipher_type) {
447-
case TLS_CIPHER_AES_GCM_128: {
448-
if (optlen != sizeof(struct tls12_crypto_info_aes_gcm_128)) {
472+
case TLS_CIPHER_AES_GCM_128:
473+
case TLS_CIPHER_AES_GCM_256: {
474+
optsize = crypto_info->cipher_type == TLS_CIPHER_AES_GCM_128 ?
475+
sizeof(struct tls12_crypto_info_aes_gcm_128) :
476+
sizeof(struct tls12_crypto_info_aes_gcm_256);
477+
if (optlen != optsize) {
449478
rc = -EINVAL;
450479
goto err_crypto_info;
451480
}

net/tls/tls_sw.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,14 +1999,16 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
19991999
{
20002000
struct tls_crypto_info *crypto_info;
20012001
struct tls12_crypto_info_aes_gcm_128 *gcm_128_info;
2002+
struct tls12_crypto_info_aes_gcm_256 *gcm_256_info;
20022003
struct tls_sw_context_tx *sw_ctx_tx = NULL;
20032004
struct tls_sw_context_rx *sw_ctx_rx = NULL;
20042005
struct cipher_context *cctx;
20052006
struct crypto_aead **aead;
20062007
struct strp_callbacks cb;
20072008
u16 nonce_size, tag_size, iv_size, rec_seq_size;
20082009
struct crypto_tfm *tfm;
2009-
char *iv, *rec_seq;
2010+
char *iv, *rec_seq, *key, *salt;
2011+
size_t keysize;
20102012
int rc = 0;
20112013

20122014
if (!ctx) {
@@ -2067,6 +2069,24 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
20672069
((struct tls12_crypto_info_aes_gcm_128 *)crypto_info)->rec_seq;
20682070
gcm_128_info =
20692071
(struct tls12_crypto_info_aes_gcm_128 *)crypto_info;
2072+
keysize = TLS_CIPHER_AES_GCM_128_KEY_SIZE;
2073+
key = gcm_128_info->key;
2074+
salt = gcm_128_info->salt;
2075+
break;
2076+
}
2077+
case TLS_CIPHER_AES_GCM_256: {
2078+
nonce_size = TLS_CIPHER_AES_GCM_256_IV_SIZE;
2079+
tag_size = TLS_CIPHER_AES_GCM_256_TAG_SIZE;
2080+
iv_size = TLS_CIPHER_AES_GCM_256_IV_SIZE;
2081+
iv = ((struct tls12_crypto_info_aes_gcm_256 *)crypto_info)->iv;
2082+
rec_seq_size = TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE;
2083+
rec_seq =
2084+
((struct tls12_crypto_info_aes_gcm_256 *)crypto_info)->rec_seq;
2085+
gcm_256_info =
2086+
(struct tls12_crypto_info_aes_gcm_256 *)crypto_info;
2087+
keysize = TLS_CIPHER_AES_GCM_256_KEY_SIZE;
2088+
key = gcm_256_info->key;
2089+
salt = gcm_256_info->salt;
20702090
break;
20712091
}
20722092
default:
@@ -2090,7 +2110,8 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
20902110
rc = -ENOMEM;
20912111
goto free_priv;
20922112
}
2093-
memcpy(cctx->iv, gcm_128_info->salt, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
2113+
/* Note: 128 & 256 bit salt are the same size */
2114+
memcpy(cctx->iv, salt, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
20942115
memcpy(cctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv, iv_size);
20952116
cctx->rec_seq_size = rec_seq_size;
20962117
cctx->rec_seq = kmemdup(rec_seq, rec_seq_size, GFP_KERNEL);
@@ -2110,8 +2131,8 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
21102131

21112132
ctx->push_pending_record = tls_sw_push_pending_record;
21122133

2113-
rc = crypto_aead_setkey(*aead, gcm_128_info->key,
2114-
TLS_CIPHER_AES_GCM_128_KEY_SIZE);
2134+
rc = crypto_aead_setkey(*aead, key, keysize);
2135+
21152136
if (rc)
21162137
goto free_aead;
21172138

tools/testing/selftests/net/tls.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,4 +763,66 @@ TEST_F(tls, control_msg)
763763
EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
764764
}
765765

766+
TEST(keysizes) {
767+
struct tls12_crypto_info_aes_gcm_256 tls12;
768+
struct sockaddr_in addr;
769+
int sfd, ret, fd, cfd;
770+
socklen_t len;
771+
bool notls;
772+
773+
notls = false;
774+
len = sizeof(addr);
775+
776+
memset(&tls12, 0, sizeof(tls12));
777+
tls12.info.version = TLS_1_2_VERSION;
778+
tls12.info.cipher_type = TLS_CIPHER_AES_GCM_256;
779+
780+
addr.sin_family = AF_INET;
781+
addr.sin_addr.s_addr = htonl(INADDR_ANY);
782+
addr.sin_port = 0;
783+
784+
fd = socket(AF_INET, SOCK_STREAM, 0);
785+
sfd = socket(AF_INET, SOCK_STREAM, 0);
786+
787+
ret = bind(sfd, &addr, sizeof(addr));
788+
ASSERT_EQ(ret, 0);
789+
ret = listen(sfd, 10);
790+
ASSERT_EQ(ret, 0);
791+
792+
ret = getsockname(sfd, &addr, &len);
793+
ASSERT_EQ(ret, 0);
794+
795+
ret = connect(fd, &addr, sizeof(addr));
796+
ASSERT_EQ(ret, 0);
797+
798+
ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
799+
if (ret != 0) {
800+
notls = true;
801+
printf("Failure setting TCP_ULP, testing without tls\n");
802+
}
803+
804+
if (!notls) {
805+
ret = setsockopt(fd, SOL_TLS, TLS_TX, &tls12,
806+
sizeof(tls12));
807+
EXPECT_EQ(ret, 0);
808+
}
809+
810+
cfd = accept(sfd, &addr, &len);
811+
ASSERT_GE(cfd, 0);
812+
813+
if (!notls) {
814+
ret = setsockopt(cfd, IPPROTO_TCP, TCP_ULP, "tls",
815+
sizeof("tls"));
816+
EXPECT_EQ(ret, 0);
817+
818+
ret = setsockopt(cfd, SOL_TLS, TLS_RX, &tls12,
819+
sizeof(tls12));
820+
EXPECT_EQ(ret, 0);
821+
}
822+
823+
close(sfd);
824+
close(fd);
825+
close(cfd);
826+
}
827+
766828
TEST_HARNESS_MAIN

0 commit comments

Comments
 (0)