summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cr50/tpm2/ecc.c324
-rw-r--r--test/tpm_test/ecc_test.py188
2 files changed, 368 insertions, 144 deletions
diff --git a/board/cr50/tpm2/ecc.c b/board/cr50/tpm2/ecc.c
index 3aea411487..95afd01ce9 100644
--- a/board/cr50/tpm2/ecc.c
+++ b/board/cr50/tpm2/ecc.c
@@ -361,13 +361,17 @@ CRYPT_RESULT _cpri__GetEphemeralEcc(TPMS_ECC_POINT *q, TPM2B_ECC_PARAMETER *d,
#ifdef CRYPTO_TEST_SETUP
+#include "console.h"
#include "extension.h"
enum {
TEST_SIGN = 0,
TEST_VERIFY = 1,
TEST_KEYGEN = 2,
- TEST_KEYDERIVE = 3
+ TEST_KEYDERIVE = 3,
+ TEST_POINT = 4,
+ TEST_VERIFY_ANY = 5,
+ TEST_SIGN_ANY = 6,
};
struct TPM2B_ECC_PARAMETER_aligned {
@@ -434,182 +438,278 @@ static int point_equals(const TPMS_ECC_POINT *a, const TPMS_ECC_POINT *b)
return !diff;
}
+/**
+ * Parse TPM_2B data, copy data to destination, update position
+ * @param ptr - pointer to current position, updated if parsed successfully
+ * @param cmd_size - remaining number of bytes, [in/out]
+ * @param len [out] - length of parsed data
+ * @param out [out] - destination buffer to copy data
+ * @param out_len - size of destination buffer
+ */
+static int parse_2b(uint8_t **ptr, size_t *cmd_size, uint16_t *len,
+ uint8_t *out, size_t out_len)
+{
+ uint16_t length;
+ uint8_t *local_ptr = *ptr;
+
+ *len = 0;
+ /* if there is no space for 2 bytes of length, exit */
+ if (*cmd_size < sizeof(length))
+ return 0;
+ length = local_ptr[0];
+ length = (length << 8) | local_ptr[1];
+ *cmd_size -= sizeof(length);
+ local_ptr += 2;
+ if (*cmd_size < length || length > out_len) {
+ ccprintf("%s: length = %d (0x%4x),"
+ " data available = %d, out_len = %d\n",
+ __func__, length, length, *cmd_size, out_len);
+ *cmd_size = 0;
+ return 0;
+ }
+ *len = length;
+ memcpy(out, local_ptr, length);
+ *ptr = local_ptr + length;
+ *cmd_size -= length;
+ return 1;
+}
+
+static void store_2b(uint8_t **ptr, size_t *rsp_size, TPM2B_ECC_PARAMETER *p)
+{
+ uint8_t *out = *ptr;
+
+ *out++ = p->t.size >> 8;
+ *out++ = p->t.size & 0xff;
+ memcpy(out, p->t.buffer, p->t.size);
+ *ptr = out + p->t.size;
+ *rsp_size += 2 + p->t.size;
+}
+
static void ecc_command_handler(void *cmd_body, size_t cmd_size,
size_t *response_size_out)
{
uint8_t *cmd;
uint8_t op;
uint8_t curve_id;
- uint8_t sign_mode;
- uint8_t hashing;
- uint16_t in_len;
- uint8_t in[MAX_MSG_BYTES];
- uint16_t digest_len;
+ uint8_t sign_mode = 0;
+ uint8_t hashing = 0;
+ TPM2B_SEED seed;
+
struct TPM2B_MAX_BUFFER_aligned digest;
uint8_t *out = (uint8_t *) cmd_body;
- uint32_t *response_size = (uint32_t *) response_size_out;
+ size_t *response_size = response_size_out;
TPMS_ECC_POINT q;
TPM2B_ECC_PARAMETER d;
struct TPM2B_ECC_PARAMETER_aligned r;
struct TPM2B_ECC_PARAMETER_aligned s;
-
- /* Command format.
+ /**
+ * Command formats:
+ *
+ * TEST_SIGN:
+ * OP | CURVE_ID | SIGN_MODE | HASHING | DIGEST_LEN | DIGEST
+ * @returns 0/1 | R_LEN | R | S_LEN | S
+ *
+ * TEST_SIGN_ANY:
+ * OP | CURVE_ID | SIGN_MODE | HASHING | DIGEST_LEN | DIGEST |
+ * D_LEN | D
+ * @returns 0/1 | R_LEN | R | S_LEN | S
+ *
+ * TEST_VERIFY:
+ * OP | CURVE_ID | SIGN_MODE | HASHING | R_LEN | R | S_LEN | S
+ * DIGEST_LEN | DIGEST
+ * @returns 0/1 | if successful
+ *
+ * TEST_VERIFY_ANY:
+ * OP | CURVE_ID | SIGN_MODE | HASHING | R_LEN | R | S_LEN | S |
+ * DIGEST_LEN | DIGEST | QX_LEN | QX | QY_LEN | QY
+ * @returns 1 if successful
+ *
+ * TEST_KEYDERIVE :
+ * OP | CURVE_ID | SEED_LEN | SEED
+ * @returns 1 if successful
+ *
+ * TEST_POINT:
+ * OP | CURVE_ID | QX_LEN | QX | QY_LEN | QY
+ * @returns 1 if point is on curve
*
- * OFFSET FIELD
- * 0 OP
- * 1 CURVE_ID
- * 2 SIGN_MODE
- * 3 HASHING
- * 4 MSB IN LEN
- * 5 LSB IN LEN
- * 6 IN
- * 6 + IN_LEN MSB DIGEST LEN
- * 7 + IN_LEN LSB DIGEST LEN
- * 8 + IN_LEN DIGEST
+ * TEST_KEYGEN:
+ * OP | CURVE_ID
+ * @returns 0/1 | D_LEN | D | QX_LEN | QX | QY_LEN | QY
+ *
+ * Field size:
+ * FIELD LENGTH
+ * OP 1
+ * CURVE_ID 1
+ * SIGN_MODE 1
+ * HASHING 1
+ * MSG_LEN 2 (big endian)
+ * MSG MSG_LEN
+ * SEED_LEN 2 (big endian)
+ * SEED SEED_LEN
+ * R_LEN 2 (big endian)
+ * R R_LEN
+ * S_LEN 2 (big endian)
+ * S S_LEN
+ * DIGEST_LEN 2 (big endian)
+ * DIGEST DIGEST_LEN
+ * D_LEN 2 (big endian)
+ * D D_LEN
+ * QX_LEN 2 (big endian)
+ * QX QX_LEN
+ * QY_LEN 2 (big endian)
+ * QY QX_LEN
*/
+ *response_size = 0;
+ if (cmd_size < 2)
+ return;
- cmd = (uint8_t *) cmd_body;
+ cmd = (uint8_t *)cmd_body;
op = *cmd++;
curve_id = *cmd++;
- sign_mode = *cmd++;
- hashing = *cmd++;
- in_len = ((uint16_t) (cmd[0] << 8)) | cmd[1];
- cmd += 2;
- if (in_len > sizeof(in)) {
- *response_size = 0;
- return;
+ cmd_size -= 2;
+
+ if (op == TEST_SIGN || op == TEST_VERIFY || op == TEST_VERIFY_ANY ||
+ op == TEST_SIGN_ANY) {
+ if (cmd_size >= 2) {
+ sign_mode = *cmd++;
+ hashing = *cmd++;
+ cmd_size -= 2;
+ } else
+ return;
+ }
+
+ if (op == TEST_SIGN || op == TEST_SIGN_ANY) {
+ if (!parse_2b(&cmd, &cmd_size, &digest.d.t.size,
+ digest.d.t.buffer, sizeof(digest.d.t.buffer)))
+ return;
+ if (op == TEST_SIGN_ANY &&
+ !parse_2b(&cmd, &cmd_size, &d.t.size, d.t.buffer,
+ sizeof(d.t.buffer)))
+ return;
+ if (op == TEST_SIGN) {
+ if (curve_id == TPM_ECC_NIST_P256)
+ d = NIST_P256_d.d;
+ else
+ return;
+ }
}
- memcpy(in, cmd, in_len);
- cmd += in_len;
- digest_len = ((uint16_t) (cmd[0] << 8)) | cmd[1];
- cmd += 2;
- if (digest_len > sizeof(digest.d.t.buffer)) {
- *response_size = 0;
+ if (op == TEST_KEYDERIVE &&
+ !parse_2b(&cmd, &cmd_size, &seed.t.size, seed.t.buffer,
+ sizeof(seed.t.buffer)))
return;
+
+ if (op == TEST_VERIFY || op == TEST_VERIFY_ANY) {
+ if (!parse_2b(&cmd, &cmd_size, &r.d.t.size, r.d.t.buffer,
+ sizeof(r.d.t.buffer)))
+ return;
+ if (!parse_2b(&cmd, &cmd_size, &s.d.t.size, s.d.t.buffer,
+ sizeof(s.d.t.buffer)))
+ return;
+ if (!parse_2b(&cmd, &cmd_size, &digest.d.t.size,
+ digest.d.t.buffer, sizeof(digest.d.t.buffer)))
+ return;
}
- digest.d.t.size = digest_len;
- memcpy(digest.d.t.buffer, cmd, digest_len);
- cmd += digest_len;
- /* Make copies of d, and q, as const data is immutable. */
- switch (curve_id) {
- case TPM_ECC_NIST_P256:
- d = NIST_P256_d.d;
+ if (op == TEST_VERIFY_ANY || op == TEST_POINT) {
+ if (!parse_2b(&cmd, &cmd_size, &q.x.t.size, q.x.t.buffer,
+ sizeof(q.x.t.buffer)))
+ return;
+ if (!parse_2b(&cmd, &cmd_size, &q.y.t.size, q.y.t.buffer,
+ sizeof(q.y.t.buffer)))
+ return;
+ } else {
+ /* use fixed signature */
q.x = NIST_P256_qx.d;
q.y = NIST_P256_qy.d;
- break;
- default:
- *response_size = 0;
- return;
}
+ /* there should be no other data as command is parsed */
+ if (cmd_size != 0)
+ return;
+
+ *out = 0;
+ *response_size = 1;
switch (op) {
case TEST_SIGN:
- if (_cpri__SignEcc(&r.d, &s.d, sign_mode, hashing,
- curve_id, &d, &digest.d.b, NULL)
- != CRYPT_SUCCESS) {
- *response_size = 0;
+ case TEST_SIGN_ANY:
+ if (hashing != TPM_ALG_SHA256 && hashing != TPM_ALG_NULL)
+ return;
+ if (_cpri__SignEcc(&r.d, &s.d, sign_mode, hashing, curve_id, &d,
+ &digest.d.b, NULL) != CRYPT_SUCCESS) {
+ ccprintf("test_sign: error signing\n");
return;
}
- memcpy(out, r.d.b.buffer, r.d.b.size);
- out += r.d.b.size;
- memcpy(out, s.d.b.buffer, s.d.b.size);
- *response_size = r.d.b.size + s.d.b.size;
+ *out++ = 1;
+ store_2b(&out, response_size, &r.d);
+ store_2b(&out, response_size, &s.d);
break;
case TEST_VERIFY:
- r.d.b.size = in_len / 2;
- memcpy(r.d.b.buffer, in, r.d.b.size);
- s.d.b.size = in_len / 2;
- memcpy(s.d.b.buffer, in + r.d.b.size, s.d.b.size);
- if (_cpri__ValidateSignatureEcc(
- &r.d, &s.d, sign_mode, hashing, curve_id,
- &q, &digest.d.b) != CRYPT_SUCCESS) {
- *response_size = 0;
- } else {
+ case TEST_VERIFY_ANY:
+ if (_cpri__ValidateSignatureEcc(&r.d, &s.d, sign_mode, hashing,
+ curve_id, &q,
+ &digest.d.b) != CRYPT_SUCCESS) {
+ ccprintf("test_verify: verification failed\n");
+ } else
*out = 1;
- *response_size = 1;
- }
return;
- case TEST_KEYGEN:
- {
+ case TEST_KEYGEN: {
struct TPM2B_ECC_PARAMETER_aligned d_local;
TPMS_ECC_POINT q_local;
if (_cpri__GetEphemeralEcc(&q, &d_local.d, curve_id)
- != CRYPT_SUCCESS) {
- *response_size = 0;
+ != CRYPT_SUCCESS)
return;
- }
- if (_cpri__EccIsPointOnCurve(curve_id, &q) != TRUE) {
- *response_size = 0;
+
+ if (_cpri__EccIsPointOnCurve(curve_id, &q) != TRUE)
return;
- }
/* Verify correspondence of secret with the public point. */
if (_cpri__EccPointMultiply(
&q_local, curve_id, &d_local.d,
- NULL, NULL) != CRYPT_SUCCESS) {
- *response_size = 0;
+ NULL, NULL) != CRYPT_SUCCESS)
return;
- }
- if (!point_equals(&q, &q_local)) {
- *response_size = 0;
+ if (!point_equals(&q, &q_local))
return;
- }
- *out = 1;
- *response_size = 1;
+
+ *out++ = 1;
+ store_2b(&out, response_size, &d_local.d);
+ store_2b(&out, response_size, &q.x);
+ store_2b(&out, response_size, &q.y);
return;
}
- case TEST_KEYDERIVE:
- {
- /* Random seed. */
- TPM2B_SEED seed;
+ case TEST_KEYDERIVE: {
struct TPM2B_ECC_PARAMETER_aligned d_local;
TPMS_ECC_POINT q_local;
const char *label = "ecc_test";
-
- if (in_len > PRIMARY_SEED_SIZE) {
- *response_size = 0;
+ if (_cpri__GenerateKeyEcc(&q, &d_local.d, curve_id, hashing,
+ &seed.b, label, NULL,
+ NULL) != CRYPT_SUCCESS)
return;
- }
- seed.t.size = in_len;
- memcpy(seed.t.buffer, in, in_len);
-
- if (_cpri__GenerateKeyEcc(
- &q, &d_local.d, curve_id, hashing,
- &seed.b, label, NULL, NULL) != CRYPT_SUCCESS) {
- *response_size = 0;
- return;
- }
- if (_cpri__EccIsPointOnCurve(curve_id, &q) != TRUE) {
- *response_size = 0;
+ if (_cpri__EccIsPointOnCurve(curve_id, &q) != TRUE)
return;
- }
/* Verify correspondence of secret with the public point. */
- if (_cpri__EccPointMultiply(
- &q_local, curve_id, &d_local.d,
- NULL, NULL) != CRYPT_SUCCESS) {
- *response_size = 0;
+ if (_cpri__EccPointMultiply(&q_local, curve_id, &d_local.d,
+ NULL, NULL) != CRYPT_SUCCESS)
return;
- }
- if (!point_equals(&q, &q_local)) {
- *response_size = 0;
+
+ if (!point_equals(&q, &q_local))
return;
- }
*out = 1;
- *response_size = 1;
- return;
+ break;
}
+ case TEST_POINT:
+ *out = _cpri__EccIsPointOnCurve(curve_id, &q);
+ break;
+
default:
- *response_size = 0;
- return;
+ break;
}
}
diff --git a/test/tpm_test/ecc_test.py b/test/tpm_test/ecc_test.py
index 155a497b98..9ec34c2f21 100644
--- a/test/tpm_test/ecc_test.py
+++ b/test/tpm_test/ecc_test.py
@@ -4,7 +4,7 @@
# found in the LICENSE file.
"""Module for testing ecc functions using extended commands."""
-import binascii
+from binascii import a2b_hex as a2b
import hashlib
import os
import struct
@@ -17,6 +17,9 @@ _ECC_OPCODES = {
'VERIFY': 0x01,
'KEYGEN': 0x02,
'KEYDERIVE': 0x03,
+ 'TEST_POINT': 0x04,
+ 'VERIFY_ANY': 0x05,
+ 'SIGN_ANY': 0x06,
}
_ECC_CURVES = {
@@ -42,54 +45,134 @@ _HASH_FUNC = {
'NIST-P256': hashlib.sha256
}
-# Command format.
+NIST_P256_QX = ('12c3d6a2679ca8ee3c4d927f204ed5bc'
+ 'b4577a04b0ac02b2a36ab3e9e10781de')
+NIST_P256_QY = ('5c85ad7413971172fca5738fee9d0e7b'
+ 'c59ffd8a626d689bc6cca4b58665521d')
+
+PKEY = ('fc441e07744e48f109b7e66b29482f7b'
+ '7e3ec91fa27fd4870991b289fea0d20a')
+
+##
+# Field size:
+# FIELD LENGTH
+# OP 1
+# CURVE_ID 1
+# SIGN_MODE 1
+# HASHING 1
+# MSG_LEN 2 (big endian)
+# MSG MSG_LEN
+# R_LEN 2 (big endian)
+# R R_LEN
+# S_LEN 2 (big endian)
+# S S_LEN
+# DIGEST_LEN 2 (big endian)
+# DIGEST DIGEST_LEN
+# D_LEN 2 (big endian)
+# D D_LEN
+# QX_LEN 2 (big endian)
+# QX QX_LEN
+# QY_LEN 2 (big endian)
+# QY QX_LEN
#
-# 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
+# Command formats:
#
-_ECC_CMD_FORMAT = '{o:c}{c:c}{s:c}{h:c}{ml:s}{msg}{dl:s}{dig}'
+# TEST_SIGN:
+# OP | CURVE_ID | SIGN_MODE | HASHING | DIGEST_LEN | DIGEST
+# @returns 0/1 | R_LEN | R | S_LEN | S
+_TEST_SIGN = '{o:c}{c:c}{s:c}{h:c}{dl:s}{dig}'
+# TEST_SIGN_ANY:
+# OP | CURVE_ID | SIGN_MODE | HASHING | DIGEST_LEN | DIGEST | D_LEN | D
+# @returns 0/1 | R_LEN | R | S_LEN | S
+_TEST_SIGN_ANY = '{o:c}{c:c}{s:c}{h:c}{dl:s}{dig}{pl:s}{pk}'
+
+#
+# TEST_VERIFY:
+# OP | CURVE_ID | SIGN_MODE | HASHING | R_LEN | R | S_LEN | S
+# DIGEST_LEN | DIGEST
+# @returns 1 if successful
+_TEST_VERIFY = '{o:c}{c:c}{sm:c}{h:c}{rs}{dl:s}{dig}'
+
+# TEST_VERIFY_ANY:
+# OP | CURVE_ID | SIGN_MODE | HASHING | R_LEN | R | S_LEN | S |
+# DIGEST_LEN | DIGEST | QX_LEN | QX | QY_LEN | QY
+# @returns 1 if successful
+_TEST_VERIFY_ANY = _TEST_VERIFY + '{qxl:s}{qx}{qyl:s}{qy}'
+
+# TEST_KEYDERIVE:
+# OP | CURVE_ID | SEED_LEN | SEED
+# @returns 1 if successful
+#
+_TEST_KEYDERIVE = '{o:c}{c:c}{ml:s}{msg}'
+
+# TEST_POINT:
+# OP | CURVE_ID | QX_LEN | QX | QY_LEN | QY
+# @returns 1 if point is on curve
+
+_TEST_POINT = '{o:c}{c:c}{qxl:s}{qx}{qyl:s}{qy}'
+
+#
+# TEST_KEYGEN:
+# OP | CURVE_ID
+# @returns 0/1 | D_LEN | D | QX_LEN | QX | QY_LEN | QY
+#
+_TEST_KEYGEN = '{o:c}{c:c}'
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)
+ return _TEST_SIGN.format(o=op, c=curve_id, s=sign_mode, h=_HASH['SHA256'],
+ dl=struct.pack('>H', digest_len), dig=digest)
+
+def _sign_any_cmd(curve_id, hash_func, sign_mode, msg, pkey):
+ op = _ECC_OPCODES['SIGN_ANY']
+ digest = hash_func(msg).digest()
+ digest_len = len(digest)
+ return _TEST_SIGN_ANY.format(o=op, c=curve_id, s=sign_mode,
+ h=_HASH['SHA256'],
+ dl=struct.pack('>H', digest_len), dig=digest,
+ pl=struct.pack('>H', len(pkey)), pk=pkey)
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)
+ return _TEST_VERIFY.format(o=op, c=curve_id, sm=sign_mode, h=_HASH['SHA256'],
+ rs=sig,
+ dl=struct.pack('>H', digest_len),
+ dig=digest)
+
+def _verify_any_cmd(curve_id, hash_func, sign_mode, msg, sig, qx, qy):
+ op = _ECC_OPCODES['VERIFY_ANY']
+ digest = hash_func(msg).digest()
+ digest_len = len(digest)
+ return _TEST_VERIFY_ANY.format(o=op, c=curve_id, sm=sign_mode,
+ h=_HASH['SHA256'],
+ rs=sig,
+ dl=struct.pack('>H', digest_len), dig=digest,
+ qxl=struct.pack('>H', len(qx)), qx=qx,
+ qyl=struct.pack('>H', len(qy)), qy=qy)
+
+def _test_point_cmd(curve_id, qx, qy):
+ op = _ECC_OPCODES['TEST_POINT']
+ return _TEST_POINT.format(o=op, c=curve_id,
+ qxl=struct.pack('>H', len(qx)), qx=qx,
+ qyl=struct.pack('>H', len(qy)), qy=qy)
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='')
+ return _TEST_KEYGEN.format(o=op, c=curve_id)
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='')
+ return _TEST_KEYDERIVE.format(o=op, c=curve_id,
+ ml=struct.pack('>H', seed_len), msg=seed)
_SIGN_INPUTS = (
@@ -117,18 +200,57 @@ def _sign_test(tpm):
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))
+ expected = '\x01'
signature = tpm.unwrap_ext_response(subcmd.ECC, wrapped_response)
-
+ if signature[:1] != expected:
+ raise subcmd.TpmTestError('%s error:%s:%s' % (
+ test_name, utils.hex_dump(signature[:1]), utils.hex_dump(expected)))
cmd = _verify_cmd(_ECC_CURVES[curve_id], _HASH_FUNC[curve_id],
- _SIGN_MODE[sign_mode], msg, signature)
+ _SIGN_MODE[sign_mode], msg, signature[1:])
wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECC, cmd))
verified = tpm.unwrap_ext_response(subcmd.ECC, wrapped_response)
+
+ if verified[:1] != expected:
+ raise subcmd.TpmTestError('%s error:%s:%s' % (
+ test_name, utils.hex_dump(verified[:1]), utils.hex_dump(expected)))
+ print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
+
+def _sign_test_any(tpm):
+ msg = 'Hello CR50'
+
+ for data in _SIGN_INPUTS:
+ curve_id, sign_mode = data
+ test_name = 'ECC-SIGN, Q:%s:%s' % data
+ cmd = _sign_any_cmd(_ECC_CURVES[curve_id], _HASH_FUNC[curve_id],
+ _SIGN_MODE[sign_mode], msg, a2b(PKEY))
+ wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECC, cmd))
expected = '\x01'
- if verified != expected:
+ signature = tpm.unwrap_ext_response(subcmd.ECC, wrapped_response)
+ if signature[:1] != expected:
+ raise subcmd.TpmTestError('%s error:%s:%s' % (
+ test_name, utils.hex_dump(signature[:1]), utils.hex_dump(expected)))
+ # make sure properly supplied Q.x, Q.y works
+ cmd = _verify_any_cmd(_ECC_CURVES[curve_id], _HASH_FUNC[curve_id],
+ _SIGN_MODE[sign_mode], msg, signature[1:],
+ a2b(NIST_P256_QX), a2b(NIST_P256_QY))
+ wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.ECC, cmd))
+ verified = tpm.unwrap_ext_response(subcmd.ECC, wrapped_response)
+ if verified[:1] != expected:
raise subcmd.TpmTestError('%s error:%s:%s' % (
- test_name, utils.hex_dump(verified), utils.hex_dump(expected)))
+ test_name, utils.hex_dump(verified[:1]), utils.hex_dump(expected)))
print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
+def _point_test(tpm):
+ test_name = 'POINT-TEST: NIST-P256'
+ cmd = _test_point_cmd(_ECC_CURVES['NIST-P256'],
+ a2b(NIST_P256_QX), a2b(NIST_P256_QY))
+ 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:
@@ -138,9 +260,9 @@ def _keygen_test(tpm):
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:
+ if valid[:1] != expected:
raise subcmd.TpmTestError('%s error:%s:%s' % (
- test_name, utils.hex_dump(valid), utils.hex_dump(expected)))
+ test_name, utils.hex_dump(valid[:1]), utils.hex_dump(expected)))
print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
@@ -161,5 +283,7 @@ def _keyderive_test(tpm):
def ecc_test(tpm):
_sign_test(tpm)
+ _sign_test_any(tpm)
+ _point_test(tpm)
_keygen_test(tpm)
_keyderive_test(tpm)