summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2020-02-07 18:34:55 -0800
committerCommit Bot <commit-bot@chromium.org>2020-02-19 23:22:03 +0000
commit38f6e45971620382dd03d48a22120cef71db0179 (patch)
tree06dd4fcdd3a37b90476f635698a7ed6f36fcdceb
parent3ac621b0628074bf7d93856fcd33b42b205c7a27 (diff)
downloadchrome-ec-38f6e45971620382dd03d48a22120cef71db0179.tar.gz
utils: script for calculating Cr50 version fingerprint
This scrip copies the Chrome OS run time code which calculates Cr50 image hash, used as the UMA key to keep track of various TPM versions. BRANCH=none BUG=none TEST=verified that generated fingerprint values match previously generated values: $ for b in /opt/google/cr50/firmware/*; do gsctool -b $b util/tpm_hash_gen.py $b done read 524288(0x80000) bytes from ... RO_A:0.0.11 RW_A:0.4.24[FFFF:00000000:00000010]... 37564a12 928401938 /opt/google/cr50/firmware/cr50.bin.prepvt read 524288(0x80000) bytes from ... RO_A:0.0.11 RW_A:0.3.24[00000000:00000000:00000000]... 795daf5c 2036182876 /opt/google/cr50/firmware/cr50.bin.prod $ Change-Id: Ie129227cea3c68937223c81c068612b044cd5c8b Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2051306 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rwxr-xr-xutil/tpm_hash_gen.py114
1 files changed, 114 insertions, 0 deletions
diff --git a/util/tpm_hash_gen.py b/util/tpm_hash_gen.py
new file mode 100755
index 0000000000..c741c88ade
--- /dev/null
+++ b/util/tpm_hash_gen.py
@@ -0,0 +1,114 @@
+#!/usr/bin/python
+# Copyright 2020 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.
+"""A program for calculating Cr50 TPM image identifier used in UMA.
+
+The code of this program is a Python equivalent of the code of function
+GetFingerprint() defined in
+
+https://chromium.googlesource.com/chromiumos/platform2/+/16911186/cryptohome/tpm.cc#78
+
+"""
+
+import hashlib
+import re
+import sys
+
+class MyError(Exception):
+ """Local Exception wrapper."""
+ pass
+
+
+def get_git_versions(cr50_file):
+ """Find git versions in a Cr50 binary image.
+
+ The Cr50 version string is generated at build time by the
+ ./util/getversion.sh script. The version string is built based on the
+ following template:
+
+ cr50_v<vers>-<git sha> tpm2:<vers>-<git sha> ... <year>-<month>-<day>
+
+ Since the Cr50 image includes sections for RW_A and RW_B, the same version
+ string is supposed to be present in the image twice.
+
+ This function reads the passed in file name, looks for the version, makes
+ sure that the version is present twice and both instances are identical,
+ then extracts git hashes of the ec and tpm2 trees from the version string
+ and returns them as a list of two integers.
+
+ Args:
+ cr50_file: A string, name of the Cr50 image file.
+
+ Returns:
+ A list of two integers, hashes of ec and tpm2 trees at build time.
+
+ Raises:
+ MyError: if consistent version string was not found in the file.
+
+ """
+ git_vers_regexp = re.compile(b'cr50_v[12].* tpm2.* 20[12][0-9]')
+ text = open(cr50_file, 'rb').read()
+ strings = git_vers_regexp.findall(text)
+ hashes = []
+
+ if len(strings) != 2 or strings[0] != strings[1]:
+ raise MyError('Could not find git version string in %s' % cr50_file)
+
+ for piece in strings[0].decode().split():
+ if piece.startswith('cr50_') or piece.startswith('tpm2'):
+ hashes.append(piece.split('-')[1])
+
+ return [int(x, 16) for x in hashes]
+
+
+def hash_cr50_file(cr50_file):
+ """Calculate UMA key of a Cr50 image.
+
+ Find out git hashes of the ec and tpm2 components of the passed in Cr50
+ image and then generate a file hash following the same pattern which is
+ used by
+ https://chromium.googlesource.com/chromiumos/platform2/+/16911186/cryptohome/tpm.cc#78
+
+ Args:
+ cr50_file: A string, name of the Cr50 image file.
+
+ Returns:
+ An int, cr50 image hash calculated following the fixed template.
+ """
+ git_versions = get_git_versions(cr50_file)
+ hash_const = '322e3000000000000000007443524f5300000001'
+ tpm_hash_template = '%s%8.8x%8.8x%16.16x%s'
+ vendor_specific = 'xCG fTPM'
+
+ hash_input = tpm_hash_template % (hash_const, git_versions[0],
+ git_versions[1], len(vendor_specific),
+ vendor_specific)
+
+ h = hashlib.sha256()
+ h.update(bytes(hash_input, 'ascii'))
+
+ hex_digest = h.hexdigest()
+ uma_digest_list = [hex_digest[2*x:2*x + 2] for x in range(4)]
+ hex_uma_key = ''.join(uma_digest_list[::-1])
+ uma_key = int(hex_uma_key, 16) & 0x7fffffff
+ return uma_key
+
+
+def main(cr50_files):
+ """Calculate and report UMA keys for passed in Cr50 images.
+
+ Args:
+ cr50_files: A list of strings, names of Cr50 files to hash.
+ """
+ for cr50_file in cr50_files:
+ key = hash_cr50_file(cr50_file)
+ print('%08x %-9d %s' % (key, key, cr50_file))
+
+if __name__ == '__main__':
+ try:
+ main(sys.argv[1:])
+ except MyError as e:
+ print('Error:', e)
+ sys.exit(1)
+ sys.exit(0)