def calc_mac_params(self): self.xor_nonce = sxor(self.card_nonce, self.lib_nonce) + "\x00\x00\x00\x02" self.digest = SHA.new(self.xor_nonce).digest() logger.info("xor nonce\n%s", to_hex_blocks(self.xor_nonce)) logger.info("digest\n%s", to_hex_blocks(self.digest)) self.mac_counter = 0
def calc_cr_params(self): card_identifier_rev = self.card_identifier[::-1] cipher1 = DES3.new(self.static_key, DES3.MODE_ECB) cipher2 = DES3.new(self.static_key[8:16] + self.static_key[:8], DES3.MODE_ECB) self.cr_des3_key = cipher1.encrypt( self.card_identifier) + cipher2.encrypt(self.card_identifier) self.cr_mac_key = cipher1.encrypt( card_identifier_rev) + cipher2.encrypt(card_identifier_rev) logger.info("cr des3 key\n%s", to_hex_blocks(self.cr_des3_key)) logger.info("cr mac key\n%s", to_hex_blocks(self.cr_mac_key))
def parse_lib_challenge(self, msg): ciphertext = msg[5:-8] mac = msg[-8:] mac_valid = self.mac_cr(ciphertext) == mac logger.info("MAC valid: %s", mac_valid) msg_data = self.decrypt_cr(ciphertext) self.lib_random = msg_data[:16] challenge = msg_data[16:24] self.lib_constant = msg_data[24:32] self.lib_nonce = msg_data[32:64] logger.info("Challenge valid: %s", challenge == self.card_challenge) logger.info("lib random\n%s", to_hex_blocks(self.lib_random)) logger.info("lib constant\n%s", to_hex_blocks(self.lib_constant)) logger.info("lib nonce\n%s", to_hex_blocks(self.lib_nonce))
def test_challenge_response(): challenge = from_hex('53 30 77 04 FB 36 DD 39') lib_msg = from_hex(''' 80 82 00 00 48 74 91 3E 6A 34 54 3F 85 05 D0 A6 FE E6 F3 52 1B 02 FB 4F 5B 9A B4 63 42 EF 04 13 B7 3D 94 9A F6 A3 99 E2 E0 0D 6B 06 6B DD E0 B0 AD 5A AE 9F 9F 65 44 F7 37 2D 33 41 E2 32 1E 0E CD 0D 54 78 87 EE 39 DC 4D AC 29 3D 7B ''') card_msg = from_hex(''' 14 F5 06 49 D8 3B 86 CC 16 97 53 87 45 AC 2A C7 DC 6A 54 84 26 77 FF 31 0A B2 51 3E 39 CB 59 CA 0E 9B D3 4F 60 55 3B 93 0D 48 8C 50 04 28 5A F9 6B C4 B8 B2 7B 3D 00 EB CB A7 23 25 63 B1 93 B9 34 92 28 9D 81 01 78 E6 90 00 ''') c = GemaltoCrypto() c.card_identifier = from_hex('30 40 00 1A 66 83 29 71') c.calc_cr_params() lib_encr = lib_msg[5:-8] lib_mac = lib_msg[-8:] card_encr = card_msg[:-10] card_mac = card_msg[-10:-2] lib_decr = c.decrypt_cr(lib_encr) card_decr = c.decrypt_cr(card_encr) logger.info("lib decr\n%s", to_hex_blocks(lib_decr)) logger.info("card decr\n%s", to_hex_blocks(card_decr)) lib_mac_calc = c.mac_cr(lib_encr) card_mac_calc = c.mac_cr(card_encr) assert challenge == lib_decr[16:24] assert challenge == card_decr[:8] assert lib_mac == lib_mac_calc assert card_mac == card_mac_calc
def parse_card_ch_response(self, msg): ciphertext = msg[:-10] mac = msg[-10:-2] mac_valid = self.mac_cr(ciphertext) == mac logger.info("MAC valid: %s", mac_valid) msg_data = self.decrypt_cr(ciphertext) params_valid = msg_data[:32] == self.card_challenge + \ self.lib_constant + self.lib_random logger.info("Parameters valid: %s", params_valid) self.card_nonce = msg_data[32:64] logger.info("card nonce\n%s", to_hex_blocks(self.card_nonce))
def parse_card_challenge(self, resp): self.card_challenge = resp[:-2] logger.info("card challenge\n%s", to_hex_blocks(self.card_challenge))