1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# -*- 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))
if tpm.debug_enabled():
print('U2F sign 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)
if tpm.debug_enabled():
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)
if tpm.debug_enabled():
print('key_handle v2 = ',utils.hex_dump(khv2), len(khv2))
sig1 = u2f_sign(tpm, origin, user, auth, khv1, msg, 2)
if tpm.debug_enabled():
print('sig v1 = ',utils.hex_dump(sig1), len(sig1))
sig1 = u2f_sign(tpm, origin, user, auth, khv2, msg, 2)
if tpm.debug_enabled():
print('sig v2 = ',utils.hex_dump(sig1), len(sig1))
sig1 = u2f_sign(tpm, user, origin, auth, khv2, msg, 2, fail=True)
if tpm.debug_enabled():
print('sig v2 = ',utils.hex_dump(sig1), len(sig1))
sig_attest = u2f_attest(tpm, origin, user, auth, khv1, public_key1)
if tpm.debug_enabled():
print('sig attest = ',utils.hex_dump(sig_attest), len(sig_attest))
print('%sSUCCESS: %s' % (utils.cursor_back(), 'U2F test'))
|