18c2ecf20Sopenharmony_ci# SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ciimport hashlib
48c2ecf20Sopenharmony_ciimport os
58c2ecf20Sopenharmony_ciimport socket
68c2ecf20Sopenharmony_ciimport struct
78c2ecf20Sopenharmony_ciimport sys
88c2ecf20Sopenharmony_ciimport unittest
98c2ecf20Sopenharmony_ciimport fcntl
108c2ecf20Sopenharmony_ciimport select
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ciTPM2_ST_NO_SESSIONS = 0x8001
138c2ecf20Sopenharmony_ciTPM2_ST_SESSIONS = 0x8002
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ciTPM2_CC_FIRST = 0x01FF
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciTPM2_CC_CREATE_PRIMARY = 0x0131
188c2ecf20Sopenharmony_ciTPM2_CC_DICTIONARY_ATTACK_LOCK_RESET = 0x0139
198c2ecf20Sopenharmony_ciTPM2_CC_CREATE = 0x0153
208c2ecf20Sopenharmony_ciTPM2_CC_LOAD = 0x0157
218c2ecf20Sopenharmony_ciTPM2_CC_UNSEAL = 0x015E
228c2ecf20Sopenharmony_ciTPM2_CC_FLUSH_CONTEXT = 0x0165
238c2ecf20Sopenharmony_ciTPM2_CC_START_AUTH_SESSION = 0x0176
248c2ecf20Sopenharmony_ciTPM2_CC_GET_CAPABILITY	= 0x017A
258c2ecf20Sopenharmony_ciTPM2_CC_GET_RANDOM = 0x017B
268c2ecf20Sopenharmony_ciTPM2_CC_PCR_READ = 0x017E
278c2ecf20Sopenharmony_ciTPM2_CC_POLICY_PCR = 0x017F
288c2ecf20Sopenharmony_ciTPM2_CC_PCR_EXTEND = 0x0182
298c2ecf20Sopenharmony_ciTPM2_CC_POLICY_PASSWORD = 0x018C
308c2ecf20Sopenharmony_ciTPM2_CC_POLICY_GET_DIGEST = 0x0189
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ciTPM2_SE_POLICY = 0x01
338c2ecf20Sopenharmony_ciTPM2_SE_TRIAL = 0x03
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ciTPM2_ALG_RSA = 0x0001
368c2ecf20Sopenharmony_ciTPM2_ALG_SHA1 = 0x0004
378c2ecf20Sopenharmony_ciTPM2_ALG_AES = 0x0006
388c2ecf20Sopenharmony_ciTPM2_ALG_KEYEDHASH = 0x0008
398c2ecf20Sopenharmony_ciTPM2_ALG_SHA256 = 0x000B
408c2ecf20Sopenharmony_ciTPM2_ALG_NULL = 0x0010
418c2ecf20Sopenharmony_ciTPM2_ALG_CBC = 0x0042
428c2ecf20Sopenharmony_ciTPM2_ALG_CFB = 0x0043
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ciTPM2_RH_OWNER = 0x40000001
458c2ecf20Sopenharmony_ciTPM2_RH_NULL = 0x40000007
468c2ecf20Sopenharmony_ciTPM2_RH_LOCKOUT = 0x4000000A
478c2ecf20Sopenharmony_ciTPM2_RS_PW = 0x40000009
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ciTPM2_RC_SIZE            = 0x01D5
508c2ecf20Sopenharmony_ciTPM2_RC_AUTH_FAIL       = 0x098E
518c2ecf20Sopenharmony_ciTPM2_RC_POLICY_FAIL     = 0x099D
528c2ecf20Sopenharmony_ciTPM2_RC_COMMAND_CODE    = 0x0143
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ciTSS2_RC_LAYER_SHIFT = 16
558c2ecf20Sopenharmony_ciTSS2_RESMGR_TPM_RC_LAYER = (11 << TSS2_RC_LAYER_SHIFT)
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ciTPM2_CAP_HANDLES = 0x00000001
588c2ecf20Sopenharmony_ciTPM2_CAP_COMMANDS = 0x00000002
598c2ecf20Sopenharmony_ciTPM2_CAP_TPM_PROPERTIES = 0x00000006
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ciTPM2_PT_FIXED = 0x100
628c2ecf20Sopenharmony_ciTPM2_PT_TOTAL_COMMANDS = TPM2_PT_FIXED + 41
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ciHR_SHIFT = 24
658c2ecf20Sopenharmony_ciHR_LOADED_SESSION = 0x02000000
668c2ecf20Sopenharmony_ciHR_TRANSIENT = 0x80000000
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ciSHA1_DIGEST_SIZE = 20
698c2ecf20Sopenharmony_ciSHA256_DIGEST_SIZE = 32
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ciTPM2_VER0_ERRORS = {
728c2ecf20Sopenharmony_ci    0x000: "TPM_RC_SUCCESS",
738c2ecf20Sopenharmony_ci    0x030: "TPM_RC_BAD_TAG",
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ciTPM2_VER1_ERRORS = {
778c2ecf20Sopenharmony_ci    0x000: "TPM_RC_FAILURE",
788c2ecf20Sopenharmony_ci    0x001: "TPM_RC_FAILURE",
798c2ecf20Sopenharmony_ci    0x003: "TPM_RC_SEQUENCE",
808c2ecf20Sopenharmony_ci    0x00B: "TPM_RC_PRIVATE",
818c2ecf20Sopenharmony_ci    0x019: "TPM_RC_HMAC",
828c2ecf20Sopenharmony_ci    0x020: "TPM_RC_DISABLED",
838c2ecf20Sopenharmony_ci    0x021: "TPM_RC_EXCLUSIVE",
848c2ecf20Sopenharmony_ci    0x024: "TPM_RC_AUTH_TYPE",
858c2ecf20Sopenharmony_ci    0x025: "TPM_RC_AUTH_MISSING",
868c2ecf20Sopenharmony_ci    0x026: "TPM_RC_POLICY",
878c2ecf20Sopenharmony_ci    0x027: "TPM_RC_PCR",
888c2ecf20Sopenharmony_ci    0x028: "TPM_RC_PCR_CHANGED",
898c2ecf20Sopenharmony_ci    0x02D: "TPM_RC_UPGRADE",
908c2ecf20Sopenharmony_ci    0x02E: "TPM_RC_TOO_MANY_CONTEXTS",
918c2ecf20Sopenharmony_ci    0x02F: "TPM_RC_AUTH_UNAVAILABLE",
928c2ecf20Sopenharmony_ci    0x030: "TPM_RC_REBOOT",
938c2ecf20Sopenharmony_ci    0x031: "TPM_RC_UNBALANCED",
948c2ecf20Sopenharmony_ci    0x042: "TPM_RC_COMMAND_SIZE",
958c2ecf20Sopenharmony_ci    0x043: "TPM_RC_COMMAND_CODE",
968c2ecf20Sopenharmony_ci    0x044: "TPM_RC_AUTHSIZE",
978c2ecf20Sopenharmony_ci    0x045: "TPM_RC_AUTH_CONTEXT",
988c2ecf20Sopenharmony_ci    0x046: "TPM_RC_NV_RANGE",
998c2ecf20Sopenharmony_ci    0x047: "TPM_RC_NV_SIZE",
1008c2ecf20Sopenharmony_ci    0x048: "TPM_RC_NV_LOCKED",
1018c2ecf20Sopenharmony_ci    0x049: "TPM_RC_NV_AUTHORIZATION",
1028c2ecf20Sopenharmony_ci    0x04A: "TPM_RC_NV_UNINITIALIZED",
1038c2ecf20Sopenharmony_ci    0x04B: "TPM_RC_NV_SPACE",
1048c2ecf20Sopenharmony_ci    0x04C: "TPM_RC_NV_DEFINED",
1058c2ecf20Sopenharmony_ci    0x050: "TPM_RC_BAD_CONTEXT",
1068c2ecf20Sopenharmony_ci    0x051: "TPM_RC_CPHASH",
1078c2ecf20Sopenharmony_ci    0x052: "TPM_RC_PARENT",
1088c2ecf20Sopenharmony_ci    0x053: "TPM_RC_NEEDS_TEST",
1098c2ecf20Sopenharmony_ci    0x054: "TPM_RC_NO_RESULT",
1108c2ecf20Sopenharmony_ci    0x055: "TPM_RC_SENSITIVE",
1118c2ecf20Sopenharmony_ci    0x07F: "RC_MAX_FM0",
1128c2ecf20Sopenharmony_ci}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ciTPM2_FMT1_ERRORS = {
1158c2ecf20Sopenharmony_ci    0x001: "TPM_RC_ASYMMETRIC",
1168c2ecf20Sopenharmony_ci    0x002: "TPM_RC_ATTRIBUTES",
1178c2ecf20Sopenharmony_ci    0x003: "TPM_RC_HASH",
1188c2ecf20Sopenharmony_ci    0x004: "TPM_RC_VALUE",
1198c2ecf20Sopenharmony_ci    0x005: "TPM_RC_HIERARCHY",
1208c2ecf20Sopenharmony_ci    0x007: "TPM_RC_KEY_SIZE",
1218c2ecf20Sopenharmony_ci    0x008: "TPM_RC_MGF",
1228c2ecf20Sopenharmony_ci    0x009: "TPM_RC_MODE",
1238c2ecf20Sopenharmony_ci    0x00A: "TPM_RC_TYPE",
1248c2ecf20Sopenharmony_ci    0x00B: "TPM_RC_HANDLE",
1258c2ecf20Sopenharmony_ci    0x00C: "TPM_RC_KDF",
1268c2ecf20Sopenharmony_ci    0x00D: "TPM_RC_RANGE",
1278c2ecf20Sopenharmony_ci    0x00E: "TPM_RC_AUTH_FAIL",
1288c2ecf20Sopenharmony_ci    0x00F: "TPM_RC_NONCE",
1298c2ecf20Sopenharmony_ci    0x010: "TPM_RC_PP",
1308c2ecf20Sopenharmony_ci    0x012: "TPM_RC_SCHEME",
1318c2ecf20Sopenharmony_ci    0x015: "TPM_RC_SIZE",
1328c2ecf20Sopenharmony_ci    0x016: "TPM_RC_SYMMETRIC",
1338c2ecf20Sopenharmony_ci    0x017: "TPM_RC_TAG",
1348c2ecf20Sopenharmony_ci    0x018: "TPM_RC_SELECTOR",
1358c2ecf20Sopenharmony_ci    0x01A: "TPM_RC_INSUFFICIENT",
1368c2ecf20Sopenharmony_ci    0x01B: "TPM_RC_SIGNATURE",
1378c2ecf20Sopenharmony_ci    0x01C: "TPM_RC_KEY",
1388c2ecf20Sopenharmony_ci    0x01D: "TPM_RC_POLICY_FAIL",
1398c2ecf20Sopenharmony_ci    0x01F: "TPM_RC_INTEGRITY",
1408c2ecf20Sopenharmony_ci    0x020: "TPM_RC_TICKET",
1418c2ecf20Sopenharmony_ci    0x021: "TPM_RC_RESERVED_BITS",
1428c2ecf20Sopenharmony_ci    0x022: "TPM_RC_BAD_AUTH",
1438c2ecf20Sopenharmony_ci    0x023: "TPM_RC_EXPIRED",
1448c2ecf20Sopenharmony_ci    0x024: "TPM_RC_POLICY_CC",
1458c2ecf20Sopenharmony_ci    0x025: "TPM_RC_BINDING",
1468c2ecf20Sopenharmony_ci    0x026: "TPM_RC_CURVE",
1478c2ecf20Sopenharmony_ci    0x027: "TPM_RC_ECC_POINT",
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ciTPM2_WARN_ERRORS = {
1518c2ecf20Sopenharmony_ci    0x001: "TPM_RC_CONTEXT_GAP",
1528c2ecf20Sopenharmony_ci    0x002: "TPM_RC_OBJECT_MEMORY",
1538c2ecf20Sopenharmony_ci    0x003: "TPM_RC_SESSION_MEMORY",
1548c2ecf20Sopenharmony_ci    0x004: "TPM_RC_MEMORY",
1558c2ecf20Sopenharmony_ci    0x005: "TPM_RC_SESSION_HANDLES",
1568c2ecf20Sopenharmony_ci    0x006: "TPM_RC_OBJECT_HANDLES",
1578c2ecf20Sopenharmony_ci    0x007: "TPM_RC_LOCALITY",
1588c2ecf20Sopenharmony_ci    0x008: "TPM_RC_YIELDED",
1598c2ecf20Sopenharmony_ci    0x009: "TPM_RC_CANCELED",
1608c2ecf20Sopenharmony_ci    0x00A: "TPM_RC_TESTING",
1618c2ecf20Sopenharmony_ci    0x010: "TPM_RC_REFERENCE_H0",
1628c2ecf20Sopenharmony_ci    0x011: "TPM_RC_REFERENCE_H1",
1638c2ecf20Sopenharmony_ci    0x012: "TPM_RC_REFERENCE_H2",
1648c2ecf20Sopenharmony_ci    0x013: "TPM_RC_REFERENCE_H3",
1658c2ecf20Sopenharmony_ci    0x014: "TPM_RC_REFERENCE_H4",
1668c2ecf20Sopenharmony_ci    0x015: "TPM_RC_REFERENCE_H5",
1678c2ecf20Sopenharmony_ci    0x016: "TPM_RC_REFERENCE_H6",
1688c2ecf20Sopenharmony_ci    0x018: "TPM_RC_REFERENCE_S0",
1698c2ecf20Sopenharmony_ci    0x019: "TPM_RC_REFERENCE_S1",
1708c2ecf20Sopenharmony_ci    0x01A: "TPM_RC_REFERENCE_S2",
1718c2ecf20Sopenharmony_ci    0x01B: "TPM_RC_REFERENCE_S3",
1728c2ecf20Sopenharmony_ci    0x01C: "TPM_RC_REFERENCE_S4",
1738c2ecf20Sopenharmony_ci    0x01D: "TPM_RC_REFERENCE_S5",
1748c2ecf20Sopenharmony_ci    0x01E: "TPM_RC_REFERENCE_S6",
1758c2ecf20Sopenharmony_ci    0x020: "TPM_RC_NV_RATE",
1768c2ecf20Sopenharmony_ci    0x021: "TPM_RC_LOCKOUT",
1778c2ecf20Sopenharmony_ci    0x022: "TPM_RC_RETRY",
1788c2ecf20Sopenharmony_ci    0x023: "TPM_RC_NV_UNAVAILABLE",
1798c2ecf20Sopenharmony_ci    0x7F: "TPM_RC_NOT_USED",
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ciRC_VER1 = 0x100
1838c2ecf20Sopenharmony_ciRC_FMT1 = 0x080
1848c2ecf20Sopenharmony_ciRC_WARN = 0x900
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ciALG_DIGEST_SIZE_MAP = {
1878c2ecf20Sopenharmony_ci    TPM2_ALG_SHA1: SHA1_DIGEST_SIZE,
1888c2ecf20Sopenharmony_ci    TPM2_ALG_SHA256: SHA256_DIGEST_SIZE,
1898c2ecf20Sopenharmony_ci}
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ciALG_HASH_FUNCTION_MAP = {
1928c2ecf20Sopenharmony_ci    TPM2_ALG_SHA1: hashlib.sha1,
1938c2ecf20Sopenharmony_ci    TPM2_ALG_SHA256: hashlib.sha256
1948c2ecf20Sopenharmony_ci}
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ciNAME_ALG_MAP = {
1978c2ecf20Sopenharmony_ci    "sha1": TPM2_ALG_SHA1,
1988c2ecf20Sopenharmony_ci    "sha256": TPM2_ALG_SHA256,
1998c2ecf20Sopenharmony_ci}
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ciclass UnknownAlgorithmIdError(Exception):
2038c2ecf20Sopenharmony_ci    def __init__(self, alg):
2048c2ecf20Sopenharmony_ci        self.alg = alg
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci    def __str__(self):
2078c2ecf20Sopenharmony_ci        return '0x%0x' % (alg)
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ciclass UnknownAlgorithmNameError(Exception):
2118c2ecf20Sopenharmony_ci    def __init__(self, name):
2128c2ecf20Sopenharmony_ci        self.name = name
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci    def __str__(self):
2158c2ecf20Sopenharmony_ci        return name
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ciclass UnknownPCRBankError(Exception):
2198c2ecf20Sopenharmony_ci    def __init__(self, alg):
2208c2ecf20Sopenharmony_ci        self.alg = alg
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci    def __str__(self):
2238c2ecf20Sopenharmony_ci        return '0x%0x' % (alg)
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ciclass ProtocolError(Exception):
2278c2ecf20Sopenharmony_ci    def __init__(self, cc, rc):
2288c2ecf20Sopenharmony_ci        self.cc = cc
2298c2ecf20Sopenharmony_ci        self.rc = rc
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci        if (rc & RC_FMT1) == RC_FMT1:
2328c2ecf20Sopenharmony_ci            self.name = TPM2_FMT1_ERRORS.get(rc & 0x3f, "TPM_RC_UNKNOWN")
2338c2ecf20Sopenharmony_ci        elif (rc & RC_WARN) == RC_WARN:
2348c2ecf20Sopenharmony_ci            self.name = TPM2_WARN_ERRORS.get(rc & 0x7f, "TPM_RC_UNKNOWN")
2358c2ecf20Sopenharmony_ci        elif (rc & RC_VER1) == RC_VER1:
2368c2ecf20Sopenharmony_ci            self.name = TPM2_VER1_ERRORS.get(rc & 0x7f, "TPM_RC_UNKNOWN")
2378c2ecf20Sopenharmony_ci        else:
2388c2ecf20Sopenharmony_ci            self.name = TPM2_VER0_ERRORS.get(rc & 0x7f, "TPM_RC_UNKNOWN")
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci    def __str__(self):
2418c2ecf20Sopenharmony_ci        if self.cc:
2428c2ecf20Sopenharmony_ci            return '%s: cc=0x%08x, rc=0x%08x' % (self.name, self.cc, self.rc)
2438c2ecf20Sopenharmony_ci        else:
2448c2ecf20Sopenharmony_ci            return '%s: rc=0x%08x' % (self.name, self.rc)
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ciclass AuthCommand(object):
2488c2ecf20Sopenharmony_ci    """TPMS_AUTH_COMMAND"""
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci    def __init__(self, session_handle=TPM2_RS_PW, nonce=bytes(),
2518c2ecf20Sopenharmony_ci                 session_attributes=0, hmac=bytes()):
2528c2ecf20Sopenharmony_ci        self.session_handle = session_handle
2538c2ecf20Sopenharmony_ci        self.nonce = nonce
2548c2ecf20Sopenharmony_ci        self.session_attributes = session_attributes
2558c2ecf20Sopenharmony_ci        self.hmac = hmac
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci    def __bytes__(self):
2588c2ecf20Sopenharmony_ci        fmt = '>I H%us B H%us' % (len(self.nonce), len(self.hmac))
2598c2ecf20Sopenharmony_ci        return struct.pack(fmt, self.session_handle, len(self.nonce),
2608c2ecf20Sopenharmony_ci                           self.nonce, self.session_attributes, len(self.hmac),
2618c2ecf20Sopenharmony_ci                           self.hmac)
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci    def __len__(self):
2648c2ecf20Sopenharmony_ci        fmt = '>I H%us B H%us' % (len(self.nonce), len(self.hmac))
2658c2ecf20Sopenharmony_ci        return struct.calcsize(fmt)
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ciclass SensitiveCreate(object):
2698c2ecf20Sopenharmony_ci    """TPMS_SENSITIVE_CREATE"""
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci    def __init__(self, user_auth=bytes(), data=bytes()):
2728c2ecf20Sopenharmony_ci        self.user_auth = user_auth
2738c2ecf20Sopenharmony_ci        self.data = data
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci    def __bytes__(self):
2768c2ecf20Sopenharmony_ci        fmt = '>H%us H%us' % (len(self.user_auth), len(self.data))
2778c2ecf20Sopenharmony_ci        return struct.pack(fmt, len(self.user_auth), self.user_auth,
2788c2ecf20Sopenharmony_ci                           len(self.data), self.data)
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci    def __len__(self):
2818c2ecf20Sopenharmony_ci        fmt = '>H%us H%us' % (len(self.user_auth), len(self.data))
2828c2ecf20Sopenharmony_ci        return struct.calcsize(fmt)
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ciclass Public(object):
2868c2ecf20Sopenharmony_ci    """TPMT_PUBLIC"""
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci    FIXED_TPM = (1 << 1)
2898c2ecf20Sopenharmony_ci    FIXED_PARENT = (1 << 4)
2908c2ecf20Sopenharmony_ci    SENSITIVE_DATA_ORIGIN = (1 << 5)
2918c2ecf20Sopenharmony_ci    USER_WITH_AUTH = (1 << 6)
2928c2ecf20Sopenharmony_ci    RESTRICTED = (1 << 16)
2938c2ecf20Sopenharmony_ci    DECRYPT = (1 << 17)
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci    def __fmt(self):
2968c2ecf20Sopenharmony_ci        return '>HHIH%us%usH%us' % \
2978c2ecf20Sopenharmony_ci            (len(self.auth_policy), len(self.parameters), len(self.unique))
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci    def __init__(self, object_type, name_alg, object_attributes,
3008c2ecf20Sopenharmony_ci                 auth_policy=bytes(), parameters=bytes(),
3018c2ecf20Sopenharmony_ci                 unique=bytes()):
3028c2ecf20Sopenharmony_ci        self.object_type = object_type
3038c2ecf20Sopenharmony_ci        self.name_alg = name_alg
3048c2ecf20Sopenharmony_ci        self.object_attributes = object_attributes
3058c2ecf20Sopenharmony_ci        self.auth_policy = auth_policy
3068c2ecf20Sopenharmony_ci        self.parameters = parameters
3078c2ecf20Sopenharmony_ci        self.unique = unique
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci    def __bytes__(self):
3108c2ecf20Sopenharmony_ci        return struct.pack(self.__fmt(),
3118c2ecf20Sopenharmony_ci                           self.object_type,
3128c2ecf20Sopenharmony_ci                           self.name_alg,
3138c2ecf20Sopenharmony_ci                           self.object_attributes,
3148c2ecf20Sopenharmony_ci                           len(self.auth_policy),
3158c2ecf20Sopenharmony_ci                           self.auth_policy,
3168c2ecf20Sopenharmony_ci                           self.parameters,
3178c2ecf20Sopenharmony_ci                           len(self.unique),
3188c2ecf20Sopenharmony_ci                           self.unique)
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci    def __len__(self):
3218c2ecf20Sopenharmony_ci        return struct.calcsize(self.__fmt())
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_cidef get_digest_size(alg):
3258c2ecf20Sopenharmony_ci    ds = ALG_DIGEST_SIZE_MAP.get(alg)
3268c2ecf20Sopenharmony_ci    if not ds:
3278c2ecf20Sopenharmony_ci        raise UnknownAlgorithmIdError(alg)
3288c2ecf20Sopenharmony_ci    return ds
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_cidef get_hash_function(alg):
3328c2ecf20Sopenharmony_ci    f = ALG_HASH_FUNCTION_MAP.get(alg)
3338c2ecf20Sopenharmony_ci    if not f:
3348c2ecf20Sopenharmony_ci        raise UnknownAlgorithmIdError(alg)
3358c2ecf20Sopenharmony_ci    return f
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_cidef get_algorithm(name):
3398c2ecf20Sopenharmony_ci    alg = NAME_ALG_MAP.get(name)
3408c2ecf20Sopenharmony_ci    if not alg:
3418c2ecf20Sopenharmony_ci        raise UnknownAlgorithmNameError(name)
3428c2ecf20Sopenharmony_ci    return alg
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_cidef hex_dump(d):
3468c2ecf20Sopenharmony_ci    d = [format(ord(x), '02x') for x in d]
3478c2ecf20Sopenharmony_ci    d = [d[i: i + 16] for i in range(0, len(d), 16)]
3488c2ecf20Sopenharmony_ci    d = [' '.join(x) for x in d]
3498c2ecf20Sopenharmony_ci    d = os.linesep.join(d)
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci    return d
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ciclass Client:
3548c2ecf20Sopenharmony_ci    FLAG_DEBUG = 0x01
3558c2ecf20Sopenharmony_ci    FLAG_SPACE = 0x02
3568c2ecf20Sopenharmony_ci    FLAG_NONBLOCK = 0x04
3578c2ecf20Sopenharmony_ci    TPM_IOC_NEW_SPACE = 0xa200
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci    def __init__(self, flags = 0):
3608c2ecf20Sopenharmony_ci        self.flags = flags
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci        if (self.flags & Client.FLAG_SPACE) == 0:
3638c2ecf20Sopenharmony_ci            self.tpm = open('/dev/tpm0', 'r+b', buffering=0)
3648c2ecf20Sopenharmony_ci        else:
3658c2ecf20Sopenharmony_ci            self.tpm = open('/dev/tpmrm0', 'r+b', buffering=0)
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci        if (self.flags & Client.FLAG_NONBLOCK):
3688c2ecf20Sopenharmony_ci            flags = fcntl.fcntl(self.tpm, fcntl.F_GETFL)
3698c2ecf20Sopenharmony_ci            flags |= os.O_NONBLOCK
3708c2ecf20Sopenharmony_ci            fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags)
3718c2ecf20Sopenharmony_ci            self.tpm_poll = select.poll()
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci    def __del__(self):
3748c2ecf20Sopenharmony_ci        if self.tpm:
3758c2ecf20Sopenharmony_ci            self.tpm.close()
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci    def close(self):
3788c2ecf20Sopenharmony_ci        self.tpm.close()
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci    def send_cmd(self, cmd):
3818c2ecf20Sopenharmony_ci        self.tpm.write(cmd)
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci        if (self.flags & Client.FLAG_NONBLOCK):
3848c2ecf20Sopenharmony_ci            self.tpm_poll.register(self.tpm, select.POLLIN)
3858c2ecf20Sopenharmony_ci            self.tpm_poll.poll(10000)
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci        rsp = self.tpm.read()
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci        if (self.flags & Client.FLAG_NONBLOCK):
3908c2ecf20Sopenharmony_ci            self.tpm_poll.unregister(self.tpm)
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci        if (self.flags & Client.FLAG_DEBUG) != 0:
3938c2ecf20Sopenharmony_ci            sys.stderr.write('cmd' + os.linesep)
3948c2ecf20Sopenharmony_ci            sys.stderr.write(hex_dump(cmd) + os.linesep)
3958c2ecf20Sopenharmony_ci            sys.stderr.write('rsp' + os.linesep)
3968c2ecf20Sopenharmony_ci            sys.stderr.write(hex_dump(rsp) + os.linesep)
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_ci        rc = struct.unpack('>I', rsp[6:10])[0]
3998c2ecf20Sopenharmony_ci        if rc != 0:
4008c2ecf20Sopenharmony_ci            cc = struct.unpack('>I', cmd[6:10])[0]
4018c2ecf20Sopenharmony_ci            raise ProtocolError(cc, rc)
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci        return rsp
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci    def read_pcr(self, i, bank_alg = TPM2_ALG_SHA1):
4068c2ecf20Sopenharmony_ci        pcrsel_len = max((i >> 3) + 1, 3)
4078c2ecf20Sopenharmony_ci        pcrsel = [0] * pcrsel_len
4088c2ecf20Sopenharmony_ci        pcrsel[i >> 3] = 1 << (i & 7)
4098c2ecf20Sopenharmony_ci        pcrsel = ''.join(map(chr, pcrsel)).encode()
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci        fmt = '>HII IHB%us' % (pcrsel_len)
4128c2ecf20Sopenharmony_ci        cmd = struct.pack(fmt,
4138c2ecf20Sopenharmony_ci                          TPM2_ST_NO_SESSIONS,
4148c2ecf20Sopenharmony_ci                          struct.calcsize(fmt),
4158c2ecf20Sopenharmony_ci                          TPM2_CC_PCR_READ,
4168c2ecf20Sopenharmony_ci                          1,
4178c2ecf20Sopenharmony_ci                          bank_alg,
4188c2ecf20Sopenharmony_ci                          pcrsel_len, pcrsel)
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci        rsp = self.send_cmd(cmd)
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_ci        pcr_update_cnt, pcr_select_cnt = struct.unpack('>II', rsp[10:18])
4238c2ecf20Sopenharmony_ci        assert pcr_select_cnt == 1
4248c2ecf20Sopenharmony_ci        rsp = rsp[18:]
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci        alg2, pcrsel_len2 = struct.unpack('>HB', rsp[:3])
4278c2ecf20Sopenharmony_ci        assert bank_alg == alg2 and pcrsel_len == pcrsel_len2
4288c2ecf20Sopenharmony_ci        rsp = rsp[3 + pcrsel_len:]
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci        digest_cnt = struct.unpack('>I', rsp[:4])[0]
4318c2ecf20Sopenharmony_ci        if digest_cnt == 0:
4328c2ecf20Sopenharmony_ci            return None
4338c2ecf20Sopenharmony_ci        rsp = rsp[6:]
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_ci        return rsp
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci    def extend_pcr(self, i, dig, bank_alg = TPM2_ALG_SHA1):
4388c2ecf20Sopenharmony_ci        ds = get_digest_size(bank_alg)
4398c2ecf20Sopenharmony_ci        assert(ds == len(dig))
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_ci        auth_cmd = AuthCommand()
4428c2ecf20Sopenharmony_ci
4438c2ecf20Sopenharmony_ci        fmt = '>HII I I%us IH%us' % (len(auth_cmd), ds)
4448c2ecf20Sopenharmony_ci        cmd = struct.pack(
4458c2ecf20Sopenharmony_ci            fmt,
4468c2ecf20Sopenharmony_ci            TPM2_ST_SESSIONS,
4478c2ecf20Sopenharmony_ci            struct.calcsize(fmt),
4488c2ecf20Sopenharmony_ci            TPM2_CC_PCR_EXTEND,
4498c2ecf20Sopenharmony_ci            i,
4508c2ecf20Sopenharmony_ci            len(auth_cmd),
4518c2ecf20Sopenharmony_ci            bytes(auth_cmd),
4528c2ecf20Sopenharmony_ci            1, bank_alg, dig)
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci        self.send_cmd(cmd)
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci    def start_auth_session(self, session_type, name_alg = TPM2_ALG_SHA1):
4578c2ecf20Sopenharmony_ci        fmt = '>HII IIH16sHBHH'
4588c2ecf20Sopenharmony_ci        cmd = struct.pack(fmt,
4598c2ecf20Sopenharmony_ci                          TPM2_ST_NO_SESSIONS,
4608c2ecf20Sopenharmony_ci                          struct.calcsize(fmt),
4618c2ecf20Sopenharmony_ci                          TPM2_CC_START_AUTH_SESSION,
4628c2ecf20Sopenharmony_ci                          TPM2_RH_NULL,
4638c2ecf20Sopenharmony_ci                          TPM2_RH_NULL,
4648c2ecf20Sopenharmony_ci                          16,
4658c2ecf20Sopenharmony_ci                          ('\0' * 16).encode(),
4668c2ecf20Sopenharmony_ci                          0,
4678c2ecf20Sopenharmony_ci                          session_type,
4688c2ecf20Sopenharmony_ci                          TPM2_ALG_NULL,
4698c2ecf20Sopenharmony_ci                          name_alg)
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci        return struct.unpack('>I', self.send_cmd(cmd)[10:14])[0]
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci    def __calc_pcr_digest(self, pcrs, bank_alg = TPM2_ALG_SHA1,
4748c2ecf20Sopenharmony_ci                          digest_alg = TPM2_ALG_SHA1):
4758c2ecf20Sopenharmony_ci        x = []
4768c2ecf20Sopenharmony_ci        f = get_hash_function(digest_alg)
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci        for i in pcrs:
4798c2ecf20Sopenharmony_ci            pcr = self.read_pcr(i, bank_alg)
4808c2ecf20Sopenharmony_ci            if pcr is None:
4818c2ecf20Sopenharmony_ci                return None
4828c2ecf20Sopenharmony_ci            x += pcr
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ci        return f(bytearray(x)).digest()
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci    def policy_pcr(self, handle, pcrs, bank_alg = TPM2_ALG_SHA1,
4878c2ecf20Sopenharmony_ci                   name_alg = TPM2_ALG_SHA1):
4888c2ecf20Sopenharmony_ci        ds = get_digest_size(name_alg)
4898c2ecf20Sopenharmony_ci        dig = self.__calc_pcr_digest(pcrs, bank_alg, name_alg)
4908c2ecf20Sopenharmony_ci        if not dig:
4918c2ecf20Sopenharmony_ci            raise UnknownPCRBankError(bank_alg)
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci        pcrsel_len = max((max(pcrs) >> 3) + 1, 3)
4948c2ecf20Sopenharmony_ci        pcrsel = [0] * pcrsel_len
4958c2ecf20Sopenharmony_ci        for i in pcrs:
4968c2ecf20Sopenharmony_ci            pcrsel[i >> 3] |= 1 << (i & 7)
4978c2ecf20Sopenharmony_ci        pcrsel = ''.join(map(chr, pcrsel)).encode()
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci        fmt = '>HII IH%usIHB3s' % ds
5008c2ecf20Sopenharmony_ci        cmd = struct.pack(fmt,
5018c2ecf20Sopenharmony_ci                          TPM2_ST_NO_SESSIONS,
5028c2ecf20Sopenharmony_ci                          struct.calcsize(fmt),
5038c2ecf20Sopenharmony_ci                          TPM2_CC_POLICY_PCR,
5048c2ecf20Sopenharmony_ci                          handle,
5058c2ecf20Sopenharmony_ci                          len(dig),
5068c2ecf20Sopenharmony_ci                          bytes(dig),
5078c2ecf20Sopenharmony_ci                          1,
5088c2ecf20Sopenharmony_ci                          bank_alg,
5098c2ecf20Sopenharmony_ci                          pcrsel_len, pcrsel)
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci        self.send_cmd(cmd)
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci    def policy_password(self, handle):
5148c2ecf20Sopenharmony_ci        fmt = '>HII I'
5158c2ecf20Sopenharmony_ci        cmd = struct.pack(fmt,
5168c2ecf20Sopenharmony_ci                          TPM2_ST_NO_SESSIONS,
5178c2ecf20Sopenharmony_ci                          struct.calcsize(fmt),
5188c2ecf20Sopenharmony_ci                          TPM2_CC_POLICY_PASSWORD,
5198c2ecf20Sopenharmony_ci                          handle)
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ci        self.send_cmd(cmd)
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci    def get_policy_digest(self, handle):
5248c2ecf20Sopenharmony_ci        fmt = '>HII I'
5258c2ecf20Sopenharmony_ci        cmd = struct.pack(fmt,
5268c2ecf20Sopenharmony_ci                          TPM2_ST_NO_SESSIONS,
5278c2ecf20Sopenharmony_ci                          struct.calcsize(fmt),
5288c2ecf20Sopenharmony_ci                          TPM2_CC_POLICY_GET_DIGEST,
5298c2ecf20Sopenharmony_ci                          handle)
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci        return self.send_cmd(cmd)[12:]
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci    def flush_context(self, handle):
5348c2ecf20Sopenharmony_ci        fmt = '>HIII'
5358c2ecf20Sopenharmony_ci        cmd = struct.pack(fmt,
5368c2ecf20Sopenharmony_ci                          TPM2_ST_NO_SESSIONS,
5378c2ecf20Sopenharmony_ci                          struct.calcsize(fmt),
5388c2ecf20Sopenharmony_ci                          TPM2_CC_FLUSH_CONTEXT,
5398c2ecf20Sopenharmony_ci                          handle)
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci        self.send_cmd(cmd)
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_ci    def create_root_key(self, auth_value = bytes()):
5448c2ecf20Sopenharmony_ci        attributes = \
5458c2ecf20Sopenharmony_ci            Public.FIXED_TPM | \
5468c2ecf20Sopenharmony_ci            Public.FIXED_PARENT | \
5478c2ecf20Sopenharmony_ci            Public.SENSITIVE_DATA_ORIGIN | \
5488c2ecf20Sopenharmony_ci            Public.USER_WITH_AUTH | \
5498c2ecf20Sopenharmony_ci            Public.RESTRICTED | \
5508c2ecf20Sopenharmony_ci            Public.DECRYPT
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci        auth_cmd = AuthCommand()
5538c2ecf20Sopenharmony_ci        sensitive = SensitiveCreate(user_auth=auth_value)
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_ci        public_parms = struct.pack(
5568c2ecf20Sopenharmony_ci            '>HHHHHI',
5578c2ecf20Sopenharmony_ci            TPM2_ALG_AES,
5588c2ecf20Sopenharmony_ci            128,
5598c2ecf20Sopenharmony_ci            TPM2_ALG_CFB,
5608c2ecf20Sopenharmony_ci            TPM2_ALG_NULL,
5618c2ecf20Sopenharmony_ci            2048,
5628c2ecf20Sopenharmony_ci            0)
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_ci        public = Public(
5658c2ecf20Sopenharmony_ci            object_type=TPM2_ALG_RSA,
5668c2ecf20Sopenharmony_ci            name_alg=TPM2_ALG_SHA1,
5678c2ecf20Sopenharmony_ci            object_attributes=attributes,
5688c2ecf20Sopenharmony_ci            parameters=public_parms)
5698c2ecf20Sopenharmony_ci
5708c2ecf20Sopenharmony_ci        fmt = '>HIII I%us H%us H%us HI' % \
5718c2ecf20Sopenharmony_ci            (len(auth_cmd), len(sensitive), len(public))
5728c2ecf20Sopenharmony_ci        cmd = struct.pack(
5738c2ecf20Sopenharmony_ci            fmt,
5748c2ecf20Sopenharmony_ci            TPM2_ST_SESSIONS,
5758c2ecf20Sopenharmony_ci            struct.calcsize(fmt),
5768c2ecf20Sopenharmony_ci            TPM2_CC_CREATE_PRIMARY,
5778c2ecf20Sopenharmony_ci            TPM2_RH_OWNER,
5788c2ecf20Sopenharmony_ci            len(auth_cmd),
5798c2ecf20Sopenharmony_ci            bytes(auth_cmd),
5808c2ecf20Sopenharmony_ci            len(sensitive),
5818c2ecf20Sopenharmony_ci            bytes(sensitive),
5828c2ecf20Sopenharmony_ci            len(public),
5838c2ecf20Sopenharmony_ci            bytes(public),
5848c2ecf20Sopenharmony_ci            0, 0)
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_ci        return struct.unpack('>I', self.send_cmd(cmd)[10:14])[0]
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci    def seal(self, parent_key, data, auth_value, policy_dig,
5898c2ecf20Sopenharmony_ci             name_alg = TPM2_ALG_SHA1):
5908c2ecf20Sopenharmony_ci        ds = get_digest_size(name_alg)
5918c2ecf20Sopenharmony_ci        assert(not policy_dig or ds == len(policy_dig))
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_ci        attributes = 0
5948c2ecf20Sopenharmony_ci        if not policy_dig:
5958c2ecf20Sopenharmony_ci            attributes |= Public.USER_WITH_AUTH
5968c2ecf20Sopenharmony_ci            policy_dig = bytes()
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_ci        auth_cmd =  AuthCommand()
5998c2ecf20Sopenharmony_ci        sensitive = SensitiveCreate(user_auth=auth_value, data=data)
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_ci        public = Public(
6028c2ecf20Sopenharmony_ci            object_type=TPM2_ALG_KEYEDHASH,
6038c2ecf20Sopenharmony_ci            name_alg=name_alg,
6048c2ecf20Sopenharmony_ci            object_attributes=attributes,
6058c2ecf20Sopenharmony_ci            auth_policy=policy_dig,
6068c2ecf20Sopenharmony_ci            parameters=struct.pack('>H', TPM2_ALG_NULL))
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_ci        fmt = '>HIII I%us H%us H%us HI' % \
6098c2ecf20Sopenharmony_ci            (len(auth_cmd), len(sensitive), len(public))
6108c2ecf20Sopenharmony_ci        cmd = struct.pack(
6118c2ecf20Sopenharmony_ci            fmt,
6128c2ecf20Sopenharmony_ci            TPM2_ST_SESSIONS,
6138c2ecf20Sopenharmony_ci            struct.calcsize(fmt),
6148c2ecf20Sopenharmony_ci            TPM2_CC_CREATE,
6158c2ecf20Sopenharmony_ci            parent_key,
6168c2ecf20Sopenharmony_ci            len(auth_cmd),
6178c2ecf20Sopenharmony_ci            bytes(auth_cmd),
6188c2ecf20Sopenharmony_ci            len(sensitive),
6198c2ecf20Sopenharmony_ci            bytes(sensitive),
6208c2ecf20Sopenharmony_ci            len(public),
6218c2ecf20Sopenharmony_ci            bytes(public),
6228c2ecf20Sopenharmony_ci            0, 0)
6238c2ecf20Sopenharmony_ci
6248c2ecf20Sopenharmony_ci        rsp = self.send_cmd(cmd)
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci        return rsp[14:]
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_ci    def unseal(self, parent_key, blob, auth_value, policy_handle):
6298c2ecf20Sopenharmony_ci        private_len = struct.unpack('>H', blob[0:2])[0]
6308c2ecf20Sopenharmony_ci        public_start = private_len + 2
6318c2ecf20Sopenharmony_ci        public_len = struct.unpack('>H', blob[public_start:public_start + 2])[0]
6328c2ecf20Sopenharmony_ci        blob = blob[:private_len + public_len + 4]
6338c2ecf20Sopenharmony_ci
6348c2ecf20Sopenharmony_ci        auth_cmd = AuthCommand()
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_ci        fmt = '>HII I I%us %us' % (len(auth_cmd), len(blob))
6378c2ecf20Sopenharmony_ci        cmd = struct.pack(
6388c2ecf20Sopenharmony_ci            fmt,
6398c2ecf20Sopenharmony_ci            TPM2_ST_SESSIONS,
6408c2ecf20Sopenharmony_ci            struct.calcsize(fmt),
6418c2ecf20Sopenharmony_ci            TPM2_CC_LOAD,
6428c2ecf20Sopenharmony_ci            parent_key,
6438c2ecf20Sopenharmony_ci            len(auth_cmd),
6448c2ecf20Sopenharmony_ci            bytes(auth_cmd),
6458c2ecf20Sopenharmony_ci            blob)
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_ci        data_handle = struct.unpack('>I', self.send_cmd(cmd)[10:14])[0]
6488c2ecf20Sopenharmony_ci
6498c2ecf20Sopenharmony_ci        if policy_handle:
6508c2ecf20Sopenharmony_ci            auth_cmd = AuthCommand(session_handle=policy_handle, hmac=auth_value)
6518c2ecf20Sopenharmony_ci        else:
6528c2ecf20Sopenharmony_ci            auth_cmd = AuthCommand(hmac=auth_value)
6538c2ecf20Sopenharmony_ci
6548c2ecf20Sopenharmony_ci        fmt = '>HII I I%us' % (len(auth_cmd))
6558c2ecf20Sopenharmony_ci        cmd = struct.pack(
6568c2ecf20Sopenharmony_ci            fmt,
6578c2ecf20Sopenharmony_ci            TPM2_ST_SESSIONS,
6588c2ecf20Sopenharmony_ci            struct.calcsize(fmt),
6598c2ecf20Sopenharmony_ci            TPM2_CC_UNSEAL,
6608c2ecf20Sopenharmony_ci            data_handle,
6618c2ecf20Sopenharmony_ci            len(auth_cmd),
6628c2ecf20Sopenharmony_ci            bytes(auth_cmd))
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci        try:
6658c2ecf20Sopenharmony_ci            rsp = self.send_cmd(cmd)
6668c2ecf20Sopenharmony_ci        finally:
6678c2ecf20Sopenharmony_ci            self.flush_context(data_handle)
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_ci        data_len = struct.unpack('>I', rsp[10:14])[0] - 2
6708c2ecf20Sopenharmony_ci
6718c2ecf20Sopenharmony_ci        return rsp[16:16 + data_len]
6728c2ecf20Sopenharmony_ci
6738c2ecf20Sopenharmony_ci    def reset_da_lock(self):
6748c2ecf20Sopenharmony_ci        auth_cmd = AuthCommand()
6758c2ecf20Sopenharmony_ci
6768c2ecf20Sopenharmony_ci        fmt = '>HII I I%us' % (len(auth_cmd))
6778c2ecf20Sopenharmony_ci        cmd = struct.pack(
6788c2ecf20Sopenharmony_ci            fmt,
6798c2ecf20Sopenharmony_ci            TPM2_ST_SESSIONS,
6808c2ecf20Sopenharmony_ci            struct.calcsize(fmt),
6818c2ecf20Sopenharmony_ci            TPM2_CC_DICTIONARY_ATTACK_LOCK_RESET,
6828c2ecf20Sopenharmony_ci            TPM2_RH_LOCKOUT,
6838c2ecf20Sopenharmony_ci            len(auth_cmd),
6848c2ecf20Sopenharmony_ci            bytes(auth_cmd))
6858c2ecf20Sopenharmony_ci
6868c2ecf20Sopenharmony_ci        self.send_cmd(cmd)
6878c2ecf20Sopenharmony_ci
6888c2ecf20Sopenharmony_ci    def __get_cap_cnt(self, cap, pt, cnt):
6898c2ecf20Sopenharmony_ci        handles = []
6908c2ecf20Sopenharmony_ci        fmt = '>HII III'
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_ci        cmd = struct.pack(fmt,
6938c2ecf20Sopenharmony_ci                          TPM2_ST_NO_SESSIONS,
6948c2ecf20Sopenharmony_ci                          struct.calcsize(fmt),
6958c2ecf20Sopenharmony_ci                          TPM2_CC_GET_CAPABILITY,
6968c2ecf20Sopenharmony_ci                          cap, pt, cnt)
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci        rsp = self.send_cmd(cmd)[10:]
6998c2ecf20Sopenharmony_ci        more_data, cap, cnt = struct.unpack('>BII', rsp[:9])
7008c2ecf20Sopenharmony_ci        rsp = rsp[9:]
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_ci        for i in range(0, cnt):
7038c2ecf20Sopenharmony_ci            handle = struct.unpack('>I', rsp[:4])[0]
7048c2ecf20Sopenharmony_ci            handles.append(handle)
7058c2ecf20Sopenharmony_ci            rsp = rsp[4:]
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci        return handles, more_data
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci    def get_cap(self, cap, pt):
7108c2ecf20Sopenharmony_ci        handles = []
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_ci        more_data = True
7138c2ecf20Sopenharmony_ci        while more_data:
7148c2ecf20Sopenharmony_ci            next_handles, more_data = self.__get_cap_cnt(cap, pt, 1)
7158c2ecf20Sopenharmony_ci            handles += next_handles
7168c2ecf20Sopenharmony_ci            pt += 1
7178c2ecf20Sopenharmony_ci
7188c2ecf20Sopenharmony_ci        return handles
719