cr50: add firmware upgrade test

This extends the test harness with a test verifying firmware upgrade.
The test in fact just determines the area available for upgrade, picks
the appropriate image and sends it to the device, 1K at a time.

The test does not verify that the device in fact switched to the new
image, the test succeeds if the device accepts all update messages.

BRANCH=none
BUG=chrome-os-partner:37774
TEST=verified that all tests still pass:
   $ ./test/tpm_test/tpmtest.py
   Starting MPSSE at 800 kHz
   Connected to device vid:did:rid of 1ae0:0028:00
   SUCCESS: AES:ECB common
   SUCCESS: AES:ECB128 1
   SUCCESS: AES:ECB192 1
   SUCCESS: AES:ECB256 1
   SUCCESS: AES:ECB256 2
   SUCCESS: AES:CTR128I 1
   SUCCESS: AES:CTR256I 1
   SUCCESS: EC-SIGN:NIST-P256:ECDSA
   New max timeout: 1 s
   SUCCESS: EC-KEYGEN:NIST-P256
   SUCCESS: EC-KEYDERIVE:NIST-P256
   SUCCESS: sha1:single:0
   SUCCESS: sha256:single:0
   SUCCESS: sha1:single:3
   SUCCESS: sha256:single:3
   SUCCESS: sha256:finish:1
   SUCCESS: sha1:finish:3
   SUCCESS: sha256:finish:2
   -New max timeout: 3 s
   SUCCESS: RSA-ENC:OAEP:SHA1:768
   SUCCESS: RSA-ENC:OAEP:SHA256:768
   SUCCESS: RSA-ENC:PKCS1-ES:NONE:768
   New max timeout: 49 s
   SUCCESS: RSA-ENC:PKCS1-ES:NONE:2048
   SUCCESS: RSA-SIGN:PKCS1-SSA:SHA1:768
   SUCCESS: RSA-SIGN:PKCS1-SSA:SHA256:768
   SUCCESS: Firmware upgrade

Change-Id: I49052feb8e97a3e281bb20b7fddc359a55e96ae3
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/327416
Reviewed-by: Nagendra Modadugu <ngm@google.com>
This commit is contained in:
Vadim Bendebury
2016-02-11 16:43:23 -08:00
committed by chrome-bot
parent 93f2848eb9
commit 12d032553a
3 changed files with 71 additions and 2 deletions

View File

@@ -10,7 +10,7 @@ AES = 0
HASH = 1
RSA = 2
EC = 3
FW_UPGRADE = 4
# The same exception class used by all tpmtest modules.
class TpmTestError(Exception):

View File

@@ -24,7 +24,7 @@ import ftdi_spi_tpm
import hash_test
import rsa_test
import subcmd
import upgrade_test
# Extension command for dcypto testing
EXT_CMD = 0xbaccd00a
@@ -137,6 +137,7 @@ if __name__ == '__main__':
ecc_test.ecc_test(t)
hash_test.hash_test(t)
rsa_test.rsa_test(t)
upgrade_test.upgrade(t)
except subcmd.TpmTestError as e:
exc_file, exc_line = traceback.extract_tb(sys.exc_traceback)[-1][:2]
print('\nError in %s:%s: ' % (os.path.basename(exc_file), exc_line), e)

View File

@@ -0,0 +1,68 @@
#!/usr/bin/python
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from __future__ import print_function
import hashlib
import os
import struct
import subcmd
import utils
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()))