/*
* Copyright 2021 , The Android Open Source Project
*
* 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 .
*/
#define TLOG_TAG "hwbcc-srv"
#include <assert.h>
#include <interface/hwbcc/hwbcc.h>
#include <lib/hwbcc/srv/srv.h>
#include <lib/tipc/tipc.h>
#include <lib/tipc/tipc_srv.h>
#include <string.h>
#include <trusty_ipc.h>
#include <trusty_log.h>
#include <uapi/err.h>
struct hwbcc_req {
struct hwbcc_req_hdr hdr;
struct hwbcc_req_sign_data args;
uint8_t data_and_aad[HWBCC_MAX_DATA_TO_SIGN_SIZE + HWBCC_MAX_AAD_SIZE];
};
STATIC_ASSERT(sizeof (struct hwbcc_req) ==
sizeof (struct hwbcc_req_hdr) +
sizeof (struct hwbcc_req_sign_data) +
HWBCC_MAX_DATA_TO_SIGN_SIZE + HWBCC_MAX_AAD_SIZE);
struct hwbcc_resp {
struct hwbcc_resp_hdr hdr;
uint8_t payload[HWBCC_MAX_RESP_PAYLOAD_SIZE];
};
STATIC_ASSERT(sizeof (struct hwbcc_resp) ==
sizeof (struct hwbcc_resp_hdr) + HWBCC_MAX_RESP_PAYLOAD_SIZE);
/* UUID: {5f902ace-5e5c-4cd8-ae54-87b88c22ddaf} */
static const struct uuid km_uuid = {
0 x5f902ace,
0 x5e5c,
0 x4cd8,
{0 xae, 0 x54, 0 x87, 0 xb8, 0 x8c, 0 x22, 0 xdd, 0 xaf},
};
/* UUID: {0e109d31-8bbe-47d6-bb47-e1dd08910e16} */
static const struct uuid hwbcc_test_uuid = {
0 x0e109d31,
0 x8bbe,
0 x47d6,
{0 xbb, 0 x47, 0 xe1, 0 xdd, 0 x08, 0 x91, 0 x0e, 0 x16},
};
/* UUID: {67925337-2c03-49ed-9240-d51b6fea3e30} */
static const struct uuid hwbcc_rust_test_uuid = {
0 x67925337,
0 x2c03,
0 x49ed,
{0 x92, 0 x40, 0 xd5, 0 x1b, 0 x6f, 0 xea, 0 x3e, 0 x30},
};
/* UUID: {08d3ed40-bde2-448c-a91d75f1989c57ef} */
static const struct uuid widevine_uuid = {
0 x08d3ed40,
0 xbde2,
0 x448c,
{0 xa9, 0 x1d, 0 x75, 0 xf1, 0 x98, 0 x9c, 0 x57, 0 xef},
};
/* UUID: {19c7289c-5004-4a30-b85a-2a22a76e6327} */
static const struct uuid widevine_vm_uuid = {
0 x19c7289c,
0 x5004,
0 x4a30,
{0 xb8, 0 x5a, 0 x2a, 0 x22, 0 xa7, 0 x6e, 0 x63, 0 x27},
};
/* ZERO UUID to allow connections from non-secure world */
static const struct uuid zero_uuid = UUID_INITIAL_VALUE(zero_uuid);
static const struct uuid* allowed_uuids[] = {
&km_uuid, &hwbcc_test_uuid, &hwbcc_rust_test_uuid,
&widevine_uuid, &widevine_vm_uuid, &zero_uuid,
};
static struct tipc_port_acl acl = {
.flags = IPC_PORT_ALLOW_TA_CONNECT | IPC_PORT_ALLOW_NS_CONNECT,
.uuids = allowed_uuids,
.uuid_num = countof(allowed_uuids),
};
static struct tipc_port port = {
.name = HWBCC_PORT,
.msg_max_size =
MAX(sizeof (struct hwbcc_req), sizeof (struct hwbcc_resp)),
.msg_queue_len = 1 ,
.acl = &acl,
};
static const struct hwbcc_ops* hwbcc_ops;
static int hwbcc_check_ops(const struct hwbcc_ops* ops) {
if (!ops->init || !ops->close || !ops->sign_key || !ops->get_bcc ||
!ops->get_dice_artifacts || !ops->ns_deprivilege) {
TLOGE("NULL ops pointers\n" );
return ERR_INVALID_ARGS;
}
return NO_ERROR;
}
static int on_connect(const struct tipc_port* port,
handle_t chan,
const struct uuid* peer,
void ** ctx_p) {
assert(hwbcc_ops);
hwbcc_session_t s;
int rc = hwbcc_ops->init(&s, peer);
if (rc != NO_ERROR) {
TLOGE("Failed to init HWBCC session: %d\n" , rc);
return rc;
}
*ctx_p = s;
return NO_ERROR;
}
static void on_channel_cleanup(void * ctx) {
assert(hwbcc_ops);
hwbcc_session_t s = ctx;
hwbcc_ops->close(s);
}
static int handle_sign_data(hwbcc_session_t s,
handle_t chan,
uint32_t test_mode,
struct hwbcc_req_sign_data* args,
const uint8_t* data_and_aad) {
int rc;
struct hwbcc_resp resp = {0 };
size_t payload_size = 0 ;
assert(hwbcc_ops);
rc = hwbcc_ops->sign_key(s, test_mode, args->algorithm, data_and_aad,
args->data_size, data_and_aad + args->data_size,
args->aad_size, resp.payload, sizeof (resp.payload),
&payload_size);
if (rc != NO_ERROR) {
TLOGE("HWBCC_CMD_SIGN_DATA failure: %d\n" , rc);
}
resp.hdr.cmd = HWBCC_CMD_SIGN_DATA | HWBCC_CMD_RESP_BIT;
resp.hdr.status = rc;
resp.hdr.payload_size = payload_size;
rc = tipc_send1(chan, &resp, sizeof (resp.hdr) + payload_size);
if (rc < 0 ) {
return rc;
}
if ((size_t)rc != sizeof (resp.hdr) + payload_size) {
return ERR_BAD_LEN;
}
return NO_ERROR;
}
static int handle_get_bcc(hwbcc_session_t s,
handle_t chan,
uint32_t test_mode) {
int rc;
struct hwbcc_resp resp = {0 };
size_t payload_size = 0 ;
assert(hwbcc_ops);
rc = hwbcc_ops->get_bcc(s, test_mode, resp.payload, sizeof (resp.payload),
&payload_size);
if (rc != NO_ERROR) {
TLOGE("HWBCC_CMD_GET_BCC failure: %d\n" , rc);
}
resp.hdr.cmd = HWBCC_CMD_GET_BCC | HWBCC_CMD_RESP_BIT;
resp.hdr.status = rc;
resp.hdr.payload_size = payload_size;
rc = tipc_send1(chan, &resp, sizeof (resp.hdr) + payload_size);
if (rc < 0 ) {
return rc;
}
if ((size_t)rc != sizeof (resp.hdr) + payload_size) {
return ERR_BAD_LEN;
}
return NO_ERROR;
}
static int handle_get_dice_artifacts(hwbcc_session_t s,
handle_t chan,
uint64_t context) {
int rc;
struct hwbcc_resp resp = {0 };
size_t payload_size = 0 ;
assert(hwbcc_ops);
rc = hwbcc_ops->get_dice_artifacts(s, context, resp.payload,
sizeof (resp.payload), &payload_size);
if (rc != NO_ERROR) {
TLOGE("HWBCC_CMD_GET_DICE_ARTIFACTS failure: %d\n" , rc);
}
resp.hdr.cmd = HWBCC_CMD_GET_DICE_ARTIFACTS | HWBCC_CMD_RESP_BIT;
resp.hdr.status = rc;
resp.hdr.payload_size = payload_size;
rc = tipc_send1(chan, &resp, sizeof (resp.hdr) + payload_size);
if (rc < 0 ) {
return rc;
}
if ((size_t)rc != sizeof (resp.hdr) + payload_size) {
return ERR_BAD_LEN;
}
return NO_ERROR;
}
static int handle_ns_deprivilege(hwbcc_session_t s, handle_t chan) {
int rc;
struct hwbcc_resp resp = {0 };
assert(hwbcc_ops);
rc = hwbcc_ops->ns_deprivilege(s);
if (rc != NO_ERROR) {
TLOGE("HWBCC_CMD_NS_DEPRIVILEGE failure: %d\n" , rc);
}
resp.hdr.cmd = HWBCC_CMD_NS_DEPRIVILEGE | HWBCC_CMD_RESP_BIT;
resp.hdr.status = rc;
rc = tipc_send1(chan, &resp, sizeof (resp.hdr));
if (rc < 0 ) {
return rc;
}
if ((size_t)rc != sizeof (resp.hdr)) {
return ERR_BAD_LEN;
}
return NO_ERROR;
}
static int on_message(const struct tipc_port* port, handle_t chan, void * ctx) {
int rc;
struct hwbcc_req req;
hwbcc_session_t s = ctx;
rc = tipc_recv1(chan, sizeof (req.hdr), &req, sizeof (req));
if (rc < 0 ) {
TLOGE("Failed to read command %d\n" , rc);
return rc;
}
switch (req.hdr.cmd) {
case HWBCC_CMD_SIGN_DATA: {
if ((size_t)rc < sizeof (req.hdr) + sizeof (req.args)) {
return ERR_BAD_LEN;
}
if (req.args.aad_size > HWBCC_MAX_AAD_SIZE) {
return ERR_BAD_LEN;
}
if (req.args.data_size > HWBCC_MAX_DATA_TO_SIGN_SIZE) {
return ERR_BAD_LEN;
}
if (rc - sizeof (req.hdr) - sizeof (req.args) !=
req.args.data_size + req.args.aad_size) {
return ERR_BAD_LEN;
}
return handle_sign_data(s, chan, req.hdr.test_mode, &req.args,
req.data_and_aad);
}
case HWBCC_CMD_GET_BCC:
if (rc != sizeof (req.hdr)) {
return ERR_BAD_LEN;
}
return handle_get_bcc(s, chan, req.hdr.test_mode);
case HWBCC_CMD_GET_DICE_ARTIFACTS:
if (rc != sizeof (req.hdr)) {
return ERR_BAD_LEN;
}
return handle_get_dice_artifacts(s, chan, req.hdr.context);
case HWBCC_CMD_NS_DEPRIVILEGE:
if (rc != sizeof (req.hdr)) {
return ERR_BAD_LEN;
}
return handle_ns_deprivilege(s, chan);
default :
TLOGE("Received unknown command %x\n" , req.hdr.cmd);
return ERR_CMD_UNKNOWN;
}
return NO_ERROR;
}
static struct tipc_srv_ops tipc_ops = {
.on_connect = on_connect,
.on_message = on_message,
.on_channel_cleanup = on_channel_cleanup,
};
/*
* TODO : Currently we only support one instance of HWBCC service , i . e . this
* function can only be called once .
*/
int add_hwbcc_service(struct tipc_hset* hset, const struct hwbcc_ops* ops) {
int rc = hwbcc_check_ops(ops);
if (rc != NO_ERROR) {
return rc;
}
hwbcc_ops = ops;
return tipc_add_service(hset, &port, 1 , 1 , &tipc_ops);
}
Messung V0.5 in Prozent C=93 H=97 G=94
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-26)
¤
*© Formatika GbR, Deutschland