@@ -1121,3 +1121,200 @@ int test_tls12_peerauth_failsafe(void)
11211121#endif
11221122 return EXPECT_RESULT ();
11231123}
1124+
1125+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES )
1126+ /* Cipher-name substrings that need extra setup (PSK callback, ECDSA cert,
1127+ * SRP, etc.) which the default test_memio_setup() doesn't provide. */
1128+ static int record_size_skip_cipher (const char * name )
1129+ {
1130+ /* "ECDH-" matches static-ECDH ciphers ("ECDH-RSA-*", "ECDH-ECDSA-*")
1131+ * and not ECDHE-* because of the trailing '-'. */
1132+ static const char * const deny [] = {
1133+ "PSK" , "SRP" , "ANON" , "NULL" , "ECDSA" , "ECDH-" , "SM"
1134+ };
1135+ size_t i ;
1136+ for (i = 0 ; i < XELEM_CNT (deny ); i ++ ) {
1137+ if (XSTRSTR (name , deny [i ]) != NULL )
1138+ return 1 ;
1139+ }
1140+ return 0 ;
1141+ }
1142+
1143+ /* Cross-check wolfssl_local_GetRecordSize() against BuildMessage(sizeOnly=1)
1144+ * with the cache cold, then call it a second time and assert both calls
1145+ * return the same size — that exercises the cached path for AEAD ciphers
1146+ * without duplicating the BuildMessage arithmetic. */
1147+ static int record_size_check_ssl (WOLFSSL * ssl )
1148+ {
1149+ EXPECT_DECLS ;
1150+ static const int payloads [] = { 1 , 16 , 256 , 1300 , 4096 };
1151+ size_t k ;
1152+
1153+ for (k = 0 ; k < XELEM_CNT (payloads ); k ++ ) {
1154+ int payloadSz = payloads [k ];
1155+ int expectedSz = BuildMessage (ssl , NULL , 0 , NULL , payloadSz ,
1156+ application_data , 0 , 1 , 0 , CUR_ORDER );
1157+ int firstSz , secondSz ;
1158+
1159+ ssl -> recordSzOverhead = 0 ;
1160+ firstSz = wolfssl_local_GetRecordSize (ssl , payloadSz , 1 );
1161+ secondSz = wolfssl_local_GetRecordSize (ssl , payloadSz , 1 );
1162+ ExpectIntEQ (firstSz , expectedSz );
1163+ ExpectIntEQ (secondSz , expectedSz );
1164+ }
1165+ return EXPECT_RESULT ();
1166+ }
1167+
1168+ /* Returns 1 if `suite` is selectable for the given client/server method
1169+ * pair, 0 otherwise. wolfSSL rejects some ciphers for DTLS at
1170+ * set_cipher_list time (e.g. RFC 7465 forbids RC4 in DTLS); skip those
1171+ * silently rather than failing the cross-check. */
1172+ static int record_size_cipher_selectable (method_provider client_method ,
1173+ method_provider server_method , const char * suite )
1174+ {
1175+ WOLFSSL_CTX * ctx_c = wolfSSL_CTX_new (client_method ());
1176+ WOLFSSL_CTX * ctx_s = wolfSSL_CTX_new (server_method ());
1177+ int ok = (ctx_c != NULL && ctx_s != NULL &&
1178+ wolfSSL_CTX_set_cipher_list (ctx_c , suite ) == WOLFSSL_SUCCESS &&
1179+ wolfSSL_CTX_set_cipher_list (ctx_s , suite ) == WOLFSSL_SUCCESS );
1180+ if (ctx_c ) wolfSSL_CTX_free (ctx_c );
1181+ if (ctx_s ) wolfSSL_CTX_free (ctx_s );
1182+ return ok ;
1183+ }
1184+
1185+ /* Run the cross-check on a memio pair using the given (de)multiplexing
1186+ * methods and cipher suite. Optionally enable DTLS-CID with peer CIDs of
1187+ * different sizes so the test covers CID-extended record framing. */
1188+ static int record_size_run_pair (method_provider client_method ,
1189+ method_provider server_method , const char * suite , int useCid )
1190+ {
1191+ EXPECT_DECLS ;
1192+ WOLFSSL_CTX * ctx_c = NULL , * ctx_s = NULL ;
1193+ WOLFSSL * ssl_c = NULL , * ssl_s = NULL ;
1194+ struct test_memio_ctx test_ctx ;
1195+
1196+ (void )useCid ;
1197+ if (!record_size_cipher_selectable (client_method , server_method , suite ))
1198+ return TEST_SUCCESS ; /* not valid for this protocol -- skip */
1199+
1200+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
1201+ test_ctx .c_ciphers = test_ctx .s_ciphers = suite ;
1202+ ExpectIntEQ (test_memio_setup (& test_ctx , & ctx_c , & ctx_s , & ssl_c , & ssl_s ,
1203+ client_method , server_method ), 0 );
1204+ #ifdef WOLFSSL_DTLS_CID
1205+ if (useCid ) {
1206+ /* Different sizes on each side to exercise asymmetric framing. */
1207+ static unsigned char client_cid [] = { 1 , 2 , 3 , 4 , 5 , 6 };
1208+ static unsigned char server_cid [] = { 7 , 8 , 9 };
1209+ ExpectIntEQ (wolfSSL_dtls_cid_use (ssl_c ), 1 );
1210+ ExpectIntEQ (wolfSSL_dtls_cid_set (ssl_c , server_cid ,
1211+ sizeof (server_cid )), 1 );
1212+ ExpectIntEQ (wolfSSL_dtls_cid_use (ssl_s ), 1 );
1213+ ExpectIntEQ (wolfSSL_dtls_cid_set (ssl_s , client_cid ,
1214+ sizeof (client_cid )), 1 );
1215+ }
1216+ #endif
1217+ ExpectIntEQ (test_memio_do_handshake (ssl_c , ssl_s , 30 , NULL ), 0 );
1218+ ExpectIntEQ (record_size_check_ssl (ssl_c ), TEST_SUCCESS );
1219+ ExpectIntEQ (record_size_check_ssl (ssl_s ), TEST_SUCCESS );
1220+
1221+ wolfSSL_free (ssl_c );
1222+ wolfSSL_free (ssl_s );
1223+ wolfSSL_CTX_free (ctx_c );
1224+ wolfSSL_CTX_free (ctx_s );
1225+ return EXPECT_RESULT ();
1226+ }
1227+ #endif /* HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES */
1228+
1229+ int test_record_size_matches_build_message (void )
1230+ {
1231+ EXPECT_DECLS ;
1232+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES )
1233+ const CipherSuiteInfo * suites = GetCipherNames ();
1234+ int n = GetCipherNamesSize ();
1235+ int i ;
1236+
1237+ for (i = 0 ; i < n ; i ++ ) {
1238+ const char * name = suites [i ].name ;
1239+ /* Names prefixed "TLS13-" are TLS 1.3 suites regardless of
1240+ * cipherSuite0, which may be either TLS13_BYTE or ECC_BYTE (for
1241+ * the integrity-only TLS_SHA*_SHA* suites). */
1242+ int isTls13 = (XSTRNCMP (name , "TLS13-" , 6 ) == 0 );
1243+ if (record_size_skip_cipher (name ))
1244+ continue ;
1245+
1246+ if (isTls13 ) {
1247+ #ifdef WOLFSSL_TLS13
1248+ ExpectIntEQ (record_size_run_pair (wolfTLSv1_3_client_method ,
1249+ wolfTLSv1_3_server_method , name , 0 ), TEST_SUCCESS );
1250+ #endif
1251+ #ifdef WOLFSSL_DTLS13
1252+ ExpectIntEQ (record_size_run_pair (wolfDTLSv1_3_client_method ,
1253+ wolfDTLSv1_3_server_method , name , 0 ), TEST_SUCCESS );
1254+ #if defined(WOLFSSL_DTLS_CID )
1255+ ExpectIntEQ (record_size_run_pair (wolfDTLSv1_3_client_method ,
1256+ wolfDTLSv1_3_server_method , name , 1 ), TEST_SUCCESS );
1257+ #endif
1258+ #endif
1259+ }
1260+ else {
1261+ #ifndef WOLFSSL_NO_TLS12
1262+ ExpectIntEQ (record_size_run_pair (wolfTLSv1_2_client_method ,
1263+ wolfTLSv1_2_server_method , name , 0 ), TEST_SUCCESS );
1264+ #endif
1265+ #if defined(WOLFSSL_DTLS ) && !defined(WOLFSSL_NO_TLS12 )
1266+ ExpectIntEQ (record_size_run_pair (wolfDTLSv1_2_client_method ,
1267+ wolfDTLSv1_2_server_method , name , 0 ), TEST_SUCCESS );
1268+ #if defined(WOLFSSL_DTLS_CID )
1269+ ExpectIntEQ (record_size_run_pair (wolfDTLSv1_2_client_method ,
1270+ wolfDTLSv1_2_server_method , name , 1 ), TEST_SUCCESS );
1271+ #endif
1272+ #endif
1273+ }
1274+ }
1275+ #endif /* HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES */
1276+ return EXPECT_RESULT ();
1277+ }
1278+
1279+ int test_record_size_cache_invalidated_on_renegotiation (void )
1280+ {
1281+ EXPECT_DECLS ;
1282+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && \
1283+ defined(HAVE_SECURE_RENEGOTIATION ) && !defined(WOLFSSL_NO_TLS12 ) && \
1284+ defined(BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 )
1285+ WOLFSSL_CTX * ctx_c = NULL , * ctx_s = NULL ;
1286+ WOLFSSL * ssl_c = NULL , * ssl_s = NULL ;
1287+ struct test_memio_ctx test_ctx ;
1288+ byte readBuf [16 ];
1289+ int sz ;
1290+
1291+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
1292+ ExpectIntEQ (test_memio_setup (& test_ctx , & ctx_c , & ctx_s , & ssl_c , & ssl_s ,
1293+ wolfTLSv1_2_client_method , wolfTLSv1_2_server_method ), 0 );
1294+ ExpectIntEQ (wolfSSL_UseSecureRenegotiation (ssl_c ), WOLFSSL_SUCCESS );
1295+ ExpectIntEQ (wolfSSL_UseSecureRenegotiation (ssl_s ), WOLFSSL_SUCCESS );
1296+ ExpectIntEQ (test_memio_do_handshake (ssl_c , ssl_s , 10 , NULL ), 0 );
1297+
1298+ sz = wolfssl_local_GetRecordSize (ssl_c , 256 , 1 );
1299+ ExpectIntEQ (sz , BuildMessage (ssl_c , NULL , 0 , NULL , 256 ,
1300+ application_data , 0 , 1 , 0 , CUR_ORDER ));
1301+ ExpectIntNE (ssl_c -> recordSzOverhead , 0 );
1302+
1303+ ExpectIntEQ (wolfSSL_Rehandshake (ssl_c ), -1 );
1304+ ExpectIntEQ (wolfSSL_get_error (ssl_c , -1 ), WOLFSSL_ERROR_WANT_READ );
1305+ ExpectIntEQ (wolfSSL_read (ssl_s , readBuf , sizeof (readBuf )), -1 );
1306+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), WOLFSSL_ERROR_WANT_READ );
1307+ ExpectIntEQ (test_memio_do_handshake (ssl_c , ssl_s , 10 , NULL ), 0 );
1308+
1309+ /* SetKeysSide() during renegotiation must have cleared the cache. */
1310+ sz = wolfssl_local_GetRecordSize (ssl_c , 256 , 1 );
1311+ ExpectIntEQ (sz , BuildMessage (ssl_c , NULL , 0 , NULL , 256 ,
1312+ application_data , 0 , 1 , 0 , CUR_ORDER ));
1313+
1314+ wolfSSL_free (ssl_c );
1315+ wolfSSL_free (ssl_s );
1316+ wolfSSL_CTX_free (ctx_c );
1317+ wolfSSL_CTX_free (ctx_s );
1318+ #endif
1319+ return EXPECT_RESULT ();
1320+ }
0 commit comments