Skip to content

Commit 6fc100b

Browse files
committed
Reject SM cipher suites over DTLS and exercise them in record-size test
RFC 8998 registers TLS_SM4_GCM_SM3 / TLS_SM4_CCM_SM3 (and the TLS 1.2 SM4 suites) with DTLS-OK: No and defines no record-number-mask construction for SM4. RFC 9147 Section 4.2.3 requires any non-AES / non-ChaCha20 cipher to define its own record sequence number encryption to be usable with DTLS. Drop SM cipher suites from the negotiable list in InitSuites when DTLS, and reject them defensively in VerifyServerSuite for the case where the user pins a cipher list explicitly. Update test_record_size_matches_build_message to set up an SM2 cert chain and SM2 key share for SM ciphers (so they actually handshake over TLS 1.2 / TLS 1.3) and to skip the DTLS variants with the RFC reason.
1 parent b243069 commit 6fc100b

2 files changed

Lines changed: 61 additions & 8 deletions

File tree

src/internal.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3706,14 +3706,17 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
37063706
#endif
37073707

37083708
#ifdef BUILD_TLS_SM4_GCM_SM3
3709-
if (tls1_3) {
3709+
/* RFC 8998 registers TLS_SM4_GCM_SM3 with DTLS-OK: No and provides no
3710+
* record-number-mask construction; RFC 9147 Section 4.2.3 forbids using
3711+
* non-AES / non-ChaCha20 ciphers over DTLS without one. */
3712+
if (tls1_3 && !dtls) {
37103713
suites->suites[idx++] = CIPHER_BYTE;
37113714
suites->suites[idx++] = TLS_SM4_GCM_SM3;
37123715
}
37133716
#endif
37143717

37153718
#ifdef BUILD_TLS_SM4_CCM_SM3
3716-
if (tls1_3) {
3719+
if (tls1_3 && !dtls) {
37173720
suites->suites[idx++] = CIPHER_BYTE;
37183721
suites->suites[idx++] = TLS_SM4_CCM_SM3;
37193722
}
@@ -4647,21 +4650,22 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
46474650
#endif /* BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
46484651

46494652
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3
4650-
if (tls && haveECC) {
4653+
/* RFC 8998 registers the SM4 cipher suites with DTLS-OK: No. */
4654+
if (tls && !dtls && haveECC) {
46514655
suites->suites[idx++] = SM_BYTE;
46524656
suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3;
46534657
}
46544658
#endif
46554659

46564660
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3
4657-
if (tls && haveECC) {
4661+
if (tls && !dtls && haveECC) {
46584662
suites->suites[idx++] = SM_BYTE;
46594663
suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3;
46604664
}
46614665
#endif
46624666

46634667
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3
4664-
if (tls && haveECC) {
4668+
if (tls && !dtls && haveECC) {
46654669
suites->suites[idx++] = SM_BYTE;
46664670
suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3;
46674671
}
@@ -37283,6 +37287,22 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3728337287
first = suites->suites[idx];
3728437288
second = suites->suites[idx+1];
3728537289

37290+
#ifdef WOLFSSL_DTLS
37291+
/* RFC 8998 registers the SM4 cipher suites with DTLS-OK: No.
37292+
* RFC 9147 Section 4.2.3 forbids using non-AES / non-ChaCha20 ciphers
37293+
* over DTLS without a defined record-number-mask construction, which
37294+
* RFC 8998 does not provide. */
37295+
if (ssl->options.dtls) {
37296+
if ((first == CIPHER_BYTE && (second == TLS_SM4_GCM_SM3 ||
37297+
second == TLS_SM4_CCM_SM3)) ||
37298+
first == SM_BYTE) {
37299+
WOLFSSL_MSG("SM cipher suite not allowed over DTLS "
37300+
"(RFC 8998)");
37301+
return 0;
37302+
}
37303+
}
37304+
#endif /* WOLFSSL_DTLS */
37305+
3728637306
#ifdef WOLFSSL_TLS13
3728737307
/* When negotiating TLS 1.3, reject non-TLS 1.3 cipher suites */
3728837308
if (IsAtLeastTLSv1_3(ssl->version) &&

tests/api/test_tls.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
#include <tests/utils.h>
3232
#include <tests/api/test_tls.h>
3333
#include <wolfssl/internal.h>
34+
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && defined(WOLFSSL_SM4)
35+
#include <wolfssl/certs_test_sm.h>
36+
#endif
3437

3538

3639
int test_utils_memio_move_message(void)
@@ -1184,12 +1187,34 @@ int test_record_size_matches_build_message(void)
11841187
struct test_memio_ctx test_ctx;
11851188
const char* name = allCiphers[i].name;
11861189
int isTls13Cipher = (XSTRSTR(name, "TLS13-") != NULL);
1190+
int isSmCipher = (XSTRSTR(name, "SM4") != NULL);
11871191
int handshakeRet;
11881192

11891193
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
11901194

1191-
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
1192-
&ssl_s, versions[v].client, versions[v].server), 0);
1195+
if (isSmCipher) {
1196+
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && defined(WOLFSSL_SM4)
1197+
ExpectIntEQ(test_memio_setup_ex(&test_ctx, &ctx_c, &ctx_s,
1198+
&ssl_c, &ssl_s, versions[v].client, versions[v].server,
1199+
(byte*)ca_sm2_der, (int)sizeof_ca_sm2_der,
1200+
(byte*)server_sm2_der, (int)sizeof_server_sm2_der,
1201+
(byte*)server_sm2_priv_der,
1202+
(int)sizeof_server_sm2_priv_der), 0);
1203+
if (versions[v].is_tls13) {
1204+
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c,
1205+
WOLFSSL_ECC_SM2P256V1), 1);
1206+
}
1207+
#else
1208+
fprintf(stderr,
1209+
" [SKIP %-12s %-40s] SM build not enabled\n",
1210+
versions[v].label, name);
1211+
goto next_iter;
1212+
#endif
1213+
}
1214+
else {
1215+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
1216+
&ssl_s, versions[v].client, versions[v].server), 0);
1217+
}
11931218

11941219
/* Skip ciphers that aren't valid for this version/build. */
11951220
if (wolfSSL_set_cipher_list(ssl_c, name) != 1 ||
@@ -1200,6 +1225,14 @@ int test_record_size_matches_build_message(void)
12001225
goto next_iter;
12011226
}
12021227

1228+
if (isSmCipher &&
1229+
XSTRNCMP(versions[v].label, "DTLS", 4) == 0) {
1230+
fprintf(stderr,
1231+
" [SKIP %-12s %-40s] RFC 8998 forbids SM suites over DTLS\n",
1232+
versions[v].label, name);
1233+
goto next_iter;
1234+
}
1235+
12031236
#ifdef WOLFSSL_DTLS_CID
12041237
if (versions[v].use_cid) {
12051238
unsigned char cid_c[] = { 0, 1, 2, 3 };
@@ -1225,7 +1258,7 @@ int test_record_size_matches_build_message(void)
12251258
expected = 1;
12261259
reason = "version mismatch";
12271260
}
1228-
else if (XSTRSTR(name, "ECDSA") != NULL) {
1261+
else if (XSTRSTR(name, "ECDSA") != NULL && !isSmCipher) {
12291262
expected = 1;
12301263
reason = "no ECDSA cert";
12311264
}

0 commit comments

Comments
 (0)