コード例 #1
0
def msg_authenticate_sign(challenge: bytes, app_id: bytes, privkey: bytes) -> bytes:
    flags = bytes([_AUTH_FLAG_TUP])

    # get next counter
    ctr = storage.next_u2f_counter()
    ctrbuf = ustruct.pack(">L", ctr)

    # hash input data together with counter
    dig = hashlib.sha256()
    dig.update(app_id)  # uint8_t appId[32];
    dig.update(flags)  # uint8_t flags;
    dig.update(ctrbuf)  # uint8_t ctr[4];
    dig.update(challenge)  # uint8_t chal[32];
    dig = dig.digest()

    # sign the digest and convert to der
    sig = nist256p1.sign(privkey, dig, False)
    sig = der.encode_seq((sig[1:33], sig[33:]))

    # pack to a response
    buf, resp = make_struct(resp_cmd_authenticate(len(sig)))
    resp.flags = flags[0]
    resp.ctr = ctr
    utils.memcpy(resp.sig, 0, sig, 0, len(sig))
    resp.status = _SW_NO_ERROR

    return buf
コード例 #2
0
 def test_sign_verify_random(self):
     for _ in range(100):
         sk = nist256p1.generate_secret()
         pk = nist256p1.publickey(sk)
         dig = random.bytes(32)
         sig = nist256p1.sign(sk, dig)
         self.assertTrue(nist256p1.verify(pk, sig, dig))
         self.assertTrue(nist256p1.verify(pk, sig[1:], dig))
コード例 #3
0
 def test_verify_recover(self):
     for compressed in [False, True]:
         for _ in range(100):
             sk = nist256p1.generate_secret()
             pk = nist256p1.publickey(sk, compressed)
             dig = random.bytes(32)
             sig = nist256p1.sign(sk, dig, compressed)
             pk2 = nist256p1.verify_recover(sig, dig)
             self.assertEqual(pk, pk2)
コード例 #4
0
    def test_sign_verify_min_max(self):
        sk = nist256p1.generate_secret()
        pk = nist256p1.publickey(sk)

        dig = bytes([1] + [0] * 31)
        sig = nist256p1.sign(sk, dig)
        self.assertTrue(nist256p1.verify(pk, sig, dig))
        self.assertTrue(nist256p1.verify(pk, sig[1:], dig))

        dig = bytes([0] * 31 + [1])
        sig = nist256p1.sign(sk, dig)
        self.assertTrue(nist256p1.verify(pk, sig, dig))
        self.assertTrue(nist256p1.verify(pk, sig[1:], dig))

        dig = bytes([0xFF] * 32)
        sig = nist256p1.sign(sk, dig)
        self.assertTrue(nist256p1.verify(pk, sig, dig))
        self.assertTrue(nist256p1.verify(pk, sig[1:], dig))
コード例 #5
0
def sign_challenge(
    seckey: bytes,
    challenge_hidden: bytes,
    challenge_visual: str,
    sigtype: Union[str, coininfo.CoinInfo],
    curve: str,
) -> bytes:
    from trezor.crypto.hashlib import sha256

    if curve == "secp256k1":
        from trezor.crypto.curve import secp256k1
    elif curve == "nist256p1":
        from trezor.crypto.curve import nist256p1
    elif curve == "ed25519":
        from trezor.crypto.curve import ed25519
    from apps.common.signverify import message_digest

    if sigtype == "gpg":
        data = challenge_hidden
    elif sigtype == "signify":
        if curve != "ed25519":
            raise wire.DataError("Unsupported curve")
        data = challenge_hidden
    elif sigtype == "ssh":
        if curve != "ed25519":
            data = sha256(challenge_hidden).digest()
        else:
            data = challenge_hidden
    elif isinstance(sigtype, coininfo.CoinInfo):
        # sigtype is coin
        challenge = (
            sha256(challenge_hidden).digest()
            + sha256(challenge_visual.encode()).digest()
        )
        data = message_digest(sigtype, challenge)
    else:
        raise wire.DataError("Unsupported sigtype")

    if curve == "secp256k1":
        signature = secp256k1.sign(seckey, data)
    elif curve == "nist256p1":
        signature = nist256p1.sign(seckey, data)
    elif curve == "ed25519":
        signature = ed25519.sign(seckey, data)
    else:
        raise wire.DataError("Unknown curve")

    if curve == "ed25519":
        signature = b"\x00" + signature
    elif sigtype == "gpg" or sigtype == "ssh":
        signature = b"\x00" + signature[1:]

    return signature
コード例 #6
0
def msg_register_sign(challenge: bytes, app_id: bytes) -> bytes:

    from apps.common import seed

    # derivation path is m/U2F'/r'/r'/r'/r'/r'/r'/r'/r'
    keypath = [0x80000000 | random.uniform(0xf0000000) for _ in range(0, 8)]
    nodepath = [_U2F_KEY_PATH] + keypath

    # prepare signing key from random path, compute decompressed public key
    node = seed.get_root_without_passphrase('nist256p1')
    node.derive_path(nodepath)
    pubkey = nist256p1.publickey(node.private_key(), False)

    # first half of keyhandle is keypath
    keybuf = ustruct.pack('>8L', *keypath)

    # second half of keyhandle is a hmac of app_id and keypath
    keybase = hmac.Hmac(node.private_key(), app_id, hashlib.sha256)
    keybase.update(keybuf)
    keybase = keybase.digest()

    # hash the request data together with keyhandle and pubkey
    dig = hashlib.sha256()
    dig.update(b'\x00')  # uint8_t reserved;
    dig.update(app_id)  # uint8_t appId[32];
    dig.update(challenge)  # uint8_t chal[32];
    dig.update(keybuf)  # uint8_t keyHandle[64];
    dig.update(keybase)
    dig.update(pubkey)  # uint8_t pubKey[65];
    dig = dig.digest()

    # sign the digest and convert to der
    sig = nist256p1.sign(_U2F_ATT_PRIV_KEY, dig, False)
    sig = der.encode_seq((sig[1:33], sig[33:]))

    # pack to a response
    buf, resp = make_struct(
        resp_cmd_register(
            len(keybuf) + len(keybase), len(_U2F_ATT_CERT), len(sig)))
    resp.registerId = _U2F_REGISTER_ID
    utils.memcpy(resp.pubKey, 0, pubkey, 0, len(pubkey))
    resp.keyHandleLen = len(keybuf) + len(keybase)
    utils.memcpy(resp.keyHandle, 0, keybuf, 0, len(keybuf))
    utils.memcpy(resp.keyHandle, len(keybuf), keybase, 0, len(keybase))
    utils.memcpy(resp.cert, 0, _U2F_ATT_CERT, 0, len(_U2F_ATT_CERT))
    utils.memcpy(resp.sig, 0, sig, 0, len(sig))
    resp.status = _SW_NO_ERROR

    return buf
コード例 #7
0
ファイル: sign_identity.py プロジェクト: davidftv/trezor-core
def sign_challenge(seckey: bytes,
                   challenge_hidden: bytes,
                   challenge_visual: str,
                   sigtype,
                   curve: str) -> bytes:
    from trezor.crypto.hashlib import sha256
    if curve == 'secp256k1':
        from trezor.crypto.curve import secp256k1
    elif curve == 'nist256p1':
        from trezor.crypto.curve import nist256p1
    elif curve == 'ed25519':
        from trezor.crypto.curve import ed25519
    from ..common.signverify import message_digest

    if sigtype == 'gpg':
        data = challenge_hidden
    elif sigtype == 'ssh':
        if curve != 'ed25519':
            data = sha256(challenge_hidden).digest()
        else:
            data = challenge_hidden
    else:
        # sigtype is coin
        challenge = sha256(challenge_hidden).digest() + sha256(challenge_visual).digest()
        data = message_digest(sigtype, challenge)

    if curve == 'secp256k1':
        signature = secp256k1.sign(seckey, data)
    elif curve == 'nist256p1':
        signature = nist256p1.sign(seckey, data)
    elif curve == 'ed25519':
        signature = ed25519.sign(seckey, data)
    else:
        raise ValueError('Unknown curve')

    if curve == 'ed25519':
        signature = b'\x00' + signature
    elif sigtype == 'gpg' or sigtype == 'ssh':
        signature = b'\x00' + signature[1:]

    return signature
コード例 #8
0
def sign_challenge(seckey: bytes, challenge_hidden: bytes,
                   challenge_visual: str, sigtype, curve: str) -> bytes:
    from trezor.crypto.hashlib import sha256

    if curve == "secp256k1":
        from trezor.crypto.curve import secp256k1
    elif curve == "nist256p1":
        from trezor.crypto.curve import nist256p1
    elif curve == "ed25519":
        from trezor.crypto.curve import ed25519
    from apps.common.signverify import message_digest

    if sigtype == "gpg":
        data = challenge_hidden
    elif sigtype == "ssh":
        if curve != "ed25519":
            data = sha256(challenge_hidden).digest()
        else:
            data = challenge_hidden
    else:
        # sigtype is coin
        challenge = (sha256(challenge_hidden).digest() +
                     sha256(challenge_visual).digest())
        data = message_digest(sigtype, challenge)

    if curve == "secp256k1":
        signature = secp256k1.sign(seckey, data)
    elif curve == "nist256p1":
        signature = nist256p1.sign(seckey, data)
    elif curve == "ed25519":
        signature = ed25519.sign(seckey, data)
    else:
        raise ValueError("Unknown curve")

    if curve == "ed25519":
        signature = b"\x00" + signature
    elif sigtype == "gpg" or sigtype == "ssh":
        signature = b"\x00" + signature[1:]

    return signature
コード例 #9
0
 def _u2f_sign(self, data: Iterable[bytes]) -> bytes:
     dig = hashlib.sha256()
     for segment in data:
         dig.update(segment)
     sig = nist256p1.sign(self._private_key(), dig.digest(), False)
     return der.encode_seq((sig[1:33], sig[33:]))