Skip to content

Commit 227b964

Browse files
uudiindavem330
authored andcommitted
net/tls: support SM4 GCM/CCM algorithm
The RFC8998 specification defines the use of the ShangMi algorithm cipher suites in TLS 1.3, and also supports the GCM/CCM mode using the SM4 algorithm. Signed-off-by: Tianjia Zhang <[email protected]> Acked-by: Jakub Kicinski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d1ab264 commit 227b964

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

include/uapi/linux/tls.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,20 @@
8484
#define TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE 16
8585
#define TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE 8
8686

87+
#define TLS_CIPHER_SM4_GCM 55
88+
#define TLS_CIPHER_SM4_GCM_IV_SIZE 8
89+
#define TLS_CIPHER_SM4_GCM_KEY_SIZE 16
90+
#define TLS_CIPHER_SM4_GCM_SALT_SIZE 4
91+
#define TLS_CIPHER_SM4_GCM_TAG_SIZE 16
92+
#define TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE 8
93+
94+
#define TLS_CIPHER_SM4_CCM 56
95+
#define TLS_CIPHER_SM4_CCM_IV_SIZE 8
96+
#define TLS_CIPHER_SM4_CCM_KEY_SIZE 16
97+
#define TLS_CIPHER_SM4_CCM_SALT_SIZE 4
98+
#define TLS_CIPHER_SM4_CCM_TAG_SIZE 16
99+
#define TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE 8
100+
87101
#define TLS_SET_RECORD_TYPE 1
88102
#define TLS_GET_RECORD_TYPE 2
89103

@@ -124,6 +138,22 @@ struct tls12_crypto_info_chacha20_poly1305 {
124138
unsigned char rec_seq[TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE];
125139
};
126140

141+
struct tls12_crypto_info_sm4_gcm {
142+
struct tls_crypto_info info;
143+
unsigned char iv[TLS_CIPHER_SM4_GCM_IV_SIZE];
144+
unsigned char key[TLS_CIPHER_SM4_GCM_KEY_SIZE];
145+
unsigned char salt[TLS_CIPHER_SM4_GCM_SALT_SIZE];
146+
unsigned char rec_seq[TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE];
147+
};
148+
149+
struct tls12_crypto_info_sm4_ccm {
150+
struct tls_crypto_info info;
151+
unsigned char iv[TLS_CIPHER_SM4_CCM_IV_SIZE];
152+
unsigned char key[TLS_CIPHER_SM4_CCM_KEY_SIZE];
153+
unsigned char salt[TLS_CIPHER_SM4_CCM_SALT_SIZE];
154+
unsigned char rec_seq[TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE];
155+
};
156+
127157
enum {
128158
TLS_INFO_UNSPEC,
129159
TLS_INFO_VERSION,

net/tls/tls_main.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,46 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
421421
rc = -EFAULT;
422422
break;
423423
}
424+
case TLS_CIPHER_SM4_GCM: {
425+
struct tls12_crypto_info_sm4_gcm *sm4_gcm_info =
426+
container_of(crypto_info,
427+
struct tls12_crypto_info_sm4_gcm, info);
428+
429+
if (len != sizeof(*sm4_gcm_info)) {
430+
rc = -EINVAL;
431+
goto out;
432+
}
433+
lock_sock(sk);
434+
memcpy(sm4_gcm_info->iv,
435+
cctx->iv + TLS_CIPHER_SM4_GCM_SALT_SIZE,
436+
TLS_CIPHER_SM4_GCM_IV_SIZE);
437+
memcpy(sm4_gcm_info->rec_seq, cctx->rec_seq,
438+
TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE);
439+
release_sock(sk);
440+
if (copy_to_user(optval, sm4_gcm_info, sizeof(*sm4_gcm_info)))
441+
rc = -EFAULT;
442+
break;
443+
}
444+
case TLS_CIPHER_SM4_CCM: {
445+
struct tls12_crypto_info_sm4_ccm *sm4_ccm_info =
446+
container_of(crypto_info,
447+
struct tls12_crypto_info_sm4_ccm, info);
448+
449+
if (len != sizeof(*sm4_ccm_info)) {
450+
rc = -EINVAL;
451+
goto out;
452+
}
453+
lock_sock(sk);
454+
memcpy(sm4_ccm_info->iv,
455+
cctx->iv + TLS_CIPHER_SM4_CCM_SALT_SIZE,
456+
TLS_CIPHER_SM4_CCM_IV_SIZE);
457+
memcpy(sm4_ccm_info->rec_seq, cctx->rec_seq,
458+
TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE);
459+
release_sock(sk);
460+
if (copy_to_user(optval, sm4_ccm_info, sizeof(*sm4_ccm_info)))
461+
rc = -EFAULT;
462+
break;
463+
}
424464
default:
425465
rc = -EINVAL;
426466
}
@@ -524,6 +564,12 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
524564
case TLS_CIPHER_CHACHA20_POLY1305:
525565
optsize = sizeof(struct tls12_crypto_info_chacha20_poly1305);
526566
break;
567+
case TLS_CIPHER_SM4_GCM:
568+
optsize = sizeof(struct tls12_crypto_info_sm4_gcm);
569+
break;
570+
case TLS_CIPHER_SM4_CCM:
571+
optsize = sizeof(struct tls12_crypto_info_sm4_ccm);
572+
break;
527573
default:
528574
rc = -EINVAL;
529575
goto err_crypto_info;

net/tls/tls_sw.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,6 +2424,40 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
24242424
cipher_name = "rfc7539(chacha20,poly1305)";
24252425
break;
24262426
}
2427+
case TLS_CIPHER_SM4_GCM: {
2428+
struct tls12_crypto_info_sm4_gcm *sm4_gcm_info;
2429+
2430+
sm4_gcm_info = (void *)crypto_info;
2431+
nonce_size = TLS_CIPHER_SM4_GCM_IV_SIZE;
2432+
tag_size = TLS_CIPHER_SM4_GCM_TAG_SIZE;
2433+
iv_size = TLS_CIPHER_SM4_GCM_IV_SIZE;
2434+
iv = sm4_gcm_info->iv;
2435+
rec_seq_size = TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE;
2436+
rec_seq = sm4_gcm_info->rec_seq;
2437+
keysize = TLS_CIPHER_SM4_GCM_KEY_SIZE;
2438+
key = sm4_gcm_info->key;
2439+
salt = sm4_gcm_info->salt;
2440+
salt_size = TLS_CIPHER_SM4_GCM_SALT_SIZE;
2441+
cipher_name = "gcm(sm4)";
2442+
break;
2443+
}
2444+
case TLS_CIPHER_SM4_CCM: {
2445+
struct tls12_crypto_info_sm4_ccm *sm4_ccm_info;
2446+
2447+
sm4_ccm_info = (void *)crypto_info;
2448+
nonce_size = TLS_CIPHER_SM4_CCM_IV_SIZE;
2449+
tag_size = TLS_CIPHER_SM4_CCM_TAG_SIZE;
2450+
iv_size = TLS_CIPHER_SM4_CCM_IV_SIZE;
2451+
iv = sm4_ccm_info->iv;
2452+
rec_seq_size = TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE;
2453+
rec_seq = sm4_ccm_info->rec_seq;
2454+
keysize = TLS_CIPHER_SM4_CCM_KEY_SIZE;
2455+
key = sm4_ccm_info->key;
2456+
salt = sm4_ccm_info->salt;
2457+
salt_size = TLS_CIPHER_SM4_CCM_SALT_SIZE;
2458+
cipher_name = "ccm(sm4)";
2459+
break;
2460+
}
24272461
default:
24282462
rc = -EINVAL;
24292463
goto free_priv;

0 commit comments

Comments
 (0)