Adding pico-fido-tool for enabling some configs.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2022-10-17 17:37:54 +02:00
parent 4425722a71
commit 32c938674a
No known key found for this signature in database
GPG Key ID: C0095B7870A4CCD3

84
tools/pico-fido-tool.py Normal file
View File

@ -0,0 +1,84 @@
from fido2.ctap2.config import Config
from fido2.ctap2 import Ctap2
from fido2.hid import CtapHidDevice
from fido2.utils import bytes2int, int2bytes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
from cryptography.hazmat.primitives import hashes
from enum import IntEnum
from binascii import hexlify
class VendorConfig(Config):
class PARAM(IntEnum):
VENDOR_COMMAND_ID = 0x01
VENDOR_AUT_KEY_AGREEMENT = 0x02
VENDOR_AUT_CT = 0x03
class CMD(IntEnum):
CONFIG_AUT = 0x03e43f56b34285e2
CONFIG_KEY_AGREEMENT = 0x1831a40f04a25ed9
class RESP(IntEnum):
KEY_AGREEMENT = 0x01
def __init__(self, ctap, pin_uv_protocol=None, pin_uv_token=None):
super().__init__(ctap, pin_uv_protocol, pin_uv_token)
def enable_device_aut(self):
ret = self._call(
Config.CMD.VENDOR_PROTOTYPE,
{
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_KEY_AGREEMENT,
},
)
peer_cose_key = ret[VendorConfig.RESP.KEY_AGREEMENT]
sk = ec.generate_private_key(ec.SECP256R1())
pn = sk.public_key().public_numbers()
pb = sk.public_key().public_bytes(Encoding.X962, PublicFormat.UncompressedPoint)
key_agreement = {
1: 2,
3: -25, # Per the spec, "although this is NOT the algorithm actually used"
-1: 1,
-2: int2bytes(pn.x, 32),
-3: int2bytes(pn.y, 32),
}
x = bytes2int(peer_cose_key[-2])
y = bytes2int(peer_cose_key[-3])
pk = ec.EllipticCurvePublicNumbers(x, y, ec.SECP256R1()).public_key()
shared_key = sk.exchange(ec.ECDH(), pk)
xkdf = HKDF(
algorithm=hashes.SHA256(),
length=12+32,
salt=None,
info=pb
)
print(hexlify(shared_key))
kdf_out = xkdf.derive(shared_key)
key_enc = kdf_out[12:]
iv = kdf_out[:12]
print(hexlify(kdf_out))
print(hexlify(pb))
chacha = ChaCha20Poly1305(key_enc)
ct = chacha.encrypt(iv, b"\x69"*32, pb)
self._call(
Config.CMD.VENDOR_PROTOTYPE,
{
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_AUT,
VendorConfig.PARAM.VENDOR_AUT_KEY_AGREEMENT: key_agreement,
VendorConfig.PARAM.VENDOR_AUT_CT: ct
},
)
dev = next(CtapHidDevice.list_devices(), None)
vcfg = VendorConfig(Ctap2(dev))
vcfg.enable_device_aut()