Serenity Operating System
at master 571 lines 24 kB view raw
1/* 2 * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Debug.h> 8#include <AK/Endian.h> 9#include <AK/MemoryStream.h> 10#include <LibCore/EventLoop.h> 11#include <LibCore/Timer.h> 12#include <LibCrypto/PK/Code/EMSA_PSS.h> 13#include <LibTLS/TLSv12.h> 14 15namespace TLS { 16 17ByteBuffer TLSv12::build_alert(bool critical, u8 code) 18{ 19 PacketBuilder builder(MessageType::Alert, (u16)m_context.options.version); 20 builder.append((u8)(critical ? AlertLevel::Critical : AlertLevel::Warning)); 21 builder.append(code); 22 23 if (critical) 24 m_context.critical_error = code; 25 26 auto packet = builder.build(); 27 update_packet(packet); 28 29 return packet; 30} 31 32void TLSv12::alert(AlertLevel level, AlertDescription code) 33{ 34 auto the_alert = build_alert(level == AlertLevel::Critical, (u8)code); 35 write_packet(the_alert); 36 MUST(flush()); 37} 38 39void TLSv12::write_packet(ByteBuffer& packet) 40{ 41 auto schedule_or_perform_flush = [&](bool immediate) { 42 if (m_context.connection_status > ConnectionStatus::Disconnected) { 43 if (!m_has_scheduled_write_flush && !immediate) { 44 dbgln_if(TLS_DEBUG, "Scheduling write of {}", m_context.tls_buffer.size()); 45 Core::deferred_invoke([this] { write_into_socket(); }); 46 m_has_scheduled_write_flush = true; 47 } else { 48 // multiple packet are available, let's flush some out 49 dbgln_if(TLS_DEBUG, "Flushing scheduled write of {}", m_context.tls_buffer.size()); 50 write_into_socket(); 51 // the deferred invoke is still in place 52 m_has_scheduled_write_flush = true; 53 } 54 } 55 }; 56 // Record size limit is 18432 bytes, leave some headroom and flush at 16K. 57 if (m_context.tls_buffer.size() + packet.size() > 16 * KiB) 58 schedule_or_perform_flush(true); 59 60 if (m_context.tls_buffer.try_append(packet.data(), packet.size()).is_error()) { 61 // Toooooo bad, drop the record on the ground. 62 return; 63 } 64 schedule_or_perform_flush(false); 65} 66 67void TLSv12::update_packet(ByteBuffer& packet) 68{ 69 u32 header_size = 5; 70 ByteReader::store(packet.offset_pointer(3), AK::convert_between_host_and_network_endian((u16)(packet.size() - header_size))); 71 72 if (packet[0] != (u8)MessageType::ChangeCipher) { 73 if (packet[0] == (u8)MessageType::Handshake && packet.size() > header_size) { 74 u8 handshake_type = packet[header_size]; 75 if (handshake_type != HandshakeType::HelloRequest && handshake_type != HandshakeType::HelloVerifyRequest) { 76 update_hash(packet.bytes(), header_size); 77 } 78 } 79 if (m_context.cipher_spec_set && m_context.crypto.created) { 80 size_t length = packet.size() - header_size; 81 size_t block_size = 0; 82 size_t padding = 0; 83 size_t mac_size = 0; 84 85 m_cipher_local.visit( 86 [&](Empty&) { VERIFY_NOT_REACHED(); }, 87 [&](Crypto::Cipher::AESCipher::GCMMode& gcm) { 88 VERIFY(is_aead()); 89 block_size = gcm.cipher().block_size(); 90 padding = 0; 91 mac_size = 0; // AEAD provides its own authentication scheme. 92 }, 93 [&](Crypto::Cipher::AESCipher::CBCMode& cbc) { 94 VERIFY(!is_aead()); 95 block_size = cbc.cipher().block_size(); 96 // If the length is already a multiple a block_size, 97 // an entire block of padding is added. 98 // In short, we _never_ have no padding. 99 mac_size = mac_length(); 100 length += mac_size; 101 padding = block_size - length % block_size; 102 length += padding; 103 }); 104 105 if (m_context.crypto.created == 1) { 106 // `buffer' will continue to be encrypted 107 auto buffer_result = ByteBuffer::create_uninitialized(length); 108 if (buffer_result.is_error()) { 109 dbgln("LibTLS: Failed to allocate enough memory"); 110 VERIFY_NOT_REACHED(); 111 } 112 auto buffer = buffer_result.release_value(); 113 size_t buffer_position = 0; 114 auto iv_size = iv_length(); 115 116 // copy the packet, sans the header 117 buffer.overwrite(buffer_position, packet.offset_pointer(header_size), packet.size() - header_size); 118 buffer_position += packet.size() - header_size; 119 120 ByteBuffer ct; 121 122 m_cipher_local.visit( 123 [&](Empty&) { VERIFY_NOT_REACHED(); }, 124 [&](Crypto::Cipher::AESCipher::GCMMode& gcm) { 125 VERIFY(is_aead()); 126 // We need enough space for a header, the data, a tag, and the IV 127 auto ct_buffer_result = ByteBuffer::create_uninitialized(length + header_size + iv_size + 16); 128 if (ct_buffer_result.is_error()) { 129 dbgln("LibTLS: Failed to allocate enough memory for the ciphertext"); 130 VERIFY_NOT_REACHED(); 131 } 132 ct = ct_buffer_result.release_value(); 133 134 // copy the header over 135 ct.overwrite(0, packet.data(), header_size - 2); 136 137 // AEAD AAD (13) 138 // Seq. no (8) 139 // content type (1) 140 // version (2) 141 // length (2) 142 u8 aad[13]; 143 Bytes aad_bytes { aad, 13 }; 144 FixedMemoryStream aad_stream { aad_bytes }; 145 146 u64 seq_no = AK::convert_between_host_and_network_endian(m_context.local_sequence_number); 147 u16 len = AK::convert_between_host_and_network_endian((u16)(packet.size() - header_size)); 148 149 MUST(aad_stream.write_value(seq_no)); // sequence number 150 MUST(aad_stream.write_until_depleted(packet.bytes().slice(0, 3))); // content-type + version 151 MUST(aad_stream.write_value(len)); // length 152 VERIFY(MUST(aad_stream.tell()) == MUST(aad_stream.size())); 153 154 // AEAD IV (12) 155 // IV (4) 156 // (Nonce) (8) 157 // -- Our GCM impl takes 16 bytes 158 // zero (4) 159 u8 iv[16]; 160 Bytes iv_bytes { iv, 16 }; 161 Bytes { m_context.crypto.local_aead_iv, 4 }.copy_to(iv_bytes); 162 fill_with_random(iv_bytes.offset(4), 8); 163 memset(iv_bytes.offset(12), 0, 4); 164 165 // write the random part of the iv out 166 iv_bytes.slice(4, 8).copy_to(ct.bytes().slice(header_size)); 167 168 // Write the encrypted data and the tag 169 gcm.encrypt( 170 packet.bytes().slice(header_size, length), 171 ct.bytes().slice(header_size + 8, length), 172 iv_bytes, 173 aad_bytes, 174 ct.bytes().slice(header_size + 8 + length, 16)); 175 176 VERIFY(header_size + 8 + length + 16 == ct.size()); 177 }, 178 [&](Crypto::Cipher::AESCipher::CBCMode& cbc) { 179 VERIFY(!is_aead()); 180 // We need enough space for a header, iv_length bytes of IV and whatever the packet contains 181 auto ct_buffer_result = ByteBuffer::create_uninitialized(length + header_size + iv_size); 182 if (ct_buffer_result.is_error()) { 183 dbgln("LibTLS: Failed to allocate enough memory for the ciphertext"); 184 VERIFY_NOT_REACHED(); 185 } 186 ct = ct_buffer_result.release_value(); 187 188 // copy the header over 189 ct.overwrite(0, packet.data(), header_size - 2); 190 191 // get the appropriate HMAC value for the entire packet 192 auto mac = hmac_message(packet, {}, mac_size, true); 193 194 // write the MAC 195 buffer.overwrite(buffer_position, mac.data(), mac.size()); 196 buffer_position += mac.size(); 197 198 // Apply the padding (a packet MUST always be padded) 199 memset(buffer.offset_pointer(buffer_position), padding - 1, padding); 200 buffer_position += padding; 201 202 VERIFY(buffer_position == buffer.size()); 203 204 auto iv_buffer_result = ByteBuffer::create_uninitialized(iv_size); 205 if (iv_buffer_result.is_error()) { 206 dbgln("LibTLS: Failed to allocate memory for IV"); 207 VERIFY_NOT_REACHED(); 208 } 209 auto iv = iv_buffer_result.release_value(); 210 fill_with_random(iv.data(), iv.size()); 211 212 // write it into the ciphertext portion of the message 213 ct.overwrite(header_size, iv.data(), iv.size()); 214 215 VERIFY(header_size + iv_size + length == ct.size()); 216 VERIFY(length % block_size == 0); 217 218 // get a block to encrypt into 219 auto view = ct.bytes().slice(header_size + iv_size, length); 220 cbc.encrypt(buffer, view, iv); 221 }); 222 223 // store the correct ciphertext length into the packet 224 u16 ct_length = (u16)ct.size() - header_size; 225 226 ByteReader::store(ct.offset_pointer(header_size - 2), AK::convert_between_host_and_network_endian(ct_length)); 227 228 // replace the packet with the ciphertext 229 packet = ct; 230 } 231 } 232 } 233 ++m_context.local_sequence_number; 234} 235 236void TLSv12::update_hash(ReadonlyBytes message, size_t header_size) 237{ 238 dbgln_if(TLS_DEBUG, "Update hash with message of size {}", message.size()); 239 m_context.handshake_hash.update(message.slice(header_size)); 240} 241 242void TLSv12::ensure_hmac(size_t digest_size, bool local) 243{ 244 if (local && m_hmac_local) 245 return; 246 247 if (!local && m_hmac_remote) 248 return; 249 250 auto hash_kind = Crypto::Hash::HashKind::None; 251 252 switch (digest_size) { 253 case Crypto::Hash::SHA1::DigestSize: 254 hash_kind = Crypto::Hash::HashKind::SHA1; 255 break; 256 case Crypto::Hash::SHA256::DigestSize: 257 hash_kind = Crypto::Hash::HashKind::SHA256; 258 break; 259 case Crypto::Hash::SHA384::DigestSize: 260 hash_kind = Crypto::Hash::HashKind::SHA384; 261 break; 262 case Crypto::Hash::SHA512::DigestSize: 263 hash_kind = Crypto::Hash::HashKind::SHA512; 264 break; 265 default: 266 dbgln("Failed to find a suitable hash for size {}", digest_size); 267 break; 268 } 269 270 auto hmac = make<Crypto::Authentication::HMAC<Crypto::Hash::Manager>>(ReadonlyBytes { local ? m_context.crypto.local_mac : m_context.crypto.remote_mac, digest_size }, hash_kind); 271 if (local) 272 m_hmac_local = move(hmac); 273 else 274 m_hmac_remote = move(hmac); 275} 276 277ByteBuffer TLSv12::hmac_message(ReadonlyBytes buf, Optional<ReadonlyBytes> const buf2, size_t mac_length, bool local) 278{ 279 u64 sequence_number = AK::convert_between_host_and_network_endian(local ? m_context.local_sequence_number : m_context.remote_sequence_number); 280 ensure_hmac(mac_length, local); 281 auto& hmac = local ? *m_hmac_local : *m_hmac_remote; 282 if constexpr (TLS_DEBUG) { 283 dbgln("========================= PACKET DATA =========================="); 284 print_buffer((u8 const*)&sequence_number, sizeof(u64)); 285 print_buffer(buf.data(), buf.size()); 286 if (buf2.has_value()) 287 print_buffer(buf2.value().data(), buf2.value().size()); 288 dbgln("========================= PACKET DATA =========================="); 289 } 290 hmac.update((u8 const*)&sequence_number, sizeof(u64)); 291 hmac.update(buf); 292 if (buf2.has_value() && buf2.value().size()) { 293 hmac.update(buf2.value()); 294 } 295 auto digest = hmac.digest(); 296 auto mac_result = ByteBuffer::copy(digest.immutable_data(), digest.data_length()); 297 if (mac_result.is_error()) { 298 dbgln("Failed to calculate message HMAC: Not enough memory"); 299 return {}; 300 } 301 302 if constexpr (TLS_DEBUG) { 303 dbgln("HMAC of the block for sequence number {}", sequence_number); 304 print_buffer(mac_result.value()); 305 } 306 307 return mac_result.release_value(); 308} 309 310ssize_t TLSv12::handle_message(ReadonlyBytes buffer) 311{ 312 auto res { 5ll }; 313 size_t header_size = res; 314 ssize_t payload_res = 0; 315 316 dbgln_if(TLS_DEBUG, "buffer size: {}", buffer.size()); 317 318 if (buffer.size() < 5) { 319 return (i8)Error::NeedMoreData; 320 } 321 322 auto type = (MessageType)buffer[0]; 323 size_t buffer_position { 1 }; 324 325 // FIXME: Read the version and verify it 326 327 if constexpr (TLS_DEBUG) { 328 auto version = ByteReader::load16(buffer.offset_pointer(buffer_position)); 329 dbgln("type={}, version={}", (u8)type, (u16)version); 330 } 331 332 buffer_position += 2; 333 334 auto length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(buffer_position))); 335 336 dbgln_if(TLS_DEBUG, "record length: {} at offset: {}", length, buffer_position); 337 buffer_position += 2; 338 339 if (buffer_position + length > buffer.size()) { 340 dbgln_if(TLS_DEBUG, "record length more than what we have: {}", buffer.size()); 341 return (i8)Error::NeedMoreData; 342 } 343 344 dbgln_if(TLS_DEBUG, "message type: {}, length: {}", (u8)type, length); 345 auto plain = buffer.slice(buffer_position, buffer.size() - buffer_position); 346 347 ByteBuffer decrypted; 348 349 if (m_context.cipher_spec_set && type != MessageType::ChangeCipher) { 350 if constexpr (TLS_DEBUG) { 351 dbgln("Encrypted: "); 352 print_buffer(buffer.slice(header_size, length)); 353 } 354 355 Error return_value = Error::NoError; 356 m_cipher_remote.visit( 357 [&](Empty&) { VERIFY_NOT_REACHED(); }, 358 [&](Crypto::Cipher::AESCipher::GCMMode& gcm) { 359 VERIFY(is_aead()); 360 if (length < 24) { 361 dbgln("Invalid packet length"); 362 auto packet = build_alert(true, (u8)AlertDescription::DecryptError); 363 write_packet(packet); 364 return_value = Error::BrokenPacket; 365 return; 366 } 367 368 auto packet_length = length - iv_length() - 16; 369 auto payload = plain; 370 auto decrypted_result = ByteBuffer::create_uninitialized(packet_length); 371 if (decrypted_result.is_error()) { 372 dbgln("Failed to allocate memory for the packet"); 373 return_value = Error::DecryptionFailed; 374 return; 375 } 376 decrypted = decrypted_result.release_value(); 377 378 // AEAD AAD (13) 379 // Seq. no (8) 380 // content type (1) 381 // version (2) 382 // length (2) 383 u8 aad[13]; 384 Bytes aad_bytes { aad, 13 }; 385 FixedMemoryStream aad_stream { aad_bytes }; 386 387 u64 seq_no = AK::convert_between_host_and_network_endian(m_context.remote_sequence_number); 388 u16 len = AK::convert_between_host_and_network_endian((u16)packet_length); 389 390 MUST(aad_stream.write_value(seq_no)); // sequence number 391 MUST(aad_stream.write_until_depleted(buffer.slice(0, header_size - 2))); // content-type + version 392 MUST(aad_stream.write_value(len)); // length 393 VERIFY(MUST(aad_stream.tell()) == MUST(aad_stream.size())); 394 395 auto nonce = payload.slice(0, iv_length()); 396 payload = payload.slice(iv_length()); 397 398 // AEAD IV (12) 399 // IV (4) 400 // (Nonce) (8) 401 // -- Our GCM impl takes 16 bytes 402 // zero (4) 403 u8 iv[16]; 404 Bytes iv_bytes { iv, 16 }; 405 Bytes { m_context.crypto.remote_aead_iv, 4 }.copy_to(iv_bytes); 406 nonce.copy_to(iv_bytes.slice(4)); 407 memset(iv_bytes.offset(12), 0, 4); 408 409 auto ciphertext = payload.slice(0, payload.size() - 16); 410 auto tag = payload.slice(ciphertext.size()); 411 412 auto consistency = gcm.decrypt( 413 ciphertext, 414 decrypted, 415 iv_bytes, 416 aad_bytes, 417 tag); 418 419 if (consistency != Crypto::VerificationConsistency::Consistent) { 420 dbgln("integrity check failed (tag length {})", tag.size()); 421 auto packet = build_alert(true, (u8)AlertDescription::BadRecordMAC); 422 write_packet(packet); 423 424 return_value = Error::IntegrityCheckFailed; 425 return; 426 } 427 428 plain = decrypted; 429 }, 430 [&](Crypto::Cipher::AESCipher::CBCMode& cbc) { 431 VERIFY(!is_aead()); 432 auto iv_size = iv_length(); 433 434 auto decrypted_result = cbc.create_aligned_buffer(length - iv_size); 435 if (decrypted_result.is_error()) { 436 dbgln("Failed to allocate memory for the packet"); 437 return_value = Error::DecryptionFailed; 438 return; 439 } 440 decrypted = decrypted_result.release_value(); 441 auto iv = buffer.slice(header_size, iv_size); 442 443 Bytes decrypted_span = decrypted; 444 cbc.decrypt(buffer.slice(header_size + iv_size, length - iv_size), decrypted_span, iv); 445 446 length = decrypted_span.size(); 447 448 if constexpr (TLS_DEBUG) { 449 dbgln("Decrypted: "); 450 print_buffer(decrypted); 451 } 452 453 auto mac_size = mac_length(); 454 if (length < mac_size) { 455 dbgln("broken packet"); 456 auto packet = build_alert(true, (u8)AlertDescription::DecryptError); 457 write_packet(packet); 458 return_value = Error::BrokenPacket; 459 return; 460 } 461 462 length -= mac_size; 463 464 const u8* message_hmac = decrypted_span.offset(length); 465 u8 temp_buf[5]; 466 memcpy(temp_buf, buffer.offset_pointer(0), 3); 467 *(u16*)(temp_buf + 3) = AK::convert_between_host_and_network_endian(length); 468 auto hmac = hmac_message({ temp_buf, 5 }, decrypted_span.slice(0, length), mac_size); 469 auto message_mac = ReadonlyBytes { message_hmac, mac_size }; 470 if (hmac != message_mac) { 471 dbgln("integrity check failed (mac length {})", mac_size); 472 dbgln("mac received:"); 473 print_buffer(message_mac); 474 dbgln("mac computed:"); 475 print_buffer(hmac); 476 auto packet = build_alert(true, (u8)AlertDescription::BadRecordMAC); 477 write_packet(packet); 478 479 return_value = Error::IntegrityCheckFailed; 480 return; 481 } 482 plain = decrypted.bytes().slice(0, length); 483 }); 484 485 if (return_value != Error::NoError) { 486 return (i8)return_value; 487 } 488 } 489 m_context.remote_sequence_number++; 490 491 switch (type) { 492 case MessageType::ApplicationData: 493 if (m_context.connection_status != ConnectionStatus::Established) { 494 dbgln("unexpected application data"); 495 payload_res = (i8)Error::UnexpectedMessage; 496 auto packet = build_alert(true, (u8)AlertDescription::UnexpectedMessage); 497 write_packet(packet); 498 } else { 499 dbgln_if(TLS_DEBUG, "application data message of size {}", plain.size()); 500 501 if (m_context.application_buffer.try_append(plain.data(), plain.size()).is_error()) { 502 payload_res = (i8)Error::DecryptionFailed; 503 auto packet = build_alert(true, (u8)AlertDescription::DecryptionFailed); 504 write_packet(packet); 505 } 506 } 507 break; 508 case MessageType::Handshake: 509 dbgln_if(TLS_DEBUG, "tls handshake message"); 510 payload_res = handle_handshake_payload(plain); 511 break; 512 case MessageType::ChangeCipher: 513 if (m_context.connection_status != ConnectionStatus::KeyExchange) { 514 dbgln("unexpected change cipher message"); 515 auto packet = build_alert(true, (u8)AlertDescription::UnexpectedMessage); 516 write_packet(packet); 517 payload_res = (i8)Error::UnexpectedMessage; 518 } else { 519 dbgln_if(TLS_DEBUG, "change cipher spec message"); 520 m_context.cipher_spec_set = true; 521 m_context.remote_sequence_number = 0; 522 } 523 break; 524 case MessageType::Alert: 525 dbgln_if(TLS_DEBUG, "alert message of length {}", length); 526 if (length >= 2) { 527 if constexpr (TLS_DEBUG) 528 print_buffer(plain); 529 530 auto level = plain[0]; 531 auto code = plain[1]; 532 dbgln_if(TLS_DEBUG, "Alert received with level {}, code {}", level, code); 533 534 if (level == (u8)AlertLevel::Critical) { 535 dbgln("We were alerted of a critical error: {} ({})", code, alert_name((AlertDescription)code)); 536 m_context.critical_error = code; 537 try_disambiguate_error(); 538 res = (i8)Error::UnknownError; 539 } 540 541 if (code == (u8)AlertDescription::CloseNotify) { 542 res += 2; 543 alert(AlertLevel::Critical, AlertDescription::CloseNotify); 544 if (!m_context.cipher_spec_set) { 545 // AWS CloudFront hits this. 546 dbgln("Server sent a close notify and we haven't agreed on a cipher suite. Treating it as a handshake failure."); 547 m_context.critical_error = (u8)AlertDescription::HandshakeFailure; 548 try_disambiguate_error(); 549 } 550 m_context.close_notify = true; 551 } 552 m_context.error_code = (Error)code; 553 check_connection_state(false); 554 notify_client_for_app_data(); // Give the user one more chance to observe the EOF 555 } 556 break; 557 default: 558 dbgln("message not understood"); 559 return (i8)Error::NotUnderstood; 560 } 561 562 if (payload_res < 0) 563 return payload_res; 564 565 if (res > 0) 566 return header_size + length; 567 568 return res; 569} 570 571}