python3-yubico/yubico/yubikey_defs.py
2025-08-13 10:23:20 +02:00

212 lines
6.6 KiB
Python

"""
Module with constants. Many of them from ykdefs.h.
"""
# Copyright (c) 2010, 2011 Yubico AB
# See the file COPYING for licence statement.
__all__ = [
# constants
'RESP_TIMEOUT_WAIT_MASK',
'RESP_TIMEOUT_WAIT_FLAG',
'RESP_PENDING_FLAG',
'SLOT_WRITE_FLAG',
'SHA1_MAX_BLOCK_SIZE',
'SHA1_DIGEST_SIZE',
'OTP_CHALRESP_SIZE',
'UID_SIZE',
'YUBICO_VID',
# functions
# classes
'SLOT',
'MODE',
'PID',
'YK4_CAPA'
]
from .yubico_version import __version__
# Yubikey Low level interface #2.3
RESP_TIMEOUT_WAIT_MASK = 0x1f # Mask to get timeout value
RESP_TIMEOUT_WAIT_FLAG = 0x20 # Waiting for timeout operation - seconds left in lower 5 bits
RESP_PENDING_FLAG = 0x40 # Response pending flag
SLOT_WRITE_FLAG = 0x80 # Write flag - set by app - cleared by device
SHA1_MAX_BLOCK_SIZE = 64 # Max size of input SHA1 block
SHA1_DIGEST_SIZE = 20 # Size of SHA1 digest = 160 bits
OTP_CHALRESP_SIZE = 16 # Number of bytes returned for an Yubico-OTP challenge (not from ykdef.h)
UID_SIZE = 6 # Size of secret ID field
class SLOT(object):
"""Slot entries"""
CONFIG = 0x01 # First (default / V1) configuration
CONFIG2 = 0x03 # Second (V2) configuration
UPDATE1 = 0x04 # Update slot 1
UPDATE2 = 0x05 # Update slot 2
SWAP = 0x06 # Swap slot 1 and 2
NDEF = 0x08 # Write NDEF record
NDEF2 = 0x09 # Write NDEF record for slot 2
DEVICE_SERIAL = 0x10 # Device serial number
DEVICE_CONFIG = 0x11 # Write device configuration record
SCAN_MAP = 0x12 # Write scancode map
YK4_CAPABILITIES = 0x13 # Read YK4 capabilities list
CHAL_OTP1 = 0x20 # Write 6 byte challenge to slot 1, get Yubico OTP response
CHAL_OTP2 = 0x28 # Write 6 byte challenge to slot 2, get Yubico OTP response
CHAL_HMAC1 = 0x30 # Write 64 byte challenge to slot 1, get HMAC-SHA1 response
CHAL_HMAC2 = 0x38 # Write 64 byte challenge to slot 2, get HMAC-SHA1 response
class MODE(object):
"""USB modes"""
OTP = 0x00 # OTP only
CCID = 0x01 # CCID only, no eject
OTP_CCID = 0x02 # OTP + CCID composite
U2F = 0x03 # U2F mode
OTP_U2F = 0x04 # OTP + U2F composite
U2F_CCID = 0x05 # U2F + U2F composite
OTP_U2F_CCID = 0x06 # OTP + U2F + CCID composite
MASK = 0x07 # Mask for mode bits
FLAG_EJECT = 0x80 # CCID device supports eject (CCID) / OTP force eject (CCID composite)
@classmethod
def all(cls, otp=False, ccid=False, u2f=False):
"""Returns a set of all USB modes, with optional filtering"""
modes = set([
cls.OTP,
cls.CCID,
cls.OTP_CCID,
cls.U2F,
cls.OTP_U2F,
cls.U2F_CCID,
cls.OTP_U2F_CCID
])
if otp:
modes.difference_update(set([
cls.CCID,
cls.U2F,
cls.U2F_CCID
]))
if ccid:
modes.difference_update(set([
cls.OTP,
cls.U2F,
cls.OTP_U2F
]))
if u2f:
modes.difference_update(set([
cls.OTP,
cls.CCID,
cls.OTP_CCID
]))
return modes
YUBICO_VID = 0x1050 # Global vendor ID
class PID(object):
"""USB Product IDs"""
YUBIKEY = 0x0010 # Yubikey (version 1 and 2)
NEO_OTP = 0x0110 # Yubikey NEO - OTP only
NEO_OTP_CCID = 0x0111 # Yubikey NEO - OTP and CCID
NEO_CCID = 0x0112 # Yubikey NEO - CCID only
NEO_U2F = 0x0113 # Yubikey NEO - U2F only
NEO_OTP_U2F = 0x0114 # Yubikey NEO - OTP and U2F
NEO_U2F_CCID = 0x0115 # Yubikey NEO - U2F and CCID
NEO_OTP_U2F_CCID = 0x0116 # Yubikey NEO - OTP, U2F and CCID
NEO_SKY = 0x0120 # Security Key by Yubico
YK4_OTP = 0x0401 # Yubikey 4 - OTP only
YK4_U2F = 0x0402 # Yubikey 4 - U2F only
YK4_OTP_U2F = 0x0403 # Yubikey 4 - OTP and U2F
YK4_CCID = 0x0404 # Yubikey 4 - CCID only
YK4_OTP_CCID = 0x0405 # Yubikey 4 - OTP and CCID
YK4_U2F_CCID = 0x0406 # Yubikey 4 - U2F and CCID
YK4_OTP_U2F_CCID = 0x0407 # Yubikey 4 - OTP, U2F and CCID
PLUS_U2F_OTP = 0x0410 # Yubikey plus - OTP+U2F
@classmethod
def all(cls, otp=False, ccid=False, u2f=False):
"""Returns a set of all PIDs, with optional filtering"""
pids = set([
cls.YUBIKEY,
cls.NEO_OTP,
cls.NEO_OTP_CCID,
cls.NEO_CCID,
cls.NEO_U2F,
cls.NEO_OTP_U2F,
cls.NEO_U2F_CCID,
cls.NEO_OTP_U2F_CCID,
cls.NEO_SKY,
cls.YK4_OTP,
cls.YK4_U2F,
cls.YK4_OTP_U2F,
cls.YK4_CCID,
cls.YK4_OTP_CCID,
cls.YK4_U2F_CCID,
cls.YK4_OTP_U2F_CCID,
cls.PLUS_U2F_OTP
])
if otp:
pids.difference_update(set([
cls.NEO_CCID,
cls.NEO_U2F,
cls.NEO_U2F_CCID,
cls.NEO_SKY,
cls.YK4_U2F,
cls.YK4_CCID,
cls.YK4_U2F_CCID
]))
if ccid:
pids.difference_update(set([
cls.YUBIKEY,
cls.NEO_OTP,
cls.NEO_U2F,
cls.NEO_OTP_U2F,
cls.NEO_SKY,
cls.YK4_OTP,
cls.YK4_U2F,
cls.YK4_OTP_U2F,
cls.PLUS_U2F_OTP
]))
if u2f:
pids.difference_update(set([
cls.YUBIKEY,
cls.NEO_OTP,
cls.NEO_OTP_CCID,
cls.NEO_CCID,
cls.YK4_OTP,
cls.YK4_CCID,
cls.YK4_OTP_CCID
]))
return pids
class YK4_CAPA(object):
"""Capability bits in the YK4_CAPA field"""
OTP = 0x01 # OTP functionality
U2F = 0x02 # U2F functionality
CCID = 0x04 # CCID functionality
class TAG(object):
"""Tags for TLV data read from the YK4_CAPABILITIES slot"""
CAPA = 0x01 # capabilities
SERIAL = 0x02 # serial number