678 lines
20 KiB
C
678 lines
20 KiB
C
#include "amduat/asl/store.h"
|
|
#include "amduat/enc/asl1_core.h"
|
|
#include "amduat/enc/asl1_core_codec.h"
|
|
#include "amduat/enc/pel1_result.h"
|
|
#include "amduat/enc/pel_program_dag.h"
|
|
#include "amduat/enc/pel_trace_dag.h"
|
|
#include "amduat/hash/asl1.h"
|
|
#include "amduat/pel/program_dag.h"
|
|
#include "amduat/pel/program_dag_desc.h"
|
|
#include "amduat/pel/surf.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef struct {
|
|
amduat_reference_t ref;
|
|
amduat_artifact_t artifact;
|
|
} stub_store_entry_t;
|
|
|
|
typedef struct {
|
|
stub_store_entry_t *entries;
|
|
size_t len;
|
|
size_t cap;
|
|
amduat_asl_store_config_t config;
|
|
} stub_store_t;
|
|
|
|
static void stub_store_init(stub_store_t *store) {
|
|
if (store == NULL) {
|
|
return;
|
|
}
|
|
store->entries = NULL;
|
|
store->len = 0;
|
|
store->cap = 0;
|
|
store->config.encoding_profile_id = 0;
|
|
store->config.hash_id = 0;
|
|
}
|
|
|
|
static void stub_store_free(stub_store_t *store) {
|
|
size_t i;
|
|
|
|
if (store == NULL) {
|
|
return;
|
|
}
|
|
for (i = 0; i < store->len; ++i) {
|
|
stub_store_entry_t *entry = &store->entries[i];
|
|
free((void *)entry->ref.digest.data);
|
|
entry->ref.digest.data = NULL;
|
|
entry->ref.digest.len = 0;
|
|
free((void *)entry->artifact.bytes.data);
|
|
entry->artifact.bytes.data = NULL;
|
|
entry->artifact.bytes.len = 0;
|
|
}
|
|
free(store->entries);
|
|
store->entries = NULL;
|
|
store->len = 0;
|
|
store->cap = 0;
|
|
}
|
|
|
|
static bool artifact_eq(const amduat_artifact_t *a,
|
|
const amduat_artifact_t *b) {
|
|
if (a == NULL || b == NULL) {
|
|
return false;
|
|
}
|
|
if (a->has_type_tag != b->has_type_tag) {
|
|
return false;
|
|
}
|
|
if (a->has_type_tag && a->type_tag.tag_id != b->type_tag.tag_id) {
|
|
return false;
|
|
}
|
|
if (a->bytes.len != b->bytes.len) {
|
|
return false;
|
|
}
|
|
if (a->bytes.len != 0) {
|
|
if (a->bytes.data == NULL || b->bytes.data == NULL) {
|
|
return false;
|
|
}
|
|
if (memcmp(a->bytes.data, b->bytes.data, a->bytes.len) != 0) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool stub_store_add_entry(stub_store_t *store,
|
|
amduat_reference_t stored_ref,
|
|
amduat_artifact_t stored_artifact) {
|
|
stub_store_entry_t *entries;
|
|
size_t new_cap;
|
|
|
|
if (store->len == store->cap) {
|
|
new_cap = store->cap == 0 ? 8 : store->cap * 2;
|
|
entries = (stub_store_entry_t *)realloc(store->entries,
|
|
new_cap * sizeof(*entries));
|
|
if (entries == NULL) {
|
|
return false;
|
|
}
|
|
store->entries = entries;
|
|
store->cap = new_cap;
|
|
}
|
|
|
|
store->entries[store->len++] =
|
|
(stub_store_entry_t){stored_ref, stored_artifact};
|
|
return true;
|
|
}
|
|
|
|
static amduat_asl_store_error_t stub_store_put(
|
|
void *ctx,
|
|
amduat_artifact_t artifact,
|
|
amduat_reference_t *out_ref) {
|
|
stub_store_t *store;
|
|
amduat_octets_t encoded;
|
|
const amduat_hash_asl1_desc_t *hash_desc;
|
|
uint8_t *digest_store = NULL;
|
|
uint8_t *digest_out = NULL;
|
|
uint8_t *payload;
|
|
amduat_reference_t stored_ref;
|
|
amduat_artifact_t stored_artifact;
|
|
size_t i;
|
|
|
|
if (ctx == NULL || out_ref == NULL) {
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
store = (stub_store_t *)ctx;
|
|
out_ref->hash_id = 0;
|
|
out_ref->digest = amduat_octets(NULL, 0);
|
|
|
|
if (store->config.encoding_profile_id != AMDUAT_ENC_ASL1_CORE_V1) {
|
|
return AMDUAT_ASL_STORE_ERR_UNSUPPORTED;
|
|
}
|
|
encoded = amduat_octets(NULL, 0);
|
|
if (!amduat_enc_asl1_core_encode_artifact_v1(artifact, &encoded)) {
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
|
|
hash_desc = amduat_hash_asl1_desc_lookup(store->config.hash_id);
|
|
if (hash_desc == NULL || hash_desc->digest_len == 0) {
|
|
free((void *)encoded.data);
|
|
return AMDUAT_ASL_STORE_ERR_UNSUPPORTED;
|
|
}
|
|
|
|
digest_store = (uint8_t *)malloc(hash_desc->digest_len);
|
|
digest_out = (uint8_t *)malloc(hash_desc->digest_len);
|
|
if (digest_store == NULL || digest_out == NULL) {
|
|
free((void *)encoded.data);
|
|
free(digest_store);
|
|
free(digest_out);
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
if (!amduat_hash_asl1_digest(store->config.hash_id, encoded, digest_store,
|
|
hash_desc->digest_len)) {
|
|
free((void *)encoded.data);
|
|
free(digest_store);
|
|
free(digest_out);
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
memcpy(digest_out, digest_store, hash_desc->digest_len);
|
|
free((void *)encoded.data);
|
|
|
|
stored_ref.hash_id = store->config.hash_id;
|
|
stored_ref.digest = amduat_octets(digest_store, hash_desc->digest_len);
|
|
out_ref->hash_id = store->config.hash_id;
|
|
out_ref->digest = amduat_octets(digest_out, hash_desc->digest_len);
|
|
|
|
for (i = 0; i < store->len; ++i) {
|
|
stub_store_entry_t *entry = &store->entries[i];
|
|
if (amduat_reference_eq(entry->ref, stored_ref)) {
|
|
if (!artifact_eq(&entry->artifact, &artifact)) {
|
|
free(digest_store);
|
|
free(digest_out);
|
|
out_ref->hash_id = 0;
|
|
out_ref->digest = amduat_octets(NULL, 0);
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
free(digest_store);
|
|
return AMDUAT_ASL_STORE_OK;
|
|
}
|
|
}
|
|
|
|
payload = NULL;
|
|
if (artifact.bytes.len != 0) {
|
|
if (artifact.bytes.data == NULL) {
|
|
free(digest_store);
|
|
free(digest_out);
|
|
out_ref->hash_id = 0;
|
|
out_ref->digest = amduat_octets(NULL, 0);
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
payload = (uint8_t *)malloc(artifact.bytes.len);
|
|
if (payload == NULL) {
|
|
free(digest_store);
|
|
free(digest_out);
|
|
out_ref->hash_id = 0;
|
|
out_ref->digest = amduat_octets(NULL, 0);
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
memcpy(payload, artifact.bytes.data, artifact.bytes.len);
|
|
}
|
|
stored_artifact.bytes = amduat_octets(payload, artifact.bytes.len);
|
|
stored_artifact.has_type_tag = artifact.has_type_tag;
|
|
stored_artifact.type_tag = artifact.type_tag;
|
|
|
|
if (!stub_store_add_entry(store, stored_ref, stored_artifact)) {
|
|
free(payload);
|
|
free(digest_store);
|
|
free(digest_out);
|
|
out_ref->hash_id = 0;
|
|
out_ref->digest = amduat_octets(NULL, 0);
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
|
|
return AMDUAT_ASL_STORE_OK;
|
|
}
|
|
|
|
static amduat_asl_store_error_t stub_store_get(
|
|
void *ctx,
|
|
amduat_reference_t ref,
|
|
amduat_artifact_t *out_artifact) {
|
|
stub_store_t *store;
|
|
size_t i;
|
|
|
|
if (ctx == NULL || out_artifact == NULL) {
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
store = (stub_store_t *)ctx;
|
|
|
|
for (i = 0; i < store->len; ++i) {
|
|
stub_store_entry_t *entry = &store->entries[i];
|
|
if (amduat_reference_eq(entry->ref, ref)) {
|
|
uint8_t *payload = NULL;
|
|
if (entry->artifact.bytes.len != 0) {
|
|
payload = (uint8_t *)malloc(entry->artifact.bytes.len);
|
|
if (payload == NULL) {
|
|
return AMDUAT_ASL_STORE_ERR_INTEGRITY;
|
|
}
|
|
memcpy(payload, entry->artifact.bytes.data, entry->artifact.bytes.len);
|
|
}
|
|
out_artifact->bytes = amduat_octets(payload,
|
|
entry->artifact.bytes.len);
|
|
out_artifact->has_type_tag = entry->artifact.has_type_tag;
|
|
out_artifact->type_tag = entry->artifact.type_tag;
|
|
return AMDUAT_ASL_STORE_OK;
|
|
}
|
|
}
|
|
|
|
return AMDUAT_ASL_STORE_ERR_NOT_FOUND;
|
|
}
|
|
|
|
static void artifact_free(amduat_artifact_t *artifact) {
|
|
if (artifact == NULL) {
|
|
return;
|
|
}
|
|
free((void *)artifact->bytes.data);
|
|
artifact->bytes.data = NULL;
|
|
artifact->bytes.len = 0;
|
|
}
|
|
|
|
static void store_u64_be(uint8_t *out, uint64_t value) {
|
|
out[0] = (uint8_t)((value >> 56) & 0xffu);
|
|
out[1] = (uint8_t)((value >> 48) & 0xffu);
|
|
out[2] = (uint8_t)((value >> 40) & 0xffu);
|
|
out[3] = (uint8_t)((value >> 32) & 0xffu);
|
|
out[4] = (uint8_t)((value >> 24) & 0xffu);
|
|
out[5] = (uint8_t)((value >> 16) & 0xffu);
|
|
out[6] = (uint8_t)((value >> 8) & 0xffu);
|
|
out[7] = (uint8_t)(value & 0xffu);
|
|
}
|
|
|
|
static amduat_octets_t make_const_params(const uint8_t *bytes, size_t len) {
|
|
size_t total = 1 + 8 + len;
|
|
uint8_t *buffer = (uint8_t *)malloc(total);
|
|
if (buffer == NULL) {
|
|
return amduat_octets(NULL, 0);
|
|
}
|
|
buffer[0] = 0x00u;
|
|
store_u64_be(buffer + 1, (uint64_t)len);
|
|
if (len != 0 && bytes != NULL) {
|
|
memcpy(buffer + 1 + 8, bytes, len);
|
|
}
|
|
return amduat_octets(buffer, total);
|
|
}
|
|
|
|
static bool build_const_program_artifact(amduat_artifact_t *out_artifact) {
|
|
amduat_pel_node_t nodes[1];
|
|
amduat_pel_root_ref_t roots[1];
|
|
amduat_pel_program_t program;
|
|
amduat_octets_t params;
|
|
amduat_octets_t encoded;
|
|
const char op_const[] = "pel.bytes.const";
|
|
const uint8_t payload[] = {'h', 'i'};
|
|
|
|
params = make_const_params(payload, sizeof(payload));
|
|
if (params.data == NULL) {
|
|
return false;
|
|
}
|
|
|
|
nodes[0].id = 1;
|
|
nodes[0].op.name = amduat_octets(op_const, strlen(op_const));
|
|
nodes[0].op.version = 1;
|
|
nodes[0].inputs = NULL;
|
|
nodes[0].inputs_len = 0;
|
|
nodes[0].params = params;
|
|
|
|
roots[0].node_id = 1;
|
|
roots[0].output_index = 0;
|
|
|
|
program.nodes = nodes;
|
|
program.nodes_len = 1;
|
|
program.roots = roots;
|
|
program.roots_len = 1;
|
|
|
|
encoded = amduat_octets(NULL, 0);
|
|
if (!amduat_enc_pel_program_dag_encode_v1(&program, &encoded)) {
|
|
free((void *)params.data);
|
|
return false;
|
|
}
|
|
|
|
*out_artifact = amduat_artifact_with_type(
|
|
encoded, amduat_type_tag(AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1));
|
|
free((void *)params.data);
|
|
return true;
|
|
}
|
|
|
|
static bool build_concat_program_artifact(amduat_artifact_t *out_artifact) {
|
|
amduat_pel_dag_input_t inputs[1];
|
|
amduat_pel_node_t nodes[1];
|
|
amduat_pel_root_ref_t roots[1];
|
|
amduat_pel_program_t program;
|
|
amduat_octets_t encoded;
|
|
const char op_concat[] = "pel.bytes.concat";
|
|
|
|
inputs[0].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
|
inputs[0].value.external.input_index = 0;
|
|
|
|
nodes[0].id = 1;
|
|
nodes[0].op.name = amduat_octets(op_concat, strlen(op_concat));
|
|
nodes[0].op.version = 1;
|
|
nodes[0].inputs = inputs;
|
|
nodes[0].inputs_len = 1;
|
|
nodes[0].params = amduat_octets(NULL, 0);
|
|
|
|
roots[0].node_id = 1;
|
|
roots[0].output_index = 0;
|
|
|
|
program.nodes = nodes;
|
|
program.nodes_len = 1;
|
|
program.roots = roots;
|
|
program.roots_len = 1;
|
|
|
|
encoded = amduat_octets(NULL, 0);
|
|
if (!amduat_enc_pel_program_dag_encode_v1(&program, &encoded)) {
|
|
return false;
|
|
}
|
|
|
|
*out_artifact = amduat_artifact_with_type(
|
|
encoded, amduat_type_tag(AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1));
|
|
return true;
|
|
}
|
|
|
|
static amduat_reference_t make_ref(uint8_t seed) {
|
|
uint8_t *digest = (uint8_t *)malloc(32);
|
|
if (digest == NULL) {
|
|
return amduat_reference(0, amduat_octets(NULL, 0));
|
|
}
|
|
memset(digest, seed, 32);
|
|
return amduat_reference(AMDUAT_HASH_ASL1_ID_SHA256,
|
|
amduat_octets(digest, 32));
|
|
}
|
|
|
|
static int test_surf_success(void) {
|
|
stub_store_t stub;
|
|
amduat_asl_store_t store;
|
|
amduat_asl_store_ops_t ops;
|
|
amduat_asl_store_config_t cfg;
|
|
amduat_artifact_t program_artifact;
|
|
amduat_reference_t program_ref;
|
|
amduat_reference_t *output_refs = NULL;
|
|
size_t output_refs_len = 0;
|
|
amduat_reference_t result_ref;
|
|
amduat_artifact_t result_artifact;
|
|
amduat_pel_surface_execution_result_t decoded;
|
|
amduat_artifact_t trace_artifact;
|
|
amduat_pel_trace_dag_value_t trace;
|
|
const char op_const[] = "pel.bytes.const";
|
|
int exit_code = 1;
|
|
|
|
cfg.encoding_profile_id = AMDUAT_ENC_ASL1_CORE_V1;
|
|
cfg.hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
|
stub_store_init(&stub);
|
|
stub.config = cfg;
|
|
ops.put = stub_store_put;
|
|
ops.get = stub_store_get;
|
|
amduat_asl_store_init(&store, cfg, ops, &stub);
|
|
|
|
if (!build_const_program_artifact(&program_artifact)) {
|
|
fprintf(stderr, "build program failed\n");
|
|
goto cleanup_store;
|
|
}
|
|
if (stub_store_put(&stub, program_artifact, &program_ref) !=
|
|
AMDUAT_ASL_STORE_OK) {
|
|
fprintf(stderr, "program put failed\n");
|
|
free((void *)program_artifact.bytes.data);
|
|
goto cleanup_store;
|
|
}
|
|
free((void *)program_artifact.bytes.data);
|
|
|
|
if (!amduat_pel_surf_run(&store, amduat_pel_program_dag_scheme_ref(),
|
|
program_ref, NULL, 0, false,
|
|
amduat_reference(0, amduat_octets(NULL, 0)),
|
|
&output_refs, &output_refs_len, &result_ref)) {
|
|
fprintf(stderr, "surf run failed\n");
|
|
goto cleanup_refs;
|
|
}
|
|
|
|
if (output_refs_len != 1) {
|
|
fprintf(stderr, "unexpected output ref count\n");
|
|
goto cleanup_refs;
|
|
}
|
|
|
|
if (stub_store_get(&stub, result_ref, &result_artifact) !=
|
|
AMDUAT_ASL_STORE_OK) {
|
|
fprintf(stderr, "result get failed\n");
|
|
goto cleanup_refs;
|
|
}
|
|
if (!result_artifact.has_type_tag ||
|
|
result_artifact.type_tag.tag_id != AMDUAT_TYPE_TAG_PEL1_RESULT_1) {
|
|
fprintf(stderr, "result type tag mismatch\n");
|
|
artifact_free(&result_artifact);
|
|
goto cleanup_refs;
|
|
}
|
|
if (!amduat_enc_pel1_result_decode_v1(result_artifact.bytes, &decoded)) {
|
|
fprintf(stderr, "result decode failed\n");
|
|
artifact_free(&result_artifact);
|
|
goto cleanup_refs;
|
|
}
|
|
artifact_free(&result_artifact);
|
|
|
|
if (decoded.core_result.status != AMDUAT_PEL_EXEC_STATUS_OK ||
|
|
decoded.core_result.summary.kind != AMDUAT_PEL_EXEC_ERROR_NONE ||
|
|
decoded.core_result.summary.status_code != 0) {
|
|
fprintf(stderr, "unexpected core status\n");
|
|
goto cleanup_decoded;
|
|
}
|
|
if (!decoded.has_trace_ref) {
|
|
fprintf(stderr, "missing trace ref\n");
|
|
goto cleanup_decoded;
|
|
}
|
|
if (decoded.output_refs_len != 1 ||
|
|
!amduat_reference_eq(decoded.output_refs[0], output_refs[0])) {
|
|
fprintf(stderr, "output refs mismatch\n");
|
|
goto cleanup_decoded;
|
|
}
|
|
|
|
if (stub_store_get(&stub, decoded.trace_ref, &trace_artifact) !=
|
|
AMDUAT_ASL_STORE_OK) {
|
|
fprintf(stderr, "trace get failed\n");
|
|
goto cleanup_decoded;
|
|
}
|
|
if (!trace_artifact.has_type_tag ||
|
|
trace_artifact.type_tag.tag_id != AMDUAT_TYPE_TAG_PEL_TRACE_DAG_1) {
|
|
fprintf(stderr, "trace type tag mismatch\n");
|
|
artifact_free(&trace_artifact);
|
|
goto cleanup_decoded;
|
|
}
|
|
if (!amduat_enc_pel_trace_dag_decode_v1(trace_artifact.bytes, &trace)) {
|
|
fprintf(stderr, "trace decode failed\n");
|
|
artifact_free(&trace_artifact);
|
|
goto cleanup_decoded;
|
|
}
|
|
artifact_free(&trace_artifact);
|
|
|
|
if (trace.node_traces_len != 1 ||
|
|
trace.node_traces[0].status != AMDUAT_PEL_NODE_TRACE_OK ||
|
|
trace.node_traces[0].output_refs_len != 1 ||
|
|
!amduat_reference_eq(trace.node_traces[0].output_refs[0],
|
|
output_refs[0]) ||
|
|
trace.node_traces[0].op_name.len != strlen(op_const) ||
|
|
memcmp(trace.node_traces[0].op_name.data,
|
|
op_const, trace.node_traces[0].op_name.len) != 0) {
|
|
fprintf(stderr, "trace node mismatch\n");
|
|
amduat_enc_pel_trace_dag_free(&trace);
|
|
goto cleanup_decoded;
|
|
}
|
|
|
|
amduat_enc_pel_trace_dag_free(&trace);
|
|
exit_code = 0;
|
|
|
|
cleanup_decoded:
|
|
amduat_enc_pel1_result_free(&decoded);
|
|
cleanup_refs:
|
|
amduat_pel_surf_free_refs(output_refs, output_refs_len);
|
|
amduat_pel_surf_free_ref(&result_ref);
|
|
amduat_pel_surf_free_ref(&program_ref);
|
|
cleanup_store:
|
|
stub_store_free(&stub);
|
|
return exit_code;
|
|
}
|
|
|
|
static int test_surf_missing_program(void) {
|
|
stub_store_t stub;
|
|
amduat_asl_store_t store;
|
|
amduat_asl_store_ops_t ops;
|
|
amduat_asl_store_config_t cfg;
|
|
amduat_reference_t program_ref;
|
|
amduat_reference_t *output_refs = NULL;
|
|
size_t output_refs_len = 0;
|
|
amduat_reference_t result_ref;
|
|
amduat_artifact_t result_artifact;
|
|
amduat_pel_surface_execution_result_t decoded;
|
|
int exit_code = 1;
|
|
|
|
cfg.encoding_profile_id = AMDUAT_ENC_ASL1_CORE_V1;
|
|
cfg.hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
|
stub_store_init(&stub);
|
|
stub.config = cfg;
|
|
ops.put = stub_store_put;
|
|
ops.get = stub_store_get;
|
|
amduat_asl_store_init(&store, cfg, ops, &stub);
|
|
|
|
program_ref = make_ref(0x42u);
|
|
if (program_ref.digest.data == NULL) {
|
|
goto cleanup_store;
|
|
}
|
|
|
|
if (!amduat_pel_surf_run(&store, amduat_pel_program_dag_scheme_ref(),
|
|
program_ref, NULL, 0, false,
|
|
amduat_reference(0, amduat_octets(NULL, 0)),
|
|
&output_refs, &output_refs_len, &result_ref)) {
|
|
fprintf(stderr, "surf run failed\n");
|
|
goto cleanup_refs;
|
|
}
|
|
|
|
if (output_refs_len != 0) {
|
|
fprintf(stderr, "unexpected output refs\n");
|
|
goto cleanup_refs;
|
|
}
|
|
|
|
if (stub_store_get(&stub, result_ref, &result_artifact) !=
|
|
AMDUAT_ASL_STORE_OK) {
|
|
fprintf(stderr, "result get failed\n");
|
|
goto cleanup_refs;
|
|
}
|
|
if (!amduat_enc_pel1_result_decode_v1(result_artifact.bytes, &decoded)) {
|
|
artifact_free(&result_artifact);
|
|
fprintf(stderr, "result decode failed\n");
|
|
goto cleanup_refs;
|
|
}
|
|
artifact_free(&result_artifact);
|
|
|
|
if (decoded.core_result.status != AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM ||
|
|
decoded.core_result.summary.kind != AMDUAT_PEL_EXEC_ERROR_PROGRAM ||
|
|
decoded.core_result.summary.status_code != 2 ||
|
|
!decoded.has_store_failure ||
|
|
decoded.store_failure.phase != AMDUAT_PEL_STORE_FAILURE_PROGRAM ||
|
|
decoded.store_failure.error_code != AMDUAT_PEL_STORE_ERROR_NOT_FOUND ||
|
|
!amduat_reference_eq(decoded.store_failure.failing_ref, program_ref) ||
|
|
decoded.has_trace_ref) {
|
|
fprintf(stderr, "missing program mapping mismatch\n");
|
|
goto cleanup_decoded;
|
|
}
|
|
|
|
exit_code = 0;
|
|
|
|
cleanup_decoded:
|
|
amduat_enc_pel1_result_free(&decoded);
|
|
cleanup_refs:
|
|
amduat_pel_surf_free_refs(output_refs, output_refs_len);
|
|
amduat_pel_surf_free_ref(&result_ref);
|
|
amduat_pel_surf_free_ref(&program_ref);
|
|
cleanup_store:
|
|
stub_store_free(&stub);
|
|
return exit_code;
|
|
}
|
|
|
|
static int test_surf_missing_input(void) {
|
|
stub_store_t stub;
|
|
amduat_asl_store_t store;
|
|
amduat_asl_store_ops_t ops;
|
|
amduat_asl_store_config_t cfg;
|
|
amduat_artifact_t program_artifact;
|
|
amduat_reference_t program_ref;
|
|
amduat_reference_t input_ref;
|
|
amduat_reference_t *output_refs = NULL;
|
|
size_t output_refs_len = 0;
|
|
amduat_reference_t result_ref;
|
|
amduat_artifact_t result_artifact;
|
|
amduat_pel_surface_execution_result_t decoded;
|
|
int exit_code = 1;
|
|
|
|
cfg.encoding_profile_id = AMDUAT_ENC_ASL1_CORE_V1;
|
|
cfg.hash_id = AMDUAT_HASH_ASL1_ID_SHA256;
|
|
stub_store_init(&stub);
|
|
stub.config = cfg;
|
|
ops.put = stub_store_put;
|
|
ops.get = stub_store_get;
|
|
amduat_asl_store_init(&store, cfg, ops, &stub);
|
|
|
|
if (!build_concat_program_artifact(&program_artifact)) {
|
|
goto cleanup_store;
|
|
}
|
|
if (stub_store_put(&stub, program_artifact, &program_ref) !=
|
|
AMDUAT_ASL_STORE_OK) {
|
|
free((void *)program_artifact.bytes.data);
|
|
goto cleanup_store;
|
|
}
|
|
free((void *)program_artifact.bytes.data);
|
|
|
|
input_ref = make_ref(0x33u);
|
|
if (input_ref.digest.data == NULL) {
|
|
goto cleanup_refs;
|
|
}
|
|
|
|
if (!amduat_pel_surf_run(&store, amduat_pel_program_dag_scheme_ref(),
|
|
program_ref, &input_ref, 1, false,
|
|
amduat_reference(0, amduat_octets(NULL, 0)),
|
|
&output_refs, &output_refs_len, &result_ref)) {
|
|
fprintf(stderr, "surf run failed\n");
|
|
goto cleanup_refs;
|
|
}
|
|
|
|
if (output_refs_len != 0) {
|
|
fprintf(stderr, "unexpected output refs\n");
|
|
goto cleanup_refs;
|
|
}
|
|
|
|
if (stub_store_get(&stub, result_ref, &result_artifact) !=
|
|
AMDUAT_ASL_STORE_OK) {
|
|
fprintf(stderr, "result get failed\n");
|
|
goto cleanup_refs;
|
|
}
|
|
if (!amduat_enc_pel1_result_decode_v1(result_artifact.bytes, &decoded)) {
|
|
artifact_free(&result_artifact);
|
|
fprintf(stderr, "result decode failed\n");
|
|
goto cleanup_refs;
|
|
}
|
|
artifact_free(&result_artifact);
|
|
|
|
if (decoded.core_result.status != AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS ||
|
|
decoded.core_result.summary.kind != AMDUAT_PEL_EXEC_ERROR_INPUTS ||
|
|
decoded.core_result.summary.status_code != 3 ||
|
|
!decoded.has_store_failure ||
|
|
decoded.store_failure.phase != AMDUAT_PEL_STORE_FAILURE_INPUT ||
|
|
decoded.store_failure.error_code != AMDUAT_PEL_STORE_ERROR_NOT_FOUND ||
|
|
!amduat_reference_eq(decoded.store_failure.failing_ref, input_ref) ||
|
|
decoded.has_trace_ref) {
|
|
fprintf(stderr, "missing input mapping mismatch\n");
|
|
goto cleanup_decoded;
|
|
}
|
|
|
|
exit_code = 0;
|
|
|
|
cleanup_decoded:
|
|
amduat_enc_pel1_result_free(&decoded);
|
|
cleanup_refs:
|
|
amduat_pel_surf_free_refs(output_refs, output_refs_len);
|
|
amduat_pel_surf_free_ref(&result_ref);
|
|
amduat_pel_surf_free_ref(&program_ref);
|
|
amduat_pel_surf_free_ref(&input_ref);
|
|
cleanup_store:
|
|
stub_store_free(&stub);
|
|
return exit_code;
|
|
}
|
|
|
|
int main(void) {
|
|
if (test_surf_success() != 0) {
|
|
return 1;
|
|
}
|
|
if (test_surf_missing_program() != 0) {
|
|
return 1;
|
|
}
|
|
if (test_surf_missing_input() != 0) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|