Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 60 additions & 6 deletions examples/htool.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,65 @@ static int command_show_chipinfo(const struct htool_invocation* inv) {
if (!dev) {
return -1;
}

struct hoth_response_chip_info response;
int status = libhoth_chipinfo(dev, &response);
if (status != 0) {
return -1;
}

printf("Chip Info:\n");
printf("Hardware Identity: 0x%016llx\n",
(unsigned long long)response.hardware_identity);
printf("Hardware Category: %d\n", response.hardware_category);
printf("Info Variant: %lu\n", (unsigned long)response.info_variant);
if (response.version == 0) {
printf("Hardware Identity: 0x%016llx\n",
(unsigned long long)response.data.hoth_device_id.hardware_identity);
printf("Hardware Category: %u\n",
(unsigned)response.data.hoth_device_id.hardware_category);
printf("Info Variant: %lu\n",
(unsigned long)response.data.hoth_device_id.info_variant);
return 0;
}

if (response.version != 1) {
printf("Unsupported chipinfo version: %u\n", response.version);
return -1;
}

uint8_t* id = response.data.open_titan_device_id;
struct opentitan_device_id parsed_id;
if (parse_opentitan_device_id(id, &parsed_id) != 0) {
printf("Failed to parse OpenTitan Device ID\n");
return -1;
}

printf("OpenTitan iSerial: 0x");
for (int i = 0; i < 32; i++) {
printf("%02x", id[i]);
}
printf("\nOpenTitan Device ID: 0x");
for (int i = 20; i < 32; i++) {
Comment thread
paipeng-g marked this conversation as resolved.
printf("%02x", id[i]);
}
printf("\n\nGeneric Identifier:\n");

printf(" %-22s 0x%04x\n", "SI Creator ID:", parsed_id.creator_id);
printf(" %-22s 0x%04x\n", "Product ID:", parsed_id.product_id);
printf(" %-22s %u week %02u\n", "Device Date:", parsed_id.device_year,
parsed_id.device_week);
printf(" %-22s %u\n", "Lot Number:", parsed_id.lot_number);
printf(" %-22s %u\n", "Wafer Number:", parsed_id.wafer_number);
printf(" %-22s %u\n", "Wafer X Coord:", parsed_id.wafer_x);
printf(" %-22s %u\n", "Wafer Y Coord:", parsed_id.wafer_y);
printf(" %-22s 0x%02x\n", "Reserved DIN:", parsed_id.reserved_din);
printf(" %-22s 0x%08x\n", "Reserved:", parsed_id.reserved);
printf("\nSKU-specific Identifier:\n");
printf(" %-22s %u\n", "Package ID:", parsed_id.package_id);
printf(" %-22s %u\n", "AST Config Version:", parsed_id.ast_config_version);
printf(" %-22s \"%s\"\n", "OTP ID:", parsed_id.otp_id);
printf(" %-22s %u\n", "OTP Version:", parsed_id.otp_version);
printf(" %-22s \"%s\"\n", "SKU ID String:", parsed_id.sku_id_string);
printf(" %-22s %u\n",
"SKU Specific Version:", parsed_id.sku_specific_version);

return 0;
}

Expand Down Expand Up @@ -215,6 +264,11 @@ static int command_authz_host_command_build(
fprintf(stderr, "Failed to get chip ID. status=%d\n", status);
return -1;
}
if (chipinfo_resp.version != 0) {
Comment thread
paipeng-g marked this conversation as resolved.
fprintf(stderr, "Unsupported chipinfo version: %u\n",
chipinfo_resp.version);
return -1;
}

struct hoth_authorized_command_get_nonce_response nonce_resp;
status = libhoth_hostcmd_exec(
Expand All @@ -227,8 +281,8 @@ static int command_authz_host_command_build(
}

struct hoth_authorized_command_request request = authz_command_build_request(
chipinfo_resp.hardware_identity, opcode, nonce_resp.supported_key_info,
nonce_resp.nonce);
chipinfo_resp.data.hoth_device_id.hardware_identity, opcode,
nonce_resp.supported_key_info, nonce_resp.nonce);
authz_command_print_request(&request);
return 0;
}
Expand Down
11 changes: 9 additions & 2 deletions protocol/authz_record.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,15 @@ int libhoth_authz_record_build(struct libhoth_device* dev,
if (status != 0) {
return -1;
}
record->dev_id_0 = chipinfo_resp.hardware_identity & 0xfffffffful;
record->dev_id_1 = (chipinfo_resp.hardware_identity >> 32);
if (chipinfo_resp.version != 0) {
fprintf(stderr, "Unsupported chipinfo version: %u\n",
chipinfo_resp.version);
return -1;
}
record->dev_id_0 =
chipinfo_resp.data.hoth_device_id.hardware_identity & 0xfffffffful;
record->dev_id_1 =
(chipinfo_resp.data.hoth_device_id.hardware_identity >> 32);

struct hoth_authz_record_get_nonce_response nonce_resp;
status = libhoth_hostcmd_exec(
Expand Down
32 changes: 16 additions & 16 deletions protocol/authz_record_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ TEST_F(LibHothTest, authz_read_test) {
}

TEST_F(LibHothTest, authz_build_test) {
struct hoth_response_chip_info chipinfo = {};
chipinfo.hardware_identity = 0xABCD;
chipinfo.hardware_identity |= (0x1234UL << 32);
struct libhoth_hoth_device_id hoth_data = {};
hoth_data.hardware_identity = 0xABCD;
hoth_data.hardware_identity |= (0x1234UL << 32);

struct hoth_authz_record_get_nonce_response nonce_resp = {};
nonce_resp.ro_supported_key_id = 1;
Expand All @@ -98,7 +98,7 @@ TEST_F(LibHothTest, authz_build_test) {

EXPECT_CALL(mock_, receive)
.WillOnce(
DoAll(CopyResp(&chipinfo, sizeof(chipinfo)), Return(LIBHOTH_OK)))
DoAll(CopyResp(&hoth_data, sizeof(hoth_data)), Return(LIBHOTH_OK)))
.WillOnce(
DoAll(CopyResp(&nonce_resp, sizeof(nonce_resp)), Return(LIBHOTH_OK)));

Expand All @@ -115,9 +115,9 @@ TEST_F(LibHothTest, authz_build_test) {
}

TEST_F(LibHothTest, authz_build_fail_test) {
struct hoth_response_chip_info chipinfo = {};
chipinfo.hardware_identity = 0xABCD;
chipinfo.hardware_identity |= (0x1234UL << 32);
struct libhoth_hoth_device_id hoth_data = {};
hoth_data.hardware_identity = 0xABCD;
hoth_data.hardware_identity |= (0x1234UL << 32);

// key_id supported by RO and RW. These key_id's are expected to match one
// another to successfully program an authorization record. key_id == 0 should
Expand All @@ -140,7 +140,7 @@ TEST_F(LibHothTest, authz_build_fail_test) {

EXPECT_CALL(mock_, receive)
.WillOnce(
DoAll(CopyResp(&chipinfo, sizeof(chipinfo)), Return(LIBHOTH_OK)))
DoAll(CopyResp(&hoth_data, sizeof(hoth_data)), Return(LIBHOTH_OK)))
.WillOnce(
DoAll(CopyResp(&nonce_resp, sizeof(nonce_resp)), Return(LIBHOTH_OK)));

Expand All @@ -151,9 +151,9 @@ TEST_F(LibHothTest, authz_build_fail_test) {
}

TEST_F(LibHothTest, authz_mismatch_key_id_test) {
struct hoth_response_chip_info chipinfo = {};
chipinfo.hardware_identity = 0xABCD;
chipinfo.hardware_identity |= (0x1234UL << 32);
struct libhoth_hoth_device_id hoth_data = {};
hoth_data.hardware_identity = 0xABCD;
hoth_data.hardware_identity |= (0x1234UL << 32);

// key_id supported by RO and RW. These key_id's are expected to match one
// another to successfully program an authorization record. key_id == 0 should
Expand All @@ -176,7 +176,7 @@ TEST_F(LibHothTest, authz_mismatch_key_id_test) {

EXPECT_CALL(mock_, receive)
.WillOnce(
DoAll(CopyResp(&chipinfo, sizeof(chipinfo)), Return(LIBHOTH_OK)))
DoAll(CopyResp(&hoth_data, sizeof(hoth_data)), Return(LIBHOTH_OK)))
.WillOnce(
DoAll(CopyResp(&nonce_resp, sizeof(nonce_resp)), Return(LIBHOTH_OK)));

Expand All @@ -187,9 +187,9 @@ TEST_F(LibHothTest, authz_mismatch_key_id_test) {
}

TEST_F(LibHothTest, authz_nonce_fail_test) {
struct hoth_response_chip_info chipinfo = {};
chipinfo.hardware_identity = 0xABCD;
chipinfo.hardware_identity |= (0x1234UL << 32);
struct libhoth_hoth_device_id hoth_data = {};
hoth_data.hardware_identity = 0xABCD;
hoth_data.hardware_identity |= (0x1234UL << 32);

struct hoth_authz_record_get_nonce_response nonce_resp = {};
nonce_resp.ro_supported_key_id = 0;
Expand All @@ -208,7 +208,7 @@ TEST_F(LibHothTest, authz_nonce_fail_test) {

EXPECT_CALL(mock_, receive)
.WillOnce(
DoAll(CopyResp(&chipinfo, sizeof(chipinfo)), Return(LIBHOTH_OK)))
DoAll(CopyResp(&hoth_data, sizeof(hoth_data)), Return(LIBHOTH_OK)))
.WillOnce(
DoAll(CopyResp(&nonce_resp, sizeof(nonce_resp)), Return(LIBHOTH_OK)));

Expand Down
62 changes: 60 additions & 2 deletions protocol/chipinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,69 @@

#include "chipinfo.h"

#include <string.h>

#include "host_cmd.h"

int libhoth_chipinfo(struct libhoth_device* dev,
struct hoth_response_chip_info* chipinfo) {
return libhoth_hostcmd_exec(
uint8_t resp_buf[32]; // Max size for new format
size_t resp_size;

int ret = libhoth_hostcmd_exec(
dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CHIP_INFO,
/*version=*/0, NULL, 0, chipinfo, sizeof(*chipinfo), NULL);
/*version=*/0, NULL, 0, resp_buf, sizeof(resp_buf), &resp_size);

if (ret != 0) {
return ret;
}

if (resp_size == 16) {
// Old format: structured data
chipinfo->version = 0;
memcpy(&chipinfo->data.hoth_device_id, resp_buf, 16);
} else if (resp_size == 32) {
// New format: OpenTitan Device ID
chipinfo->version = 1;
memcpy(chipinfo->data.open_titan_device_id, resp_buf, 32);
} else {
// Unexpected size
return HTOOL_ERROR_HOST_COMMAND_START + HOTH_RES_INVALID_PARAM;
}

return 0;
}

int parse_opentitan_device_id(const uint8_t* src,
struct opentitan_device_id* dst) {
if (src == NULL || dst == NULL) {
return -1;
}

dst->creator_id = (uint16_t)(src[31]) | (src[30] << 8);
dst->product_id = (uint16_t)(src[29]) | (src[28] << 8);
dst->device_year = 2020 + (src[27] & 0x0F);
dst->device_week = (src[26] & 0x0F) * 10 + (src[27] >> 4);
dst->lot_number =
(src[25] >> 4) * 100 + (src[25] & 0x0F) * 10 + (src[26] >> 4);
dst->wafer_number = (src[24] >> 4) * 10 + (src[24] & 0x0F);
dst->wafer_x =
(src[22] & 0x0F) * 100 + (src[23] >> 4) * 10 + (src[23] & 0x0F);
dst->wafer_y = (src[21] >> 4) * 100 + (src[21] & 0x0F) * 10 + (src[22] >> 4);
dst->reserved_din = src[20];
dst->reserved = (src[16] << 24) | (src[17] << 16) | (src[18] << 8) | src[19];
dst->package_id = src[15];
dst->ast_config_version = src[14];
dst->otp_id[0] = src[12];
dst->otp_id[1] = src[13];
dst->otp_id[2] = '\0';
dst->otp_version = src[11];
dst->sku_id_string[0] = src[4];
dst->sku_id_string[1] = src[5];
dst->sku_id_string[2] = src[6];
dst->sku_id_string[3] = src[7];
dst->sku_id_string[4] = '\0';
dst->sku_specific_version = src[0];

return 0;
}
37 changes: 34 additions & 3 deletions protocol/chipinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,44 @@ extern "C" {
#include "transports/libhoth_device.h"

#define HOTH_PRV_CMD_HOTH_CHIP_INFO 0x0010

struct hoth_response_chip_info {
struct libhoth_hoth_device_id {
uint64_t hardware_identity;
uint16_t hardware_category;
uint16_t reserved0;
uint32_t info_variant;
} __attribute__((packed, aligned(4)));
};

struct opentitan_device_id {
uint16_t creator_id;
uint16_t product_id;
uint16_t device_year;
uint8_t device_week;
uint16_t lot_number;
uint8_t wafer_number;
uint16_t wafer_x;
uint16_t wafer_y;
uint8_t reserved_din;
uint32_t reserved;
uint8_t package_id;
uint8_t ast_config_version;
char otp_id[3];
uint8_t otp_version;
char sku_id_string[5];
uint8_t sku_specific_version;
};

int parse_opentitan_device_id(const uint8_t* src,
struct opentitan_device_id* dst);

struct hoth_response_chip_info {
uint32_t version; // 0: old format, 1: OpenTitan
uint32_t reserved;
union {
struct libhoth_hoth_device_id hoth_device_id; // Old format (16 bytes)
uint8_t open_titan_device_id[32]; // New format (32 bytes) - OpenTitan
// Device ID
} data;
};

int libhoth_chipinfo(struct libhoth_device* dev,
struct hoth_response_chip_info* chipinfo);
Expand Down
Loading
Loading