Skip to content

Commit

Permalink
net/tls: support SM4 GCM/CCM algorithm
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
uudiin authored and davem330 committed Sep 16, 2021
1 parent d1ab264 commit 227b964
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
30 changes: 30 additions & 0 deletions include/uapi/linux/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@
#define TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE 16
#define TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE 8

#define TLS_CIPHER_SM4_GCM 55
#define TLS_CIPHER_SM4_GCM_IV_SIZE 8
#define TLS_CIPHER_SM4_GCM_KEY_SIZE 16
#define TLS_CIPHER_SM4_GCM_SALT_SIZE 4
#define TLS_CIPHER_SM4_GCM_TAG_SIZE 16
#define TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE 8

#define TLS_CIPHER_SM4_CCM 56
#define TLS_CIPHER_SM4_CCM_IV_SIZE 8
#define TLS_CIPHER_SM4_CCM_KEY_SIZE 16
#define TLS_CIPHER_SM4_CCM_SALT_SIZE 4
#define TLS_CIPHER_SM4_CCM_TAG_SIZE 16
#define TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE 8

#define TLS_SET_RECORD_TYPE 1
#define TLS_GET_RECORD_TYPE 2

Expand Down Expand Up @@ -124,6 +138,22 @@ struct tls12_crypto_info_chacha20_poly1305 {
unsigned char rec_seq[TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE];
};

struct tls12_crypto_info_sm4_gcm {
struct tls_crypto_info info;
unsigned char iv[TLS_CIPHER_SM4_GCM_IV_SIZE];
unsigned char key[TLS_CIPHER_SM4_GCM_KEY_SIZE];
unsigned char salt[TLS_CIPHER_SM4_GCM_SALT_SIZE];
unsigned char rec_seq[TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE];
};

struct tls12_crypto_info_sm4_ccm {
struct tls_crypto_info info;
unsigned char iv[TLS_CIPHER_SM4_CCM_IV_SIZE];
unsigned char key[TLS_CIPHER_SM4_CCM_KEY_SIZE];
unsigned char salt[TLS_CIPHER_SM4_CCM_SALT_SIZE];
unsigned char rec_seq[TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE];
};

enum {
TLS_INFO_UNSPEC,
TLS_INFO_VERSION,
Expand Down
46 changes: 46 additions & 0 deletions net/tls/tls_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,46 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
rc = -EFAULT;
break;
}
case TLS_CIPHER_SM4_GCM: {
struct tls12_crypto_info_sm4_gcm *sm4_gcm_info =
container_of(crypto_info,
struct tls12_crypto_info_sm4_gcm, info);

if (len != sizeof(*sm4_gcm_info)) {
rc = -EINVAL;
goto out;
}
lock_sock(sk);
memcpy(sm4_gcm_info->iv,
cctx->iv + TLS_CIPHER_SM4_GCM_SALT_SIZE,
TLS_CIPHER_SM4_GCM_IV_SIZE);
memcpy(sm4_gcm_info->rec_seq, cctx->rec_seq,
TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE);
release_sock(sk);
if (copy_to_user(optval, sm4_gcm_info, sizeof(*sm4_gcm_info)))
rc = -EFAULT;
break;
}
case TLS_CIPHER_SM4_CCM: {
struct tls12_crypto_info_sm4_ccm *sm4_ccm_info =
container_of(crypto_info,
struct tls12_crypto_info_sm4_ccm, info);

if (len != sizeof(*sm4_ccm_info)) {
rc = -EINVAL;
goto out;
}
lock_sock(sk);
memcpy(sm4_ccm_info->iv,
cctx->iv + TLS_CIPHER_SM4_CCM_SALT_SIZE,
TLS_CIPHER_SM4_CCM_IV_SIZE);
memcpy(sm4_ccm_info->rec_seq, cctx->rec_seq,
TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE);
release_sock(sk);
if (copy_to_user(optval, sm4_ccm_info, sizeof(*sm4_ccm_info)))
rc = -EFAULT;
break;
}
default:
rc = -EINVAL;
}
Expand Down Expand Up @@ -524,6 +564,12 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
case TLS_CIPHER_CHACHA20_POLY1305:
optsize = sizeof(struct tls12_crypto_info_chacha20_poly1305);
break;
case TLS_CIPHER_SM4_GCM:
optsize = sizeof(struct tls12_crypto_info_sm4_gcm);
break;
case TLS_CIPHER_SM4_CCM:
optsize = sizeof(struct tls12_crypto_info_sm4_ccm);
break;
default:
rc = -EINVAL;
goto err_crypto_info;
Expand Down
34 changes: 34 additions & 0 deletions net/tls/tls_sw.c
Original file line number Diff line number Diff line change
Expand Up @@ -2424,6 +2424,40 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
cipher_name = "rfc7539(chacha20,poly1305)";
break;
}
case TLS_CIPHER_SM4_GCM: {
struct tls12_crypto_info_sm4_gcm *sm4_gcm_info;

sm4_gcm_info = (void *)crypto_info;
nonce_size = TLS_CIPHER_SM4_GCM_IV_SIZE;
tag_size = TLS_CIPHER_SM4_GCM_TAG_SIZE;
iv_size = TLS_CIPHER_SM4_GCM_IV_SIZE;
iv = sm4_gcm_info->iv;
rec_seq_size = TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE;
rec_seq = sm4_gcm_info->rec_seq;
keysize = TLS_CIPHER_SM4_GCM_KEY_SIZE;
key = sm4_gcm_info->key;
salt = sm4_gcm_info->salt;
salt_size = TLS_CIPHER_SM4_GCM_SALT_SIZE;
cipher_name = "gcm(sm4)";
break;
}
case TLS_CIPHER_SM4_CCM: {
struct tls12_crypto_info_sm4_ccm *sm4_ccm_info;

sm4_ccm_info = (void *)crypto_info;
nonce_size = TLS_CIPHER_SM4_CCM_IV_SIZE;
tag_size = TLS_CIPHER_SM4_CCM_TAG_SIZE;
iv_size = TLS_CIPHER_SM4_CCM_IV_SIZE;
iv = sm4_ccm_info->iv;
rec_seq_size = TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE;
rec_seq = sm4_ccm_info->rec_seq;
keysize = TLS_CIPHER_SM4_CCM_KEY_SIZE;
key = sm4_ccm_info->key;
salt = sm4_ccm_info->salt;
salt_size = TLS_CIPHER_SM4_CCM_SALT_SIZE;
cipher_name = "ccm(sm4)";
break;
}
default:
rc = -EINVAL;
goto free_priv;
Expand Down

0 comments on commit 227b964

Please sign in to comment.