def process_encrypted_pap_avp(tls_state, tls_packet): records = tls_packet.get_records() if len(records) != 0x1: return [] message = bytearray(records[0].get_bytes_without_header()) key = tls_state.get_client_write_cipher_key() iv = message[0:aes.IV_SIZE] cipher = aes.AESCipher(aes.AES_CBC_MODE, key, iv) decrypted_bytes = cipher.decrypt(message[aes.IV_SIZE:len(message)]) # The decrypted message comprises the following parts: # (i) Actual payload # (ii) HMAC # (iii) Padding # (iv) Padding length (last byte) payload = decrypted_bytes[0:len(decrypted_bytes) - tls.HMAC_LENGTH - decrypted_bytes[len(decrypted_bytes) - 1] - 1] hmac_value = decrypted_bytes[len(payload):len(payload) + tls.HMAC_LENGTH] client_sequence_number = tls_state.get_client_sequence_number() if not (utils.Utils.verify_mac( tls_state.get_client_write_mac_key(), client_sequence_number, tls.TLS_CONTENT_TYPE_APPLICATION_DATA, tls.TLS_PROTOCOL_VERSION, payload, hmac_value)): print("Failed to verify MAC of the PAP message. Dropping...") return False tls_state.increment_client_sequence_number() return eap.ParseAVP().parse(payload)
def process_encrypted_alert(tls_state, tls_packet): packet_bytes = bytearray( tls_packet.get_records()[0].get_bytes_without_header()) key = tls_state.get_client_write_cipher_key() iv = packet_bytes[0:aes.IV_SIZE] cipher = aes.AESCipher(aes.AES_CBC_MODE, key, iv) decrypted_bytes = cipher.decrypt( packet_bytes[aes.IV_SIZE:len(packet_bytes)])
def handle_client_encrypted_finish_message(tls_packet, tls_state, handshake_messages): """ Handles client's encrypted finished message """ # We need to check the number of records first. It can be that all protocols are # embedded into single record layer. records = tls_packet.get_records() # This ugly code needs to be restructured # Also we should consider TLS packets which have single record, but many protocols encrypted_finished_protocol = bytearray( records[2].get_bytes_without_header()) key = tls_state.get_client_write_cipher_key() iv = encrypted_finished_protocol[0:aes.IV_SIZE] cipher = aes.AESCipher(aes.AES_CBC_MODE, key, iv) decrypted_bytes = cipher.decrypt(encrypted_finished_protocol[ aes.IV_SIZE:len(encrypted_finished_protocol)]) master_secret = tls_state.get_master_secret() finished_message_protocol = tls.FinishedMessageProtocol( decrypted_bytes) verify_data_original = finished_message_protocol.get_verify_data() # https://stackoverflow.com/questions/2359662a2/tls-1-0-calculating-the-finished-message-mac # https://tools.ietf.org/html/rfc5246#section-6.2.3.1 length = finished_message_protocol.get_length() offset = tls.FINISHED_MESSAGE_VERIFY_DATA_OFFSET + length hmac_value = decrypted_bytes[offset:offset + tls.FINISHED_MESSAGE_HMAC_LENGTH] #print(hexlify(bytearray(hmac_value))); message = decrypted_bytes[0:tls.FINISHED_MESSAGE_VERIFY_DATA_OFFSET + length] client_sequence_number = tls_state.get_client_sequence_number() if not (utils.Utils.verify_mac( tls_state.get_client_write_mac_key(), client_sequence_number, tls.TLS_CONTENT_TYPE_HANDSHAKE, tls.TLS_PROTOCOL_VERSION, message, hmac_value)): print("Failed to verify MAC of the finished message. Dropping...") return False tls_state.increment_client_sequence_number() verify_data_computed = utils.Utils.verify_client_finshed_message( master_secret, handshake_messages, finished_message_protocol.get_length()) return utils.Utils.compare_bytearrays(verify_data_original, verify_data_computed)
def get_unencrypted_finished_message(tls_state, tls_packet): """ Extracts finished message from TLS packet """ records = tls_packet.get_records() encrypted_finished_protocol = bytearray( records[2].get_bytes_without_header()) key = tls_state.get_client_write_cipher_key() iv = encrypted_finished_protocol[0:aes.IV_SIZE] cipher = aes.AESCipher(aes.AES_CBC_MODE, key, iv) decrypted_bytes = cipher.decrypt(encrypted_finished_protocol[ aes.IV_SIZE:len(encrypted_finished_protocol)]) length = ( (decrypted_bytes[tls.TLS_HANDSHAKE_LENGTH_OFFSET] << 16) | (decrypted_bytes[tls.TLS_HANDSHAKE_LENGTH_OFFSET + 1] << 8) | (decrypted_bytes[tls.TLS_HANDSHAKE_LENGTH_OFFSET + 2] & 0xFF)) finished_message_protocol = tls.FinishedMessageProtocol( decrypted_bytes[0:tls.FINISHED_MESSAGE_VERIFY_DATA_OFFSET + length]) #hexlify(bytearray(finished_message_protocol.get_bytes())) return finished_message_protocol.get_bytes()
def process_server_encrypted_finish_message(tls_state, handshake_messages, authenticator, radius_identifier, socket, address): """ Processes server's encrypted finish message """ master_secret = tls_state.get_master_secret() verify_data_computed = utils.Utils.verify_server_finshed_message( master_secret, handshake_messages, tls.FINISHED_MESSAGE_VERIFY_DATA_LENGTH) server_sequence_number = tls_state.get_server_sequence_number() tls_packet = tls.TLSPacket() tls_record = tls.TLSRecordLayer() finished_message_protocol = tls.FinishedMessageProtocol() finished_message_protocol.set_verify_data(verify_data_computed) hmac = utils.Utils.compute_server_finished_message_mac( tls_state.get_server_write_mac_key(), server_sequence_number, tls.TLS_CONTENT_TYPE_HANDSHAKE, tls.TLS_PROTOCOL_VERSION, finished_message_protocol.get_bytes()) finished_message_protocol_bytes = finished_message_protocol.get_bytes( ) message = bytearray(finished_message_protocol_bytes) + hmac # This should be # padding = [(aes.BLOCK_SIZE - len(message) % aes.BLOCK_SIZE)] * (aes.BLOCK_SIZE - len(message) % aes.BLOCK_SIZE); padding = [0x0f] * (aes.BLOCK_SIZE - len(message) % aes.BLOCK_SIZE) padding[len(padding) - 1] = len(padding) - 1 key = tls_state.get_server_write_cipher_key() iv = utils.Utils.generate_random(aes.IV_SIZE) cipher = aes.AESCipher(aes.AES_CBC_MODE, key, iv) encrypted_bytes = cipher.encrypt((message + bytearray(padding))) tls_record.add_encrypted_protocol(bytearray(iv + encrypted_bytes)) tls_packet.add_record(tls_record) eap_ttls_packet = eap.EAPTTLSRequest() eap_ttls_packet.set_payload(tls_packet.get_bytes(), len(tls_packet.get_bytes())) packet = eap_ttls_packet.get_bytes() radius_challenge = radius.RADIUSPacket() """ Set the code of the RADIUS packet to challenge type """ radius_challenge.set_code(radius.RADIUS_ACCESS_CHALLENGE_TYPE) """ Set correct value of the authenticator field """ radius_challenge.set_authenticator(authenticator) """ Set the identifier so that the NAS can match request with response """ radius_challenge.set_identifier(radius_identifier) #message = outstanding_packets[calling_station_id][0].get_bytes(); Utils.Utils.radius_split_message( radius_challenge, packet, config["networking"]["eap_message_attribute_length"]) message_authenticator_attribute = (radius.RADIUSAttribute( radius.RADIUS_EAP_MESSAGE_AUTHENTICATOR_ATTRIBUTE, [0] * radius.RADIUS_AUTHENTICATOR_FIELD_LENGTH)) radius_challenge.add_attribute(message_authenticator_attribute) """ Compute message authentication """ message_authentication_bytes = ( Utils.Utils.compute_message_authentication( radius_challenge, bytearray(config["security"]["radius_master_secret"], encoding='utf8'))) """ Update the message authentication attribute """ radius_challenge = Utils.Utils.set_message_authentication( radius_challenge, message_authentication_bytes) """ Compute and update response authenticator """ response_authenticator = Utils.Utils.compute_response_authenticator( radius_challenge, bytearray(config["security"]["radius_master_secret"], encoding='utf8')) radius_challenge.set_authenticator(response_authenticator) bytes_out = socket.sendto(bytearray(radius_challenge.get_bytes()), address) print("Sent %d" % (bytes_out))
import crypto from crypto import aes import os from time import time import numpy as np results = [] IV_SIZE = 16 for i in range(0, 10000): iv = os.urandom(16) data = os.urandom(1024) key = os.urandom(32) cipher = aes.AESCipher(aes.AES_CBC_MODE, key, iv) ciphertext = cipher.encrypt(data) start = time() cipher.decrypt(ciphertext) end = time() results.append(end - start) print("Mean: ", np.mean(results)) print("SD: ", np.std(results))