diff options
-rw-r--r-- | include/net/tls.h | 15 | ||||
-rw-r--r-- | include/uapi/linux/tls.h | 15 | ||||
-rw-r--r-- | net/tls/tls_main.c | 31 | ||||
-rw-r--r-- | net/tls/tls_sw.c | 67 |
4 files changed, 97 insertions, 31 deletions
diff --git a/include/net/tls.h b/include/net/tls.h index a5a938583295..3ce71d78414c 100644 --- a/include/net/tls.h +++ b/include/net/tls.h | |||
@@ -60,6 +60,17 @@ | |||
60 | #define TLS_AAD_SPACE_SIZE 13 | 60 | #define TLS_AAD_SPACE_SIZE 13 |
61 | #define TLS_DEVICE_NAME_MAX 32 | 61 | #define TLS_DEVICE_NAME_MAX 32 |
62 | 62 | ||
63 | #define MAX_IV_SIZE 16 | ||
64 | |||
65 | /* For AES-CCM, the full 16-bytes of IV is made of '4' fields of given sizes. | ||
66 | * | ||
67 | * IV[16] = b0[1] || implicit nonce[4] || explicit nonce[8] || length[3] | ||
68 | * | ||
69 | * The field 'length' is encoded in field 'b0' as '(length width - 1)'. | ||
70 | * Hence b0 contains (3 - 1) = 2. | ||
71 | */ | ||
72 | #define TLS_AES_CCM_IV_B0_BYTE 2 | ||
73 | |||
63 | /* | 74 | /* |
64 | * This structure defines the routines for Inline TLS driver. | 75 | * This structure defines the routines for Inline TLS driver. |
65 | * The following routines are optional and filled with a | 76 | * The following routines are optional and filled with a |
@@ -123,8 +134,7 @@ struct tls_rec { | |||
123 | struct scatterlist sg_content_type; | 134 | struct scatterlist sg_content_type; |
124 | 135 | ||
125 | char aad_space[TLS_AAD_SPACE_SIZE]; | 136 | char aad_space[TLS_AAD_SPACE_SIZE]; |
126 | u8 iv_data[TLS_CIPHER_AES_GCM_128_IV_SIZE + | 137 | u8 iv_data[MAX_IV_SIZE]; |
127 | TLS_CIPHER_AES_GCM_128_SALT_SIZE]; | ||
128 | struct aead_request aead_req; | 138 | struct aead_request aead_req; |
129 | u8 aead_req_ctx[]; | 139 | u8 aead_req_ctx[]; |
130 | }; | 140 | }; |
@@ -219,6 +229,7 @@ struct tls_prot_info { | |||
219 | u16 tag_size; | 229 | u16 tag_size; |
220 | u16 overhead_size; | 230 | u16 overhead_size; |
221 | u16 iv_size; | 231 | u16 iv_size; |
232 | u16 salt_size; | ||
222 | u16 rec_seq_size; | 233 | u16 rec_seq_size; |
223 | u16 aad_size; | 234 | u16 aad_size; |
224 | u16 tail_size; | 235 | u16 tail_size; |
diff --git a/include/uapi/linux/tls.h b/include/uapi/linux/tls.h index 401d6f01de6a..5b9c26753e46 100644 --- a/include/uapi/linux/tls.h +++ b/include/uapi/linux/tls.h | |||
@@ -70,6 +70,13 @@ | |||
70 | #define TLS_CIPHER_AES_GCM_256_TAG_SIZE 16 | 70 | #define TLS_CIPHER_AES_GCM_256_TAG_SIZE 16 |
71 | #define TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE 8 | 71 | #define TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE 8 |
72 | 72 | ||
73 | #define TLS_CIPHER_AES_CCM_128 53 | ||
74 | #define TLS_CIPHER_AES_CCM_128_IV_SIZE 8 | ||
75 | #define TLS_CIPHER_AES_CCM_128_KEY_SIZE 16 | ||
76 | #define TLS_CIPHER_AES_CCM_128_SALT_SIZE 4 | ||
77 | #define TLS_CIPHER_AES_CCM_128_TAG_SIZE 16 | ||
78 | #define TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE 8 | ||
79 | |||
73 | #define TLS_SET_RECORD_TYPE 1 | 80 | #define TLS_SET_RECORD_TYPE 1 |
74 | #define TLS_GET_RECORD_TYPE 2 | 81 | #define TLS_GET_RECORD_TYPE 2 |
75 | 82 | ||
@@ -94,4 +101,12 @@ struct tls12_crypto_info_aes_gcm_256 { | |||
94 | unsigned char rec_seq[TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE]; | 101 | unsigned char rec_seq[TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE]; |
95 | }; | 102 | }; |
96 | 103 | ||
104 | struct tls12_crypto_info_aes_ccm_128 { | ||
105 | struct tls_crypto_info info; | ||
106 | unsigned char iv[TLS_CIPHER_AES_CCM_128_IV_SIZE]; | ||
107 | unsigned char key[TLS_CIPHER_AES_CCM_128_KEY_SIZE]; | ||
108 | unsigned char salt[TLS_CIPHER_AES_CCM_128_SALT_SIZE]; | ||
109 | unsigned char rec_seq[TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE]; | ||
110 | }; | ||
111 | |||
97 | #endif /* _UAPI_LINUX_TLS_H */ | 112 | #endif /* _UAPI_LINUX_TLS_H */ |
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index df921a2904b9..0e24edab2535 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
@@ -469,27 +469,32 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval, | |||
469 | 469 | ||
470 | switch (crypto_info->cipher_type) { | 470 | switch (crypto_info->cipher_type) { |
471 | case TLS_CIPHER_AES_GCM_128: | 471 | case TLS_CIPHER_AES_GCM_128: |
472 | optsize = sizeof(struct tls12_crypto_info_aes_gcm_128); | ||
473 | break; | ||
472 | case TLS_CIPHER_AES_GCM_256: { | 474 | case TLS_CIPHER_AES_GCM_256: { |
473 | optsize = crypto_info->cipher_type == TLS_CIPHER_AES_GCM_128 ? | 475 | optsize = sizeof(struct tls12_crypto_info_aes_gcm_256); |
474 | sizeof(struct tls12_crypto_info_aes_gcm_128) : | ||
475 | sizeof(struct tls12_crypto_info_aes_gcm_256); | ||
476 | if (optlen != optsize) { | ||
477 | rc = -EINVAL; | ||
478 | goto err_crypto_info; | ||
479 | } | ||
480 | rc = copy_from_user(crypto_info + 1, optval + sizeof(*crypto_info), | ||
481 | optlen - sizeof(*crypto_info)); | ||
482 | if (rc) { | ||
483 | rc = -EFAULT; | ||
484 | goto err_crypto_info; | ||
485 | } | ||
486 | break; | 476 | break; |
487 | } | 477 | } |
478 | case TLS_CIPHER_AES_CCM_128: | ||
479 | optsize = sizeof(struct tls12_crypto_info_aes_ccm_128); | ||
480 | break; | ||
488 | default: | 481 | default: |
489 | rc = -EINVAL; | 482 | rc = -EINVAL; |
490 | goto err_crypto_info; | 483 | goto err_crypto_info; |
491 | } | 484 | } |
492 | 485 | ||
486 | if (optlen != optsize) { | ||
487 | rc = -EINVAL; | ||
488 | goto err_crypto_info; | ||
489 | } | ||
490 | |||
491 | rc = copy_from_user(crypto_info + 1, optval + sizeof(*crypto_info), | ||
492 | optlen - sizeof(*crypto_info)); | ||
493 | if (rc) { | ||
494 | rc = -EFAULT; | ||
495 | goto err_crypto_info; | ||
496 | } | ||
497 | |||
493 | if (tx) { | 498 | if (tx) { |
494 | #ifdef CONFIG_TLS_DEVICE | 499 | #ifdef CONFIG_TLS_DEVICE |
495 | rc = tls_set_device_offload(sk, ctx); | 500 | rc = tls_set_device_offload(sk, ctx); |
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 425351ac2a9b..f635c103581e 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c | |||
@@ -42,8 +42,6 @@ | |||
42 | #include <net/strparser.h> | 42 | #include <net/strparser.h> |
43 | #include <net/tls.h> | 43 | #include <net/tls.h> |
44 | 44 | ||
45 | #define MAX_IV_SIZE TLS_CIPHER_AES_GCM_128_IV_SIZE | ||
46 | |||
47 | static int __skb_nsg(struct sk_buff *skb, int offset, int len, | 45 | static int __skb_nsg(struct sk_buff *skb, int offset, int len, |
48 | unsigned int recursion_level) | 46 | unsigned int recursion_level) |
49 | { | 47 | { |
@@ -479,11 +477,18 @@ static int tls_do_encryption(struct sock *sk, | |||
479 | struct tls_rec *rec = ctx->open_rec; | 477 | struct tls_rec *rec = ctx->open_rec; |
480 | struct sk_msg *msg_en = &rec->msg_encrypted; | 478 | struct sk_msg *msg_en = &rec->msg_encrypted; |
481 | struct scatterlist *sge = sk_msg_elem(msg_en, start); | 479 | struct scatterlist *sge = sk_msg_elem(msg_en, start); |
482 | int rc; | 480 | int rc, iv_offset = 0; |
481 | |||
482 | /* For CCM based ciphers, first byte of IV is a constant */ | ||
483 | if (prot->cipher_type == TLS_CIPHER_AES_CCM_128) { | ||
484 | rec->iv_data[0] = TLS_AES_CCM_IV_B0_BYTE; | ||
485 | iv_offset = 1; | ||
486 | } | ||
487 | |||
488 | memcpy(&rec->iv_data[iv_offset], tls_ctx->tx.iv, | ||
489 | prot->iv_size + prot->salt_size); | ||
483 | 490 | ||
484 | memcpy(rec->iv_data, tls_ctx->tx.iv, sizeof(rec->iv_data)); | 491 | xor_iv_with_seq(prot->version, rec->iv_data, tls_ctx->tx.rec_seq); |
485 | xor_iv_with_seq(prot->version, rec->iv_data, | ||
486 | tls_ctx->tx.rec_seq); | ||
487 | 492 | ||
488 | sge->offset += prot->prepend_size; | 493 | sge->offset += prot->prepend_size; |
489 | sge->length -= prot->prepend_size; | 494 | sge->length -= prot->prepend_size; |
@@ -1344,6 +1349,7 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb, | |||
1344 | struct scatterlist *sgout = NULL; | 1349 | struct scatterlist *sgout = NULL; |
1345 | const int data_len = rxm->full_len - prot->overhead_size + | 1350 | const int data_len = rxm->full_len - prot->overhead_size + |
1346 | prot->tail_size; | 1351 | prot->tail_size; |
1352 | int iv_offset = 0; | ||
1347 | 1353 | ||
1348 | if (*zc && (out_iov || out_sg)) { | 1354 | if (*zc && (out_iov || out_sg)) { |
1349 | if (out_iov) | 1355 | if (out_iov) |
@@ -1386,18 +1392,25 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb, | |||
1386 | aad = (u8 *)(sgout + n_sgout); | 1392 | aad = (u8 *)(sgout + n_sgout); |
1387 | iv = aad + prot->aad_size; | 1393 | iv = aad + prot->aad_size; |
1388 | 1394 | ||
1395 | /* For CCM based ciphers, first byte of nonce+iv is always '2' */ | ||
1396 | if (prot->cipher_type == TLS_CIPHER_AES_CCM_128) { | ||
1397 | iv[0] = 2; | ||
1398 | iv_offset = 1; | ||
1399 | } | ||
1400 | |||
1389 | /* Prepare IV */ | 1401 | /* Prepare IV */ |
1390 | err = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE, | 1402 | err = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE, |
1391 | iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, | 1403 | iv + iv_offset + prot->salt_size, |
1392 | prot->iv_size); | 1404 | prot->iv_size); |
1393 | if (err < 0) { | 1405 | if (err < 0) { |
1394 | kfree(mem); | 1406 | kfree(mem); |
1395 | return err; | 1407 | return err; |
1396 | } | 1408 | } |
1397 | if (prot->version == TLS_1_3_VERSION) | 1409 | if (prot->version == TLS_1_3_VERSION) |
1398 | memcpy(iv, tls_ctx->rx.iv, crypto_aead_ivsize(ctx->aead_recv)); | 1410 | memcpy(iv + iv_offset, tls_ctx->rx.iv, |
1411 | crypto_aead_ivsize(ctx->aead_recv)); | ||
1399 | else | 1412 | else |
1400 | memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); | 1413 | memcpy(iv + iv_offset, tls_ctx->rx.iv, prot->salt_size); |
1401 | 1414 | ||
1402 | xor_iv_with_seq(prot->version, iv, tls_ctx->rx.rec_seq); | 1415 | xor_iv_with_seq(prot->version, iv, tls_ctx->rx.rec_seq); |
1403 | 1416 | ||
@@ -2152,14 +2165,15 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) | |||
2152 | struct tls_crypto_info *crypto_info; | 2165 | struct tls_crypto_info *crypto_info; |
2153 | struct tls12_crypto_info_aes_gcm_128 *gcm_128_info; | 2166 | struct tls12_crypto_info_aes_gcm_128 *gcm_128_info; |
2154 | struct tls12_crypto_info_aes_gcm_256 *gcm_256_info; | 2167 | struct tls12_crypto_info_aes_gcm_256 *gcm_256_info; |
2168 | struct tls12_crypto_info_aes_ccm_128 *ccm_128_info; | ||
2155 | struct tls_sw_context_tx *sw_ctx_tx = NULL; | 2169 | struct tls_sw_context_tx *sw_ctx_tx = NULL; |
2156 | struct tls_sw_context_rx *sw_ctx_rx = NULL; | 2170 | struct tls_sw_context_rx *sw_ctx_rx = NULL; |
2157 | struct cipher_context *cctx; | 2171 | struct cipher_context *cctx; |
2158 | struct crypto_aead **aead; | 2172 | struct crypto_aead **aead; |
2159 | struct strp_callbacks cb; | 2173 | struct strp_callbacks cb; |
2160 | u16 nonce_size, tag_size, iv_size, rec_seq_size; | 2174 | u16 nonce_size, tag_size, iv_size, rec_seq_size, salt_size; |
2161 | struct crypto_tfm *tfm; | 2175 | struct crypto_tfm *tfm; |
2162 | char *iv, *rec_seq, *key, *salt; | 2176 | char *iv, *rec_seq, *key, *salt, *cipher_name; |
2163 | size_t keysize; | 2177 | size_t keysize; |
2164 | int rc = 0; | 2178 | int rc = 0; |
2165 | 2179 | ||
@@ -2224,6 +2238,8 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) | |||
2224 | keysize = TLS_CIPHER_AES_GCM_128_KEY_SIZE; | 2238 | keysize = TLS_CIPHER_AES_GCM_128_KEY_SIZE; |
2225 | key = gcm_128_info->key; | 2239 | key = gcm_128_info->key; |
2226 | salt = gcm_128_info->salt; | 2240 | salt = gcm_128_info->salt; |
2241 | salt_size = TLS_CIPHER_AES_GCM_128_SALT_SIZE; | ||
2242 | cipher_name = "gcm(aes)"; | ||
2227 | break; | 2243 | break; |
2228 | } | 2244 | } |
2229 | case TLS_CIPHER_AES_GCM_256: { | 2245 | case TLS_CIPHER_AES_GCM_256: { |
@@ -2239,6 +2255,25 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) | |||
2239 | keysize = TLS_CIPHER_AES_GCM_256_KEY_SIZE; | 2255 | keysize = TLS_CIPHER_AES_GCM_256_KEY_SIZE; |
2240 | key = gcm_256_info->key; | 2256 | key = gcm_256_info->key; |
2241 | salt = gcm_256_info->salt; | 2257 | salt = gcm_256_info->salt; |
2258 | salt_size = TLS_CIPHER_AES_GCM_256_SALT_SIZE; | ||
2259 | cipher_name = "gcm(aes)"; | ||
2260 | break; | ||
2261 | } | ||
2262 | case TLS_CIPHER_AES_CCM_128: { | ||
2263 | nonce_size = TLS_CIPHER_AES_CCM_128_IV_SIZE; | ||
2264 | tag_size = TLS_CIPHER_AES_CCM_128_TAG_SIZE; | ||
2265 | iv_size = TLS_CIPHER_AES_CCM_128_IV_SIZE; | ||
2266 | iv = ((struct tls12_crypto_info_aes_ccm_128 *)crypto_info)->iv; | ||
2267 | rec_seq_size = TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE; | ||
2268 | rec_seq = | ||
2269 | ((struct tls12_crypto_info_aes_ccm_128 *)crypto_info)->rec_seq; | ||
2270 | ccm_128_info = | ||
2271 | (struct tls12_crypto_info_aes_ccm_128 *)crypto_info; | ||
2272 | keysize = TLS_CIPHER_AES_CCM_128_KEY_SIZE; | ||
2273 | key = ccm_128_info->key; | ||
2274 | salt = ccm_128_info->salt; | ||
2275 | salt_size = TLS_CIPHER_AES_CCM_128_SALT_SIZE; | ||
2276 | cipher_name = "ccm(aes)"; | ||
2242 | break; | 2277 | break; |
2243 | } | 2278 | } |
2244 | default: | 2279 | default: |
@@ -2268,16 +2303,16 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) | |||
2268 | prot->overhead_size = prot->prepend_size + | 2303 | prot->overhead_size = prot->prepend_size + |
2269 | prot->tag_size + prot->tail_size; | 2304 | prot->tag_size + prot->tail_size; |
2270 | prot->iv_size = iv_size; | 2305 | prot->iv_size = iv_size; |
2271 | cctx->iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE, | 2306 | prot->salt_size = salt_size; |
2272 | GFP_KERNEL); | 2307 | cctx->iv = kmalloc(iv_size + salt_size, GFP_KERNEL); |
2273 | if (!cctx->iv) { | 2308 | if (!cctx->iv) { |
2274 | rc = -ENOMEM; | 2309 | rc = -ENOMEM; |
2275 | goto free_priv; | 2310 | goto free_priv; |
2276 | } | 2311 | } |
2277 | /* Note: 128 & 256 bit salt are the same size */ | 2312 | /* Note: 128 & 256 bit salt are the same size */ |
2278 | memcpy(cctx->iv, salt, TLS_CIPHER_AES_GCM_128_SALT_SIZE); | ||
2279 | memcpy(cctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv, iv_size); | ||
2280 | prot->rec_seq_size = rec_seq_size; | 2313 | prot->rec_seq_size = rec_seq_size; |
2314 | memcpy(cctx->iv, salt, salt_size); | ||
2315 | memcpy(cctx->iv + salt_size, iv, iv_size); | ||
2281 | cctx->rec_seq = kmemdup(rec_seq, rec_seq_size, GFP_KERNEL); | 2316 | cctx->rec_seq = kmemdup(rec_seq, rec_seq_size, GFP_KERNEL); |
2282 | if (!cctx->rec_seq) { | 2317 | if (!cctx->rec_seq) { |
2283 | rc = -ENOMEM; | 2318 | rc = -ENOMEM; |
@@ -2285,7 +2320,7 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) | |||
2285 | } | 2320 | } |
2286 | 2321 | ||
2287 | if (!*aead) { | 2322 | if (!*aead) { |
2288 | *aead = crypto_alloc_aead("gcm(aes)", 0, 0); | 2323 | *aead = crypto_alloc_aead(cipher_name, 0, 0); |
2289 | if (IS_ERR(*aead)) { | 2324 | if (IS_ERR(*aead)) { |
2290 | rc = PTR_ERR(*aead); | 2325 | rc = PTR_ERR(*aead); |
2291 | *aead = NULL; | 2326 | *aead = NULL; |