1189251Ssam/*
2189251Ssam * TLSv1 common routines
3252726Srpaulo * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
4189251Ssam *
5252726Srpaulo * This software may be distributed under the terms of the BSD license.
6252726Srpaulo * See README for more details.
7189251Ssam */
8189251Ssam
9189251Ssam#include "includes.h"
10189251Ssam
11189251Ssam#include "common.h"
12252726Srpaulo#include "crypto/sha1.h"
13252726Srpaulo#include "crypto/sha256.h"
14189251Ssam#include "x509v3.h"
15189251Ssam#include "tlsv1_common.h"
16189251Ssam
17189251Ssam
18189251Ssam/*
19189251Ssam * TODO:
20189251Ssam * RFC 2246 Section 9: Mandatory to implement TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
21189251Ssam * Add support for commonly used cipher suites; don't bother with exportable
22189251Ssam * suites.
23189251Ssam */
24189251Ssam
25189251Ssamstatic const struct tls_cipher_suite tls_cipher_suites[] = {
26189251Ssam	{ TLS_NULL_WITH_NULL_NULL, TLS_KEY_X_NULL, TLS_CIPHER_NULL,
27189251Ssam	  TLS_HASH_NULL },
28189251Ssam	{ TLS_RSA_WITH_RC4_128_MD5, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128,
29189251Ssam	  TLS_HASH_MD5 },
30189251Ssam	{ TLS_RSA_WITH_RC4_128_SHA, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128,
31189251Ssam	  TLS_HASH_SHA },
32189251Ssam	{ TLS_RSA_WITH_DES_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_DES_CBC,
33189251Ssam	  TLS_HASH_SHA },
34189251Ssam	{ TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_RSA,
35189251Ssam	  TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA },
36189251Ssam 	{ TLS_DH_anon_WITH_RC4_128_MD5, TLS_KEY_X_DH_anon,
37189251Ssam	  TLS_CIPHER_RC4_128, TLS_HASH_MD5 },
38189251Ssam 	{ TLS_DH_anon_WITH_DES_CBC_SHA, TLS_KEY_X_DH_anon,
39189251Ssam	  TLS_CIPHER_DES_CBC, TLS_HASH_SHA },
40189251Ssam 	{ TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_DH_anon,
41189251Ssam	  TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA },
42189251Ssam	{ TLS_RSA_WITH_AES_128_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_128_CBC,
43189251Ssam	  TLS_HASH_SHA },
44189251Ssam	{ TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_KEY_X_DH_anon,
45189251Ssam	  TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA },
46189251Ssam	{ TLS_RSA_WITH_AES_256_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_256_CBC,
47189251Ssam	  TLS_HASH_SHA },
48189251Ssam	{ TLS_DH_anon_WITH_AES_256_CBC_SHA, TLS_KEY_X_DH_anon,
49252726Srpaulo	  TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA },
50252726Srpaulo	{ TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_KEY_X_RSA,
51252726Srpaulo	  TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA256 },
52252726Srpaulo	{ TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_KEY_X_RSA,
53252726Srpaulo	  TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA256 },
54252726Srpaulo	{ TLS_DH_anon_WITH_AES_128_CBC_SHA256, TLS_KEY_X_DH_anon,
55252726Srpaulo	  TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA256 },
56252726Srpaulo	{ TLS_DH_anon_WITH_AES_256_CBC_SHA256, TLS_KEY_X_DH_anon,
57252726Srpaulo	  TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA256 }
58189251Ssam};
59189251Ssam
60189251Ssam#define NUM_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
61189251Ssam#define NUM_TLS_CIPHER_SUITES NUM_ELEMS(tls_cipher_suites)
62189251Ssam
63189251Ssam
64189251Ssamstatic const struct tls_cipher_data tls_ciphers[] = {
65189251Ssam	{ TLS_CIPHER_NULL,         TLS_CIPHER_STREAM,  0,  0,  0,
66189251Ssam	  CRYPTO_CIPHER_NULL },
67189251Ssam	{ TLS_CIPHER_IDEA_CBC,     TLS_CIPHER_BLOCK,  16, 16,  8,
68189251Ssam	  CRYPTO_CIPHER_NULL },
69189251Ssam	{ TLS_CIPHER_RC2_CBC_40,   TLS_CIPHER_BLOCK,   5, 16,  0,
70189251Ssam	  CRYPTO_CIPHER_ALG_RC2 },
71189251Ssam	{ TLS_CIPHER_RC4_40,       TLS_CIPHER_STREAM,  5, 16,  0,
72189251Ssam	  CRYPTO_CIPHER_ALG_RC4 },
73189251Ssam	{ TLS_CIPHER_RC4_128,      TLS_CIPHER_STREAM, 16, 16,  0,
74189251Ssam	  CRYPTO_CIPHER_ALG_RC4 },
75189251Ssam	{ TLS_CIPHER_DES40_CBC,    TLS_CIPHER_BLOCK,   5,  8,  8,
76189251Ssam	  CRYPTO_CIPHER_ALG_DES },
77189251Ssam	{ TLS_CIPHER_DES_CBC,      TLS_CIPHER_BLOCK,   8,  8,  8,
78189251Ssam	  CRYPTO_CIPHER_ALG_DES },
79189251Ssam	{ TLS_CIPHER_3DES_EDE_CBC, TLS_CIPHER_BLOCK,  24, 24,  8,
80189251Ssam	  CRYPTO_CIPHER_ALG_3DES },
81189251Ssam	{ TLS_CIPHER_AES_128_CBC,  TLS_CIPHER_BLOCK,  16, 16, 16,
82189251Ssam	  CRYPTO_CIPHER_ALG_AES },
83189251Ssam	{ TLS_CIPHER_AES_256_CBC,  TLS_CIPHER_BLOCK,  32, 32, 16,
84189251Ssam	  CRYPTO_CIPHER_ALG_AES }
85189251Ssam};
86189251Ssam
87189251Ssam#define NUM_TLS_CIPHER_DATA NUM_ELEMS(tls_ciphers)
88189251Ssam
89189251Ssam
90189251Ssam/**
91189251Ssam * tls_get_cipher_suite - Get TLS cipher suite
92189251Ssam * @suite: Cipher suite identifier
93189251Ssam * Returns: Pointer to the cipher data or %NULL if not found
94189251Ssam */
95189251Ssamconst struct tls_cipher_suite * tls_get_cipher_suite(u16 suite)
96189251Ssam{
97189251Ssam	size_t i;
98189251Ssam	for (i = 0; i < NUM_TLS_CIPHER_SUITES; i++)
99189251Ssam		if (tls_cipher_suites[i].suite == suite)
100189251Ssam			return &tls_cipher_suites[i];
101189251Ssam	return NULL;
102189251Ssam}
103189251Ssam
104189251Ssam
105189251Ssamconst struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher)
106189251Ssam{
107189251Ssam	size_t i;
108189251Ssam	for (i = 0; i < NUM_TLS_CIPHER_DATA; i++)
109189251Ssam		if (tls_ciphers[i].cipher == cipher)
110189251Ssam			return &tls_ciphers[i];
111189251Ssam	return NULL;
112189251Ssam}
113189251Ssam
114189251Ssam
115189251Ssamint tls_server_key_exchange_allowed(tls_cipher cipher)
116189251Ssam{
117189251Ssam	const struct tls_cipher_suite *suite;
118189251Ssam
119189251Ssam	/* RFC 2246, Section 7.4.3 */
120189251Ssam	suite = tls_get_cipher_suite(cipher);
121189251Ssam	if (suite == NULL)
122189251Ssam		return 0;
123189251Ssam
124189251Ssam	switch (suite->key_exchange) {
125189251Ssam	case TLS_KEY_X_DHE_DSS:
126189251Ssam	case TLS_KEY_X_DHE_DSS_EXPORT:
127189251Ssam	case TLS_KEY_X_DHE_RSA:
128189251Ssam	case TLS_KEY_X_DHE_RSA_EXPORT:
129189251Ssam	case TLS_KEY_X_DH_anon_EXPORT:
130189251Ssam	case TLS_KEY_X_DH_anon:
131189251Ssam		return 1;
132189251Ssam	case TLS_KEY_X_RSA_EXPORT:
133189251Ssam		return 1 /* FIX: public key len > 512 bits */;
134189251Ssam	default:
135189251Ssam		return 0;
136189251Ssam	}
137189251Ssam}
138189251Ssam
139189251Ssam
140189251Ssam/**
141189251Ssam * tls_parse_cert - Parse DER encoded X.509 certificate and get public key
142189251Ssam * @buf: ASN.1 DER encoded certificate
143189251Ssam * @len: Length of the buffer
144189251Ssam * @pk: Buffer for returning the allocated public key
145189251Ssam * Returns: 0 on success, -1 on failure
146189251Ssam *
147189251Ssam * This functions parses an ASN.1 DER encoded X.509 certificate and retrieves
148189251Ssam * the public key from it. The caller is responsible for freeing the public key
149189251Ssam * by calling crypto_public_key_free().
150189251Ssam */
151189251Ssamint tls_parse_cert(const u8 *buf, size_t len, struct crypto_public_key **pk)
152189251Ssam{
153189251Ssam	struct x509_certificate *cert;
154189251Ssam
155189251Ssam	wpa_hexdump(MSG_MSGDUMP, "TLSv1: Parse ASN.1 DER certificate",
156189251Ssam		    buf, len);
157189251Ssam
158189251Ssam	*pk = crypto_public_key_from_cert(buf, len);
159189251Ssam	if (*pk)
160189251Ssam		return 0;
161189251Ssam
162189251Ssam	cert = x509_certificate_parse(buf, len);
163189251Ssam	if (cert == NULL) {
164189251Ssam		wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse X.509 "
165189251Ssam			   "certificate");
166189251Ssam		return -1;
167189251Ssam	}
168189251Ssam
169189251Ssam	/* TODO
170189251Ssam	 * verify key usage (must allow encryption)
171189251Ssam	 *
172189251Ssam	 * All certificate profiles, key and cryptographic formats are
173189251Ssam	 * defined by the IETF PKIX working group [PKIX]. When a key
174189251Ssam	 * usage extension is present, the digitalSignature bit must be
175189251Ssam	 * set for the key to be eligible for signing, as described
176189251Ssam	 * above, and the keyEncipherment bit must be present to allow
177189251Ssam	 * encryption, as described above. The keyAgreement bit must be
178189251Ssam	 * set on Diffie-Hellman certificates. (PKIX: RFC 3280)
179189251Ssam	 */
180189251Ssam
181189251Ssam	*pk = crypto_public_key_import(cert->public_key, cert->public_key_len);
182189251Ssam	x509_certificate_free(cert);
183189251Ssam
184189251Ssam	if (*pk == NULL) {
185189251Ssam		wpa_printf(MSG_ERROR, "TLSv1: Failed to import "
186189251Ssam			   "server public key");
187189251Ssam		return -1;
188189251Ssam	}
189189251Ssam
190189251Ssam	return 0;
191189251Ssam}
192189251Ssam
193189251Ssam
194189251Ssamint tls_verify_hash_init(struct tls_verify_hash *verify)
195189251Ssam{
196189251Ssam	tls_verify_hash_free(verify);
197189251Ssam	verify->md5_client = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
198189251Ssam	verify->md5_server = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
199189251Ssam	verify->md5_cert = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
200189251Ssam	verify->sha1_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
201189251Ssam	verify->sha1_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
202189251Ssam	verify->sha1_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
203189251Ssam	if (verify->md5_client == NULL || verify->md5_server == NULL ||
204189251Ssam	    verify->md5_cert == NULL || verify->sha1_client == NULL ||
205189251Ssam	    verify->sha1_server == NULL || verify->sha1_cert == NULL) {
206189251Ssam		tls_verify_hash_free(verify);
207189251Ssam		return -1;
208189251Ssam	}
209252726Srpaulo#ifdef CONFIG_TLSV12
210252726Srpaulo	verify->sha256_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL,
211252726Srpaulo						 0);
212252726Srpaulo	verify->sha256_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL,
213252726Srpaulo						 0);
214252726Srpaulo	verify->sha256_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL,
215252726Srpaulo					       0);
216252726Srpaulo	if (verify->sha256_client == NULL || verify->sha256_server == NULL ||
217252726Srpaulo	    verify->sha256_cert == NULL) {
218252726Srpaulo		tls_verify_hash_free(verify);
219252726Srpaulo		return -1;
220252726Srpaulo	}
221252726Srpaulo#endif /* CONFIG_TLSV12 */
222189251Ssam	return 0;
223189251Ssam}
224189251Ssam
225189251Ssam
226189251Ssamvoid tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf,
227189251Ssam			 size_t len)
228189251Ssam{
229189251Ssam	if (verify->md5_client && verify->sha1_client) {
230189251Ssam		crypto_hash_update(verify->md5_client, buf, len);
231189251Ssam		crypto_hash_update(verify->sha1_client, buf, len);
232189251Ssam	}
233189251Ssam	if (verify->md5_server && verify->sha1_server) {
234189251Ssam		crypto_hash_update(verify->md5_server, buf, len);
235189251Ssam		crypto_hash_update(verify->sha1_server, buf, len);
236189251Ssam	}
237189251Ssam	if (verify->md5_cert && verify->sha1_cert) {
238189251Ssam		crypto_hash_update(verify->md5_cert, buf, len);
239189251Ssam		crypto_hash_update(verify->sha1_cert, buf, len);
240189251Ssam	}
241252726Srpaulo#ifdef CONFIG_TLSV12
242252726Srpaulo	if (verify->sha256_client)
243252726Srpaulo		crypto_hash_update(verify->sha256_client, buf, len);
244252726Srpaulo	if (verify->sha256_server)
245252726Srpaulo		crypto_hash_update(verify->sha256_server, buf, len);
246252726Srpaulo	if (verify->sha256_cert)
247252726Srpaulo		crypto_hash_update(verify->sha256_cert, buf, len);
248252726Srpaulo#endif /* CONFIG_TLSV12 */
249189251Ssam}
250189251Ssam
251189251Ssam
252189251Ssamvoid tls_verify_hash_free(struct tls_verify_hash *verify)
253189251Ssam{
254189251Ssam	crypto_hash_finish(verify->md5_client, NULL, NULL);
255189251Ssam	crypto_hash_finish(verify->md5_server, NULL, NULL);
256189251Ssam	crypto_hash_finish(verify->md5_cert, NULL, NULL);
257189251Ssam	crypto_hash_finish(verify->sha1_client, NULL, NULL);
258189251Ssam	crypto_hash_finish(verify->sha1_server, NULL, NULL);
259189251Ssam	crypto_hash_finish(verify->sha1_cert, NULL, NULL);
260189251Ssam	verify->md5_client = NULL;
261189251Ssam	verify->md5_server = NULL;
262189251Ssam	verify->md5_cert = NULL;
263189251Ssam	verify->sha1_client = NULL;
264189251Ssam	verify->sha1_server = NULL;
265189251Ssam	verify->sha1_cert = NULL;
266252726Srpaulo#ifdef CONFIG_TLSV12
267252726Srpaulo	crypto_hash_finish(verify->sha256_client, NULL, NULL);
268252726Srpaulo	crypto_hash_finish(verify->sha256_server, NULL, NULL);
269252726Srpaulo	crypto_hash_finish(verify->sha256_cert, NULL, NULL);
270252726Srpaulo	verify->sha256_client = NULL;
271252726Srpaulo	verify->sha256_server = NULL;
272252726Srpaulo	verify->sha256_cert = NULL;
273252726Srpaulo#endif /* CONFIG_TLSV12 */
274189251Ssam}
275252726Srpaulo
276252726Srpaulo
277252726Srpauloint tls_version_ok(u16 ver)
278252726Srpaulo{
279252726Srpaulo	if (ver == TLS_VERSION_1)
280252726Srpaulo		return 1;
281252726Srpaulo#ifdef CONFIG_TLSV11
282252726Srpaulo	if (ver == TLS_VERSION_1_1)
283252726Srpaulo		return 1;
284252726Srpaulo#endif /* CONFIG_TLSV11 */
285252726Srpaulo#ifdef CONFIG_TLSV12
286252726Srpaulo	if (ver == TLS_VERSION_1_2)
287252726Srpaulo		return 1;
288252726Srpaulo#endif /* CONFIG_TLSV12 */
289252726Srpaulo
290252726Srpaulo	return 0;
291252726Srpaulo}
292252726Srpaulo
293252726Srpaulo
294252726Srpauloconst char * tls_version_str(u16 ver)
295252726Srpaulo{
296252726Srpaulo	switch (ver) {
297252726Srpaulo	case TLS_VERSION_1:
298252726Srpaulo		return "1.0";
299252726Srpaulo	case TLS_VERSION_1_1:
300252726Srpaulo		return "1.1";
301252726Srpaulo	case TLS_VERSION_1_2:
302252726Srpaulo		return "1.2";
303252726Srpaulo	}
304252726Srpaulo
305252726Srpaulo	return "?";
306252726Srpaulo}
307252726Srpaulo
308252726Srpaulo
309252726Srpauloint tls_prf(u16 ver, const u8 *secret, size_t secret_len, const char *label,
310252726Srpaulo	    const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
311252726Srpaulo{
312252726Srpaulo#ifdef CONFIG_TLSV12
313252726Srpaulo	if (ver >= TLS_VERSION_1_2) {
314252726Srpaulo		tls_prf_sha256(secret, secret_len, label, seed, seed_len,
315252726Srpaulo			       out, outlen);
316252726Srpaulo		return 0;
317252726Srpaulo	}
318252726Srpaulo#endif /* CONFIG_TLSV12 */
319252726Srpaulo
320252726Srpaulo	return tls_prf_sha1_md5(secret, secret_len, label, seed, seed_len, out,
321252726Srpaulo				outlen);
322252726Srpaulo}
323