xref: /dflybsd-src/contrib/wpa_supplicant/src/tls/tlsv1_common.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
16d49e1aeSJan Lentfer /*
26d49e1aeSJan Lentfer  * TLSv1 common routines
3*a1157835SDaniel Fojt  * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi>
46d49e1aeSJan Lentfer  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
76d49e1aeSJan Lentfer  */
86d49e1aeSJan Lentfer 
96d49e1aeSJan Lentfer #include "includes.h"
106d49e1aeSJan Lentfer 
116d49e1aeSJan Lentfer #include "common.h"
12*a1157835SDaniel Fojt #include "crypto/md5.h"
133ff40c12SJohn Marino #include "crypto/sha1.h"
143ff40c12SJohn Marino #include "crypto/sha256.h"
156d49e1aeSJan Lentfer #include "x509v3.h"
166d49e1aeSJan Lentfer #include "tlsv1_common.h"
176d49e1aeSJan Lentfer 
186d49e1aeSJan Lentfer 
196d49e1aeSJan Lentfer /*
206d49e1aeSJan Lentfer  * TODO:
216d49e1aeSJan Lentfer  * RFC 2246 Section 9: Mandatory to implement TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
226d49e1aeSJan Lentfer  * Add support for commonly used cipher suites; don't bother with exportable
236d49e1aeSJan Lentfer  * suites.
246d49e1aeSJan Lentfer  */
256d49e1aeSJan Lentfer 
266d49e1aeSJan Lentfer static const struct tls_cipher_suite tls_cipher_suites[] = {
276d49e1aeSJan Lentfer 	{ TLS_NULL_WITH_NULL_NULL, TLS_KEY_X_NULL, TLS_CIPHER_NULL,
286d49e1aeSJan Lentfer 	  TLS_HASH_NULL },
296d49e1aeSJan Lentfer 	{ TLS_RSA_WITH_RC4_128_MD5, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128,
306d49e1aeSJan Lentfer 	  TLS_HASH_MD5 },
316d49e1aeSJan Lentfer 	{ TLS_RSA_WITH_RC4_128_SHA, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128,
326d49e1aeSJan Lentfer 	  TLS_HASH_SHA },
336d49e1aeSJan Lentfer 	{ TLS_RSA_WITH_DES_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_DES_CBC,
346d49e1aeSJan Lentfer 	  TLS_HASH_SHA },
356d49e1aeSJan Lentfer 	{ TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_RSA,
366d49e1aeSJan Lentfer 	  TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA },
37*a1157835SDaniel Fojt 	{ TLS_DHE_RSA_WITH_DES_CBC_SHA, TLS_KEY_X_DHE_RSA, TLS_CIPHER_DES_CBC,
38*a1157835SDaniel Fojt 	  TLS_HASH_SHA},
39*a1157835SDaniel Fojt 	{ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_DHE_RSA,
40*a1157835SDaniel Fojt 	  TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA },
416d49e1aeSJan Lentfer  	{ TLS_DH_anon_WITH_RC4_128_MD5, TLS_KEY_X_DH_anon,
426d49e1aeSJan Lentfer 	  TLS_CIPHER_RC4_128, TLS_HASH_MD5 },
436d49e1aeSJan Lentfer  	{ TLS_DH_anon_WITH_DES_CBC_SHA, TLS_KEY_X_DH_anon,
446d49e1aeSJan Lentfer 	  TLS_CIPHER_DES_CBC, TLS_HASH_SHA },
456d49e1aeSJan Lentfer  	{ TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_DH_anon,
466d49e1aeSJan Lentfer 	  TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA },
476d49e1aeSJan Lentfer 	{ TLS_RSA_WITH_AES_128_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_128_CBC,
486d49e1aeSJan Lentfer 	  TLS_HASH_SHA },
49*a1157835SDaniel Fojt 	{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_KEY_X_DHE_RSA,
50*a1157835SDaniel Fojt 	  TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA },
516d49e1aeSJan Lentfer 	{ TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_KEY_X_DH_anon,
526d49e1aeSJan Lentfer 	  TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA },
536d49e1aeSJan Lentfer 	{ TLS_RSA_WITH_AES_256_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_256_CBC,
546d49e1aeSJan Lentfer 	  TLS_HASH_SHA },
55*a1157835SDaniel Fojt 	{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_KEY_X_DHE_RSA,
56*a1157835SDaniel Fojt 	  TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA },
576d49e1aeSJan Lentfer 	{ TLS_DH_anon_WITH_AES_256_CBC_SHA, TLS_KEY_X_DH_anon,
583ff40c12SJohn Marino 	  TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA },
593ff40c12SJohn Marino 	{ TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_KEY_X_RSA,
603ff40c12SJohn Marino 	  TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA256 },
613ff40c12SJohn Marino 	{ TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_KEY_X_RSA,
623ff40c12SJohn Marino 	  TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA256 },
63*a1157835SDaniel Fojt 	{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_KEY_X_DHE_RSA,
64*a1157835SDaniel Fojt 	  TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA256 },
65*a1157835SDaniel Fojt 	{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_KEY_X_DHE_RSA,
66*a1157835SDaniel Fojt 	  TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA256 },
673ff40c12SJohn Marino 	{ TLS_DH_anon_WITH_AES_128_CBC_SHA256, TLS_KEY_X_DH_anon,
683ff40c12SJohn Marino 	  TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA256 },
693ff40c12SJohn Marino 	{ TLS_DH_anon_WITH_AES_256_CBC_SHA256, TLS_KEY_X_DH_anon,
703ff40c12SJohn Marino 	  TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA256 }
716d49e1aeSJan Lentfer };
726d49e1aeSJan Lentfer 
733ff40c12SJohn Marino #define NUM_TLS_CIPHER_SUITES ARRAY_SIZE(tls_cipher_suites)
746d49e1aeSJan Lentfer 
756d49e1aeSJan Lentfer 
766d49e1aeSJan Lentfer static const struct tls_cipher_data tls_ciphers[] = {
776d49e1aeSJan Lentfer 	{ TLS_CIPHER_NULL,         TLS_CIPHER_STREAM,  0,  0,  0,
786d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_NULL },
796d49e1aeSJan Lentfer 	{ TLS_CIPHER_IDEA_CBC,     TLS_CIPHER_BLOCK,  16, 16,  8,
806d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_NULL },
816d49e1aeSJan Lentfer 	{ TLS_CIPHER_RC2_CBC_40,   TLS_CIPHER_BLOCK,   5, 16,  0,
826d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_ALG_RC2 },
836d49e1aeSJan Lentfer 	{ TLS_CIPHER_RC4_40,       TLS_CIPHER_STREAM,  5, 16,  0,
846d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_ALG_RC4 },
856d49e1aeSJan Lentfer 	{ TLS_CIPHER_RC4_128,      TLS_CIPHER_STREAM, 16, 16,  0,
866d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_ALG_RC4 },
876d49e1aeSJan Lentfer 	{ TLS_CIPHER_DES40_CBC,    TLS_CIPHER_BLOCK,   5,  8,  8,
886d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_ALG_DES },
896d49e1aeSJan Lentfer 	{ TLS_CIPHER_DES_CBC,      TLS_CIPHER_BLOCK,   8,  8,  8,
906d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_ALG_DES },
916d49e1aeSJan Lentfer 	{ TLS_CIPHER_3DES_EDE_CBC, TLS_CIPHER_BLOCK,  24, 24,  8,
926d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_ALG_3DES },
936d49e1aeSJan Lentfer 	{ TLS_CIPHER_AES_128_CBC,  TLS_CIPHER_BLOCK,  16, 16, 16,
946d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_ALG_AES },
956d49e1aeSJan Lentfer 	{ TLS_CIPHER_AES_256_CBC,  TLS_CIPHER_BLOCK,  32, 32, 16,
966d49e1aeSJan Lentfer 	  CRYPTO_CIPHER_ALG_AES }
976d49e1aeSJan Lentfer };
986d49e1aeSJan Lentfer 
993ff40c12SJohn Marino #define NUM_TLS_CIPHER_DATA ARRAY_SIZE(tls_ciphers)
1006d49e1aeSJan Lentfer 
1016d49e1aeSJan Lentfer 
1026d49e1aeSJan Lentfer /**
1036d49e1aeSJan Lentfer  * tls_get_cipher_suite - Get TLS cipher suite
1046d49e1aeSJan Lentfer  * @suite: Cipher suite identifier
1056d49e1aeSJan Lentfer  * Returns: Pointer to the cipher data or %NULL if not found
1066d49e1aeSJan Lentfer  */
tls_get_cipher_suite(u16 suite)1076d49e1aeSJan Lentfer const struct tls_cipher_suite * tls_get_cipher_suite(u16 suite)
1086d49e1aeSJan Lentfer {
1096d49e1aeSJan Lentfer 	size_t i;
1106d49e1aeSJan Lentfer 	for (i = 0; i < NUM_TLS_CIPHER_SUITES; i++)
1116d49e1aeSJan Lentfer 		if (tls_cipher_suites[i].suite == suite)
1126d49e1aeSJan Lentfer 			return &tls_cipher_suites[i];
1136d49e1aeSJan Lentfer 	return NULL;
1146d49e1aeSJan Lentfer }
1156d49e1aeSJan Lentfer 
1166d49e1aeSJan Lentfer 
tls_get_cipher_data(tls_cipher cipher)1176d49e1aeSJan Lentfer const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher)
1186d49e1aeSJan Lentfer {
1196d49e1aeSJan Lentfer 	size_t i;
1206d49e1aeSJan Lentfer 	for (i = 0; i < NUM_TLS_CIPHER_DATA; i++)
1216d49e1aeSJan Lentfer 		if (tls_ciphers[i].cipher == cipher)
1226d49e1aeSJan Lentfer 			return &tls_ciphers[i];
1236d49e1aeSJan Lentfer 	return NULL;
1246d49e1aeSJan Lentfer }
1256d49e1aeSJan Lentfer 
1266d49e1aeSJan Lentfer 
tls_server_key_exchange_allowed(tls_cipher cipher)1276d49e1aeSJan Lentfer int tls_server_key_exchange_allowed(tls_cipher cipher)
1286d49e1aeSJan Lentfer {
1296d49e1aeSJan Lentfer 	const struct tls_cipher_suite *suite;
1306d49e1aeSJan Lentfer 
1316d49e1aeSJan Lentfer 	/* RFC 2246, Section 7.4.3 */
1326d49e1aeSJan Lentfer 	suite = tls_get_cipher_suite(cipher);
1336d49e1aeSJan Lentfer 	if (suite == NULL)
1346d49e1aeSJan Lentfer 		return 0;
1356d49e1aeSJan Lentfer 
1366d49e1aeSJan Lentfer 	switch (suite->key_exchange) {
1376d49e1aeSJan Lentfer 	case TLS_KEY_X_DHE_DSS:
1386d49e1aeSJan Lentfer 	case TLS_KEY_X_DHE_DSS_EXPORT:
1396d49e1aeSJan Lentfer 	case TLS_KEY_X_DHE_RSA:
1406d49e1aeSJan Lentfer 	case TLS_KEY_X_DHE_RSA_EXPORT:
1416d49e1aeSJan Lentfer 	case TLS_KEY_X_DH_anon_EXPORT:
1426d49e1aeSJan Lentfer 	case TLS_KEY_X_DH_anon:
1436d49e1aeSJan Lentfer 		return 1;
1446d49e1aeSJan Lentfer 	case TLS_KEY_X_RSA_EXPORT:
1456d49e1aeSJan Lentfer 		return 1 /* FIX: public key len > 512 bits */;
1466d49e1aeSJan Lentfer 	default:
1476d49e1aeSJan Lentfer 		return 0;
1486d49e1aeSJan Lentfer 	}
1496d49e1aeSJan Lentfer }
1506d49e1aeSJan Lentfer 
1516d49e1aeSJan Lentfer 
1526d49e1aeSJan Lentfer /**
1536d49e1aeSJan Lentfer  * tls_parse_cert - Parse DER encoded X.509 certificate and get public key
1546d49e1aeSJan Lentfer  * @buf: ASN.1 DER encoded certificate
1556d49e1aeSJan Lentfer  * @len: Length of the buffer
1566d49e1aeSJan Lentfer  * @pk: Buffer for returning the allocated public key
1576d49e1aeSJan Lentfer  * Returns: 0 on success, -1 on failure
1586d49e1aeSJan Lentfer  *
1596d49e1aeSJan Lentfer  * This functions parses an ASN.1 DER encoded X.509 certificate and retrieves
1606d49e1aeSJan Lentfer  * the public key from it. The caller is responsible for freeing the public key
1616d49e1aeSJan Lentfer  * by calling crypto_public_key_free().
1626d49e1aeSJan Lentfer  */
tls_parse_cert(const u8 * buf,size_t len,struct crypto_public_key ** pk)1636d49e1aeSJan Lentfer int tls_parse_cert(const u8 *buf, size_t len, struct crypto_public_key **pk)
1646d49e1aeSJan Lentfer {
1656d49e1aeSJan Lentfer 	struct x509_certificate *cert;
1666d49e1aeSJan Lentfer 
1676d49e1aeSJan Lentfer 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: Parse ASN.1 DER certificate",
1686d49e1aeSJan Lentfer 		    buf, len);
1696d49e1aeSJan Lentfer 
1706d49e1aeSJan Lentfer 	*pk = crypto_public_key_from_cert(buf, len);
1716d49e1aeSJan Lentfer 	if (*pk)
1726d49e1aeSJan Lentfer 		return 0;
1736d49e1aeSJan Lentfer 
1746d49e1aeSJan Lentfer 	cert = x509_certificate_parse(buf, len);
1756d49e1aeSJan Lentfer 	if (cert == NULL) {
1766d49e1aeSJan Lentfer 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse X.509 "
1776d49e1aeSJan Lentfer 			   "certificate");
1786d49e1aeSJan Lentfer 		return -1;
1796d49e1aeSJan Lentfer 	}
1806d49e1aeSJan Lentfer 
1816d49e1aeSJan Lentfer 	/* TODO
1826d49e1aeSJan Lentfer 	 * verify key usage (must allow encryption)
1836d49e1aeSJan Lentfer 	 *
1846d49e1aeSJan Lentfer 	 * All certificate profiles, key and cryptographic formats are
1856d49e1aeSJan Lentfer 	 * defined by the IETF PKIX working group [PKIX]. When a key
1866d49e1aeSJan Lentfer 	 * usage extension is present, the digitalSignature bit must be
1876d49e1aeSJan Lentfer 	 * set for the key to be eligible for signing, as described
1886d49e1aeSJan Lentfer 	 * above, and the keyEncipherment bit must be present to allow
1896d49e1aeSJan Lentfer 	 * encryption, as described above. The keyAgreement bit must be
1906d49e1aeSJan Lentfer 	 * set on Diffie-Hellman certificates. (PKIX: RFC 3280)
1916d49e1aeSJan Lentfer 	 */
1926d49e1aeSJan Lentfer 
1936d49e1aeSJan Lentfer 	*pk = crypto_public_key_import(cert->public_key, cert->public_key_len);
1946d49e1aeSJan Lentfer 	x509_certificate_free(cert);
1956d49e1aeSJan Lentfer 
1966d49e1aeSJan Lentfer 	if (*pk == NULL) {
1976d49e1aeSJan Lentfer 		wpa_printf(MSG_ERROR, "TLSv1: Failed to import "
1986d49e1aeSJan Lentfer 			   "server public key");
1996d49e1aeSJan Lentfer 		return -1;
2006d49e1aeSJan Lentfer 	}
2016d49e1aeSJan Lentfer 
2026d49e1aeSJan Lentfer 	return 0;
2036d49e1aeSJan Lentfer }
2046d49e1aeSJan Lentfer 
2056d49e1aeSJan Lentfer 
tls_verify_hash_init(struct tls_verify_hash * verify)2066d49e1aeSJan Lentfer int tls_verify_hash_init(struct tls_verify_hash *verify)
2076d49e1aeSJan Lentfer {
2086d49e1aeSJan Lentfer 	tls_verify_hash_free(verify);
2096d49e1aeSJan Lentfer 	verify->md5_client = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
2106d49e1aeSJan Lentfer 	verify->md5_server = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
2116d49e1aeSJan Lentfer 	verify->md5_cert = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
2126d49e1aeSJan Lentfer 	verify->sha1_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
2136d49e1aeSJan Lentfer 	verify->sha1_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
2146d49e1aeSJan Lentfer 	verify->sha1_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
2156d49e1aeSJan Lentfer 	if (verify->md5_client == NULL || verify->md5_server == NULL ||
2166d49e1aeSJan Lentfer 	    verify->md5_cert == NULL || verify->sha1_client == NULL ||
2176d49e1aeSJan Lentfer 	    verify->sha1_server == NULL || verify->sha1_cert == NULL) {
2186d49e1aeSJan Lentfer 		tls_verify_hash_free(verify);
2196d49e1aeSJan Lentfer 		return -1;
2206d49e1aeSJan Lentfer 	}
2213ff40c12SJohn Marino #ifdef CONFIG_TLSV12
2223ff40c12SJohn Marino 	verify->sha256_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL,
2233ff40c12SJohn Marino 						 0);
2243ff40c12SJohn Marino 	verify->sha256_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL,
2253ff40c12SJohn Marino 						 0);
2263ff40c12SJohn Marino 	verify->sha256_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL,
2273ff40c12SJohn Marino 					       0);
2283ff40c12SJohn Marino 	if (verify->sha256_client == NULL || verify->sha256_server == NULL ||
2293ff40c12SJohn Marino 	    verify->sha256_cert == NULL) {
2303ff40c12SJohn Marino 		tls_verify_hash_free(verify);
2313ff40c12SJohn Marino 		return -1;
2323ff40c12SJohn Marino 	}
2333ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
2346d49e1aeSJan Lentfer 	return 0;
2356d49e1aeSJan Lentfer }
2366d49e1aeSJan Lentfer 
2376d49e1aeSJan Lentfer 
tls_verify_hash_add(struct tls_verify_hash * verify,const u8 * buf,size_t len)2386d49e1aeSJan Lentfer void tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf,
2396d49e1aeSJan Lentfer 			 size_t len)
2406d49e1aeSJan Lentfer {
2416d49e1aeSJan Lentfer 	if (verify->md5_client && verify->sha1_client) {
2426d49e1aeSJan Lentfer 		crypto_hash_update(verify->md5_client, buf, len);
2436d49e1aeSJan Lentfer 		crypto_hash_update(verify->sha1_client, buf, len);
2446d49e1aeSJan Lentfer 	}
2456d49e1aeSJan Lentfer 	if (verify->md5_server && verify->sha1_server) {
2466d49e1aeSJan Lentfer 		crypto_hash_update(verify->md5_server, buf, len);
2476d49e1aeSJan Lentfer 		crypto_hash_update(verify->sha1_server, buf, len);
2486d49e1aeSJan Lentfer 	}
2496d49e1aeSJan Lentfer 	if (verify->md5_cert && verify->sha1_cert) {
2506d49e1aeSJan Lentfer 		crypto_hash_update(verify->md5_cert, buf, len);
2516d49e1aeSJan Lentfer 		crypto_hash_update(verify->sha1_cert, buf, len);
2526d49e1aeSJan Lentfer 	}
2533ff40c12SJohn Marino #ifdef CONFIG_TLSV12
2543ff40c12SJohn Marino 	if (verify->sha256_client)
2553ff40c12SJohn Marino 		crypto_hash_update(verify->sha256_client, buf, len);
2563ff40c12SJohn Marino 	if (verify->sha256_server)
2573ff40c12SJohn Marino 		crypto_hash_update(verify->sha256_server, buf, len);
2583ff40c12SJohn Marino 	if (verify->sha256_cert)
2593ff40c12SJohn Marino 		crypto_hash_update(verify->sha256_cert, buf, len);
2603ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
2616d49e1aeSJan Lentfer }
2626d49e1aeSJan Lentfer 
2636d49e1aeSJan Lentfer 
tls_verify_hash_free(struct tls_verify_hash * verify)2646d49e1aeSJan Lentfer void tls_verify_hash_free(struct tls_verify_hash *verify)
2656d49e1aeSJan Lentfer {
2666d49e1aeSJan Lentfer 	crypto_hash_finish(verify->md5_client, NULL, NULL);
2676d49e1aeSJan Lentfer 	crypto_hash_finish(verify->md5_server, NULL, NULL);
2686d49e1aeSJan Lentfer 	crypto_hash_finish(verify->md5_cert, NULL, NULL);
2696d49e1aeSJan Lentfer 	crypto_hash_finish(verify->sha1_client, NULL, NULL);
2706d49e1aeSJan Lentfer 	crypto_hash_finish(verify->sha1_server, NULL, NULL);
2716d49e1aeSJan Lentfer 	crypto_hash_finish(verify->sha1_cert, NULL, NULL);
2726d49e1aeSJan Lentfer 	verify->md5_client = NULL;
2736d49e1aeSJan Lentfer 	verify->md5_server = NULL;
2746d49e1aeSJan Lentfer 	verify->md5_cert = NULL;
2756d49e1aeSJan Lentfer 	verify->sha1_client = NULL;
2766d49e1aeSJan Lentfer 	verify->sha1_server = NULL;
2776d49e1aeSJan Lentfer 	verify->sha1_cert = NULL;
2783ff40c12SJohn Marino #ifdef CONFIG_TLSV12
2793ff40c12SJohn Marino 	crypto_hash_finish(verify->sha256_client, NULL, NULL);
2803ff40c12SJohn Marino 	crypto_hash_finish(verify->sha256_server, NULL, NULL);
2813ff40c12SJohn Marino 	crypto_hash_finish(verify->sha256_cert, NULL, NULL);
2823ff40c12SJohn Marino 	verify->sha256_client = NULL;
2833ff40c12SJohn Marino 	verify->sha256_server = NULL;
2843ff40c12SJohn Marino 	verify->sha256_cert = NULL;
2853ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
2863ff40c12SJohn Marino }
2873ff40c12SJohn Marino 
2883ff40c12SJohn Marino 
tls_version_ok(u16 ver)2893ff40c12SJohn Marino int tls_version_ok(u16 ver)
2903ff40c12SJohn Marino {
2913ff40c12SJohn Marino 	if (ver == TLS_VERSION_1)
2923ff40c12SJohn Marino 		return 1;
2933ff40c12SJohn Marino #ifdef CONFIG_TLSV11
2943ff40c12SJohn Marino 	if (ver == TLS_VERSION_1_1)
2953ff40c12SJohn Marino 		return 1;
2963ff40c12SJohn Marino #endif /* CONFIG_TLSV11 */
2973ff40c12SJohn Marino #ifdef CONFIG_TLSV12
2983ff40c12SJohn Marino 	if (ver == TLS_VERSION_1_2)
2993ff40c12SJohn Marino 		return 1;
3003ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
3013ff40c12SJohn Marino 
3023ff40c12SJohn Marino 	return 0;
3033ff40c12SJohn Marino }
3043ff40c12SJohn Marino 
3053ff40c12SJohn Marino 
tls_version_str(u16 ver)3063ff40c12SJohn Marino const char * tls_version_str(u16 ver)
3073ff40c12SJohn Marino {
3083ff40c12SJohn Marino 	switch (ver) {
3093ff40c12SJohn Marino 	case TLS_VERSION_1:
3103ff40c12SJohn Marino 		return "1.0";
3113ff40c12SJohn Marino 	case TLS_VERSION_1_1:
3123ff40c12SJohn Marino 		return "1.1";
3133ff40c12SJohn Marino 	case TLS_VERSION_1_2:
3143ff40c12SJohn Marino 		return "1.2";
3153ff40c12SJohn Marino 	}
3163ff40c12SJohn Marino 
3173ff40c12SJohn Marino 	return "?";
3183ff40c12SJohn Marino }
3193ff40c12SJohn Marino 
3203ff40c12SJohn Marino 
tls_prf(u16 ver,const u8 * secret,size_t secret_len,const char * label,const u8 * seed,size_t seed_len,u8 * out,size_t outlen)3213ff40c12SJohn Marino int tls_prf(u16 ver, const u8 *secret, size_t secret_len, const char *label,
3223ff40c12SJohn Marino 	    const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
3233ff40c12SJohn Marino {
3243ff40c12SJohn Marino #ifdef CONFIG_TLSV12
3253ff40c12SJohn Marino 	if (ver >= TLS_VERSION_1_2) {
3263ff40c12SJohn Marino 		tls_prf_sha256(secret, secret_len, label, seed, seed_len,
3273ff40c12SJohn Marino 			       out, outlen);
3283ff40c12SJohn Marino 		return 0;
3293ff40c12SJohn Marino 	}
3303ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
3313ff40c12SJohn Marino 
3323ff40c12SJohn Marino 	return tls_prf_sha1_md5(secret, secret_len, label, seed, seed_len, out,
3333ff40c12SJohn Marino 				outlen);
3346d49e1aeSJan Lentfer }
335*a1157835SDaniel Fojt 
336*a1157835SDaniel Fojt 
337*a1157835SDaniel Fojt #ifdef CONFIG_TLSV12
tlsv12_key_x_server_params_hash(u16 tls_version,u8 hash_alg,const u8 * client_random,const u8 * server_random,const u8 * server_params,size_t server_params_len,u8 * hash)338*a1157835SDaniel Fojt int tlsv12_key_x_server_params_hash(u16 tls_version, u8 hash_alg,
339*a1157835SDaniel Fojt 				    const u8 *client_random,
340*a1157835SDaniel Fojt 				    const u8 *server_random,
341*a1157835SDaniel Fojt 				    const u8 *server_params,
342*a1157835SDaniel Fojt 				    size_t server_params_len, u8 *hash)
343*a1157835SDaniel Fojt {
344*a1157835SDaniel Fojt 	size_t hlen;
345*a1157835SDaniel Fojt 	struct crypto_hash *ctx;
346*a1157835SDaniel Fojt 	enum crypto_hash_alg alg;
347*a1157835SDaniel Fojt 
348*a1157835SDaniel Fojt 	switch (hash_alg) {
349*a1157835SDaniel Fojt 	case TLS_HASH_ALG_SHA256:
350*a1157835SDaniel Fojt 		alg = CRYPTO_HASH_ALG_SHA256;
351*a1157835SDaniel Fojt 		hlen = SHA256_MAC_LEN;
352*a1157835SDaniel Fojt 		break;
353*a1157835SDaniel Fojt 	case TLS_HASH_ALG_SHA384:
354*a1157835SDaniel Fojt 		alg = CRYPTO_HASH_ALG_SHA384;
355*a1157835SDaniel Fojt 		hlen = 48;
356*a1157835SDaniel Fojt 		break;
357*a1157835SDaniel Fojt 	case TLS_HASH_ALG_SHA512:
358*a1157835SDaniel Fojt 		alg = CRYPTO_HASH_ALG_SHA512;
359*a1157835SDaniel Fojt 		hlen = 64;
360*a1157835SDaniel Fojt 		break;
361*a1157835SDaniel Fojt 	default:
362*a1157835SDaniel Fojt 		return -1;
363*a1157835SDaniel Fojt 	}
364*a1157835SDaniel Fojt 	ctx = crypto_hash_init(alg, NULL, 0);
365*a1157835SDaniel Fojt 	if (ctx == NULL)
366*a1157835SDaniel Fojt 		return -1;
367*a1157835SDaniel Fojt 	crypto_hash_update(ctx, client_random, TLS_RANDOM_LEN);
368*a1157835SDaniel Fojt 	crypto_hash_update(ctx, server_random, TLS_RANDOM_LEN);
369*a1157835SDaniel Fojt 	crypto_hash_update(ctx, server_params, server_params_len);
370*a1157835SDaniel Fojt 	if (crypto_hash_finish(ctx, hash, &hlen) < 0)
371*a1157835SDaniel Fojt 		return -1;
372*a1157835SDaniel Fojt 
373*a1157835SDaniel Fojt 	return hlen;
374*a1157835SDaniel Fojt }
375*a1157835SDaniel Fojt #endif /* CONFIG_TLSV12 */
376*a1157835SDaniel Fojt 
377*a1157835SDaniel Fojt 
tls_key_x_server_params_hash(u16 tls_version,const u8 * client_random,const u8 * server_random,const u8 * server_params,size_t server_params_len,u8 * hash)378*a1157835SDaniel Fojt int tls_key_x_server_params_hash(u16 tls_version, const u8 *client_random,
379*a1157835SDaniel Fojt 				 const u8 *server_random,
380*a1157835SDaniel Fojt 				 const u8 *server_params,
381*a1157835SDaniel Fojt 				 size_t server_params_len, u8 *hash)
382*a1157835SDaniel Fojt {
383*a1157835SDaniel Fojt 	u8 *hpos;
384*a1157835SDaniel Fojt 	size_t hlen;
385*a1157835SDaniel Fojt 	struct crypto_hash *ctx;
386*a1157835SDaniel Fojt 
387*a1157835SDaniel Fojt 	hpos = hash;
388*a1157835SDaniel Fojt 
389*a1157835SDaniel Fojt 	ctx = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
390*a1157835SDaniel Fojt 	if (ctx == NULL)
391*a1157835SDaniel Fojt 		return -1;
392*a1157835SDaniel Fojt 	crypto_hash_update(ctx, client_random, TLS_RANDOM_LEN);
393*a1157835SDaniel Fojt 	crypto_hash_update(ctx, server_random, TLS_RANDOM_LEN);
394*a1157835SDaniel Fojt 	crypto_hash_update(ctx, server_params, server_params_len);
395*a1157835SDaniel Fojt 	hlen = MD5_MAC_LEN;
396*a1157835SDaniel Fojt 	if (crypto_hash_finish(ctx, hash, &hlen) < 0)
397*a1157835SDaniel Fojt 		return -1;
398*a1157835SDaniel Fojt 	hpos += hlen;
399*a1157835SDaniel Fojt 
400*a1157835SDaniel Fojt 	ctx = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
401*a1157835SDaniel Fojt 	if (ctx == NULL)
402*a1157835SDaniel Fojt 		return -1;
403*a1157835SDaniel Fojt 	crypto_hash_update(ctx, client_random, TLS_RANDOM_LEN);
404*a1157835SDaniel Fojt 	crypto_hash_update(ctx, server_random, TLS_RANDOM_LEN);
405*a1157835SDaniel Fojt 	crypto_hash_update(ctx, server_params, server_params_len);
406*a1157835SDaniel Fojt 	hlen = hash + sizeof(hash) - hpos;
407*a1157835SDaniel Fojt 	if (crypto_hash_finish(ctx, hpos, &hlen) < 0)
408*a1157835SDaniel Fojt 		return -1;
409*a1157835SDaniel Fojt 	hpos += hlen;
410*a1157835SDaniel Fojt 	return hpos - hash;
411*a1157835SDaniel Fojt }
412*a1157835SDaniel Fojt 
413*a1157835SDaniel Fojt 
tls_verify_signature(u16 tls_version,struct crypto_public_key * pk,const u8 * data,size_t data_len,const u8 * pos,size_t len,u8 * alert)414*a1157835SDaniel Fojt int tls_verify_signature(u16 tls_version, struct crypto_public_key *pk,
415*a1157835SDaniel Fojt 			 const u8 *data, size_t data_len,
416*a1157835SDaniel Fojt 			 const u8 *pos, size_t len, u8 *alert)
417*a1157835SDaniel Fojt {
418*a1157835SDaniel Fojt 	u8 *buf;
419*a1157835SDaniel Fojt 	const u8 *end = pos + len;
420*a1157835SDaniel Fojt 	const u8 *decrypted;
421*a1157835SDaniel Fojt 	u16 slen;
422*a1157835SDaniel Fojt 	size_t buflen;
423*a1157835SDaniel Fojt 
424*a1157835SDaniel Fojt 	if (end - pos < 2) {
425*a1157835SDaniel Fojt 		*alert = TLS_ALERT_DECODE_ERROR;
426*a1157835SDaniel Fojt 		return -1;
427*a1157835SDaniel Fojt 	}
428*a1157835SDaniel Fojt 	slen = WPA_GET_BE16(pos);
429*a1157835SDaniel Fojt 	pos += 2;
430*a1157835SDaniel Fojt 	if (end - pos < slen) {
431*a1157835SDaniel Fojt 		*alert = TLS_ALERT_DECODE_ERROR;
432*a1157835SDaniel Fojt 		return -1;
433*a1157835SDaniel Fojt 	}
434*a1157835SDaniel Fojt 	if (end - pos > slen) {
435*a1157835SDaniel Fojt 		wpa_hexdump(MSG_MSGDUMP, "Additional data after Signature",
436*a1157835SDaniel Fojt 			    pos + slen, end - pos - slen);
437*a1157835SDaniel Fojt 		end = pos + slen;
438*a1157835SDaniel Fojt 	}
439*a1157835SDaniel Fojt 
440*a1157835SDaniel Fojt 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: Signature", pos, end - pos);
441*a1157835SDaniel Fojt 	if (pk == NULL) {
442*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG, "TLSv1: No public key to verify signature");
443*a1157835SDaniel Fojt 		*alert = TLS_ALERT_INTERNAL_ERROR;
444*a1157835SDaniel Fojt 		return -1;
445*a1157835SDaniel Fojt 	}
446*a1157835SDaniel Fojt 
447*a1157835SDaniel Fojt 	buflen = end - pos;
448*a1157835SDaniel Fojt 	buf = os_malloc(end - pos);
449*a1157835SDaniel Fojt 	if (buf == NULL) {
450*a1157835SDaniel Fojt 		*alert = TLS_ALERT_INTERNAL_ERROR;
451*a1157835SDaniel Fojt 		return -1;
452*a1157835SDaniel Fojt 	}
453*a1157835SDaniel Fojt 	if (crypto_public_key_decrypt_pkcs1(pk, pos, end - pos, buf, &buflen) <
454*a1157835SDaniel Fojt 	    0) {
455*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt signature");
456*a1157835SDaniel Fojt 		os_free(buf);
457*a1157835SDaniel Fojt 		*alert = TLS_ALERT_DECRYPT_ERROR;
458*a1157835SDaniel Fojt 		return -1;
459*a1157835SDaniel Fojt 	}
460*a1157835SDaniel Fojt 	decrypted = buf;
461*a1157835SDaniel Fojt 
462*a1157835SDaniel Fojt 	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Decrypted Signature",
463*a1157835SDaniel Fojt 			decrypted, buflen);
464*a1157835SDaniel Fojt 
465*a1157835SDaniel Fojt #ifdef CONFIG_TLSV12
466*a1157835SDaniel Fojt 	if (tls_version >= TLS_VERSION_1_2) {
467*a1157835SDaniel Fojt 		/*
468*a1157835SDaniel Fojt 		 * RFC 3447, A.2.4 RSASSA-PKCS1-v1_5
469*a1157835SDaniel Fojt 		 *
470*a1157835SDaniel Fojt 		 * DigestInfo ::= SEQUENCE {
471*a1157835SDaniel Fojt 		 *   digestAlgorithm DigestAlgorithm,
472*a1157835SDaniel Fojt 		 *   digest OCTET STRING
473*a1157835SDaniel Fojt 		 * }
474*a1157835SDaniel Fojt 		 *
475*a1157835SDaniel Fojt 		 * SHA-256 OID: sha256WithRSAEncryption ::= {pkcs-1 11}
476*a1157835SDaniel Fojt 		 *
477*a1157835SDaniel Fojt 		 * DER encoded DigestInfo for SHA256 per RFC 3447:
478*a1157835SDaniel Fojt 		 * 30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 ||
479*a1157835SDaniel Fojt 		 * H
480*a1157835SDaniel Fojt 		 */
481*a1157835SDaniel Fojt 		if (buflen >= 19 + 32 &&
482*a1157835SDaniel Fojt 		    os_memcmp(buf, "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01"
483*a1157835SDaniel Fojt 			      "\x65\x03\x04\x02\x01\x05\x00\x04\x20", 19) == 0)
484*a1157835SDaniel Fojt 		{
485*a1157835SDaniel Fojt 			wpa_printf(MSG_DEBUG, "TLSv1.2: DigestAlgorithm = SHA-256");
486*a1157835SDaniel Fojt 			decrypted = buf + 19;
487*a1157835SDaniel Fojt 			buflen -= 19;
488*a1157835SDaniel Fojt 		} else if (buflen >= 19 + 48 &&
489*a1157835SDaniel Fojt 		    os_memcmp(buf, "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01"
490*a1157835SDaniel Fojt 			      "\x65\x03\x04\x02\x02\x05\x00\x04\x30", 19) == 0)
491*a1157835SDaniel Fojt 		{
492*a1157835SDaniel Fojt 			wpa_printf(MSG_DEBUG, "TLSv1.2: DigestAlgorithm = SHA-384");
493*a1157835SDaniel Fojt 			decrypted = buf + 19;
494*a1157835SDaniel Fojt 			buflen -= 19;
495*a1157835SDaniel Fojt 		} else if (buflen >= 19 + 64 &&
496*a1157835SDaniel Fojt 		    os_memcmp(buf, "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01"
497*a1157835SDaniel Fojt 			      "\x65\x03\x04\x02\x03\x05\x00\x04\x40", 19) == 0)
498*a1157835SDaniel Fojt 		{
499*a1157835SDaniel Fojt 			wpa_printf(MSG_DEBUG, "TLSv1.2: DigestAlgorithm = SHA-512");
500*a1157835SDaniel Fojt 			decrypted = buf + 19;
501*a1157835SDaniel Fojt 			buflen -= 19;
502*a1157835SDaniel Fojt 
503*a1157835SDaniel Fojt 		} else {
504*a1157835SDaniel Fojt 			wpa_printf(MSG_DEBUG, "TLSv1.2: Unrecognized DigestInfo");
505*a1157835SDaniel Fojt 			os_free(buf);
506*a1157835SDaniel Fojt 			*alert = TLS_ALERT_DECRYPT_ERROR;
507*a1157835SDaniel Fojt 			return -1;
508*a1157835SDaniel Fojt 		}
509*a1157835SDaniel Fojt 	}
510*a1157835SDaniel Fojt #endif /* CONFIG_TLSV12 */
511*a1157835SDaniel Fojt 
512*a1157835SDaniel Fojt 	if (buflen != data_len ||
513*a1157835SDaniel Fojt 	    os_memcmp_const(decrypted, data, data_len) != 0) {
514*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG, "TLSv1: Invalid Signature in CertificateVerify - did not match calculated hash");
515*a1157835SDaniel Fojt 		os_free(buf);
516*a1157835SDaniel Fojt 		*alert = TLS_ALERT_DECRYPT_ERROR;
517*a1157835SDaniel Fojt 		return -1;
518*a1157835SDaniel Fojt 	}
519*a1157835SDaniel Fojt 
520*a1157835SDaniel Fojt 	os_free(buf);
521*a1157835SDaniel Fojt 
522*a1157835SDaniel Fojt 	return 0;
523*a1157835SDaniel Fojt }
524