Skip to content

Commit

Permalink
Add authz_host_command build/send
Browse files Browse the repository at this point in the history
  • Loading branch information
rkr35 committed Jun 28, 2024
1 parent ddb327a commit 87d1685
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 0 deletions.
2 changes: 2 additions & 0 deletions examples/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ cc_binary(
"host_commands.h",
"htool.c",
"htool.h",
"htool_authz_command.h",
"htool_authz_command.c",
"htool_cmd.c",
"htool_cmd.h",
"htool_console.c",
Expand Down
24 changes: 24 additions & 0 deletions examples/host_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,30 @@ struct ec_authz_record_get_nonce_response {
uint32_t rw_supported_key_id;
} __attribute__((packed));

#define AUTHORIZED_COMMAND_SIGNATURE_SIZE 64
#define AUTHORIZED_COMMAND_NONCE_SIZE 32

#define EC_PRV_CMD_HOTH_GET_AUTHZ_COMMAND_NONCE 0x0035

struct ec_authorized_command_get_nonce_response {
uint32_t nonce[AUTHORIZED_COMMAND_NONCE_SIZE / sizeof(uint32_t)];
uint32_t supported_key_info;
} __attribute__((packed, aligned(4)));

#define EC_PRV_CMD_HOTH_AUTHZ_COMMAND 0x0034

struct ec_authorized_command_request {
uint8_t signature[AUTHORIZED_COMMAND_SIGNATURE_SIZE];
uint32_t version;
uint32_t size;
uint32_t key_info;
uint32_t dev_id_0;
uint32_t dev_id_1;
uint32_t nonce[AUTHORIZED_COMMAND_NONCE_SIZE / sizeof(uint32_t)];
uint32_t opcode;
uint32_t arg_bytes[];
} __attribute__((packed, aligned(4)));

#define MAILBOX_SIZE 1024

#define EC_PRV_CMD_HOTH_PAYLOAD_UPDATE 0x0005
Expand Down
85 changes: 85 additions & 0 deletions examples/htool.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "authorization_record.h"
#include "ec_util.h"
#include "host_commands.h"
#include "htool_authz_command.h"
#include "htool_cmd.h"
#include "htool_console.h"
#include "htool_i2c.h"
Expand Down Expand Up @@ -234,6 +235,70 @@ static int command_authz_record_set(const struct htool_invocation* inv) {
return 0;
}

static int command_authz_host_command_build(
const struct htool_invocation* inv) {
uint32_t opcode;
if (htool_get_param_u32(inv, "opcode", &opcode)) {
return -1;
}

struct libhoth_device* dev = htool_libhoth_device();
if (!dev) {
return -1;
}

struct ec_response_chip_info chipinfo_resp;
int status = htool_exec_hostcmd(
dev, EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_CHIP_INFO,
/*version=*/0, NULL, 0, &chipinfo_resp, sizeof(chipinfo_resp), NULL);
if (status != 0) {
fprintf(stderr, "Failed to get chip ID. status=%d\n", status);
return -1;
}

struct ec_authorized_command_get_nonce_response nonce_resp;
status = htool_exec_hostcmd(
dev, EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_GET_AUTHZ_COMMAND_NONCE,
/*version=*/0, NULL, 0, &nonce_resp, sizeof(nonce_resp), NULL);
if (status != 0) {
fprintf(stderr, "Failed to get nonce. status=%d\n", status);
return -1;
}

struct ec_authorized_command_request request = authz_command_build_request(
chipinfo_resp.hardware_identity, opcode, nonce_resp.supported_key_info,
nonce_resp.nonce);
authz_command_print_request(&request);
return 0;
}

static int command_authz_host_command_send(const struct htool_invocation* inv) {
const char* command_hex;
if (htool_get_param_string(inv, "command", &command_hex)) {
return -1;
}

struct libhoth_device* dev = htool_libhoth_device();
if (!dev) {
return -1;
}

struct ec_authorized_command_request request;
int status = authz_command_hex_to_struct(command_hex, &request);
if (status != 0) {
return -1;
}

status = htool_exec_hostcmd(
dev, EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_AUTHZ_COMMAND,
/*version=*/0, &request, sizeof(request), NULL, 0, NULL);
if (status != 0) {
return -1;
}

return 0;
}

static int force_write(int fd, const void* buf, size_t size) {
const uint8_t* cbuf = (const uint8_t*)buf;
while (size > 0) {
Expand Down Expand Up @@ -869,6 +934,26 @@ static const struct htool_cmd CMDS[] = {
},
.func = command_authz_record_set,
},
{
.verbs = (const char*[]){"authz_host_command", "build", NULL},
.desc = "Build an authorized host command",
.params =
(const struct htool_param[]){
{HTOOL_POSITIONAL, .name = "opcode"},
{},
},
.func = command_authz_host_command_build,
},
{
.verbs = (const char*[]){"authz_host_command", "send", NULL},
.desc = "Send an authorized host command",
.params =
(const struct htool_param[]){
{HTOOL_POSITIONAL, .name = "command"},
{},
},
.func = command_authz_host_command_send,
},
{
.verbs = (const char*[]){"arm_coordinated_reset", NULL},
.desc = "Arms the coordinated reset to hard reset when it receives a "
Expand Down
79 changes: 79 additions & 0 deletions examples/htool_authz_command.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "host_commands.h"

struct ec_authorized_command_request authz_command_build_request(
uint64_t hardware_identity, uint32_t opcode, uint32_t key_info,
const uint32_t* nonce) {
struct ec_authorized_command_request request = {
.key_info = key_info,
.dev_id_0 = hardware_identity & UINT32_C(0xffffffff),
.dev_id_1 = hardware_identity >> 32,
.opcode = opcode,
};
memcpy(request.nonce, nonce, sizeof(request.nonce));
return request;
}

void authz_command_print_request(
struct ec_authorized_command_request* request) {
const uint8_t* out = (const uint8_t*)request;
for (int i = 0; i < sizeof(*request); i++) {
printf("%02x", out[i]);
}
printf("\n");
}

static uint8_t parse_nibble(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'a' && c <= 'f') {
return c - 'a' + 0xa;
}
if (c >= 'A' && c <= 'F') {
return c - 'A' + 0xa;
}
return UINT8_MAX;
}

int authz_command_hex_to_struct(const char* hexstring,
struct ec_authorized_command_request* request) {
size_t actual_len = strlen(hexstring);
size_t expected_len = 2 * sizeof(*request);
if (actual_len != expected_len) {
fprintf(stderr, "Bad hexstring length. Got %ld but expected %ld\n",
actual_len, expected_len);
return -1;
}

uint8_t* out = (uint8_t*)request;

for (int i = 0; i < sizeof(*request); i++) {
uint8_t nibble_0 = parse_nibble(hexstring[2 * i]);
uint8_t nibble_1 = parse_nibble(hexstring[2 * i + 1]);
if (nibble_0 == UINT8_MAX || nibble_1 == UINT8_MAX) {
fprintf(stderr, "Invalid hex character at byte %d\n", i);
return -1;
}
out[i] = (nibble_0 << 4) | nibble_1;
}

return 0;
}
39 changes: 39 additions & 0 deletions examples/htool_authz_command.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef LIBHOTH_EXAMPLES_AUTHZ_COMMAND_H_
#define LIBHOTH_EXAMPLES_AUTHZ_COMMAND_H_

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

struct ec_authorized_command_request;

struct ec_authorized_command_request authz_command_build_request(
uint64_t hardware_identity, uint32_t opcode, uint32_t key_info,
const uint32_t* nonce);

void authz_command_print_request(struct ec_authorized_command_request* request);

int authz_command_hex_to_struct(const char* hexstring,
struct ec_authorized_command_request* out);

#ifdef __cplusplus
}
#endif

#endif // LIBHOTH_EXAMPLES_AUTHZ_COMMAND_H_
1 change: 1 addition & 0 deletions examples/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ executable(
'authorization_record.c',
'ec_util.c',
'htool.c',
'htool_authz_command.c',
'htool_cmd.c',
'htool_console.c',
'htool_dbus.c',
Expand Down

0 comments on commit 87d1685

Please sign in to comment.