Skip to content

Commit

Permalink
net/tls: support SM4 CCM algorithm
Browse files Browse the repository at this point in the history
The IV of CCM mode has special requirements, this patch supports CCM
mode of SM4 algorithm.

Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Tianjia Zhang authored and David S. Miller committed Sep 28, 2021
1 parent 1817750 commit 128cfb8
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
3 changes: 2 additions & 1 deletion include/net/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,15 @@
#define MAX_IV_SIZE 16
#define TLS_MAX_REC_SEQ_SIZE 8

/* For AES-CCM, the full 16-bytes of IV is made of '4' fields of given sizes.
/* For CCM mode, the full 16-bytes of IV is made of '4' fields of given sizes.
*
* IV[16] = b0[1] || implicit nonce[4] || explicit nonce[8] || length[3]
*
* The field 'length' is encoded in field 'b0' as '(length width - 1)'.
* Hence b0 contains (3 - 1) = 2.
*/
#define TLS_AES_CCM_IV_B0_BYTE 2
#define TLS_SM4_CCM_IV_B0_BYTE 2

#define __TLS_INC_STATS(net, field) \
__SNMP_INC_STATS((net)->mib.tls_statistics, field)
Expand Down
20 changes: 16 additions & 4 deletions net/tls/tls_sw.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,9 +498,15 @@ static int tls_do_encryption(struct sock *sk,
int rc, iv_offset = 0;

/* For CCM based ciphers, first byte of IV is a constant */
if (prot->cipher_type == TLS_CIPHER_AES_CCM_128) {
switch (prot->cipher_type) {
case TLS_CIPHER_AES_CCM_128:
rec->iv_data[0] = TLS_AES_CCM_IV_B0_BYTE;
iv_offset = 1;
break;
case TLS_CIPHER_SM4_CCM:
rec->iv_data[0] = TLS_SM4_CCM_IV_B0_BYTE;
iv_offset = 1;
break;
}

memcpy(&rec->iv_data[iv_offset], tls_ctx->tx.iv,
Expand Down Expand Up @@ -1457,10 +1463,16 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
aad = (u8 *)(sgout + n_sgout);
iv = aad + prot->aad_size;

/* For CCM based ciphers, first byte of nonce+iv is always '2' */
if (prot->cipher_type == TLS_CIPHER_AES_CCM_128) {
iv[0] = 2;
/* For CCM based ciphers, first byte of nonce+iv is a constant */
switch (prot->cipher_type) {
case TLS_CIPHER_AES_CCM_128:
iv[0] = TLS_AES_CCM_IV_B0_BYTE;
iv_offset = 1;
break;
case TLS_CIPHER_SM4_CCM:
iv[0] = TLS_SM4_CCM_IV_B0_BYTE;
iv_offset = 1;
break;
}

/* Prepare IV */
Expand Down

0 comments on commit 128cfb8

Please sign in to comment.