def trng_test(tpm): """Download entropy samples from TRNG Command structure, shared out of band with the test running on the target: field | size | note =================================================================== text_len | 2 | size of the text to process, big endian Args: tpm: a tpm object used to communicate with the device Raises: subcmd.TpmTestError: on unexpected target responses """ with open('/tmp/trng_output', 'wb') as f: for x in range(0, TRNG_SAMPLE_COUNT): wrapped_response = tpm.command(tpm.wrap_ext_command(TRNG_TEST_CC, get_random_command(TRNG_SAMPLE_SIZE))) if wrapped_response[:12] != get_random_command_rsp(TRNG_SAMPLE_SIZE): raise subcmd.TpmTestError("Unexpected response to '%s': %s" % ("trng", utils.hex_dump(wrapped_response))) f.write(wrapped_response[12:]) print('%s %d%%\r' %( utils.cursor_back(), (x/10)), end=""), print('%sSUCCESS: %s' % (utils.cursor_back(), 'trng'))
def _encrypt_tests(tpm): msg = 'Hello CR50!' for data in _ENCRYPT_INPUTS: padding, hashing, key_len = data test_name = 'RSA-ENC:%s:%s:%d' % data cmd = _encrypt_cmd(_RSA_PADDING[padding], _HASH[hashing], key_len, msg) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) ciphertext = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) cmd = _decrypt_cmd(_RSA_PADDING[padding], _HASH[hashing], key_len, ciphertext) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) plaintext = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) if padding == 'NULL': # Check for leading zeros. if reduce(lambda x, y: x | y, map(ord, plaintext[:len(plaintext) - len(msg)])): raise subcmd.TpmTestError('%s error:%s%s' % ( test_name, utils.hex_dump(msg), utils.hex_dump(plaintext))) else: plaintext = plaintext[len(plaintext) - len(msg):] if msg != plaintext: raise subcmd.TpmTestError('%s error:%s%s' % ( test_name, utils.hex_dump(msg), utils.hex_dump(plaintext))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _encrypt_tests(tpm): msg = 'Hello CR50!' for data in _ENCRYPT_INPUTS: padding, hashing, key_len = data test_name = 'RSA-ENC:%s:%s:%d' % data cmd = _encrypt_cmd(_RSA_PADDING[padding], _HASH[hashing], key_len, msg) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) ciphertext = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) cmd = _decrypt_cmd(_RSA_PADDING[padding], _HASH[hashing], key_len, ciphertext) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) plaintext = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) if padding == 'NULL': # Check for leading zeros. if reduce(lambda x, y: x | y, map(ord, plaintext[:len(plaintext) - len(msg)])): raise subcmd.TpmTestError('%s error:%s%s' % (test_name, utils.hex_dump(msg), utils.hex_dump(plaintext))) else: plaintext = plaintext[len(plaintext) - len(msg):] if msg != plaintext: raise subcmd.TpmTestError( '%s error:%s%s' % (test_name, utils.hex_dump(msg), utils.hex_dump(plaintext))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _keygen_tests(tpm): for data in _KEYGEN_INPUTS: key_len, e, label = data test_name = 'RSA-KEYGEN:%d:%d:%s' % data cmd = _keygen_cmd(key_len, e, label) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) result = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) result_len = len(result) if result_len != int(key_len / 8 * 1.5): raise subcmd.TpmTestError('%s error:%s' % (test_name, utils.hex_dump(result))) N = int(binascii.b2a_hex(result[0:result_len * 2 / 3]), 16) p = int(binascii.b2a_hex(result[result_len * 2 / 3:]), 16) q = N / p if not rsa.prime.is_prime(p): raise subcmd.TpmTestError('%s error:%s' % (test_name, utils.hex_dump(result))) if not rsa.prime.is_prime(q): raise subcmd.TpmTestError('%s error:%s' % (test_name, utils.hex_dump(result))) if p == q: raise subcmd.TpmTestError('%s error:%s' % (test_name, utils.hex_dump(result))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _primegen_tests(tpm): for data in _PRIMEGEN_INPUTS: key_len = data test_name = 'RSA-PRIMEGEN:%d' % data seed = rsa.randnum.read_random_bits(key_len / 2) assert len(seed) == key_len / 16 # dcrypto interface is little-endian. cmd = _primegen_cmd(seed[::-1]) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) result = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) result_len = len(result) if result_len != key_len / 16: raise subcmd.TpmTestError('%s error:%s' % ( test_name, utils.hex_dump(result))) p = int(binascii.b2a_hex(result[::-1]), 16) if not rsa.prime.is_prime(p): raise subcmd.TpmTestError('%s error:%s' % ( test_name, utils.hex_dump(result))) calculated = _prime_from_seed(seed) if p != calculated: raise subcmd.TpmTestError('%s error:%s' % ( test_name, utils.hex_dump(result))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _primegen_tests(tpm): for data in _PRIMEGEN_INPUTS: key_len = data test_name = 'RSA-PRIMEGEN:%d' % data seed = rsa.randnum.read_random_bits(key_len / 2) assert len(seed) == key_len / 16 # dcrypto interface is little-endian. cmd = _primegen_cmd(seed[::-1]) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) result = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) result_len = len(result) if result_len != key_len / 16: raise subcmd.TpmTestError('%s error:%s' % (test_name, utils.hex_dump(result))) p = int(binascii.b2a_hex(result[::-1]), 16) if not rsa.prime.is_prime(p): raise subcmd.TpmTestError('%s error:%s' % (test_name, utils.hex_dump(result))) calculated = _prime_from_seed(seed) if p != calculated: raise subcmd.TpmTestError('%s error:%s' % (test_name, utils.hex_dump(result))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _keygen_tests(tpm): for data in _KEYGEN_INPUTS: key_len, e, label, expected_N = data test_name = 'RSA-KEYGEN:%d:%d:%s' % data[:-1] cmd = _keygen_cmd(key_len, e, label) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) result = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) result_len = len(result) if result_len != int(key_len / 8 * 1.5): raise subcmd.TpmTestError('%s error:%s' % ( test_name, utils.hex_dump(result))) N = int(binascii.b2a_hex(result[0:result_len * 2 / 3]), 16) if expected_N and N != expected_N: raise subcmd.TpmTestError('%s error:%s' % ( test_name, utils.hex_dump(result))) p = int(binascii.b2a_hex(result[result_len * 2 / 3:]), 16) q = N / p if not rsa.prime.is_prime(p): raise subcmd.TpmTestError('%s error:%s' % ( test_name, utils.hex_dump(result))) if not rsa.prime.is_prime(q): raise subcmd.TpmTestError('%s error:%s' % ( test_name, utils.hex_dump(result))) if p == q: raise subcmd.TpmTestError('%s error:%s' % ( test_name, utils.hex_dump(result))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def crypto_test(tdesc, tpm): """Perform a single test described in the xml file. The xml node contains all pertinent information about the test inputs and outputs. Args: tdesc: an Element of the ElementTree, a test descriptor containing necessary information to run a single encryption/description session. tpm: a TPM object to send extended commands to an initialized TPM Raises: CryptoError: on various execution errors, the details are included in the error message. """ node_name = tdesc.get('name') key = get_attribute(tdesc, 'key') if len(key) not in (16, 24, 32): raise CryptoError('wrong key size "%s:%s"' % (node_name, ''.join('%2.2x' % ord(x) for x in key))) iv = get_attribute(tdesc, 'iv', required=False) if iv and len(iv) != 16: raise CryptoError('wrong iv size "%s:%s"' % (node_name, ''.join('%2.2x' % ord(x) for x in iv))) clear_text = get_attribute(tdesc, 'clear_text') if tpm.debug_enabled(): print('clear text size', len(clear_text)) cipher_text = get_attribute(tdesc, 'cipher_text', required=False) real_cipher_text = crypto_run(node_name, ENCRYPT, key, iv, clear_text, cipher_text, tpm) crypto_run(node_name, DECRYPT, key, iv, real_cipher_text, clear_text, tpm) print(utils.cursor_back() + 'SUCCESS: %s' % node_name)
def crypto_test(tdesc, tpm): """Perform a single test described in the xml file. The xml node contains all pertinent information about the test inputs and outputs. Args: tdesc: an Element of the ElementTree, a test descriptor containing necessary information to run a single encryption/description session. tpm: a TPM object to send extended commands to an initialized TPM Raises: CryptoError: on various execution errors, the details are included in the error message. """ node_name = tdesc.get('name') key = get_attribute(tdesc, 'key') if len(key) not in (16, 24, 32): raise CryptoError('wrong key size "%s:%s"' % ( node_name, ''.join('%2.2x' % ord(x) for x in key))) iv = get_attribute(tdesc, 'iv', required=False) if iv and len(iv) != 16: raise CryptoError('wrong iv size "%s:%s"' % ( node_name, ''.join('%2.2x' % ord(x) for x in iv))) clear_text = get_attribute(tdesc, 'clear_text') if tpm.debug_enabled(): print('clear text size', len(clear_text)) cipher_text = get_attribute(tdesc, 'cipher_text', required=False) real_cipher_text = crypto_run(node_name, ENCRYPT, key, iv, clear_text, cipher_text, tpm) crypto_run(node_name, DECRYPT, key, iv, real_cipher_text, clear_text, tpm) print(utils.cursor_back() + 'SUCCESS: %s' % node_name)
def _x509_verify_tests(tpm): test_name = 'RSA-X509-2048-VERIFY' cmd = _x509_verify_cmd(2048) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) valid = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) expected = '\x01' if valid != expected: raise subcmd.TpmTestError('%s error:%s%s' % ( test_name, utils.hex_dump(valid), utils.hex_dump(expected))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def upgrade(tpm): """Exercise the upgrade command. The target expect the upgrade extension command to have the following structure: cmd 1 value of FW_UPGRADE digest 4 first 4 bytes of sha1 of the remainder of the message block_base 4 address of the block to write data var Args: tpm: a properly initialized tpmtest.TPM object Raises: subcmd.TpmTestError: In case of various test problems """ cmd = struct.pack('>I', 0) # address cmd += struct.pack('>I', 0) # data (a noop) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.FW_UPGRADE, cmd)) base_str = tpm.unwrap_ext_response(subcmd.FW_UPGRADE, wrapped_response) if len(base_str) < 4: raise subcmd.TpmTestError('Initialization error %d' % ord(base_str[0])) base = struct.unpack('>I', base_str)[0] if base == 0x84000: fname = 'build/cr50/RW/ec.RW_B.flat' elif base == 0x44000: fname = 'build/cr50/RW/ec.RW.flat' else: raise subcmd.TpmTestError('Unknown base address 0x%x' % base) fname = os.path.join(os.path.dirname(__file__), '../..', fname) data = open(fname, 'r').read() transferred = 0 block_size = 1024 while transferred < len(data): tx_size = min(block_size, len(data) - transferred) chunk = data[transferred:transferred+tx_size] cmd = struct.pack('>I', base) # address h = hashlib.sha1() h.update(cmd) h.update(chunk) cmd = h.digest()[0:4] + cmd + chunk resp = tpm.unwrap_ext_response(subcmd.FW_UPGRADE, tpm.command(tpm.wrap_ext_command( subcmd.FW_UPGRADE, cmd))) code = ord(resp[0]) if code: raise subcmd.TpmTestError('%x - resp %d' % (base, code)) base += tx_size transferred += tx_size print('%sSUCCESS: Firmware upgrade' % (utils.cursor_back()))
def _rfc_tests(tpm): for data in _RFC_TEST_INPUTS: IKM, salt, info, OKM = map(a2b, data[:-1]) test_name = 'HKDF:SHA256:%s' % data[-1] cmd = _rfc_test_cmd(salt, IKM, info, len(OKM)) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.HKDF, cmd)) result = tpm.unwrap_ext_response(subcmd.HKDF, wrapped_response) if result != OKM: raise subcmd.TpmTestError('%s error:%s%s' % ( test_name, utils.hex_dump(result), utils.hex_dump(OKM))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _keytest_tests(tpm): for data in _KEYTEST_INPUTS: key_len, = data test_name = 'RSA-KEYTEST:%d' % data cmd = _keytest_cmd(key_len) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) valid = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) expected = '\x01' if valid != expected: raise subcmd.TpmTestError('%s error:%s%s' % ( test_name, utils.hex_dump(valid), utils.hex_dump(expected))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def upgrade(tpm): """Exercise the upgrade command. The target expect the upgrade extension command to have the following structure: cmd 1 value of FW_UPGRADE digest 4 first 4 bytes of sha1 of the remainder of the message block_base 4 address of the block to write data var Args: tpm: a properly initialized tpmtest.TPM object Raises: subcmd.TpmTestError: In case of various test problems """ cmd = struct.pack('>I', 0) # address cmd += struct.pack('>I', 0) # data (a noop) wrapped_response = tpm.command(tpm.wrap_ext_command( subcmd.FW_UPGRADE, cmd)) base_str = tpm.unwrap_ext_response(subcmd.FW_UPGRADE, wrapped_response) if len(base_str) < 4: raise subcmd.TpmTestError('Initialization error %d' % ord(base_str[0])) base = struct.unpack('>I', base_str)[0] if base == 0x84000: fname = 'build/cr50/RW/ec.RW_B.flat' elif base == 0x44000: fname = 'build/cr50/RW/ec.RW.flat' else: raise subcmd.TpmTestError('Unknown base address 0x%x' % base) fname = os.path.join(os.path.dirname(__file__), '../..', fname) data = open(fname, 'r').read() transferred = 0 block_size = 1024 while transferred < len(data): tx_size = min(block_size, len(data) - transferred) chunk = data[transferred:transferred + tx_size] cmd = struct.pack('>I', base) # address h = hashlib.sha1() h.update(cmd) h.update(chunk) cmd = h.digest()[0:4] + cmd + chunk resp = tpm.unwrap_ext_response( subcmd.FW_UPGRADE, tpm.command(tpm.wrap_ext_command(subcmd.FW_UPGRADE, cmd))) code = ord(resp[0]) if code: raise subcmd.TpmTestError('%x - resp %d' % (base, code)) base += tx_size transferred += tx_size print('%sSUCCESS: Firmware upgrade' % (utils.cursor_back()))
def _keygen_test(tpm): for data in _KEYGEN_INPUTS: curve_id, = data test_name = 'ECC-KEYGEN:%s' % data cmd = _keygen_cmd(_ECC_CURVES[curve_id]) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECC, cmd)) valid = tpm.unwrap_ext_response(subcmd.ECC, wrapped_response) expected = '\x01' if valid != expected: raise subcmd.TpmTestError('%s error:%s:%s' % ( test_name, utils.hex_dump(valid), utils.hex_dump(expected))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _rfc_tests(tpm): for data in _RFC_TEST_INPUTS: IKM, salt, info, OKM = map(a2b, data[:-1]) test_name = 'HKDF:SHA256:%s' % data[-1] cmd = _rfc_test_cmd(salt, IKM, info, len(OKM)) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.HKDF, cmd)) result = tpm.unwrap_ext_response(subcmd.HKDF, wrapped_response) if result != OKM: raise subcmd.TpmTestError( '%s error:%s%s' % (test_name, utils.hex_dump(result), utils.hex_dump(OKM))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _keyderive_test(tpm): for data in _KEYDERIVE_INPUTS: curve_id, seed_bytes = data seed = os.urandom(seed_bytes) test_name = 'ECC-KEYDERIVE:%s' % data[0] cmd = _keyderive_cmd(_ECC_CURVES[curve_id], seed) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECC, cmd)) valid = tpm.unwrap_ext_response(subcmd.ECC, wrapped_response) expected = '\x01' if valid != expected: raise subcmd.TpmTestError('%s error:%s:%s' % ( test_name, utils.hex_dump(valid), utils.hex_dump(expected))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def crypto_test(tdesc, tpm): """Perform a single test described in the xml file. The xml node contains all pertinent information about the test inputs and outputs. Args: tdesc: an Element of the ElementTree, a test descriptor containing necessary information to run a single encryption/description session. tpm: a TPM object to send extended commands to an initialized TPM Raises: subcmd.TpmTestError: on various execution errors, the details are included in the error message. """ node_name = tdesc.get('name') key = get_attribute(tdesc, 'key') if len(key) not in (16, 24, 32): raise subcmd.TpmTestError('wrong key size "%s:%s"' % (node_name, ''.join('%2.2x' % ord(x) for x in key))) iv = get_attribute(tdesc, 'iv', required=False) if iv and not node_name.startswith('AES:GCM') and len(iv) != 16: raise subcmd.TpmTestError('wrong iv size "%s:%s"' % (node_name, ''.join('%2.2x' % ord(x) for x in iv))) clear_text = get_attribute(tdesc, 'clear_text', required=False) if clear_text: clear_text_len = get_attribute(tdesc, 'clear_text_len', required=False) if clear_text_len: clear_text = clear_text[:int(clear_text_len)] else: clear_text_len = None if tpm.debug_enabled(): print('clear text size', len(clear_text)) cipher_text = get_attribute(tdesc, 'cipher_text', required=False) if clear_text_len: cipher_text = cipher_text[:int(clear_text_len)] tag = get_attribute(tdesc, 'tag', required=False) aad = get_attribute(tdesc, 'aad', required=False) if aad: aad_len = get_attribute(tdesc, 'aad_len', required=False) if aad_len: aad = aad[:int(aad_len)] real_cipher_text = crypto_run(node_name, ENCRYPT, key, iv, aad or '', clear_text, cipher_text + tag, tpm) crypto_run(node_name, DECRYPT, key, iv, aad or '', real_cipher_text[:len(real_cipher_text) - len(tag)], clear_text + tag, tpm) print(utils.cursor_back() + 'SUCCESS: %s' % node_name)
def _compat_test(tpm): for data in _ECIES_COMPAT_INPUTS: auth, plaintext, iv, ciphertext, d, salt, info = data[:-1] test_name = 'ECIES-TEST:%s' % data[-1] cmd = _decrypt_cmd(auth, ciphertext, iv, d, salt, info) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECIES, cmd)) decrypted = tpm.unwrap_ext_response(subcmd.ECIES, wrapped_response) expected = auth + plaintext if decrypted != expected: raise subcmd.TpmTestError('%s error:%s:%s' % ( test_name, utils.hex_dump(decrypted), utils.hex_dump(expected))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _sign_tests(tpm): msg = 'Hello CR50!' for data in _SIGN_INPUTS: padding, hashing, key_len = data test_name = 'RSA-SIGN:%s:%s:%d' % data cmd = _sign_cmd(_RSA_PADDING[padding], _HASH[hashing], key_len, msg) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) signature = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) cmd = _verify_cmd(_RSA_PADDING[padding], _HASH[hashing], key_len, signature, msg) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) verified = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) expected = '\x01' if verified != expected: raise subcmd.TpmTestError('%s error:%s%s' % ( test_name, utils.hex_dump(verified), utils.hex_dump(expected))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _sign_test(tpm): msg = 'Hello CR50' for data in _SIGN_INPUTS: curve_id, sign_mode = data test_name = 'ECC-SIGN:%s:%s' % data cmd = _sign_cmd(_ECC_CURVES[curve_id], _HASH_FUNC[curve_id], _SIGN_MODE[sign_mode], msg) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECC, cmd)) signature = tpm.unwrap_ext_response(subcmd.ECC, wrapped_response) cmd = _verify_cmd(_ECC_CURVES[curve_id], _HASH_FUNC[curve_id], _SIGN_MODE[sign_mode], msg, signature) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECC, cmd)) verified = tpm.unwrap_ext_response(subcmd.ECC, wrapped_response) expected = '\x01' if verified != expected: raise subcmd.TpmTestError('%s error:%s:%s' % ( test_name, utils.hex_dump(verified), utils.hex_dump(expected))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _ecies_test(tpm): for data in _ECIES_INPUTS: auth, input, iv, d, pubx, puby, salt, info = data[:-1] test_name = 'ECIES-TEST:%s' % data[-1] cmd = _encrypt_cmd(auth, input, iv, pubx, puby, salt, info) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECIES, cmd)) encrypted = tpm.unwrap_ext_response(subcmd.ECIES, wrapped_response) # check length of encrypted. if not encrypted: raise subcmd.TpmTestError('%s error:%s' % ( test_name, 'null encrypted')) cmd = _decrypt_cmd(auth, encrypted, iv, d, salt, info) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECIES, cmd)) decrypted = tpm.unwrap_ext_response(subcmd.ECIES, wrapped_response) expected = auth + input if decrypted != expected: raise subcmd.TpmTestError('%s error:%s:%s' % ( test_name, utils.hex_dump(decrypted), utils.hex_dump(expected))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def _verify_tests(tpm): for data in _VERIFY_INPUTS: msg = rsa.randnum.read_random_bits(256) padding, hashing, key_len = data test_name = 'RSA-VERIFY:%s:%s:%d' % data key = _KEYS[key_len] signer = _SIGNER[padding].new(key) h = _HASHER[hashing].new() h.update(msg) signature = signer.sign(h) cmd = _verify_cmd(_RSA_PADDING[padding], _HASH[hashing], key_len, signature, h.digest()) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) verified = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) expected = '\x01' if verified != expected: raise subcmd.TpmTestError('%s error:%s%s' % ( test_name, utils.hex_dump(verified), utils.hex_dump(expected))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def drbg_test(tpm): """Runs DRBG test case. Args: tpm: a tpm object used to communicate with the device Raises: subcmd.TpmTestError: on unexpected target responses """ for test in test_inputs: drbg_op, drbg_params = test if drbg_op == DRBG_INIT: entropy, nonce, perso = drbg_params cmd = _drbg_init_cmd(drbg_op, a2b(entropy), a2b(nonce), a2b(perso)) response = tpm.command(tpm.wrap_ext_command(subcmd.DRBG_TEST, cmd)) if response != EMPTY_DRBG_RESPONSE: raise subcmd.TpmTestError( "Unexpected response to DRBG_INIT: %s" % (utils.hex_dump(wrapped_response))) elif drbg_op == DRBG_RESEED: entropy, inp1, inp2 = drbg_params cmd = _drbg_init_cmd(drbg_op, a2b(entropy), a2b(inp1), a2b(inp2)) response = tpm.command(tpm.wrap_ext_command(subcmd.DRBG_TEST, cmd)) if response != EMPTY_DRBG_RESPONSE: raise subcmd.TpmTestError( "Unexpected response to DRBG_RESEED: %s" % (utils.hex_dump(wrapped_response))) elif drbg_op == DRBG_GENERATE: inp, expected = drbg_params cmd = _drbg_gen_cmd(a2b(inp), a2b(expected)) response = tpm.command(tpm.wrap_ext_command(subcmd.DRBG_TEST, cmd)) if expected != '': result = response[12:] if a2b(expected) != result: raise subcmd.TpmTestError( 'error:\nexpected %s\nreceived %s' % (utils.hex_dump( a2b(expected)), utils.hex_dump(result))) print('%sSUCCESS: %s' % (utils.cursor_back(), 'DRBG test'))
def _sign_tests(tpm): for data in _SIGN_INPUTS: msg = rsa.randnum.read_random_bits(256) padding, hashing, key_len = data test_name = 'RSA-SIGN:%s:%s:%d' % data key = _KEYS[key_len] verifier = _SIGNER[padding].new(key) h = _HASHER[hashing].new() h.update(msg) cmd = _sign_cmd(_RSA_PADDING[padding], _HASH[hashing], key_len, h.digest()) wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.RSA, cmd)) signature = tpm.unwrap_ext_response(subcmd.RSA, wrapped_response) signer = _SIGNER[padding].new(key) expected_signature = signer.sign(h) if not verifier.verify(h, signature): raise subcmd.TpmTestError('%s error' % ( test_name,)) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def hash_test(tpm): """Exercise multiple hash threads simultaneously. Command structure, shared out of band with the test running on the target: field | size | note =================================================================== hash_cmd | 1 | 0 - start, 1 - cont., 2 - finish, 4 - single hash_mode | 1 | 0 - sha1, 1 - sha256 handle | 1 | session handle, ignored in 'single' mode text_len | 2 | size of the text to process, big endian text | text_len | text to hash Args: tpm: a tpm object used to communicate with the device Raises: HashError: on unexpected target responses """ contexts = {} function_map = { MODE_SHA1: ('sha1', hashlib.sha1), MODE_SHA256: ('sha256', hashlib.sha256) } cmd_map = { 'start': CMD_START, 'cont': CMD_CONT, 'finish': CMD_FINISH, 'single': CMD_SINGLE } for test in test_inputs: hash_mode, cmd_name, handle, text = test mode_name, hash_func = function_map[hash_mode] hash_cmd = cmd_map[cmd_name] test_name = '%s:%s:%d' % (mode_name, cmd_name, handle) cmd = '%c' % hash_cmd cmd += '%c' % hash_mode cmd += '%c' % handle # Ignored for single shots cmd += struct.pack('>H', len(text)) cmd += text wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.HASH, cmd)) if hash_cmd in (CMD_START, CMD_CONT): if hash_cmd == CMD_START: contexts[handle] = hash_func() h = contexts[handle] h.update(text) if wrapped_response != EMPTY_RESPONSE: raise HashError("Unexpected response to '%s': %s" % (test_name, utils.hex_dump(wrapped_response))) continue if hash_cmd == CMD_FINISH: h = contexts[handle] elif hash_cmd == CMD_SINGLE: h = hash_func() else: raise HashError('Unknown command %d' % hash_cmd) h.update(text) digest = h.digest() result = wrapped_response[12:] if result != h.digest(): raise HashError('%s error:%s%s' % (test_name, utils.hex_dump(digest), utils.hex_dump(result))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
def hash_test(tpm): """Exercise multiple hash threads simultaneously. Command structure, shared out of band with the test running on the target: field | size | note =================================================================== hash_cmd | 1 | 0 - start, 1 - cont., 2 - finish, 4 - single hash_mode | 1 | 0 - sha1, 1 - sha256 handle | 1 | session handle, ignored in 'single' mode text_len | 2 | size of the text to process, big endian text | text_len | text to hash Args: tpm: a tpm object used to communicate with the device Raises: subcmd.TpmTestError: on unexpected target responses """ contexts = {} function_map = { MODE_SHA1: ('sha1', hashlib.sha1), MODE_SHA256: ('sha256', hashlib.sha256) } cmd_map = { 'start': CMD_START, 'cont': CMD_CONT, 'finish': CMD_FINISH, 'single': CMD_SINGLE } for test in test_inputs: hash_mode, cmd_name, handle, text = test mode_name, hash_func = function_map[hash_mode] hash_cmd = cmd_map[cmd_name] test_name = '%s:%s:%d' % (mode_name, cmd_name, handle) cmd = '%c' % hash_cmd cmd += '%c' % hash_mode cmd += '%c' % handle # Ignored for single shots cmd += struct.pack('>H', len(text)) cmd += text wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.HASH, cmd)) if hash_cmd in (CMD_START, CMD_CONT): if hash_cmd == CMD_START: contexts[handle] = hash_func() h = contexts[handle] h.update(text) if wrapped_response != EMPTY_RESPONSE: raise subcmd.TpmTestError("Unexpected response to '%s': %s" % (test_name, utils.hex_dump(wrapped_response))) continue if hash_cmd == CMD_FINISH: h = contexts[handle] elif hash_cmd == CMD_SINGLE: h = hash_func() else: raise subcmd.TpmTestError('Unknown command %d' % hash_cmd) h.update(text) digest = h.digest() result = wrapped_response[12:] if result != h.digest(): raise subcmd.TpmTestError('%s error:%s%s' % (test_name, utils.hex_dump(digest), utils.hex_dump(result))) print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))