Implement PEL encodings and tests
This commit is contained in:
parent
96bf3f08b3
commit
585844a6fc
|
|
@ -78,6 +78,7 @@ set(AMDUAT_ENC_SRCS
|
||||||
src/near_core/enc/asl1_core_codec.c
|
src/near_core/enc/asl1_core_codec.c
|
||||||
src/near_core/enc/pel_program_dag.c
|
src/near_core/enc/pel_program_dag.c
|
||||||
src/near_core/enc/pel_trace_dag.c
|
src/near_core/enc/pel_trace_dag.c
|
||||||
|
src/near_core/enc/pel1_result.c
|
||||||
src/near_core/enc/tgk1_edge.c
|
src/near_core/enc/tgk1_edge.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -147,3 +148,35 @@ target_link_libraries(amduat_asl_cli
|
||||||
PRIVATE amduat_asl_store_fs amduat_asl amduat_enc amduat_hash_asl1 amduat_util
|
PRIVATE amduat_asl_store_fs amduat_asl amduat_enc amduat_hash_asl1 amduat_util
|
||||||
)
|
)
|
||||||
set_target_properties(amduat_asl_cli PROPERTIES OUTPUT_NAME amduat-asl)
|
set_target_properties(amduat_asl_cli PROPERTIES OUTPUT_NAME amduat-asl)
|
||||||
|
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
add_executable(amduat_test_pel_program_dag tests/enc/test_pel_program_dag.c)
|
||||||
|
target_include_directories(amduat_test_pel_program_dag
|
||||||
|
PRIVATE ${AMDUAT_INTERNAL_DIR}
|
||||||
|
PRIVATE ${AMDUAT_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(amduat_test_pel_program_dag
|
||||||
|
PRIVATE amduat_enc amduat_hash_asl1 amduat_asl amduat_util
|
||||||
|
)
|
||||||
|
add_test(NAME pel_program_dag COMMAND amduat_test_pel_program_dag)
|
||||||
|
|
||||||
|
add_executable(amduat_test_pel_trace_dag tests/enc/test_pel_trace_dag.c)
|
||||||
|
target_include_directories(amduat_test_pel_trace_dag
|
||||||
|
PRIVATE ${AMDUAT_INTERNAL_DIR}
|
||||||
|
PRIVATE ${AMDUAT_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(amduat_test_pel_trace_dag
|
||||||
|
PRIVATE amduat_enc amduat_hash_asl1 amduat_asl amduat_util
|
||||||
|
)
|
||||||
|
add_test(NAME pel_trace_dag COMMAND amduat_test_pel_trace_dag)
|
||||||
|
|
||||||
|
add_executable(amduat_test_pel1_result tests/enc/test_pel1_result.c)
|
||||||
|
target_include_directories(amduat_test_pel1_result
|
||||||
|
PRIVATE ${AMDUAT_INTERNAL_DIR}
|
||||||
|
PRIVATE ${AMDUAT_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(amduat_test_pel1_result
|
||||||
|
PRIVATE amduat_enc amduat_hash_asl1 amduat_asl amduat_util
|
||||||
|
)
|
||||||
|
add_test(NAME pel1_result COMMAND amduat_test_pel1_result)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef AMDUAT_ENC_PEL1_RESULT_H
|
#ifndef AMDUAT_ENC_PEL1_RESULT_H
|
||||||
#define AMDUAT_ENC_PEL1_RESULT_H
|
#define AMDUAT_ENC_PEL1_RESULT_H
|
||||||
|
|
||||||
|
#include "amduat/asl/core.h"
|
||||||
|
#include "amduat/pel/surf.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -8,6 +11,17 @@ extern "C" {
|
||||||
enum { PEL_ENC_EXECUTION_RESULT_V1 = 0x0103u };
|
enum { PEL_ENC_EXECUTION_RESULT_V1 = 0x0103u };
|
||||||
enum { AMDUAT_PEL_ENC_EXECUTION_RESULT_V1 = PEL_ENC_EXECUTION_RESULT_V1 };
|
enum { AMDUAT_PEL_ENC_EXECUTION_RESULT_V1 = PEL_ENC_EXECUTION_RESULT_V1 };
|
||||||
|
|
||||||
|
/* Caller owns any heap allocations returned in out_bytes/out_result. */
|
||||||
|
bool amduat_enc_pel1_result_encode_v1(
|
||||||
|
const amduat_pel_surface_execution_result_t *result,
|
||||||
|
amduat_octets_t *out_bytes);
|
||||||
|
|
||||||
|
bool amduat_enc_pel1_result_decode_v1(
|
||||||
|
amduat_octets_t bytes,
|
||||||
|
amduat_pel_surface_execution_result_t *out_result);
|
||||||
|
|
||||||
|
void amduat_enc_pel1_result_free(amduat_pel_surface_execution_result_t *result);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef AMDUAT_ENC_PEL_PROGRAM_DAG_H
|
#ifndef AMDUAT_ENC_PEL_PROGRAM_DAG_H
|
||||||
#define AMDUAT_ENC_PEL_PROGRAM_DAG_H
|
#define AMDUAT_ENC_PEL_PROGRAM_DAG_H
|
||||||
|
|
||||||
|
#include "amduat/asl/core.h"
|
||||||
|
#include "amduat/pel/program_dag.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -8,6 +11,17 @@ extern "C" {
|
||||||
enum { PEL_ENC_PROGRAM_DAG_V1 = 0x0101u };
|
enum { PEL_ENC_PROGRAM_DAG_V1 = 0x0101u };
|
||||||
enum { AMDUAT_PEL_ENC_PROGRAM_DAG_V1 = PEL_ENC_PROGRAM_DAG_V1 };
|
enum { AMDUAT_PEL_ENC_PROGRAM_DAG_V1 = PEL_ENC_PROGRAM_DAG_V1 };
|
||||||
|
|
||||||
|
/* Caller owns any heap allocations returned in out_bytes/out_program. */
|
||||||
|
bool amduat_enc_pel_program_dag_encode_v1(
|
||||||
|
const amduat_pel_program_t *program,
|
||||||
|
amduat_octets_t *out_bytes);
|
||||||
|
|
||||||
|
bool amduat_enc_pel_program_dag_decode_v1(
|
||||||
|
amduat_octets_t bytes,
|
||||||
|
amduat_pel_program_t *out_program);
|
||||||
|
|
||||||
|
void amduat_enc_pel_program_dag_free(amduat_pel_program_t *program);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef AMDUAT_ENC_PEL_TRACE_DAG_H
|
#ifndef AMDUAT_ENC_PEL_TRACE_DAG_H
|
||||||
#define AMDUAT_ENC_PEL_TRACE_DAG_H
|
#define AMDUAT_ENC_PEL_TRACE_DAG_H
|
||||||
|
|
||||||
|
#include "amduat/asl/core.h"
|
||||||
|
#include "amduat/pel/trace_dag.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -8,6 +11,17 @@ extern "C" {
|
||||||
enum { PEL_ENC_TRACE_DAG_V1 = 0x0102u };
|
enum { PEL_ENC_TRACE_DAG_V1 = 0x0102u };
|
||||||
enum { AMDUAT_PEL_ENC_TRACE_DAG_V1 = PEL_ENC_TRACE_DAG_V1 };
|
enum { AMDUAT_PEL_ENC_TRACE_DAG_V1 = PEL_ENC_TRACE_DAG_V1 };
|
||||||
|
|
||||||
|
/* Caller owns any heap allocations returned in out_bytes/out_trace. */
|
||||||
|
bool amduat_enc_pel_trace_dag_encode_v1(
|
||||||
|
const amduat_pel_trace_dag_value_t *trace,
|
||||||
|
amduat_octets_t *out_bytes);
|
||||||
|
|
||||||
|
bool amduat_enc_pel_trace_dag_decode_v1(
|
||||||
|
amduat_octets_t bytes,
|
||||||
|
amduat_pel_trace_dag_value_t *out_trace);
|
||||||
|
|
||||||
|
void amduat_enc_pel_trace_dag_free(amduat_pel_trace_dag_value_t *trace);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef AMDUAT_PEL_CORE_H
|
||||||
|
#define AMDUAT_PEL_CORE_H
|
||||||
|
|
||||||
|
#include "amduat/asl/core.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t amduat_pel_execution_status_t;
|
||||||
|
typedef uint8_t amduat_pel_execution_error_kind_t;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AMDUAT_PEL_EXEC_STATUS_OK = 0,
|
||||||
|
AMDUAT_PEL_EXEC_STATUS_SCHEME_UNSUPPORTED = 1,
|
||||||
|
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM = 2,
|
||||||
|
AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS = 3,
|
||||||
|
AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AMDUAT_PEL_EXEC_ERROR_NONE = 0,
|
||||||
|
AMDUAT_PEL_EXEC_ERROR_SCHEME = 1,
|
||||||
|
AMDUAT_PEL_EXEC_ERROR_PROGRAM = 2,
|
||||||
|
AMDUAT_PEL_EXEC_ERROR_INPUTS = 3,
|
||||||
|
AMDUAT_PEL_EXEC_ERROR_RUNTIME = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
amduat_pel_execution_error_kind_t kind;
|
||||||
|
uint32_t status_code;
|
||||||
|
} amduat_pel_execution_error_summary_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t code;
|
||||||
|
amduat_octets_t message;
|
||||||
|
} amduat_pel_diagnostic_entry_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t pel1_version;
|
||||||
|
amduat_pel_execution_status_t status;
|
||||||
|
amduat_reference_t scheme_ref;
|
||||||
|
amduat_pel_execution_error_summary_t summary;
|
||||||
|
amduat_pel_diagnostic_entry_t *diagnostics;
|
||||||
|
size_t diagnostics_len;
|
||||||
|
} amduat_pel_execution_result_value_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AMDUAT_PEL_CORE_H */
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
#ifndef AMDUAT_PEL_PROGRAM_DAG_H
|
||||||
|
#define AMDUAT_PEL_PROGRAM_DAG_H
|
||||||
|
|
||||||
|
#include "amduat/asl/core.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint32_t amduat_pel_node_id_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
amduat_octets_t name;
|
||||||
|
uint32_t version;
|
||||||
|
} amduat_pel_operation_id_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
AMDUAT_PEL_DAG_INPUT_EXTERNAL = 0,
|
||||||
|
AMDUAT_PEL_DAG_INPUT_NODE = 1
|
||||||
|
} amduat_pel_dag_input_kind_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t input_index;
|
||||||
|
} amduat_pel_dag_input_external_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
amduat_pel_node_id_t node_id;
|
||||||
|
uint32_t output_index;
|
||||||
|
} amduat_pel_dag_input_node_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
amduat_pel_dag_input_kind_t kind;
|
||||||
|
union {
|
||||||
|
amduat_pel_dag_input_external_t external;
|
||||||
|
amduat_pel_dag_input_node_t node;
|
||||||
|
} value;
|
||||||
|
} amduat_pel_dag_input_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
amduat_pel_node_id_t id;
|
||||||
|
amduat_pel_operation_id_t op;
|
||||||
|
amduat_pel_dag_input_t *inputs;
|
||||||
|
size_t inputs_len;
|
||||||
|
amduat_octets_t params;
|
||||||
|
} amduat_pel_node_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
amduat_pel_node_id_t node_id;
|
||||||
|
uint32_t output_index;
|
||||||
|
} amduat_pel_root_ref_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
amduat_pel_node_t *nodes;
|
||||||
|
size_t nodes_len;
|
||||||
|
amduat_pel_root_ref_t *roots;
|
||||||
|
size_t roots_len;
|
||||||
|
} amduat_pel_program_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AMDUAT_PEL_PROGRAM_DAG_H */
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
#ifndef AMDUAT_PEL_SURF_H
|
||||||
|
#define AMDUAT_PEL_SURF_H
|
||||||
|
|
||||||
|
#include "amduat/pel/core.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t amduat_pel_store_failure_phase_t;
|
||||||
|
typedef uint8_t amduat_pel_store_error_code_t;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AMDUAT_PEL_STORE_FAILURE_PROGRAM = 1,
|
||||||
|
AMDUAT_PEL_STORE_FAILURE_INPUT = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AMDUAT_PEL_STORE_ERROR_NOT_FOUND = 1,
|
||||||
|
AMDUAT_PEL_STORE_ERROR_INTEGRITY = 2,
|
||||||
|
AMDUAT_PEL_STORE_ERROR_UNSUPPORTED = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
amduat_pel_store_failure_phase_t phase;
|
||||||
|
amduat_pel_store_error_code_t error_code;
|
||||||
|
amduat_reference_t failing_ref;
|
||||||
|
} amduat_pel_store_failure_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t pel1_version;
|
||||||
|
amduat_pel_execution_result_value_t core_result;
|
||||||
|
amduat_reference_t scheme_ref;
|
||||||
|
amduat_reference_t program_ref;
|
||||||
|
amduat_reference_t *input_refs;
|
||||||
|
size_t input_refs_len;
|
||||||
|
amduat_reference_t *output_refs;
|
||||||
|
size_t output_refs_len;
|
||||||
|
bool has_params_ref;
|
||||||
|
amduat_reference_t params_ref;
|
||||||
|
bool has_store_failure;
|
||||||
|
amduat_pel_store_failure_t store_failure;
|
||||||
|
bool has_trace_ref;
|
||||||
|
amduat_reference_t trace_ref;
|
||||||
|
} amduat_pel_surface_execution_result_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AMDUAT_PEL_SURF_H */
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef AMDUAT_PEL_TRACE_DAG_H
|
||||||
|
#define AMDUAT_PEL_TRACE_DAG_H
|
||||||
|
|
||||||
|
#include "amduat/pel/core.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t amduat_pel_node_trace_status_t;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AMDUAT_PEL_NODE_TRACE_OK = 0,
|
||||||
|
AMDUAT_PEL_NODE_TRACE_FAILED = 1,
|
||||||
|
AMDUAT_PEL_NODE_TRACE_SKIPPED = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t node_id;
|
||||||
|
amduat_octets_t op_name;
|
||||||
|
uint32_t op_version;
|
||||||
|
amduat_pel_node_trace_status_t status;
|
||||||
|
uint32_t status_code;
|
||||||
|
amduat_reference_t *output_refs;
|
||||||
|
size_t output_refs_len;
|
||||||
|
amduat_pel_diagnostic_entry_t *diagnostics;
|
||||||
|
size_t diagnostics_len;
|
||||||
|
} amduat_pel_node_trace_dag_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t pel1_version;
|
||||||
|
amduat_reference_t scheme_ref;
|
||||||
|
amduat_reference_t program_ref;
|
||||||
|
amduat_pel_execution_status_t status;
|
||||||
|
amduat_pel_execution_error_summary_t summary;
|
||||||
|
bool has_exec_result_ref;
|
||||||
|
amduat_reference_t exec_result_ref;
|
||||||
|
amduat_reference_t *input_refs;
|
||||||
|
size_t input_refs_len;
|
||||||
|
bool has_params_ref;
|
||||||
|
amduat_reference_t params_ref;
|
||||||
|
amduat_pel_node_trace_dag_t *node_traces;
|
||||||
|
size_t node_traces_len;
|
||||||
|
} amduat_pel_trace_dag_value_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AMDUAT_PEL_TRACE_DAG_H */
|
||||||
734
src/near_core/enc/pel1_result.c
Normal file
734
src/near_core/enc/pel1_result.c
Normal file
|
|
@ -0,0 +1,734 @@
|
||||||
|
#include "amduat/enc/pel1_result.h"
|
||||||
|
|
||||||
|
#include "amduat/enc/asl1_core_codec.h"
|
||||||
|
#include "amduat/hash/asl1.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const uint8_t *data;
|
||||||
|
size_t len;
|
||||||
|
size_t offset;
|
||||||
|
} amduat_cursor_t;
|
||||||
|
|
||||||
|
static void amduat_store_u16_be(uint8_t *out, uint16_t value) {
|
||||||
|
out[0] = (uint8_t)((value >> 8) & 0xffu);
|
||||||
|
out[1] = (uint8_t)(value & 0xffu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_store_u32_be(uint8_t *out, uint32_t value) {
|
||||||
|
out[0] = (uint8_t)((value >> 24) & 0xffu);
|
||||||
|
out[1] = (uint8_t)((value >> 16) & 0xffu);
|
||||||
|
out[2] = (uint8_t)((value >> 8) & 0xffu);
|
||||||
|
out[3] = (uint8_t)(value & 0xffu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_u8(amduat_cursor_t *cur, uint8_t *out) {
|
||||||
|
if (cur->len - cur->offset < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = cur->data[cur->offset];
|
||||||
|
cur->offset += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_u16(amduat_cursor_t *cur, uint16_t *out) {
|
||||||
|
const uint8_t *data;
|
||||||
|
if (cur->len - cur->offset < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = cur->data + cur->offset;
|
||||||
|
*out = (uint16_t)((data[0] << 8) | data[1]);
|
||||||
|
cur->offset += 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_u32(amduat_cursor_t *cur, uint32_t *out) {
|
||||||
|
const uint8_t *data;
|
||||||
|
if (cur->len - cur->offset < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = cur->data + cur->offset;
|
||||||
|
*out = ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) |
|
||||||
|
((uint32_t)data[2] << 8) | (uint32_t)data[3];
|
||||||
|
cur->offset += 4;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_add_size(size_t *acc, size_t add) {
|
||||||
|
if (*acc > SIZE_MAX - add) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*acc += add;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_reference_bytes_len(amduat_reference_t ref, size_t *out_len) {
|
||||||
|
const amduat_hash_asl1_desc_t *desc;
|
||||||
|
|
||||||
|
if (ref.digest.len != 0 && ref.digest.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc = amduat_hash_asl1_desc_lookup(ref.hash_id);
|
||||||
|
if (desc == NULL || desc->digest_len == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ref.digest.len != desc->digest_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_len = 2 + desc->digest_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_encoded_ref_len(amduat_reference_t ref, size_t *out_len) {
|
||||||
|
size_t ref_len;
|
||||||
|
|
||||||
|
if (!amduat_reference_bytes_len(ref, &ref_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ref_len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out_len = 4 + ref_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_write_encoded_ref(uint8_t *buffer,
|
||||||
|
size_t buffer_len,
|
||||||
|
size_t *offset,
|
||||||
|
amduat_reference_t ref) {
|
||||||
|
size_t ref_len;
|
||||||
|
|
||||||
|
if (!amduat_reference_bytes_len(ref, &ref_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ref_len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (buffer_len - *offset < 4 + ref_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + *offset, (uint32_t)ref_len);
|
||||||
|
*offset += 4;
|
||||||
|
amduat_store_u16_be(buffer + *offset, ref.hash_id);
|
||||||
|
*offset += 2;
|
||||||
|
if (ref.digest.len != 0) {
|
||||||
|
memcpy(buffer + *offset, ref.digest.data, ref.digest.len);
|
||||||
|
*offset += ref.digest.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_encoded_ref(amduat_cursor_t *cur,
|
||||||
|
amduat_reference_t *out_ref) {
|
||||||
|
uint32_t ref_len_u32;
|
||||||
|
amduat_octets_t ref_bytes;
|
||||||
|
|
||||||
|
if (!amduat_read_u32(cur, &ref_len_u32)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ref_len_u32 < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cur->len - cur->offset < ref_len_u32) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ref_bytes = amduat_octets(cur->data + cur->offset, ref_len_u32);
|
||||||
|
if (!amduat_enc_asl1_core_decode_reference_v1(ref_bytes, out_ref)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cur->offset += ref_len_u32;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_reference_free(amduat_reference_t *ref) {
|
||||||
|
if (ref == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free((void *)ref->digest.data);
|
||||||
|
ref->digest.data = NULL;
|
||||||
|
ref->digest.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_diagnostic_list_free(amduat_pel_diagnostic_entry_t *entries,
|
||||||
|
size_t count) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (entries == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
free((void *)entries[i].message.data);
|
||||||
|
entries[i].message.data = NULL;
|
||||||
|
entries[i].message.len = 0;
|
||||||
|
}
|
||||||
|
free(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_execution_result_value_size(
|
||||||
|
const amduat_pel_execution_result_value_t *value,
|
||||||
|
size_t *out_len) {
|
||||||
|
size_t total = 0;
|
||||||
|
size_t enc_len;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (value->pel1_version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (value->diagnostics_len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (value->diagnostics_len > 0 && value->diagnostics == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_encoded_ref_len(value->scheme_ref, &enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_add_size(&total, 2 + 1 + enc_len + 1 + 4 + 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < value->diagnostics_len; ++i) {
|
||||||
|
const amduat_pel_diagnostic_entry_t *diag = &value->diagnostics[i];
|
||||||
|
if (diag->message.len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (diag->message.len != 0 && diag->message.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total, 4 + 4 + diag->message.len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_len = total;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_write_execution_result_value(
|
||||||
|
uint8_t *buffer,
|
||||||
|
size_t buffer_len,
|
||||||
|
size_t *offset,
|
||||||
|
const amduat_pel_execution_result_value_t *value) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (value->pel1_version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u16_be(buffer + *offset, value->pel1_version);
|
||||||
|
*offset += 2;
|
||||||
|
buffer[(*offset)++] = value->status;
|
||||||
|
if (!amduat_write_encoded_ref(buffer, buffer_len, offset, value->scheme_ref)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buffer[(*offset)++] = value->summary.kind;
|
||||||
|
amduat_store_u32_be(buffer + *offset, value->summary.status_code);
|
||||||
|
*offset += 4;
|
||||||
|
amduat_store_u32_be(buffer + *offset, (uint32_t)value->diagnostics_len);
|
||||||
|
*offset += 4;
|
||||||
|
|
||||||
|
for (i = 0; i < value->diagnostics_len; ++i) {
|
||||||
|
const amduat_pel_diagnostic_entry_t *diag = &value->diagnostics[i];
|
||||||
|
amduat_store_u32_be(buffer + *offset, diag->code);
|
||||||
|
*offset += 4;
|
||||||
|
amduat_store_u32_be(buffer + *offset, (uint32_t)diag->message.len);
|
||||||
|
*offset += 4;
|
||||||
|
if (diag->message.len != 0) {
|
||||||
|
memcpy(buffer + *offset, diag->message.data, diag->message.len);
|
||||||
|
*offset += diag->message.len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_execution_result_value(
|
||||||
|
amduat_cursor_t *cur,
|
||||||
|
amduat_pel_execution_result_value_t *out_value) {
|
||||||
|
uint16_t pel1_version;
|
||||||
|
uint32_t diag_count;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!amduat_read_u16(cur, &pel1_version)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pel1_version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_value->pel1_version = pel1_version;
|
||||||
|
if (!amduat_read_u8(cur, &out_value->status)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_encoded_ref(cur, &out_value->scheme_ref)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_u8(cur, &out_value->summary.kind) ||
|
||||||
|
!amduat_read_u32(cur, &out_value->summary.status_code)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_u32(cur, &diag_count)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_value->diagnostics_len = diag_count;
|
||||||
|
if (diag_count != 0) {
|
||||||
|
if (diag_count > SIZE_MAX / sizeof(amduat_pel_diagnostic_entry_t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_value->diagnostics = (amduat_pel_diagnostic_entry_t *)calloc(
|
||||||
|
diag_count, sizeof(amduat_pel_diagnostic_entry_t));
|
||||||
|
if (out_value->diagnostics == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < out_value->diagnostics_len; ++i) {
|
||||||
|
amduat_pel_diagnostic_entry_t *diag = &out_value->diagnostics[i];
|
||||||
|
uint32_t msg_len;
|
||||||
|
if (!amduat_read_u32(cur, &diag->code) ||
|
||||||
|
!amduat_read_u32(cur, &msg_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cur->len - cur->offset < msg_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (msg_len != 0) {
|
||||||
|
uint8_t *msg = (uint8_t *)malloc(msg_len);
|
||||||
|
if (msg == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(msg, cur->data + cur->offset, msg_len);
|
||||||
|
diag->message = amduat_octets(msg, msg_len);
|
||||||
|
}
|
||||||
|
cur->offset += msg_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void amduat_enc_pel1_result_free(amduat_pel_surface_execution_result_t *result) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (result == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_reference_free(&result->scheme_ref);
|
||||||
|
amduat_reference_free(&result->program_ref);
|
||||||
|
if (result->input_refs != NULL) {
|
||||||
|
for (i = 0; i < result->input_refs_len; ++i) {
|
||||||
|
amduat_reference_free(&result->input_refs[i]);
|
||||||
|
}
|
||||||
|
free(result->input_refs);
|
||||||
|
}
|
||||||
|
if (result->output_refs != NULL) {
|
||||||
|
for (i = 0; i < result->output_refs_len; ++i) {
|
||||||
|
amduat_reference_free(&result->output_refs[i]);
|
||||||
|
}
|
||||||
|
free(result->output_refs);
|
||||||
|
}
|
||||||
|
if (result->has_params_ref) {
|
||||||
|
amduat_reference_free(&result->params_ref);
|
||||||
|
}
|
||||||
|
if (result->has_store_failure) {
|
||||||
|
amduat_reference_free(&result->store_failure.failing_ref);
|
||||||
|
}
|
||||||
|
if (result->has_trace_ref) {
|
||||||
|
amduat_reference_free(&result->trace_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_reference_free(&result->core_result.scheme_ref);
|
||||||
|
amduat_diagnostic_list_free(result->core_result.diagnostics,
|
||||||
|
result->core_result.diagnostics_len);
|
||||||
|
result->core_result.diagnostics = NULL;
|
||||||
|
result->core_result.diagnostics_len = 0;
|
||||||
|
|
||||||
|
result->input_refs = NULL;
|
||||||
|
result->input_refs_len = 0;
|
||||||
|
result->output_refs = NULL;
|
||||||
|
result->output_refs_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduat_enc_pel1_result_encode_v1(
|
||||||
|
const amduat_pel_surface_execution_result_t *result,
|
||||||
|
amduat_octets_t *out_bytes) {
|
||||||
|
size_t total_len = 0;
|
||||||
|
size_t offset = 0;
|
||||||
|
uint8_t *buffer;
|
||||||
|
size_t i;
|
||||||
|
size_t exec_result_len = 0;
|
||||||
|
|
||||||
|
if (result == NULL || out_bytes == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_bytes->data = NULL;
|
||||||
|
out_bytes->len = 0;
|
||||||
|
|
||||||
|
if (result->pel1_version != 1 || result->core_result.pel1_version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_reference_eq(result->scheme_ref,
|
||||||
|
result->core_result.scheme_ref)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result->input_refs_len > UINT32_MAX ||
|
||||||
|
result->output_refs_len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_execution_result_value_size(&result->core_result,
|
||||||
|
&exec_result_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_add_size(&total_len, 2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(result->scheme_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_encoded_ref_len(result->program_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result->input_refs_len > 0 && result->input_refs == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < result->input_refs_len; ++i) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(result->input_refs[i], &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result->output_refs_len > 0 && result->output_refs == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < result->output_refs_len; ++i) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(result->output_refs[i], &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result->has_params_ref) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(result->params_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result->has_store_failure) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(result->store_failure.failing_ref, &enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1 + 1 + enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result->has_trace_ref) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(result->trace_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, exec_result_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = (uint8_t *)malloc(total_len);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u16_be(buffer + offset, result->pel1_version);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
result->scheme_ref) ||
|
||||||
|
!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
result->program_ref)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)result->input_refs_len);
|
||||||
|
offset += 4;
|
||||||
|
for (i = 0; i < result->input_refs_len; ++i) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
result->input_refs[i])) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)result->output_refs_len);
|
||||||
|
offset += 4;
|
||||||
|
for (i = 0; i < result->output_refs_len; ++i) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
result->output_refs[i])) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[offset++] = result->has_params_ref ? 0x01u : 0x00u;
|
||||||
|
if (result->has_params_ref) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
result->params_ref)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[offset++] = result->has_store_failure ? 0x01u : 0x00u;
|
||||||
|
if (result->has_store_failure) {
|
||||||
|
if (result->store_failure.phase != AMDUAT_PEL_STORE_FAILURE_PROGRAM &&
|
||||||
|
result->store_failure.phase != AMDUAT_PEL_STORE_FAILURE_INPUT) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result->store_failure.error_code != AMDUAT_PEL_STORE_ERROR_NOT_FOUND &&
|
||||||
|
result->store_failure.error_code != AMDUAT_PEL_STORE_ERROR_INTEGRITY &&
|
||||||
|
result->store_failure.error_code != AMDUAT_PEL_STORE_ERROR_UNSUPPORTED) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buffer[offset++] = result->store_failure.phase;
|
||||||
|
buffer[offset++] = result->store_failure.error_code;
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
result->store_failure.failing_ref)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[offset++] = result->has_trace_ref ? 0x01u : 0x00u;
|
||||||
|
if (result->has_trace_ref) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
result->trace_ref)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_write_execution_result_value(buffer,
|
||||||
|
total_len,
|
||||||
|
&offset,
|
||||||
|
&result->core_result)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_bytes->data = buffer;
|
||||||
|
out_bytes->len = total_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduat_enc_pel1_result_decode_v1(
|
||||||
|
amduat_octets_t bytes,
|
||||||
|
amduat_pel_surface_execution_result_t *out_result) {
|
||||||
|
amduat_cursor_t cur;
|
||||||
|
uint16_t pel1_version;
|
||||||
|
uint32_t input_count;
|
||||||
|
uint32_t output_count;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (out_result == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bytes.len != 0 && bytes.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(out_result, 0, sizeof(*out_result));
|
||||||
|
cur.data = bytes.data;
|
||||||
|
cur.len = bytes.len;
|
||||||
|
cur.offset = 0;
|
||||||
|
|
||||||
|
if (!amduat_read_u16(&cur, &pel1_version)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pel1_version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_result->pel1_version = pel1_version;
|
||||||
|
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_result->scheme_ref) ||
|
||||||
|
!amduat_read_encoded_ref(&cur, &out_result->program_ref)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &input_count)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_result->input_refs_len = input_count;
|
||||||
|
if (input_count != 0) {
|
||||||
|
if (input_count > SIZE_MAX / sizeof(amduat_reference_t)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_result->input_refs = (amduat_reference_t *)calloc(
|
||||||
|
input_count, sizeof(amduat_reference_t));
|
||||||
|
if (out_result->input_refs == NULL) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < out_result->input_refs_len; ++i) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_result->input_refs[i])) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &output_count)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_result->output_refs_len = output_count;
|
||||||
|
if (output_count != 0) {
|
||||||
|
if (output_count > SIZE_MAX / sizeof(amduat_reference_t)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_result->output_refs = (amduat_reference_t *)calloc(
|
||||||
|
output_count, sizeof(amduat_reference_t));
|
||||||
|
if (out_result->output_refs == NULL) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < out_result->output_refs_len; ++i) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_result->output_refs[i])) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t has_params_ref;
|
||||||
|
if (!amduat_read_u8(&cur, &has_params_ref)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_params_ref != 0x00u && has_params_ref != 0x01u) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_result->has_params_ref = (has_params_ref == 0x01u);
|
||||||
|
if (out_result->has_params_ref) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_result->params_ref)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t has_store_failure;
|
||||||
|
if (!amduat_read_u8(&cur, &has_store_failure)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_store_failure != 0x00u && has_store_failure != 0x01u) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_result->has_store_failure = (has_store_failure == 0x01u);
|
||||||
|
if (out_result->has_store_failure) {
|
||||||
|
if (!amduat_read_u8(&cur, &out_result->store_failure.phase) ||
|
||||||
|
!amduat_read_u8(&cur, &out_result->store_failure.error_code)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (out_result->store_failure.phase !=
|
||||||
|
AMDUAT_PEL_STORE_FAILURE_PROGRAM &&
|
||||||
|
out_result->store_failure.phase != AMDUAT_PEL_STORE_FAILURE_INPUT) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (out_result->store_failure.error_code !=
|
||||||
|
AMDUAT_PEL_STORE_ERROR_NOT_FOUND &&
|
||||||
|
out_result->store_failure.error_code !=
|
||||||
|
AMDUAT_PEL_STORE_ERROR_INTEGRITY &&
|
||||||
|
out_result->store_failure.error_code !=
|
||||||
|
AMDUAT_PEL_STORE_ERROR_UNSUPPORTED) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_encoded_ref(&cur,
|
||||||
|
&out_result->store_failure.failing_ref)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t has_trace_ref;
|
||||||
|
if (!amduat_read_u8(&cur, &has_trace_ref)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_trace_ref != 0x00u && has_trace_ref != 0x01u) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_result->has_trace_ref = (has_trace_ref == 0x01u);
|
||||||
|
if (out_result->has_trace_ref) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_result->trace_ref)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_execution_result_value(&cur, &out_result->core_result)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_reference_eq(out_result->scheme_ref,
|
||||||
|
out_result->core_result.scheme_ref)) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur.offset != cur.len) {
|
||||||
|
amduat_enc_pel1_result_free(out_result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,666 @@
|
||||||
|
#include "amduat/enc/pel_program_dag.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const uint8_t *data;
|
||||||
|
size_t len;
|
||||||
|
size_t offset;
|
||||||
|
} amduat_cursor_t;
|
||||||
|
|
||||||
|
static void amduat_store_u16_be(uint8_t *out, uint16_t value) {
|
||||||
|
out[0] = (uint8_t)((value >> 8) & 0xffu);
|
||||||
|
out[1] = (uint8_t)(value & 0xffu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_store_u32_be(uint8_t *out, uint32_t value) {
|
||||||
|
out[0] = (uint8_t)((value >> 24) & 0xffu);
|
||||||
|
out[1] = (uint8_t)((value >> 16) & 0xffu);
|
||||||
|
out[2] = (uint8_t)((value >> 8) & 0xffu);
|
||||||
|
out[3] = (uint8_t)(value & 0xffu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_u8(amduat_cursor_t *cur, uint8_t *out) {
|
||||||
|
if (cur->len - cur->offset < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = cur->data[cur->offset];
|
||||||
|
cur->offset += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_u16(amduat_cursor_t *cur, uint16_t *out) {
|
||||||
|
const uint8_t *data;
|
||||||
|
if (cur->len - cur->offset < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = cur->data + cur->offset;
|
||||||
|
*out = (uint16_t)((data[0] << 8) | data[1]);
|
||||||
|
cur->offset += 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_u32(amduat_cursor_t *cur, uint32_t *out) {
|
||||||
|
const uint8_t *data;
|
||||||
|
if (cur->len - cur->offset < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = cur->data + cur->offset;
|
||||||
|
*out = ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) |
|
||||||
|
((uint32_t)data[2] << 8) | (uint32_t)data[3];
|
||||||
|
cur->offset += 4;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_add_size(size_t *acc, size_t add) {
|
||||||
|
if (*acc > SIZE_MAX - add) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*acc += add;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_utf8_is_valid(amduat_octets_t value) {
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while (i < value.len) {
|
||||||
|
uint8_t c = value.data[i];
|
||||||
|
if (c <= 0x7f) {
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((c & 0xe0u) == 0xc0u) {
|
||||||
|
if (i + 1 >= value.len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((value.data[i + 1] & 0xc0u) != 0x80u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c < 0xc2u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((c & 0xf0u) == 0xe0u) {
|
||||||
|
if (i + 2 >= value.len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((value.data[i + 1] & 0xc0u) != 0x80u ||
|
||||||
|
(value.data[i + 2] & 0xc0u) != 0x80u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c == 0xe0u && value.data[i + 1] < 0xa0u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c == 0xedu && value.data[i + 1] >= 0xa0u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
i += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((c & 0xf8u) == 0xf0u) {
|
||||||
|
if (i + 3 >= value.len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((value.data[i + 1] & 0xc0u) != 0x80u ||
|
||||||
|
(value.data[i + 2] & 0xc0u) != 0x80u ||
|
||||||
|
(value.data[i + 3] & 0xc0u) != 0x80u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c == 0xf0u && value.data[i + 1] < 0x90u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c == 0xf4u && value.data[i + 1] >= 0x90u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c > 0xf4u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
i += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amduat_find_node_index(const amduat_pel_program_t *program,
|
||||||
|
amduat_pel_node_id_t node_id) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < program->nodes_len; ++i) {
|
||||||
|
if (program->nodes[i].id == node_id) {
|
||||||
|
return (int)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_build_node_order(const amduat_pel_program_t *program,
|
||||||
|
size_t *out_order) {
|
||||||
|
size_t n;
|
||||||
|
size_t *deps;
|
||||||
|
bool *placed;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
n = program->nodes_len;
|
||||||
|
deps = NULL;
|
||||||
|
placed = NULL;
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
deps = (size_t *)calloc(n, sizeof(*deps));
|
||||||
|
placed = (bool *)calloc(n, sizeof(*placed));
|
||||||
|
if (deps == NULL || placed == NULL) {
|
||||||
|
free(deps);
|
||||||
|
free(placed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
size_t j;
|
||||||
|
for (j = i + 1; j < n; ++j) {
|
||||||
|
if (program->nodes[i].id == program->nodes[j].id) {
|
||||||
|
free(deps);
|
||||||
|
free(placed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
size_t j;
|
||||||
|
const amduat_pel_node_t *node;
|
||||||
|
|
||||||
|
node = &program->nodes[i];
|
||||||
|
for (j = 0; j < node->inputs_len; ++j) {
|
||||||
|
const amduat_pel_dag_input_t *input = &node->inputs[j];
|
||||||
|
if (input->kind == AMDUAT_PEL_DAG_INPUT_NODE) {
|
||||||
|
if (amduat_find_node_index(program, input->value.node.node_id) < 0) {
|
||||||
|
free(deps);
|
||||||
|
free(placed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
deps[i] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
size_t best = SIZE_MAX;
|
||||||
|
size_t j;
|
||||||
|
amduat_pel_node_id_t best_id = 0;
|
||||||
|
|
||||||
|
for (j = 0; j < n; ++j) {
|
||||||
|
if (placed[j] || deps[j] != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (best == SIZE_MAX || program->nodes[j].id < best_id) {
|
||||||
|
best = j;
|
||||||
|
best_id = program->nodes[j].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best == SIZE_MAX) {
|
||||||
|
free(deps);
|
||||||
|
free(placed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_order[i] = best;
|
||||||
|
placed[best] = true;
|
||||||
|
|
||||||
|
for (j = 0; j < n; ++j) {
|
||||||
|
size_t k;
|
||||||
|
const amduat_pel_node_t *node;
|
||||||
|
|
||||||
|
if (placed[j]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
node = &program->nodes[j];
|
||||||
|
for (k = 0; k < node->inputs_len; ++k) {
|
||||||
|
const amduat_pel_dag_input_t *input = &node->inputs[k];
|
||||||
|
if (input->kind == AMDUAT_PEL_DAG_INPUT_NODE &&
|
||||||
|
input->value.node.node_id == program->nodes[best].id) {
|
||||||
|
if (deps[j] == 0) {
|
||||||
|
free(deps);
|
||||||
|
free(placed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
deps[j] -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(deps);
|
||||||
|
free(placed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void amduat_enc_pel_program_dag_free(amduat_pel_program_t *program) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (program == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < program->nodes_len; ++i) {
|
||||||
|
amduat_pel_node_t *node = &program->nodes[i];
|
||||||
|
free((void *)node->op.name.data);
|
||||||
|
free(node->inputs);
|
||||||
|
free((void *)node->params.data);
|
||||||
|
node->op.name.data = NULL;
|
||||||
|
node->op.name.len = 0;
|
||||||
|
node->inputs = NULL;
|
||||||
|
node->inputs_len = 0;
|
||||||
|
node->params.data = NULL;
|
||||||
|
node->params.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(program->nodes);
|
||||||
|
free(program->roots);
|
||||||
|
program->nodes = NULL;
|
||||||
|
program->nodes_len = 0;
|
||||||
|
program->roots = NULL;
|
||||||
|
program->roots_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduat_enc_pel_program_dag_encode_v1(
|
||||||
|
const amduat_pel_program_t *program,
|
||||||
|
amduat_octets_t *out_bytes) {
|
||||||
|
size_t total_len = 0;
|
||||||
|
size_t offset = 0;
|
||||||
|
uint8_t *buffer;
|
||||||
|
size_t *order;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (out_bytes == NULL || program == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_bytes->data = NULL;
|
||||||
|
out_bytes->len = 0;
|
||||||
|
|
||||||
|
if (program->nodes_len > 0 && program->nodes == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (program->roots_len > 0 && program->roots == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
order = NULL;
|
||||||
|
if (program->nodes_len > 0) {
|
||||||
|
order = (size_t *)malloc(program->nodes_len * sizeof(*order));
|
||||||
|
if (order == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_build_node_order(program, order)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_add_size(&total_len, 2)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (program->nodes_len > UINT32_MAX || program->roots_len > UINT32_MAX) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < program->nodes_len; ++i) {
|
||||||
|
const amduat_pel_node_t *node = &program->nodes[order ? order[i] : i];
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
if (node->op.name.len > UINT32_MAX) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->op.name.len > 0 && node->op.name.data == NULL) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_utf8_is_valid(node->op.name)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->inputs_len > 0 && node->inputs == NULL) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->inputs_len > UINT32_MAX) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->params.len > UINT32_MAX) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->params.len > 0 && node->params.data == NULL) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4 + node->op.name.len)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < node->inputs_len; ++j) {
|
||||||
|
const amduat_pel_dag_input_t *input = &node->inputs[j];
|
||||||
|
if (!amduat_add_size(&total_len, 1)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (input->kind == AMDUAT_PEL_DAG_INPUT_EXTERNAL) {
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (input->kind == AMDUAT_PEL_DAG_INPUT_NODE) {
|
||||||
|
if (!amduat_add_size(&total_len, 8)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_add_size(&total_len, 4 + node->params.len)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, program->roots_len * 8)) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = (uint8_t *)malloc(total_len);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
free(order);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u16_be(buffer + offset, 1);
|
||||||
|
offset += 2;
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)program->nodes_len);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
for (i = 0; i < program->nodes_len; ++i) {
|
||||||
|
const amduat_pel_node_t *node = &program->nodes[order ? order[i] : i];
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, node->id);
|
||||||
|
offset += 4;
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)node->op.name.len);
|
||||||
|
offset += 4;
|
||||||
|
if (node->op.name.len != 0) {
|
||||||
|
memcpy(buffer + offset, node->op.name.data, node->op.name.len);
|
||||||
|
offset += node->op.name.len;
|
||||||
|
}
|
||||||
|
amduat_store_u32_be(buffer + offset, node->op.version);
|
||||||
|
offset += 4;
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)node->inputs_len);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
for (j = 0; j < node->inputs_len; ++j) {
|
||||||
|
const amduat_pel_dag_input_t *input = &node->inputs[j];
|
||||||
|
buffer[offset++] = (uint8_t)input->kind;
|
||||||
|
if (input->kind == AMDUAT_PEL_DAG_INPUT_EXTERNAL) {
|
||||||
|
amduat_store_u32_be(buffer + offset, input->value.external.input_index);
|
||||||
|
offset += 4;
|
||||||
|
} else {
|
||||||
|
amduat_store_u32_be(buffer + offset, input->value.node.node_id);
|
||||||
|
offset += 4;
|
||||||
|
amduat_store_u32_be(buffer + offset, input->value.node.output_index);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)node->params.len);
|
||||||
|
offset += 4;
|
||||||
|
if (node->params.len != 0) {
|
||||||
|
memcpy(buffer + offset, node->params.data, node->params.len);
|
||||||
|
offset += node->params.len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)program->roots_len);
|
||||||
|
offset += 4;
|
||||||
|
for (i = 0; i < program->roots_len; ++i) {
|
||||||
|
amduat_store_u32_be(buffer + offset, program->roots[i].node_id);
|
||||||
|
offset += 4;
|
||||||
|
amduat_store_u32_be(buffer + offset, program->roots[i].output_index);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(order);
|
||||||
|
out_bytes->data = buffer;
|
||||||
|
out_bytes->len = total_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduat_enc_pel_program_dag_decode_v1(
|
||||||
|
amduat_octets_t bytes,
|
||||||
|
amduat_pel_program_t *out_program) {
|
||||||
|
amduat_cursor_t cur;
|
||||||
|
uint16_t version;
|
||||||
|
uint32_t node_count;
|
||||||
|
uint32_t root_count;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (out_program == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes.len != 0 && bytes.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(out_program, 0, sizeof(*out_program));
|
||||||
|
|
||||||
|
cur.data = bytes.data;
|
||||||
|
cur.len = bytes.len;
|
||||||
|
cur.offset = 0;
|
||||||
|
|
||||||
|
if (!amduat_read_u16(&cur, &version)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_u32(&cur, &node_count)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node_count != 0) {
|
||||||
|
if (node_count > SIZE_MAX / sizeof(amduat_pel_node_t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_program->nodes = (amduat_pel_node_t *)calloc(
|
||||||
|
node_count, sizeof(amduat_pel_node_t));
|
||||||
|
if (out_program->nodes == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out_program->nodes_len = node_count;
|
||||||
|
|
||||||
|
for (i = 0; i < out_program->nodes_len; ++i) {
|
||||||
|
amduat_pel_node_t *node = &out_program->nodes[i];
|
||||||
|
uint32_t name_len;
|
||||||
|
uint32_t input_count;
|
||||||
|
uint32_t params_len;
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &node->id)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_u32(&cur, &name_len)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cur.len - cur.offset < name_len) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (name_len != 0) {
|
||||||
|
uint8_t *name = (uint8_t *)malloc(name_len);
|
||||||
|
if (name == NULL) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(name, cur.data + cur.offset, name_len);
|
||||||
|
node->op.name = amduat_octets(name, name_len);
|
||||||
|
if (!amduat_utf8_is_valid(node->op.name)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cur.offset += name_len;
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &node->op.version)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_u32(&cur, &input_count)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (input_count > SIZE_MAX / sizeof(amduat_pel_dag_input_t)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
node->inputs_len = input_count;
|
||||||
|
if (input_count != 0) {
|
||||||
|
node->inputs = (amduat_pel_dag_input_t *)calloc(
|
||||||
|
input_count, sizeof(amduat_pel_dag_input_t));
|
||||||
|
if (node->inputs == NULL) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < node->inputs_len; ++j) {
|
||||||
|
uint8_t kind;
|
||||||
|
amduat_pel_dag_input_t *input = &node->inputs[j];
|
||||||
|
if (!amduat_read_u8(&cur, &kind)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (kind == AMDUAT_PEL_DAG_INPUT_EXTERNAL) {
|
||||||
|
uint32_t input_index;
|
||||||
|
if (!amduat_read_u32(&cur, &input_index)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
input->kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
input->value.external.input_index = input_index;
|
||||||
|
} else if (kind == AMDUAT_PEL_DAG_INPUT_NODE) {
|
||||||
|
uint32_t node_id;
|
||||||
|
uint32_t output_index;
|
||||||
|
if (!amduat_read_u32(&cur, &node_id) ||
|
||||||
|
!amduat_read_u32(&cur, &output_index)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
input->kind = AMDUAT_PEL_DAG_INPUT_NODE;
|
||||||
|
input->value.node.node_id = node_id;
|
||||||
|
input->value.node.output_index = output_index;
|
||||||
|
} else {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, ¶ms_len)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cur.len - cur.offset < params_len) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (params_len != 0) {
|
||||||
|
uint8_t *params = (uint8_t *)malloc(params_len);
|
||||||
|
if (params == NULL) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(params, cur.data + cur.offset, params_len);
|
||||||
|
node->params = amduat_octets(params, params_len);
|
||||||
|
}
|
||||||
|
cur.offset += params_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &root_count)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_program->roots_len = root_count;
|
||||||
|
if (root_count != 0) {
|
||||||
|
if (root_count > SIZE_MAX / sizeof(amduat_pel_root_ref_t)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_program->roots =
|
||||||
|
(amduat_pel_root_ref_t *)calloc(root_count,
|
||||||
|
sizeof(amduat_pel_root_ref_t));
|
||||||
|
if (out_program->roots == NULL) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < out_program->roots_len; ++i) {
|
||||||
|
uint32_t node_id;
|
||||||
|
uint32_t output_index;
|
||||||
|
if (!amduat_read_u32(&cur, &node_id) ||
|
||||||
|
!amduat_read_u32(&cur, &output_index)) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_program->roots[i].node_id = node_id;
|
||||||
|
out_program->roots[i].output_index = output_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur.offset != cur.len) {
|
||||||
|
amduat_enc_pel_program_dag_free(out_program);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,775 @@
|
||||||
|
#include "amduat/enc/pel_trace_dag.h"
|
||||||
|
|
||||||
|
#include "amduat/enc/asl1_core_codec.h"
|
||||||
|
#include "amduat/hash/asl1.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const uint8_t *data;
|
||||||
|
size_t len;
|
||||||
|
size_t offset;
|
||||||
|
} amduat_cursor_t;
|
||||||
|
|
||||||
|
static void amduat_store_u16_be(uint8_t *out, uint16_t value) {
|
||||||
|
out[0] = (uint8_t)((value >> 8) & 0xffu);
|
||||||
|
out[1] = (uint8_t)(value & 0xffu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_store_u32_be(uint8_t *out, uint32_t value) {
|
||||||
|
out[0] = (uint8_t)((value >> 24) & 0xffu);
|
||||||
|
out[1] = (uint8_t)((value >> 16) & 0xffu);
|
||||||
|
out[2] = (uint8_t)((value >> 8) & 0xffu);
|
||||||
|
out[3] = (uint8_t)(value & 0xffu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_u8(amduat_cursor_t *cur, uint8_t *out) {
|
||||||
|
if (cur->len - cur->offset < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = cur->data[cur->offset];
|
||||||
|
cur->offset += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_u16(amduat_cursor_t *cur, uint16_t *out) {
|
||||||
|
const uint8_t *data;
|
||||||
|
if (cur->len - cur->offset < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = cur->data + cur->offset;
|
||||||
|
*out = (uint16_t)((data[0] << 8) | data[1]);
|
||||||
|
cur->offset += 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_u32(amduat_cursor_t *cur, uint32_t *out) {
|
||||||
|
const uint8_t *data;
|
||||||
|
if (cur->len - cur->offset < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = cur->data + cur->offset;
|
||||||
|
*out = ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) |
|
||||||
|
((uint32_t)data[2] << 8) | (uint32_t)data[3];
|
||||||
|
cur->offset += 4;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_add_size(size_t *acc, size_t add) {
|
||||||
|
if (*acc > SIZE_MAX - add) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*acc += add;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_utf8_is_valid(amduat_octets_t value) {
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while (i < value.len) {
|
||||||
|
uint8_t c = value.data[i];
|
||||||
|
if (c <= 0x7f) {
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((c & 0xe0u) == 0xc0u) {
|
||||||
|
if (i + 1 >= value.len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((value.data[i + 1] & 0xc0u) != 0x80u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c < 0xc2u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((c & 0xf0u) == 0xe0u) {
|
||||||
|
if (i + 2 >= value.len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((value.data[i + 1] & 0xc0u) != 0x80u ||
|
||||||
|
(value.data[i + 2] & 0xc0u) != 0x80u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c == 0xe0u && value.data[i + 1] < 0xa0u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c == 0xedu && value.data[i + 1] >= 0xa0u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
i += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((c & 0xf8u) == 0xf0u) {
|
||||||
|
if (i + 3 >= value.len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((value.data[i + 1] & 0xc0u) != 0x80u ||
|
||||||
|
(value.data[i + 2] & 0xc0u) != 0x80u ||
|
||||||
|
(value.data[i + 3] & 0xc0u) != 0x80u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c == 0xf0u && value.data[i + 1] < 0x90u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c == 0xf4u && value.data[i + 1] >= 0x90u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c > 0xf4u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
i += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_reference_bytes_len(amduat_reference_t ref, size_t *out_len) {
|
||||||
|
const amduat_hash_asl1_desc_t *desc;
|
||||||
|
|
||||||
|
if (ref.digest.len != 0 && ref.digest.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc = amduat_hash_asl1_desc_lookup(ref.hash_id);
|
||||||
|
if (desc == NULL || desc->digest_len == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ref.digest.len != desc->digest_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_len = 2 + desc->digest_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_encoded_ref_len(amduat_reference_t ref, size_t *out_len) {
|
||||||
|
size_t ref_len;
|
||||||
|
|
||||||
|
if (!amduat_reference_bytes_len(ref, &ref_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ref_len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out_len = 4 + ref_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_write_encoded_ref(uint8_t *buffer,
|
||||||
|
size_t buffer_len,
|
||||||
|
size_t *offset,
|
||||||
|
amduat_reference_t ref) {
|
||||||
|
size_t ref_len;
|
||||||
|
|
||||||
|
if (!amduat_reference_bytes_len(ref, &ref_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ref_len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (buffer_len - *offset < 4 + ref_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + *offset, (uint32_t)ref_len);
|
||||||
|
*offset += 4;
|
||||||
|
amduat_store_u16_be(buffer + *offset, ref.hash_id);
|
||||||
|
*offset += 2;
|
||||||
|
if (ref.digest.len != 0) {
|
||||||
|
memcpy(buffer + *offset, ref.digest.data, ref.digest.len);
|
||||||
|
*offset += ref.digest.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_read_encoded_ref(amduat_cursor_t *cur,
|
||||||
|
amduat_reference_t *out_ref) {
|
||||||
|
uint32_t ref_len_u32;
|
||||||
|
amduat_octets_t ref_bytes;
|
||||||
|
|
||||||
|
if (!amduat_read_u32(cur, &ref_len_u32)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ref_len_u32 < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cur->len - cur->offset < ref_len_u32) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ref_bytes = amduat_octets(cur->data + cur->offset, ref_len_u32);
|
||||||
|
if (!amduat_enc_asl1_core_decode_reference_v1(ref_bytes, out_ref)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cur->offset += ref_len_u32;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_reference_free(amduat_reference_t *ref) {
|
||||||
|
if (ref == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free((void *)ref->digest.data);
|
||||||
|
ref->digest.data = NULL;
|
||||||
|
ref->digest.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_diagnostic_list_free(amduat_pel_diagnostic_entry_t *entries,
|
||||||
|
size_t count) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (entries == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
free((void *)entries[i].message.data);
|
||||||
|
entries[i].message.data = NULL;
|
||||||
|
entries[i].message.len = 0;
|
||||||
|
}
|
||||||
|
free(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
void amduat_enc_pel_trace_dag_free(amduat_pel_trace_dag_value_t *trace) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (trace == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_reference_free(&trace->scheme_ref);
|
||||||
|
amduat_reference_free(&trace->program_ref);
|
||||||
|
if (trace->has_exec_result_ref) {
|
||||||
|
amduat_reference_free(&trace->exec_result_ref);
|
||||||
|
}
|
||||||
|
if (trace->input_refs != NULL) {
|
||||||
|
for (i = 0; i < trace->input_refs_len; ++i) {
|
||||||
|
amduat_reference_free(&trace->input_refs[i]);
|
||||||
|
}
|
||||||
|
free(trace->input_refs);
|
||||||
|
}
|
||||||
|
if (trace->has_params_ref) {
|
||||||
|
amduat_reference_free(&trace->params_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trace->node_traces != NULL) {
|
||||||
|
for (i = 0; i < trace->node_traces_len; ++i) {
|
||||||
|
amduat_pel_node_trace_dag_t *node = &trace->node_traces[i];
|
||||||
|
free((void *)node->op_name.data);
|
||||||
|
if (node->output_refs != NULL) {
|
||||||
|
size_t j;
|
||||||
|
for (j = 0; j < node->output_refs_len; ++j) {
|
||||||
|
amduat_reference_free(&node->output_refs[j]);
|
||||||
|
}
|
||||||
|
free(node->output_refs);
|
||||||
|
}
|
||||||
|
amduat_diagnostic_list_free(node->diagnostics, node->diagnostics_len);
|
||||||
|
node->op_name.data = NULL;
|
||||||
|
node->op_name.len = 0;
|
||||||
|
node->output_refs = NULL;
|
||||||
|
node->output_refs_len = 0;
|
||||||
|
node->diagnostics = NULL;
|
||||||
|
node->diagnostics_len = 0;
|
||||||
|
}
|
||||||
|
free(trace->node_traces);
|
||||||
|
}
|
||||||
|
|
||||||
|
trace->input_refs = NULL;
|
||||||
|
trace->input_refs_len = 0;
|
||||||
|
trace->node_traces = NULL;
|
||||||
|
trace->node_traces_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduat_enc_pel_trace_dag_encode_v1(
|
||||||
|
const amduat_pel_trace_dag_value_t *trace,
|
||||||
|
amduat_octets_t *out_bytes) {
|
||||||
|
size_t total_len = 0;
|
||||||
|
size_t offset = 0;
|
||||||
|
uint8_t *buffer;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (trace == NULL || out_bytes == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_bytes->data = NULL;
|
||||||
|
out_bytes->len = 0;
|
||||||
|
|
||||||
|
if (trace->pel1_version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (trace->input_refs_len > UINT32_MAX ||
|
||||||
|
trace->node_traces_len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(trace->scheme_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_encoded_ref_len(trace->program_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1 + 1 + 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (trace->has_exec_result_ref) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(trace->exec_result_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (trace->input_refs_len > 0 && trace->input_refs == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < trace->input_refs_len; ++i) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(trace->input_refs[i], &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (trace->has_params_ref) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(trace->params_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (trace->node_traces_len > 0 && trace->node_traces == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < trace->node_traces_len; ++i) {
|
||||||
|
const amduat_pel_node_trace_dag_t *node = &trace->node_traces[i];
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
if (node->output_refs_len > UINT32_MAX ||
|
||||||
|
node->diagnostics_len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->op_name.len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->op_name.len != 0 && node->op_name.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_utf8_is_valid(node->op_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->status != AMDUAT_PEL_NODE_TRACE_OK &&
|
||||||
|
node->status != AMDUAT_PEL_NODE_TRACE_FAILED &&
|
||||||
|
node->status != AMDUAT_PEL_NODE_TRACE_SKIPPED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4 + 4 + node->op_name.len + 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1 + 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->output_refs_len > 0 && node->output_refs == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (j = 0; j < node->output_refs_len; ++j) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(node->output_refs[j], &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->diagnostics_len > 0 && node->diagnostics == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (j = 0; j < node->diagnostics_len; ++j) {
|
||||||
|
const amduat_pel_diagnostic_entry_t *diag = &node->diagnostics[j];
|
||||||
|
if (diag->message.len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (diag->message.len != 0 && diag->message.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 4 + 4 + diag->message.len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = (uint8_t *)malloc(total_len);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u16_be(buffer + offset, trace->pel1_version);
|
||||||
|
offset += 2;
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
trace->scheme_ref) ||
|
||||||
|
!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
trace->program_ref)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[offset++] = trace->status;
|
||||||
|
buffer[offset++] = trace->summary.kind;
|
||||||
|
amduat_store_u32_be(buffer + offset, trace->summary.status_code);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
buffer[offset++] = trace->has_exec_result_ref ? 0x01u : 0x00u;
|
||||||
|
if (trace->has_exec_result_ref) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
trace->exec_result_ref)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)trace->input_refs_len);
|
||||||
|
offset += 4;
|
||||||
|
for (i = 0; i < trace->input_refs_len; ++i) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
trace->input_refs[i])) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[offset++] = trace->has_params_ref ? 0x01u : 0x00u;
|
||||||
|
if (trace->has_params_ref) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
trace->params_ref)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)trace->node_traces_len);
|
||||||
|
offset += 4;
|
||||||
|
for (i = 0; i < trace->node_traces_len; ++i) {
|
||||||
|
const amduat_pel_node_trace_dag_t *node = &trace->node_traces[i];
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, node->node_id);
|
||||||
|
offset += 4;
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)node->op_name.len);
|
||||||
|
offset += 4;
|
||||||
|
if (node->op_name.len != 0) {
|
||||||
|
memcpy(buffer + offset, node->op_name.data, node->op_name.len);
|
||||||
|
offset += node->op_name.len;
|
||||||
|
}
|
||||||
|
amduat_store_u32_be(buffer + offset, node->op_version);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
buffer[offset++] = node->status;
|
||||||
|
amduat_store_u32_be(buffer + offset, node->status_code);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)node->output_refs_len);
|
||||||
|
offset += 4;
|
||||||
|
for (j = 0; j < node->output_refs_len; ++j) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
node->output_refs[j])) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)node->diagnostics_len);
|
||||||
|
offset += 4;
|
||||||
|
for (j = 0; j < node->diagnostics_len; ++j) {
|
||||||
|
const amduat_pel_diagnostic_entry_t *diag = &node->diagnostics[j];
|
||||||
|
amduat_store_u32_be(buffer + offset, diag->code);
|
||||||
|
offset += 4;
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)diag->message.len);
|
||||||
|
offset += 4;
|
||||||
|
if (diag->message.len != 0) {
|
||||||
|
memcpy(buffer + offset, diag->message.data, diag->message.len);
|
||||||
|
offset += diag->message.len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out_bytes->data = buffer;
|
||||||
|
out_bytes->len = total_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduat_enc_pel_trace_dag_decode_v1(
|
||||||
|
amduat_octets_t bytes,
|
||||||
|
amduat_pel_trace_dag_value_t *out_trace) {
|
||||||
|
amduat_cursor_t cur;
|
||||||
|
uint16_t pel1_version;
|
||||||
|
uint32_t input_count;
|
||||||
|
uint32_t node_trace_count;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (out_trace == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes.len != 0 && bytes.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(out_trace, 0, sizeof(*out_trace));
|
||||||
|
cur.data = bytes.data;
|
||||||
|
cur.len = bytes.len;
|
||||||
|
cur.offset = 0;
|
||||||
|
|
||||||
|
if (!amduat_read_u16(&cur, &pel1_version)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pel1_version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_trace->pel1_version = pel1_version;
|
||||||
|
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_trace->scheme_ref) ||
|
||||||
|
!amduat_read_encoded_ref(&cur, &out_trace->program_ref)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u8(&cur, &out_trace->status) ||
|
||||||
|
!amduat_read_u8(&cur, &out_trace->summary.kind) ||
|
||||||
|
!amduat_read_u32(&cur, &out_trace->summary.status_code)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t has_exec_result;
|
||||||
|
if (!amduat_read_u8(&cur, &has_exec_result)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_exec_result != 0x00u && has_exec_result != 0x01u) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_trace->has_exec_result_ref = (has_exec_result == 0x01u);
|
||||||
|
if (out_trace->has_exec_result_ref) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_trace->exec_result_ref)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &input_count)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_trace->input_refs_len = input_count;
|
||||||
|
if (input_count != 0) {
|
||||||
|
if (input_count > SIZE_MAX / sizeof(amduat_reference_t)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_trace->input_refs =
|
||||||
|
(amduat_reference_t *)calloc(input_count, sizeof(amduat_reference_t));
|
||||||
|
if (out_trace->input_refs == NULL) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < out_trace->input_refs_len; ++i) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_trace->input_refs[i])) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t has_params_ref;
|
||||||
|
if (!amduat_read_u8(&cur, &has_params_ref)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_params_ref != 0x00u && has_params_ref != 0x01u) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_trace->has_params_ref = (has_params_ref == 0x01u);
|
||||||
|
if (out_trace->has_params_ref) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_trace->params_ref)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &node_trace_count)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_trace->node_traces_len = node_trace_count;
|
||||||
|
if (node_trace_count != 0) {
|
||||||
|
if (node_trace_count > SIZE_MAX / sizeof(amduat_pel_node_trace_dag_t)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_trace->node_traces = (amduat_pel_node_trace_dag_t *)calloc(
|
||||||
|
node_trace_count, sizeof(amduat_pel_node_trace_dag_t));
|
||||||
|
if (out_trace->node_traces == NULL) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < out_trace->node_traces_len; ++i) {
|
||||||
|
amduat_pel_node_trace_dag_t *node = &out_trace->node_traces[i];
|
||||||
|
uint32_t name_len;
|
||||||
|
uint32_t output_ref_count;
|
||||||
|
uint32_t diag_count;
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &node->node_id)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_u32(&cur, &name_len)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cur.len - cur.offset < name_len) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (name_len != 0) {
|
||||||
|
uint8_t *name = (uint8_t *)malloc(name_len);
|
||||||
|
if (name == NULL) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(name, cur.data + cur.offset, name_len);
|
||||||
|
node->op_name = amduat_octets(name, name_len);
|
||||||
|
if (!amduat_utf8_is_valid(node->op_name)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cur.offset += name_len;
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &node->op_version)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_u8(&cur, &node->status) ||
|
||||||
|
!amduat_read_u32(&cur, &node->status_code)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (node->status != AMDUAT_PEL_NODE_TRACE_OK &&
|
||||||
|
node->status != AMDUAT_PEL_NODE_TRACE_FAILED &&
|
||||||
|
node->status != AMDUAT_PEL_NODE_TRACE_SKIPPED) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &output_ref_count)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
node->output_refs_len = output_ref_count;
|
||||||
|
if (output_ref_count != 0) {
|
||||||
|
if (output_ref_count > SIZE_MAX / sizeof(amduat_reference_t)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
node->output_refs = (amduat_reference_t *)calloc(
|
||||||
|
output_ref_count, sizeof(amduat_reference_t));
|
||||||
|
if (node->output_refs == NULL) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (j = 0; j < node->output_refs_len; ++j) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &node->output_refs[j])) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &diag_count)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
node->diagnostics_len = diag_count;
|
||||||
|
if (diag_count != 0) {
|
||||||
|
if (diag_count > SIZE_MAX / sizeof(amduat_pel_diagnostic_entry_t)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
node->diagnostics = (amduat_pel_diagnostic_entry_t *)calloc(
|
||||||
|
diag_count, sizeof(amduat_pel_diagnostic_entry_t));
|
||||||
|
if (node->diagnostics == NULL) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (j = 0; j < node->diagnostics_len; ++j) {
|
||||||
|
amduat_pel_diagnostic_entry_t *diag = &node->diagnostics[j];
|
||||||
|
uint32_t msg_len;
|
||||||
|
if (!amduat_read_u32(&cur, &diag->code) ||
|
||||||
|
!amduat_read_u32(&cur, &msg_len)) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cur.len - cur.offset < msg_len) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (msg_len != 0) {
|
||||||
|
uint8_t *msg = (uint8_t *)malloc(msg_len);
|
||||||
|
if (msg == NULL) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(msg, cur.data + cur.offset, msg_len);
|
||||||
|
diag->message = amduat_octets(msg, msg_len);
|
||||||
|
}
|
||||||
|
cur.offset += msg_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur.offset != cur.len) {
|
||||||
|
amduat_enc_pel_trace_dag_free(out_trace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
126
tests/enc/test_pel1_result.c
Normal file
126
tests/enc/test_pel1_result.c
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
#include "amduat/enc/pel1_result.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static const uint8_t k_expected_result_bytes[] = {
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||||
|
0x00, 0x22, 0x00, 0x01, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||||
|
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||||
|
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||||
|
0x11, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0x22, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||||
|
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||||
|
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||||
|
0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void fill_digest(uint8_t *out, uint8_t value) {
|
||||||
|
memset(out, value, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static amduat_reference_t make_ref(uint8_t value, uint8_t *storage) {
|
||||||
|
fill_digest(storage, value);
|
||||||
|
return amduat_reference(0x0001, amduat_octets(storage, 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool bytes_equal(amduat_octets_t bytes,
|
||||||
|
const uint8_t *expected,
|
||||||
|
size_t expected_len) {
|
||||||
|
if (bytes.len != expected_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bytes.len == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return memcmp(bytes.data, expected, expected_len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_result_encoding(void) {
|
||||||
|
amduat_pel_surface_execution_result_t result;
|
||||||
|
amduat_reference_t input_refs[2];
|
||||||
|
amduat_reference_t output_refs[1];
|
||||||
|
amduat_octets_t encoded;
|
||||||
|
amduat_pel_surface_execution_result_t decoded;
|
||||||
|
uint8_t s[32], p[32], i0[32], i1[32], o0[32], t[32];
|
||||||
|
int exit_code = 1;
|
||||||
|
|
||||||
|
memset(&result, 0, sizeof(result));
|
||||||
|
result.pel1_version = 1;
|
||||||
|
result.scheme_ref = make_ref(0x01, s);
|
||||||
|
result.program_ref = make_ref(0x02, p);
|
||||||
|
|
||||||
|
input_refs[0] = make_ref(0x10, i0);
|
||||||
|
input_refs[1] = make_ref(0x11, i1);
|
||||||
|
result.input_refs = input_refs;
|
||||||
|
result.input_refs_len = 2;
|
||||||
|
|
||||||
|
output_refs[0] = make_ref(0x20, o0);
|
||||||
|
result.output_refs = output_refs;
|
||||||
|
result.output_refs_len = 1;
|
||||||
|
|
||||||
|
result.has_params_ref = false;
|
||||||
|
result.has_store_failure = false;
|
||||||
|
result.has_trace_ref = true;
|
||||||
|
result.trace_ref = make_ref(0x30, t);
|
||||||
|
|
||||||
|
result.core_result.pel1_version = 1;
|
||||||
|
result.core_result.status = AMDUAT_PEL_EXEC_STATUS_OK;
|
||||||
|
result.core_result.scheme_ref = result.scheme_ref;
|
||||||
|
result.core_result.summary.kind = AMDUAT_PEL_EXEC_ERROR_NONE;
|
||||||
|
result.core_result.summary.status_code = 0;
|
||||||
|
result.core_result.diagnostics = NULL;
|
||||||
|
result.core_result.diagnostics_len = 0;
|
||||||
|
|
||||||
|
if (!amduat_enc_pel1_result_encode_v1(&result, &encoded)) {
|
||||||
|
fprintf(stderr, "encode failed\n");
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bytes_equal(encoded, k_expected_result_bytes,
|
||||||
|
sizeof(k_expected_result_bytes))) {
|
||||||
|
fprintf(stderr, "encoded bytes mismatch\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_enc_pel1_result_decode_v1(encoded, &decoded)) {
|
||||||
|
fprintf(stderr, "decode failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoded.input_refs_len != 2 || decoded.output_refs_len != 1) {
|
||||||
|
fprintf(stderr, "decoded lengths mismatch\n");
|
||||||
|
goto cleanup_decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_code = 0;
|
||||||
|
|
||||||
|
cleanup_decoded:
|
||||||
|
amduat_enc_pel1_result_free(&decoded);
|
||||||
|
cleanup:
|
||||||
|
free((void *)encoded.data);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
return test_result_encoding();
|
||||||
|
}
|
||||||
113
tests/enc/test_pel_program_dag.c
Normal file
113
tests/enc/test_pel_program_dag.c
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include "amduat/enc/pel_program_dag.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static const uint8_t k_expected_program_bytes[] = {
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x05, 0x61, 0x64, 0x64, 0x36, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x05, 0x6d, 0x75, 0x6c, 0x36, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool bytes_equal(amduat_octets_t bytes,
|
||||||
|
const uint8_t *expected,
|
||||||
|
size_t expected_len) {
|
||||||
|
if (bytes.len != expected_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bytes.len == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return memcmp(bytes.data, expected, expected_len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_program_encoding(void) {
|
||||||
|
amduat_pel_dag_input_t node1_inputs[2];
|
||||||
|
amduat_pel_dag_input_t node2_inputs[2];
|
||||||
|
amduat_pel_node_t nodes[2];
|
||||||
|
amduat_pel_root_ref_t roots[1];
|
||||||
|
amduat_pel_program_t program;
|
||||||
|
amduat_octets_t encoded;
|
||||||
|
amduat_pel_program_t decoded;
|
||||||
|
const char add_name[] = "add64";
|
||||||
|
const char mul_name[] = "mul64";
|
||||||
|
int exit_code = 1;
|
||||||
|
|
||||||
|
node1_inputs[0].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
node1_inputs[0].value.external.input_index = 0;
|
||||||
|
node1_inputs[1].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
node1_inputs[1].value.external.input_index = 1;
|
||||||
|
|
||||||
|
node2_inputs[0].kind = AMDUAT_PEL_DAG_INPUT_NODE;
|
||||||
|
node2_inputs[0].value.node.node_id = 1;
|
||||||
|
node2_inputs[0].value.node.output_index = 0;
|
||||||
|
node2_inputs[1].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
node2_inputs[1].value.external.input_index = 2;
|
||||||
|
|
||||||
|
nodes[0].id = 2;
|
||||||
|
nodes[0].op.name = amduat_octets(mul_name, strlen(mul_name));
|
||||||
|
nodes[0].op.version = 1;
|
||||||
|
nodes[0].inputs = node2_inputs;
|
||||||
|
nodes[0].inputs_len = 2;
|
||||||
|
nodes[0].params = amduat_octets(NULL, 0);
|
||||||
|
|
||||||
|
nodes[1].id = 1;
|
||||||
|
nodes[1].op.name = amduat_octets(add_name, strlen(add_name));
|
||||||
|
nodes[1].op.version = 1;
|
||||||
|
nodes[1].inputs = node1_inputs;
|
||||||
|
nodes[1].inputs_len = 2;
|
||||||
|
nodes[1].params = amduat_octets(NULL, 0);
|
||||||
|
|
||||||
|
roots[0].node_id = 2;
|
||||||
|
roots[0].output_index = 0;
|
||||||
|
|
||||||
|
program.nodes = nodes;
|
||||||
|
program.nodes_len = 2;
|
||||||
|
program.roots = roots;
|
||||||
|
program.roots_len = 1;
|
||||||
|
|
||||||
|
if (!amduat_enc_pel_program_dag_encode_v1(&program, &encoded)) {
|
||||||
|
fprintf(stderr, "encode failed\n");
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bytes_equal(encoded, k_expected_program_bytes,
|
||||||
|
sizeof(k_expected_program_bytes))) {
|
||||||
|
fprintf(stderr, "encoded bytes mismatch\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_enc_pel_program_dag_decode_v1(encoded, &decoded)) {
|
||||||
|
fprintf(stderr, "decode failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoded.nodes_len != 2 || decoded.roots_len != 1) {
|
||||||
|
fprintf(stderr, "decoded lengths mismatch\n");
|
||||||
|
goto cleanup_decoded;
|
||||||
|
}
|
||||||
|
if (decoded.nodes[0].id != 1 || decoded.nodes[1].id != 2) {
|
||||||
|
fprintf(stderr, "decoded node order mismatch\n");
|
||||||
|
goto cleanup_decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_code = 0;
|
||||||
|
|
||||||
|
cleanup_decoded:
|
||||||
|
amduat_enc_pel_program_dag_free(&decoded);
|
||||||
|
cleanup:
|
||||||
|
free((void *)encoded.data);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
return test_program_encoding();
|
||||||
|
}
|
||||||
155
tests/enc/test_pel_trace_dag.c
Normal file
155
tests/enc/test_pel_trace_dag.c
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
#include "amduat/enc/pel_trace_dag.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static const uint8_t k_expected_trace_bytes[] = {
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
||||||
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||||
|
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||||
|
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||||
|
0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x22, 0x00,
|
||||||
|
0x01, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x22, 0x00, 0x01, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||||
|
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||||
|
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00,
|
||||||
|
0x00, 0x00, 0x22, 0x00, 0x01, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
|
||||||
|
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
|
||||||
|
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
|
||||||
|
0x12, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x05, 0x61, 0x64, 0x64, 0x36, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22,
|
||||||
|
0x00, 0x01, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x6d, 0x75,
|
||||||
|
0x6c, 0x36, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x21, 0x21,
|
||||||
|
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
|
||||||
|
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
|
||||||
|
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void fill_digest(uint8_t *out, uint8_t value) {
|
||||||
|
memset(out, value, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static amduat_reference_t make_ref(uint8_t value, uint8_t *storage) {
|
||||||
|
fill_digest(storage, value);
|
||||||
|
return amduat_reference(0x0001, amduat_octets(storage, 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool bytes_equal(amduat_octets_t bytes,
|
||||||
|
const uint8_t *expected,
|
||||||
|
size_t expected_len) {
|
||||||
|
if (bytes.len != expected_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bytes.len == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return memcmp(bytes.data, expected, expected_len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_trace_encoding(void) {
|
||||||
|
amduat_pel_trace_dag_value_t trace;
|
||||||
|
amduat_pel_node_trace_dag_t nodes[2];
|
||||||
|
amduat_reference_t input_refs[3];
|
||||||
|
amduat_reference_t output_refs0[1];
|
||||||
|
amduat_reference_t output_refs1[1];
|
||||||
|
amduat_octets_t encoded;
|
||||||
|
amduat_pel_trace_dag_value_t decoded;
|
||||||
|
uint8_t s[32], p[32], r[32], i0[32], i1[32], i2[32], o0[32], o1[32];
|
||||||
|
const char add_name[] = "add64";
|
||||||
|
const char mul_name[] = "mul64";
|
||||||
|
int exit_code = 1;
|
||||||
|
|
||||||
|
memset(&trace, 0, sizeof(trace));
|
||||||
|
|
||||||
|
trace.pel1_version = 1;
|
||||||
|
trace.scheme_ref = make_ref(0x01, s);
|
||||||
|
trace.program_ref = make_ref(0x02, p);
|
||||||
|
trace.status = AMDUAT_PEL_EXEC_STATUS_OK;
|
||||||
|
trace.summary.kind = AMDUAT_PEL_EXEC_ERROR_NONE;
|
||||||
|
trace.summary.status_code = 0;
|
||||||
|
trace.has_exec_result_ref = true;
|
||||||
|
trace.exec_result_ref = make_ref(0x03, r);
|
||||||
|
|
||||||
|
input_refs[0] = make_ref(0x10, i0);
|
||||||
|
input_refs[1] = make_ref(0x11, i1);
|
||||||
|
input_refs[2] = make_ref(0x12, i2);
|
||||||
|
trace.input_refs = input_refs;
|
||||||
|
trace.input_refs_len = 3;
|
||||||
|
|
||||||
|
trace.has_params_ref = false;
|
||||||
|
|
||||||
|
output_refs0[0] = make_ref(0x20, o0);
|
||||||
|
output_refs1[0] = make_ref(0x21, o1);
|
||||||
|
|
||||||
|
nodes[0].node_id = 1;
|
||||||
|
nodes[0].op_name = amduat_octets(add_name, strlen(add_name));
|
||||||
|
nodes[0].op_version = 1;
|
||||||
|
nodes[0].status = AMDUAT_PEL_NODE_TRACE_OK;
|
||||||
|
nodes[0].status_code = 0;
|
||||||
|
nodes[0].output_refs = output_refs0;
|
||||||
|
nodes[0].output_refs_len = 1;
|
||||||
|
nodes[0].diagnostics = NULL;
|
||||||
|
nodes[0].diagnostics_len = 0;
|
||||||
|
|
||||||
|
nodes[1].node_id = 2;
|
||||||
|
nodes[1].op_name = amduat_octets(mul_name, strlen(mul_name));
|
||||||
|
nodes[1].op_version = 1;
|
||||||
|
nodes[1].status = AMDUAT_PEL_NODE_TRACE_OK;
|
||||||
|
nodes[1].status_code = 0;
|
||||||
|
nodes[1].output_refs = output_refs1;
|
||||||
|
nodes[1].output_refs_len = 1;
|
||||||
|
nodes[1].diagnostics = NULL;
|
||||||
|
nodes[1].diagnostics_len = 0;
|
||||||
|
|
||||||
|
trace.node_traces = nodes;
|
||||||
|
trace.node_traces_len = 2;
|
||||||
|
|
||||||
|
if (!amduat_enc_pel_trace_dag_encode_v1(&trace, &encoded)) {
|
||||||
|
fprintf(stderr, "encode failed\n");
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bytes_equal(encoded, k_expected_trace_bytes,
|
||||||
|
sizeof(k_expected_trace_bytes))) {
|
||||||
|
fprintf(stderr, "encoded bytes mismatch\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_enc_pel_trace_dag_decode_v1(encoded, &decoded)) {
|
||||||
|
fprintf(stderr, "decode failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoded.node_traces_len != 2 || decoded.input_refs_len != 3) {
|
||||||
|
fprintf(stderr, "decoded lengths mismatch\n");
|
||||||
|
goto cleanup_decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_code = 0;
|
||||||
|
|
||||||
|
cleanup_decoded:
|
||||||
|
amduat_enc_pel_trace_dag_free(&decoded);
|
||||||
|
cleanup:
|
||||||
|
free((void *)encoded.data);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
return test_trace_encoding();
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue