xref: /freebsd/crypto/openssl/test/tls13groupselection_test.c (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery  * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery  *
4*e7be843bSPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*e7be843bSPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
6*e7be843bSPierre Pronchery  * in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery  * https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery  */
9*e7be843bSPierre Pronchery 
10*e7be843bSPierre Pronchery #include "testutil.h"
11*e7be843bSPierre Pronchery #include "helpers/ssltestlib.h"
12*e7be843bSPierre Pronchery #include <openssl/objects.h>
13*e7be843bSPierre Pronchery 
14*e7be843bSPierre Pronchery #define TEST_true_or_end(a) if (!TEST_true(a)) \
15*e7be843bSPierre Pronchery         goto end;
16*e7be843bSPierre Pronchery 
17*e7be843bSPierre Pronchery #define TEST_false_or_end(a) if (!TEST_false(a)) \
18*e7be843bSPierre Pronchery         goto end;
19*e7be843bSPierre Pronchery 
20*e7be843bSPierre Pronchery #define SERVER_PREFERENCE 1
21*e7be843bSPierre Pronchery #define CLIENT_PREFERENCE 0
22*e7be843bSPierre Pronchery 
23*e7be843bSPierre Pronchery #define WORK_ON_SSL_OBJECT 1
24*e7be843bSPierre Pronchery #define WORK_ON_CONTEXT 0
25*e7be843bSPierre Pronchery 
26*e7be843bSPierre Pronchery #define SYNTAX_FAILURE "SYNTAX_FAILURE"
27*e7be843bSPierre Pronchery #define NEGOTIATION_FAILURE "NEGOTIATION_FAILURE"
28*e7be843bSPierre Pronchery 
29*e7be843bSPierre Pronchery typedef enum TEST_TYPE {
30*e7be843bSPierre Pronchery     TEST_NEGOTIATION_FAILURE = 0,
31*e7be843bSPierre Pronchery     TEST_NEGOTIATION_SUCCESS = 1,
32*e7be843bSPierre Pronchery     TEST_SYNTAX_FAILURE = 2
33*e7be843bSPierre Pronchery } TEST_TYPE;
34*e7be843bSPierre Pronchery 
35*e7be843bSPierre Pronchery typedef enum SERVER_RESPONSE {
36*e7be843bSPierre Pronchery     HRR  = 0,
37*e7be843bSPierre Pronchery     INIT = 1,
38*e7be843bSPierre Pronchery     SH   = 2
39*e7be843bSPierre Pronchery } SERVER_RESPONSE;
40*e7be843bSPierre Pronchery 
41*e7be843bSPierre Pronchery static char *cert = NULL;
42*e7be843bSPierre Pronchery static char *privkey = NULL;
43*e7be843bSPierre Pronchery 
44*e7be843bSPierre Pronchery struct tls13groupselection_test_st {
45*e7be843bSPierre Pronchery     const char *client_groups;
46*e7be843bSPierre Pronchery     const char *server_groups;
47*e7be843bSPierre Pronchery     const int preference;
48*e7be843bSPierre Pronchery     const char *expected_group;
49*e7be843bSPierre Pronchery     const enum SERVER_RESPONSE expected_server_response;
50*e7be843bSPierre Pronchery };
51*e7be843bSPierre Pronchery 
52*e7be843bSPierre Pronchery static const struct tls13groupselection_test_st tls13groupselection_tests[] =
53*e7be843bSPierre Pronchery     {
54*e7be843bSPierre Pronchery 
55*e7be843bSPierre Pronchery         /*
56*e7be843bSPierre Pronchery          * (A) Test with no explicit key share (backward compatibility)
57*e7be843bSPierre Pronchery          * Key share is implicitly sent for first client group
58*e7be843bSPierre Pronchery          * Test (implicitly) that the key share group is used
59*e7be843bSPierre Pronchery          */
60*e7be843bSPierre Pronchery         { "secp384r1:secp521r1:X25519:prime256v1:X448", /* test 0 */
61*e7be843bSPierre Pronchery           "X25519:secp521r1:secp384r1:prime256v1:X448",
62*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
63*e7be843bSPierre Pronchery           "secp384r1", SH
64*e7be843bSPierre Pronchery         },
65*e7be843bSPierre Pronchery         { "secp521r1:secp384r1:X25519:prime256v1:X448", /* test 1 */
66*e7be843bSPierre Pronchery           "X25519:secp521r1:secp384r1:prime256v1:X448",
67*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
68*e7be843bSPierre Pronchery           "secp521r1", SH
69*e7be843bSPierre Pronchery         },
70*e7be843bSPierre Pronchery 
71*e7be843bSPierre Pronchery         /*
72*e7be843bSPierre Pronchery          * (B) No explicit key share test (backward compatibility)
73*e7be843bSPierre Pronchery          * Key share is implicitly sent for first client group
74*e7be843bSPierre Pronchery          * Check HRR if server does not support key share group
75*e7be843bSPierre Pronchery          */
76*e7be843bSPierre Pronchery         { "secp521r1:secp384r1:X25519:prime256v1:X448", /* test 2 */
77*e7be843bSPierre Pronchery           "X25519:secp384r1:prime256v1",
78*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
79*e7be843bSPierre Pronchery           "secp384r1", HRR
80*e7be843bSPierre Pronchery         },
81*e7be843bSPierre Pronchery         { "secp521r1:secp384r1:X25519:prime256v1:X448", /* test 3 */
82*e7be843bSPierre Pronchery           "X25519:secp384r1:prime256v1",
83*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
84*e7be843bSPierre Pronchery           "x25519", HRR
85*e7be843bSPierre Pronchery         },
86*e7be843bSPierre Pronchery 
87*e7be843bSPierre Pronchery         /*
88*e7be843bSPierre Pronchery          * (C) Explicit key shares, SH tests
89*e7be843bSPierre Pronchery          * Test key share selection as function of client-/server-preference
90*e7be843bSPierre Pronchery          * Test (implicitly) that multiple key shares are generated
91*e7be843bSPierre Pronchery          * Test (implicitly) that multiple tuples don't influence the client
92*e7be843bSPierre Pronchery          * Test (implicitly) that key share prefix doesn't influence the server
93*e7be843bSPierre Pronchery          */
94*e7be843bSPierre Pronchery         { "secp521r1:secp384r1:*X25519/*prime256v1:X448", /* test 4 */
95*e7be843bSPierre Pronchery           "secp521r1:*prime256v1:X25519:X448",
96*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
97*e7be843bSPierre Pronchery           "x25519", SH
98*e7be843bSPierre Pronchery         },
99*e7be843bSPierre Pronchery         { "secp521r1:secp384r1:*X25519/*prime256v1:X448", /* test 5 */
100*e7be843bSPierre Pronchery           "secp521r1:*prime256v1:X25519:X448",
101*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
102*e7be843bSPierre Pronchery           "secp256r1", SH
103*e7be843bSPierre Pronchery         },
104*e7be843bSPierre Pronchery 
105*e7be843bSPierre Pronchery         /*
106*e7be843bSPierre Pronchery          * (D) Explicit key shares, HRR tests
107*e7be843bSPierre Pronchery          * Check that HRR is issued if group in first tuple
108*e7be843bSPierre Pronchery          * is supported but no key share is available for the tuple
109*e7be843bSPierre Pronchery          */
110*e7be843bSPierre Pronchery         { "secp521r1:secp384r1:*X25519:prime256v1:*X448", /* test 6 */
111*e7be843bSPierre Pronchery           "secp384r1:secp521r1:prime256v1/X25519:X448",
112*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
113*e7be843bSPierre Pronchery           "secp521r1", HRR
114*e7be843bSPierre Pronchery         },
115*e7be843bSPierre Pronchery         { "secp521r1:secp384r1:*X25519:prime256v1:*X448", /* test 7 */
116*e7be843bSPierre Pronchery           "secp384r1:secp521r1:prime256v1/X25519:X448",
117*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
118*e7be843bSPierre Pronchery           "secp384r1", HRR
119*e7be843bSPierre Pronchery         },
120*e7be843bSPierre Pronchery 
121*e7be843bSPierre Pronchery         /*
122*e7be843bSPierre Pronchery          * (E) Multiple tuples tests, client without tuple delimiters
123*e7be843bSPierre Pronchery          * Check that second tuple is evaluated if there isn't any match
124*e7be843bSPierre Pronchery          * first tuple
125*e7be843bSPierre Pronchery          */
126*e7be843bSPierre Pronchery         { "*X25519:prime256v1:*X448", /* test 8 */
127*e7be843bSPierre Pronchery           "secp521r1:secp384r1/X448:X25519",
128*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
129*e7be843bSPierre Pronchery           "x25519", SH
130*e7be843bSPierre Pronchery         },
131*e7be843bSPierre Pronchery         { "*X25519:prime256v1:*X448", /* test 9 */
132*e7be843bSPierre Pronchery           "secp521r1:secp384r1/X448:X25519",
133*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
134*e7be843bSPierre Pronchery           "x448", SH
135*e7be843bSPierre Pronchery         },
136*e7be843bSPierre Pronchery 
137*e7be843bSPierre Pronchery         /* (F) Check that '?' will ignore unknown group but use known group */
138*e7be843bSPierre Pronchery         { "*X25519:?unknown_group_123:prime256v1:*X448", /* test 10 */
139*e7be843bSPierre Pronchery           "secp521r1:secp384r1/X448:?unknown_group_456:?X25519",
140*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
141*e7be843bSPierre Pronchery           "x25519", SH
142*e7be843bSPierre Pronchery         },
143*e7be843bSPierre Pronchery         { "*X25519:prime256v1:*X448:?*unknown_group_789", /* test 11 */
144*e7be843bSPierre Pronchery           "secp521r1:secp384r1/?X448:?unknown_group_456:X25519",
145*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
146*e7be843bSPierre Pronchery           "x448", SH
147*e7be843bSPierre Pronchery         },
148*e7be843bSPierre Pronchery 
149*e7be843bSPierre Pronchery         /*
150*e7be843bSPierre Pronchery          * (G) Check full backward compatibility (= don't explicitly set any groups)
151*e7be843bSPierre Pronchery          */
152*e7be843bSPierre Pronchery         { NULL, /* test 12 */
153*e7be843bSPierre Pronchery           NULL,
154*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
155*e7be843bSPierre Pronchery #ifndef OPENSSL_NO_ML_KEM
156*e7be843bSPierre Pronchery           "X25519MLKEM768", SH
157*e7be843bSPierre Pronchery #else
158*e7be843bSPierre Pronchery           "x25519", SH
159*e7be843bSPierre Pronchery #endif
160*e7be843bSPierre Pronchery         },
161*e7be843bSPierre Pronchery         { NULL, /* test 13 */
162*e7be843bSPierre Pronchery           NULL,
163*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
164*e7be843bSPierre Pronchery #ifndef OPENSSL_NO_ML_KEM
165*e7be843bSPierre Pronchery           "X25519MLKEM768", SH
166*e7be843bSPierre Pronchery #else
167*e7be843bSPierre Pronchery           "x25519", SH
168*e7be843bSPierre Pronchery #endif
169*e7be843bSPierre Pronchery         },
170*e7be843bSPierre Pronchery 
171*e7be843bSPierre Pronchery         /*
172*e7be843bSPierre Pronchery          * (H) Check that removal of group is 'active'
173*e7be843bSPierre Pronchery          */
174*e7be843bSPierre Pronchery         { "*X25519:*X448", /* test 14 */
175*e7be843bSPierre Pronchery           "secp521r1:X25519:prime256v1:-X25519:secp384r1/X448",
176*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
177*e7be843bSPierre Pronchery           "x448", SH
178*e7be843bSPierre Pronchery         },
179*e7be843bSPierre Pronchery         { "*X25519:*X448", /* test 15 */
180*e7be843bSPierre Pronchery           "secp521r1:X25519:prime256v1:-X25519:secp384r1/X448",
181*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
182*e7be843bSPierre Pronchery           "x448", SH
183*e7be843bSPierre Pronchery         },
184*e7be843bSPierre Pronchery         { "*X25519:prime256v1:*X448", /* test 16 */
185*e7be843bSPierre Pronchery           "X25519:prime256v1/X448:-X25519",
186*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
187*e7be843bSPierre Pronchery           "secp256r1", HRR
188*e7be843bSPierre Pronchery         },
189*e7be843bSPierre Pronchery         { "*X25519:prime256v1:*X448", /* test 17 */
190*e7be843bSPierre Pronchery           "X25519:prime256v1/X448:-X25519",
191*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
192*e7be843bSPierre Pronchery           "secp256r1", HRR
193*e7be843bSPierre Pronchery         },
194*e7be843bSPierre Pronchery         /*
195*e7be843bSPierre Pronchery          * (I) Check handling of the "DEFAULT" 'pseudo group name'
196*e7be843bSPierre Pronchery          */
197*e7be843bSPierre Pronchery         { "*X25519:DEFAULT:-prime256v1:-X448", /* test 18 */
198*e7be843bSPierre Pronchery           "DEFAULT:-X25519:-?X25519MLKEM768",
199*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
200*e7be843bSPierre Pronchery           "secp384r1", HRR
201*e7be843bSPierre Pronchery         },
202*e7be843bSPierre Pronchery         { "*X25519:DEFAULT:-prime256v1:-X448", /* test 19 */
203*e7be843bSPierre Pronchery           "DEFAULT:-X25519:-?X25519MLKEM768",
204*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
205*e7be843bSPierre Pronchery           "secp384r1", HRR
206*e7be843bSPierre Pronchery         },
207*e7be843bSPierre Pronchery         /*
208*e7be843bSPierre Pronchery          * (J) Deduplication check
209*e7be843bSPierre Pronchery          */
210*e7be843bSPierre Pronchery         { "secp521r1:X25519:prime256v1/X25519:prime256v1/X448", /* test 20 */
211*e7be843bSPierre Pronchery           "secp521r1:X25519:prime256v1/X25519:prime256v1/X448",
212*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
213*e7be843bSPierre Pronchery           "secp521r1", SH
214*e7be843bSPierre Pronchery         },
215*e7be843bSPierre Pronchery         { "secp521r1:X25519:prime256v1/X25519:prime256v1/X448", /* test 21 */
216*e7be843bSPierre Pronchery           "secp521r1:X25519:prime256v1/X25519:prime256v1/X448",
217*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
218*e7be843bSPierre Pronchery           "secp521r1", SH
219*e7be843bSPierre Pronchery         },
220*e7be843bSPierre Pronchery         /*
221*e7be843bSPierre Pronchery          * (K) Check group removal when first entry requested a keyshare
222*e7be843bSPierre Pronchery          */
223*e7be843bSPierre Pronchery         { "*X25519:*prime256v1:-X25519", /* test 22 */
224*e7be843bSPierre Pronchery           "X25519:prime256v1",
225*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
226*e7be843bSPierre Pronchery           "secp256r1", SH
227*e7be843bSPierre Pronchery         },
228*e7be843bSPierre Pronchery         /*
229*e7be843bSPierre Pronchery          * (L) Syntax errors
230*e7be843bSPierre Pronchery          */
231*e7be843bSPierre Pronchery         { "*X25519:*prime256v1:NOTVALID", /* test 23 */
232*e7be843bSPierre Pronchery           "",
233*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
234*e7be843bSPierre Pronchery           SYNTAX_FAILURE
235*e7be843bSPierre Pronchery         },
236*e7be843bSPierre Pronchery         { "X25519//prime256v1", /* test 24 */
237*e7be843bSPierre Pronchery           "",
238*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
239*e7be843bSPierre Pronchery           SYNTAX_FAILURE
240*e7be843bSPierre Pronchery         },
241*e7be843bSPierre Pronchery         { "**X25519:*prime256v1", /* test 25 */
242*e7be843bSPierre Pronchery           "",
243*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
244*e7be843bSPierre Pronchery           SYNTAX_FAILURE
245*e7be843bSPierre Pronchery         },
246*e7be843bSPierre Pronchery         { "*X25519:*secp256r1:*X448:*secp521r1:*secp384r1", /* test 26 */
247*e7be843bSPierre Pronchery           "",
248*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
249*e7be843bSPierre Pronchery           SYNTAX_FAILURE
250*e7be843bSPierre Pronchery         },
251*e7be843bSPierre Pronchery         { "*X25519:*secp256r1:?:*secp521r1", /* test 27 */
252*e7be843bSPierre Pronchery           "",
253*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
254*e7be843bSPierre Pronchery           SYNTAX_FAILURE
255*e7be843bSPierre Pronchery         },
256*e7be843bSPierre Pronchery         { "*X25519:*secp256r1::secp521r1", /* test 28 */
257*e7be843bSPierre Pronchery           "",
258*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
259*e7be843bSPierre Pronchery           SYNTAX_FAILURE
260*e7be843bSPierre Pronchery         },
261*e7be843bSPierre Pronchery         { ":*secp256r1:secp521r1", /* test 29 */
262*e7be843bSPierre Pronchery           "",
263*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
264*e7be843bSPierre Pronchery           SYNTAX_FAILURE
265*e7be843bSPierre Pronchery         },
266*e7be843bSPierre Pronchery         { "*secp256r1:secp521r1:", /* test 30 */
267*e7be843bSPierre Pronchery           "",
268*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
269*e7be843bSPierre Pronchery           SYNTAX_FAILURE
270*e7be843bSPierre Pronchery         },
271*e7be843bSPierre Pronchery         { "/secp256r1/secp521r1", /* test 31 */
272*e7be843bSPierre Pronchery           "",
273*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
274*e7be843bSPierre Pronchery           SYNTAX_FAILURE
275*e7be843bSPierre Pronchery         },
276*e7be843bSPierre Pronchery         { "secp256r1/secp521r1/", /* test 32 */
277*e7be843bSPierre Pronchery           "",
278*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
279*e7be843bSPierre Pronchery           SYNTAX_FAILURE
280*e7be843bSPierre Pronchery         },
281*e7be843bSPierre Pronchery         { "X25519:??secp256r1:X448", /* test 33 */
282*e7be843bSPierre Pronchery           "",
283*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
284*e7be843bSPierre Pronchery           SYNTAX_FAILURE
285*e7be843bSPierre Pronchery         },
286*e7be843bSPierre Pronchery         { "X25519:secp256r1:**X448", /* test 34 */
287*e7be843bSPierre Pronchery           "",
288*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
289*e7be843bSPierre Pronchery           SYNTAX_FAILURE
290*e7be843bSPierre Pronchery         },
291*e7be843bSPierre Pronchery         { "--X25519:secp256r1:X448", /* test 35 */
292*e7be843bSPierre Pronchery           "",
293*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
294*e7be843bSPierre Pronchery           SYNTAX_FAILURE
295*e7be843bSPierre Pronchery         },
296*e7be843bSPierre Pronchery         { "-DEFAULT",  /* test 36 */
297*e7be843bSPierre Pronchery           "",
298*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
299*e7be843bSPierre Pronchery           SYNTAX_FAILURE
300*e7be843bSPierre Pronchery         },
301*e7be843bSPierre Pronchery         { "?DEFAULT",  /* test 37 */
302*e7be843bSPierre Pronchery           "",
303*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
304*e7be843bSPierre Pronchery           SYNTAX_FAILURE
305*e7be843bSPierre Pronchery         },
306*e7be843bSPierre Pronchery         /*
307*e7be843bSPierre Pronchery          * Negotiation Failures
308*e7be843bSPierre Pronchery          * No overlapping groups between client and server
309*e7be843bSPierre Pronchery          */
310*e7be843bSPierre Pronchery         /* test 38 remove all groups */
311*e7be843bSPierre Pronchery         { "X25519:secp256r1:X448:secp521r1:-X448:-secp256r1:-X25519:-secp521r1",
312*e7be843bSPierre Pronchery           "",
313*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
314*e7be843bSPierre Pronchery           NEGOTIATION_FAILURE
315*e7be843bSPierre Pronchery         },
316*e7be843bSPierre Pronchery         { "secp384r1:secp521r1:X25519", /* test 39 */
317*e7be843bSPierre Pronchery           "prime256v1:X448",
318*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
319*e7be843bSPierre Pronchery           NEGOTIATION_FAILURE
320*e7be843bSPierre Pronchery         },
321*e7be843bSPierre Pronchery         { "secp521r1:secp384r1:X25519", /* test 40 */
322*e7be843bSPierre Pronchery           "prime256v1:X448",
323*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
324*e7be843bSPierre Pronchery           NEGOTIATION_FAILURE
325*e7be843bSPierre Pronchery         },
326*e7be843bSPierre Pronchery         /*
327*e7be843bSPierre Pronchery          * These are allowed
328*e7be843bSPierre Pronchery          * "X25519/prime256v1:-X448", "X25519:-*X25519:*prime256v1, "*DEFAULT"
329*e7be843bSPierre Pronchery          */
330*e7be843bSPierre Pronchery         /*
331*e7be843bSPierre Pronchery          * Tests to show that spaces between tuples are allowed
332*e7be843bSPierre Pronchery          */
333*e7be843bSPierre Pronchery         { "secp521r1:X25519 / prime256v1/X25519 / prime256v1/X448", /* test 41 */
334*e7be843bSPierre Pronchery           "secp521r1:X25519 / prime256v1/X25519 / prime256v1/X448",
335*e7be843bSPierre Pronchery           CLIENT_PREFERENCE,
336*e7be843bSPierre Pronchery           "secp521r1", SH
337*e7be843bSPierre Pronchery         },
338*e7be843bSPierre Pronchery         { "secp521r1 / prime256v1:X25519 / prime256v1/X448", /* test 42 */
339*e7be843bSPierre Pronchery           "secp521r1 / prime256v1:X25519 / prime256v1/X448",
340*e7be843bSPierre Pronchery           SERVER_PREFERENCE,
341*e7be843bSPierre Pronchery           "secp521r1", SH
342*e7be843bSPierre Pronchery         },
343*e7be843bSPierre Pronchery     };
344*e7be843bSPierre Pronchery 
server_response_check_cb(int write_p,int version,int content_type,const void * buf,size_t len,SSL * ssl,void * arg)345*e7be843bSPierre Pronchery static void server_response_check_cb(int write_p, int version,
346*e7be843bSPierre Pronchery                                      int content_type, const void *buf,
347*e7be843bSPierre Pronchery                                      size_t len, SSL *ssl, void *arg)
348*e7be843bSPierre Pronchery {
349*e7be843bSPierre Pronchery     /* Cast arg to SERVER_RESPONSE */
350*e7be843bSPierre Pronchery     enum SERVER_RESPONSE *server_response = (enum SERVER_RESPONSE *)arg;
351*e7be843bSPierre Pronchery     /* Prepare check for HRR */
352*e7be843bSPierre Pronchery     const uint8_t *incoming_random = (uint8_t *)buf + 6;
353*e7be843bSPierre Pronchery     const uint8_t magic_HRR_random[32] = { 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
354*e7be843bSPierre Pronchery                                            0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
355*e7be843bSPierre Pronchery                                            0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
356*e7be843bSPierre Pronchery                                            0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C };
357*e7be843bSPierre Pronchery 
358*e7be843bSPierre Pronchery     /* Did a server hello arrive? */
359*e7be843bSPierre Pronchery     if (write_p == 0 &&                                /* Incoming data... */
360*e7be843bSPierre Pronchery         content_type == SSL3_RT_HANDSHAKE &&           /* carrying a handshake record type ... */
361*e7be843bSPierre Pronchery         version == TLS1_3_VERSION &&                   /* for TLSv1.3 ... */
362*e7be843bSPierre Pronchery         ((uint8_t *)buf)[0] == SSL3_MT_SERVER_HELLO) {  /* with message type "ServerHello" */
363*e7be843bSPierre Pronchery         /* Check what it is: SH or HRR (compare the 'random' data field with HRR magic number) */
364*e7be843bSPierre Pronchery         if (memcmp((void *)incoming_random, (void *)magic_HRR_random, 32) == 0)
365*e7be843bSPierre Pronchery             *server_response *= HRR;
366*e7be843bSPierre Pronchery         else
367*e7be843bSPierre Pronchery             *server_response *= SH;
368*e7be843bSPierre Pronchery     }
369*e7be843bSPierre Pronchery }
370*e7be843bSPierre Pronchery 
test_invalidsyntax(const struct tls13groupselection_test_st * current_test_vector,int ssl_or_ctx)371*e7be843bSPierre Pronchery static int test_invalidsyntax(const struct tls13groupselection_test_st *current_test_vector,
372*e7be843bSPierre Pronchery                               int ssl_or_ctx)
373*e7be843bSPierre Pronchery {
374*e7be843bSPierre Pronchery     int ok = 0;
375*e7be843bSPierre Pronchery     SSL_CTX *client_ctx = NULL, *server_ctx = NULL;
376*e7be843bSPierre Pronchery     SSL *clientssl = NULL, *serverssl = NULL;
377*e7be843bSPierre Pronchery 
378*e7be843bSPierre Pronchery     if (!TEST_ptr(current_test_vector->client_groups)
379*e7be843bSPierre Pronchery         || !TEST_size_t_ne(strlen(current_test_vector->client_groups), 0))
380*e7be843bSPierre Pronchery         goto end;
381*e7be843bSPierre Pronchery 
382*e7be843bSPierre Pronchery     /* Creation of the contexts */
383*e7be843bSPierre Pronchery     TEST_true_or_end(create_ssl_ctx_pair(NULL, TLS_server_method(),
384*e7be843bSPierre Pronchery                                          TLS_client_method(),
385*e7be843bSPierre Pronchery                                          TLS1_VERSION, 0,
386*e7be843bSPierre Pronchery                                          &server_ctx, &client_ctx,
387*e7be843bSPierre Pronchery                                          cert, privkey));
388*e7be843bSPierre Pronchery 
389*e7be843bSPierre Pronchery     /* Customization of the contexts */
390*e7be843bSPierre Pronchery     if (ssl_or_ctx == WORK_ON_CONTEXT)
391*e7be843bSPierre Pronchery         TEST_false_or_end(SSL_CTX_set1_groups_list(client_ctx,
392*e7be843bSPierre Pronchery                                                    current_test_vector->client_groups));
393*e7be843bSPierre Pronchery     /* Creation of the SSL objects */
394*e7be843bSPierre Pronchery     TEST_true_or_end(create_ssl_objects(server_ctx, client_ctx,
395*e7be843bSPierre Pronchery                                         &serverssl, &clientssl,
396*e7be843bSPierre Pronchery                                         NULL, NULL));
397*e7be843bSPierre Pronchery 
398*e7be843bSPierre Pronchery     /* Customization of the SSL objects */
399*e7be843bSPierre Pronchery     if (ssl_or_ctx == WORK_ON_SSL_OBJECT)
400*e7be843bSPierre Pronchery         TEST_false_or_end(SSL_set1_groups_list(clientssl, current_test_vector->client_groups));
401*e7be843bSPierre Pronchery 
402*e7be843bSPierre Pronchery     ok = 1;
403*e7be843bSPierre Pronchery 
404*e7be843bSPierre Pronchery end:
405*e7be843bSPierre Pronchery     SSL_free(serverssl);
406*e7be843bSPierre Pronchery     SSL_free(clientssl);
407*e7be843bSPierre Pronchery     SSL_CTX_free(server_ctx);
408*e7be843bSPierre Pronchery     SSL_CTX_free(client_ctx);
409*e7be843bSPierre Pronchery     return ok;
410*e7be843bSPierre Pronchery 
411*e7be843bSPierre Pronchery }
412*e7be843bSPierre Pronchery 
test_groupnegotiation(const struct tls13groupselection_test_st * current_test_vector,int ssl_or_ctx,TEST_TYPE test_type)413*e7be843bSPierre Pronchery static int test_groupnegotiation(const struct tls13groupselection_test_st *current_test_vector,
414*e7be843bSPierre Pronchery                                  int ssl_or_ctx, TEST_TYPE test_type)
415*e7be843bSPierre Pronchery {
416*e7be843bSPierre Pronchery     int ok = 0;
417*e7be843bSPierre Pronchery     int negotiated_group_client = 0;
418*e7be843bSPierre Pronchery     int negotiated_group_server = 0;
419*e7be843bSPierre Pronchery     const char *group_name_client;
420*e7be843bSPierre Pronchery     SSL_CTX *client_ctx = NULL, *server_ctx = NULL;
421*e7be843bSPierre Pronchery     SSL *clientssl = NULL, *serverssl = NULL;
422*e7be843bSPierre Pronchery     enum SERVER_RESPONSE server_response;
423*e7be843bSPierre Pronchery 
424*e7be843bSPierre Pronchery     /* Creation of the contexts */
425*e7be843bSPierre Pronchery     TEST_true_or_end(create_ssl_ctx_pair(NULL, TLS_server_method(),
426*e7be843bSPierre Pronchery                                          TLS_client_method(),
427*e7be843bSPierre Pronchery                                          TLS1_VERSION, 0,
428*e7be843bSPierre Pronchery                                          &server_ctx, &client_ctx,
429*e7be843bSPierre Pronchery                                          cert, privkey));
430*e7be843bSPierre Pronchery 
431*e7be843bSPierre Pronchery     /* Customization of the contexts */
432*e7be843bSPierre Pronchery     if (ssl_or_ctx == WORK_ON_CONTEXT) {
433*e7be843bSPierre Pronchery         if (current_test_vector->client_groups != NULL) {
434*e7be843bSPierre Pronchery             TEST_true_or_end(SSL_CTX_set1_groups_list(client_ctx,
435*e7be843bSPierre Pronchery                                                       current_test_vector->client_groups));
436*e7be843bSPierre Pronchery         }
437*e7be843bSPierre Pronchery         if (current_test_vector->server_groups != NULL) {
438*e7be843bSPierre Pronchery             TEST_true_or_end(SSL_CTX_set1_groups_list(server_ctx,
439*e7be843bSPierre Pronchery                                                       current_test_vector->server_groups));
440*e7be843bSPierre Pronchery         }
441*e7be843bSPierre Pronchery         TEST_true_or_end(SSL_CTX_set_min_proto_version(client_ctx, TLS1_3_VERSION));
442*e7be843bSPierre Pronchery         TEST_true_or_end(SSL_CTX_set_min_proto_version(server_ctx, TLS1_3_VERSION));
443*e7be843bSPierre Pronchery         if (current_test_vector->preference == SERVER_PREFERENCE)
444*e7be843bSPierre Pronchery             SSL_CTX_set_options(server_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
445*e7be843bSPierre Pronchery     }
446*e7be843bSPierre Pronchery     /* Creation of the SSL objects */
447*e7be843bSPierre Pronchery     if (!TEST_true(create_ssl_objects(server_ctx, client_ctx,
448*e7be843bSPierre Pronchery                                       &serverssl, &clientssl,
449*e7be843bSPierre Pronchery                                       NULL, NULL)))
450*e7be843bSPierre Pronchery         goto end;
451*e7be843bSPierre Pronchery 
452*e7be843bSPierre Pronchery     /* Customization of the SSL objects */
453*e7be843bSPierre Pronchery     if (ssl_or_ctx == WORK_ON_SSL_OBJECT) {
454*e7be843bSPierre Pronchery         if (current_test_vector->client_groups != NULL)
455*e7be843bSPierre Pronchery             TEST_true_or_end(SSL_set1_groups_list(clientssl, current_test_vector->client_groups));
456*e7be843bSPierre Pronchery 
457*e7be843bSPierre Pronchery         if (current_test_vector->server_groups != NULL)
458*e7be843bSPierre Pronchery             TEST_true_or_end(SSL_set1_groups_list(serverssl, current_test_vector->server_groups));
459*e7be843bSPierre Pronchery 
460*e7be843bSPierre Pronchery         TEST_true_or_end(SSL_set_min_proto_version(clientssl, TLS1_3_VERSION));
461*e7be843bSPierre Pronchery         TEST_true_or_end(SSL_set_min_proto_version(serverssl, TLS1_3_VERSION));
462*e7be843bSPierre Pronchery 
463*e7be843bSPierre Pronchery         if (current_test_vector->preference == SERVER_PREFERENCE)
464*e7be843bSPierre Pronchery             SSL_set_options(serverssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
465*e7be843bSPierre Pronchery     }
466*e7be843bSPierre Pronchery 
467*e7be843bSPierre Pronchery     /* We set the message callback on the client side (which checks SH/HRR) */
468*e7be843bSPierre Pronchery     server_response = INIT; /* Variable to hold server response info */
469*e7be843bSPierre Pronchery     SSL_set_msg_callback_arg(clientssl, &server_response); /* add it to the callback */
470*e7be843bSPierre Pronchery     SSL_set_msg_callback(clientssl, server_response_check_cb); /* and activate callback */
471*e7be843bSPierre Pronchery 
472*e7be843bSPierre Pronchery     /* Creating a test connection */
473*e7be843bSPierre Pronchery     if (test_type == TEST_NEGOTIATION_SUCCESS) {
474*e7be843bSPierre Pronchery         TEST_true_or_end(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE));
475*e7be843bSPierre Pronchery 
476*e7be843bSPierre Pronchery         /*
477*e7be843bSPierre Pronchery          * Checking that the negotiated group matches our expectation
478*e7be843bSPierre Pronchery          * and must be identical on server and client
479*e7be843bSPierre Pronchery          * and must be expected SH or HRR
480*e7be843bSPierre Pronchery          */
481*e7be843bSPierre Pronchery         negotiated_group_client = SSL_get_negotiated_group(clientssl);
482*e7be843bSPierre Pronchery         negotiated_group_server = SSL_get_negotiated_group(serverssl);
483*e7be843bSPierre Pronchery         group_name_client = SSL_group_to_name(clientssl, negotiated_group_client);
484*e7be843bSPierre Pronchery         if (!TEST_int_eq(negotiated_group_client, negotiated_group_server))
485*e7be843bSPierre Pronchery             goto end;
486*e7be843bSPierre Pronchery         if (!TEST_int_eq((int)current_test_vector->expected_server_response, (int)server_response))
487*e7be843bSPierre Pronchery             goto end;
488*e7be843bSPierre Pronchery         if (TEST_str_eq(group_name_client, current_test_vector->expected_group))
489*e7be843bSPierre Pronchery             ok = 1;
490*e7be843bSPierre Pronchery     } else {
491*e7be843bSPierre Pronchery         TEST_false_or_end(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE));
492*e7be843bSPierre Pronchery         ok = 1;
493*e7be843bSPierre Pronchery     }
494*e7be843bSPierre Pronchery 
495*e7be843bSPierre Pronchery end:
496*e7be843bSPierre Pronchery     SSL_free(serverssl);
497*e7be843bSPierre Pronchery     SSL_free(clientssl);
498*e7be843bSPierre Pronchery     SSL_CTX_free(server_ctx);
499*e7be843bSPierre Pronchery     SSL_CTX_free(client_ctx);
500*e7be843bSPierre Pronchery     return ok;
501*e7be843bSPierre Pronchery }
502*e7be843bSPierre Pronchery 
tls13groupselection_test(int i)503*e7be843bSPierre Pronchery static int tls13groupselection_test(int i)
504*e7be843bSPierre Pronchery {
505*e7be843bSPierre Pronchery     int testresult = 1; /* Assume the test will succeed */
506*e7be843bSPierre Pronchery     int res = 0;
507*e7be843bSPierre Pronchery     TEST_TYPE test_type = TEST_NEGOTIATION_SUCCESS;
508*e7be843bSPierre Pronchery 
509*e7be843bSPierre Pronchery     /*
510*e7be843bSPierre Pronchery      * Call the code under test, once such that the ssl object is used and
511*e7be843bSPierre Pronchery      * once such that the ctx is used. If any of the tests fail (= return 0),
512*e7be843bSPierre Pronchery      * the end result will be 0 thanks to multiplication
513*e7be843bSPierre Pronchery      */
514*e7be843bSPierre Pronchery     TEST_info("==> Running TLSv1.3 test %d", i);
515*e7be843bSPierre Pronchery 
516*e7be843bSPierre Pronchery     if (strncmp(tls13groupselection_tests[i].expected_group,
517*e7be843bSPierre Pronchery                 SYNTAX_FAILURE, sizeof(SYNTAX_FAILURE)) == 0)
518*e7be843bSPierre Pronchery         test_type = TEST_SYNTAX_FAILURE;
519*e7be843bSPierre Pronchery     else if (strncmp(tls13groupselection_tests[i].expected_group,
520*e7be843bSPierre Pronchery                      NEGOTIATION_FAILURE, sizeof(NEGOTIATION_FAILURE)) == 0)
521*e7be843bSPierre Pronchery         test_type = TEST_NEGOTIATION_FAILURE;
522*e7be843bSPierre Pronchery 
523*e7be843bSPierre Pronchery     if (test_type == TEST_SYNTAX_FAILURE)
524*e7be843bSPierre Pronchery         res = test_invalidsyntax(&tls13groupselection_tests[i],
525*e7be843bSPierre Pronchery                                  WORK_ON_SSL_OBJECT);
526*e7be843bSPierre Pronchery     else
527*e7be843bSPierre Pronchery         res = test_groupnegotiation(&tls13groupselection_tests[i],
528*e7be843bSPierre Pronchery                                     WORK_ON_SSL_OBJECT, test_type);
529*e7be843bSPierre Pronchery 
530*e7be843bSPierre Pronchery     if (!res)
531*e7be843bSPierre Pronchery         TEST_error("====> [ERROR] TLSv1.3 test %d with WORK_ON_SSL_OBJECT failed", i);
532*e7be843bSPierre Pronchery     testresult *= res;
533*e7be843bSPierre Pronchery 
534*e7be843bSPierre Pronchery     if (test_type == TEST_SYNTAX_FAILURE)
535*e7be843bSPierre Pronchery         res = test_invalidsyntax(&tls13groupselection_tests[i],
536*e7be843bSPierre Pronchery                                  WORK_ON_CONTEXT);
537*e7be843bSPierre Pronchery     else
538*e7be843bSPierre Pronchery         res = test_groupnegotiation(&tls13groupselection_tests[i],
539*e7be843bSPierre Pronchery                                     WORK_ON_CONTEXT, test_type);
540*e7be843bSPierre Pronchery 
541*e7be843bSPierre Pronchery     if (!res)
542*e7be843bSPierre Pronchery         TEST_error("====> [ERROR] TLSv1.3 test %d with WORK_ON_CONTEXT failed", i);
543*e7be843bSPierre Pronchery     testresult *= res;
544*e7be843bSPierre Pronchery 
545*e7be843bSPierre Pronchery     return testresult;
546*e7be843bSPierre Pronchery }
547*e7be843bSPierre Pronchery 
setup_tests(void)548*e7be843bSPierre Pronchery int setup_tests(void)
549*e7be843bSPierre Pronchery {
550*e7be843bSPierre Pronchery     if (!TEST_ptr(cert = test_get_argument(0))
551*e7be843bSPierre Pronchery         || !TEST_ptr(privkey = test_get_argument(1)))
552*e7be843bSPierre Pronchery         return 0;
553*e7be843bSPierre Pronchery 
554*e7be843bSPierre Pronchery     ADD_ALL_TESTS(tls13groupselection_test, OSSL_NELEM(tls13groupselection_tests));
555*e7be843bSPierre Pronchery     return 1;
556*e7be843bSPierre Pronchery }
557