hannestschofenig / mbedtls

An open source, portable, easy to use, readable and flexible SSL library
https://tls.mbed.org
Apache License 2.0
15 stars 8 forks source link

PSK check in mbedtls_ssl_tls13_key_schedule_stage_early #406

Open lhuang04 opened 1 year ago

lhuang04 commented 1 year ago

Suggested enhancement

I found one issue when we tested the following early data fallback 1-RTT test case:

Looking into the code, the psk will be clear out after ssl_tls13_write_early_data_postprocess. And psk may be set again in ssl_tls13_parse_server_pre_shared_key_ext only when the server accepts the psk.

So for this test case, it sounds reasonable that psk is not set when we call mbedtls_ssl_tls13_key_schedule_stage_early for the 2nd server hello that rejects the early data. And we should allow such a case, and treat it as if there is no psk, and continue the handshake. It seems be the case in the old logic of tls13-prototype.

Here is our local patch to work around the issue by restoring old logic.

diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -1300,21 +1300,12 @@
     hash_alg = handshake->ciphersuite_info->mac;
 #endif /* MBEDTLS_USE_PSA_CRYPTO */

-
 #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
-    if( mbedtls_ssl_tls13_key_exchange_mode_with_psk( ssl )             ||
-#if defined(MBEDTLS_ZERO_RTT)
-        ssl->handshake->early_data == MBEDTLS_SSL_EARLY_DATA_ON ||
-#endif
-        0 )
+    ret = mbedtls_ssl_tls13_export_handshake_psk( ssl, &psk, &psk_len );
+    if( ret != 0 )
     {
-        ret = mbedtls_ssl_tls13_export_handshake_psk( ssl, &psk, &psk_len );
-        if( ret != 0 )
-        {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_export_handshake_psk",
-                                   ret );
-            return( ret );
-        }
+        psk = NULL;
+        psk_len = 0;
     }
 #endif

cc @ronald-cron-arm , @yuhaoth

Justification

Mbed TLS needs this because

yuhaoth commented 1 year ago

I think I did not understand the problem. Could you share your test scripts?

Client initiates early data handshake but server rejects early data.

I did not know why mbedtls_ssl_tls13_key_schedule_stage_early is called in this case.

-  Ignore the extension and return a regular 1-RTT response.  The
      server then skips past early data by attempting to deprotect
      received records using the handshake traffic key, discarding
      records which fail deprotection (up to the configured
      max_early_data_size).  Once a record is deprotected successfully,
      it is treated as the start of the client's second flight and the
      server proceeds as with an ordinary 1-RTT handshake.

As my understand, if early data indication of EE is not received, client SHOULD skip send EndOfEarlyData and switch outbound transform to handshake transform. ( mbedtls_ssl_set_outbound_transform( ssl, handshake->handshake_transform) )

yuhaoth commented 1 year ago

If 2nd client hello is received, early data MUST be disabled. mbedtls_ssl_tls13_key_schedule_stage_early should not be called in ClientHello, it should be called in ServerHello. Then the reported issue should not exists.

lhuang04 commented 1 year ago

I think I did not understand the problem. Could you share your test scripts?

Sorry, this is from our own integration test. It is a case for QUIC and we use gtest to mock the case. I will try to create a test in ssl-opt.sh for this case, but it may take time.

The following is the mbedtls debug log from client. The issue is in the last few lines.

mbedtls_ssl_tls13_export_handshake_psk() returned -27648 (-0x6c00)
mbedtls_ssl_tls13_key_schedule_stage_early() returned -27648 (-0x6c00)
<= ssl_tls13_process_server_hello ( ServerHello )

The rough flow is like this:

  1. Client does a full handshake with the server. It includes Client Hello, Server Hello, EE and NST.
  2. Client stores the NST.
  3. Client closes the connection.
  4. Client tries to use the stored NST to do 0-RTT.
  5. We mock a server rejection by providing a fake NST.
  6. Client tries to do 0-RTT by sending a Client Hello with a fake NST.
  7. Server rejects the 0-RTT(resumption) by not sending the pre-shared-key extension back in the server hello.
  8. When the client receives the Server hello from step 7. It calls mbedtls_ssl_tls13_key_schedule_stage_early
  9. mbedtls_ssl_tls13_export_handshake_psk is called in mbedtls_ssl_tls13_key_schedule_stage_early. (The ssl->handshake->early_data == MBEDTLS_SSL_EARLY_DATA_ON in this case).
  10. mbedtls_ssl_tls13_export_handshake_psk returns MBEDTLS_ERR_SSL_INTERNAL_ERROR because the psk is rejected by the server.
  11. We would expect the client to continue the handshake because server already send back certificate/certificate verify/finish as part of 1-RTT.
The SSL configuration is tls13 only.
=> mbedtls_quic_input_init
<= mbedtls_quic_input_init
=> mbedtls_quic_input_setup
mbedtls_quic_input_setup() returned 0 (-0x0000)
=> quic_input_provide_data
<= quic_input_provide_data (null input)
mbedtls_quic_input_provide_data() returned 0 (-0x0000)
client state: MBEDTLS_SSL_HELLO_REQUEST
client state: MBEDTLS_SSL_CLIENT_HELLO
=> write client hello
dumping 'client hello, random bytes' (32 bytes)
0000:  e8 77 39 73 10 b8 5a 78 05 1b c9 a0 52 dc 02 64  .w9s..Zx....R..d
0010:  7d a4 0c 7b d6 4b 7c 80 49 92 b6 f3 3e 17 69 ef  }..{.K|.I...>.i.
dumping 'session id' (0 bytes)
client hello, add ciphersuite: 1301, TLS1-3-AES-128-GCM-SHA256
adding EMPTY_RENEGOTIATION_INFO_SCSV
client hello, got 2 cipher suites
client hello, adding server name extension: 127.0.0.1
client hello, adding alpn extension
client hello, adding supported versions extension
supported version: [3:4]
no cookie to send; skip extension
client hello: adding key share extension
dumping 'client hello, key_share extension' (75 bytes)
0000:  00 33 00 47 00 45 00 17 00 41 04 00 df 75 03 ce  .3.G.E...A...u..
0010:  9a 6a c6 c4 2e 89 a0 ef 49 14 38 77 15 4a a2 a1  .j......I.8w.J..
0020:  0c 2b 03 0c a9 97 34 8b 65 ed bb cb c5 00 4e 45  .+....4.e.....NE
0030:  01 d0 46 26 7b c2 e1 5d 15 1e 0d 31 95 9e dc 53  ..F&{..]...1...S
0040:  d0 1f 81 b7 ae 6e bc 14 65 8f bf                 .....n..e..
<= skip write early_data extension
client hello, adding quic_transport_parameters extension: 0x606000036d40 59
client hello, adding psk_key_exchange_modes extension
Adding PSK-ECDHE key exchange mode
client hello, adding supported_groups extension
got supported group(0017)
NamedGroup: secp256r1 ( 17 )
dumping 'Supported groups extension' (4 bytes)
0000:  00 02 00 17                                      ....
adding signature_algorithms extension
got signature scheme [403] ecdsa_secp256r1_sha256
sent signature scheme [403] ecdsa_secp256r1_sha256
got signature scheme [503] ecdsa_secp384r1_sha384
sent signature scheme [503] ecdsa_secp384r1_sha384
got signature scheme [806] rsa_pss_rsae_sha512
sent signature scheme [806] rsa_pss_rsae_sha512
got signature scheme [805] rsa_pss_rsae_sha384
sent signature scheme [805] rsa_pss_rsae_sha384
got signature scheme [804] rsa_pss_rsae_sha256
sent signature scheme [804] rsa_pss_rsae_sha256
got signature scheme [601] rsa_pkcs1_sha512
sent signature scheme [601] rsa_pkcs1_sha512
got signature scheme [501] rsa_pkcs1_sha384
sent signature scheme [501] rsa_pkcs1_sha384
got signature scheme [401] rsa_pkcs1_sha256
sent signature scheme [401] rsa_pkcs1_sha256
skip pre_shared_key extensions
client hello, total extension length: 217
dumping 'client hello extensions' (217 bytes)
0000:  00 d9 00 00 00 0e 00 0c 00 00 09 31 32 37 2e 30  ...........127.0
0010:  2e 30 2e 31 00 10 00 0e 00 0c 0b 68 33 2d 61 6c  .0.1.......h3-al
0020:  69 61 73 2d 30 31 00 2b 00 03 02 03 04 00 33 00  ias-01.+......3.
0030:  47 00 45 00 17 00 41 04 00 df 75 03 ce 9a 6a c6  G.E...A...u...j.
0040:  c4 2e 89 a0 ef 49 14 38 77 15 4a a2 a1 0c 2b 03  .....I.8w.J...+.
0050:  0c a9 97 34 8b 65 ed bb cb c5 00 4e 45 01 d0 46  ...4.e.....NE..F
0060:  26 7b c2 e1 5d 15 1e 0d 31 95 9e dc 53 d0 1f 81  &{..]...1...S...
0070:  b7 ae 6e bc 14 65 8f bf 00 39 00 3b 0f 00 05 04  ..n..e...9.;....
0080:  80 04 00 00 06 04 80 04 00 00 07 04 80 04 00 00  ................
0090:  04 04 80 10 00 00 09 02 40 64 03 02 45 00 01 04  ........@d..E...
00a0:  80 00 75 30 0e 01 07 6a b2 00 80 ff 73 db 08 00  ..u0...j....s...
00b0:  00 00 01 00 00 00 01 00 2d 00 02 01 01 00 0a 00  ........-.......
00c0:  04 00 02 00 17 00 0d 00 12 00 10 04 03 05 03 08  ................
00d0:  06 08 05 08 04 06 01 05 01                       .........
=> write handshake message
=> write record (quic)
<= write record (quic)
<= write handshake message
<= write client hello
client state: MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO
tls13 client state: MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO(27)
=> write change cipher spec
<= write change cipher spec
client state: MBEDTLS_SSL_EARLY_APP_DATA
tls13 client state: MBEDTLS_SSL_EARLY_APP_DATA(30)
=> write early data
<= write early data
client state: MBEDTLS_SSL_SERVER_HELLO
tls13 client state: MBEDTLS_SSL_SERVER_HELLO(2)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= quic_input_peek: WANT_READ
<= mbedtls_quic_input_peek
mbedtls_quic_input_peek: ret: -26880 type: 0 size: 0 len: 0
=> mbedtls_quic_input_provide_data: level: 0 len: 123
=> quic_input_provide_data
quic_input_fill_last_msg_hdr: parsing new handshake message header: hdr_len 0
quic_input_fill_msg_data: appending 119 bytes to the partial message: size: 123 len: 4
mbedtls_quic_input_provide_data() returned 0 (-0x0000)
client state: MBEDTLS_SSL_SERVER_HELLO
tls13 client state: MBEDTLS_SSL_SERVER_HELLO(2)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= mbedtls_quic_input_peek
=> ssl_tls13_process_server_hello
=> mbedtls_quic_input_read: level 0 data: 0x62900000f20d len: 16672
=> quic_input_read: data: 0x62900000f20d len: 16672
quic_input_read: empty queue
quic_input_read() returned 123 (-0xffffff85)
mbedtls_quic_input_read() returned 123 (-0xffffff85)
handshake message: msglen = 123, type = 2, hslen = 123
received ServerHello message
dumping 'server hello' (119 bytes)
0000:  03 03 58 30 e0 1c 54 31 12 2c 28 64 dc bf de e1  ..X0..T1.,(d....
0010:  59 23 27 de ec 73 79 46 99 0c 00 bc b8 ab e1 9d  Y#'..syF........
0020:  ed 0d 00 13 01 00 00 4f 00 2b 00 02 03 04 00 33  .......O.+.....3
0030:  00 45 00 17 00 41 04 d8 0c 12 da a0 cd 8c cc 4f  .E...A.........O
0040:  bd f8 fa a7 fb 11 35 bf 4d 32 29 26 1a 4e 3b ea  ......5.M2)&.N;.
0050:  e2 de 7d 7b c0 94 a3 72 a4 0d 87 5f 63 5f 7e 8e  ..}{...r..._c_~.
0060:  e0 66 96 dd 8b 70 f4 ef fd 50 14 0c 18 67 23 52  .f...p...P...g#R
0070:  a6 92 11 e7 7a b3 8f                             ....z..
dumping 'server hello, version' (2 bytes)
0000:  03 03                                            ..
dumping 'server hello, random bytes' (32 bytes)
0000:  58 30 e0 1c 54 31 12 2c 28 64 dc bf de e1 59 23  X0..T1.,(d....Y#
0010:  27 de ec 73 79 46 99 0c 00 bc b8 ab e1 9d ed 0d  '..syF..........
dumping 'Session ID' (0 bytes)
server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256
dumping 'server hello extensions' (79 bytes)
0000:  00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 d8  .+.....3.E...A..
0010:  0c 12 da a0 cd 8c cc 4f bd f8 fa a7 fb 11 35 bf  .......O......5.
0020:  4d 32 29 26 1a 4e 3b ea e2 de 7d 7b c0 94 a3 72  M2)&.N;...}{...r
0030:  a4 0d 87 5f 63 5f 7e 8e e0 66 96 dd 8b 70 f4 ef  ..._c_~..f...p..
0040:  fd 50 14 0c 18 67 23 52 a6 92 11 e7 7a b3 8f     .P...g#R....z..
found key_shares extension
ECDH curve: secp256r1
Selected key exchange mode: ephemeral
dumping 'mbedtls_ssl_tls13_key_schedule_stage_early' (20 bytes)
0000:  33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c e2  3...`~.;.....h..
0010:  10 ad f3 00                                      ....
dumping 'Handshake secret' (32 bytes)
0000:  b2 7d e5 4d c7 c6 3a 85 c3 94 bd 8a 96 f9 04 46  .}.M..:........F
0010:  06 15 da b7 68 13 0e 18 b2 54 2f 7c fa da d9 ee  ....h....T/|....
=> mbedtls_ssl_tls13_generate_handshake_keys
dumping 'Client handshake traffic secret' (32 bytes)
0000:  39 90 4f e1 76 20 d6 ab d9 4a e6 d0 da 99 0b 6d  9.O.v ...J.....m
0010:  4a 47 46 3a 62 73 b0 e6 06 d3 65 d5 5c 93 4a 60  JGF:bs....e.\.J`
dumping 'Server handshake traffic secret' (32 bytes)
0000:  06 d5 0a bd 8a 9e 3b be 70 9d d7 a9 c0 5c c7 2a  ......;.p....\.*
0010:  b0 fa 95 5c 62 fd 25 f7 7a d9 f5 57 68 79 1a 1a  ...\b.%.z..Why..
dumping 'client_handshake write_key' (16 bytes)
0000:  db 09 99 b5 e8 96 dd 47 1d 2b 47 84 bc 3e 80 96  .......G.+G..>..
dumping 'server_handshake write_key' (16 bytes)
0000:  e5 95 c7 20 e7 9a 53 77 8d a6 fc a3 72 32 69 42  ... ..Sw....r2iB
dumping 'client_handshake write_iv' (12 bytes)
0000:  1c 9b 9b 29 c5 9b a6 30 f1 48 13 80              ...)...0.H..
dumping 'server_handshake write_iv' (12 bytes)
0000:  4f 06 2a ea a8 b3 67 fb d2 02 a8 c4              O.*...g.....
<= mbedtls_ssl_tls13_generate_handshake_keys
Switch to handshake keys for inbound traffic
setting QUIC secrets, level = 1
<= ssl_tls13_process_server_hello ( ServerHello )
client state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS
tls13 client state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS(20)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= quic_input_peek: WANT_READ
<= mbedtls_quic_input_peek
mbedtls_quic_input_peek: ret: -26880 type: 0 size: 0 len: 0
=> mbedtls_quic_input_provide_data: level: 1 len: 752
=> quic_input_provide_data
quic_input_fill_last_msg_hdr: parsing new handshake message header: hdr_len 0
quic_input_fill_msg_data: appending 142 bytes to the partial message: size: 146 len: 4
quic_input_fill_last_msg_hdr: parsing new handshake message header: hdr_len 0
quic_input_fill_msg_data: appending 487 bytes to the partial message: size: 491 len: 4
quic_input_fill_last_msg_hdr: parsing new handshake message header: hdr_len 0
quic_input_fill_msg_data: appending 75 bytes to the partial message: size: 79 len: 4
quic_input_fill_last_msg_hdr: parsing new handshake message header: hdr_len 0
quic_input_fill_msg_data: appending 32 bytes to the partial message: size: 36 len: 4
mbedtls_quic_input_provide_data() returned 0 (-0x0000)
client state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS
tls13 client state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS(20)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= mbedtls_quic_input_peek
=> parse encrypted extensions
=> mbedtls_quic_input_read: level 1 data: 0x62900000f20d len: 16672
=> quic_input_read: data: 0x62900000f20d len: 16672
quic_input_read() returned 146 (-0xffffff6e)
mbedtls_quic_input_read() returned 146 (-0xffffff6e)
handshake message: msglen = 146, type = 8, hslen = 146
dumping 'encrypted extensions' (140 bytes)
0000:  00 0a 00 0a 00 08 00 1d 00 17 00 18 00 19 00 10  ................
0010:  00 0e 00 0c 0b 68 33 2d 61 6c 69 61 73 2d 30 31  .....h3-alias-01
0020:  00 39 00 68 00 08 27 88 f8 14 fc 21 5b ee 02 10  .9.h..'....![...
0030:  d5 24 51 45 fa 51 4f 3e 8a 15 d3 d1 0c 5f a0 01  .$QE.QO>....._..
0040:  0f 12 3b e7 e2 fa e7 d6 67 4d f5 21 84 30 f1 c3  ..;.....gM.!.0..
0050:  f6 38 ef 16 05 04 80 04 00 00 06 04 80 04 00 00  .8..............
0060:  07 04 80 04 00 00 04 04 80 10 00 00 08 02 40 64  ..............@d
0070:  09 01 03 01 04 80 00 75 30 0e 01 07 6a b2 00 80  .......u0...j...
0080:  ff 73 db 08 00 00 00 01 00 00 00 01              .s..........
found extensions supported groups
found alpn extension
found quic_transport_parameters extension
<= parse encrypted extensions
client state: MBEDTLS_SSL_CERTIFICATE_REQUEST
tls13 client state: MBEDTLS_SSL_CERTIFICATE_REQUEST(5)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= mbedtls_quic_input_peek
=> parse certificate request
=> mbedtls_quic_input_read: level 1 data: 0x62900000f20d len: 16672
=> quic_input_read: data: 0x62900000f20d len: 16672
quic_input_read() returned 491 (-0xfffffe15)
mbedtls_quic_input_read() returned 491 (-0xfffffe15)
handshake message: msglen = 491, type = 11, hslen = 491
got no certificate request
<= parse certificate request
client state: MBEDTLS_SSL_SERVER_CERTIFICATE
tls13 client state: MBEDTLS_SSL_SERVER_CERTIFICATE(3)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= mbedtls_quic_input_peek
=> parse certificate
reuse previously read message
peer certificate #1:
cert. version     : 1
serial number     : 92:D1:D2:51:FA:B3:C5:64
issuer name       : CN=testroot
subject name      : CN=testserver
issued  on        : 2020-09-24 13:56:44
expires on        : 2120-08-31 13:56:44
signed using      : RSA with SHA-256
EC key size       : 256 bits
value of 'crt->eckey.Q(X)' (255 bits) is:
 79 e2 8e be e7 0a b1 09 4f 78 71 ec a1 b8 6d e6
 9c 2c 09 7f 51 20 26 b9 2c 67 c6 69 ae 4b 50 6e
value of 'crt->eckey.Q(Y)' (256 bits) is:
 f4 42 2a 9f 33 74 f5 bc 92 d7 08 5e 16 32 e5 20
 09 7a 1c cb d2 0e e0 be 22 cb a4 06 94 da 58 81
Certificate verification flags clear
<= parse certificate
client state: MBEDTLS_SSL_CERTIFICATE_VERIFY
tls13 client state: MBEDTLS_SSL_CERTIFICATE_VERIFY(9)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= mbedtls_quic_input_peek
=> parse certificate verify
=> mbedtls_quic_input_read: level 1 data: 0x62900000f20d len: 16672
=> quic_input_read: data: 0x62900000f20d len: 16672
quic_input_read() returned 79 (-0xffffffb1)
mbedtls_quic_input_read() returned 79 (-0xffffffb1)
handshake message: msglen = 79, type = 15, hslen = 79
dumping 'handshake hash' (32 bytes)
0000:  90 30 d4 c4 40 c4 59 b5 4e c0 38 78 d4 4b a1 8a  .0..@.Y.N.8x.K..
0010:  72 da 75 21 58 a0 38 2e 34 a7 e6 df a5 02 cd 0c  r.u!X.8.4.......
Certificate Verify: Signature algorithm ( 0403 )
dumping 'verify hash' (32 bytes)
0000:  9e 25 82 1b 2f df 58 41 b6 d3 46 b3 35 b8 86 eb  .%../.XA..F.5...
0010:  47 c9 f5 5f 19 41 79 64 fd 17 a5 78 3d e2 51 65  G.._.Ayd...x=.Qe
<= parse certificate verify
mbedtls_ssl_tls13_process_certificate_verify() returned 0 (-0x0000)
client state: MBEDTLS_SSL_SERVER_FINISHED
tls13 client state: MBEDTLS_SSL_SERVER_FINISHED(13)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= mbedtls_quic_input_peek
=> parse finished message
=> mbedtls_quic_input_read: level 1 data: 0x62900000f20d len: 16672
=> quic_input_read: data: 0x62900000f20d len: 16672
quic_input_read: empty queue
quic_input_read() returned 36 (-0xffffffdc)
mbedtls_quic_input_read() returned 36 (-0xffffffdc)
handshake message: msglen = 36, type = 20, hslen = 36
=> mbedtls_ssl_tls13_calculate_verify_data
dumping 'handshake hash' (32 bytes)
0000:  ed 4e b3 fb 71 e4 f4 9f 67 69 39 9d 73 f3 54 45  .N..q...gi9.s.TE
0010:  50 b9 90 b7 46 2d a8 35 88 19 fe 7d 58 b1 bb 39  P...F-.5...}X..9
dumping 'verify_data for finished message' (32 bytes)
0000:  07 eb 48 9a 9d 93 9a fb b2 8a b8 03 e8 4a d8 d7  ..H..........J..
0010:  fe a5 3a a7 71 78 a4 9c a6 25 e6 50 b2 c3 f4 3d  ..:.qx...%.P...=
<= mbedtls_ssl_tls13_calculate_verify_data
dumping 'verify_data (self-computed):' (32 bytes)
0000:  07 eb 48 9a 9d 93 9a fb b2 8a b8 03 e8 4a d8 d7  ..H..........J..
0010:  fe a5 3a a7 71 78 a4 9c a6 25 e6 50 b2 c3 f4 3d  ..:.qx...%.P...=
dumping 'verify_data (received message):' (32 bytes)
0000:  07 eb 48 9a 9d 93 9a fb b2 8a b8 03 e8 4a d8 d7  ..H..........J..
0010:  fe a5 3a a7 71 78 a4 9c a6 25 e6 50 b2 c3 f4 3d  ..:.qx...%.P...=
<= parse finished message
dumping 'Master secret' (32 bytes)
0000:  68 fc 33 78 8d 1d a0 3c bf bb f4 1d 09 90 42 f3  h.3x...<......B.
0010:  47 a0 80 28 48 0f d9 94 0d 57 78 ce fa c4 96 bf  G..(H....Wx.....
=> derive application traffic keys
dumping 'Client application traffic secret' (32 bytes)
0000:  f7 95 31 79 17 dd 76 c0 11 aa ec 8d e2 06 30 7b  ..1y..v.......0{
0010:  75 42 fe 65 e7 09 0e d7 d3 41 9b 79 aa 8e 15 eb  uB.e.....A.y....
dumping 'Server application traffic secret' (32 bytes)
0000:  2f 5e 46 02 3b 9b 3f ac fd 9c 1e 1b b7 11 d8 d3  /^F.;.?.........
0010:  51 49 50 94 ec 6d 39 43 6b f3 10 80 ad 26 59 01  QIP..m9Ck....&Y.
dumping 'client application_write_key:' (16 bytes)
0000:  39 a2 9f 19 a9 32 1c b8 99 27 43 46 8e 16 7c 96  9....2...'CF..|.
dumping 'server application write key' (16 bytes)
0000:  0f 25 5c 08 a2 b7 4a 7c 7b 26 d1 98 94 a7 c1 a3  .%\...J|{&......
dumping 'client application write IV' (12 bytes)
0000:  12 58 4f 49 63 6d ab ab 95 a9 6b a9              .XOIcm....k.
dumping 'server application write IV' (12 bytes)
0000:  15 29 33 92 3a a6 8e b2 cd 23 a7 32              .)3.:....#.2
<= derive application traffic keys
client state: MBEDTLS_SSL_END_OF_EARLY_DATA
tls13 client state: MBEDTLS_SSL_END_OF_EARLY_DATA(22)
=> write EndOfEarlyData
<= write EndOfEarlyData
client state: MBEDTLS_SSL_CLIENT_CERTIFICATE
tls13 client state: MBEDTLS_SSL_CLIENT_CERTIFICATE(7)
Switch to handshake traffic keys for outbound traffic
skip write certificate
skip write certificate verify
client state: MBEDTLS_SSL_CLIENT_FINISHED
tls13 client state: MBEDTLS_SSL_CLIENT_FINISHED(11)
=> write finished message
=> mbedtls_ssl_tls13_calculate_verify_data
dumping 'handshake hash' (32 bytes)
0000:  2e be 7e cf b5 03 3c 0b a2 12 86 90 ed 53 02 db  ..~...<......S..
0010:  b4 f5 dd 12 db f9 9d 6d 12 f6 12 f1 e5 6a 1e 88  .......m.....j..
dumping 'verify_data for finished message' (32 bytes)
0000:  d6 1f eb e7 ab 98 2a df 8c f5 f0 d9 e5 a7 6a bc  ......*.......j.
0010:  a6 88 33 95 cb 5b b8 ae 3b 5f 7b 47 b5 22 4a 2f  ..3..[..;_{G."J/
<= mbedtls_ssl_tls13_calculate_verify_data
=> write handshake message
=> write record (quic)
<= write record (quic)
<= write handshake message
<= write finished message
=> mbedtls_ssl_tls13_compute_resumption_master_secret
dumping 'Resumption master secret' (32 bytes)
0000:  1e 71 a5 45 f8 51 70 79 42 f4 03 69 5b b1 1d f6  .q.E.QpyB..i[...
0010:  7a 52 bb e3 e2 16 25 5a 99 75 be 53 8e 5c d9 6a  zR....%Z.u.S.\.j
<= mbedtls_ssl_tls13_compute_resumption_master_secret
client state: MBEDTLS_SSL_FLUSH_BUFFERS
tls13 client state: MBEDTLS_SSL_FLUSH_BUFFERS(14)
handshake: done
client state: MBEDTLS_SSL_HANDSHAKE_WRAPUP
tls13 client state: MBEDTLS_SSL_HANDSHAKE_WRAPUP(15)
setting QUIC secrets, level = 2
=> handshake wrapup
Switch to application keys for inbound traffic
Switch to application keys for outbound traffic
<= handshake wrapup
=> mbedtls_quic_input_peek
=> quic_input_peek
<= quic_input_peek: WANT_READ
<= mbedtls_quic_input_peek
=> mbedtls_quic_input_provide_data: level: 2 len: 514
=> quic_input_provide_data
quic_input_fill_last_msg_hdr: parsing new handshake message header: hdr_len 0
quic_input_fill_msg_data: appending 253 bytes to the partial message: size: 257 len: 4
quic_input_fill_last_msg_hdr: parsing new handshake message header: hdr_len 0
quic_input_fill_msg_data: appending 253 bytes to the partial message: size: 257 len: 4
mbedtls_quic_input_provide_data() returned 0 (-0x0000)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= mbedtls_quic_input_peek
=> mbedtls_quic_input_read: level 2 data: 0x62900000f20d len: 16672
=> quic_input_read: data: 0x62900000f20d len: 16672
quic_input_read() returned 257 (-0xfffffeff)
mbedtls_quic_input_read() returned 257 (-0xfffffeff)
handshake message: msglen = 257, type = 4, hslen = 257
NewSessionTicket received
=> parse new session ticket
ticket_lifetime: 7200
ticket_age_add: 1678542054
dumping 'ticket_nonce:' (8 bytes)
0000:  00 00 00 00 00 00 00 00                          ........
dumping 'received ticket' (224 bytes)
0000:  d8 aa 29 2b 44 12 fb 03 0b de 9f 47 d4 db fb f5  ..)+D......G....
0010:  9c 86 cf 28 ba cf 56 9e 9a 69 5d 9b 1d 00 b0 66  ...(..V..i]....f
0020:  36 40 36 8d 4d 17 4c 1b 4c a7 b3 89 5c 32 93 72  6@6.M.L.L...\2.r
0030:  a5 3f 52 47 6c 24 10 49 3a 35 bd c7 f8 ef 9e e8  .?RGl$.I:5......
0040:  9d 56 12 67 6d 7b ee d2 8b a7 18 43 2d 7b d4 5f  .V.gm{.....C-{._
0050:  29 db a7 e5 44 4c 62 f5 3a e8 82 51 2d d3 58 28  )...DLb.:..Q-.X(
0060:  49 69 be 0a 30 6a 5c ac 11 7c 4f bf a2 fc 62 4e  Ii..0j\..|O...bN
0070:  20 43 5e 80 48 0f 82 4a a3 f9 a5 9c ba f5 c1 be   C^.H..J........
0080:  e9 5f 79 6d 77 e5 99 f2 5d b0 46 46 d4 df 25 0c  ._ymw...].FF..%.
0090:  1e b1 5f a2 f8 4c 2c 5d d9 1a 71 dd 3f 7e 4d 42  .._..L,]..q.?~MB
00a0:  36 89 f8 c0 85 9f 00 66 34 ca 10 ec 58 ee 70 1f  6......f4...X.p.
00b0:  4c 40 10 1d 88 a9 f2 f9 70 1a a5 1d 85 8c c7 0b  L@......p.......
00c0:  ca f4 e4 b0 40 83 2c ec ad 1e 22 fa f2 77 9c 3c  ....@.,..."..w.<
00d0:  30 73 39 f2 fd 62 a1 1c 92 73 5c 1f cb 90 67 bf  0s9..b...s\...g.
dumping 'ticket extension' (8 bytes)
0000:  00 2a 00 04 ff ff ff ff                          .*......
early_data extension received
ticket->max_early_data_size: 4294967295
dumping 'resumption_master_secret' (32 bytes)
0000:  1e 71 a5 45 f8 51 70 79 42 f4 03 69 5b b1 1d f6  .q.E.QpyB..i[...
0010:  7a 52 bb e3 e2 16 25 5a 99 75 be 53 8e 5c d9 6a  zR....%Z.u.S.\.j
dumping 'Ticket-resumed PSK' (32 bytes)
0000:  c4 04 f6 48 1e 86 93 2f c0 ee 0d 80 51 ac 93 e4  ...H.../....Q...
0010:  fe d6 f8 a8 cc 4b 55 76 af c1 5b b0 48 52 41 f3  .....KUv..[.HRA.
<= parse new session ticket
=> free
=> mbedtls_quic_input_free
=> quic_input_free: level: 0
<= quic_input_free: level: 0
=> quic_input_free: level: 1
<= quic_input_free: level: 1
=> quic_input_free: level: 2
<= quic_input_free: level: 2
<= mbedtls_quic_input_free
<= free
The SSL configuration is tls13 only.
=> mbedtls_quic_input_init
<= mbedtls_quic_input_init
=> mbedtls_quic_input_setup
mbedtls_quic_input_setup() returned 0 (-0x0000)
=> mbedtls_quic_input_provide_data: level: 0 len: 0
=> quic_input_provide_data
<= quic_input_provide_data (null input)
mbedtls_quic_input_provide_data() returned 0 (-0x0000)
client state: MBEDTLS_SSL_HELLO_REQUEST
client state: MBEDTLS_SSL_CLIENT_HELLO
=> write client hello
dumping 'client hello, random bytes' (32 bytes)
0000:  ce d0 55 1a 99 f4 32 4b 3d 2d 11 96 3e c2 f2 16  ..U...2K=-..>...
0010:  7b 6b 07 cc 61 64 8c 89 52 52 e0 df 32 4e ca 12  {k..ad..RR..2N..
dumping 'session id' (0 bytes)
client hello, add ciphersuite: 1301, TLS1-3-AES-128-GCM-SHA256
adding EMPTY_RENEGOTIATION_INFO_SCSV
client hello, got 2 cipher suites
client hello, adding server name extension: 127.0.0.1
client hello, adding alpn extension
client hello, adding supported versions extension
supported version: [3:4]
no cookie to send; skip extension
client hello: adding key share extension
dumping 'client hello, key_share extension' (75 bytes)
0000:  00 33 00 47 00 45 00 17 00 41 04 a8 bd 08 aa af  .3.G.E...A......
0010:  90 65 1a ba 91 3b 14 3e 9d e9 bd 23 cd 0f b6 81  .e...;.>...#....
0020:  5a ba 83 06 8e 88 41 97 bb d3 2e 44 6f 58 8e 78  Z.....A....DoX.x
0030:  7a 33 01 e9 9b 6f b9 12 f2 5b 5b b5 0c 68 c4 29  z3...o...[[..h.)
0040:  58 6e 76 93 16 2e cf c3 bc ef 4c                 Xnv.......L
client hello, adding early_data extension
client hello, adding quic_transport_parameters extension: 0x606000045080 59
client hello, adding psk_key_exchange_modes extension
Adding PSK-ECDHE key exchange mode
client hello, adding supported_groups extension
got supported group(0017)
NamedGroup: secp256r1 ( 17 )
dumping 'Supported groups extension' (4 bytes)
0000:  00 02 00 17                                      ....
adding signature_algorithms extension
got signature scheme [403] ecdsa_secp256r1_sha256
sent signature scheme [403] ecdsa_secp256r1_sha256
got signature scheme [503] ecdsa_secp384r1_sha384
sent signature scheme [503] ecdsa_secp384r1_sha384
got signature scheme [806] rsa_pss_rsae_sha512
sent signature scheme [806] rsa_pss_rsae_sha512
got signature scheme [805] rsa_pss_rsae_sha384
sent signature scheme [805] rsa_pss_rsae_sha384
got signature scheme [804] rsa_pss_rsae_sha256
sent signature scheme [804] rsa_pss_rsae_sha256
got signature scheme [601] rsa_pkcs1_sha512
sent signature scheme [601] rsa_pkcs1_sha512
got signature scheme [501] rsa_pkcs1_sha384
sent signature scheme [501] rsa_pkcs1_sha384
got signature scheme [401] rsa_pkcs1_sha256
sent signature scheme [401] rsa_pkcs1_sha256
Ticket is configured
Pre-configured PSK number = 1
dumping 'write identity' (38 bytes)
0000:  00 20 30 31 32 33 34 35 36 37 38 39 30 31 32 33  . 01234567890123
0010:  34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39  4567890123456789
0020:  30 31 00 00 c3 5c                                01...\
client hello, adding pre_shared_key extension, omitting PSK binder list
dumping 'pre_shared_key identities' (44 bytes)
0000:  00 29 00 4b 00 26 00 20 30 31 32 33 34 35 36 37  .).K.&. 01234567
0010:  38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33  8901234567890123
0020:  34 35 36 37 38 39 30 31 00 00 c3 5c              45678901...\
client hello, total extension length: 300
dumping 'client hello extensions' (300 bytes)
0000:  01 2c 00 00 00 0e 00 0c 00 00 09 31 32 37 2e 30  .,.........127.0
0010:  2e 30 2e 31 00 10 00 0e 00 0c 0b 68 33 2d 61 6c  .0.1.......h3-al
0020:  69 61 73 2d 30 31 00 2b 00 03 02 03 04 00 33 00  ias-01.+......3.
0030:  47 00 45 00 17 00 41 04 a8 bd 08 aa af 90 65 1a  G.E...A.......e.
0040:  ba 91 3b 14 3e 9d e9 bd 23 cd 0f b6 81 5a ba 83  ..;.>...#....Z..
0050:  06 8e 88 41 97 bb d3 2e 44 6f 58 8e 78 7a 33 01  ...A....DoX.xz3.
0060:  e9 9b 6f b9 12 f2 5b 5b b5 0c 68 c4 29 58 6e 76  ..o...[[..h.)Xnv
0070:  93 16 2e cf c3 bc ef 4c 00 2a 00 00 00 39 00 3b  .......L.*...9.;
0080:  0f 00 05 04 80 04 00 00 06 04 80 04 00 00 07 04  ................
0090:  80 04 00 00 04 04 80 10 00 00 09 02 40 64 03 02  ............@d..
00a0:  45 00 01 04 80 00 75 30 0e 01 07 6a b2 00 80 ff  E.....u0...j....
00b0:  73 db 08 00 00 00 01 00 00 00 01 00 2d 00 02 01  s...........-...
00c0:  01 00 0a 00 04 00 02 00 17 00 0d 00 12 00 10 04  ................
00d0:  03 05 03 08 06 08 05 08 04 06 01 05 01 04 01 00  ................
00e0:  29 00 4b 00 26 00 20 30 31 32 33 34 35 36 37 38  ).K.&. 012345678
00f0:  39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34  9012345678901234
0100:  35 36 37 38 39 30 31 00 00 c3 5c 00 00 00 00 00  5678901...\.....
0110:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0120:  00 00 00 00 00 00 00 00 00 00 00 00              ............
dumping 'mbedtls_ssl_tls13_create_psk_binder' (32 bytes)
0000:  73 30 f1 ff 9c 3a 32 1d 2b 2f 05 1a b2 5a 85 0b  s0...:2.+/...Z..
0010:  63 00 a1 64 7d 87 a2 99 f4 1e 05 96 16 62 89 6f  c..d}........b.o
Derive Early Secret with 'res binder'
dumping 'psk binder' (32 bytes)
0000:  cc fb 1f 19 59 f2 c3 e6 60 cd c9 67 6b 40 43 12  ....Y...`..gk@C.
0010:  b0 2d b0 06 db 9f f1 da 6a 33 74 48 ce 35 5e e3  .-......j3tH.5^.
dumping 'write binder' (33 bytes)
0000:  20 cc fb 1f 19 59 f2 c3 e6 60 cd c9 67 6b 40 43   ....Y...`..gk@C
0010:  12 b0 2d b0 06 db 9f f1 da 6a 33 74 48 ce 35 5e  ..-......j3tH.5^
0020:  e3                                               .
client hello, adding PSK binder list.
dumping 'pre_shared_key binders' (35 bytes)
0000:  00 21 20 cc fb 1f 19 59 f2 c3 e6 60 cd c9 67 6b  .! ....Y...`..gk
0010:  40 43 12 b0 2d b0 06 db 9f f1 da 6a 33 74 48 ce  @C..-......j3tH.
0020:  35 5e e3                                         5^.
=> write handshake message
=> write record (quic)
<= write record (quic)
<= write handshake message
<= write client hello
client state: MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO
tls13 client state: MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO(27)
=> write change cipher spec
<= write change cipher spec
client state: MBEDTLS_SSL_EARLY_APP_DATA
tls13 client state: MBEDTLS_SSL_EARLY_APP_DATA(30)
=> write early data
dumping 'mbedtls_ssl_tls13_key_schedule_stage_early' (20 bytes)
0000:  73 30 f1 ff 9c 3a 32 1d 2b 2f 05 1a b2 5a 85 0b  s0...:2.+/...Z..
0010:  63 00 a1 64                                      c..d
=> mbedtls_ssl_tls13_generate_early_data_keys
dumping 'client_early_traffic_secret' (32 bytes)
0000:  17 67 69 c2 93 43 b4 47 48 c8 ac 14 02 20 78 d5  .gi..C.GH.... x.
0010:  04 03 76 fe be 1a 4f ba 64 44 b7 df 90 26 8f 0b  ..v...O.dD...&..
<= mbedtls_ssl_tls13_generate_early_data_keys
setting QUIC secrets, level = 3
Switch to 0-RTT keys for outbound traffic
<= write early data
client state: MBEDTLS_SSL_SERVER_HELLO
tls13 client state: MBEDTLS_SSL_SERVER_HELLO(2)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= quic_input_peek: WANT_READ
<= mbedtls_quic_input_peek
mbedtls_quic_input_peek: ret: -26880 type: 0 size: 0 len: 0
=> mbedtls_quic_input_provide_data: level: 0 len: 123
=> quic_input_provide_data
quic_input_fill_last_msg_hdr: parsing new handshake message header: hdr_len 0
quic_input_fill_msg_data: appending 119 bytes to the partial message: size: 123 len: 4
mbedtls_quic_input_provide_data() returned 0 (-0x0000)
client state: MBEDTLS_SSL_SERVER_HELLO
tls13 client state: MBEDTLS_SSL_SERVER_HELLO(2)
=> mbedtls_quic_input_peek
=> quic_input_peek
<= mbedtls_quic_input_peek
=> ssl_tls13_process_server_hello
=> mbedtls_quic_input_read: level 0 data: 0x62900002320d len: 16672
=> quic_input_read: data: 0x62900002320d len: 16672
quic_input_read: empty queue
quic_input_read() returned 123 (-0xffffff85)
mbedtls_quic_input_read() returned 123 (-0xffffff85)
handshake message: msglen = 123, type = 2, hslen = 123
received ServerHello message
dumping 'server hello' (119 bytes)
0000:  03 03 ff 4c b1 b3 c2 8a b0 2c 5e c7 e2 fd e9 18  ...L.....,^.....
0010:  07 a8 6f 7c a7 1e 55 9f de e3 06 00 21 bb 9d c4  ..o|..U.....!...
0020:  4f de 00 13 01 00 00 4f 00 2b 00 02 03 04 00 33  O......O.+.....3
0030:  00 45 00 17 00 41 04 19 fb 6c de 03 20 71 55 54  .E...A...l.. qUT
0040:  6e 7a 66 35 6e 90 69 1a f0 38 4e 8b 56 83 eb fd  nzf5n.i..8N.V...
0050:  47 99 60 96 eb 45 35 6f 90 fc ba e5 0d 18 69 81  G.`..E5o......i.
0060:  12 55 b0 c8 cf b6 0b c1 6d 18 aa 31 93 e7 9d cd  .U......m..1....
0070:  df aa 99 fe 26 a5 af                             ....&..
dumping 'server hello, version' (2 bytes)
0000:  03 03                                            ..
dumping 'server hello, random bytes' (32 bytes)
0000:  ff 4c b1 b3 c2 8a b0 2c 5e c7 e2 fd e9 18 07 a8  .L.....,^.......
0010:  6f 7c a7 1e 55 9f de e3 06 00 21 bb 9d c4 4f de  o|..U.....!...O.
dumping 'Session ID' (0 bytes)
server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256
dumping 'server hello extensions' (79 bytes)
0000:  00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 19  .+.....3.E...A..
0010:  fb 6c de 03 20 71 55 54 6e 7a 66 35 6e 90 69 1a  .l.. qUTnzf5n.i.
0020:  f0 38 4e 8b 56 83 eb fd 47 99 60 96 eb 45 35 6f  .8N.V...G.`..E5o
0030:  90 fc ba e5 0d 18 69 81 12 55 b0 c8 cf b6 0b c1  ......i..U......
0040:  6d 18 aa 31 93 e7 9d cd df aa 99 fe 26 a5 af     m..1........&..
found key_shares extension
ECDH curve: secp256r1
Selected key exchange mode: ephemeral
mbedtls_ssl_tls13_export_handshake_psk() returned -27648 (-0x6c00)
mbedtls_ssl_tls13_key_schedule_stage_early() returned -27648 (-0x6c00)
<= ssl_tls13_process_server_hello ( ServerHello )
=> send alert message
send alert level=2 message=40
<= send alert message
=> free
=> mbedtls_quic_input_free

I did not know why mbedtls_ssl_tls13_key_schedule_stage_early is called in this case.

I touch it in step 8 above. mbedtls_ssl_tls13_key_schedule_stage_early is called from ssl_tls13_postprocess_server_hello.

If 2nd client hello is received, early data MUST be disabled. mbedtls_ssl_tls13_key_schedule_stage_early should not be called in ClientHello, it should be called in ServerHello. Then the reported issue should not exists.

mbedtls_ssl_tls13_key_schedule_stage_early is indeed called when client process server hello. See the debug log above.

mbedtls_ssl_tls13_export_handshake_psk() returned -27648 (-0x6c00)
mbedtls_ssl_tls13_key_schedule_stage_early() returned -27648 (-0x6c00)
<= ssl_tls13_process_server_hello ( ServerHello )