1/* 2 * TLSv1 common routines 3 * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9#include "includes.h" 10 11#include "common.h" 12#include "crypto/sha1.h" 13#include "crypto/sha256.h" 14#include "x509v3.h" 15#include "tlsv1_common.h" 16 17 18/* 19 * TODO: 20 * RFC 2246 Section 9: Mandatory to implement TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 21 * Add support for commonly used cipher suites; don't bother with exportable 22 * suites. 23 */ 24 25static const struct tls_cipher_suite tls_cipher_suites[] = { 26 { TLS_NULL_WITH_NULL_NULL, TLS_KEY_X_NULL, TLS_CIPHER_NULL, 27 TLS_HASH_NULL }, 28 { TLS_RSA_WITH_RC4_128_MD5, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128, 29 TLS_HASH_MD5 }, 30 { TLS_RSA_WITH_RC4_128_SHA, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128, 31 TLS_HASH_SHA }, 32 { TLS_RSA_WITH_DES_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_DES_CBC, 33 TLS_HASH_SHA }, 34 { TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_RSA, 35 TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA }, 36 { TLS_DH_anon_WITH_RC4_128_MD5, TLS_KEY_X_DH_anon, 37 TLS_CIPHER_RC4_128, TLS_HASH_MD5 }, 38 { TLS_DH_anon_WITH_DES_CBC_SHA, TLS_KEY_X_DH_anon, 39 TLS_CIPHER_DES_CBC, TLS_HASH_SHA }, 40 { TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_DH_anon, 41 TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA }, 42 { TLS_RSA_WITH_AES_128_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_128_CBC, 43 TLS_HASH_SHA }, 44 { TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_KEY_X_DH_anon, 45 TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA }, 46 { TLS_RSA_WITH_AES_256_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_256_CBC, 47 TLS_HASH_SHA }, 48 { TLS_DH_anon_WITH_AES_256_CBC_SHA, TLS_KEY_X_DH_anon, 49 TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA }, 50 { TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_KEY_X_RSA, 51 TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA256 }, 52 { TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_KEY_X_RSA, 53 TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA256 }, 54 { TLS_DH_anon_WITH_AES_128_CBC_SHA256, TLS_KEY_X_DH_anon, 55 TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA256 }, 56 { TLS_DH_anon_WITH_AES_256_CBC_SHA256, TLS_KEY_X_DH_anon, 57 TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA256 } 58}; 59 60#define NUM_ELEMS(a) (sizeof(a) / sizeof((a)[0])) 61#define NUM_TLS_CIPHER_SUITES NUM_ELEMS(tls_cipher_suites) 62 63 64static const struct tls_cipher_data tls_ciphers[] = { 65 { TLS_CIPHER_NULL, TLS_CIPHER_STREAM, 0, 0, 0, 66 CRYPTO_CIPHER_NULL }, 67 { TLS_CIPHER_IDEA_CBC, TLS_CIPHER_BLOCK, 16, 16, 8, 68 CRYPTO_CIPHER_NULL }, 69 { TLS_CIPHER_RC2_CBC_40, TLS_CIPHER_BLOCK, 5, 16, 0, 70 CRYPTO_CIPHER_ALG_RC2 }, 71 { TLS_CIPHER_RC4_40, TLS_CIPHER_STREAM, 5, 16, 0, 72 CRYPTO_CIPHER_ALG_RC4 }, 73 { TLS_CIPHER_RC4_128, TLS_CIPHER_STREAM, 16, 16, 0, 74 CRYPTO_CIPHER_ALG_RC4 }, 75 { TLS_CIPHER_DES40_CBC, TLS_CIPHER_BLOCK, 5, 8, 8, 76 CRYPTO_CIPHER_ALG_DES }, 77 { TLS_CIPHER_DES_CBC, TLS_CIPHER_BLOCK, 8, 8, 8, 78 CRYPTO_CIPHER_ALG_DES }, 79 { TLS_CIPHER_3DES_EDE_CBC, TLS_CIPHER_BLOCK, 24, 24, 8, 80 CRYPTO_CIPHER_ALG_3DES }, 81 { TLS_CIPHER_AES_128_CBC, TLS_CIPHER_BLOCK, 16, 16, 16, 82 CRYPTO_CIPHER_ALG_AES }, 83 { TLS_CIPHER_AES_256_CBC, TLS_CIPHER_BLOCK, 32, 32, 16, 84 CRYPTO_CIPHER_ALG_AES } 85}; 86 87#define NUM_TLS_CIPHER_DATA NUM_ELEMS(tls_ciphers) 88 89 90/** 91 * tls_get_cipher_suite - Get TLS cipher suite 92 * @suite: Cipher suite identifier 93 * Returns: Pointer to the cipher data or %NULL if not found 94 */ 95const struct tls_cipher_suite * tls_get_cipher_suite(u16 suite) 96{ 97 size_t i; 98 for (i = 0; i < NUM_TLS_CIPHER_SUITES; i++) 99 if (tls_cipher_suites[i].suite == suite) 100 return &tls_cipher_suites[i]; 101 return NULL; 102} 103 104 105const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher) 106{ 107 size_t i; 108 for (i = 0; i < NUM_TLS_CIPHER_DATA; i++) 109 if (tls_ciphers[i].cipher == cipher) 110 return &tls_ciphers[i]; 111 return NULL; 112} 113 114 115int tls_server_key_exchange_allowed(tls_cipher cipher) 116{ 117 const struct tls_cipher_suite *suite; 118 119 /* RFC 2246, Section 7.4.3 */ 120 suite = tls_get_cipher_suite(cipher); 121 if (suite == NULL) 122 return 0; 123 124 switch (suite->key_exchange) { 125 case TLS_KEY_X_DHE_DSS: 126 case TLS_KEY_X_DHE_DSS_EXPORT: 127 case TLS_KEY_X_DHE_RSA: 128 case TLS_KEY_X_DHE_RSA_EXPORT: 129 case TLS_KEY_X_DH_anon_EXPORT: 130 case TLS_KEY_X_DH_anon: 131 return 1; 132 case TLS_KEY_X_RSA_EXPORT: 133 return 1 /* FIX: public key len > 512 bits */; 134 default: 135 return 0; 136 } 137} 138 139 140/** 141 * tls_parse_cert - Parse DER encoded X.509 certificate and get public key 142 * @buf: ASN.1 DER encoded certificate 143 * @len: Length of the buffer 144 * @pk: Buffer for returning the allocated public key 145 * Returns: 0 on success, -1 on failure 146 * 147 * This functions parses an ASN.1 DER encoded X.509 certificate and retrieves 148 * the public key from it. The caller is responsible for freeing the public key 149 * by calling crypto_public_key_free(). 150 */ 151int tls_parse_cert(const u8 *buf, size_t len, struct crypto_public_key **pk) 152{ 153 struct x509_certificate *cert; 154 155 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Parse ASN.1 DER certificate", 156 buf, len); 157 158 *pk = crypto_public_key_from_cert(buf, len); 159 if (*pk) 160 return 0; 161 162 cert = x509_certificate_parse(buf, len); 163 if (cert == NULL) { 164 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse X.509 " 165 "certificate"); 166 return -1; 167 } 168 169 /* TODO 170 * verify key usage (must allow encryption) 171 * 172 * All certificate profiles, key and cryptographic formats are 173 * defined by the IETF PKIX working group [PKIX]. When a key 174 * usage extension is present, the digitalSignature bit must be 175 * set for the key to be eligible for signing, as described 176 * above, and the keyEncipherment bit must be present to allow 177 * encryption, as described above. The keyAgreement bit must be 178 * set on Diffie-Hellman certificates. (PKIX: RFC 3280) 179 */ 180 181 *pk = crypto_public_key_import(cert->public_key, cert->public_key_len); 182 x509_certificate_free(cert); 183 184 if (*pk == NULL) { 185 wpa_printf(MSG_ERROR, "TLSv1: Failed to import " 186 "server public key"); 187 return -1; 188 } 189 190 return 0; 191} 192 193 194int tls_verify_hash_init(struct tls_verify_hash *verify) 195{ 196 tls_verify_hash_free(verify); 197 verify->md5_client = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); 198 verify->md5_server = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); 199 verify->md5_cert = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); 200 verify->sha1_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0); 201 verify->sha1_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0); 202 verify->sha1_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0); 203 if (verify->md5_client == NULL || verify->md5_server == NULL || 204 verify->md5_cert == NULL || verify->sha1_client == NULL || 205 verify->sha1_server == NULL || verify->sha1_cert == NULL) { 206 tls_verify_hash_free(verify); 207 return -1; 208 } 209#ifdef CONFIG_TLSV12 210 verify->sha256_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL, 211 0); 212 verify->sha256_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL, 213 0); 214 verify->sha256_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL, 215 0); 216 if (verify->sha256_client == NULL || verify->sha256_server == NULL || 217 verify->sha256_cert == NULL) { 218 tls_verify_hash_free(verify); 219 return -1; 220 } 221#endif /* CONFIG_TLSV12 */ 222 return 0; 223} 224 225 226void tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf, 227 size_t len) 228{ 229 if (verify->md5_client && verify->sha1_client) { 230 crypto_hash_update(verify->md5_client, buf, len); 231 crypto_hash_update(verify->sha1_client, buf, len); 232 } 233 if (verify->md5_server && verify->sha1_server) { 234 crypto_hash_update(verify->md5_server, buf, len); 235 crypto_hash_update(verify->sha1_server, buf, len); 236 } 237 if (verify->md5_cert && verify->sha1_cert) { 238 crypto_hash_update(verify->md5_cert, buf, len); 239 crypto_hash_update(verify->sha1_cert, buf, len); 240 } 241#ifdef CONFIG_TLSV12 242 if (verify->sha256_client) 243 crypto_hash_update(verify->sha256_client, buf, len); 244 if (verify->sha256_server) 245 crypto_hash_update(verify->sha256_server, buf, len); 246 if (verify->sha256_cert) 247 crypto_hash_update(verify->sha256_cert, buf, len); 248#endif /* CONFIG_TLSV12 */ 249} 250 251 252void tls_verify_hash_free(struct tls_verify_hash *verify) 253{ 254 crypto_hash_finish(verify->md5_client, NULL, NULL); 255 crypto_hash_finish(verify->md5_server, NULL, NULL); 256 crypto_hash_finish(verify->md5_cert, NULL, NULL); 257 crypto_hash_finish(verify->sha1_client, NULL, NULL); 258 crypto_hash_finish(verify->sha1_server, NULL, NULL); 259 crypto_hash_finish(verify->sha1_cert, NULL, NULL); 260 verify->md5_client = NULL; 261 verify->md5_server = NULL; 262 verify->md5_cert = NULL; 263 verify->sha1_client = NULL; 264 verify->sha1_server = NULL; 265 verify->sha1_cert = NULL; 266#ifdef CONFIG_TLSV12 267 crypto_hash_finish(verify->sha256_client, NULL, NULL); 268 crypto_hash_finish(verify->sha256_server, NULL, NULL); 269 crypto_hash_finish(verify->sha256_cert, NULL, NULL); 270 verify->sha256_client = NULL; 271 verify->sha256_server = NULL; 272 verify->sha256_cert = NULL; 273#endif /* CONFIG_TLSV12 */ 274} 275 276 277int tls_version_ok(u16 ver) 278{ 279 if (ver == TLS_VERSION_1) 280 return 1; 281#ifdef CONFIG_TLSV11 282 if (ver == TLS_VERSION_1_1) 283 return 1; 284#endif /* CONFIG_TLSV11 */ 285#ifdef CONFIG_TLSV12 286 if (ver == TLS_VERSION_1_2) 287 return 1; 288#endif /* CONFIG_TLSV12 */ 289 290 return 0; 291} 292 293 294const char * tls_version_str(u16 ver) 295{ 296 switch (ver) { 297 case TLS_VERSION_1: 298 return "1.0"; 299 case TLS_VERSION_1_1: 300 return "1.1"; 301 case TLS_VERSION_1_2: 302 return "1.2"; 303 } 304 305 return "?"; 306} 307 308 309int tls_prf(u16 ver, const u8 *secret, size_t secret_len, const char *label, 310 const u8 *seed, size_t seed_len, u8 *out, size_t outlen) 311{ 312#ifdef CONFIG_TLSV12 313 if (ver >= TLS_VERSION_1_2) { 314 tls_prf_sha256(secret, secret_len, label, seed, seed_len, 315 out, outlen); 316 return 0; 317 } 318#endif /* CONFIG_TLSV12 */ 319 320 return tls_prf_sha1_md5(secret, secret_len, label, seed, seed_len, out, 321 outlen); 322} 323