1*053f45beSAndroid Build Coastguard Worker# SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2*053f45beSAndroid Build Coastguard Worker 3*053f45beSAndroid Build Coastguard Workerimport hashlib 4*053f45beSAndroid Build Coastguard Workerimport os 5*053f45beSAndroid Build Coastguard Workerimport socket 6*053f45beSAndroid Build Coastguard Workerimport struct 7*053f45beSAndroid Build Coastguard Workerimport sys 8*053f45beSAndroid Build Coastguard Workerimport unittest 9*053f45beSAndroid Build Coastguard Workerimport fcntl 10*053f45beSAndroid Build Coastguard Workerimport select 11*053f45beSAndroid Build Coastguard Worker 12*053f45beSAndroid Build Coastguard WorkerTPM2_ST_NO_SESSIONS = 0x8001 13*053f45beSAndroid Build Coastguard WorkerTPM2_ST_SESSIONS = 0x8002 14*053f45beSAndroid Build Coastguard Worker 15*053f45beSAndroid Build Coastguard WorkerTPM2_CC_FIRST = 0x01FF 16*053f45beSAndroid Build Coastguard Worker 17*053f45beSAndroid Build Coastguard WorkerTPM2_CC_CREATE_PRIMARY = 0x0131 18*053f45beSAndroid Build Coastguard WorkerTPM2_CC_DICTIONARY_ATTACK_LOCK_RESET = 0x0139 19*053f45beSAndroid Build Coastguard WorkerTPM2_CC_CREATE = 0x0153 20*053f45beSAndroid Build Coastguard WorkerTPM2_CC_LOAD = 0x0157 21*053f45beSAndroid Build Coastguard WorkerTPM2_CC_UNSEAL = 0x015E 22*053f45beSAndroid Build Coastguard WorkerTPM2_CC_FLUSH_CONTEXT = 0x0165 23*053f45beSAndroid Build Coastguard WorkerTPM2_CC_START_AUTH_SESSION = 0x0176 24*053f45beSAndroid Build Coastguard WorkerTPM2_CC_GET_CAPABILITY = 0x017A 25*053f45beSAndroid Build Coastguard WorkerTPM2_CC_GET_RANDOM = 0x017B 26*053f45beSAndroid Build Coastguard WorkerTPM2_CC_PCR_READ = 0x017E 27*053f45beSAndroid Build Coastguard WorkerTPM2_CC_POLICY_PCR = 0x017F 28*053f45beSAndroid Build Coastguard WorkerTPM2_CC_PCR_EXTEND = 0x0182 29*053f45beSAndroid Build Coastguard WorkerTPM2_CC_POLICY_PASSWORD = 0x018C 30*053f45beSAndroid Build Coastguard WorkerTPM2_CC_POLICY_GET_DIGEST = 0x0189 31*053f45beSAndroid Build Coastguard Worker 32*053f45beSAndroid Build Coastguard WorkerTPM2_SE_POLICY = 0x01 33*053f45beSAndroid Build Coastguard WorkerTPM2_SE_TRIAL = 0x03 34*053f45beSAndroid Build Coastguard Worker 35*053f45beSAndroid Build Coastguard WorkerTPM2_ALG_RSA = 0x0001 36*053f45beSAndroid Build Coastguard WorkerTPM2_ALG_SHA1 = 0x0004 37*053f45beSAndroid Build Coastguard WorkerTPM2_ALG_AES = 0x0006 38*053f45beSAndroid Build Coastguard WorkerTPM2_ALG_KEYEDHASH = 0x0008 39*053f45beSAndroid Build Coastguard WorkerTPM2_ALG_SHA256 = 0x000B 40*053f45beSAndroid Build Coastguard WorkerTPM2_ALG_NULL = 0x0010 41*053f45beSAndroid Build Coastguard WorkerTPM2_ALG_CBC = 0x0042 42*053f45beSAndroid Build Coastguard WorkerTPM2_ALG_CFB = 0x0043 43*053f45beSAndroid Build Coastguard Worker 44*053f45beSAndroid Build Coastguard WorkerTPM2_RH_OWNER = 0x40000001 45*053f45beSAndroid Build Coastguard WorkerTPM2_RH_NULL = 0x40000007 46*053f45beSAndroid Build Coastguard WorkerTPM2_RH_LOCKOUT = 0x4000000A 47*053f45beSAndroid Build Coastguard WorkerTPM2_RS_PW = 0x40000009 48*053f45beSAndroid Build Coastguard Worker 49*053f45beSAndroid Build Coastguard WorkerTPM2_RC_SIZE = 0x01D5 50*053f45beSAndroid Build Coastguard WorkerTPM2_RC_AUTH_FAIL = 0x098E 51*053f45beSAndroid Build Coastguard WorkerTPM2_RC_POLICY_FAIL = 0x099D 52*053f45beSAndroid Build Coastguard WorkerTPM2_RC_COMMAND_CODE = 0x0143 53*053f45beSAndroid Build Coastguard Worker 54*053f45beSAndroid Build Coastguard WorkerTSS2_RC_LAYER_SHIFT = 16 55*053f45beSAndroid Build Coastguard WorkerTSS2_RESMGR_TPM_RC_LAYER = (11 << TSS2_RC_LAYER_SHIFT) 56*053f45beSAndroid Build Coastguard Worker 57*053f45beSAndroid Build Coastguard WorkerTPM2_CAP_HANDLES = 0x00000001 58*053f45beSAndroid Build Coastguard WorkerTPM2_CAP_COMMANDS = 0x00000002 59*053f45beSAndroid Build Coastguard WorkerTPM2_CAP_PCRS = 0x00000005 60*053f45beSAndroid Build Coastguard WorkerTPM2_CAP_TPM_PROPERTIES = 0x00000006 61*053f45beSAndroid Build Coastguard Worker 62*053f45beSAndroid Build Coastguard WorkerTPM2_PT_FIXED = 0x100 63*053f45beSAndroid Build Coastguard WorkerTPM2_PT_TOTAL_COMMANDS = TPM2_PT_FIXED + 41 64*053f45beSAndroid Build Coastguard Worker 65*053f45beSAndroid Build Coastguard WorkerHR_SHIFT = 24 66*053f45beSAndroid Build Coastguard WorkerHR_LOADED_SESSION = 0x02000000 67*053f45beSAndroid Build Coastguard WorkerHR_TRANSIENT = 0x80000000 68*053f45beSAndroid Build Coastguard Worker 69*053f45beSAndroid Build Coastguard WorkerSHA1_DIGEST_SIZE = 20 70*053f45beSAndroid Build Coastguard WorkerSHA256_DIGEST_SIZE = 32 71*053f45beSAndroid Build Coastguard Worker 72*053f45beSAndroid Build Coastguard WorkerTPM2_VER0_ERRORS = { 73*053f45beSAndroid Build Coastguard Worker 0x000: "TPM_RC_SUCCESS", 74*053f45beSAndroid Build Coastguard Worker 0x030: "TPM_RC_BAD_TAG", 75*053f45beSAndroid Build Coastguard Worker} 76*053f45beSAndroid Build Coastguard Worker 77*053f45beSAndroid Build Coastguard WorkerTPM2_VER1_ERRORS = { 78*053f45beSAndroid Build Coastguard Worker 0x000: "TPM_RC_FAILURE", 79*053f45beSAndroid Build Coastguard Worker 0x001: "TPM_RC_FAILURE", 80*053f45beSAndroid Build Coastguard Worker 0x003: "TPM_RC_SEQUENCE", 81*053f45beSAndroid Build Coastguard Worker 0x00B: "TPM_RC_PRIVATE", 82*053f45beSAndroid Build Coastguard Worker 0x019: "TPM_RC_HMAC", 83*053f45beSAndroid Build Coastguard Worker 0x020: "TPM_RC_DISABLED", 84*053f45beSAndroid Build Coastguard Worker 0x021: "TPM_RC_EXCLUSIVE", 85*053f45beSAndroid Build Coastguard Worker 0x024: "TPM_RC_AUTH_TYPE", 86*053f45beSAndroid Build Coastguard Worker 0x025: "TPM_RC_AUTH_MISSING", 87*053f45beSAndroid Build Coastguard Worker 0x026: "TPM_RC_POLICY", 88*053f45beSAndroid Build Coastguard Worker 0x027: "TPM_RC_PCR", 89*053f45beSAndroid Build Coastguard Worker 0x028: "TPM_RC_PCR_CHANGED", 90*053f45beSAndroid Build Coastguard Worker 0x02D: "TPM_RC_UPGRADE", 91*053f45beSAndroid Build Coastguard Worker 0x02E: "TPM_RC_TOO_MANY_CONTEXTS", 92*053f45beSAndroid Build Coastguard Worker 0x02F: "TPM_RC_AUTH_UNAVAILABLE", 93*053f45beSAndroid Build Coastguard Worker 0x030: "TPM_RC_REBOOT", 94*053f45beSAndroid Build Coastguard Worker 0x031: "TPM_RC_UNBALANCED", 95*053f45beSAndroid Build Coastguard Worker 0x042: "TPM_RC_COMMAND_SIZE", 96*053f45beSAndroid Build Coastguard Worker 0x043: "TPM_RC_COMMAND_CODE", 97*053f45beSAndroid Build Coastguard Worker 0x044: "TPM_RC_AUTHSIZE", 98*053f45beSAndroid Build Coastguard Worker 0x045: "TPM_RC_AUTH_CONTEXT", 99*053f45beSAndroid Build Coastguard Worker 0x046: "TPM_RC_NV_RANGE", 100*053f45beSAndroid Build Coastguard Worker 0x047: "TPM_RC_NV_SIZE", 101*053f45beSAndroid Build Coastguard Worker 0x048: "TPM_RC_NV_LOCKED", 102*053f45beSAndroid Build Coastguard Worker 0x049: "TPM_RC_NV_AUTHORIZATION", 103*053f45beSAndroid Build Coastguard Worker 0x04A: "TPM_RC_NV_UNINITIALIZED", 104*053f45beSAndroid Build Coastguard Worker 0x04B: "TPM_RC_NV_SPACE", 105*053f45beSAndroid Build Coastguard Worker 0x04C: "TPM_RC_NV_DEFINED", 106*053f45beSAndroid Build Coastguard Worker 0x050: "TPM_RC_BAD_CONTEXT", 107*053f45beSAndroid Build Coastguard Worker 0x051: "TPM_RC_CPHASH", 108*053f45beSAndroid Build Coastguard Worker 0x052: "TPM_RC_PARENT", 109*053f45beSAndroid Build Coastguard Worker 0x053: "TPM_RC_NEEDS_TEST", 110*053f45beSAndroid Build Coastguard Worker 0x054: "TPM_RC_NO_RESULT", 111*053f45beSAndroid Build Coastguard Worker 0x055: "TPM_RC_SENSITIVE", 112*053f45beSAndroid Build Coastguard Worker 0x07F: "RC_MAX_FM0", 113*053f45beSAndroid Build Coastguard Worker} 114*053f45beSAndroid Build Coastguard Worker 115*053f45beSAndroid Build Coastguard WorkerTPM2_FMT1_ERRORS = { 116*053f45beSAndroid Build Coastguard Worker 0x001: "TPM_RC_ASYMMETRIC", 117*053f45beSAndroid Build Coastguard Worker 0x002: "TPM_RC_ATTRIBUTES", 118*053f45beSAndroid Build Coastguard Worker 0x003: "TPM_RC_HASH", 119*053f45beSAndroid Build Coastguard Worker 0x004: "TPM_RC_VALUE", 120*053f45beSAndroid Build Coastguard Worker 0x005: "TPM_RC_HIERARCHY", 121*053f45beSAndroid Build Coastguard Worker 0x007: "TPM_RC_KEY_SIZE", 122*053f45beSAndroid Build Coastguard Worker 0x008: "TPM_RC_MGF", 123*053f45beSAndroid Build Coastguard Worker 0x009: "TPM_RC_MODE", 124*053f45beSAndroid Build Coastguard Worker 0x00A: "TPM_RC_TYPE", 125*053f45beSAndroid Build Coastguard Worker 0x00B: "TPM_RC_HANDLE", 126*053f45beSAndroid Build Coastguard Worker 0x00C: "TPM_RC_KDF", 127*053f45beSAndroid Build Coastguard Worker 0x00D: "TPM_RC_RANGE", 128*053f45beSAndroid Build Coastguard Worker 0x00E: "TPM_RC_AUTH_FAIL", 129*053f45beSAndroid Build Coastguard Worker 0x00F: "TPM_RC_NONCE", 130*053f45beSAndroid Build Coastguard Worker 0x010: "TPM_RC_PP", 131*053f45beSAndroid Build Coastguard Worker 0x012: "TPM_RC_SCHEME", 132*053f45beSAndroid Build Coastguard Worker 0x015: "TPM_RC_SIZE", 133*053f45beSAndroid Build Coastguard Worker 0x016: "TPM_RC_SYMMETRIC", 134*053f45beSAndroid Build Coastguard Worker 0x017: "TPM_RC_TAG", 135*053f45beSAndroid Build Coastguard Worker 0x018: "TPM_RC_SELECTOR", 136*053f45beSAndroid Build Coastguard Worker 0x01A: "TPM_RC_INSUFFICIENT", 137*053f45beSAndroid Build Coastguard Worker 0x01B: "TPM_RC_SIGNATURE", 138*053f45beSAndroid Build Coastguard Worker 0x01C: "TPM_RC_KEY", 139*053f45beSAndroid Build Coastguard Worker 0x01D: "TPM_RC_POLICY_FAIL", 140*053f45beSAndroid Build Coastguard Worker 0x01F: "TPM_RC_INTEGRITY", 141*053f45beSAndroid Build Coastguard Worker 0x020: "TPM_RC_TICKET", 142*053f45beSAndroid Build Coastguard Worker 0x021: "TPM_RC_RESERVED_BITS", 143*053f45beSAndroid Build Coastguard Worker 0x022: "TPM_RC_BAD_AUTH", 144*053f45beSAndroid Build Coastguard Worker 0x023: "TPM_RC_EXPIRED", 145*053f45beSAndroid Build Coastguard Worker 0x024: "TPM_RC_POLICY_CC", 146*053f45beSAndroid Build Coastguard Worker 0x025: "TPM_RC_BINDING", 147*053f45beSAndroid Build Coastguard Worker 0x026: "TPM_RC_CURVE", 148*053f45beSAndroid Build Coastguard Worker 0x027: "TPM_RC_ECC_POINT", 149*053f45beSAndroid Build Coastguard Worker} 150*053f45beSAndroid Build Coastguard Worker 151*053f45beSAndroid Build Coastguard WorkerTPM2_WARN_ERRORS = { 152*053f45beSAndroid Build Coastguard Worker 0x001: "TPM_RC_CONTEXT_GAP", 153*053f45beSAndroid Build Coastguard Worker 0x002: "TPM_RC_OBJECT_MEMORY", 154*053f45beSAndroid Build Coastguard Worker 0x003: "TPM_RC_SESSION_MEMORY", 155*053f45beSAndroid Build Coastguard Worker 0x004: "TPM_RC_MEMORY", 156*053f45beSAndroid Build Coastguard Worker 0x005: "TPM_RC_SESSION_HANDLES", 157*053f45beSAndroid Build Coastguard Worker 0x006: "TPM_RC_OBJECT_HANDLES", 158*053f45beSAndroid Build Coastguard Worker 0x007: "TPM_RC_LOCALITY", 159*053f45beSAndroid Build Coastguard Worker 0x008: "TPM_RC_YIELDED", 160*053f45beSAndroid Build Coastguard Worker 0x009: "TPM_RC_CANCELED", 161*053f45beSAndroid Build Coastguard Worker 0x00A: "TPM_RC_TESTING", 162*053f45beSAndroid Build Coastguard Worker 0x010: "TPM_RC_REFERENCE_H0", 163*053f45beSAndroid Build Coastguard Worker 0x011: "TPM_RC_REFERENCE_H1", 164*053f45beSAndroid Build Coastguard Worker 0x012: "TPM_RC_REFERENCE_H2", 165*053f45beSAndroid Build Coastguard Worker 0x013: "TPM_RC_REFERENCE_H3", 166*053f45beSAndroid Build Coastguard Worker 0x014: "TPM_RC_REFERENCE_H4", 167*053f45beSAndroid Build Coastguard Worker 0x015: "TPM_RC_REFERENCE_H5", 168*053f45beSAndroid Build Coastguard Worker 0x016: "TPM_RC_REFERENCE_H6", 169*053f45beSAndroid Build Coastguard Worker 0x018: "TPM_RC_REFERENCE_S0", 170*053f45beSAndroid Build Coastguard Worker 0x019: "TPM_RC_REFERENCE_S1", 171*053f45beSAndroid Build Coastguard Worker 0x01A: "TPM_RC_REFERENCE_S2", 172*053f45beSAndroid Build Coastguard Worker 0x01B: "TPM_RC_REFERENCE_S3", 173*053f45beSAndroid Build Coastguard Worker 0x01C: "TPM_RC_REFERENCE_S4", 174*053f45beSAndroid Build Coastguard Worker 0x01D: "TPM_RC_REFERENCE_S5", 175*053f45beSAndroid Build Coastguard Worker 0x01E: "TPM_RC_REFERENCE_S6", 176*053f45beSAndroid Build Coastguard Worker 0x020: "TPM_RC_NV_RATE", 177*053f45beSAndroid Build Coastguard Worker 0x021: "TPM_RC_LOCKOUT", 178*053f45beSAndroid Build Coastguard Worker 0x022: "TPM_RC_RETRY", 179*053f45beSAndroid Build Coastguard Worker 0x023: "TPM_RC_NV_UNAVAILABLE", 180*053f45beSAndroid Build Coastguard Worker 0x7F: "TPM_RC_NOT_USED", 181*053f45beSAndroid Build Coastguard Worker} 182*053f45beSAndroid Build Coastguard Worker 183*053f45beSAndroid Build Coastguard WorkerRC_VER1 = 0x100 184*053f45beSAndroid Build Coastguard WorkerRC_FMT1 = 0x080 185*053f45beSAndroid Build Coastguard WorkerRC_WARN = 0x900 186*053f45beSAndroid Build Coastguard Worker 187*053f45beSAndroid Build Coastguard WorkerALG_DIGEST_SIZE_MAP = { 188*053f45beSAndroid Build Coastguard Worker TPM2_ALG_SHA1: SHA1_DIGEST_SIZE, 189*053f45beSAndroid Build Coastguard Worker TPM2_ALG_SHA256: SHA256_DIGEST_SIZE, 190*053f45beSAndroid Build Coastguard Worker} 191*053f45beSAndroid Build Coastguard Worker 192*053f45beSAndroid Build Coastguard WorkerALG_HASH_FUNCTION_MAP = { 193*053f45beSAndroid Build Coastguard Worker TPM2_ALG_SHA1: hashlib.sha1, 194*053f45beSAndroid Build Coastguard Worker TPM2_ALG_SHA256: hashlib.sha256 195*053f45beSAndroid Build Coastguard Worker} 196*053f45beSAndroid Build Coastguard Worker 197*053f45beSAndroid Build Coastguard WorkerNAME_ALG_MAP = { 198*053f45beSAndroid Build Coastguard Worker "sha1": TPM2_ALG_SHA1, 199*053f45beSAndroid Build Coastguard Worker "sha256": TPM2_ALG_SHA256, 200*053f45beSAndroid Build Coastguard Worker} 201*053f45beSAndroid Build Coastguard Worker 202*053f45beSAndroid Build Coastguard Worker 203*053f45beSAndroid Build Coastguard Workerclass UnknownAlgorithmIdError(Exception): 204*053f45beSAndroid Build Coastguard Worker def __init__(self, alg): 205*053f45beSAndroid Build Coastguard Worker self.alg = alg 206*053f45beSAndroid Build Coastguard Worker 207*053f45beSAndroid Build Coastguard Worker def __str__(self): 208*053f45beSAndroid Build Coastguard Worker return '0x%0x' % (alg) 209*053f45beSAndroid Build Coastguard Worker 210*053f45beSAndroid Build Coastguard Worker 211*053f45beSAndroid Build Coastguard Workerclass UnknownAlgorithmNameError(Exception): 212*053f45beSAndroid Build Coastguard Worker def __init__(self, name): 213*053f45beSAndroid Build Coastguard Worker self.name = name 214*053f45beSAndroid Build Coastguard Worker 215*053f45beSAndroid Build Coastguard Worker def __str__(self): 216*053f45beSAndroid Build Coastguard Worker return name 217*053f45beSAndroid Build Coastguard Worker 218*053f45beSAndroid Build Coastguard Worker 219*053f45beSAndroid Build Coastguard Workerclass UnknownPCRBankError(Exception): 220*053f45beSAndroid Build Coastguard Worker def __init__(self, alg): 221*053f45beSAndroid Build Coastguard Worker self.alg = alg 222*053f45beSAndroid Build Coastguard Worker 223*053f45beSAndroid Build Coastguard Worker def __str__(self): 224*053f45beSAndroid Build Coastguard Worker return '0x%0x' % (alg) 225*053f45beSAndroid Build Coastguard Worker 226*053f45beSAndroid Build Coastguard Worker 227*053f45beSAndroid Build Coastguard Workerclass ProtocolError(Exception): 228*053f45beSAndroid Build Coastguard Worker def __init__(self, cc, rc): 229*053f45beSAndroid Build Coastguard Worker self.cc = cc 230*053f45beSAndroid Build Coastguard Worker self.rc = rc 231*053f45beSAndroid Build Coastguard Worker 232*053f45beSAndroid Build Coastguard Worker if (rc & RC_FMT1) == RC_FMT1: 233*053f45beSAndroid Build Coastguard Worker self.name = TPM2_FMT1_ERRORS.get(rc & 0x3f, "TPM_RC_UNKNOWN") 234*053f45beSAndroid Build Coastguard Worker elif (rc & RC_WARN) == RC_WARN: 235*053f45beSAndroid Build Coastguard Worker self.name = TPM2_WARN_ERRORS.get(rc & 0x7f, "TPM_RC_UNKNOWN") 236*053f45beSAndroid Build Coastguard Worker elif (rc & RC_VER1) == RC_VER1: 237*053f45beSAndroid Build Coastguard Worker self.name = TPM2_VER1_ERRORS.get(rc & 0x7f, "TPM_RC_UNKNOWN") 238*053f45beSAndroid Build Coastguard Worker else: 239*053f45beSAndroid Build Coastguard Worker self.name = TPM2_VER0_ERRORS.get(rc & 0x7f, "TPM_RC_UNKNOWN") 240*053f45beSAndroid Build Coastguard Worker 241*053f45beSAndroid Build Coastguard Worker def __str__(self): 242*053f45beSAndroid Build Coastguard Worker if self.cc: 243*053f45beSAndroid Build Coastguard Worker return '%s: cc=0x%08x, rc=0x%08x' % (self.name, self.cc, self.rc) 244*053f45beSAndroid Build Coastguard Worker else: 245*053f45beSAndroid Build Coastguard Worker return '%s: rc=0x%08x' % (self.name, self.rc) 246*053f45beSAndroid Build Coastguard Worker 247*053f45beSAndroid Build Coastguard Worker 248*053f45beSAndroid Build Coastguard Workerclass AuthCommand(object): 249*053f45beSAndroid Build Coastguard Worker """TPMS_AUTH_COMMAND""" 250*053f45beSAndroid Build Coastguard Worker 251*053f45beSAndroid Build Coastguard Worker def __init__(self, session_handle=TPM2_RS_PW, nonce=bytes(), 252*053f45beSAndroid Build Coastguard Worker session_attributes=0, hmac=bytes()): 253*053f45beSAndroid Build Coastguard Worker self.session_handle = session_handle 254*053f45beSAndroid Build Coastguard Worker self.nonce = nonce 255*053f45beSAndroid Build Coastguard Worker self.session_attributes = session_attributes 256*053f45beSAndroid Build Coastguard Worker self.hmac = hmac 257*053f45beSAndroid Build Coastguard Worker 258*053f45beSAndroid Build Coastguard Worker def __bytes__(self): 259*053f45beSAndroid Build Coastguard Worker fmt = '>I H%us B H%us' % (len(self.nonce), len(self.hmac)) 260*053f45beSAndroid Build Coastguard Worker return struct.pack(fmt, self.session_handle, len(self.nonce), 261*053f45beSAndroid Build Coastguard Worker self.nonce, self.session_attributes, len(self.hmac), 262*053f45beSAndroid Build Coastguard Worker self.hmac) 263*053f45beSAndroid Build Coastguard Worker 264*053f45beSAndroid Build Coastguard Worker def __len__(self): 265*053f45beSAndroid Build Coastguard Worker fmt = '>I H%us B H%us' % (len(self.nonce), len(self.hmac)) 266*053f45beSAndroid Build Coastguard Worker return struct.calcsize(fmt) 267*053f45beSAndroid Build Coastguard Worker 268*053f45beSAndroid Build Coastguard Worker 269*053f45beSAndroid Build Coastguard Workerclass SensitiveCreate(object): 270*053f45beSAndroid Build Coastguard Worker """TPMS_SENSITIVE_CREATE""" 271*053f45beSAndroid Build Coastguard Worker 272*053f45beSAndroid Build Coastguard Worker def __init__(self, user_auth=bytes(), data=bytes()): 273*053f45beSAndroid Build Coastguard Worker self.user_auth = user_auth 274*053f45beSAndroid Build Coastguard Worker self.data = data 275*053f45beSAndroid Build Coastguard Worker 276*053f45beSAndroid Build Coastguard Worker def __bytes__(self): 277*053f45beSAndroid Build Coastguard Worker fmt = '>H%us H%us' % (len(self.user_auth), len(self.data)) 278*053f45beSAndroid Build Coastguard Worker return struct.pack(fmt, len(self.user_auth), self.user_auth, 279*053f45beSAndroid Build Coastguard Worker len(self.data), self.data) 280*053f45beSAndroid Build Coastguard Worker 281*053f45beSAndroid Build Coastguard Worker def __len__(self): 282*053f45beSAndroid Build Coastguard Worker fmt = '>H%us H%us' % (len(self.user_auth), len(self.data)) 283*053f45beSAndroid Build Coastguard Worker return struct.calcsize(fmt) 284*053f45beSAndroid Build Coastguard Worker 285*053f45beSAndroid Build Coastguard Worker 286*053f45beSAndroid Build Coastguard Workerclass Public(object): 287*053f45beSAndroid Build Coastguard Worker """TPMT_PUBLIC""" 288*053f45beSAndroid Build Coastguard Worker 289*053f45beSAndroid Build Coastguard Worker FIXED_TPM = (1 << 1) 290*053f45beSAndroid Build Coastguard Worker FIXED_PARENT = (1 << 4) 291*053f45beSAndroid Build Coastguard Worker SENSITIVE_DATA_ORIGIN = (1 << 5) 292*053f45beSAndroid Build Coastguard Worker USER_WITH_AUTH = (1 << 6) 293*053f45beSAndroid Build Coastguard Worker RESTRICTED = (1 << 16) 294*053f45beSAndroid Build Coastguard Worker DECRYPT = (1 << 17) 295*053f45beSAndroid Build Coastguard Worker 296*053f45beSAndroid Build Coastguard Worker def __fmt(self): 297*053f45beSAndroid Build Coastguard Worker return '>HHIH%us%usH%us' % \ 298*053f45beSAndroid Build Coastguard Worker (len(self.auth_policy), len(self.parameters), len(self.unique)) 299*053f45beSAndroid Build Coastguard Worker 300*053f45beSAndroid Build Coastguard Worker def __init__(self, object_type, name_alg, object_attributes, 301*053f45beSAndroid Build Coastguard Worker auth_policy=bytes(), parameters=bytes(), 302*053f45beSAndroid Build Coastguard Worker unique=bytes()): 303*053f45beSAndroid Build Coastguard Worker self.object_type = object_type 304*053f45beSAndroid Build Coastguard Worker self.name_alg = name_alg 305*053f45beSAndroid Build Coastguard Worker self.object_attributes = object_attributes 306*053f45beSAndroid Build Coastguard Worker self.auth_policy = auth_policy 307*053f45beSAndroid Build Coastguard Worker self.parameters = parameters 308*053f45beSAndroid Build Coastguard Worker self.unique = unique 309*053f45beSAndroid Build Coastguard Worker 310*053f45beSAndroid Build Coastguard Worker def __bytes__(self): 311*053f45beSAndroid Build Coastguard Worker return struct.pack(self.__fmt(), 312*053f45beSAndroid Build Coastguard Worker self.object_type, 313*053f45beSAndroid Build Coastguard Worker self.name_alg, 314*053f45beSAndroid Build Coastguard Worker self.object_attributes, 315*053f45beSAndroid Build Coastguard Worker len(self.auth_policy), 316*053f45beSAndroid Build Coastguard Worker self.auth_policy, 317*053f45beSAndroid Build Coastguard Worker self.parameters, 318*053f45beSAndroid Build Coastguard Worker len(self.unique), 319*053f45beSAndroid Build Coastguard Worker self.unique) 320*053f45beSAndroid Build Coastguard Worker 321*053f45beSAndroid Build Coastguard Worker def __len__(self): 322*053f45beSAndroid Build Coastguard Worker return struct.calcsize(self.__fmt()) 323*053f45beSAndroid Build Coastguard Worker 324*053f45beSAndroid Build Coastguard Worker 325*053f45beSAndroid Build Coastguard Workerdef get_digest_size(alg): 326*053f45beSAndroid Build Coastguard Worker ds = ALG_DIGEST_SIZE_MAP.get(alg) 327*053f45beSAndroid Build Coastguard Worker if not ds: 328*053f45beSAndroid Build Coastguard Worker raise UnknownAlgorithmIdError(alg) 329*053f45beSAndroid Build Coastguard Worker return ds 330*053f45beSAndroid Build Coastguard Worker 331*053f45beSAndroid Build Coastguard Worker 332*053f45beSAndroid Build Coastguard Workerdef get_hash_function(alg): 333*053f45beSAndroid Build Coastguard Worker f = ALG_HASH_FUNCTION_MAP.get(alg) 334*053f45beSAndroid Build Coastguard Worker if not f: 335*053f45beSAndroid Build Coastguard Worker raise UnknownAlgorithmIdError(alg) 336*053f45beSAndroid Build Coastguard Worker return f 337*053f45beSAndroid Build Coastguard Worker 338*053f45beSAndroid Build Coastguard Worker 339*053f45beSAndroid Build Coastguard Workerdef get_algorithm(name): 340*053f45beSAndroid Build Coastguard Worker alg = NAME_ALG_MAP.get(name) 341*053f45beSAndroid Build Coastguard Worker if not alg: 342*053f45beSAndroid Build Coastguard Worker raise UnknownAlgorithmNameError(name) 343*053f45beSAndroid Build Coastguard Worker return alg 344*053f45beSAndroid Build Coastguard Worker 345*053f45beSAndroid Build Coastguard Worker 346*053f45beSAndroid Build Coastguard Workerdef hex_dump(d): 347*053f45beSAndroid Build Coastguard Worker d = [format(ord(x), '02x') for x in d] 348*053f45beSAndroid Build Coastguard Worker d = [d[i: i + 16] for i in range(0, len(d), 16)] 349*053f45beSAndroid Build Coastguard Worker d = [' '.join(x) for x in d] 350*053f45beSAndroid Build Coastguard Worker d = os.linesep.join(d) 351*053f45beSAndroid Build Coastguard Worker 352*053f45beSAndroid Build Coastguard Worker return d 353*053f45beSAndroid Build Coastguard Worker 354*053f45beSAndroid Build Coastguard Workerclass Client: 355*053f45beSAndroid Build Coastguard Worker FLAG_DEBUG = 0x01 356*053f45beSAndroid Build Coastguard Worker FLAG_SPACE = 0x02 357*053f45beSAndroid Build Coastguard Worker FLAG_NONBLOCK = 0x04 358*053f45beSAndroid Build Coastguard Worker TPM_IOC_NEW_SPACE = 0xa200 359*053f45beSAndroid Build Coastguard Worker 360*053f45beSAndroid Build Coastguard Worker def __init__(self, flags = 0): 361*053f45beSAndroid Build Coastguard Worker self.flags = flags 362*053f45beSAndroid Build Coastguard Worker 363*053f45beSAndroid Build Coastguard Worker if (self.flags & Client.FLAG_SPACE) == 0: 364*053f45beSAndroid Build Coastguard Worker self.tpm = open('/dev/tpm0', 'r+b', buffering=0) 365*053f45beSAndroid Build Coastguard Worker else: 366*053f45beSAndroid Build Coastguard Worker self.tpm = open('/dev/tpmrm0', 'r+b', buffering=0) 367*053f45beSAndroid Build Coastguard Worker 368*053f45beSAndroid Build Coastguard Worker if (self.flags & Client.FLAG_NONBLOCK): 369*053f45beSAndroid Build Coastguard Worker flags = fcntl.fcntl(self.tpm, fcntl.F_GETFL) 370*053f45beSAndroid Build Coastguard Worker flags |= os.O_NONBLOCK 371*053f45beSAndroid Build Coastguard Worker fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags) 372*053f45beSAndroid Build Coastguard Worker self.tpm_poll = select.poll() 373*053f45beSAndroid Build Coastguard Worker 374*053f45beSAndroid Build Coastguard Worker def __del__(self): 375*053f45beSAndroid Build Coastguard Worker if self.tpm: 376*053f45beSAndroid Build Coastguard Worker self.tpm.close() 377*053f45beSAndroid Build Coastguard Worker 378*053f45beSAndroid Build Coastguard Worker def close(self): 379*053f45beSAndroid Build Coastguard Worker self.tpm.close() 380*053f45beSAndroid Build Coastguard Worker 381*053f45beSAndroid Build Coastguard Worker def send_cmd(self, cmd): 382*053f45beSAndroid Build Coastguard Worker self.tpm.write(cmd) 383*053f45beSAndroid Build Coastguard Worker 384*053f45beSAndroid Build Coastguard Worker if (self.flags & Client.FLAG_NONBLOCK): 385*053f45beSAndroid Build Coastguard Worker self.tpm_poll.register(self.tpm, select.POLLIN) 386*053f45beSAndroid Build Coastguard Worker self.tpm_poll.poll(10000) 387*053f45beSAndroid Build Coastguard Worker 388*053f45beSAndroid Build Coastguard Worker rsp = self.tpm.read() 389*053f45beSAndroid Build Coastguard Worker 390*053f45beSAndroid Build Coastguard Worker if (self.flags & Client.FLAG_NONBLOCK): 391*053f45beSAndroid Build Coastguard Worker self.tpm_poll.unregister(self.tpm) 392*053f45beSAndroid Build Coastguard Worker 393*053f45beSAndroid Build Coastguard Worker if (self.flags & Client.FLAG_DEBUG) != 0: 394*053f45beSAndroid Build Coastguard Worker sys.stderr.write('cmd' + os.linesep) 395*053f45beSAndroid Build Coastguard Worker sys.stderr.write(hex_dump(cmd) + os.linesep) 396*053f45beSAndroid Build Coastguard Worker sys.stderr.write('rsp' + os.linesep) 397*053f45beSAndroid Build Coastguard Worker sys.stderr.write(hex_dump(rsp) + os.linesep) 398*053f45beSAndroid Build Coastguard Worker 399*053f45beSAndroid Build Coastguard Worker rc = struct.unpack('>I', rsp[6:10])[0] 400*053f45beSAndroid Build Coastguard Worker if rc != 0: 401*053f45beSAndroid Build Coastguard Worker cc = struct.unpack('>I', cmd[6:10])[0] 402*053f45beSAndroid Build Coastguard Worker raise ProtocolError(cc, rc) 403*053f45beSAndroid Build Coastguard Worker 404*053f45beSAndroid Build Coastguard Worker return rsp 405*053f45beSAndroid Build Coastguard Worker 406*053f45beSAndroid Build Coastguard Worker def read_pcr(self, i, bank_alg = TPM2_ALG_SHA1): 407*053f45beSAndroid Build Coastguard Worker pcrsel_len = max((i >> 3) + 1, 3) 408*053f45beSAndroid Build Coastguard Worker pcrsel = [0] * pcrsel_len 409*053f45beSAndroid Build Coastguard Worker pcrsel[i >> 3] = 1 << (i & 7) 410*053f45beSAndroid Build Coastguard Worker pcrsel = ''.join(map(chr, pcrsel)).encode() 411*053f45beSAndroid Build Coastguard Worker 412*053f45beSAndroid Build Coastguard Worker fmt = '>HII IHB%us' % (pcrsel_len) 413*053f45beSAndroid Build Coastguard Worker cmd = struct.pack(fmt, 414*053f45beSAndroid Build Coastguard Worker TPM2_ST_NO_SESSIONS, 415*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 416*053f45beSAndroid Build Coastguard Worker TPM2_CC_PCR_READ, 417*053f45beSAndroid Build Coastguard Worker 1, 418*053f45beSAndroid Build Coastguard Worker bank_alg, 419*053f45beSAndroid Build Coastguard Worker pcrsel_len, pcrsel) 420*053f45beSAndroid Build Coastguard Worker 421*053f45beSAndroid Build Coastguard Worker rsp = self.send_cmd(cmd) 422*053f45beSAndroid Build Coastguard Worker 423*053f45beSAndroid Build Coastguard Worker pcr_update_cnt, pcr_select_cnt = struct.unpack('>II', rsp[10:18]) 424*053f45beSAndroid Build Coastguard Worker assert pcr_select_cnt == 1 425*053f45beSAndroid Build Coastguard Worker rsp = rsp[18:] 426*053f45beSAndroid Build Coastguard Worker 427*053f45beSAndroid Build Coastguard Worker alg2, pcrsel_len2 = struct.unpack('>HB', rsp[:3]) 428*053f45beSAndroid Build Coastguard Worker assert bank_alg == alg2 and pcrsel_len == pcrsel_len2 429*053f45beSAndroid Build Coastguard Worker rsp = rsp[3 + pcrsel_len:] 430*053f45beSAndroid Build Coastguard Worker 431*053f45beSAndroid Build Coastguard Worker digest_cnt = struct.unpack('>I', rsp[:4])[0] 432*053f45beSAndroid Build Coastguard Worker if digest_cnt == 0: 433*053f45beSAndroid Build Coastguard Worker return None 434*053f45beSAndroid Build Coastguard Worker rsp = rsp[6:] 435*053f45beSAndroid Build Coastguard Worker 436*053f45beSAndroid Build Coastguard Worker return rsp 437*053f45beSAndroid Build Coastguard Worker 438*053f45beSAndroid Build Coastguard Worker def extend_pcr(self, i, dig, bank_alg = TPM2_ALG_SHA1): 439*053f45beSAndroid Build Coastguard Worker ds = get_digest_size(bank_alg) 440*053f45beSAndroid Build Coastguard Worker assert(ds == len(dig)) 441*053f45beSAndroid Build Coastguard Worker 442*053f45beSAndroid Build Coastguard Worker auth_cmd = AuthCommand() 443*053f45beSAndroid Build Coastguard Worker 444*053f45beSAndroid Build Coastguard Worker fmt = '>HII I I%us IH%us' % (len(auth_cmd), ds) 445*053f45beSAndroid Build Coastguard Worker cmd = struct.pack( 446*053f45beSAndroid Build Coastguard Worker fmt, 447*053f45beSAndroid Build Coastguard Worker TPM2_ST_SESSIONS, 448*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 449*053f45beSAndroid Build Coastguard Worker TPM2_CC_PCR_EXTEND, 450*053f45beSAndroid Build Coastguard Worker i, 451*053f45beSAndroid Build Coastguard Worker len(auth_cmd), 452*053f45beSAndroid Build Coastguard Worker bytes(auth_cmd), 453*053f45beSAndroid Build Coastguard Worker 1, bank_alg, dig) 454*053f45beSAndroid Build Coastguard Worker 455*053f45beSAndroid Build Coastguard Worker self.send_cmd(cmd) 456*053f45beSAndroid Build Coastguard Worker 457*053f45beSAndroid Build Coastguard Worker def start_auth_session(self, session_type, name_alg = TPM2_ALG_SHA1): 458*053f45beSAndroid Build Coastguard Worker fmt = '>HII IIH16sHBHH' 459*053f45beSAndroid Build Coastguard Worker cmd = struct.pack(fmt, 460*053f45beSAndroid Build Coastguard Worker TPM2_ST_NO_SESSIONS, 461*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 462*053f45beSAndroid Build Coastguard Worker TPM2_CC_START_AUTH_SESSION, 463*053f45beSAndroid Build Coastguard Worker TPM2_RH_NULL, 464*053f45beSAndroid Build Coastguard Worker TPM2_RH_NULL, 465*053f45beSAndroid Build Coastguard Worker 16, 466*053f45beSAndroid Build Coastguard Worker ('\0' * 16).encode(), 467*053f45beSAndroid Build Coastguard Worker 0, 468*053f45beSAndroid Build Coastguard Worker session_type, 469*053f45beSAndroid Build Coastguard Worker TPM2_ALG_NULL, 470*053f45beSAndroid Build Coastguard Worker name_alg) 471*053f45beSAndroid Build Coastguard Worker 472*053f45beSAndroid Build Coastguard Worker return struct.unpack('>I', self.send_cmd(cmd)[10:14])[0] 473*053f45beSAndroid Build Coastguard Worker 474*053f45beSAndroid Build Coastguard Worker def __calc_pcr_digest(self, pcrs, bank_alg = TPM2_ALG_SHA1, 475*053f45beSAndroid Build Coastguard Worker digest_alg = TPM2_ALG_SHA1): 476*053f45beSAndroid Build Coastguard Worker x = [] 477*053f45beSAndroid Build Coastguard Worker f = get_hash_function(digest_alg) 478*053f45beSAndroid Build Coastguard Worker 479*053f45beSAndroid Build Coastguard Worker for i in pcrs: 480*053f45beSAndroid Build Coastguard Worker pcr = self.read_pcr(i, bank_alg) 481*053f45beSAndroid Build Coastguard Worker if pcr is None: 482*053f45beSAndroid Build Coastguard Worker return None 483*053f45beSAndroid Build Coastguard Worker x += pcr 484*053f45beSAndroid Build Coastguard Worker 485*053f45beSAndroid Build Coastguard Worker return f(bytearray(x)).digest() 486*053f45beSAndroid Build Coastguard Worker 487*053f45beSAndroid Build Coastguard Worker def policy_pcr(self, handle, pcrs, bank_alg = TPM2_ALG_SHA1, 488*053f45beSAndroid Build Coastguard Worker name_alg = TPM2_ALG_SHA1): 489*053f45beSAndroid Build Coastguard Worker ds = get_digest_size(name_alg) 490*053f45beSAndroid Build Coastguard Worker dig = self.__calc_pcr_digest(pcrs, bank_alg, name_alg) 491*053f45beSAndroid Build Coastguard Worker if not dig: 492*053f45beSAndroid Build Coastguard Worker raise UnknownPCRBankError(bank_alg) 493*053f45beSAndroid Build Coastguard Worker 494*053f45beSAndroid Build Coastguard Worker pcrsel_len = max((max(pcrs) >> 3) + 1, 3) 495*053f45beSAndroid Build Coastguard Worker pcrsel = [0] * pcrsel_len 496*053f45beSAndroid Build Coastguard Worker for i in pcrs: 497*053f45beSAndroid Build Coastguard Worker pcrsel[i >> 3] |= 1 << (i & 7) 498*053f45beSAndroid Build Coastguard Worker pcrsel = ''.join(map(chr, pcrsel)).encode() 499*053f45beSAndroid Build Coastguard Worker 500*053f45beSAndroid Build Coastguard Worker fmt = '>HII IH%usIHB3s' % ds 501*053f45beSAndroid Build Coastguard Worker cmd = struct.pack(fmt, 502*053f45beSAndroid Build Coastguard Worker TPM2_ST_NO_SESSIONS, 503*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 504*053f45beSAndroid Build Coastguard Worker TPM2_CC_POLICY_PCR, 505*053f45beSAndroid Build Coastguard Worker handle, 506*053f45beSAndroid Build Coastguard Worker len(dig), 507*053f45beSAndroid Build Coastguard Worker bytes(dig), 508*053f45beSAndroid Build Coastguard Worker 1, 509*053f45beSAndroid Build Coastguard Worker bank_alg, 510*053f45beSAndroid Build Coastguard Worker pcrsel_len, pcrsel) 511*053f45beSAndroid Build Coastguard Worker 512*053f45beSAndroid Build Coastguard Worker self.send_cmd(cmd) 513*053f45beSAndroid Build Coastguard Worker 514*053f45beSAndroid Build Coastguard Worker def policy_password(self, handle): 515*053f45beSAndroid Build Coastguard Worker fmt = '>HII I' 516*053f45beSAndroid Build Coastguard Worker cmd = struct.pack(fmt, 517*053f45beSAndroid Build Coastguard Worker TPM2_ST_NO_SESSIONS, 518*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 519*053f45beSAndroid Build Coastguard Worker TPM2_CC_POLICY_PASSWORD, 520*053f45beSAndroid Build Coastguard Worker handle) 521*053f45beSAndroid Build Coastguard Worker 522*053f45beSAndroid Build Coastguard Worker self.send_cmd(cmd) 523*053f45beSAndroid Build Coastguard Worker 524*053f45beSAndroid Build Coastguard Worker def get_policy_digest(self, handle): 525*053f45beSAndroid Build Coastguard Worker fmt = '>HII I' 526*053f45beSAndroid Build Coastguard Worker cmd = struct.pack(fmt, 527*053f45beSAndroid Build Coastguard Worker TPM2_ST_NO_SESSIONS, 528*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 529*053f45beSAndroid Build Coastguard Worker TPM2_CC_POLICY_GET_DIGEST, 530*053f45beSAndroid Build Coastguard Worker handle) 531*053f45beSAndroid Build Coastguard Worker 532*053f45beSAndroid Build Coastguard Worker return self.send_cmd(cmd)[12:] 533*053f45beSAndroid Build Coastguard Worker 534*053f45beSAndroid Build Coastguard Worker def flush_context(self, handle): 535*053f45beSAndroid Build Coastguard Worker fmt = '>HIII' 536*053f45beSAndroid Build Coastguard Worker cmd = struct.pack(fmt, 537*053f45beSAndroid Build Coastguard Worker TPM2_ST_NO_SESSIONS, 538*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 539*053f45beSAndroid Build Coastguard Worker TPM2_CC_FLUSH_CONTEXT, 540*053f45beSAndroid Build Coastguard Worker handle) 541*053f45beSAndroid Build Coastguard Worker 542*053f45beSAndroid Build Coastguard Worker self.send_cmd(cmd) 543*053f45beSAndroid Build Coastguard Worker 544*053f45beSAndroid Build Coastguard Worker def create_root_key(self, auth_value = bytes()): 545*053f45beSAndroid Build Coastguard Worker attributes = \ 546*053f45beSAndroid Build Coastguard Worker Public.FIXED_TPM | \ 547*053f45beSAndroid Build Coastguard Worker Public.FIXED_PARENT | \ 548*053f45beSAndroid Build Coastguard Worker Public.SENSITIVE_DATA_ORIGIN | \ 549*053f45beSAndroid Build Coastguard Worker Public.USER_WITH_AUTH | \ 550*053f45beSAndroid Build Coastguard Worker Public.RESTRICTED | \ 551*053f45beSAndroid Build Coastguard Worker Public.DECRYPT 552*053f45beSAndroid Build Coastguard Worker 553*053f45beSAndroid Build Coastguard Worker auth_cmd = AuthCommand() 554*053f45beSAndroid Build Coastguard Worker sensitive = SensitiveCreate(user_auth=auth_value) 555*053f45beSAndroid Build Coastguard Worker 556*053f45beSAndroid Build Coastguard Worker public_parms = struct.pack( 557*053f45beSAndroid Build Coastguard Worker '>HHHHHI', 558*053f45beSAndroid Build Coastguard Worker TPM2_ALG_AES, 559*053f45beSAndroid Build Coastguard Worker 128, 560*053f45beSAndroid Build Coastguard Worker TPM2_ALG_CFB, 561*053f45beSAndroid Build Coastguard Worker TPM2_ALG_NULL, 562*053f45beSAndroid Build Coastguard Worker 2048, 563*053f45beSAndroid Build Coastguard Worker 0) 564*053f45beSAndroid Build Coastguard Worker 565*053f45beSAndroid Build Coastguard Worker public = Public( 566*053f45beSAndroid Build Coastguard Worker object_type=TPM2_ALG_RSA, 567*053f45beSAndroid Build Coastguard Worker name_alg=TPM2_ALG_SHA1, 568*053f45beSAndroid Build Coastguard Worker object_attributes=attributes, 569*053f45beSAndroid Build Coastguard Worker parameters=public_parms) 570*053f45beSAndroid Build Coastguard Worker 571*053f45beSAndroid Build Coastguard Worker fmt = '>HIII I%us H%us H%us HI' % \ 572*053f45beSAndroid Build Coastguard Worker (len(auth_cmd), len(sensitive), len(public)) 573*053f45beSAndroid Build Coastguard Worker cmd = struct.pack( 574*053f45beSAndroid Build Coastguard Worker fmt, 575*053f45beSAndroid Build Coastguard Worker TPM2_ST_SESSIONS, 576*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 577*053f45beSAndroid Build Coastguard Worker TPM2_CC_CREATE_PRIMARY, 578*053f45beSAndroid Build Coastguard Worker TPM2_RH_OWNER, 579*053f45beSAndroid Build Coastguard Worker len(auth_cmd), 580*053f45beSAndroid Build Coastguard Worker bytes(auth_cmd), 581*053f45beSAndroid Build Coastguard Worker len(sensitive), 582*053f45beSAndroid Build Coastguard Worker bytes(sensitive), 583*053f45beSAndroid Build Coastguard Worker len(public), 584*053f45beSAndroid Build Coastguard Worker bytes(public), 585*053f45beSAndroid Build Coastguard Worker 0, 0) 586*053f45beSAndroid Build Coastguard Worker 587*053f45beSAndroid Build Coastguard Worker return struct.unpack('>I', self.send_cmd(cmd)[10:14])[0] 588*053f45beSAndroid Build Coastguard Worker 589*053f45beSAndroid Build Coastguard Worker def seal(self, parent_key, data, auth_value, policy_dig, 590*053f45beSAndroid Build Coastguard Worker name_alg = TPM2_ALG_SHA1): 591*053f45beSAndroid Build Coastguard Worker ds = get_digest_size(name_alg) 592*053f45beSAndroid Build Coastguard Worker assert(not policy_dig or ds == len(policy_dig)) 593*053f45beSAndroid Build Coastguard Worker 594*053f45beSAndroid Build Coastguard Worker attributes = 0 595*053f45beSAndroid Build Coastguard Worker if not policy_dig: 596*053f45beSAndroid Build Coastguard Worker attributes |= Public.USER_WITH_AUTH 597*053f45beSAndroid Build Coastguard Worker policy_dig = bytes() 598*053f45beSAndroid Build Coastguard Worker 599*053f45beSAndroid Build Coastguard Worker auth_cmd = AuthCommand() 600*053f45beSAndroid Build Coastguard Worker sensitive = SensitiveCreate(user_auth=auth_value, data=data) 601*053f45beSAndroid Build Coastguard Worker 602*053f45beSAndroid Build Coastguard Worker public = Public( 603*053f45beSAndroid Build Coastguard Worker object_type=TPM2_ALG_KEYEDHASH, 604*053f45beSAndroid Build Coastguard Worker name_alg=name_alg, 605*053f45beSAndroid Build Coastguard Worker object_attributes=attributes, 606*053f45beSAndroid Build Coastguard Worker auth_policy=policy_dig, 607*053f45beSAndroid Build Coastguard Worker parameters=struct.pack('>H', TPM2_ALG_NULL)) 608*053f45beSAndroid Build Coastguard Worker 609*053f45beSAndroid Build Coastguard Worker fmt = '>HIII I%us H%us H%us HI' % \ 610*053f45beSAndroid Build Coastguard Worker (len(auth_cmd), len(sensitive), len(public)) 611*053f45beSAndroid Build Coastguard Worker cmd = struct.pack( 612*053f45beSAndroid Build Coastguard Worker fmt, 613*053f45beSAndroid Build Coastguard Worker TPM2_ST_SESSIONS, 614*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 615*053f45beSAndroid Build Coastguard Worker TPM2_CC_CREATE, 616*053f45beSAndroid Build Coastguard Worker parent_key, 617*053f45beSAndroid Build Coastguard Worker len(auth_cmd), 618*053f45beSAndroid Build Coastguard Worker bytes(auth_cmd), 619*053f45beSAndroid Build Coastguard Worker len(sensitive), 620*053f45beSAndroid Build Coastguard Worker bytes(sensitive), 621*053f45beSAndroid Build Coastguard Worker len(public), 622*053f45beSAndroid Build Coastguard Worker bytes(public), 623*053f45beSAndroid Build Coastguard Worker 0, 0) 624*053f45beSAndroid Build Coastguard Worker 625*053f45beSAndroid Build Coastguard Worker rsp = self.send_cmd(cmd) 626*053f45beSAndroid Build Coastguard Worker 627*053f45beSAndroid Build Coastguard Worker return rsp[14:] 628*053f45beSAndroid Build Coastguard Worker 629*053f45beSAndroid Build Coastguard Worker def unseal(self, parent_key, blob, auth_value, policy_handle): 630*053f45beSAndroid Build Coastguard Worker private_len = struct.unpack('>H', blob[0:2])[0] 631*053f45beSAndroid Build Coastguard Worker public_start = private_len + 2 632*053f45beSAndroid Build Coastguard Worker public_len = struct.unpack('>H', blob[public_start:public_start + 2])[0] 633*053f45beSAndroid Build Coastguard Worker blob = blob[:private_len + public_len + 4] 634*053f45beSAndroid Build Coastguard Worker 635*053f45beSAndroid Build Coastguard Worker auth_cmd = AuthCommand() 636*053f45beSAndroid Build Coastguard Worker 637*053f45beSAndroid Build Coastguard Worker fmt = '>HII I I%us %us' % (len(auth_cmd), len(blob)) 638*053f45beSAndroid Build Coastguard Worker cmd = struct.pack( 639*053f45beSAndroid Build Coastguard Worker fmt, 640*053f45beSAndroid Build Coastguard Worker TPM2_ST_SESSIONS, 641*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 642*053f45beSAndroid Build Coastguard Worker TPM2_CC_LOAD, 643*053f45beSAndroid Build Coastguard Worker parent_key, 644*053f45beSAndroid Build Coastguard Worker len(auth_cmd), 645*053f45beSAndroid Build Coastguard Worker bytes(auth_cmd), 646*053f45beSAndroid Build Coastguard Worker blob) 647*053f45beSAndroid Build Coastguard Worker 648*053f45beSAndroid Build Coastguard Worker data_handle = struct.unpack('>I', self.send_cmd(cmd)[10:14])[0] 649*053f45beSAndroid Build Coastguard Worker 650*053f45beSAndroid Build Coastguard Worker if policy_handle: 651*053f45beSAndroid Build Coastguard Worker auth_cmd = AuthCommand(session_handle=policy_handle, hmac=auth_value) 652*053f45beSAndroid Build Coastguard Worker else: 653*053f45beSAndroid Build Coastguard Worker auth_cmd = AuthCommand(hmac=auth_value) 654*053f45beSAndroid Build Coastguard Worker 655*053f45beSAndroid Build Coastguard Worker fmt = '>HII I I%us' % (len(auth_cmd)) 656*053f45beSAndroid Build Coastguard Worker cmd = struct.pack( 657*053f45beSAndroid Build Coastguard Worker fmt, 658*053f45beSAndroid Build Coastguard Worker TPM2_ST_SESSIONS, 659*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 660*053f45beSAndroid Build Coastguard Worker TPM2_CC_UNSEAL, 661*053f45beSAndroid Build Coastguard Worker data_handle, 662*053f45beSAndroid Build Coastguard Worker len(auth_cmd), 663*053f45beSAndroid Build Coastguard Worker bytes(auth_cmd)) 664*053f45beSAndroid Build Coastguard Worker 665*053f45beSAndroid Build Coastguard Worker try: 666*053f45beSAndroid Build Coastguard Worker rsp = self.send_cmd(cmd) 667*053f45beSAndroid Build Coastguard Worker finally: 668*053f45beSAndroid Build Coastguard Worker self.flush_context(data_handle) 669*053f45beSAndroid Build Coastguard Worker 670*053f45beSAndroid Build Coastguard Worker data_len = struct.unpack('>I', rsp[10:14])[0] - 2 671*053f45beSAndroid Build Coastguard Worker 672*053f45beSAndroid Build Coastguard Worker return rsp[16:16 + data_len] 673*053f45beSAndroid Build Coastguard Worker 674*053f45beSAndroid Build Coastguard Worker def reset_da_lock(self): 675*053f45beSAndroid Build Coastguard Worker auth_cmd = AuthCommand() 676*053f45beSAndroid Build Coastguard Worker 677*053f45beSAndroid Build Coastguard Worker fmt = '>HII I I%us' % (len(auth_cmd)) 678*053f45beSAndroid Build Coastguard Worker cmd = struct.pack( 679*053f45beSAndroid Build Coastguard Worker fmt, 680*053f45beSAndroid Build Coastguard Worker TPM2_ST_SESSIONS, 681*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 682*053f45beSAndroid Build Coastguard Worker TPM2_CC_DICTIONARY_ATTACK_LOCK_RESET, 683*053f45beSAndroid Build Coastguard Worker TPM2_RH_LOCKOUT, 684*053f45beSAndroid Build Coastguard Worker len(auth_cmd), 685*053f45beSAndroid Build Coastguard Worker bytes(auth_cmd)) 686*053f45beSAndroid Build Coastguard Worker 687*053f45beSAndroid Build Coastguard Worker self.send_cmd(cmd) 688*053f45beSAndroid Build Coastguard Worker 689*053f45beSAndroid Build Coastguard Worker def __get_cap_cnt(self, cap, pt, cnt): 690*053f45beSAndroid Build Coastguard Worker handles = [] 691*053f45beSAndroid Build Coastguard Worker fmt = '>HII III' 692*053f45beSAndroid Build Coastguard Worker 693*053f45beSAndroid Build Coastguard Worker cmd = struct.pack(fmt, 694*053f45beSAndroid Build Coastguard Worker TPM2_ST_NO_SESSIONS, 695*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 696*053f45beSAndroid Build Coastguard Worker TPM2_CC_GET_CAPABILITY, 697*053f45beSAndroid Build Coastguard Worker cap, pt, cnt) 698*053f45beSAndroid Build Coastguard Worker 699*053f45beSAndroid Build Coastguard Worker rsp = self.send_cmd(cmd)[10:] 700*053f45beSAndroid Build Coastguard Worker more_data, cap, cnt = struct.unpack('>BII', rsp[:9]) 701*053f45beSAndroid Build Coastguard Worker rsp = rsp[9:] 702*053f45beSAndroid Build Coastguard Worker 703*053f45beSAndroid Build Coastguard Worker for i in range(0, cnt): 704*053f45beSAndroid Build Coastguard Worker handle = struct.unpack('>I', rsp[:4])[0] 705*053f45beSAndroid Build Coastguard Worker handles.append(handle) 706*053f45beSAndroid Build Coastguard Worker rsp = rsp[4:] 707*053f45beSAndroid Build Coastguard Worker 708*053f45beSAndroid Build Coastguard Worker return handles, more_data 709*053f45beSAndroid Build Coastguard Worker 710*053f45beSAndroid Build Coastguard Worker def get_cap(self, cap, pt): 711*053f45beSAndroid Build Coastguard Worker handles = [] 712*053f45beSAndroid Build Coastguard Worker 713*053f45beSAndroid Build Coastguard Worker more_data = True 714*053f45beSAndroid Build Coastguard Worker while more_data: 715*053f45beSAndroid Build Coastguard Worker next_handles, more_data = self.__get_cap_cnt(cap, pt, 1) 716*053f45beSAndroid Build Coastguard Worker handles += next_handles 717*053f45beSAndroid Build Coastguard Worker pt += 1 718*053f45beSAndroid Build Coastguard Worker 719*053f45beSAndroid Build Coastguard Worker return handles 720*053f45beSAndroid Build Coastguard Worker 721*053f45beSAndroid Build Coastguard Worker def get_cap_pcrs(self): 722*053f45beSAndroid Build Coastguard Worker pcr_banks = {} 723*053f45beSAndroid Build Coastguard Worker 724*053f45beSAndroid Build Coastguard Worker fmt = '>HII III' 725*053f45beSAndroid Build Coastguard Worker 726*053f45beSAndroid Build Coastguard Worker cmd = struct.pack(fmt, 727*053f45beSAndroid Build Coastguard Worker TPM2_ST_NO_SESSIONS, 728*053f45beSAndroid Build Coastguard Worker struct.calcsize(fmt), 729*053f45beSAndroid Build Coastguard Worker TPM2_CC_GET_CAPABILITY, 730*053f45beSAndroid Build Coastguard Worker TPM2_CAP_PCRS, 0, 1) 731*053f45beSAndroid Build Coastguard Worker rsp = self.send_cmd(cmd)[10:] 732*053f45beSAndroid Build Coastguard Worker _, _, cnt = struct.unpack('>BII', rsp[:9]) 733*053f45beSAndroid Build Coastguard Worker rsp = rsp[9:] 734*053f45beSAndroid Build Coastguard Worker 735*053f45beSAndroid Build Coastguard Worker # items are TPMS_PCR_SELECTION's 736*053f45beSAndroid Build Coastguard Worker for i in range(0, cnt): 737*053f45beSAndroid Build Coastguard Worker hash, sizeOfSelect = struct.unpack('>HB', rsp[:3]) 738*053f45beSAndroid Build Coastguard Worker rsp = rsp[3:] 739*053f45beSAndroid Build Coastguard Worker 740*053f45beSAndroid Build Coastguard Worker pcrSelect = 0 741*053f45beSAndroid Build Coastguard Worker if sizeOfSelect > 0: 742*053f45beSAndroid Build Coastguard Worker pcrSelect, = struct.unpack('%ds' % sizeOfSelect, 743*053f45beSAndroid Build Coastguard Worker rsp[:sizeOfSelect]) 744*053f45beSAndroid Build Coastguard Worker rsp = rsp[sizeOfSelect:] 745*053f45beSAndroid Build Coastguard Worker pcrSelect = int.from_bytes(pcrSelect, byteorder='big') 746*053f45beSAndroid Build Coastguard Worker 747*053f45beSAndroid Build Coastguard Worker pcr_banks[hash] = pcrSelect 748*053f45beSAndroid Build Coastguard Worker 749*053f45beSAndroid Build Coastguard Worker return pcr_banks 750