diff --git a/include/amduat/pel/opreg_kernel.h b/include/amduat/pel/opreg_kernel.h index 49fbb4b..5b34a35 100644 --- a/include/amduat/pel/opreg_kernel.h +++ b/include/amduat/pel/opreg_kernel.h @@ -15,12 +15,14 @@ extern "C" { #define AMDUAT_PEL_KERNEL_OP_SLICE_NAME "pel.bytes.slice" #define AMDUAT_PEL_KERNEL_OP_CONST_NAME "pel.bytes.const" #define AMDUAT_PEL_KERNEL_OP_HASH_ASL1_NAME "pel.bytes.hash.asl1" +#define AMDUAT_PEL_KERNEL_OP_PARAMS_NAME "pel.bytes.params" enum { AMDUAT_PEL_KERNEL_OP_CODE_CONCAT = 0x0001u, AMDUAT_PEL_KERNEL_OP_CODE_SLICE = 0x0002u, AMDUAT_PEL_KERNEL_OP_CODE_CONST = 0x0003u, - AMDUAT_PEL_KERNEL_OP_CODE_HASH_ASL1 = 0x0004u + AMDUAT_PEL_KERNEL_OP_CODE_HASH_ASL1 = 0x0004u, + AMDUAT_PEL_KERNEL_OP_CODE_PARAMS = 0x0005u }; enum { @@ -34,7 +36,8 @@ typedef enum { AMDUAT_PEL_KERNEL_OP_CONCAT = 1, AMDUAT_PEL_KERNEL_OP_SLICE = 2, AMDUAT_PEL_KERNEL_OP_CONST = 3, - AMDUAT_PEL_KERNEL_OP_HASH_ASL1 = 4 + AMDUAT_PEL_KERNEL_OP_HASH_ASL1 = 4, + AMDUAT_PEL_KERNEL_OP_PARAMS = 5 } amduat_pel_kernel_op_kind_t; typedef struct { @@ -62,6 +65,7 @@ bool amduat_pel_kernel_op_eval( const amduat_artifact_t *inputs, size_t inputs_len, const amduat_pel_kernel_params_t *params, + const amduat_artifact_t *global_params, amduat_artifact_t **out_outputs, size_t *out_outputs_len, uint32_t *out_status_code); diff --git a/include/amduat/pel/program_dag.h b/include/amduat/pel/program_dag.h index 616f342..f5f51cb 100644 --- a/include/amduat/pel/program_dag.h +++ b/include/amduat/pel/program_dag.h @@ -82,6 +82,7 @@ bool amduat_pel_program_dag_exec( const amduat_pel_program_t *program, const amduat_artifact_t *inputs, size_t inputs_len, + const amduat_artifact_t *params, amduat_artifact_t **out_outputs, size_t *out_outputs_len, amduat_pel_execution_result_value_t *out_result); @@ -90,6 +91,7 @@ bool amduat_pel_program_dag_exec_trace( const amduat_pel_program_t *program, const amduat_artifact_t *inputs, size_t inputs_len, + const amduat_artifact_t *params, amduat_artifact_t **out_outputs, size_t *out_outputs_len, amduat_pel_execution_result_value_t *out_result, diff --git a/include/amduat/pel/run.h b/include/amduat/pel/run.h index 753c888..02415a2 100644 --- a/include/amduat/pel/run.h +++ b/include/amduat/pel/run.h @@ -33,10 +33,19 @@ bool amduat_pel_surf_run_with_result(amduat_asl_store_t *store, bool amduat_pel_exec_program_bytes(amduat_octets_t program_bytes, const amduat_artifact_t *inputs, size_t inputs_len, + const amduat_artifact_t *params, amduat_artifact_t **out_outputs, size_t *out_outputs_len, amduat_pel_execution_result_value_t *out_result); +bool amduat_pel_exec_program_artifact(amduat_artifact_t program_artifact, + const amduat_artifact_t *inputs, + size_t inputs_len, + const amduat_artifact_t *params, + amduat_artifact_t **out_outputs, + size_t *out_outputs_len, + amduat_pel_execution_result_value_t *out_result); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/pel_stack/opreg/kernel.c b/src/pel_stack/opreg/kernel.c index fcc5e88..3fb3905 100644 --- a/src/pel_stack/opreg/kernel.c +++ b/src/pel_stack/opreg/kernel.c @@ -49,6 +49,13 @@ static const amduat_pel_kernel_op_desc_t k_kernel_descs[] = { 1, 1 }, + { + AMDUAT_PEL_KERNEL_OP_PARAMS, + AMDUAT_PEL_KERNEL_OP_CODE_PARAMS, + 0, + 0, + 1 + }, }; const amduat_pel_kernel_op_desc_t *amduat_pel_kernel_op_lookup( @@ -69,6 +76,9 @@ const amduat_pel_kernel_op_desc_t *amduat_pel_kernel_op_lookup( if (amduat_name_eq(name, AMDUAT_PEL_KERNEL_OP_HASH_ASL1_NAME)) { return &k_kernel_descs[3]; } + if (amduat_name_eq(name, AMDUAT_PEL_KERNEL_OP_PARAMS_NAME)) { + return &k_kernel_descs[4]; + } return NULL; } @@ -90,6 +100,8 @@ const char *amduat_pel_kernel_op_name(amduat_pel_kernel_op_kind_t kind) { return AMDUAT_PEL_KERNEL_OP_CONST_NAME; case AMDUAT_PEL_KERNEL_OP_HASH_ASL1: return AMDUAT_PEL_KERNEL_OP_HASH_ASL1_NAME; + case AMDUAT_PEL_KERNEL_OP_PARAMS: + return AMDUAT_PEL_KERNEL_OP_PARAMS_NAME; default: return NULL; } @@ -413,11 +425,65 @@ static bool amduat_kernel_hash(const amduat_artifact_t *inputs, return true; } +static bool amduat_kernel_params(const amduat_artifact_t *global_params, + amduat_artifact_t **out_outputs, + size_t *out_outputs_len, + uint32_t *out_status_code) { + uint8_t *buffer; + + if (global_params == NULL) { + if (out_status_code) { + *out_status_code = AMDUAT_PEL_KERNEL_STATUS_INTERNAL; + } + return false; + } + if (global_params->bytes.len != 0 && global_params->bytes.data == NULL) { + if (out_status_code) { + *out_status_code = AMDUAT_PEL_KERNEL_STATUS_INTERNAL; + } + return false; + } + + buffer = NULL; + if (global_params->bytes.len != 0) { + buffer = (uint8_t *)malloc(global_params->bytes.len); + if (buffer == NULL) { + if (out_status_code) { + *out_status_code = AMDUAT_PEL_KERNEL_STATUS_OOM; + } + return false; + } + memcpy(buffer, global_params->bytes.data, global_params->bytes.len); + } + + if (!amduat_alloc_outputs(1, out_outputs)) { + free(buffer); + if (out_status_code) { + *out_status_code = AMDUAT_PEL_KERNEL_STATUS_OOM; + } + return false; + } + + (*out_outputs)[0].bytes = amduat_octets(buffer, global_params->bytes.len); + if (global_params->has_type_tag) { + (*out_outputs)[0].has_type_tag = true; + (*out_outputs)[0].type_tag = global_params->type_tag; + } else { + (*out_outputs)[0].has_type_tag = false; + (*out_outputs)[0].type_tag.tag_id = 0; + } + if (out_outputs_len) { + *out_outputs_len = 1; + } + return true; +} + bool amduat_pel_kernel_op_eval( const amduat_pel_kernel_op_desc_t *desc, const amduat_artifact_t *inputs, size_t inputs_len, const amduat_pel_kernel_params_t *params, + const amduat_artifact_t *global_params, amduat_artifact_t **out_outputs, size_t *out_outputs_len, uint32_t *out_status_code) { @@ -449,6 +515,9 @@ bool amduat_pel_kernel_op_eval( case AMDUAT_PEL_KERNEL_OP_HASH_ASL1: return amduat_kernel_hash(inputs, inputs_len, ¶ms->value.hash, out_outputs, out_outputs_len, out_status_code); + case AMDUAT_PEL_KERNEL_OP_PARAMS: + return amduat_kernel_params(global_params, out_outputs, out_outputs_len, + out_status_code); default: *out_status_code = AMDUAT_PEL_KERNEL_STATUS_INTERNAL; return false; diff --git a/src/pel_stack/opreg/kernel_params.c b/src/pel_stack/opreg/kernel_params.c index dbdd364..775efcf 100644 --- a/src/pel_stack/opreg/kernel_params.c +++ b/src/pel_stack/opreg/kernel_params.c @@ -126,6 +126,8 @@ bool amduat_pel_kernel_params_decode( return amduat_decode_const(params_bytes, &out_params->value.konst); case AMDUAT_PEL_KERNEL_OP_HASH_ASL1: return amduat_decode_hash(params_bytes, &out_params->value.hash); + case AMDUAT_PEL_KERNEL_OP_PARAMS: + return amduat_decode_unit(params_bytes); default: return false; } diff --git a/src/pel_stack/program_dag/program_dag.c b/src/pel_stack/program_dag/program_dag.c index 493af28..f7bcb78 100644 --- a/src/pel_stack/program_dag/program_dag.c +++ b/src/pel_stack/program_dag/program_dag.c @@ -460,6 +460,7 @@ static bool amduat_pel_program_dag_exec_internal( const amduat_pel_program_t *program, const amduat_artifact_t *inputs, size_t inputs_len, + const amduat_artifact_t *params, amduat_artifact_t **out_outputs, size_t *out_outputs_len, amduat_pel_execution_result_value_t *out_result, @@ -476,6 +477,7 @@ static bool amduat_pel_program_dag_exec_internal( if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) { return false; } + (void)params; *out_outputs = NULL; *out_outputs_len = 0; @@ -594,7 +596,8 @@ static bool amduat_pel_program_dag_exec_internal( if (!amduat_pel_kernel_op_eval( prepared.ops[node_index], resolved_inputs, node->inputs_len, - &prepared.params[node_index], &node_results[node_index].outputs, + &prepared.params[node_index], params, + &node_results[node_index].outputs, &node_results[node_index].outputs_len, &status_code)) { if (status_code == AMDUAT_PEL_KERNEL_STATUS_OOM) { free(resolved_inputs); @@ -699,18 +702,20 @@ bool amduat_pel_program_dag_exec( const amduat_pel_program_t *program, const amduat_artifact_t *inputs, size_t inputs_len, + const amduat_artifact_t *params, amduat_artifact_t **out_outputs, size_t *out_outputs_len, amduat_pel_execution_result_value_t *out_result) { return amduat_pel_program_dag_exec_internal( - program, inputs, inputs_len, out_outputs, out_outputs_len, out_result, - NULL); + program, inputs, inputs_len, params, out_outputs, out_outputs_len, + out_result, NULL); } bool amduat_pel_program_dag_exec_trace( const amduat_pel_program_t *program, const amduat_artifact_t *inputs, size_t inputs_len, + const amduat_artifact_t *params, amduat_artifact_t **out_outputs, size_t *out_outputs_len, amduat_pel_execution_result_value_t *out_result, @@ -719,8 +724,8 @@ bool amduat_pel_program_dag_exec_trace( return false; } return amduat_pel_program_dag_exec_internal( - program, inputs, inputs_len, out_outputs, out_outputs_len, out_result, - out_trace); + program, inputs, inputs_len, params, out_outputs, out_outputs_len, + out_result, out_trace); } void amduat_pel_program_dag_free_outputs(amduat_artifact_t *outputs, diff --git a/src/pel_stack/run.c b/src/pel_stack/run.c index 6b0e37b..e574321 100644 --- a/src/pel_stack/run.c +++ b/src/pel_stack/run.c @@ -51,6 +51,7 @@ bool amduat_pel_surf_run_with_result(amduat_asl_store_t *store, bool amduat_pel_exec_program_bytes(amduat_octets_t program_bytes, const amduat_artifact_t *inputs, size_t inputs_len, + const amduat_artifact_t *params, amduat_artifact_t **out_outputs, size_t *out_outputs_len, amduat_pel_execution_result_value_t *out_result) { @@ -96,9 +97,44 @@ bool amduat_pel_exec_program_bytes(amduat_octets_t program_bytes, ok = amduat_pel_program_dag_exec(&program, inputs, inputs_len, + params, out_outputs, out_outputs_len, out_result); amduat_enc_pel_program_dag_free(&program); return ok; } + +bool amduat_pel_exec_program_artifact(amduat_artifact_t program_artifact, + const amduat_artifact_t *inputs, + size_t inputs_len, + const amduat_artifact_t *params, + amduat_artifact_t **out_outputs, + size_t *out_outputs_len, + amduat_pel_execution_result_value_t *out_result) { + if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) { + return false; + } + + if (!program_artifact.has_type_tag || + program_artifact.type_tag.tag_id != AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1) { + out_result->pel1_version = 1; + out_result->status = AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM; + out_result->scheme_ref = amduat_pel_program_dag_scheme_ref(); + out_result->summary.kind = AMDUAT_PEL_EXEC_ERROR_PROGRAM; + out_result->summary.status_code = 2; + out_result->diagnostics = NULL; + out_result->diagnostics_len = 0; + *out_outputs = NULL; + *out_outputs_len = 0; + return true; + } + + return amduat_pel_exec_program_bytes(program_artifact.bytes, + inputs, + inputs_len, + params, + out_outputs, + out_outputs_len, + out_result); +} diff --git a/src/pel_stack/surf/surf.c b/src/pel_stack/surf/surf.c index 2f69aaf..63fd716 100644 --- a/src/pel_stack/surf/surf.c +++ b/src/pel_stack/surf/surf.c @@ -60,9 +60,6 @@ static bool amduat_store_error_map(amduat_asl_store_error_t err, case AMDUAT_ASL_STORE_ERR_UNSUPPORTED: *out_code = AMDUAT_PEL_STORE_ERROR_UNSUPPORTED; return true; - case AMDUAT_ASL_STORE_ERR_IO: - *out_code = AMDUAT_PEL_STORE_ERROR_INTEGRITY; - return true; default: return false; } @@ -425,9 +422,11 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store, AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2); } else { program_decoded = true; + const amduat_artifact_t *params_arg = + has_params_artifact ? ¶ms_artifact : NULL; if (!amduat_pel_program_dag_exec_trace( - &program, input_artifacts, input_refs_len, &outputs, &outputs_len, - &core_result, &trace_eval)) { + &program, input_artifacts, input_refs_len, params_arg, &outputs, + &outputs_len, &core_result, &trace_eval)) { amduat_artifact_free(&program_artifact); amduat_enc_pel_program_dag_free(&program); for (i = 0; i < input_refs_len; ++i) { diff --git a/src/tools/amduat_pel_cli.c b/src/tools/amduat_pel_cli.c index 83420dc..7baf28d 100644 --- a/src/tools/amduat_pel_cli.c +++ b/src/tools/amduat_pel_cli.c @@ -810,6 +810,7 @@ static int amduat_pel_cli_cmd_exec(int argc, program_len), inputs, input_paths_len, + NULL, &outputs, &outputs_len, &result)) { diff --git a/tests/pel/test_pel_program_dag_exec.c b/tests/pel/test_pel_program_dag_exec.c index 5becc86..c2bb77f 100644 --- a/tests/pel/test_pel_program_dag_exec.c +++ b/tests/pel/test_pel_program_dag_exec.c @@ -94,7 +94,7 @@ static int test_valid_program(void) { inputs[0] = amduat_artifact(amduat_octets("!", 1)); - if (!amduat_pel_program_dag_exec(&program, inputs, 1, &outputs, + if (!amduat_pel_program_dag_exec(&program, inputs, 1, NULL, &outputs, &outputs_len, &result)) { fprintf(stderr, "exec failed\n"); goto cleanup; @@ -162,7 +162,7 @@ static int test_invalid_program_cycle(void) { program.roots = roots; program.roots_len = 1; - if (!amduat_pel_program_dag_exec(&program, NULL, 0, &outputs, + if (!amduat_pel_program_dag_exec(&program, NULL, 0, NULL, &outputs, &outputs_len, &result)) { fprintf(stderr, "exec failed\n"); return 1; @@ -212,7 +212,7 @@ static int test_invalid_params(void) { inputs[0] = amduat_artifact(amduat_octets("x", 1)); - if (!amduat_pel_program_dag_exec(&program, inputs, 1, &outputs, + if (!amduat_pel_program_dag_exec(&program, inputs, 1, NULL, &outputs, &outputs_len, &result)) { fprintf(stderr, "exec failed\n"); return 1; @@ -261,7 +261,7 @@ static int test_invalid_input_index(void) { inputs[0] = amduat_artifact(amduat_octets("x", 1)); - if (!amduat_pel_program_dag_exec(&program, inputs, 1, &outputs, + if (!amduat_pel_program_dag_exec(&program, inputs, 1, NULL, &outputs, &outputs_len, &result)) { fprintf(stderr, "exec failed\n"); return 1; diff --git a/tests/pel/test_pel_surf_run.c b/tests/pel/test_pel_surf_run.c index d55de64..145f09d 100644 --- a/tests/pel/test_pel_surf_run.c +++ b/tests/pel/test_pel_surf_run.c @@ -25,6 +25,9 @@ typedef struct { size_t len; size_t cap; amduat_asl_store_config_t config; + bool fail_get; + amduat_reference_t fail_get_ref; + amduat_asl_store_error_t fail_get_error; } stub_store_t; static void stub_store_init(stub_store_t *store) { @@ -36,6 +39,9 @@ static void stub_store_init(stub_store_t *store) { store->cap = 0; store->config.encoding_profile_id = 0; store->config.hash_id = 0; + store->fail_get = false; + store->fail_get_ref = amduat_reference(0, amduat_octets(NULL, 0)); + store->fail_get_error = AMDUAT_ASL_STORE_OK; } static void stub_store_free(stub_store_t *store) { @@ -57,6 +63,8 @@ static void stub_store_free(stub_store_t *store) { store->entries = NULL; store->len = 0; store->cap = 0; + amduat_reference_free(&store->fail_get_ref); + store->fail_get = false; } static bool artifact_eq(const amduat_artifact_t *a, @@ -199,6 +207,11 @@ static amduat_asl_store_error_t stub_store_get( } store = (stub_store_t *)ctx; + if (store->fail_get && + amduat_reference_eq(store->fail_get_ref, ref)) { + return store->fail_get_error; + } + for (i = 0; i < store->len; ++i) { stub_store_entry_t *entry = &store->entries[i]; if (amduat_reference_eq(entry->ref, ref)) { @@ -332,6 +345,38 @@ static bool build_concat_program_artifact(amduat_artifact_t *out_artifact) { return true; } +static bool build_params_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 encoded; + const char op_params[] = "pel.bytes.params"; + + nodes[0].id = 1; + nodes[0].op.name = amduat_octets(op_params, strlen(op_params)); + nodes[0].op.version = 1; + nodes[0].inputs = NULL; + nodes[0].inputs_len = 0; + 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) { @@ -367,6 +412,8 @@ static int test_surf_success(void) { ops.put = stub_store_put; ops.get = stub_store_get; amduat_asl_store_init(&store, cfg, ops, &stub); + program_ref = amduat_reference(0, amduat_octets(NULL, 0)); + result_ref = amduat_reference(0, amduat_octets(NULL, 0)); if (!build_const_program_artifact(&program_artifact)) { fprintf(stderr, "build program failed\n"); @@ -639,6 +686,178 @@ cleanup_store: return exit_code; } +static int test_surf_store_io_failure(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; + size_t entries_before = 0; + 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; + amduat_asl_store_ops_init(&ops); + 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_reference_clone(program_ref, &stub.fail_get_ref)) { + fprintf(stderr, "fail ref clone failed\n"); + goto cleanup_refs; + } + stub.fail_get = true; + stub.fail_get_error = AMDUAT_ASL_STORE_ERR_IO; + entries_before = stub.len; + + 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, "expected surf run failure\n"); + goto cleanup_refs; + } + + if (stub.len != entries_before) { + fprintf(stderr, "unexpected store mutation\n"); + goto cleanup_refs; + } + + exit_code = 0; + +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_params_pass_through(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_artifact_t params_artifact; + amduat_reference_t params_ref; + amduat_reference_t *output_refs = NULL; + size_t output_refs_len = 0; + amduat_reference_t result_ref; + amduat_artifact_t output_artifact; + amduat_artifact_t result_artifact; + amduat_pel_surface_execution_result_t decoded; + const uint8_t params_bytes[] = {'p', 'a', 'r', 'a', 'm', 's'}; + 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; + amduat_asl_store_ops_init(&ops); + ops.put = stub_store_put; + ops.get = stub_store_get; + amduat_asl_store_init(&store, cfg, ops, &stub); + program_ref = amduat_reference(0, amduat_octets(NULL, 0)); + params_ref = amduat_reference(0, amduat_octets(NULL, 0)); + result_ref = amduat_reference(0, amduat_octets(NULL, 0)); + + if (!build_params_program_artifact(&program_artifact)) { + fprintf(stderr, "build params 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); + + params_artifact = amduat_artifact(amduat_octets(params_bytes, + sizeof(params_bytes))); + if (stub_store_put(&stub, params_artifact, ¶ms_ref) != + AMDUAT_ASL_STORE_OK) { + fprintf(stderr, "params put failed\n"); + goto cleanup_refs; + } + + if (!amduat_pel_surf_run(&store, amduat_pel_program_dag_scheme_ref(), + program_ref, NULL, 0, true, params_ref, + &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, output_refs[0], &output_artifact) != + AMDUAT_ASL_STORE_OK) { + fprintf(stderr, "output get failed\n"); + goto cleanup_refs; + } + if (!artifact_eq(&output_artifact, ¶ms_artifact)) { + artifact_free(&output_artifact); + fprintf(stderr, "params output mismatch\n"); + goto cleanup_refs; + } + artifact_free(&output_artifact); + + 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.has_params_ref || + !amduat_reference_eq(decoded.params_ref, params_ref)) { + fprintf(stderr, "missing params ref\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(¶ms_ref); +cleanup_store: + stub_store_free(&stub); + return exit_code; +} + int main(void) { if (test_surf_success() != 0) { return 1; @@ -649,5 +868,11 @@ int main(void) { if (test_surf_missing_input() != 0) { return 1; } + if (test_surf_store_io_failure() != 0) { + return 1; + } + if (test_surf_params_pass_through() != 0) { + return 1; + } return 0; }