summaryrefslogtreecommitdiff
path: root/test/tpm_test/u2f_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/tpm_test/u2f_test.py')
-rw-r--r--test/tpm_test/u2f_test.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/test/tpm_test/u2f_test.py b/test/tpm_test/u2f_test.py
new file mode 100644
index 0000000000..9cb7d5e609
--- /dev/null
+++ b/test/tpm_test/u2f_test.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 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.
+
+"""Module for testing u2f functions using extended commands."""
+from binascii import a2b_hex as a2b
+import hashlib
+import os
+import struct
+
+import subcmd
+import utils
+
+
+# U2F_GENERATE:
+# origin [32] | user [32] | flag | [auth_secret[32]]
+def u2f_generate(tpm, origin, user, flag, auth):
+ origin = origin[:32].ljust(32, b'\0')
+ user = user[:32].ljust(32, b'\0')
+ auth = auth[:32].ljust(32, b'\0')
+ cmd = origin + user + flag.to_bytes(1, 'big') + auth
+ wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.U2F_GENERATE, cmd))
+ response = tpm.unwrap_ext_response(subcmd.U2F_GENERATE, wrapped_response)
+ public_key = response[:65]
+ kh = response[65:]
+ return public_key, kh
+
+def u2f_sign(tpm, origin, user, auth, kh, msg, flag, fail=False):
+ origin = origin[:32].ljust(32, b'\0')
+ user = user[:32].ljust(32, b'\0')
+ auth = auth[:32].ljust(32, b'\0')
+ msg = msg[:32].ljust(32, b'\0')
+
+ # determine version by size of key handle
+ if (len(kh) == 64):
+ cmd = origin + user + kh + msg + flag.to_bytes(1, 'big')
+ else:
+ cmd = origin + user + auth + msg + flag.to_bytes(1, 'big') + kh
+
+ if fail==False:
+ wrapped_response = tpm.command(tpm.wrap_ext_command(
+ subcmd.U2F_SIGN, cmd))
+ response = tpm.unwrap_ext_response(subcmd.U2F_SIGN, wrapped_response)
+ sig = response[:64]
+ else:
+ response, size, response_code = tpm.command_unchecked(
+ tpm.wrap_ext_command(subcmd.U2F_SIGN, cmd))
+ if size != 12:
+ raise subcmd.TpmTestError('Unexpected response: '
+ + utils.hex_dump(response))
+ print('response: ', hex(response_code))
+ return b''
+ return sig
+
+def u2f_attest(tpm, origin, user, challenge, kh, public_key, fail=False):
+ origin = origin[:32].ljust(32, b'\0')
+ user = user[:32].ljust(32, b'\0')
+ challenge = challenge[:32].ljust(32, b'\0')
+ g2f_cmd = b'\0' + origin + challenge + kh + public_key
+ cmd = user + b'\0' + len(g2f_cmd).to_bytes(1, 'big') + g2f_cmd
+ if fail==False:
+ wrapped_response = tpm.command(tpm.wrap_ext_command(
+ subcmd.U2F_ATTEST, cmd))
+ response = tpm.unwrap_ext_response(subcmd.U2F_ATTEST, wrapped_response)
+ sig = response[:64]
+ else:
+ response, size, response_code = tpm.command_unchecked(
+ tpm.wrap_ext_command(subcmd.U2F_ATTEST, cmd))
+ if size != 12:
+ raise subcmd.TpmTestError('Unexpected response: '
+ + utils.hex_dump(response))
+ print('response: ', hex(response_code))
+ return b''
+ return sig
+
+def u2f_test(tpm):
+ """Run U2F tests"""
+ origin = b'1'
+ user = b'2'
+ auth = b'3'
+ msg = b'12345'
+ public_key1, khv1 = u2f_generate(tpm, origin, user, 0, auth)
+ print('key_handle v1 = ',utils.hex_dump(khv1), len(khv1))
+ print('public_key v1 = ',utils.hex_dump(public_key1), len(public_key1))
+
+ public_key2, khv2 = u2f_generate(tpm, origin, user, 8, auth)
+ print('key_handle v2 = ',utils.hex_dump(khv2), len(khv2))
+
+ sig1 = u2f_sign(tpm, origin, user, auth, khv1, msg, 2)
+ print('sig v1 = ',utils.hex_dump(sig1), len(sig1))
+
+ sig1 = u2f_sign(tpm, origin, user, auth, khv2, msg, 2)
+ print('sig v2 = ',utils.hex_dump(sig1), len(sig1))
+
+ sig1 = u2f_sign(tpm, user, origin, auth, khv2, msg, 2, fail=True)
+ print('sig v2 = ',utils.hex_dump(sig1), len(sig1))
+
+ sig_attest = u2f_attest(tpm, origin, user, auth, khv1, public_key1)
+ print('sig attest = ',utils.hex_dump(sig_attest), len(sig_attest))