1 /* 2 * wpa_supplicant/hostapd: TLSv1 common routines 3 * Copyright (c) 2006, Jouni Malinen <j (at) w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #include "common.h" 18 #include "md5.h" 19 #include "sha1.h" 20 #include "crypto.h" 21 #include "x509v3.h" 22 #include "tlsv1_common.h" 23 24 25 /* 26 * TODO: 27 * RFC 2246 Section 9: Mandatory to implement TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 28 * Add support for commonly used cipher suites; don't bother with exportable 29 * suites. 30 */ 31 32 static const struct tls_cipher_suite tls_cipher_suites[] = { 33 { TLS_NULL_WITH_NULL_NULL, TLS_KEY_X_NULL, TLS_CIPHER_NULL, 34 TLS_HASH_NULL }, 35 { TLS_RSA_WITH_RC4_128_MD5, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128, 36 TLS_HASH_MD5 }, 37 { TLS_RSA_WITH_RC4_128_SHA, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128, 38 TLS_HASH_SHA }, 39 { TLS_RSA_WITH_DES_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_DES_CBC, 40 TLS_HASH_SHA }, 41 { TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_RSA, 42 TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA }, 43 { TLS_DH_anon_WITH_RC4_128_MD5, TLS_KEY_X_DH_anon, 44 TLS_CIPHER_RC4_128, TLS_HASH_MD5 }, 45 { TLS_DH_anon_WITH_DES_CBC_SHA, TLS_KEY_X_DH_anon, 46 TLS_CIPHER_DES_CBC, TLS_HASH_SHA }, 47 { TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_DH_anon, 48 TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA }, 49 { TLS_RSA_WITH_AES_128_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_128_CBC, 50 TLS_HASH_SHA }, 51 { TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_KEY_X_DH_anon, 52 TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA }, 53 { TLS_RSA_WITH_AES_256_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_256_CBC, 54 TLS_HASH_SHA }, 55 { TLS_DH_anon_WITH_AES_256_CBC_SHA, TLS_KEY_X_DH_anon, 56 TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA } 57 }; 58 59 #define NUM_ELEMS(a) (sizeof(a) / sizeof((a)[0])) 60 #define NUM_TLS_CIPHER_SUITES NUM_ELEMS(tls_cipher_suites) 61 62 63 static const struct tls_cipher_data tls_ciphers[] = { 64 { TLS_CIPHER_NULL, TLS_CIPHER_STREAM, 0, 0, 0, 65 CRYPTO_CIPHER_NULL }, 66 { TLS_CIPHER_IDEA_CBC, TLS_CIPHER_BLOCK, 16, 16, 8, 67 CRYPTO_CIPHER_NULL }, 68 { TLS_CIPHER_RC2_CBC_40, TLS_CIPHER_BLOCK, 5, 16, 0, 69 CRYPTO_CIPHER_ALG_RC2 }, 70 { TLS_CIPHER_RC4_40, TLS_CIPHER_STREAM, 5, 16, 0, 71 CRYPTO_CIPHER_ALG_RC4 }, 72 { TLS_CIPHER_RC4_128, TLS_CIPHER_STREAM, 16, 16, 0, 73 CRYPTO_CIPHER_ALG_RC4 }, 74 { TLS_CIPHER_DES40_CBC, TLS_CIPHER_BLOCK, 5, 8, 8, 75 CRYPTO_CIPHER_ALG_DES }, 76 { TLS_CIPHER_DES_CBC, TLS_CIPHER_BLOCK, 8, 8, 8, 77 CRYPTO_CIPHER_ALG_DES }, 78 { TLS_CIPHER_3DES_EDE_CBC, TLS_CIPHER_BLOCK, 24, 24, 8, 79 CRYPTO_CIPHER_ALG_3DES }, 80 { TLS_CIPHER_AES_128_CBC, TLS_CIPHER_BLOCK, 16, 16, 16, 81 CRYPTO_CIPHER_ALG_AES }, 82 { TLS_CIPHER_AES_256_CBC, TLS_CIPHER_BLOCK, 32, 32, 16, 83 CRYPTO_CIPHER_ALG_AES } 84 }; 85 86 #define NUM_TLS_CIPHER_DATA NUM_ELEMS(tls_ciphers) 87 88 89 /** 90 * tls_get_cipher_suite - Get TLS cipher suite 91 * @suite: Cipher suite identifier 92 * Returns: Pointer to the cipher data or %NULL if not found 93 */ 94 const struct tls_cipher_suite * tls_get_cipher_suite(u16 suite) 95 { 96 size_t i; 97 for (i = 0; i < NUM_TLS_CIPHER_SUITES; i++) 98 if (tls_cipher_suites[i].suite == suite) 99 return &tls_cipher_suites[i]; 100 return NULL; 101 } 102 103 104 static const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher) 105 { 106 size_t i; 107 for (i = 0; i < NUM_TLS_CIPHER_DATA; i++) 108 if (tls_ciphers[i].cipher == cipher) 109 return &tls_ciphers[i]; 110 return NULL; 111 } 112 113 114 /** 115 * tls_parse_cert - Parse DER encoded X.509 certificate and get public key 116 * @buf: ASN.1 DER encoded certificate 117 * @len: Length of the buffer 118 * @pk: Buffer for returning the allocated public key 119 * Returns: 0 on success, -1 on failure 120 * 121 * This functions parses an ASN.1 DER encoded X.509 certificate and retrieves 122 * the public key from it. The caller is responsible for freeing the public key 123 * by calling crypto_public_key_free(). 124 */ 125 int tls_parse_cert(const u8 *buf, size_t len, struct crypto_public_key **pk) 126 { 127 struct x509_certificate *cert; 128 129 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Parse ASN.1 DER certificate", 130 buf, len); 131 132 *pk = crypto_public_key_from_cert(buf, len); 133 if (*pk) 134 return 0; 135 136 cert = x509_certificate_parse(buf, len); 137 if (cert == NULL) { 138 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse X.509 " 139 "certificate"); 140 return -1; 141 } 142 143 /* TODO 144 * verify key usage (must allow encryption) 145 * 146 * All certificate profiles, key and cryptographic formats are 147 * defined by the IETF PKIX working group [PKIX]. When a key 148 * usage extension is present, the digitalSignature bit must be 149 * set for the key to be eligible for signing, as described 150 * above, and the keyEncipherment bit must be present to allow 151 * encryption, as described above. The keyAgreement bit must be 152 * set on Diffie-Hellman certificates. (PKIX: RFC 3280) 153 */ 154 155 *pk = crypto_public_key_import(cert->public_key, cert->public_key_len); 156 x509_certificate_free(cert); 157 158 if (*pk == NULL) { 159 wpa_printf(MSG_ERROR, "TLSv1: Failed to import " 160 "server public key"); 161 return -1; 162 } 163 164 return 0; 165 } 166 167 168 /** 169 * tlsv1_record_set_cipher_suite - TLS record layer: Set cipher suite 170 * @rl: Pointer to TLS record layer data 171 * @cipher_suite: New cipher suite 172 * Returns: 0 on success, -1 on failure 173 * 174 * This function is used to prepare TLS record layer for cipher suite change. 175 * tlsv1_record_change_write_cipher() and 176 * tlsv1_record_change_read_cipher() functions can then be used to change the 177 * currently used ciphers. 178 */ 179 int tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl, 180 u16 cipher_suite) 181 { 182 const struct tls_cipher_suite *suite; 183 const struct tls_cipher_data *data; 184 185 wpa_printf(MSG_DEBUG, "TLSv1: Selected cipher suite: 0x%04x", 186 cipher_suite); 187 rl->cipher_suite = cipher_suite; 188 189 suite = tls_get_cipher_suite(cipher_suite); 190 if (suite == NULL) 191 return -1; 192 193 if (suite->hash == TLS_HASH_MD5) { 194 rl->hash_alg = CRYPTO_HASH_ALG_HMAC_MD5; 195 rl->hash_size = MD5_MAC_LEN; 196 } else if (suite->hash == TLS_HASH_SHA) { 197 rl->hash_alg = CRYPTO_HASH_ALG_HMAC_SHA1; 198 rl->hash_size = SHA1_MAC_LEN; 199 } 200 201 data = tls_get_cipher_data(suite->cipher); 202 if (data == NULL) 203 return -1; 204 205 rl->key_material_len = data->key_material; 206 rl->iv_size = data->block_size; 207 rl->cipher_alg = data->alg; 208 209 return 0; 210 } 211 212 213 /** 214 * tlsv1_record_change_write_cipher - TLS record layer: Change write cipher 215 * @rl: Pointer to TLS record layer data 216 * Returns: 0 on success (cipher changed), -1 on failure 217 * 218 * This function changes TLS record layer to use the new cipher suite 219 * configured with tlsv1_record_set_cipher_suite() for writing. 220 */ 221 int tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl) 222 { 223 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New write cipher suite " 224 "0x%04x", rl->cipher_suite); 225 rl->write_cipher_suite = rl->cipher_suite; 226 os_memset(rl->write_seq_num, 0, TLS_SEQ_NUM_LEN); 227 228 if (rl->write_cbc) { 229 crypto_cipher_deinit(rl->write_cbc); 230 rl->write_cbc = NULL; 231 } 232 if (rl->cipher_alg != CRYPTO_CIPHER_NULL) { 233 rl->write_cbc = crypto_cipher_init(rl->cipher_alg, 234 rl->write_iv, rl->write_key, 235 rl->key_material_len); 236 if (rl->write_cbc == NULL) { 237 wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize " 238 "cipher"); 239 return -1; 240 } 241 } 242 243 return 0; 244 } 245 246 247 /** 248 * tlsv1_record_change_read_cipher - TLS record layer: Change read cipher 249 * @rl: Pointer to TLS record layer data 250 * Returns: 0 on success (cipher changed), -1 on failure 251 * 252 * This function changes TLS record layer to use the new cipher suite 253 * configured with tlsv1_record_set_cipher_suite() for reading. 254 */ 255 int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl) 256 { 257 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New read cipher suite " 258 "0x%04x", rl->cipher_suite); 259 rl->read_cipher_suite = rl->cipher_suite; 260 os_memset(rl->read_seq_num, 0, TLS_SEQ_NUM_LEN); 261 262 if (rl->read_cbc) { 263 crypto_cipher_deinit(rl->read_cbc); 264 rl->read_cbc = NULL; 265 } 266 if (rl->cipher_alg != CRYPTO_CIPHER_NULL) { 267 rl->read_cbc = crypto_cipher_init(rl->cipher_alg, 268 rl->read_iv, rl->read_key, 269 rl->key_material_len); 270 if (rl->read_cbc == NULL) { 271 wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize " 272 "cipher"); 273 return -1; 274 } 275 } 276 277 return 0; 278 } 279 280 281 /** 282 * tlsv1_record_send - TLS record layer: Send a message 283 * @rl: Pointer to TLS record layer data 284 * @content_type: Content type (TLS_CONTENT_TYPE_*) 285 * @buf: Buffer to send (with TLS_RECORD_HEADER_LEN octets reserved in the 286 * beginning for record layer to fill in; payload filled in after this and 287 * extra space in the end for HMAC). 288 * @buf_size: Maximum buf size 289 * @payload_len: Length of the payload 290 * @out_len: Buffer for returning the used buf length 291 * Returns: 0 on success, -1 on failure 292 * 293 * This function fills in the TLS record layer header, adds HMAC, and encrypts 294 * the data using the current write cipher. 295 */ 296 int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf, 297 size_t buf_size, size_t payload_len, size_t *out_len) 298 { 299 u8 *pos, *ct_start, *length, *payload; 300 struct crypto_hash *hmac; 301 size_t clen; 302 303 pos = buf; 304 /* ContentType type */ 305 ct_start = pos; 306 *pos++ = content_type; 307 /* ProtocolVersion version */ 308 WPA_PUT_BE16(pos, TLS_VERSION); 309 pos += 2; 310 /* uint16 length */ 311 length = pos; 312 WPA_PUT_BE16(length, payload_len); 313 pos += 2; 314 315 /* opaque fragment[TLSPlaintext.length] */ 316 payload = pos; 317 pos += payload_len; 318 319 if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) { 320 hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret, 321 rl->hash_size); 322 if (hmac == NULL) { 323 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed " 324 "to initialize HMAC"); 325 return -1; 326 } 327 crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN); 328 /* type + version + length + fragment */ 329 crypto_hash_update(hmac, ct_start, pos - ct_start); 330 clen = buf + buf_size - pos; 331 if (clen < rl->hash_size) { 332 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not " 333 "enough room for MAC"); 334 crypto_hash_finish(hmac, NULL, NULL); 335 return -1; 336 } 337 338 if (crypto_hash_finish(hmac, pos, &clen) < 0) { 339 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed " 340 "to calculate HMAC"); 341 return -1; 342 } 343 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Write HMAC", 344 pos, clen); 345 pos += clen; 346 if (rl->iv_size) { 347 size_t len = pos - payload; 348 size_t pad; 349 pad = (len + 1) % rl->iv_size; 350 if (pad) 351 pad = rl->iv_size - pad; 352 if (pos + pad + 1 > buf + buf_size) { 353 wpa_printf(MSG_DEBUG, "TLSv1: No room for " 354 "block cipher padding"); 355 return -1; 356 } 357 os_memset(pos, pad, pad + 1); 358 pos += pad + 1; 359 } 360 361 if (crypto_cipher_encrypt(rl->write_cbc, payload, 362 payload, pos - payload) < 0) 363 return -1; 364 } 365 366 WPA_PUT_BE16(length, pos - length - 2); 367 inc_byte_array(rl->write_seq_num, TLS_SEQ_NUM_LEN); 368 369 *out_len = pos - buf; 370 371 return 0; 372 } 373 374 375 /** 376 * tlsv1_record_receive - TLS record layer: Process a received message 377 * @rl: Pointer to TLS record layer data 378 * @in_data: Received data 379 * @in_len: Length of the received data 380 * @out_data: Buffer for output data (must be at least as long as in_data) 381 * @out_len: Set to maximum out_data length by caller; used to return the 382 * length of the used data 383 * @alert: Buffer for returning an alert value on failure 384 * Returns: 0 on success, -1 on failure 385 * 386 * This function decrypts the received message, verifies HMAC and TLS record 387 * layer header. 388 */ 389 int tlsv1_record_receive(struct tlsv1_record_layer *rl, 390 const u8 *in_data, size_t in_len, 391 u8 *out_data, size_t *out_len, u8 *alert) 392 { 393 size_t i, rlen, hlen; 394 u8 padlen; 395 struct crypto_hash *hmac; 396 u8 len[2], hash[100]; 397 398 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received", 399 in_data, in_len); 400 401 if (in_len < TLS_RECORD_HEADER_LEN) { 402 wpa_printf(MSG_DEBUG, "TLSv1: Too short record (in_len=%lu)", 403 (unsigned long) in_len); 404 *alert = TLS_ALERT_DECODE_ERROR; 405 return -1; 406 } 407 408 wpa_printf(MSG_DEBUG, "TLSv1: Received content type %d version %d.%d " 409 "length %d", in_data[0], in_data[1], in_data[2], 410 WPA_GET_BE16(in_data + 3)); 411 412 if (in_data[0] != TLS_CONTENT_TYPE_HANDSHAKE && 413 in_data[0] != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC && 414 in_data[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) { 415 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type 0x%x", 416 in_data[0]); 417 *alert = TLS_ALERT_UNEXPECTED_MESSAGE; 418 return -1; 419 } 420 421 if (WPA_GET_BE16(in_data + 1) != TLS_VERSION) { 422 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version " 423 "%d.%d", in_data[1], in_data[2]); 424 *alert = TLS_ALERT_PROTOCOL_VERSION; 425 return -1; 426 } 427 428 rlen = WPA_GET_BE16(in_data + 3); 429 430 /* TLSCiphertext must not be more than 2^14+2048 bytes */ 431 if (TLS_RECORD_HEADER_LEN + rlen > 18432) { 432 wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)", 433 (unsigned long) (TLS_RECORD_HEADER_LEN + rlen)); 434 *alert = TLS_ALERT_RECORD_OVERFLOW; 435 return -1; 436 } 437 438 in_data += TLS_RECORD_HEADER_LEN; 439 in_len -= TLS_RECORD_HEADER_LEN; 440 441 if (rlen > in_len) { 442 wpa_printf(MSG_DEBUG, "TLSv1: Not all record data included " 443 "(rlen=%lu > in_len=%lu)", 444 (unsigned long) rlen, (unsigned long) in_len); 445 *alert = TLS_ALERT_DECODE_ERROR; 446 return -1; 447 } 448 449 in_len = rlen; 450 451 if (*out_len < in_len) { 452 wpa_printf(MSG_DEBUG, "TLSv1: Not enough output buffer for " 453 "processing received record"); 454 *alert = TLS_ALERT_INTERNAL_ERROR; 455 return -1; 456 } 457 458 os_memcpy(out_data, in_data, in_len); 459 *out_len = in_len; 460 461 if (rl->read_cipher_suite != TLS_NULL_WITH_NULL_NULL) { 462 if (crypto_cipher_decrypt(rl->read_cbc, out_data, 463 out_data, in_len) < 0) { 464 *alert = TLS_ALERT_DECRYPTION_FAILED; 465 return -1; 466 } 467 if (rl->iv_size) { 468 if (in_len == 0) { 469 wpa_printf(MSG_DEBUG, "TLSv1: Too short record" 470 " (no pad)"); 471 *alert = TLS_ALERT_DECODE_ERROR; 472 return -1; 473 } 474 padlen = out_data[in_len - 1]; 475 if (padlen >= in_len) { 476 wpa_printf(MSG_DEBUG, "TLSv1: Incorrect pad " 477 "length (%u, in_len=%lu) in " 478 "received record", 479 padlen, (unsigned long) in_len); 480 *alert = TLS_ALERT_DECRYPTION_FAILED; 481 return -1; 482 } 483 for (i = in_len - padlen; i < in_len; i++) { 484 if (out_data[i] != padlen) { 485 wpa_hexdump(MSG_DEBUG, 486 "TLSv1: Invalid pad in " 487 "received record", 488 out_data + in_len - padlen, 489 padlen); 490 *alert = TLS_ALERT_DECRYPTION_FAILED; 491 return -1; 492 } 493 } 494 495 *out_len -= padlen + 1; 496 } 497 498 wpa_hexdump(MSG_MSGDUMP, 499 "TLSv1: Record Layer - Decrypted data", 500 out_data, in_len); 501 502 if (*out_len < rl->hash_size) { 503 wpa_printf(MSG_DEBUG, "TLSv1: Too short record; no " 504 "hash value"); 505 *alert = TLS_ALERT_INTERNAL_ERROR; 506 return -1; 507 } 508 509 *out_len -= rl->hash_size; 510 511 hmac = crypto_hash_init(rl->hash_alg, rl->read_mac_secret, 512 rl->hash_size); 513 if (hmac == NULL) { 514 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed " 515 "to initialize HMAC"); 516 *alert = TLS_ALERT_INTERNAL_ERROR; 517 return -1; 518 } 519 520 crypto_hash_update(hmac, rl->read_seq_num, TLS_SEQ_NUM_LEN); 521 /* type + version + length + fragment */ 522 crypto_hash_update(hmac, in_data - TLS_RECORD_HEADER_LEN, 3); 523 WPA_PUT_BE16(len, *out_len); 524 crypto_hash_update(hmac, len, 2); 525 crypto_hash_update(hmac, out_data, *out_len); 526 hlen = sizeof(hash); 527 if (crypto_hash_finish(hmac, hash, &hlen) < 0) { 528 wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed " 529 "to calculate HMAC"); 530 return -1; 531 } 532 if (hlen != rl->hash_size || 533 os_memcmp(hash, out_data + *out_len, hlen) != 0) { 534 wpa_printf(MSG_DEBUG, "TLSv1: Invalid HMAC value in " 535 "received message"); 536 *alert = TLS_ALERT_BAD_RECORD_MAC; 537 return -1; 538 } 539 } 540 541 /* TLSCompressed must not be more than 2^14+1024 bytes */ 542 if (TLS_RECORD_HEADER_LEN + *out_len > 17408) { 543 wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)", 544 (unsigned long) (TLS_RECORD_HEADER_LEN + *out_len)); 545 *alert = TLS_ALERT_RECORD_OVERFLOW; 546 return -1; 547 } 548 549 inc_byte_array(rl->read_seq_num, TLS_SEQ_NUM_LEN); 550 551 return 0; 552 } 553