xref: /openbsd/regress/lib/libssl/unit/tls_prf.c (revision d89ec533)
1 /* $OpenBSD: tls_prf.c,v 1.5 2021/03/24 19:02:35 jsing Exp $ */
2 /*
3  * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <err.h>
19 
20 #include "ssl_locl.h"
21 
22 int tls1_PRF(SSL *s, const unsigned char *secret, size_t secret_len,
23     const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len,
24     const void *seed3, size_t seed3_len, const void *seed4, size_t seed4_len,
25     const void *seed5, size_t seed5_len, unsigned char *out, size_t out_len);
26 
27 #define TLS_PRF_OUT_LEN 128
28 
29 struct tls_prf_test {
30 	const unsigned char *desc;
31 	const SSL_METHOD *(*ssl_method)(void);
32 	const uint16_t cipher_value;
33 	const unsigned char out[TLS_PRF_OUT_LEN];
34 };
35 
36 static struct tls_prf_test tls_prf_tests[] = {
37 	{
38 		.desc = "MD5+SHA1",
39 		.ssl_method = TLSv1_method,
40 		.cipher_value = 0x0033,
41 		.out = {
42 			0x03, 0xa1, 0xc1, 0x7d, 0x2c, 0xa5, 0x3d, 0xe8,
43 			0x9d, 0x59, 0x5e, 0x30, 0xf5, 0x71, 0xbb, 0x96,
44 			0xde, 0x5c, 0x8e, 0xdc, 0x25, 0x8a, 0x7c, 0x05,
45 			0x9f, 0x7d, 0x35, 0x29, 0x45, 0xae, 0x56, 0xad,
46 			0x9f, 0x57, 0x15, 0x5c, 0xdb, 0x83, 0x3a, 0xac,
47 			0x19, 0xa8, 0x2b, 0x40, 0x72, 0x38, 0x1e, 0xed,
48 			0xf3, 0x25, 0xde, 0x84, 0x84, 0xd8, 0xd1, 0xfc,
49 			0x31, 0x85, 0x81, 0x12, 0x55, 0x4d, 0x12, 0xb5,
50 			0xed, 0x78, 0x5e, 0xba, 0xc8, 0xec, 0x8d, 0x28,
51 			0xa1, 0x21, 0x1e, 0x6e, 0x07, 0xf1, 0xfc, 0xf5,
52 			0xbf, 0xe4, 0x8e, 0x8e, 0x97, 0x15, 0x93, 0x85,
53 			0x75, 0xdd, 0x87, 0x09, 0xd0, 0x4e, 0xe5, 0xd5,
54 			0x9e, 0x1f, 0xd6, 0x1c, 0x3b, 0xe9, 0xad, 0xba,
55 			0xe0, 0x16, 0x56, 0x62, 0x90, 0xd6, 0x82, 0x84,
56 			0xec, 0x8a, 0x22, 0xbe, 0xdc, 0x6a, 0x5e, 0x05,
57 			0x12, 0x44, 0xec, 0x60, 0x61, 0xd1, 0x8a, 0x66,
58 		},
59 	},
60 	{
61 		.desc = "GOST94",
62 		.ssl_method = TLSv1_2_method,
63 		.cipher_value = 0x0081,
64 		.out = {
65 			 0xcc, 0xd4, 0x89, 0x5f, 0x52, 0x08, 0x9b, 0xc7,
66 			 0xf9, 0xb5, 0x83, 0x58, 0xe8, 0xc7, 0x71, 0x49,
67 			 0x39, 0x99, 0x1f, 0x14, 0x8f, 0x85, 0xbe, 0x64,
68 			 0xee, 0x40, 0x5c, 0xe7, 0x5f, 0x68, 0xaf, 0xf2,
69 			 0xcd, 0x3a, 0x94, 0x52, 0x33, 0x53, 0x46, 0x7d,
70 			 0xb6, 0xc5, 0xe1, 0xb8, 0xa4, 0x04, 0x69, 0x91,
71 			 0x0a, 0x9c, 0x88, 0x86, 0xd9, 0x60, 0x63, 0xdd,
72 			 0xd8, 0xe7, 0x2e, 0xee, 0xce, 0xe2, 0x20, 0xd8,
73 			 0x9a, 0xfa, 0x9c, 0x63, 0x0c, 0x9c, 0xa1, 0x76,
74 			 0xed, 0x78, 0x9a, 0x84, 0x70, 0xb4, 0xd1, 0x51,
75 			 0x1f, 0xde, 0x44, 0xe8, 0x90, 0x21, 0x3f, 0xeb,
76 			 0x05, 0xf4, 0x77, 0x59, 0xf3, 0xad, 0xdd, 0x34,
77 			 0x3d, 0x3a, 0x7c, 0xd0, 0x59, 0x40, 0xe1, 0x3f,
78 			 0x04, 0x4b, 0x8b, 0xd6, 0x95, 0x46, 0xb4, 0x9e,
79 			 0x4c, 0x2d, 0xf7, 0xee, 0xbd, 0xbc, 0xcb, 0x5c,
80 			 0x3a, 0x36, 0x0c, 0xd0, 0x27, 0xcb, 0x45, 0x06,
81 		},
82 	},
83 	{
84 		.desc = "SHA256 (via TLSv1.2)",
85 		.ssl_method = TLSv1_2_method,
86 		.cipher_value = 0x0033,
87 		.out = {
88 			 0x37, 0xa7, 0x06, 0x71, 0x6e, 0x19, 0x19, 0xda,
89 			 0x23, 0x8c, 0xcc, 0xb4, 0x2f, 0x31, 0x64, 0x9d,
90 			 0x05, 0x29, 0x1c, 0x33, 0x7e, 0x09, 0x1b, 0x0c,
91 			 0x0e, 0x23, 0xc1, 0xb0, 0x40, 0xcc, 0x31, 0xf7,
92 			 0x55, 0x66, 0x68, 0xd9, 0xa8, 0xae, 0x74, 0x75,
93 			 0xf3, 0x46, 0xe9, 0x3a, 0x54, 0x9d, 0xe0, 0x8b,
94 			 0x7e, 0x6c, 0x63, 0x1c, 0xfa, 0x2f, 0xfd, 0xc9,
95 			 0xd3, 0xf1, 0xd3, 0xfe, 0x7b, 0x9e, 0x14, 0x95,
96 			 0xb5, 0xd0, 0xad, 0x9b, 0xee, 0x78, 0x8c, 0x83,
97 			 0x18, 0x58, 0x7e, 0xa2, 0x23, 0xc1, 0x8b, 0x62,
98 			 0x94, 0x12, 0xcb, 0xb6, 0x60, 0x69, 0x32, 0xfe,
99 			 0x98, 0x0e, 0x93, 0xb0, 0x8e, 0x5c, 0xfb, 0x6e,
100 			 0xdb, 0x9a, 0xc2, 0x9f, 0x8c, 0x5c, 0x43, 0x19,
101 			 0xeb, 0x4a, 0x52, 0xad, 0x62, 0x2b, 0xdd, 0x9f,
102 			 0xa3, 0x74, 0xa6, 0x96, 0x61, 0x4d, 0x98, 0x40,
103 			 0x63, 0xa6, 0xd4, 0xbb, 0x17, 0x11, 0x75, 0xed,
104 		},
105 	},
106 	{
107 		.desc = "SHA384",
108 		.ssl_method = TLSv1_2_method,
109 		.cipher_value = 0x009d,
110 		.out = {
111 			 0x00, 0x93, 0xc3, 0xfd, 0xa7, 0xbb, 0xdc, 0x5b,
112 			 0x13, 0x3a, 0xe6, 0x8b, 0x1b, 0xac, 0xf3, 0xfb,
113 			 0x3c, 0x9a, 0x78, 0xf6, 0x19, 0xf0, 0x13, 0x0f,
114 			 0x0d, 0x01, 0x9d, 0xdf, 0x0a, 0x28, 0x38, 0xce,
115 			 0x1a, 0x9b, 0x43, 0xbe, 0x56, 0x12, 0xa7, 0x16,
116 			 0x58, 0xe1, 0x8a, 0xe4, 0xc5, 0xbb, 0x10, 0x4c,
117 			 0x3a, 0xf3, 0x7f, 0xd3, 0xdb, 0xe4, 0xe0, 0x3d,
118 			 0xcc, 0x83, 0xca, 0xf0, 0xf9, 0x69, 0xcc, 0x70,
119 			 0x83, 0x32, 0xf6, 0xfc, 0x81, 0x80, 0x02, 0xe8,
120 			 0x31, 0x1e, 0x7c, 0x3b, 0x34, 0xf7, 0x34, 0xd1,
121 			 0xcf, 0x2a, 0xc4, 0x36, 0x2f, 0xe9, 0xaa, 0x7f,
122 			 0x6d, 0x1f, 0x5e, 0x0e, 0x39, 0x05, 0x15, 0xe1,
123 			 0xa2, 0x9a, 0x4d, 0x97, 0x8c, 0x62, 0x46, 0xf1,
124 			 0x87, 0x65, 0xd8, 0xe9, 0x14, 0x11, 0xa6, 0x48,
125 			 0xd7, 0x0e, 0x6e, 0x70, 0xad, 0xfb, 0x3f, 0x36,
126 			 0x05, 0x76, 0x4b, 0xe4, 0x28, 0x50, 0x4a, 0xf2,
127 		},
128 	},
129 	{
130 		.desc = "STREEBOG256",
131 		.ssl_method = TLSv1_2_method,
132 		.cipher_value = 0xff87,
133 		.out = {
134 			0x3e, 0x13, 0xb9, 0xeb, 0x85, 0x8c, 0xb4, 0x21,
135 			0x23, 0x40, 0x9b, 0x73, 0x04, 0x56, 0xe2, 0xff,
136 			0xce, 0x52, 0x1f, 0x82, 0x7f, 0x17, 0x5b, 0x80,
137 			0x23, 0x71, 0xca, 0x30, 0xdf, 0xfc, 0xdc, 0x2d,
138 			0xc0, 0xfc, 0x5d, 0x23, 0x5a, 0x54, 0x7f, 0xae,
139 			0xf5, 0x7d, 0x52, 0x1e, 0x86, 0x95, 0xe1, 0x2d,
140 			0x28, 0xe7, 0xbe, 0xd7, 0xd0, 0xbf, 0xa9, 0x96,
141 			0x13, 0xd0, 0x9c, 0x0c, 0x1c, 0x16, 0x05, 0xbb,
142 			0x26, 0xd7, 0x30, 0x39, 0xb9, 0x53, 0x28, 0x98,
143 			0x4f, 0x1b, 0x83, 0xc3, 0xce, 0x1c, 0x7c, 0x34,
144 			0xa2, 0xc4, 0x7a, 0x54, 0x16, 0xc6, 0xa7, 0x9e,
145 			0xed, 0x4b, 0x7b, 0x83, 0xa6, 0xae, 0xe2, 0x5b,
146 			0x96, 0xf5, 0x6c, 0xad, 0x1f, 0xa3, 0x83, 0xb2,
147 			0x84, 0x32, 0xed, 0xe3, 0x2c, 0xf6, 0xd4, 0x73,
148 			0x30, 0xef, 0x9d, 0xbe, 0xe7, 0x23, 0x9a, 0xbf,
149 			0x4d, 0x1c, 0xe7, 0xef, 0x3d, 0xea, 0x46, 0xe2,
150 		},
151 	},
152 };
153 
154 #define N_TLS_PRF_TESTS \
155     (sizeof(tls_prf_tests) / sizeof(*tls_prf_tests))
156 
157 #define TLS_PRF_SEED1	"tls prf seed 1"
158 #define TLS_PRF_SEED2	"tls prf seed 2"
159 #define TLS_PRF_SEED3	"tls prf seed 3"
160 #define TLS_PRF_SEED4	"tls prf seed 4"
161 #define TLS_PRF_SEED5	"tls prf seed 5"
162 #define TLS_PRF_SECRET	"tls prf secretz"
163 
164 static void
165 hexdump(const unsigned char *buf, size_t len)
166 {
167 	size_t i;
168 
169 	for (i = 1; i <= len; i++)
170 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
171 
172 	fprintf(stderr, "\n");
173 }
174 
175 static int
176 do_tls_prf_test(int test_no, struct tls_prf_test *tpt)
177 {
178 	unsigned char *out = NULL;
179 	const SSL_CIPHER *cipher;
180 	SSL_CTX *ssl_ctx = NULL;
181 	SSL *ssl = NULL;
182 	int failure = 1;
183 	int len;
184 
185 	fprintf(stderr, "Test %i - %s\n", test_no, tpt->desc);
186 
187 	if ((out = malloc(TLS_PRF_OUT_LEN)) == NULL)
188 		errx(1, "failed to allocate out");
189 
190 	if ((ssl_ctx = SSL_CTX_new(tpt->ssl_method())) == NULL)
191 		errx(1, "failed to create SSL context");
192 	if ((ssl = SSL_new(ssl_ctx)) == NULL)
193 		errx(1, "failed to create SSL context");
194 
195 	if ((cipher = ssl3_get_cipher_by_value(tpt->cipher_value)) == NULL) {
196 		fprintf(stderr, "FAIL: no cipher %hx\n", tpt->cipher_value);
197 		goto failure;
198 	}
199 
200 	S3I(ssl)->hs.cipher = cipher;
201 
202 	for (len = 1; len <= TLS_PRF_OUT_LEN; len++) {
203 		memset(out, 'A', TLS_PRF_OUT_LEN);
204 
205 		if (tls1_PRF(ssl, TLS_PRF_SECRET, sizeof(TLS_PRF_SECRET),
206 		    TLS_PRF_SEED1, sizeof(TLS_PRF_SEED1), TLS_PRF_SEED2,
207 		    sizeof(TLS_PRF_SEED2), TLS_PRF_SEED3, sizeof(TLS_PRF_SEED3),
208 		    TLS_PRF_SEED4, sizeof(TLS_PRF_SEED4), TLS_PRF_SEED5,
209 		    sizeof(TLS_PRF_SEED5), out, len) != 1) {
210 			fprintf(stderr, "FAIL: tls_PRF failed for len %i\n",
211 			    len);
212 			goto failure;
213 		}
214 
215 		if (memcmp(out, tpt->out, len) != 0) {
216 			fprintf(stderr, "FAIL: tls_PRF output differs for "
217 			    "len %i\n", len);
218 			fprintf(stderr, "output:\n");
219 			hexdump(out, TLS_PRF_OUT_LEN);
220 			fprintf(stderr, "test data:\n");
221 			hexdump(tpt->out, TLS_PRF_OUT_LEN);
222 			fprintf(stderr, "\n");
223 			goto failure;
224 		}
225 	}
226 
227 	failure = 0;
228 
229  failure:
230 	SSL_free(ssl);
231 	SSL_CTX_free(ssl_ctx);
232 
233 	free(out);
234 
235 	return failure;
236 }
237 
238 int
239 main(int argc, char **argv)
240 {
241 	int failed = 0;
242 	size_t i;
243 
244 	SSL_library_init();
245 	SSL_load_error_strings();
246 
247 	for (i = 0; i < N_TLS_PRF_TESTS; i++)
248 		failed |= do_tls_prf_test(i, &tls_prf_tests[i]);
249 
250 	return failed;
251 }
252