| from dataclasses import dataclass |
| from enum import Enum |
| from typing import Mapping, Union |
|
|
| from ..cose import COSECRV, COSEAlgorithmIdentifier |
| from ..exceptions import InvalidTPMPubAreaStructure |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| class TPM_ST(str, Enum): |
| RSP_COMMAND = "TPM_ST_RSP_COMMAND" |
| NULL = "TPM_ST_NULL" |
| NO_SESSIONS = "TPM_ST_NO_SESSIONS" |
| SESSIONS = "TPM_ST_SESSIONS" |
| ATTEST_NV = "TPM_ST_ATTEST_NV" |
| ATTEST_COMMAND_AUDIT = "TPM_ST_ATTEST_COMMAND_AUDIT" |
| ATTEST_SESSION_AUDIT = "TPM_ST_ATTEST_SESSION_AUDIT" |
| ATTEST_CERTIFY = "TPM_ST_ATTEST_CERTIFY" |
| ATTEST_QUOTE = "TPM_ST_ATTEST_QUOTE" |
| ATTEST_TIME = "TPM_ST_ATTEST_TIME" |
| ATTEST_CREATION = "TPM_ST_ATTEST_CREATION" |
| CREATION = "TPM_ST_CREATION" |
| VERIFIED = "TPM_ST_VERIFIED" |
| AUTH_SECRET = "TPM_ST_AUTH_SECRET" |
| HASHCHECK = "TPM_ST_HASHCHECK" |
| AUTH_SIGNED = "TPM_ST_AUTH_SIGNED" |
| FU_MANIFEST = "TPM_ST_FU_MANIFEST" |
|
|
|
|
| class TPM_ALG(str, Enum): |
| ERROR = "TPM_ALG_ERROR" |
| RSA = "TPM_ALG_RSA" |
| SHA1 = "TPM_ALG_SHA1" |
| HMAC = "TPM_ALG_HMAC" |
| AES = "TPM_ALG_AES" |
| MGF1 = "TPM_ALG_MGF1" |
| KEYEDHASH = "TPM_ALG_KEYEDHASH" |
| XOR = "TPM_ALG_XOR" |
| SHA256 = "TPM_ALG_SHA256" |
| SHA384 = "TPM_ALG_SHA384" |
| SHA512 = "TPM_ALG_SHA512" |
| NULL = "TPM_ALG_NULL" |
| SM3_256 = "TPM_ALG_SM3_256" |
| SM4 = "TPM_ALG_SM4" |
| RSASSA = "TPM_ALG_RSASSA" |
| RSAES = "TPM_ALG_RSAES" |
| RSAPSS = "TPM_ALG_RSAPSS" |
| OAEP = "TPM_ALG_OAEP" |
| ECDSA = "TPM_ALG_ECDSA" |
| ECDH = "TPM_ALG_ECDH" |
| ECDAA = "TPM_ALG_ECDAA" |
| SM2 = "TPM_ALG_SM2" |
| ECSCHNORR = "TPM_ALG_ECSCHNORR" |
| ECMQV = "TPM_ALG_ECMQV" |
| KDF1_SP800_56A = "TPM_ALG_KDF1_SP800_56A" |
| KDF2 = "TPM_ALG_KDF2" |
| KDF1_SP800_108 = "TPM_ALG_KDF1_SP800_108" |
| ECC = "TPM_ALG_ECC" |
| SYMCIPHER = "TPM_ALG_SYMCIPHER" |
| CAMELLIA = "TPM_ALG_CAMELLIA" |
| CTR = "TPM_ALG_CTR" |
| OFB = "TPM_ALG_OFB" |
| CBC = "TPM_ALG_CBC" |
| CFB = "TPM_ALG_CFB" |
| ECB = "TPM_ALG_ECB" |
|
|
|
|
| class TPM_ECC_CURVE(str, Enum): |
| NONE = "NONE" |
| NIST_P192 = "NIST_P192" |
| NIST_P224 = "NIST_P224" |
| NIST_P256 = "NIST_P256" |
| NIST_P384 = "NIST_P384" |
| NIST_P521 = "NIST_P521" |
| BN_P256 = "BN_P256" |
| BN_P638 = "BN_P638" |
| SM2_P256 = "SM2_P256" |
|
|
|
|
| class TPMCertInfoClockInfo: |
| """ |
| 10.11.1 TPMS_CLOCK_INFO |
| """ |
|
|
| clock: bytes |
| reset_count: int |
| restart_count: int |
| safe: bool |
|
|
| def __init__(self, clock_info: bytes): |
| self.clock = clock_info[0:8] |
| self.reset_count = int.from_bytes(clock_info[8:12], "big") |
| self.restart_count = int.from_bytes(clock_info[12:16], "big") |
| self.safe = bool(clock_info[16]) |
|
|
|
|
| class TPMCertInfoAttested: |
| """ |
| 10.12.3 TPMS_CERTIFY_INFO |
| """ |
|
|
| name_alg: TPM_ALG |
| name_alg_bytes: bytes |
| name: bytes |
| qualified_name: bytes |
|
|
| def __init__(self, attested_name: bytes, qualified_name: bytes): |
| self.name_alg = TPM_ALG_MAP[attested_name[0:2]] |
| self.name_alg_bytes = attested_name[0:2] |
| self.name = attested_name |
| self.qualified_name = qualified_name |
|
|
|
|
| @dataclass |
| class TPMCertInfo: |
| """ |
| 10.12.8 TPMS_ATTEST |
| """ |
|
|
| magic: bytes |
| type: TPM_ST |
| qualified_signer: bytes |
| extra_data: bytes |
| clock_info: TPMCertInfoClockInfo |
| firmware_version: bytes |
| attested: TPMCertInfoAttested |
|
|
|
|
| class TPMPubAreaParametersRSA: |
| """ |
| 12.2.3.5 TPMS_RSA_PARMS |
| """ |
|
|
| symmetric: TPM_ALG |
| scheme: TPM_ALG |
| key_bits: bytes |
| exponent: bytes |
|
|
| def __init__(self, params: bytes): |
| self.symmetric = TPM_ALG_MAP[params[0:2]] |
| self.scheme = TPM_ALG_MAP[params[2:4]] |
| self.key_bits = params[4:6] |
| self.exponent = params[6:10] |
|
|
|
|
| class TPMPubAreaParametersECC: |
| """ |
| 12.2.3.6 TPMS_ECC_PARMS |
| """ |
|
|
| symmetric: TPM_ALG |
| scheme: TPM_ALG |
| curve_id: TPM_ECC_CURVE |
| kdf: TPM_ALG |
|
|
| def __init__(self, params: bytes): |
| self.symmetric = TPM_ALG_MAP[params[0:2]] |
| self.scheme = TPM_ALG_MAP[params[2:4]] |
| self.curve_id = TPM_ECC_CURVE_MAP[params[4:6]] |
| self.kdf = TPM_ALG_MAP[params[6:8]] |
|
|
|
|
| class TPMPubAreaObjectAttributes: |
| """ |
| 8.3 TPMA_OBJECT (Object Attributes) |
| """ |
|
|
| fixed_tpm: bool |
| st_clear: bool |
| fixed_parent: bool |
| sensitive_data_origin: bool |
| user_with_auth: bool |
| admin_with_policy: bool |
| no_da: bool |
| encrypted_duplication: bool |
| restricted: bool |
| decrypt: bool |
| sign_or_encrypt: bool |
|
|
| def __init__(self, object_attributes: bytes): |
| attrs = int.from_bytes(object_attributes[0:4], "big") |
| self.fixed_tpm = attrs & (1 << 1) != 0 |
| self.st_clear = attrs & (1 << 2) != 0 |
| self.fixed_parent = attrs & (1 << 4) != 0 |
| self.sensitive_data_origin = attrs & (1 << 5) != 0 |
| self.user_with_auth = attrs & (1 << 6) != 0 |
| self.admin_with_policy = attrs & (1 << 7) != 0 |
| self.no_da = attrs & (1 << 10) != 0 |
| self.encrypted_duplication = attrs & (1 << 11) != 0 |
| self.restricted = attrs & (1 << 16) != 0 |
| self.decrypt = attrs & (1 << 17) != 0 |
| self.sign_or_encrypt = attrs & (1 << 18) != 0 |
|
|
|
|
| class TPMPubAreaUnique: |
| """ |
| 12.2.3.2 TPMU_PUBLIC_ID |
| """ |
|
|
| value: bytes |
|
|
| def __init__(self, unique: bytes, alg_type: TPM_ALG): |
| if alg_type == TPM_ALG.RSA: |
| """ |
| As per 11.2.4.5 TPM2B_PUBLIC_KEY_RSA, extract `unique` of dynamic length |
| """ |
| unique_length = int.from_bytes(unique[0:2], "big") |
| rsa_unique = unique[2 : 2 + unique_length] |
| self.value = rsa_unique |
| elif alg_type == TPM_ALG.ECC: |
| """ |
| As per 12.2.3.2 TPMU_PUBLIC_ID, `unique` is `TPMS_ECC_POINT` when `type` |
| indicates ECC. |
| |
| As per 11.2.5.2 TPMS_ECC_POINT, `x` and `y` within are |
| `TPM2B_ECC_PARAMETER`, which is a uint16 `size`, followed by bytes of |
| the indicated length. |
| |
| `unique`, then, is structured thusly: |
| [ |
| [x_len, ...x_bytes], |
| [y_len, ...y_bytes] |
| ] |
| |
| Get `unique` to this structure for easier comparison with the output from |
| `decode_credential_public_key`, which will return bytes for its `x` and `y` |
| and to which this value will be compared: |
| |
| [ |
| x_bytes, |
| y_bytes, |
| ] |
| |
| """ |
| pointer = 0 |
| unique_x_len = int.from_bytes(unique[0:2], "big") |
| pointer += 2 |
| unique_x = unique[pointer : pointer + unique_x_len] |
| pointer += unique_x_len |
| unique_y_len = int.from_bytes(unique[pointer : pointer + 2], "big") |
| pointer += 2 |
| unique_y = unique[pointer : pointer + unique_y_len] |
|
|
| self.value = b"".join([unique_x, unique_y]) |
| else: |
| raise InvalidTPMPubAreaStructure( |
| f'Pub Area alg type "{alg_type}" was not "{TPM_ALG.RSA}" or "{TPM_ALG.ECC}"' |
| ) |
|
|
|
|
| @dataclass |
| class TPMPubArea: |
| """ |
| 12.2.4 TPMT_PUBLIC |
| """ |
|
|
| type: TPM_ALG |
| name_alg: TPM_ALG |
| object_attributes: TPMPubAreaObjectAttributes |
| auth_policy: bytes |
| parameters: Union[TPMPubAreaParametersRSA, TPMPubAreaParametersECC] |
| unique: TPMPubAreaUnique |
|
|
|
|
| @dataclass |
| class TPMManufacturerInfo: |
| name: str |
| id: str |
|
|
|
|
| """ |
| 6.9 TPM_ST (Structure Tags) |
| """ |
| TPM_ST_MAP: Mapping[bytes, TPM_ST] = { |
| b"\x00\xc4": TPM_ST.RSP_COMMAND, |
| b"\x80\x00": TPM_ST.NULL, |
| b"\x80\x01": TPM_ST.NO_SESSIONS, |
| b"\x80\x02": TPM_ST.SESSIONS, |
| b"\x80\x14": TPM_ST.ATTEST_NV, |
| b"\x80\x15": TPM_ST.ATTEST_COMMAND_AUDIT, |
| b"\x80\x16": TPM_ST.ATTEST_SESSION_AUDIT, |
| b"\x80\x17": TPM_ST.ATTEST_CERTIFY, |
| b"\x80\x18": TPM_ST.ATTEST_QUOTE, |
| b"\x80\x19": TPM_ST.ATTEST_TIME, |
| b"\x80\x1a": TPM_ST.ATTEST_CREATION, |
| b"\x80\x21": TPM_ST.CREATION, |
| b"\x80\x22": TPM_ST.VERIFIED, |
| b"\x80\x23": TPM_ST.AUTH_SECRET, |
| b"\x80\x24": TPM_ST.HASHCHECK, |
| b"\x80\x25": TPM_ST.AUTH_SIGNED, |
| b"\x80\x29": TPM_ST.FU_MANIFEST, |
| } |
|
|
|
|
| """ |
| 6.3 TPM_ALG_ID |
| """ |
| TPM_ALG_MAP: Mapping[bytes, TPM_ALG] = { |
| b"\x00\x00": TPM_ALG.ERROR, |
| b"\x00\x01": TPM_ALG.RSA, |
| b"\x00\x04": TPM_ALG.SHA1, |
| b"\x00\x05": TPM_ALG.HMAC, |
| b"\x00\x06": TPM_ALG.AES, |
| b"\x00\x07": TPM_ALG.MGF1, |
| b"\x00\x08": TPM_ALG.KEYEDHASH, |
| b"\x00\x0a": TPM_ALG.XOR, |
| b"\x00\x0b": TPM_ALG.SHA256, |
| b"\x00\x0c": TPM_ALG.SHA384, |
| b"\x00\x0d": TPM_ALG.SHA512, |
| b"\x00\x10": TPM_ALG.NULL, |
| b"\x00\x12": TPM_ALG.SM3_256, |
| b"\x00\x13": TPM_ALG.SM4, |
| b"\x00\x14": TPM_ALG.RSASSA, |
| b"\x00\x15": TPM_ALG.RSAES, |
| b"\x00\x16": TPM_ALG.RSAPSS, |
| b"\x00\x17": TPM_ALG.OAEP, |
| b"\x00\x18": TPM_ALG.ECDSA, |
| b"\x00\x19": TPM_ALG.ECDH, |
| b"\x00\x1a": TPM_ALG.ECDAA, |
| b"\x00\x1b": TPM_ALG.SM2, |
| b"\x00\x1c": TPM_ALG.ECSCHNORR, |
| b"\x00\x1d": TPM_ALG.ECMQV, |
| b"\x00\x20": TPM_ALG.KDF1_SP800_56A, |
| b"\x00\x21": TPM_ALG.KDF2, |
| b"\x00\x22": TPM_ALG.KDF1_SP800_108, |
| b"\x00\x23": TPM_ALG.ECC, |
| b"\x00\x25": TPM_ALG.SYMCIPHER, |
| b"\x00\x26": TPM_ALG.CAMELLIA, |
| b"\x00\x40": TPM_ALG.CTR, |
| b"\x00\x41": TPM_ALG.OFB, |
| b"\x00\x42": TPM_ALG.CBC, |
| b"\x00\x43": TPM_ALG.CFB, |
| b"\x00\x44": TPM_ALG.ECB, |
| } |
|
|
|
|
| """ |
| 6.4 TPM_ECC_CURVE |
| """ |
| TPM_ECC_CURVE_MAP: Mapping[bytes, TPM_ECC_CURVE] = { |
| b"\x00\x00": TPM_ECC_CURVE.NONE, |
| b"\x00\x01": TPM_ECC_CURVE.NIST_P192, |
| b"\x00\x02": TPM_ECC_CURVE.NIST_P224, |
| b"\x00\x03": TPM_ECC_CURVE.NIST_P256, |
| b"\x00\x04": TPM_ECC_CURVE.NIST_P384, |
| b"\x00\x05": TPM_ECC_CURVE.NIST_P521, |
| b"\x00\x10": TPM_ECC_CURVE.BN_P256, |
| b"\x00\x11": TPM_ECC_CURVE.BN_P638, |
| b"\x00\x20": TPM_ECC_CURVE.SM2_P256, |
| } |
|
|
|
|
| |
| TPM_ECC_CURVE_COSE_CRV_MAP: Mapping[TPM_ECC_CURVE, COSECRV] = { |
| TPM_ECC_CURVE.NIST_P256: COSECRV.P256, |
| TPM_ECC_CURVE.NIST_P384: COSECRV.P384, |
| TPM_ECC_CURVE.NIST_P521: COSECRV.P521, |
| TPM_ECC_CURVE.BN_P256: COSECRV.P256, |
| TPM_ECC_CURVE.SM2_P256: COSECRV.P256, |
| } |
|
|
|
|
| |
| TPM_ALG_COSE_ALG_MAP: Mapping[TPM_ALG, COSEAlgorithmIdentifier] = { |
| TPM_ALG.SHA256: COSEAlgorithmIdentifier.RSASSA_PSS_SHA_256, |
| TPM_ALG.SHA384: COSEAlgorithmIdentifier.RSASSA_PKCS1_v1_5_SHA_384, |
| TPM_ALG.SHA512: COSEAlgorithmIdentifier.RSASSA_PKCS1_v1_5_SHA_512, |
| TPM_ALG.SHA1: COSEAlgorithmIdentifier.RSASSA_PKCS1_v1_5_SHA_1, |
| } |
|
|
|
|
| |
| |
| TPM_MANUFACTURERS: Mapping[str, TPMManufacturerInfo] = { |
| "id:414D4400": TPMManufacturerInfo(name="AMD", id="AMD"), |
| "id:41544D4C": TPMManufacturerInfo(name="Atmel", id="ATML"), |
| "id:4252434D": TPMManufacturerInfo(name="Broadcom", id="BRCM"), |
| "id:4353434F": TPMManufacturerInfo(name="Cisco", id="CSCO"), |
| "id:464C5953": TPMManufacturerInfo(name="Flyslice Technologies", id="FLYS"), |
| "id:48504500": TPMManufacturerInfo(name="HPE", id="HPE"), |
| "id:49424d00": TPMManufacturerInfo(name="IBM", id="IBM"), |
| "id:49465800": TPMManufacturerInfo(name="Infineon", id="IFX"), |
| "id:494E5443": TPMManufacturerInfo(name="Intel", id="INTC"), |
| "id:4C454E00": TPMManufacturerInfo(name="Lenovo", id="LEN"), |
| "id:4D534654": TPMManufacturerInfo(name="Microsoft", id="MSFT"), |
| "id:4E534D20": TPMManufacturerInfo(name="National Semiconductor", id="NSM"), |
| "id:4E545A00": TPMManufacturerInfo(name="Nationz", id="NTZ"), |
| "id:4E544300": TPMManufacturerInfo(name="Nuvoton Technology", id="NTC"), |
| "id:51434F4D": TPMManufacturerInfo(name="Qualcomm", id="QCOM"), |
| "id:534D5343": TPMManufacturerInfo(name="SMSC", id="SMSC"), |
| "id:53544D20": TPMManufacturerInfo(name="ST Microelectronics", id="STM"), |
| "id:534D534E": TPMManufacturerInfo(name="Samsung", id="SMSN"), |
| "id:534E5300": TPMManufacturerInfo(name="Sinosun", id="SNS"), |
| "id:54584E00": TPMManufacturerInfo(name="Texas Instruments", id="TXN"), |
| "id:57454300": TPMManufacturerInfo(name="Winbond", id="WEC"), |
| "id:524F4343": TPMManufacturerInfo(name="Fuzhou Rockchip", id="ROCC"), |
| "id:474F4F47": TPMManufacturerInfo(name="Google", id="GOOG"), |
| } |
|
|