Пример #1
0
def user():
    start = yield []
    assert start is Start

    a = dh_secret(P)
    A = mod(G, a)

    print("user: sending email")
    salt, B = yield [b"*****@*****.**", A]
    u = hash_to_int(int_to_bytes(A) + int_to_bytes(B))

    print("user: A:", A)
    print("user: B:", B)
    print("user: salt:", bytes_to_int(salt))
    print("user: u", u)

    x = hash_to_int(salt + b"pass")
    print("user: x:", x)

    t1 = B - K * mod(G, x)
    assert t1 > 0

    S = mod(t1, a + u * x)

    print("user: S:", S)

    key = hashlib.sha256(int_to_bytes(S)).digest()
    print("user: key:", binascii.hexlify(key))

    response, *_ = yield [hmac_sha256(key, salt)]
    print("server says password was", response)

    assert response == "OK"
Пример #2
0
def user():
    start = yield []
    assert start is actors.Start

    a = dh_secret(P)
    A = mod(G, a)

    salt, B, u = yield [b"*****@*****.**", A]
    x = hash_to_int(salt + b"pass")
    S = mod(B, a + u * x)
    key = hashlib.sha256(int_to_bytes(S)).digest()

    response, *_ = yield [hmac_sha256(key, salt)]

    print("=" * 80)
    print("user: A:", A)
    print("user: B:", B)
    print("user: salt:", bytes_to_int(salt))
    print("user: u", u)
    print("user: x:", x)
    print("user: S:", S)
    print("user: key:", binascii.hexlify(key))
    print("user: server says password was", response)

    assert response == "OK"
Пример #3
0
def host():
    email, A = yield []

    password = USERS[email]

    salt = random_bytes(16)
    x = hash_to_int(salt + password)
    print("s: x:", x)
    v = mod(G, x)

    b = dh_secret(P)
    B = K * v + mod(G, b)

    print("{} trying to log in".format(email.decode()))
    u = hash_to_int(int_to_bytes(A) + int_to_bytes(B))

    print("host: A:", A)
    print("host: B:", B)
    print("host: salt:", bytes_to_int(salt))
    print("host: u", u)
    print("host: x:", x)

    user_mac, *_ = yield [salt, B]

    t0 = A * mod(v, u)
    S = mod(t0, b)

    print("host: S:", S)

    key = hashlib.sha256(int_to_bytes(S)).digest()
    print("host: key:", binascii.hexlify(key))

    host_mac = hmac_sha256(key, salt)
    yield ["OK" if user_mac == host_mac else "NO"]
Пример #4
0
def host():
    email, A = yield []
    password = USERS[email]

    salt = random_bytes(16)
    x = hash_to_int(salt + password)
    v = mod(G, x)

    b = dh_secret(P)
    B = mod(G, b)
    u = random_int_from_n_bytes(128 // 8)

    user_mac, *_ = yield [salt, B, u]

    S = mod(A * mod(v, u), b)
    key = hashlib.sha256(int_to_bytes(S)).digest()
    host_mac = hmac_sha256(key, salt)

    print("=" * 80)
    print("{} trying to log in".format(email.decode()))
    print("host: A:", A)
    print("host: B:", B)
    print("host: salt:", bytes_to_int(salt))
    print("host: u", u)
    print("host: x:", x)
    print("host: S:", S)
    print("host: key:", binascii.hexlify(key))

    yield ["OK" if user_mac == host_mac else "NO"]
Пример #5
0
def dec_key_handle(data, application_parameter):
    global ks_u2f
    if len(data) != KEY_HANDLE_LENGTH:
        return b''
    if data[-32:] != hmac_sha256(ks_u2f.KEY_5C, ks_u2f.KEY_36,
                                 data[:-32] + application_parameter):
        return b''
    dec = aes(ks_u2f.AES_KEY, MODE_CBC, ks_u2f.AES_IV)
    return dec.decrypt(data[:32])
Пример #6
0
    def test_s4c31(self):
        eq = self.assertEqual
        eq(
            hmac.hmac_md5(b"", b""),
            "74e6f7298a9c2d168935f58c001bad88",
        )

        eq(
            hmac.hmac_sha1(b"", b""),
            "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d",
        )

        eq(
            hmac.hmac_sha256(b"", b""),
            "b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad",
        )

        eq(
            hmac.hmac_md5(b"key",
                          b"The quick brown fox jumps over the lazy dog"),
            "80070713463e7749b90c2dc24911e275",
        )

        eq(
            hmac.hmac_sha1(b"key",
                           b"The quick brown fox jumps over the lazy dog"),
            "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9",
        )

        eq(
            hmac.hmac_sha256(b"key",
                             b"The quick brown fox jumps over the lazy dog"),
            "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8",
        )

        self.assertTrue(insecure_compare(0.0, "abcd", "abcd"))
        self.assertFalse(insecure_compare(0.0, "abcd", "abce"))
        self.assertFalse(insecure_compare(0.0, "aBcd", "abcd"))
        self.assertFalse(insecure_compare(0.0, "abc", "abcd"))
        self.assertFalse(insecure_compare(0.0, "abcd", "abc"))
Пример #7
0
def dec_key_handle(data):
    if len(data) < 64 or len(data) % 16 > 0:
        return b''
    if data[-32:] != hmac_sha256(ks_ctap2.KEY_5C, ks_ctap2.KEY_36, data[:-32]):
        return b''
    dec = aes(ks_ctap2.AES_KEY, MODE_CBC, ks_ctap2.AES_IV)
    m = dec.decrypt(data[:-32])
    # remove padding 80 00 00 ...
    for i in range(len(m) - 1, 31, -1):
        if m[i] == 0x80:
            return m[:i]
        elif m[i] == 0x00:
            continue
        else:
            return b''  # wrong padding
    return b''
Пример #8
0
def user():
    start = yield []
    assert start is actors.Start

    A = 0

    print("user: sending email")
    salt, B = yield [b"*****@*****.**", A]

    S = 0

    print("user: S:", S)

    key = hashlib.sha256(int_to_bytes(S)).digest()
    print("user: key:", binascii.hexlify(key))

    response, *_ = yield [hmac_sha256(key, salt)]
    print("server says password was", response)

    assert response == "OK"
Пример #9
0
def verifyPIN(pinAuth, clientDataHash):
    n = -(len(ks_pin.PIN_TOKEN)) % 64
    k5c = bytes((c ^ 0x5c for c in ks_pin.PIN_TOKEN)) + b'\x5c' * n
    k36 = bytes((c ^ 0x36 for c in ks_pin.PIN_TOKEN)) + b'\x36' * n
    return hmac_sha256(k5c, k36, clientDataHash)[:16] == pinAuth
Пример #10
0
def clientPIN(data):
    global ks_pin, PIN_CONSECUTIVE_RETRIES
    # https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#authenticatorClientPIN
    try:
        data = decode(data)
    except ValueError:
        return CTAP2_ERR_INVALID_CBOR
    ret = ccp.authenticatorClientPIN.verify(data)
    if ret != CTAP2_OK:
        return ret
    if data[2] == 0x01:  # getRetries
        return CTAP2_OK + encode({3: ks_pin.PIN_RETRIES})
    elif data[2] == 0x02:  # getKeyAgreement
        return CTAP2_OK + encode({1: {1: 2,   # kty: EC2 key type
                                      3: -25,  # alg: ECDH-ES+HKDF-256
                                      -1: 1,   # crv: P-256 curve
                                      # x-coordinate
                                      -2: ks_pin.DH_PK_x,
                                      # y-coordinate
                                      -3: ks_pin.DH_PK_y
                                      }
                                  })
    elif data[2] in (0x03, 0x04, 0x05):
        # verify parameters for setPIN, changePIN, getPINToken
        if 3 not in data:  # platformKeyAgreementKey
            return CTAP2_ERR_MISSING_PARAMETER
        if (data[2] in (0x03, 0x04)):
            if 4 not in data or 5 not in data:  # pinAuth, newPinEnc
                return CTAP2_ERR_MISSING_PARAMETER
        if (data[2] in (0x04, 0x05)):
            if 6 not in data:  # pinHashEnc
                return CTAP2_ERR_MISSING_PARAMETER
        if (data[2] == 0x03 and ks_pin.PIN != b'') \
           or (data[2] in (0x04, 0x05) and ks_pin.PIN == b''):
            # either setPIN command and PIN already set
            # or changePIN/getPINToken command and PIN not yet set
            return CTAP2_ERR_PIN_NOT_SET
        Q = point(int.from_bytes(data[3][-2], 'big', False),
                  int.from_bytes(data[3][-3], 'big', False))
        if secp256r1.verify_point(Q) is False:
            return CTAP1_ERR_OTHER
        # compute shared secret as SHA-256(Q.x)
        d = int.from_bytes(ks_pin.DH_SK, 'big', False)
        shared_secret = sha256(
            secp256r1.kP(d, Q).x.to_bytes(32, 'big')).digest()
        k5c = bytes((c ^ 0x5c for c in shared_secret)) + b'\x5c' * 32
        k36 = bytes((c ^ 0x36 for c in shared_secret)) + b'\x36' * 32
        if data[2] == 0x03:  # setPIN
            # Authenticator verifies pinAuth by generating
            # LEFT(HMAC-SHA-256(sharedSecret, newPinEnc), 16)
            # and matching against input pinAuth parameter.
            if hmac_sha256(k5c, k36, data[5])[:16] != data[4]:
                return CTAP2_ERR_PIN_AUTH_INVALID
            # Authenticator decrypts newPinEnc using above "sharedSecret"
            # producing newPin and checks newPin length against minimum
            # PIN length of 4 bytes.
            return set_new_pin(shared_secret, data[5])
        elif data[2] == 0x04:  # changePIN
            # If the retries counter is 0, return CTAP2_ERR_PIN_BLOCKED error.
            if ks_pin.PIN_RETRIES == 0:
                return CTAP2_ERR_PIN_BLOCKED
            if PIN_CONSECUTIVE_RETRIES == 3:
                return CTAP2_ERR_PIN_AUTH_BLOCKED
            # Authenticator verifies pinAuth by generating
            # LEFT(HMAC-SHA-256(sharedSecret, newPinEnc || pinHashEnc), 16)
            # and matching against input pinAuth parameter.
            if hmac_sha256(k5c, k36, data[5] + data[6])[:16] != data[4]:
                return CTAP2_ERR_PIN_AUTH_INVALID
            # Authenticator decrements the retries counter by 1.
            ks_pin.PIN_RETRIES -= 1
            PIN_CONSECUTIVE_RETRIES += 1
            ks_pin.save_keystore()
            # Authenticator decrypts pinHashEnc and verifies against its
            # internal stored LEFT(SHA-256(curPin), 16).
            if len(data[6]) != 16:
                return CTAP1_ERR_OTHER
            dec = aes(shared_secret, MODE_CBC, bytes(16))
            if dec.decrypt(data[6]) != ks_pin.PIN_DIGEST:
                if ks_pin.PIN_RETRIES == 0:
                    return CTAP2_ERR_PIN_BLOCKED
                elif PIN_CONSECUTIVE_RETRIES == 3:
                    return CTAP2_ERR_PIN_AUTH_BLOCKED
                else:
                    return CTAP2_ERR_PIN_INVALID
            # Authenticator sets the retries counter to 8.
            ks_pin.PIN_RETRIES = ks_pin.PIN_MAX_RETRIES
            ks_pin.save_keystore()
            PIN_CONSECUTIVE_RETRIES = 0
            # Authenticator decrypts newPinEnc using above "sharedSecret"
            # producing newPin and checks newPin length against minimum
            # PIN length of 4 bytes.
            return set_new_pin(shared_secret, data[5])
        elif data[2] == 0x05:  # getPINToken
            # If the retries counter is 0, return CTAP2_ERR_PIN_BLOCKED error.
            if ks_pin.PIN_RETRIES == 0:
                return CTAP2_ERR_PIN_BLOCKED
            if PIN_CONSECUTIVE_RETRIES == 3:
                return CTAP2_ERR_PIN_AUTH_BLOCKED
            # Authenticator decrements the retries counter by 1.
            ks_pin.PIN_RETRIES -= 1
            ks_pin.save_keystore()
            PIN_CONSECUTIVE_RETRIES += 1
            # Authenticator decrypts pinHashEnc and verifies against its
            # internal stored LEFT(SHA-256(curPin), 16).
            if len(data[6]) != 16:
                return CTAP1_ERR_OTHER
            dec = aes(shared_secret, MODE_CBC, bytes(16))
            if dec.decrypt(data[6]) != ks_pin.PIN_DIGEST:
                if ks_pin.PIN_RETRIES == 0:
                    return CTAP2_ERR_PIN_BLOCKED
                elif PIN_CONSECUTIVE_RETRIES == 3:
                    return CTAP2_ERR_PIN_AUTH_BLOCKED
                else:
                    return CTAP2_ERR_PIN_INVALID
            # Authenticator sets the retries counter to 8.
            ks_pin.PIN_RETRIES = ks_pin.PIN_MAX_RETRIES
            ks_pin.save_keystore()
            PIN_CONSECUTIVE_RETRIES = 0
            # Authenticator returns encrypted pinToken using
            # "sharedSecret": AES256-CBC(sharedSecret, IV=0, pinToken).
            ks_pin.PIN_TOKEN = urandom(16)
            ks_pin.save_keystore()
            enc = aes(shared_secret, MODE_CBC, bytes(16))
            return CTAP2_OK + encode({2: enc.encrypt(ks_pin.PIN_TOKEN)})
Пример #11
0
def enc_key_handle(data):
    # add padding data 80 00 00 ...
    enc = aes(ks_ctap2.AES_KEY, MODE_CBC, ks_ctap2.AES_IV)
    cipher = enc.encrypt(data + b'\x80' + bytes(-(1 + len(data)) % 16))
    return cipher + hmac_sha256(ks_ctap2.KEY_5C, ks_ctap2.KEY_36, cipher)
Пример #12
0
def enc_key_handle(data, application_parameter):
    global ks_u2f
    enc = aes(ks_u2f.AES_KEY, MODE_CBC, ks_u2f.AES_IV)
    cipher = enc.encrypt(data)
    return cipher + hmac_sha256(ks_u2f.KEY_5C, ks_u2f.KEY_36,
                                cipher + application_parameter)