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