Esempio n. 1
0
def test_derive_icc_mk_a_no_psn(pan: Union[bytes, str]) -> None:
    """
    Verify ICC MK derivation method A with a zero PSN.

    Master Key Derivation = Option A
    ARQC verification using Common Session Key Derivation
    ARPC generation using ICC Master Key
    ARPC Method = 1
    """
    # Verify issuer master key check digits
    iss_mk = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    assert tools.key_check_digits(iss_mk, 2).hex().upper() == "08D7"

    # Derive ICC master key
    icc_mk = kd.derive_icc_mk_a(iss_mk, pan)

    # Verify AC session key
    # Common Session Key Derivation Option
    r = bytes.fromhex("1234567890123456")
    sk_ac = kd.derive_common_sk(icc_mk, r)
    assert tools.key_check_digits(sk_ac, 2).hex().upper() == "3F4F"

    # ARQC validation using Session Key
    cipher_text = bytes.fromhex("0123456789ABCDEF0123456789ABCDEF")
    arqc = ac.generate_ac(sk_ac, cipher_text)
    assert arqc.hex().upper() == "8698A7319324FD93"

    # ARPC Method 1 using ICC Master Key
    arpc_rc = bytes.fromhex("0000")
    arpc = ac.generate_arpc_1(icc_mk, arqc, arpc_rc)
    assert arpc.hex().upper() == "BEA11C8F4A47EF6F"
Esempio n. 2
0
def test_derive_icc_mk_a_psn(pan: Union[bytes, str], psn: Union[bytes,
                                                                str]) -> None:
    """
    Verify ICC MK derivation method A with non-zero PSN.

    Master Key Derivation = Option A
    ARQC verification using Common Session Key Derivation
    ARPC generation using ICC Master Key
    ARPC Method = 1
    """
    # Verify issuer master key check digits
    iss_mk = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    assert tools.key_check_digits(iss_mk, 2).hex().upper() == "08D7"

    # Derive ICC master key
    icc_mk = kd.derive_icc_mk_a(iss_mk, pan, psn)
    assert tools.key_check_digits(icc_mk, 2).hex().upper() == "FF08"

    # Verify AC session key
    # Common Session Key Derivation Option
    r = bytes.fromhex("1234567890123456")
    sk_ac = kd.derive_common_sk(icc_mk, r)
    assert tools.key_check_digits(sk_ac, 2).hex().upper() == "DF82"

    # ARQC validation using Session Key
    cipher_text = bytes.fromhex("0123456789ABCDEF0123456789ABCDEF")
    arqc = ac.generate_ac(sk_ac, cipher_text)
    assert arqc.hex().upper() == "19C1FBC83EBDC0D5"

    # ARPC Method 1 using ICC Master Key
    arpc_rc = bytes.fromhex("0000")
    arpc = ac.generate_arpc_1(icc_mk, arqc, arpc_rc)
    assert arpc.hex().upper() == "78A372523FA35A03"
Esempio n. 3
0
def test_generate_ac_visa_aprc1() -> None:
    r"""
    Test generate AC with Visa padding (\x00 padding).

    Master Key Derivation = Option A
    ARQC verification using Common Session Key Derivation
    ARPC generation using ICC Master Key
    ARPC Method = 1
    """
    # Verify issuer master key check digits
    iss_mk = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    assert tools.key_check_digits(iss_mk, 2).hex().upper() == "08D7"

    # Derive ICC master key
    pan = "9901234567890123"
    psn = "45"
    icc_mk = kd.derive_icc_mk_a(iss_mk, pan, psn)
    assert tools.key_check_digits(icc_mk, 2).hex().upper() == "1DA5"

    # Verify AC session key
    # Common Session Key Derivation Option
    r = bytes.fromhex("1234567890123456")
    sk_ac = kd.derive_common_sk(icc_mk, r)
    assert tools.key_check_digits(sk_ac, 2).hex().upper() == "0995"

    # ARQC validation using Session Key
    cipher_text = bytes.fromhex("0123456789ABCDEF0123456789ABCDEF01")
    arqc = ac.generate_ac(sk_ac, cipher_text, ac.PaddingType.VISA)
    assert arqc.hex().upper() == "2E141C6BC4A20DA8"

    # ARPC Method 1 using ICC Master Key
    arpc_rc = bytes.fromhex("0000")
    arpc = ac.generate_arpc_1(icc_mk, arqc, arpc_rc)
    assert arpc.hex().upper() == "16A49AAB314B9262"
Esempio n. 4
0
def test_generate_ac_default_emv_arpc1() -> None:
    r"""
    Test generate AC with default EMV padding (\x80 padding).

    Master Key Derivation = Option A
    ARQC verification using Common Session Key Derivation
    ARPC generation using ICC Master Key
    ARPC Method = 1
    """
    # Verify issuer master key check digits
    iss_mk = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    assert tools.key_check_digits(iss_mk, 2).hex().upper() == "08D7"

    # Derive ICC master key.
    pan = "9901234567890123"
    psn = "45"
    icc_mk = kd.derive_icc_mk_a(iss_mk, pan, psn)
    assert tools.key_check_digits(icc_mk, 2).hex().upper() == "1DA5"

    # Verify AC session key
    # Common Session Key Derivation Option
    r = bytes.fromhex("1234567890123456")
    sk_ac = kd.derive_common_sk(icc_mk, r)
    assert tools.key_check_digits(sk_ac, 2).hex().upper() == "0995"

    # ARQC validation using Session Key
    cipher_text = bytes.fromhex("0123456789ABCDEF0123456789ABCDEF")
    arqc = ac.generate_ac(sk_ac, cipher_text)
    assert arqc.hex().upper() == "4B46013359B7A58B"

    # ARPC Method 1 using ICC Master Key
    arpc_rc = bytes.fromhex("0000")
    arpc = ac.generate_arpc_1(icc_mk, arqc, arpc_rc)
    assert arpc.hex().upper() == "F8C9CECAABD55AD1"
Esempio n. 5
0
def test_generate_ac_visa_aprc1_no_padding_required() -> None:
    r"""
    Test generate AC with Visa padding (\x00 padding).
    However, no padding is required. The data is already multiple of 8.

    Master Key Derivation = Option A
    ARQC verification using Common Session Key Derivation
    ARPC generation using ICC Master Key
    ARPC Method = 1
    """
    # Verify issuer master key check digits
    iss_mk = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    assert tools.key_check_digits(iss_mk, 2).hex().upper() == "08D7"

    # Derive ICC master key
    pan = "9901234567890123"
    psn = "45"
    icc_mk = kd.derive_icc_mk_a(iss_mk, pan, psn)
    assert tools.key_check_digits(icc_mk, 2).hex().upper() == "1DA5"

    # Verify AC session key
    # Common Session Key Derivation Option
    r = bytes.fromhex("1234567890123456")
    sk_ac = kd.derive_common_sk(icc_mk, r)
    assert tools.key_check_digits(sk_ac, 2).hex().upper() == "0995"

    # ARQC validation using Session Key
    cipher_text = bytes.fromhex("0123456789ABCDEF0123456789ABCDEF")
    arqc = ac.generate_ac(sk_ac, cipher_text, ac.PaddingType.VISA)
    assert arqc.hex().upper() == "922F3E83125EB46B"

    # ARPC Method 1 using ICC Master Key
    arpc_rc = bytes.fromhex("0000")
    arpc = ac.generate_arpc_1(icc_mk, arqc, arpc_rc)
    assert arpc.hex().upper() == "8AE6E836084B0E80"
Esempio n. 6
0
def test_derive_common_sk() -> None:
    """
    Verify common session key derivation using algorithm
    type where both ARQC and ARPC are verified using derived
    session key.

    Master Key Derivation = Option A
    ARQC verification using Common Session Key Derivation
    ARPC generation using Common Session Key Derivation
    ARPC Method = 1
    """
    # Verify issuer master key check digits
    iss_mk = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    assert tools.key_check_digits(iss_mk, 2).hex().upper() == "08D7"

    # Derive ICC master key
    pan = "12345678901234567"
    psn = "45"
    icc_mk = kd.derive_icc_mk_a(iss_mk, pan, psn)
    assert tools.key_check_digits(icc_mk, 2).hex().upper() == "FF08"

    # Verify AC session key
    # Common Session Key Derivation Option
    r = bytes.fromhex("1234567890123456")
    sk_ac = kd.derive_common_sk(icc_mk, r)
    assert tools.key_check_digits(sk_ac, 2).hex().upper() == "DF82"

    # ARQC validation using Session Key
    cipher_text = bytes.fromhex("0123456789ABCDEF0123456789ABCDEF")
    arqc = ac.generate_ac(sk_ac, cipher_text)
    assert arqc.hex().upper() == "19C1FBC83EBDC0D5"

    # ARPC Method 1 using Session Key
    arpc_rc = bytes.fromhex("0000")
    arpc = ac.generate_arpc_1(sk_ac, arqc, arpc_rc)
    assert arpc.hex().upper() == "C3620580668E5B65"
Esempio n. 7
0
def test_generate_arpc_1_exception() -> None:
    # SK < 16 bytes
    with pytest.raises(
            ValueError,
            match="Session Key must be a double length DES key",
    ):
        ac.generate_arpc_1(
            sk_ac=bytes.fromhex("AAAAAAAAAAAAAAAA"),
            arqc=bytes.fromhex("12345678"),
            arpc_rc=bytes.fromhex("0000"),
        )

    # SK > 16 bytes
    with pytest.raises(
            ValueError,
            match="Session Key must be a double length DES key",
    ):
        ac.generate_arpc_1(
            sk_ac=bytes.fromhex(
                "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCC"),
            arqc=bytes.fromhex("12345678"),
            arpc_rc=bytes.fromhex("0000"),
        )

    # ARQC < 8 bytes
    with pytest.raises(
            ValueError,
            match="ARQC must be 8 bytes long",
    ):
        ac.generate_arpc_1(
            sk_ac=bytes.fromhex("AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"),
            arqc=bytes.fromhex("12345678"),
            arpc_rc=bytes.fromhex("0000"),
        )

    # ARQC > 16 bytes
    with pytest.raises(
            ValueError,
            match="ARQC must be 8 bytes long",
    ):
        ac.generate_arpc_1(
            sk_ac=bytes.fromhex("AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"),
            arqc=bytes.fromhex("1234567890ABCDEF12"),
            arpc_rc=bytes.fromhex("0000"),
        )

    # ARPC-RC < 2 bytes
    with pytest.raises(
            ValueError,
            match="ARPC-RC must be 2 bytes long",
    ):
        ac.generate_arpc_1(
            sk_ac=bytes.fromhex("AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"),
            arqc=bytes.fromhex("1234567890123456"),
            arpc_rc=bytes.fromhex("00"),
        )

    # ARPC-RC > 2 bytes
    with pytest.raises(
            ValueError,
            match="ARPC-RC must be 2 bytes long",
    ):
        ac.generate_arpc_1(
            sk_ac=bytes.fromhex("AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"),
            arqc=bytes.fromhex("1234567890123456"),
            arpc_rc=bytes.fromhex("001122"),
        )