mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-07 16:11:43 +00:00
I keep thinking this refers to "Embedded Controller" instead of "Elliptic Curve Cryptography". Make it clearer. There's no functional change, I'm just renaming a constant. BUG=none BRANCH=none TEST=make buildall; run tests on Cr50 dev board make -C test/tpm_test && sudo ./test/tpm_test/tpmtest.py Change-Id: Iaf2e2839e88fdbbcb1a712934be56a0dd47e4a70 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/366752 Reviewed-by: Nagendra Modadugu <ngm@google.com> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
166 lines
4.5 KiB
Python
166 lines
4.5 KiB
Python
#!/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.
|
|
|
|
"""Module for testing ecc functions using extended commands."""
|
|
import binascii
|
|
import hashlib
|
|
import os
|
|
import struct
|
|
|
|
import subcmd
|
|
import utils
|
|
|
|
_ECC_OPCODES = {
|
|
'SIGN': 0x00,
|
|
'VERIFY': 0x01,
|
|
'KEYGEN': 0x02,
|
|
'KEYDERIVE': 0x03,
|
|
}
|
|
|
|
_ECC_CURVES = {
|
|
'NIST-P256': 0x03,
|
|
}
|
|
|
|
# TPM2 signature codes.
|
|
_SIGN_MODE = {
|
|
'NONE': 0x00,
|
|
'ECDSA': 0x18,
|
|
# TODO(ngm): add support for SCHNORR.
|
|
# 'SCHNORR': 0x1c
|
|
}
|
|
|
|
# TPM2 ALG codes.
|
|
_HASH = {
|
|
'NONE': 0x00,
|
|
'SHA1': 0x04,
|
|
'SHA256': 0x0B
|
|
}
|
|
|
|
_HASH_FUNC = {
|
|
'NIST-P256': hashlib.sha256
|
|
}
|
|
|
|
# Command format.
|
|
#
|
|
# 0x00 OP
|
|
# 0x00 CURVE_ID
|
|
# 0x00 SIGN_MODE
|
|
# 0x00 HASHING
|
|
# 0x00 MSB IN LEN
|
|
# 0x00 LSB IN LEN
|
|
# .... IN
|
|
# 0x00 MSB DIGEST LEN
|
|
# 0x00 LSB DIGEST LEN
|
|
# .... DIGEST
|
|
#
|
|
_ECC_CMD_FORMAT = '{o:c}{c:c}{s:c}{h:c}{ml:s}{msg}{dl:s}{dig}'
|
|
|
|
|
|
def _sign_cmd(curve_id, hash_func, sign_mode, msg):
|
|
op = _ECC_OPCODES['SIGN']
|
|
digest = hash_func(msg).digest()
|
|
digest_len = len(digest)
|
|
return _ECC_CMD_FORMAT.format(o=op, c=curve_id, s=sign_mode, h=_HASH['NONE'],
|
|
ml=struct.pack('>H', 0), msg='',
|
|
dl=struct.pack('>H', digest_len), dig=digest)
|
|
|
|
|
|
def _verify_cmd(curve_id, hash_func, sign_mode, msg, sig):
|
|
op = _ECC_OPCODES['VERIFY']
|
|
sig_len = len(sig)
|
|
digest = hash_func(msg).digest()
|
|
digest_len = len(digest)
|
|
return _ECC_CMD_FORMAT.format(o=op, c=curve_id, s=sign_mode, h=_HASH['NONE'],
|
|
ml=struct.pack('>H', sig_len), msg=sig,
|
|
dl=struct.pack('>H', digest_len), dig=digest)
|
|
|
|
|
|
def _keygen_cmd(curve_id):
|
|
op = _ECC_OPCODES['KEYGEN']
|
|
return _ECC_CMD_FORMAT.format(o=op, c=curve_id, s=_SIGN_MODE['NONE'],
|
|
h=_HASH['NONE'], ml=struct.pack('>H', 0), msg='',
|
|
dl=struct.pack('>H', 0), dig='')
|
|
|
|
|
|
def _keyderive_cmd(curve_id, seed):
|
|
op = _ECC_OPCODES['KEYDERIVE']
|
|
seed_len = len(seed)
|
|
return _ECC_CMD_FORMAT.format(o=op, c=curve_id, s=_SIGN_MODE['NONE'],
|
|
h=_HASH['NONE'], ml=struct.pack('>H', seed_len),
|
|
msg=seed, dl=struct.pack('>H', 0), dig='')
|
|
|
|
|
|
_SIGN_INPUTS = (
|
|
('NIST-P256', 'ECDSA'),
|
|
)
|
|
|
|
|
|
_KEYGEN_INPUTS = (
|
|
('NIST-P256',),
|
|
)
|
|
|
|
|
|
_KEYDERIVE_INPUTS = (
|
|
# Curve-id, random seed size.
|
|
('NIST-P256', 32),
|
|
)
|
|
|
|
|
|
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 _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 _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 ecc_test(tpm):
|
|
_sign_test(tpm)
|
|
_keygen_test(tpm)
|
|
_keyderive_test(tpm)
|