1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2008-2020. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21-module(tls_1_3_record_SUITE).
22
23-include_lib("common_test/include/ct.hrl").
24-include_lib("ssl/src/tls_record.hrl").
25-include_lib("ssl/src/tls_handshake.hrl").
26-include_lib("ssl/src/tls_handshake_1_3.hrl").
27-include_lib("ssl/src/ssl_cipher.hrl").
28-include_lib("ssl/src/ssl_internal.hrl").
29
30%% Callback functions
31-export([all/0,
32         init_per_suite/1,
33         end_per_suite/1]).
34
35%% Testcases
36-export([encode_decode/0,
37         encode_decode/1,
38         finished_verify_data/0,
39          finished_verify_data/1,
40         '1_RTT_handshake'/0,
41         '1_RTT_handshake'/1,
42         '0_RTT_handshake'/0,
43         '0_RTT_handshake'/1
44        ]).
45
46%%--------------------------------------------------------------------
47%% Common Test interface functions -----------------------------------
48%%--------------------------------------------------------------------
49
50all() ->
51    [encode_decode,
52     finished_verify_data,
53     '1_RTT_handshake',
54     '0_RTT_handshake'].
55
56init_per_suite(Config) ->
57    catch crypto:stop(),
58    try (ok == crypto:start()) andalso ssl_test_lib:sufficient_crypto_support('tlsv1.3') of
59	true ->
60	    ssl_test_lib:clean_start(),
61            Config;
62        false ->
63            {skip, "Not enough crypto support for TLS-1.3"}
64    catch _:_ ->
65	    {skip, "Crypto did not start"}
66    end.
67
68end_per_suite(_Config) ->
69    ssl:stop(),
70    application:unload(ssl),
71    application:stop(crypto).
72%%--------------------------------------------------------------------
73%% Test Cases --------------------------------------------------------
74%%--------------------------------------------------------------------
75
76encode_decode() ->
77     [{doc,"Test TLS 1.3 record encode/decode functions"}].
78
79encode_decode(_Config) ->
80    ConnectionStates =
81        #{current_read =>
82              #{beast_mitigation => one_n_minus_one,
83                cipher_state =>
84                    {cipher_state,
85                     <<14,172,111,243,199,170,242,203,126,205,34,93,122,115,226,14,
86                       15,117,155,48,24,112,61,15,113,208,127,51,179,227,194,232>>,
87                     <<197,54,168,218,54,91,157,58,30,201,197,142,51,58,53,231,228,
88                       131,57,122,170,78,82,196,30,48,23,16,95,255,185,236>>,
89                     undefined,undefined,undefined,16},
90                client_verify_data => undefined,compression_state => undefined,
91                mac_secret => undefined,secure_renegotiation => undefined,
92                security_parameters =>
93                    #security_parameters{
94                       cipher_suite          = <<19,2>>,
95                       connection_end        = 0,
96                       bulk_cipher_algorithm = 8,
97                       cipher_type           = 2,
98                       prf_algorithm         = sha384,
99                       master_secret         =
100                           {handshake_secret,
101                            <<128,229,186,211,62,127,182,20,62,166,233,23,135,64,121,
102                              3,104,251,214,161,253,31,3,2,232,37,8,221,189,72,64,218,
103                              121,41,112,148,254,34,68,164,228,60,161,201,132,55,56,
104                              157>>},
105                       server_random         =
106                           <<92,24,205,75,244,60,136,212,250,32,214,20,37,3,213,87,61,207,
107                             147,61,168,145,177,118,160,153,33,53,48,108,191,174>>},
108                sequence_number => 0,server_verify_data => undefined,
109                max_early_data_size => 0,
110                trial_decryption => false,
111                early_data_limit => false},
112          current_write =>
113              #{beast_mitigation => one_n_minus_one,
114                cipher_state =>
115                    {cipher_state,
116                     <<14,172,111,243,199,170,242,203,126,205,34,93,122,115,226,14,
117                       15,117,155,48,24,112,61,15,113,208,127,51,179,227,194,232>>,
118                     <<197,54,168,218,54,91,157,58,30,201,197,142,51,58,53,231,228,
119                       131,57,122,170,78,82,196,30,48,23,16,95,255,185,236>>,
120                     undefined,undefined,undefined,16},
121                client_verify_data => undefined,compression_state => undefined,
122                mac_secret => undefined,secure_renegotiation => undefined,
123                security_parameters =>
124                    #security_parameters{
125                       cipher_suite          = <<19,2>>,
126                       connection_end        = 0,
127                       bulk_cipher_algorithm = 8,
128                       cipher_type           = 2,
129                       prf_algorithm         = sha384,
130                       master_secret         =
131                           {handshake_secret,
132                            <<128,229,186,211,62,127,182,20,62,166,233,23,135,64,121,
133                              3,104,251,214,161,253,31,3,2,232,37,8,221,189,72,64,218,
134                              121,41,112,148,254,34,68,164,228,60,161,201,132,55,56,
135                              157>>},
136                     server_random         =
137                           <<92,24,205,75,244,60,136,212,250,32,214,20,37,3,213,87,61,207,
138                             147,61,168,145,177,118,160,153,33,53,48,108,191,174>>},
139                sequence_number => 0,server_verify_data => undefined},max_fragment_length => undefined},
140
141    PlainText = [11,
142                 <<0,2,175>>,
143                 <<0,0,2,171,0,2,166,48,130,2,162,48,130,1,138,2,9,0,186,57,220,137,88,255,
144                   191,235,48,13,6,9,42,134,72,134,247,13,1,1,11,5,0,48,18,49,16,48,14,6,3,85,
145                   4,3,12,7,84,101,115,116,32,67,65,48,30,23,13,49,56,48,53,48,52,49,52,49,50,
146                   51,56,90,23,13,50,56,48,50,48,52,49,52,49,50,51,56,90,48,20,49,18,48,16,6,
147                   3,85,4,3,12,9,108,111,99,97,108,104,111,115,116,48,130,1,34,48,13,6,9,42,
148                   134,72,134,247,13,1,1,1,5,0,3,130,1,15,0,48,130,1,10,2,130,1,1,0,169,40,
149                   144,176,121,63,134,97,144,126,243,183,225,157,37,131,183,225,87,243,23,88,
150                   230,70,9,134,32,147,7,27,167,98,51,81,224,75,199,12,229,251,195,207,75,179,
151                   181,78,128,3,255,44,58,39,43,172,142,45,186,58,51,65,187,199,154,153,245,
152                   70,133,137,1,27,87,42,116,65,251,129,109,145,233,97,171,71,54,213,185,74,
153                   209,166,11,218,189,119,206,86,170,60,212,213,85,189,30,50,215,23,185,53,
154                   132,238,132,176,198,250,139,251,198,221,225,128,109,113,23,220,39,143,71,
155                   30,59,189,51,244,61,158,214,146,180,196,103,169,189,221,136,78,129,216,148,
156                   2,9,8,65,37,224,215,233,13,209,21,235,20,143,33,74,59,53,208,90,152,94,251,
157                   54,114,171,39,88,230,227,158,211,135,37,182,67,205,161,59,20,138,58,253,15,
158                   53,48,8,157,9,95,197,9,177,116,21,54,9,125,78,109,182,83,20,16,234,223,116,
159                   41,155,123,87,77,17,120,153,246,239,124,130,105,219,166,146,242,151,66,198,
160                   75,72,63,28,246,86,16,244,223,22,36,50,15,247,222,98,6,152,136,154,72,150,
161                   73,127,2,3,1,0,1,48,13,6,9,42,134,72,134,247,13,1,1,11,5,0,3,130,1,1,0,76,
162                   33,54,160,229,219,219,193,150,116,245,252,18,39,235,145,86,12,167,171,52,
163                   117,166,30,83,5,216,245,177,217,247,95,1,136,94,246,212,108,248,230,111,
164                   225,202,189,6,129,8,70,128,245,18,204,215,87,82,129,253,227,122,66,182,184,
165                   189,30,193,169,144,218,216,109,105,110,215,144,60,104,162,178,101,164,218,
166                   122,60,37,41,143,57,150,52,59,51,112,238,113,239,168,114,69,183,143,154,73,
167                   61,58,80,247,172,95,251,55,28,186,28,200,206,230,118,243,92,202,189,49,76,
168                   124,252,76,0,247,112,85,194,69,59,222,163,228,103,49,110,104,109,251,155,
169                   138,9,37,167,49,189,48,134,52,158,185,129,24,96,153,196,251,90,206,76,239,
170                   175,119,174,165,133,108,222,125,237,125,187,149,152,83,190,16,202,94,202,
171                   201,40,218,22,254,63,189,41,174,97,140,203,70,18,196,118,237,175,134,79,78,
172                   246,2,61,54,77,186,112,32,17,193,192,188,217,252,215,200,7,245,180,179,132,
173                   183,212,229,155,15,152,206,135,56,81,88,3,123,244,149,110,182,72,109,70,62,
174                   146,152,146,151,107,126,216,210,9,93,0,0>>],
175
176    {[_Header|Encoded], _} = tls_record_1_3:encode_plain_text(22, PlainText, ConnectionStates),
177    CipherText = #ssl_tls{type = 23, version = {3,3}, fragment = Encoded},
178
179    {#ssl_tls{type = 22, version = {3,4}, fragment = DecodedText}, _} =
180        tls_record_1_3:decode_cipher_text(CipherText, ConnectionStates),
181
182    DecodedText = iolist_to_binary(PlainText),
183    ct:log("Decoded: ~p ~n", [DecodedText]),
184    ok.
185%%--------------------------------------------------------------------
186'1_RTT_handshake'() ->
187     [{doc,"Test TLS 1.3 1-RTT Handshake"}].
188
189'1_RTT_handshake'(_Config) ->
190    %% ConnectionStates with NULL cipher
191    ConnStatesNull =
192       #{current_write =>
193             #{security_parameters =>
194                   #security_parameters{cipher_suite = ?TLS_NULL_WITH_NULL_NULL},
195               sequence_number => 0,
196               max_fragment_length => undefined
197              }
198        },
199
200    %% {client}  construct a ClientHello handshake message:
201    %%
202    %%    ClientHello (196 octets):  01 00 00 c0 03 03 cb 34 ec b1 e7 81 63
203    %%       ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83
204    %%       02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b
205    %%       00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00
206    %%       12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23
207    %%       00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2
208    %%       3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a
209    %%       af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
210    %%       02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06
211    %%       02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
212    %%
213    %% {client}  send handshake record:
214    %%
215    %%    payload (196 octets):  01 00 00 c0 03 03 cb 34 ec b1 e7 81 63 ba
216    %%       1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83 02
217    %%       4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b 00
218    %%       09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00 12
219    %%       00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23 00
220    %%       00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2 3d
221    %%       8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af
222    %%       2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03 02
223    %%       03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06 02
224    %%       02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
225    %%
226    %%    complete record (201 octets):  16 03 01 00 c4 01 00 00 c0 03 03 cb
227    %%       34 ec b1 e7 81 63 ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12
228    %%       ec 18 a2 ef 62 83 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00
229    %%       00 91 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
230    %%       00 00 0a 00 14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02
231    %%       01 03 01 04 00 23 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d
232    %%       e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d
233    %%       54 13 69 1e 52 9a af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e
234    %%       04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02
235    %%       01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
236    ClientHello =
237        hexstr2bin("01 00 00 c0 03 03 cb 34 ec b1 e7 81 63
238          ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12 ec 18 a2 ef 62 83
239          02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00 00 91 00 00 00 0b
240          00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00
241          12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 23
242          00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d e5 60 e4 bd 43 d2
243          3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a
244          af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
245          02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06
246          02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01"),
247
248    ClientHelloRecord =
249        %% Current implementation always sets
250        %% legacy_record_version to Ox0303
251        hexstr2bin("16 03 03 00 c4 01 00 00 c0 03 03 cb
252          34 ec b1 e7 81 63 ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12
253          ec 18 a2 ef 62 83 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00
254          00 91 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
255          00 00 0a 00 14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02
256          01 03 01 04 00 23 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d
257          e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d
258          54 13 69 1e 52 9a af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e
259          04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02
260          01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01"),
261
262    {CHEncrypted, _} =
263	tls_record:encode_handshake(ClientHello, {3,4}, ConnStatesNull),
264    ClientHelloRecord = iolist_to_binary(CHEncrypted),
265
266    %% {server}  extract secret "early":
267    %%
268    %%    salt:  0 (all zero octets)
269    %%
270    %%    IKM (32 octets):  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
271    %%                      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
272    %%
273    %%    secret (32 octets):  33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
274    %%       e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a
275    HKDFAlgo = sha256,
276    Salt = binary:copy(<<?BYTE(0)>>, 32),
277    _IKM = binary:copy(<<?BYTE(0)>>, 32),
278    EarlySecret =
279        hexstr2bin("33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
280          e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a"),
281
282    {early_secret, EarlySecret} = tls_v1:key_schedule(early_secret, HKDFAlgo, {psk, Salt}),
283
284    %% {client}  create an ephemeral x25519 key pair:
285    %%
286    %%    private key (32 octets):  49 af 42 ba 7f 79 94 85 2d 71 3e f2 78
287    %%       4b cb ca a7 91 1d e2 6a dc 56 42 cb 63 45 40 e7 ea 50 05
288    %%
289    %%    public key (32 octets):  99 38 1d e5 60 e4 bd 43 d2 3d 8e 43 5a 7d
290    %%       ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af 2c
291    CPublicKey =
292        hexstr2bin("99 38 1d e5 60 e4 bd 43 d2 3d 8e 43 5a 7d
293          ba fe b3 c0 6e 51 c1 3c ae 4d 54 13 69 1e 52 9a af 2c"),
294
295    %% {server}  create an ephemeral x25519 key pair:
296    %%
297    %%   private key (32 octets):  b1 58 0e ea df 6d d5 89 b8 ef 4f 2d 56
298    %%      52 57 8c c8 10 e9 98 01 91 ec 8d 05 83 08 ce a2 16 a2 1e
299    %%
300    %%   public key (32 octets):  c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6
301    %%      72 e1 56 d6 cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f
302    SPrivateKey =
303        hexstr2bin("b1 58 0e ea df 6d d5 89 b8 ef 4f 2d 56
304         52 57 8c c8 10 e9 98 01 91 ec 8d 05 83 08 ce a2 16 a2 1e"),
305
306    _SPublicKey =
307        hexstr2bin("c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6
308         72 e1 56 d6 cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f"),
309
310    %% {server}  construct a ServerHello handshake message:
311    %%
312    %%    ServerHello (90 octets):  02 00 00 56 03 03 a6 af 06 a4 12 18 60
313    %%       dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e
314    %%       d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88
315    %%       76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1
316    %%       dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
317    ServerHello =
318        hexstr2bin("02 00 00 56 03 03 a6 af 06 a4 12 18 60
319          dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e
320          d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88
321          76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1
322          dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04"),
323
324    %% {server}  derive secret for handshake "tls13 derived":
325    %%
326    %%    PRK (32 octets):  33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c e2
327    %%       10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a
328    %%
329    %%    hash (32 octets):  e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24
330    %%       27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55
331    %%
332    %%    info (49 octets):  00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
333    %%       20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
334    %%       64 9b 93 4c a4 95 99 1b 78 52 b8 55
335    %%
336    %%    expanded (32 octets):  6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba
337    %%       b6 97 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba
338    Hash =
339        hexstr2bin("e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24
340          27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55"),
341
342    Hash = crypto:hash(HKDFAlgo, <<>>),
343
344    Info =
345        hexstr2bin("00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
346          20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
347          64 9b 93 4c a4 95 99 1b 78 52 b8 55"),
348
349    Info = tls_v1:create_info(<<"derived">>, Hash,  ssl_cipher:hash_size(HKDFAlgo)),
350
351    Expanded =
352        hexstr2bin("6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba
353          b6 97 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba"),
354
355    Expanded = tls_v1:derive_secret(EarlySecret, <<"derived">>, <<>>, HKDFAlgo),
356
357    %% {server}  extract secret "handshake":
358    %%
359    %%    salt (32 octets):  6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba b6 97
360    %%       16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba
361    %%
362    %%    IKM (32 octets):  8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
363    %%       35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d
364    %%
365    %%    secret (32 octets):  1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b
366    %%       01 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
367
368    %% salt = Expanded
369    HandshakeIKM =
370        hexstr2bin("8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
371          35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d"),
372
373    HandshakeSecret =
374        hexstr2bin("1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b
375          01 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac"),
376
377    HandshakeIKM = crypto:compute_key(ecdh, CPublicKey, SPrivateKey, x25519),
378
379    {handshake_secret, HandshakeSecret} =
380        tls_v1:key_schedule(handshake_secret, HKDFAlgo, HandshakeIKM,
381                            {early_secret, EarlySecret}),
382
383    %% {server}  derive secret "tls13 c hs traffic":
384    %%
385    %%    PRK (32 octets):  1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
386    %%       04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
387    %%
388    %%    hash (32 octets):  86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
389    %%       d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
390    %%
391    %%    info (54 octets):  00 20 12 74 6c 73 31 33 20 63 20 68 73 20 74 72
392    %%       61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
393    %%       ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
394    %%
395    %%    expanded (32 octets):  b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e
396    %%       2d 8f 3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21
397
398    %% PRK = HandshakeSecret
399    CHSTHash =
400        hexstr2bin("86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
401          d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"),
402
403    CHSTInfo =
404        hexstr2bin("00 20 12 74 6c 73 31 33 20 63 20 68 73 20 74 72
405          61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
406          ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"),
407
408    CHSTrafficSecret =
409        hexstr2bin(" b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e
410          2d 8f 3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21"),
411
412    CHSH =  <<ClientHello/binary,ServerHello/binary>>,
413    CHSTHash = crypto:hash(HKDFAlgo, CHSH),
414    CHSTInfo =  tls_v1:create_info(<<"c hs traffic">>, CHSTHash,  ssl_cipher:hash_size(HKDFAlgo)),
415
416    CHSTrafficSecret =
417        tls_v1:client_handshake_traffic_secret(HKDFAlgo, {handshake_secret, HandshakeSecret}, CHSH),
418
419    %% {server}  derive secret "tls13 s hs traffic":
420    %%
421    %%    PRK (32 octets):  1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
422    %%       04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
423    %%
424    %%    hash (32 octets):  86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58 ed
425    %%       d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
426    %%
427    %%    info (54 octets):  00 20 12 74 6c 73 31 33 20 73 20 68 73 20 74 72
428    %%       61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
429    %%       ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8
430    %%
431    %%    expanded (32 octets):  b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d
432    %%       37 b4 e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
433
434    %% PRK = HandshakeSecret
435    %% hash = CHSTHash
436    SHSTInfo =
437        hexstr2bin("00 20 12 74 6c 73 31 33 20 73 20 68 73 20 74 72
438          61 66 66 69 63 20 86 0c 06 ed c0 78 58 ee 8e 78 f0 e7 42 8c 58
439          ed d6 b4 3f 2c a3 e6 e9 5f 02 ed 06 3c f0 e1 ca d8"),
440
441    SHSTrafficSecret =
442        hexstr2bin("b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d
443          37 b4 e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38"),
444
445    SHSTInfo =  tls_v1:create_info(<<"s hs traffic">>, CHSTHash,  ssl_cipher:hash_size(HKDFAlgo)),
446
447    SHSTrafficSecret =
448        tls_v1:server_handshake_traffic_secret(HKDFAlgo, {handshake_secret, HandshakeSecret}, CHSH),
449
450
451    %% {server}  derive secret for master "tls13 derived":
452    %%
453    %%    PRK (32 octets):  1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b 01
454    %%       04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac
455    %%
456    %%    hash (32 octets):  e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24
457    %%       27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55
458    %%
459    %%    info (49 octets):  00 20 0d 74 6c 73 31 33 20 64 65 72 69 76 65 64
460    %%       20 e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
461    %%       64 9b 93 4c a4 95 99 1b 78 52 b8 55
462    %%
463    %%    expanded (32 octets):  43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25
464    %%       90 b5 31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4
465
466    %% PRK = HandshakeSecret
467    %% hash = Hash
468    %% info = Info
469    MasterDeriveSecret =
470        hexstr2bin("43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25
471          90 b5 31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4"),
472
473    MasterDeriveSecret = tls_v1:derive_secret(HandshakeSecret, <<"derived">>, <<>>, HKDFAlgo),
474
475    %% {server}  extract secret "master":
476    %%
477    %%    salt (32 octets):  43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25 90 b5
478    %%       31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4
479    %%
480    %%    IKM (32 octets):  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
481    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
482    %%
483    %%    secret (32 octets):  18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a
484    %%       47 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
485
486    %% salt = MasterDeriveSecret
487    %% IKM = IKM
488    MasterSecret =
489        hexstr2bin("18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a
490          47 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19"),
491
492    {master_secret, MasterSecret} =
493        tls_v1:key_schedule(master_secret, HKDFAlgo, {handshake_secret, HandshakeSecret}),
494
495    %% {server}  send handshake record:
496    %%
497    %%    payload (90 octets):  02 00 00 56 03 03 a6 af 06 a4 12 18 60 dc 5e
498    %%       6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14 34 da c1 55 77 2e d3 e2
499    %%       69 28 00 13 01 00 00 2e 00 33 00 24 00 1d 00 20 c9 82 88 76 11
500    %%       20 95 fe 66 76 2b db f7 c6 72 e1 56 d6 cc 25 3b 83 3d f1 dd 69
501    %%       b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
502    %%
503    %%    complete record (95 octets):  16 03 03 00 5a 02 00 00 56 03 03 a6
504    %%       af 06 a4 12 18 60 dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14
505    %%       34 da c1 55 77 2e d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00
506    %%       1d 00 20 c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6
507    %%       cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04
508
509    %% payload = ServerHello
510    ServerHelloRecord =
511        hexstr2bin("16 03 03 00 5a 02 00 00 56 03 03 a6
512          af 06 a4 12 18 60 dc 5e 6e 60 24 9c d3 4c 95 93 0c 8a c5 cb 14
513          34 da c1 55 77 2e d3 e2 69 28 00 13 01 00 00 2e 00 33 00 24 00
514          1d 00 20 c9 82 88 76 11 20 95 fe 66 76 2b db f7 c6 72 e1 56 d6
515          cc 25 3b 83 3d f1 dd 69 b1 b0 4e 75 1f 0f 00 2b 00 02 03 04"),
516
517    {SHEncrypted, _} =
518	tls_record:encode_handshake(ServerHello, {3,4}, ConnStatesNull),
519    ServerHelloRecord = iolist_to_binary(SHEncrypted),
520
521    %% {server}  derive write traffic keys for handshake data:
522    %%
523    %%    PRK (32 octets):  b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d 37 b4
524    %%       e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
525    %%
526    %%    key info (13 octets):  00 10 09 74 6c 73 31 33 20 6b 65 79 00
527    %%
528    %%    key expanded (16 octets):  3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e
529    %%       e4 03 bc
530    %%
531    %%    iv info (12 octets):  00 0c 08 74 6c 73 31 33 20 69 76 00
532    %%
533    %%    iv expanded (12 octets):  5d 31 3e b2 67 12 76 ee 13 00 0b 30
534
535    %% PRK = SHSTrafficSecret
536    WriteKeyInfo =
537        hexstr2bin("00 10 09 74 6c 73 31 33 20 6b 65 79 00"),
538
539    WriteKey =
540        hexstr2bin("3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e e4 03 bc"),
541
542    WriteIVInfo =
543        hexstr2bin("00 0c 08 74 6c 73 31 33 20 69 76 00"),
544
545    WriteIV =
546        hexstr2bin(" 5d 31 3e b2 67 12 76 ee 13 00 0b 30"),
547
548    Cipher = aes_128_gcm, %% TODO: get from ServerHello
549
550    WriteKeyInfo = tls_v1:create_info(<<"key">>, <<>>,  ssl_cipher:key_material(Cipher)),
551    %% TODO: remove hardcoded IV size
552    WriteIVInfo = tls_v1:create_info(<<"iv">>, <<>>,  12),
553
554    KeyLength = ssl_cipher:key_material(Cipher),
555    {WriteKey, WriteIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, KeyLength, SHSTrafficSecret),
556
557    %% {server}  construct an EncryptedExtensions handshake message:
558    %%
559    %%    EncryptedExtensions (40 octets):  08 00 00 24 00 22 00 0a 00 14 00
560    %%       12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c
561    %%       00 02 40 01 00 00 00 00
562    %%
563    %% {server}  construct a Certificate handshake message:
564    %%
565    %%    Certificate (445 octets):  0b 00 01 b9 00 00 01 b5 00 01 b0 30 82
566    %%       01 ac 30 82 01 15 a0 03 02 01 02 02 01 02 30 0d 06 09 2a 86 48
567    %%       86 f7 0d 01 01 0b 05 00 30 0e 31 0c 30 0a 06 03 55 04 03 13 03
568    %%       72 73 61 30 1e 17 0d 31 36 30 37 33 30 30 31 32 33 35 39 5a 17
569    %%       0d 32 36 30 37 33 30 30 31 32 33 35 39 5a 30 0e 31 0c 30 0a 06
570    %%       03 55 04 03 13 03 72 73 61 30 81 9f 30 0d 06 09 2a 86 48 86 f7
571    %%       0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 b4 bb 49 8f
572    %%       82 79 30 3d 98 08 36 39 9b 36 c6 98 8c 0c 68 de 55 e1 bd b8 26
573    %%       d3 90 1a 24 61 ea fd 2d e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c
574    %%       1a f1 9e aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0 cc b0 52
575    %%       4b 1b 01 8c 3e 0b 63 26 4d 44 9a 6d 38 e2 2a 5f da 43 08 46 74
576    %%       80 30 53 0e f0 46 1c 8c a9 d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93
577    %%       ef f0 ab 9a 80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f 02 03
578    %%       01 00 01 a3 1a 30 18 30 09 06 03 55 1d 13 04 02 30 00 30 0b 06
579    %%       03 55 1d 0f 04 04 03 02 05 a0 30 0d 06 09 2a 86 48 86 f7 0d 01
580    %%       01 0b 05 00 03 81 81 00 85 aa d2 a0 e5 b9 27 6b 90 8c 65 f7 3a
581    %%       72 67 17 06 18 a5 4c 5f 8a 7b 33 7d 2d f7 a5 94 36 54 17 f2 ea
582    %%       e8 f8 a5 8c 8f 81 72 f9 31 9c f3 6b 7f d6 c5 5b 80 f2 1a 03 01
583    %%       51 56 72 60 96 fd 33 5e 5e 67 f2 db f1 02 70 2e 60 8c ca e6 be
584    %%       c1 fc 63 a4 2a 99 be 5c 3e b7 10 7c 3c 54 e9 b9 eb 2b d5 20 3b
585    %%       1c 3b 84 e0 a8 b2 f7 59 40 9b a3 ea c9 d9 1d 40 2d cc 0c c8 f8
586    %%       96 12 29 ac 91 87 b4 2b 4d e1 00 00
587    %%
588    %% {server}  construct a CertificateVerify handshake message:
589    %%
590    %%    CertificateVerify (136 octets):  0f 00 00 84 08 04 00 80 5a 74 7c
591    %%       5d 88 fa 9b d2 e5 5a b0 85 a6 10 15 b7 21 1f 82 4c d4 84 14 5a
592    %%       b3 ff 52 f1 fd a8 47 7b 0b 7a bc 90 db 78 e2 d3 3a 5c 14 1a 07
593    %%       86 53 fa 6b ef 78 0c 5e a2 48 ee aa a7 85 c4 f3 94 ca b6 d3 0b
594    %%       be 8d 48 59 ee 51 1f 60 29 57 b1 54 11 ac 02 76 71 45 9e 46 44
595    %%       5c 9e a5 8c 18 1e 81 8e 95 b8 c3 fb 0b f3 27 84 09 d3 be 15 2a
596    %%       3d a5 04 3e 06 3d da 65 cd f5 ae a2 0d 53 df ac d4 2f 74 f3
597    EncryptedExtensions =
598        hexstr2bin("08 00 00 24 00 22 00 0a 00 14 00
599          12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 1c
600          00 02 40 01 00 00 00 00"),
601
602    Certificate =
603        hexstr2bin("0b 00 01 b9 00 00 01 b5 00 01 b0 30 82
604          01 ac 30 82 01 15 a0 03 02 01 02 02 01 02 30 0d 06 09 2a 86 48
605          86 f7 0d 01 01 0b 05 00 30 0e 31 0c 30 0a 06 03 55 04 03 13 03
606          72 73 61 30 1e 17 0d 31 36 30 37 33 30 30 31 32 33 35 39 5a 17
607          0d 32 36 30 37 33 30 30 31 32 33 35 39 5a 30 0e 31 0c 30 0a 06
608          03 55 04 03 13 03 72 73 61 30 81 9f 30 0d 06 09 2a 86 48 86 f7
609          0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 b4 bb 49 8f
610          82 79 30 3d 98 08 36 39 9b 36 c6 98 8c 0c 68 de 55 e1 bd b8 26
611          d3 90 1a 24 61 ea fd 2d e4 9a 91 d0 15 ab bc 9a 95 13 7a ce 6c
612          1a f1 9e aa 6a f9 8c 7c ed 43 12 09 98 e1 87 a8 0e e0 cc b0 52
613          4b 1b 01 8c 3e 0b 63 26 4d 44 9a 6d 38 e2 2a 5f da 43 08 46 74
614          80 30 53 0e f0 46 1c 8c a9 d9 ef bf ae 8e a6 d1 d0 3e 2b d1 93
615          ef f0 ab 9a 80 02 c4 74 28 a6 d3 5a 8d 88 d7 9f 7f 1e 3f 02 03
616          01 00 01 a3 1a 30 18 30 09 06 03 55 1d 13 04 02 30 00 30 0b 06
617          03 55 1d 0f 04 04 03 02 05 a0 30 0d 06 09 2a 86 48 86 f7 0d 01
618          01 0b 05 00 03 81 81 00 85 aa d2 a0 e5 b9 27 6b 90 8c 65 f7 3a
619          72 67 17 06 18 a5 4c 5f 8a 7b 33 7d 2d f7 a5 94 36 54 17 f2 ea
620          e8 f8 a5 8c 8f 81 72 f9 31 9c f3 6b 7f d6 c5 5b 80 f2 1a 03 01
621          51 56 72 60 96 fd 33 5e 5e 67 f2 db f1 02 70 2e 60 8c ca e6 be
622          c1 fc 63 a4 2a 99 be 5c 3e b7 10 7c 3c 54 e9 b9 eb 2b d5 20 3b
623          1c 3b 84 e0 a8 b2 f7 59 40 9b a3 ea c9 d9 1d 40 2d cc 0c c8 f8
624          96 12 29 ac 91 87 b4 2b 4d e1 00 00"),
625
626    CertificateVerify =
627        hexstr2bin("0f 00 00 84 08 04 00 80 5a 74 7c
628          5d 88 fa 9b d2 e5 5a b0 85 a6 10 15 b7 21 1f 82 4c d4 84 14 5a
629          b3 ff 52 f1 fd a8 47 7b 0b 7a bc 90 db 78 e2 d3 3a 5c 14 1a 07
630          86 53 fa 6b ef 78 0c 5e a2 48 ee aa a7 85 c4 f3 94 ca b6 d3 0b
631          be 8d 48 59 ee 51 1f 60 29 57 b1 54 11 ac 02 76 71 45 9e 46 44
632          5c 9e a5 8c 18 1e 81 8e 95 b8 c3 fb 0b f3 27 84 09 d3 be 15 2a
633          3d a5 04 3e 06 3d da 65 cd f5 ae a2 0d 53 df ac d4 2f 74 f3"),
634
635    %% {server}  calculate finished "tls13 finished":
636    %%
637    %%    PRK (32 octets):  b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d 37 b4
638    %%       e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38
639    %%
640    %%    hash (0 octets):  (empty)
641    %%
642    %%    info (18 octets):  00 20 0e 74 6c 73 31 33 20 66 69 6e 69 73 68 65
643    %%       64 00
644    %%
645    %%    expanded (32 octets):  00 8d 3b 66 f8 16 ea 55 9f 96 b5 37 e8 85
646    %%       c3 1f c0 68 bf 49 2c 65 2f 01 f2 88 a1 d8 cd c1 9f c8
647    %%
648    %%    finished (32 octets):  9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4
649    %%       de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18
650
651    %% PRK = SHSTrafficSecret
652    FInfo =
653        hexstr2bin("00 20 0e 74 6c 73 31 33 20 66 69 6e 69 73 68 65
654          64 00"),
655
656    FExpanded =
657        hexstr2bin("00 8d 3b 66 f8 16 ea 55 9f 96 b5 37 e8 85
658          c3 1f c0 68 bf 49 2c 65 2f 01 f2 88 a1 d8 cd c1 9f c8"),
659
660    FinishedVerifyData =
661        hexstr2bin("9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4
662          de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18"),
663
664    FInfo = tls_v1:create_info(<<"finished">>, <<>>,  ssl_cipher:hash_size(HKDFAlgo)),
665
666    FExpanded = tls_v1:finished_key(SHSTrafficSecret, HKDFAlgo),
667
668    MessageHistory0 = [CertificateVerify,
669                       Certificate,
670                       EncryptedExtensions,
671                       ServerHello,
672                       ClientHello],
673
674    FinishedVerifyData = tls_v1:finished_verify_data(FExpanded, HKDFAlgo, MessageHistory0),
675
676    %% {server}  construct a Finished handshake message:
677    %%
678    %%    Finished (36 octets):  14 00 00 20 9b 9b 14 1d 90 63 37 fb d2 cb
679    %%       dc e7 1d f4 de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07
680    %%       18
681    FinishedHSBin =
682        hexstr2bin("14 00 00 20 9b 9b 14 1d 90 63 37 fb d2 cb
683          dc e7 1d f4 de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07
684          18"),
685
686    FinishedHS = #finished{verify_data = FinishedVerifyData},
687
688    FinishedIOList = tls_handshake:encode_handshake(FinishedHS, {3,4}),
689    FinishedHSBin = iolist_to_binary(FinishedIOList),
690
691    %% {server}  derive secret "tls13 c ap traffic":
692    %%
693    %%    PRK (32 octets):  18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
694    %%       80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
695    %%
696    %%    hash (32 octets):  96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
697    %%       00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
698    %%
699    %%    info (54 octets):  00 20 12 74 6c 73 31 33 20 63 20 61 70 20 74 72
700    %%       61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
701    %%       1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
702    %%
703    %%    expanded (32 octets):  9e 40 64 6c e7 9a 7f 9d c0 5a f8 88 9b ce
704    %%       65 52 87 5a fa 0b 06 df 00 87 f7 92 eb b7 c1 75 04 a5
705
706    %% PRK = MasterSecret
707    CAPTHash =
708        hexstr2bin("96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
709          00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
710    CAPTInfo =
711        hexstr2bin("00 20 12 74 6c 73 31 33 20 63 20 61 70 20 74 72
712          61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
713          1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
714
715    CAPTrafficSecret =
716        hexstr2bin("9e 40 64 6c e7 9a 7f 9d c0 5a f8 88 9b ce
717          65 52 87 5a fa 0b 06 df 00 87 f7 92 eb b7 c1 75 04 a5"),
718
719    CHSF = <<ClientHello/binary,
720             ServerHello/binary,
721             EncryptedExtensions/binary,
722             Certificate/binary,
723             CertificateVerify/binary,
724             FinishedHSBin/binary>>,
725
726    CAPTHash = crypto:hash(HKDFAlgo, CHSF),
727
728    CAPTInfo =
729        tls_v1:create_info(<<"c ap traffic">>, CAPTHash, ssl_cipher:hash_size(HKDFAlgo)),
730
731    CAPTrafficSecret =
732        tls_v1:client_application_traffic_secret_0(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
733
734    %% {server}  derive secret "tls13 s ap traffic":
735    %%
736    %%    PRK (32 octets):  18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
737    %%       80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
738    %%
739    %%    hash (32 octets):  96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
740    %%       00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
741    %%
742    %%    info (54 octets):  00 20 12 74 6c 73 31 33 20 73 20 61 70 20 74 72
743    %%       61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
744    %%       1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
745    %%
746    %%    expanded (32 octets):  a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9
747    %%       50 32 82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43
748
749    %% PRK = MasterSecret
750    %% hash = CAPTHash
751    SAPTInfo =
752        hexstr2bin(" 00 20 12 74 6c 73 31 33 20 73 20 61 70 20 74 72
753          61 66 66 69 63 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b
754          1a 00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
755
756    SAPTrafficSecret =
757        hexstr2bin("a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9
758          50 32 82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43"),
759
760    SAPTInfo =
761        tls_v1:create_info(<<"s ap traffic">>, CAPTHash, ssl_cipher:hash_size(HKDFAlgo)),
762
763    SAPTrafficSecret =
764        tls_v1:server_application_traffic_secret_0(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
765
766    %% Resumption master secret from '0-RTT'
767    %%
768    %% {server}  generate resumption secret "tls13 resumption":
769    %%
770    %%    PRK (32 octets):  7d f2 35 f2 03 1d 2a 05 12 87 d0 2b 02 41 b0 bf
771    %%       da f8 6c c8 56 23 1f 2d 5a ba 46 c4 34 ec 19 6c
772    %%
773    _RMS = hexstr2bin("7d f2 35 f2 03 1d 2a 05 12 87 d0 2b 02 41 b0 bf
774                      da f8 6c c8 56 23 1f 2d 5a ba 46 c4 34 ec 19 6c"),
775
776    %% Verify calculation of resumption master secret that is used to create
777    %% the pre shared key in '0-RTT'.
778    _Temp = tls_v1:resumption_master_secret(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
779
780    %% {server}  derive secret "tls13 exp master":
781    %%
782    %%    PRK (32 octets):  18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
783    %%       80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
784    %%
785    %%    hash (32 octets):  96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a
786    %%       00 0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
787    %%
788    %%    info (52 octets):  00 20 10 74 6c 73 31 33 20 65 78 70 20 6d 61 73
789    %%       74 65 72 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a 00
790    %%       0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13
791    %%
792    %%    expanded (32 octets):  fe 22 f8 81 17 6e da 18 eb 8f 44 52 9e 67
793    %%       92 c5 0c 9a 3f 89 45 2f 68 d8 ae 31 1b 43 09 d3 cf 50
794
795    %% PRK = MasterSecret
796    %% hash = CAPTHash
797    ExporterInfo =
798        hexstr2bin("00 20 10 74 6c 73 31 33 20 65 78 70 20 6d 61 73
799          74 65 72 20 96 08 10 2a 0f 1c cc 6d b6 25 0b 7b 7e 41 7b 1a 00
800          0e aa da 3d aa e4 77 7a 76 86 c9 ff 83 df 13"),
801
802    ExporterMasterSecret =
803        hexstr2bin("fe 22 f8 81 17 6e da 18 eb 8f 44 52 9e 67
804          92 c5 0c 9a 3f 89 45 2f 68 d8 ae 31 1b 43 09 d3 cf 50"),
805
806    ExporterInfo =
807        tls_v1:create_info(<<"exp master">>, CAPTHash, ssl_cipher:hash_size(HKDFAlgo)),
808
809    ExporterMasterSecret =
810        tls_v1:exporter_master_secret(HKDFAlgo, {master_secret, MasterSecret}, CHSF),
811
812    %% {server}  derive write traffic keys for application data:
813    %%
814    %%    PRK (32 octets):  a1 1a f9 f0 55 31 f8 56 ad 47 11 6b 45 a9 50 32
815    %%       82 04 b4 f4 4b fb 6b 3a 4b 4f 1f 3f cb 63 16 43
816    %%
817    %%    key info (13 octets):  00 10 09 74 6c 73 31 33 20 6b 65 79 00
818    %%
819    %%    key expanded (16 octets):  9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac
820    %%       92 e3 56
821    %%
822    %%    iv info (12 octets):  00 0c 08 74 6c 73 31 33 20 69 76 00
823    %%
824    %%    iv expanded (12 octets):  cf 78 2b 88 dd 83 54 9a ad f1 e9 84
825
826    %% PRK = SAPTrafficsecret
827    %% key info = WriteKeyInfo
828    %% iv info = WriteIVInfo
829    SWKey =
830        hexstr2bin("9f 02 28 3b 6c 9c 07 ef c2 6b b9 f2 ac 92 e3 56"),
831
832    SWIV =
833        hexstr2bin("cf 78 2b 88 dd 83 54 9a ad f1 e9 84"),
834
835    {SWKey, SWIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, KeyLength, SAPTrafficSecret),
836
837    %% {server}  derive read traffic keys for handshake data:
838    %%
839    %%    PRK (32 octets):  b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e 2d 8f
840    %%       3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21
841    %%
842    %%    key info (13 octets):  00 10 09 74 6c 73 31 33 20 6b 65 79 00
843    %%
844    %%    key expanded (16 octets):  db fa a6 93 d1 76 2c 5b 66 6a f5 d9 50
845    %%       25 8d 01
846    %%
847    %%    iv info (12 octets):  00 0c 08 74 6c 73 31 33 20 69 76 00
848    %%
849    %%    iv expanded (12 octets):  5b d3 c7 1b 83 6e 0b 76 bb 73 26 5f
850
851    %% PRK = CHSTrafficsecret
852    %% key info = WriteKeyInfo
853    %% iv info = WrtieIVInfo
854    SRKey =
855        hexstr2bin("db fa a6 93 d1 76 2c 5b 66 6a f5 d9 50 25 8d 01"),
856
857    SRIV =
858        hexstr2bin("5b d3 c7 1b 83 6e 0b 76 bb 73 26 5f"),
859
860    {SRKey, SRIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, KeyLength, CHSTrafficSecret),
861
862    %% {client}  calculate finished "tls13 finished":
863    %%
864    %%    PRK (32 octets):  b3 ed db 12 6e 06 7f 35 a7 80 b3 ab f4 5e 2d 8f
865    %%       3b 1a 95 07 38 f5 2e 96 00 74 6a 0e 27 a5 5a 21
866    %%
867    %%    hash (0 octets):  (empty)
868    %%
869    %%    info (18 octets):  00 20 0e 74 6c 73 31 33 20 66 69 6e 69 73 68 65
870    %%       64 00
871    %%
872    %%    expanded (32 octets):  b8 0a d0 10 15 fb 2f 0b d6 5f f7 d4 da 5d
873    %%       6b f8 3f 84 82 1d 1f 87 fd c7 d3 c7 5b 5a 7b 42 d9 c4
874    %%
875    %%    finished (32 octets):  a8 ec 43 6d 67 76 34 ae 52 5a c1 fc eb e1
876    %%       1a 03 9e c1 76 94 fa c6 e9 85 27 b6 42 f2 ed d5 ce 61
877
878    %% PRK = CHSTrafficsecret
879    %% info = FInfo
880    CFExpanded =
881        hexstr2bin("b8 0a d0 10 15 fb 2f 0b d6 5f f7 d4 da 5d
882        6b f8 3f 84 82 1d 1f 87 fd c7 d3 c7 5b 5a 7b 42 d9 c4"),
883
884    CFinishedVerifyData =
885        hexstr2bin("a8 ec 43 6d 67 76 34 ae 52 5a c1 fc eb e1
886        1a 03 9e c1 76 94 fa c6 e9 85 27 b6 42 f2 ed d5 ce 61"),
887
888    MessageHistory1 = [FinishedHSBin,
889                       CertificateVerify,
890                       Certificate,
891                       EncryptedExtensions,
892                       ServerHello,
893                       ClientHello],
894
895    CFExpanded = tls_v1:finished_key(CHSTrafficSecret, HKDFAlgo),
896    CFinishedVerifyData = tls_v1:finished_verify_data(CFExpanded, HKDFAlgo, MessageHistory1),
897
898    %% {client}  construct a Finished handshake message:
899    %%
900    %%    Finished (36 octets):  14 00 00 20 a8 ec 43 6d 67 76 34 ae 52 5a
901    %%       c1 fc eb e1 1a 03 9e c1 76 94 fa c6 e9 85 27 b6 42 f2 ed d5 ce
902    %%       61
903    CFinishedBin =
904        hexstr2bin("14 00 00 20 a8 ec 43 6d 67 76 34 ae 52 5a
905          c1 fc eb e1 1a 03 9e c1 76 94 fa c6 e9 85 27 b6 42 f2 ed d5 ce
906          61"),
907
908    CFinished = #finished{verify_data = CFinishedVerifyData},
909
910    CFinishedIOList = tls_handshake:encode_handshake(CFinished, {3,4}),
911    CFinishedBin = iolist_to_binary(CFinishedIOList),
912
913    %% {client}  derive write traffic keys for application data:
914    %%
915    %%    PRK (32 octets):  9e 40 64 6c e7 9a 7f 9d c0 5a f8 88 9b ce 65 52
916    %%       87 5a fa 0b 06 df 00 87 f7 92 eb b7 c1 75 04 a5
917    %%
918    %%    key info (13 octets):  00 10 09 74 6c 73 31 33 20 6b 65 79 00
919    %%
920    %%    key expanded (16 octets):  17 42 2d da 59 6e d5 d9 ac d8 90 e3 c6
921    %%       3f 50 51
922    %%
923    %%    iv info (12 octets):  00 0c 08 74 6c 73 31 33 20 69 76 00
924    %%
925    %%    iv expanded (12 octets):  5b 78 92 3d ee 08 57 90 33 e5 23 d9
926
927    %% PRK = CAPTrafficsecret
928    %% key info = WriteKeyInfo
929    %% iv info = WriteIVInfo
930
931    CWKey =
932        hexstr2bin("17 42 2d da 59 6e d5 d9 ac d8 90 e3 c6 3f 50 51"),
933
934    CWIV =
935        hexstr2bin("5b 78 92 3d ee 08 57 90 33 e5 23 d9"),
936
937    {CWKey, CWIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, KeyLength, CAPTrafficSecret),
938
939    %% {client}  derive secret "tls13 res master":
940    %%
941    %%    PRK (32 octets):  18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a 47
942    %%       80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19
943    %%
944    %%    hash (32 octets):  20 91 45 a9 6e e8 e2 a1 22 ff 81 00 47 cc 95 26
945    %%       84 65 8d 60 49 e8 64 29 42 6d b8 7c 54 ad 14 3d
946    %%
947    %%    info (52 octets):  00 20 10 74 6c 73 31 33 20 72 65 73 20 6d 61 73
948    %%       74 65 72 20 20 91 45 a9 6e e8 e2 a1 22 ff 81 00 47 cc 95 26 84
949    %%       65 8d 60 49 e8 64 29 42 6d b8 7c 54 ad 14 3d
950    %%
951    %%    expanded (32 octets):  7d f2 35 f2 03 1d 2a 05 12 87 d0 2b 02 41
952    %%       b0 bf da f8 6c c8 56 23 1f 2d 5a ba 46 c4 34 ec 19 6c
953
954    %% PRK = MasterSecret
955
956    CRMHash = hexstr2bin("20 91 45 a9 6e e8 e2 a1 22 ff 81 00 47 cc 95 26
957                          84 65 8d 60 49 e8 64 29 42 6d b8 7c 54 ad 14 3d"),
958
959    CRMInfo = hexstr2bin(" 00 20 10 74 6c 73 31 33 20 72 65 73 20 6d 61 73
960            74 65 72 20 20 91 45 a9 6e e8 e2 a1 22 ff 81 00 47 cc 95 26 84
961            65 8d 60 49 e8 64 29 42 6d b8 7c 54 ad 14 3d"),
962
963    ResumptionMasterSecret = hexstr2bin("7d f2 35 f2 03 1d 2a 05 12 87 d0 2b 02 41
964                             b0 bf da f8 6c c8 56 23 1f 2d 5a ba 46 c4 34 ec 19 6c"),
965
966    CHCF = <<ClientHello/binary,
967             ServerHello/binary,
968             EncryptedExtensions/binary,
969             Certificate/binary,
970             CertificateVerify/binary,
971             FinishedHSBin/binary,
972             CFinishedBin/binary>>,
973
974    MessageHistory3 = [ClientHello,
975                       ServerHello,
976                       EncryptedExtensions,
977                       Certificate,
978                       CertificateVerify,
979                       FinishedHSBin,
980                       CFinishedBin
981                       ],
982
983    CRMHash = crypto:hash(HKDFAlgo, CHCF),
984
985    CRMInfo =
986        tls_v1:create_info(<<"res master">>, CRMHash, ssl_cipher:hash_size(HKDFAlgo)),
987
988    ResumptionMasterSecret =
989        tls_v1:resumption_master_secret(HKDFAlgo, {master_secret, MasterSecret}, MessageHistory3),
990    ok.
991
992%%--------------------------------------------------------------------
993'0_RTT_handshake'() ->
994     [{doc,"Test TLS 1.3 0-RTT Handshake"}].
995
996'0_RTT_handshake'(_Config) ->
997    HKDFAlgo = sha256,
998
999    %% {server}  generate resumption secret "tls13 resumption":
1000    %%
1001    %%    PRK (32 octets):  7d f2 35 f2 03 1d 2a 05 12 87 d0 2b 02 41 b0 bf
1002    %%       da f8 6c c8 56 23 1f 2d 5a ba 46 c4 34 ec 19 6c
1003    %%
1004    %%    hash (2 octets):  00 00
1005    %%
1006    %%    info (22 octets):  00 20 10 74 6c 73 31 33 20 72 65 73 75 6d 70 74
1007    %%       69 6f 6e 02 00 00
1008    %%
1009    %%    expanded (32 octets):  4e cd 0e b6 ec 3b 4d 87 f5 d6 02 8f 92 2c
1010    %%       a4 c5 85 1a 27 7f d4 13 11 c9 e6 2d 2c 94 92 e1 c4 f3
1011    %%
1012    %% {server}  construct a NewSessionTicket handshake message:
1013    %%
1014    %%    NewSessionTicket (205 octets):  04 00 00 c9 00 00 00 1e fa d6 aa
1015    %%       c5 02 00 00 00 b2 2c 03 5d 82 93 59 ee 5f f7 af 4e c9 00 00 00
1016    %%       00 26 2a 64 94 dc 48 6d 2c 8a 34 cb 33 fa 90 bf 1b 00 70 ad 3c
1017    %%       49 88 83 c9 36 7c 09 a2 be 78 5a bc 55 cd 22 60 97 a3 a9 82 11
1018    %%       72 83 f8 2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61 be 7f d6 1d 28
1019    %%       27 db 27 9c ce 14 50 77 d4 54 a3 66 4d 4e 6d a4 d2 9e e0 37 25
1020    %%       a6 a4 da fc d0 fc 67 d2 ae a7 05 29 51 3e 3d a2 67 7f a5 90 6c
1021    %%       5b 3f 7d 8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb f2 97 b5 ae a6
1022    %%       17 64 6f ac 5c 03 27 2e 97 07 27 c6 21 a7 91 41 ef 5f 7d e6 50
1023    %%       5e 5b fb c3 88 e9 33 43 69 40 93 93 4a e4 d3 57 00 08 00 2a 00
1024    %%       04 00 00 04 00
1025    ResPRK =
1026        hexstr2bin("7d f2 35 f2 03 1d 2a 05 12 87 d0 2b 02 41 b0 bf
1027                    da f8 6c c8 56 23 1f 2d 5a ba 46 c4 34 ec 19 6c"),
1028
1029    _ResHash = hexstr2bin("00 00"),
1030
1031    _ResInfo = hexstr2bin("00 20 10 74 6c 73 31 33 20 72 65 73 75 6d 70 74
1032                           69 6f 6e 02 00 00"),
1033
1034    ResExpanded =
1035        hexstr2bin("4e cd 0e b6 ec 3b 4d 87 f5 d6 02 8f 92 2c
1036        a4 c5 85 1a 27 7f d4 13 11 c9 e6 2d 2c 94 92 e1 c4 f3"),
1037
1038    NewSessionTicket =
1039        hexstr2bin("04 00 00 c9 00 00 00 1e fa d6 aa
1040          c5 02 00 00 00 b2 2c 03 5d 82 93 59 ee 5f f7 af 4e c9 00 00 00
1041          00 26 2a 64 94 dc 48 6d 2c 8a 34 cb 33 fa 90 bf 1b 00 70 ad 3c
1042          49 88 83 c9 36 7c 09 a2 be 78 5a bc 55 cd 22 60 97 a3 a9 82 11
1043          72 83 f8 2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61 be 7f d6 1d 28
1044          27 db 27 9c ce 14 50 77 d4 54 a3 66 4d 4e 6d a4 d2 9e e0 37 25
1045          a6 a4 da fc d0 fc 67 d2 ae a7 05 29 51 3e 3d a2 67 7f a5 90 6c
1046          5b 3f 7d 8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb f2 97 b5 ae a6
1047          17 64 6f ac 5c 03 27 2e 97 07 27 c6 21 a7 91 41 ef 5f 7d e6 50
1048          5e 5b fb c3 88 e9 33 43 69 40 93 93 4a e4 d3 57 00 08 00 2a 00
1049          04 00 00 04 00"),
1050    <<?BYTE(NWT), ?UINT24(_), TicketBody/binary>> = NewSessionTicket,
1051    #new_session_ticket{
1052       ticket_lifetime = _LifeTime,
1053       ticket_age_add = _AgeAdd,
1054       ticket_nonce = Nonce,
1055       ticket = Ticket,
1056       extensions = _Extensions
1057      } = tls_handshake:decode_handshake({3,4}, NWT, TicketBody),
1058
1059    %% ResPRK = resumption master secret
1060    ResExpanded = tls_v1:pre_shared_key(ResPRK, Nonce, HKDFAlgo),
1061
1062    %% {client}  create an ephemeral x25519 key pair:
1063    %%
1064    %%    private key (32 octets):  bf f9 11 88 28 38 46 dd 6a 21 34 ef 71
1065    %%       80 ca 2b 0b 14 fb 10 dc e7 07 b5 09 8c 0d dd c8 13 b2 df
1066    %%
1067    %%    public key (32 octets):  e4 ff b6 8a c0 5f 8d 96 c9 9d a2 66 98 34
1068    %%       6c 6b e1 64 82 ba dd da fe 05 1a 66 b4 f1 8d 66 8f 0b
1069    %%
1070    %% {client}  extract secret "early":
1071    %%
1072    %%    salt:  0 (all zero octets)
1073    %%
1074    %%    IKM (32 octets):  4e cd 0e b6 ec 3b 4d 87 f5 d6 02 8f 92 2c a4 c5
1075    %%       85 1a 27 7f d4 13 11 c9 e6 2d 2c 94 92 e1 c4 f3
1076    %%
1077    %%    secret (32 octets):  9b 21 88 e9 b2 fc 6d 64 d7 1d c3 29 90 0e 20
1078    %%       bb 41 91 50 00 f6 78 aa 83 9c bb 79 7c b7 d8 33 2c
1079    %%
1080
1081    PSK = hexstr2bin("4e cd 0e b6 ec 3b 4d 87 f5 d6 02 8f 92 2c a4 c5
1082                      85 1a 27 7f d4 13 11 c9 e6 2d 2c 94 92 e1 c4 f3"),
1083    PSK = ResExpanded,
1084    EarlySecret = hexstr2bin("9b 21 88 e9 b2 fc 6d 64 d7 1d c3 29 90 0e 20
1085                      bb 41 91 50 00 f6 78 aa 83 9c bb 79 7c b7 d8 33 2c"),
1086
1087    {early_secret, EarlySecret} = tls_v1:key_schedule(early_secret, HKDFAlgo, {psk, PSK}),
1088
1089    %% {client}  construct a ClientHello handshake message:
1090    %%
1091    %%    ClientHello (477 octets):  01 00 01 fc 03 03 1b c3 ce b6 bb e3 9c
1092    %%       ff 93 83 55 b5 a5 0a db 6d b2 1b 7a 6a f6 49 d7 b4 bc 41 9d 78
1093    %%       76 48 7d 95 00 00 06 13 01 13 03 13 02 01 00 01 cd 00 00 00 0b
1094    %%       00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00
1095    %%       12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 33
1096    %%       00 26 00 24 00 1d 00 20 e4 ff b6 8a c0 5f 8d 96 c9 9d a2 66 98
1097    %%       34 6c 6b e1 64 82 ba dd da fe 05 1a 66 b4 f1 8d 66 8f 0b 00 2a
1098    %%       00 00 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
1099    %%       02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06
1100    %%       02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01 00 15 00 57 00 00
1101    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1102    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1103    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1104    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1105    %%       00 00 29 00 dd 00 b8 00 b2 2c 03 5d 82 93 59 ee 5f f7 af 4e c9
1106    %%       00 00 00 00 26 2a 64 94 dc 48 6d 2c 8a 34 cb 33 fa 90 bf 1b 00
1107    %%       70 ad 3c 49 88 83 c9 36 7c 09 a2 be 78 5a bc 55 cd 22 60 97 a3
1108    %%       a9 82 11 72 83 f8 2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61 be 7f
1109    %%       d6 1d 28 27 db 27 9c ce 14 50 77 d4 54 a3 66 4d 4e 6d a4 d2 9e
1110    %%       e0 37 25 a6 a4 da fc d0 fc 67 d2 ae a7 05 29 51 3e 3d a2 67 7f
1111    %%       a5 90 6c 5b 3f 7d 8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb f2 97
1112    %%       b5 ae a6 17 64 6f ac 5c 03 27 2e 97 07 27 c6 21 a7 91 41 ef 5f
1113    %%       7d e6 50 5e 5b fb c3 88 e9 33 43 69 40 93 93 4a e4 d3 57 fa d6
1114    %%       aa cb
1115    %%
1116    ClientHello =
1117        hexstr2bin("01 00 01 fc 03 03 1b c3 ce b6 bb e3 9c
1118          ff 93 83 55 b5 a5 0a db 6d b2 1b 7a 6a f6 49 d7 b4 bc 41 9d 78
1119          76 48 7d 95 00 00 06 13 01 13 03 13 02 01 00 01 cd 00 00 00 0b
1120          00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00
1121          12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 33
1122          00 26 00 24 00 1d 00 20 e4 ff b6 8a c0 5f 8d 96 c9 9d a2 66 98
1123          34 6c 6b e1 64 82 ba dd da fe 05 1a 66 b4 f1 8d 66 8f 0b 00 2a
1124          00 00 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03
1125          02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06
1126          02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01 00 15 00 57 00 00
1127          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1128          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1129          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1130          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1131          00 00 29 00 dd 00 b8 00 b2 2c 03 5d 82 93 59 ee 5f f7 af 4e c9
1132          00 00 00 00 26 2a 64 94 dc 48 6d 2c 8a 34 cb 33 fa 90 bf 1b 00
1133          70 ad 3c 49 88 83 c9 36 7c 09 a2 be 78 5a bc 55 cd 22 60 97 a3
1134          a9 82 11 72 83 f8 2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61 be 7f
1135          d6 1d 28 27 db 27 9c ce 14 50 77 d4 54 a3 66 4d 4e 6d a4 d2 9e
1136          e0 37 25 a6 a4 da fc d0 fc 67 d2 ae a7 05 29 51 3e 3d a2 67 7f
1137          a5 90 6c 5b 3f 7d 8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb f2 97
1138          b5 ae a6 17 64 6f ac 5c 03 27 2e 97 07 27 c6 21 a7 91 41 ef 5f
1139          7d e6 50 5e 5b fb c3 88 e9 33 43 69 40 93 93 4a e4 d3 57 fa d6
1140          aa cb"),
1141
1142    %% {client}  calculate PSK binder:
1143    %%
1144    %%    ClientHello prefix (477 octets):  01 00 01 fc 03 03 1b c3 ce b6 bb
1145    %%       e3 9c ff 93 83 55 b5 a5 0a db 6d b2 1b 7a 6a f6 49 d7 b4 bc 41
1146    %%       9d 78 76 48 7d 95 00 00 06 13 01 13 03 13 02 01 00 01 cd 00 00
1147    %%       00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00
1148    %%       14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04
1149    %%       00 33 00 26 00 24 00 1d 00 20 e4 ff b6 8a c0 5f 8d 96 c9 9d a2
1150    %%       66 98 34 6c 6b e1 64 82 ba dd da fe 05 1a 66 b4 f1 8d 66 8f 0b
1151    %%       00 2a 00 00 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03
1152    %%       06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05
1153    %%       02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01 00 15 00 57
1154    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1155    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1156    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1157    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1158    %%       00 00 00 00 29 00 dd 00 b8 00 b2 2c 03 5d 82 93 59 ee 5f f7 af
1159    %%       4e c9 00 00 00 00 26 2a 64 94 dc 48 6d 2c 8a 34 cb 33 fa 90 bf
1160    %%       1b 00 70 ad 3c 49 88 83 c9 36 7c 09 a2 be 78 5a bc 55 cd 22 60
1161    %%       97 a3 a9 82 11 72 83 f8 2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61
1162    %%       be 7f d6 1d 28 27 db 27 9c ce 14 50 77 d4 54 a3 66 4d 4e 6d a4
1163    %%       d2 9e e0 37 25 a6 a4 da fc d0 fc 67 d2 ae a7 05 29 51 3e 3d a2
1164    %%       67 7f a5 90 6c 5b 3f 7d 8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb
1165    %%       f2 97 b5 ae a6 17 64 6f ac 5c 03 27 2e 97 07 27 c6 21 a7 91 41
1166    %%       ef 5f 7d e6 50 5e 5b fb c3 88 e9 33 43 69 40 93 93 4a e4 d3 57
1167    %%       fa d6 aa cb
1168    %%
1169    %%    binder hash (32 octets):  63 22 4b 2e 45 73 f2 d3 45 4c a8 4b 9d
1170    %%       00 9a 04 f6 be 9e 05 71 1a 83 96 47 3a ef a0 1e 92 4a 14
1171    %%
1172    %%    PRK (32 octets):  69 fe 13 1a 3b ba d5 d6 3c 64 ee bc c3 0e 39 5b
1173    %%       9d 81 07 72 6a 13 d0 74 e3 89 db c8 a4 e4 72 56
1174    %%
1175    %%    hash (0 octets):  (empty)
1176    %%
1177    %%    info (18 octets):  00 20 0e 74 6c 73 31 33 20 66 69 6e 69 73 68 65
1178    %%       64 00
1179    %%
1180    %%    expanded (32 octets):  55 88 67 3e 72 cb 59 c8 7d 22 0c af fe 94
1181    %%       f2 de a9 a3 b1 60 9f 7d 50 e9 0a 48 22 7d b9 ed 7e aa
1182    %%
1183    %%    finished (32 octets):  3a dd 4f b2 d8 fd f8 22 a0 ca 3c f7 67 8e
1184    %%       f5 e8 8d ae 99 01 41 c5 92 4d 57 bb 6f a3 1b 9e 5f 9d
1185    BinderHash =
1186        hexstr2bin("63 22 4b 2e 45 73 f2 d3 45 4c a8 4b 9d
1187                    00 9a 04 f6 be 9e 05 71 1a 83 96 47 3a ef a0 1e 92 4a 14"),
1188
1189    %% Part of derive_secret/4
1190    BinderHash = crypto:hash(HKDFAlgo, [ClientHello]),
1191
1192    PRK = hexstr2bin("69 fe 13 1a 3b ba d5 d6 3c 64 ee bc c3 0e 39 5b
1193                      9d 81 07 72 6a 13 d0 74 e3 89 db c8 a4 e4 72 56"),
1194
1195    PRK = tls_v1:resumption_binder_key(HKDFAlgo, {early_secret, EarlySecret}),
1196
1197    Expanded =
1198        hexstr2bin("55 88 67 3e 72 cb 59 c8 7d 22 0c af fe 94
1199                    f2 de a9 a3 b1 60 9f 7d 50 e9 0a 48 22 7d b9 ed 7e aa"),
1200
1201    Expanded = tls_v1:finished_key(PRK, HKDFAlgo),
1202
1203    Finished = hexstr2bin("3a dd 4f b2 d8 fd f8 22 a0 ca 3c f7 67 8e
1204               f5 e8 8d ae 99 01 41 c5 92 4d 57 bb 6f a3 1b 9e 5f 9d"),
1205
1206    Finished = tls_v1:finished_verify_data(Expanded, HKDFAlgo, [ClientHello]),
1207
1208    %% {client}  send handshake record:
1209    %%
1210    %%    payload (512 octets):  01 00 01 fc 03 03 1b c3 ce b6 bb e3 9c ff
1211    %%       93 83 55 b5 a5 0a db 6d b2 1b 7a 6a f6 49 d7 b4 bc 41 9d 78 76
1212    %%       48 7d 95 00 00 06 13 01 13 03 13 02 01 00 01 cd 00 00 00 0b 00
1213    %%       09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00 12
1214    %%       00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 33 00
1215    %%       26 00 24 00 1d 00 20 e4 ff b6 8a c0 5f 8d 96 c9 9d a2 66 98 34
1216    %%       6c 6b e1 64 82 ba dd da fe 05 1a 66 b4 f1 8d 66 8f 0b 00 2a 00
1217    %%       00 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03 02
1218    %%       03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06 02
1219    %%       02 02 00 2d 00 02 01 01 00 1c 00 02 40 01 00 15 00 57 00 00 00
1220    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1221    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1222    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1223    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1224    %%       00 29 00 dd 00 b8 00 b2 2c 03 5d 82 93 59 ee 5f f7 af 4e c9 00
1225    %%       00 00 00 26 2a 64 94 dc 48 6d 2c 8a 34 cb 33 fa 90 bf 1b 00 70
1226    %%       ad 3c 49 88 83 c9 36 7c 09 a2 be 78 5a bc 55 cd 22 60 97 a3 a9
1227    %%       82 11 72 83 f8 2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61 be 7f d6
1228    %%       1d 28 27 db 27 9c ce 14 50 77 d4 54 a3 66 4d 4e 6d a4 d2 9e e0
1229    %%       37 25 a6 a4 da fc d0 fc 67 d2 ae a7 05 29 51 3e 3d a2 67 7f a5
1230    %%       90 6c 5b 3f 7d 8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb f2 97 b5
1231    %%       ae a6 17 64 6f ac 5c 03 27 2e 97 07 27 c6 21 a7 91 41 ef 5f 7d
1232    %%       e6 50 5e 5b fb c3 88 e9 33 43 69 40 93 93 4a e4 d3 57 fa d6 aa
1233    %%       cb 00 21 20 3a dd 4f b2 d8 fd f8 22 a0 ca 3c f7 67 8e f5 e8 8d
1234    %%       ae 99 01 41 c5 92 4d 57 bb 6f a3 1b 9e 5f 9d
1235    %%
1236    %%    complete record (517 octets):  16 03 01 02 00 01 00 01 fc 03 03 1b
1237    %%       c3 ce b6 bb e3 9c ff 93 83 55 b5 a5 0a db 6d b2 1b 7a 6a f6 49
1238    %%       d7 b4 bc 41 9d 78 76 48 7d 95 00 00 06 13 01 13 03 13 02 01 00
1239    %%       01 cd 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
1240    %%       00 00 0a 00 14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02
1241    %%       01 03 01 04 00 33 00 26 00 24 00 1d 00 20 e4 ff b6 8a c0 5f 8d
1242    %%       96 c9 9d a2 66 98 34 6c 6b e1 64 82 ba dd da fe 05 1a 66 b4 f1
1243    %%       8d 66 8f 0b 00 2a 00 00 00 2b 00 03 02 03 04 00 0d 00 20 00 1e
1244    %%       04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02
1245    %%       01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
1246    %%       00 15 00 57 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1247    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1248    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1249    %%       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1250    %%       00 00 00 00 00 00 00 00 29 00 dd 00 b8 00 b2 2c 03 5d 82 93 59
1251    %%       ee 5f f7 af 4e c9 00 00 00 00 26 2a 64 94 dc 48 6d 2c 8a 34 cb
1252    %%       33 fa 90 bf 1b 00 70 ad 3c 49 88 83 c9 36 7c 09 a2 be 78 5a bc
1253    %%       55 cd 22 60 97 a3 a9 82 11 72 83 f8 2a 03 a1 43 ef d3 ff 5d d3
1254    %%       6d 64 e8 61 be 7f d6 1d 28 27 db 27 9c ce 14 50 77 d4 54 a3 66
1255    %%       4d 4e 6d a4 d2 9e e0 37 25 a6 a4 da fc d0 fc 67 d2 ae a7 05 29
1256    %%       51 3e 3d a2 67 7f a5 90 6c 5b 3f 7d 8f 92 f2 28 bd a4 0d da 72
1257    %%       14 70 f9 fb f2 97 b5 ae a6 17 64 6f ac 5c 03 27 2e 97 07 27 c6
1258    %%       21 a7 91 41 ef 5f 7d e6 50 5e 5b fb c3 88 e9 33 43 69 40 93 93
1259    %%       4a e4 d3 57 fa d6 aa cb 00 21 20 3a dd 4f b2 d8 fd f8 22 a0 ca
1260    %%       3c f7 67 8e f5 e8 8d ae 99 01 41 c5 92 4d 57 bb 6f a3 1b 9e 5f
1261    %%       9d
1262    ClientHelloRecord =
1263        hexstr2bin("01 00 01 fc 03 03 1b c3 ce b6 bb e3 9c ff
1264          93 83 55 b5 a5 0a db 6d b2 1b 7a 6a f6 49 d7 b4 bc 41 9d 78 76
1265          48 7d 95 00 00 06 13 01 13 03 13 02 01 00 01 cd 00 00 00 0b 00
1266          09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00 12
1267          00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 33 00
1268          26 00 24 00 1d 00 20 e4 ff b6 8a c0 5f 8d 96 c9 9d a2 66 98 34
1269          6c 6b e1 64 82 ba dd da fe 05 1a 66 b4 f1 8d 66 8f 0b 00 2a 00
1270          00 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03 02
1271          03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06 02
1272          02 02 00 2d 00 02 01 01 00 1c 00 02 40 01 00 15 00 57 00 00 00
1273          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1274          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1275          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1276          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1277          00 29 00 dd 00 b8 00 b2 2c 03 5d 82 93 59 ee 5f f7 af 4e c9 00
1278          00 00 00 26 2a 64 94 dc 48 6d 2c 8a 34 cb 33 fa 90 bf 1b 00 70
1279          ad 3c 49 88 83 c9 36 7c 09 a2 be 78 5a bc 55 cd 22 60 97 a3 a9
1280          82 11 72 83 f8 2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61 be 7f d6
1281          1d 28 27 db 27 9c ce 14 50 77 d4 54 a3 66 4d 4e 6d a4 d2 9e e0
1282          37 25 a6 a4 da fc d0 fc 67 d2 ae a7 05 29 51 3e 3d a2 67 7f a5
1283          90 6c 5b 3f 7d 8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb f2 97 b5
1284          ae a6 17 64 6f ac 5c 03 27 2e 97 07 27 c6 21 a7 91 41 ef 5f 7d
1285          e6 50 5e 5b fb c3 88 e9 33 43 69 40 93 93 4a e4 d3 57 fa d6 aa
1286          cb 00 21 20 3a dd 4f b2 d8 fd f8 22 a0 ca 3c f7 67 8e f5 e8 8d
1287          ae 99 01 41 c5 92 4d 57 bb 6f a3 1b 9e 5f 9d"),
1288
1289    <<?BYTE(CH), ?UINT24(_Length), ClientHelloBody/binary>> = ClientHelloRecord,
1290    #client_hello{extensions = #{pre_shared_key := PreSharedKey}} =
1291        tls_handshake:decode_handshake({3,4}, CH, ClientHelloBody),
1292
1293    #pre_shared_key_client_hello{
1294       offered_psks = #offered_psks{
1295                         identities = [Identity],
1296                         binders = [_Binders]}} =  PreSharedKey,
1297
1298    #psk_identity{
1299       identity = Ticket} = Identity,
1300
1301    ok.
1302
1303
1304%%--------------------------------------------------------------------
1305finished_verify_data() ->
1306     [{doc,"Test TLS 1.3 Finished message handling"}].
1307
1308finished_verify_data(_Config) ->
1309    ClientHello =
1310        hexstr2bin("01 00 00 c6 03 03 00 01  02 03 04 05 06 07 08 09
1311                    0a 0b 0c 0d 0e 0f 10 11  12 13 14 15 16 17 18 19
1312                    1a 1b 1c 1d 1e 1f 20 e0  e1 e2 e3 e4 e5 e6 e7 e8
1313                    e9 ea eb ec ed ee ef f0  f1 f2 f3 f4 f5 f6 f7 f8
1314                    f9 fa fb fc fd fe ff 00  06 13 01 13 02 13 03 01
1315                    00 00 77 00 00 00 18 00  16 00 00 13 65 78 61 6d
1316                    70 6c 65 2e 75 6c 66 68  65 69 6d 2e 6e 65 74 00
1317                    0a 00 08 00 06 00 1d 00  17 00 18 00 0d 00 14 00
1318                    12 04 03 08 04 04 01 05  03 08 05 05 01 08 06 06
1319                    01 02 01 00 33 00 26 00  24 00 1d 00 20 35 80 72
1320                    d6 36 58 80 d1 ae ea 32  9a df 91 21 38 38 51 ed
1321                    21 a2 8e 3b 75 e9 65 d0  d2 cd 16 62 54 00 2d 00
1322                    02 01 01 00 2b 00 03 02  03 04"),
1323
1324    ServerHello =
1325        hexstr2bin("02 00 00 76 03 03 70 71  72 73 74 75 76 77 78 79
1326                    7a 7b 7c 7d 7e 7f 80 81  82 83 84 85 86 87 88 89
1327                    8a 8b 8c 8d 8e 8f 20 e0  e1 e2 e3 e4 e5 e6 e7 e8
1328                    e9 ea eb ec ed ee ef f0  f1 f2 f3 f4 f5 f6 f7 f8
1329                    f9 fa fb fc fd fe ff 13  01 00 00 2e 00 33 00 24
1330                    00 1d 00 20 9f d7 ad 6d  cf f4 29 8d d3 f9 6d 5b
1331                    1b 2a f9 10 a0 53 5b 14  88 d7 f8 fa bb 34 9a 98
1332                    28 80 b6 15 00 2b 00 02  03 04"),
1333
1334    EncryptedExtensions =
1335        hexstr2bin("08 00 00 02 00 00"),
1336
1337    Certificate =
1338        hexstr2bin("0b 00 03 2e 00 00 03 2a  00 03 25 30 82 03 21 30
1339                    82 02 09 a0 03 02 01 02  02 08 15 5a 92 ad c2 04
1340                    8f 90 30 0d 06 09 2a 86  48 86 f7 0d 01 01 0b 05
1341                    00 30 22 31 0b 30 09 06  03 55 04 06 13 02 55 53
1342                    31 13 30 11 06 03 55 04  0a 13 0a 45 78 61 6d 70
1343                    6c 65 20 43 41 30 1e 17  0d 31 38 31 30 30 35 30
1344                    31 33 38 31 37 5a 17 0d  31 39 31 30 30 35 30 31
1345                    33 38 31 37 5a 30 2b 31  0b 30 09 06 03 55 04 06
1346                    13 02 55 53 31 1c 30 1a  06 03 55 04 03 13 13 65
1347                    78 61 6d 70 6c 65 2e 75  6c 66 68 65 69 6d 2e 6e
1348                    65 74 30 82 01 22 30 0d  06 09 2a 86 48 86 f7 0d
1349                    01 01 01 05 00 03 82 01  0f 00 30 82 01 0a 02 82
1350                    01 01 00 c4 80 36 06 ba  e7 47 6b 08 94 04 ec a7
1351                    b6 91 04 3f f7 92 bc 19  ee fb 7d 74 d7 a8 0d 00
1352                    1e 7b 4b 3a 4a e6 0f e8  c0 71 fc 73 e7 02 4c 0d
1353                    bc f4 bd d1 1d 39 6b ba  70 46 4a 13 e9 4a f8 3d
1354                    f3 e1 09 59 54 7b c9 55  fb 41 2d a3 76 52 11 e1
1355                    f3 dc 77 6c aa 53 37 6e  ca 3a ec be c3 aa b7 3b
1356                    31 d5 6c b6 52 9c 80 98  bc c9 e0 28 18 e2 0b f7
1357                    f8 a0 3a fd 17 04 50 9e  ce 79 bd 9f 39 f1 ea 69
1358                    ec 47 97 2e 83 0f b5 ca  95 de 95 a1 e6 04 22 d5
1359                    ee be 52 79 54 a1 e7 bf  8a 86 f6 46 6d 0d 9f 16
1360                    95 1a 4c f7 a0 46 92 59  5c 13 52 f2 54 9e 5a fb
1361                    4e bf d7 7a 37 95 01 44  e4 c0 26 87 4c 65 3e 40
1362                    7d 7d 23 07 44 01 f4 84  ff d0 8f 7a 1f a0 52 10
1363                    d1 f4 f0 d5 ce 79 70 29  32 e2 ca be 70 1f df ad
1364                    6b 4b b7 11 01 f4 4b ad  66 6a 11 13 0f e2 ee 82
1365                    9e 4d 02 9d c9 1c dd 67  16 db b9 06 18 86 ed c1
1366                    ba 94 21 02 03 01 00 01  a3 52 30 50 30 0e 06 03
1367                    55 1d 0f 01 01 ff 04 04  03 02 05 a0 30 1d 06 03
1368                    55 1d 25 04 16 30 14 06  08 2b 06 01 05 05 07 03
1369                    02 06 08 2b 06 01 05 05  07 03 01 30 1f 06 03 55
1370                    1d 23 04 18 30 16 80 14  89 4f de 5b cc 69 e2 52
1371                    cf 3e a3 00 df b1 97 b8  1d e1 c1 46 30 0d 06 09
1372                    2a 86 48 86 f7 0d 01 01  0b 05 00 03 82 01 01 00
1373                    59 16 45 a6 9a 2e 37 79  e4 f6 dd 27 1a ba 1c 0b
1374                    fd 6c d7 55 99 b5 e7 c3  6e 53 3e ff 36 59 08 43
1375                    24 c9 e7 a5 04 07 9d 39  e0 d4 29 87 ff e3 eb dd
1376                    09 c1 cf 1d 91 44 55 87  0b 57 1d d1 9b df 1d 24
1377                    f8 bb 9a 11 fe 80 fd 59  2b a0 39 8c de 11 e2 65
1378                    1e 61 8c e5 98 fa 96 e5  37 2e ef 3d 24 8a fd e1
1379                    74 63 eb bf ab b8 e4 d1  ab 50 2a 54 ec 00 64 e9
1380                    2f 78 19 66 0d 3f 27 cf  20 9e 66 7f ce 5a e2 e4
1381                    ac 99 c7 c9 38 18 f8 b2  51 07 22 df ed 97 f3 2e
1382                    3e 93 49 d4 c6 6c 9e a6  39 6d 74 44 62 a0 6b 42
1383                    c6 d5 ba 68 8e ac 3a 01  7b dd fc 8e 2c fc ad 27
1384                    cb 69 d3 cc dc a2 80 41  44 65 d3 ae 34 8c e0 f3
1385                    4a b2 fb 9c 61 83 71 31  2b 19 10 41 64 1c 23 7f
1386                    11 a5 d6 5c 84 4f 04 04  84 99 38 71 2b 95 9e d6
1387                    85 bc 5c 5d d6 45 ed 19  90 94 73 40 29 26 dc b4
1388                    0e 34 69 a1 59 41 e8 e2  cc a8 4b b6 08 46 36 a0
1389                    00 00"),
1390
1391    CertificateVerify =
1392        hexstr2bin("0f 00 01 04 08 04 01 00  17 fe b5 33 ca 6d 00 7d
1393                    00 58 25 79 68 42 4b bc  3a a6 90 9e 9d 49 55 75
1394                    76 a5 20 e0 4a 5e f0 5f  0e 86 d2 4f f4 3f 8e b8
1395                    61 ee f5 95 22 8d 70 32  aa 36 0f 71 4e 66 74 13
1396                    92 6e f4 f8 b5 80 3b 69  e3 55 19 e3 b2 3f 43 73
1397                    df ac 67 87 06 6d cb 47  56 b5 45 60 e0 88 6e 9b
1398                    96 2c 4a d2 8d ab 26 ba  d1 ab c2 59 16 b0 9a f2
1399                    86 53 7f 68 4f 80 8a ef  ee 73 04 6c b7 df 0a 84
1400                    fb b5 96 7a ca 13 1f 4b  1c f3 89 79 94 03 a3 0c
1401                    02 d2 9c bd ad b7 25 12  db 9c ec 2e 5e 1d 00 e5
1402                    0c af cf 6f 21 09 1e bc  4f 25 3c 5e ab 01 a6 79
1403                    ba ea be ed b9 c9 61 8f  66 00 6b 82 44 d6 62 2a
1404                    aa 56 88 7c cf c6 6a 0f  38 51 df a1 3a 78 cf f7
1405                    99 1e 03 cb 2c 3a 0e d8  7d 73 67 36 2e b7 80 5b
1406                    00 b2 52 4f f2 98 a4 da  48 7c ac de af 8a 23 36
1407                    c5 63 1b 3e fa 93 5b b4  11 e7 53 ca 13 b0 15 fe
1408                    c7 e4 a7 30 f1 36 9f 9e"),
1409
1410    BaseKey =
1411        hexstr2bin("a2 06 72 65 e7 f0 65 2a  92 3d 5d 72 ab 04 67 c4
1412                    61 32 ee b9 68 b6 a3 2d  31 1c 80 58 68 54 88 14"),
1413
1414    VerifyData =
1415        hexstr2bin("ea 6e e1 76 dc cc 4a f1  85 9e 9e 4e 93 f7 97 ea
1416                    c9 a7 8c e4 39 30 1e 35  27 5a d4 3f 3c dd bd e3"),
1417
1418    Messages = [CertificateVerify,
1419                Certificate,
1420                EncryptedExtensions,
1421                ServerHello,
1422                ClientHello],
1423
1424    FinishedKey = tls_v1:finished_key(BaseKey, sha256),
1425    VerifyData = tls_v1:finished_verify_data(FinishedKey, sha256, Messages).
1426
1427%%--------------------------------------------------------------------
1428%% Internal functions ------------------------------------------------
1429%%--------------------------------------------------------------------
1430
1431hexstr2int(S) ->
1432    B = hexstr2bin(S),
1433    Bits = byte_size(B) * 8,
1434    <<Integer:Bits/integer>> = B,
1435    Integer.
1436
1437hexstr2bin(S) when is_binary(S) ->
1438    hexstr2bin(S, <<>>);
1439hexstr2bin(S) ->
1440    hexstr2bin(list_to_binary(S), <<>>).
1441%%
1442hexstr2bin(<<>>, Acc) ->
1443    Acc;
1444hexstr2bin(<<C,T/binary>>, Acc) when C =:= 32;   %% SPACE
1445                                     C =:= 10;   %% LF
1446                                     C =:= 13 -> %% CR
1447    hexstr2bin(T, Acc);
1448hexstr2bin(<<X,Y,T/binary>>, Acc) ->
1449    I = hex2int(X) * 16 + hex2int(Y),
1450    hexstr2bin(T, <<Acc/binary,I>>).
1451
1452hex2int(C) when $0 =< C, C =< $9 ->
1453    C - $0;
1454hex2int(C) when $A =< C, C =< $F ->
1455    C - $A + 10;
1456hex2int(C) when $a =< C, C =< $f ->
1457    C - $a + 10.
1458