コード例 #1
0
    def _decrypt_pinblock(self, encrypted_pinblock, encrypted_terminal_key):
        """
        Decrypt pin block
        """
        if encrypted_terminal_key[0:1] in [b'U']:
            clear_terminal_key = self.cipher.decrypt(
                B2raw(encrypted_terminal_key[1:]))
        else:
            clear_terminal_key = self.cipher.decrypt(
                B2raw(encrypted_terminal_key))

        cipher = DES3.new(clear_terminal_key, DES3.MODE_ECB)
        decrypted_pinblock = cipher.decrypt(B2raw(encrypted_pinblock))
        return raw2B(decrypted_pinblock)
コード例 #2
0
    def generate_key(self, request):
        """
        Get response to HC command
        TODO: generating keys for different schemes
        """
        response = OutgoingMessage(data=None, header=self.header)
        response.set_response_code('HD')
        response.set_error_code('00')

        new_clear_key = modify_key_parity(bytes(os.urandom(16)))
        self._debug_trace('Generated key: {}'.format(raw2str(new_clear_key)))

        current_key = request.get('Current Key')
        if current_key[0:1] in [b'U']:
            current_key = current_key[1:]

        clear_current_key = self.cipher.decrypt(B2raw(current_key))
        curr_key_cipher = DES3.new(clear_current_key, DES3.MODE_ECB)

        new_key_under_current_key = curr_key_cipher.encrypt(new_clear_key)
        new_key_under_lmk = self.cipher.encrypt(new_clear_key)

        response.set('New key under the current key',
                     b'U' + raw2B(new_key_under_current_key))
        response.set('New key under LMK', b'U' + raw2B(new_key_under_lmk))

        return response
コード例 #3
0
 def check_key_parity(self, _key):
     """
     """
     if self.skip_parity_check:
         return True
     else:
         key = _key[1:] if _key[0:1] in [b'U'] else _key
         return check_key_parity(self.cipher.decrypt(B2raw(key)))
コード例 #4
0
    def translate_zpk(self, request):
        """
        Get response to FA command
        """
        response = OutgoingMessage(header=self.header)
        response.set_response_code('FB')
        response.set_error_code('00')

        zmk_under_lmk = request.get('ZMK')[1:33]
        if zmk_under_lmk:
            clear_zmk = self.cipher.decrypt(B2raw(zmk_under_lmk))
            self._debug_trace('Clear ZMK: {}'.format(raw2str(clear_zmk)))

            zmk_key_cipher = DES3.new(clear_zmk, DES3.MODE_ECB)

            zpk_under_zmk = request.get('ZPK')[1:33]
            if zpk_under_zmk:
                clear_zpk = zmk_key_cipher.decrypt(B2raw(zpk_under_zmk))
                self._debug_trace('Clear ZPK: {}'.format(raw2str(clear_zpk)))

                zpk_under_lmk = self.cipher.encrypt(clear_zpk)

                response.set('ZPK under LMK', b'U' + raw2B(zpk_under_lmk))
                response.set('Key Check Value', key_CV(raw2B(zpk_under_lmk),
                                                       6))
                response.set_error_code('00')

            else:
                self._debug_trace('ERROR: Invalid ZPK')
                response.set_error_code('01')

        else:
            self._debug_trace('ERROR: Invalid ZMK')
            response.set_error_code('01')

        return response
コード例 #5
0
    def generate_key_a0(self, request):
        """
        Get response to A0 command
        """
        response = OutgoingMessage(header=self.header)
        response.set_response_code('A1')
        response.set_error_code('00')

        new_clear_key = modify_key_parity(bytes(os.urandom(16)))
        self._debug_trace('Generated key: {}'.format(raw2str(new_clear_key)))
        new_key_under_lmk = self.cipher.encrypt(new_clear_key)
        response.set('Key under LMK', b'U' + raw2B(new_key_under_lmk))

        zmk_under_lmk = request.get('ZMK/TMK')[1:33]
        if zmk_under_lmk:
            clear_zmk = self.cipher.decrypt(B2raw(zmk_under_lmk))
            zmk_key_cipher = DES3.new(clear_zmk, DES3.MODE_ECB)
            new_key_under_zmk = zmk_key_cipher.encrypt(new_clear_key)

            response.set('Key under ZMK', b'U' + raw2B(new_key_under_zmk))
            response.set('Key Check Value', key_CV(raw2B(new_clear_key), 6))

        return response
コード例 #6
0
 def test_B2raw(self):
     self.assertEqual(B2raw(b'DF1267EEDCBA9876'),
                      b'\xdf\x12g\xee\xdc\xba\x98v')
コード例 #7
0
 def test_modify_key_parity_default_TPK(self):
     self.assertEqual(
         modify_key_parity(b'2t<\xd2\x82>\xf97\xa8e\xa1\x8a\x8a:\x16W'),
         B2raw(b'33743CD2823FF939A965A38B8B3A1759'))
コード例 #8
0
    def translate_pinblock(self, request):
        """
        Get response to CA command (Translate PIN from TPK to ZPK)
        """
        response = OutgoingMessage(header=self.header)
        response.set_response_code('CB')
        pinblock_format = request.get('Destination PIN block format')

        if request.get('Destination PIN block format') != request.get(
                'Source PIN block format'):
            raise ValueError(
                'Cannot translate PIN block from format {} to format {}'.
                format(
                    request.get('Source PIN block format').decode('utf-8'),
                    request.get('Destination PIN block format').decode(
                        'utf-8')))

        if request.get('Source PIN block format') != b'01':
            raise ValueError('Unsupported PIN block format: {}'.format(
                request.get('Source PIN block format').decode('utf-8')))

        # Source key parity check
        if not self.check_key_parity(request.get('TPK')):
            self._debug_trace('Source TPK parity error')
            if self.approve_all:
                self._debug_trace(
                    'Forced approval as --approve-all option set')
                response.set_error_code('00')
            else:
                response.set_error_code('10')
            return response

        # Destination key parity check
        if not self.check_key_parity(request.get('Destination Key')):
            self._debug_trace('Destination ZPK parity error')
            if self.approve_all:
                self._debug_trace(
                    'Forced approval as --approve-all option set')
                response.set_error_code('00')
            else:
                response.set_error_code('11')
            return response

        decrypted_pinblock = self._decrypt_pinblock(
            request.get('Source PIN block'), request.get('TPK'))
        self._debug_trace('Decrypted pinblock: {}'.format(
            decrypted_pinblock.decode('utf-8')))

        pin_length = decrypted_pinblock[0:2]

        destination_key = request.get('Destination Key')
        if destination_key[0:1] in [b'U']:
            destination_key = destination_key[1:]
        cipher = DES3.new(B2raw(destination_key), DES3.MODE_ECB)
        translated_pin_block = cipher.encrypt(B2raw(decrypted_pinblock))

        response.set_error_code('00')
        response.set('PIN Length', decrypted_pinblock[0:2])
        response.set('Destination PIN Block', raw2B(translated_pin_block))
        response.set('Destination PIN Block format', pinblock_format)

        return response
コード例 #9
0
 def get_message_length(self, message):
     return B2raw(bytes(str(len(message)).zfill(4), 'utf-8'))