Add PEL DAG scheme descriptor codec and validation
If you want a longer one: Add codec + tests for PEL DAG scheme descriptor
This commit is contained in:
parent
4583b1cfd3
commit
f5e1ab8801
|
|
@ -80,6 +80,7 @@ set(AMDUAT_ENC_SRCS
|
||||||
src/near_core/enc/asl1_core_codec.c
|
src/near_core/enc/asl1_core_codec.c
|
||||||
src/near_core/asl/ref_derive.c
|
src/near_core/asl/ref_derive.c
|
||||||
src/near_core/enc/pel_program_dag.c
|
src/near_core/enc/pel_program_dag.c
|
||||||
|
src/near_core/enc/pel_program_dag_desc.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/pel1_result.c
|
||||||
src/near_core/enc/tgk1_edge.c
|
src/near_core/enc/tgk1_edge.c
|
||||||
|
|
@ -296,6 +297,17 @@ target_link_libraries(amduat_test_pel_program_dag_exec
|
||||||
)
|
)
|
||||||
add_test(NAME pel_program_dag_exec COMMAND amduat_test_pel_program_dag_exec)
|
add_test(NAME pel_program_dag_exec COMMAND amduat_test_pel_program_dag_exec)
|
||||||
|
|
||||||
|
add_executable(amduat_test_pel_program_dag_desc
|
||||||
|
tests/pel/test_pel_program_dag_desc.c)
|
||||||
|
target_include_directories(amduat_test_pel_program_dag_desc
|
||||||
|
PRIVATE ${AMDUAT_INTERNAL_DIR}
|
||||||
|
PRIVATE ${AMDUAT_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(amduat_test_pel_program_dag_desc
|
||||||
|
PRIVATE amduat_enc
|
||||||
|
)
|
||||||
|
add_test(NAME pel_program_dag_desc COMMAND amduat_test_pel_program_dag_desc)
|
||||||
|
|
||||||
add_executable(amduat_test_pel_surf_run tests/pel/test_pel_surf_run.c)
|
add_executable(amduat_test_pel_surf_run tests/pel/test_pel_surf_run.c)
|
||||||
target_include_directories(amduat_test_pel_surf_run
|
target_include_directories(amduat_test_pel_surf_run
|
||||||
PRIVATE ${AMDUAT_INTERNAL_DIR}
|
PRIVATE ${AMDUAT_INTERNAL_DIR}
|
||||||
|
|
|
||||||
40
include/amduat/enc/pel_program_dag_desc.h
Normal file
40
include/amduat/enc/pel_program_dag_desc.h
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef AMDUAT_ENC_PEL_PROGRAM_DAG_DESC_H
|
||||||
|
#define AMDUAT_ENC_PEL_PROGRAM_DAG_DESC_H
|
||||||
|
|
||||||
|
#include "amduat/asl/core.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t pel1_version;
|
||||||
|
amduat_octets_t scheme_name;
|
||||||
|
amduat_type_tag_t program_type_tag;
|
||||||
|
uint16_t program_enc_profile;
|
||||||
|
bool has_trace_profile_ref;
|
||||||
|
amduat_reference_t trace_profile_ref;
|
||||||
|
bool has_opreg_ref;
|
||||||
|
amduat_reference_t opreg_ref;
|
||||||
|
} amduat_pel_dag_scheme_descriptor_t;
|
||||||
|
|
||||||
|
/* Caller owns any heap allocations returned in out_bytes/out_desc. */
|
||||||
|
bool amduat_enc_pel_program_dag_desc_encode_v1(
|
||||||
|
const amduat_pel_dag_scheme_descriptor_t *desc,
|
||||||
|
amduat_octets_t *out_bytes);
|
||||||
|
|
||||||
|
bool amduat_enc_pel_program_dag_desc_decode_v1(
|
||||||
|
amduat_octets_t bytes,
|
||||||
|
amduat_pel_dag_scheme_descriptor_t *out_desc);
|
||||||
|
|
||||||
|
void amduat_enc_pel_program_dag_desc_free(
|
||||||
|
amduat_pel_dag_scheme_descriptor_t *desc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AMDUAT_ENC_PEL_PROGRAM_DAG_DESC_H */
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "amduat/asl/core.h"
|
#include "amduat/asl/core.h"
|
||||||
#include "amduat/pel/program_dag.h"
|
#include "amduat/pel/program_dag.h"
|
||||||
|
#include "amduat/enc/pel_program_dag_desc.h"
|
||||||
#include "amduat/pel/surf.h"
|
#include "amduat/pel/surf.h"
|
||||||
#include "amduat/pel/trace_dag.h"
|
#include "amduat/pel/trace_dag.h"
|
||||||
|
|
||||||
|
|
@ -15,6 +16,10 @@ extern "C" {
|
||||||
bool amduat_pel_program_decode_artifact(const amduat_artifact_t *artifact,
|
bool amduat_pel_program_decode_artifact(const amduat_artifact_t *artifact,
|
||||||
amduat_pel_program_t *out_program);
|
amduat_pel_program_t *out_program);
|
||||||
|
|
||||||
|
bool amduat_pel_program_dag_desc_decode_artifact(
|
||||||
|
const amduat_artifact_t *artifact,
|
||||||
|
amduat_pel_dag_scheme_descriptor_t *out_desc);
|
||||||
|
|
||||||
bool amduat_pel_trace_decode_artifact(const amduat_artifact_t *artifact,
|
bool amduat_pel_trace_decode_artifact(const amduat_artifact_t *artifact,
|
||||||
amduat_pel_trace_dag_value_t *out_trace);
|
amduat_pel_trace_dag_value_t *out_trace);
|
||||||
|
|
||||||
|
|
|
||||||
440
src/near_core/enc/pel_program_dag_desc.c
Normal file
440
src/near_core/enc/pel_program_dag_desc.c
Normal file
|
|
@ -0,0 +1,440 @@
|
||||||
|
#include "amduat/enc/pel_program_dag_desc.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void amduat_enc_pel_program_dag_desc_free(
|
||||||
|
amduat_pel_dag_scheme_descriptor_t *desc) {
|
||||||
|
if (desc == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_octets_free(&desc->scheme_name);
|
||||||
|
if (desc->has_trace_profile_ref) {
|
||||||
|
amduat_reference_free(&desc->trace_profile_ref);
|
||||||
|
}
|
||||||
|
if (desc->has_opreg_ref) {
|
||||||
|
amduat_reference_free(&desc->opreg_ref);
|
||||||
|
}
|
||||||
|
desc->has_trace_profile_ref = false;
|
||||||
|
desc->has_opreg_ref = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduat_enc_pel_program_dag_desc_encode_v1(
|
||||||
|
const amduat_pel_dag_scheme_descriptor_t *desc,
|
||||||
|
amduat_octets_t *out_bytes) {
|
||||||
|
size_t total_len = 0;
|
||||||
|
size_t offset = 0;
|
||||||
|
uint8_t *buffer;
|
||||||
|
|
||||||
|
if (desc == NULL || out_bytes == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_bytes->data = NULL;
|
||||||
|
out_bytes->len = 0;
|
||||||
|
|
||||||
|
if (desc->pel1_version != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (desc->scheme_name.len != 0 && desc->scheme_name.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (desc->scheme_name.len > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_utf8_is_valid(desc->scheme_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_add_size(&total_len, 2 + 4 + desc->scheme_name.len + 4 + 2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (desc->has_trace_profile_ref) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(desc->trace_profile_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!amduat_add_size(&total_len, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (desc->has_opreg_ref) {
|
||||||
|
size_t enc_len;
|
||||||
|
if (!amduat_encoded_ref_len(desc->opreg_ref, &enc_len) ||
|
||||||
|
!amduat_add_size(&total_len, enc_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = (uint8_t *)malloc(total_len);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_store_u16_be(buffer + offset, desc->pel1_version);
|
||||||
|
offset += 2;
|
||||||
|
amduat_store_u32_be(buffer + offset, (uint32_t)desc->scheme_name.len);
|
||||||
|
offset += 4;
|
||||||
|
if (desc->scheme_name.len != 0) {
|
||||||
|
memcpy(buffer + offset, desc->scheme_name.data, desc->scheme_name.len);
|
||||||
|
offset += desc->scheme_name.len;
|
||||||
|
}
|
||||||
|
amduat_store_u32_be(buffer + offset, desc->program_type_tag.tag_id);
|
||||||
|
offset += 4;
|
||||||
|
amduat_store_u16_be(buffer + offset, desc->program_enc_profile);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
buffer[offset] = desc->has_trace_profile_ref ? 0x01u : 0x00u;
|
||||||
|
offset += 1;
|
||||||
|
if (desc->has_trace_profile_ref) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
desc->trace_profile_ref)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[offset] = desc->has_opreg_ref ? 0x01u : 0x00u;
|
||||||
|
offset += 1;
|
||||||
|
if (desc->has_opreg_ref) {
|
||||||
|
if (!amduat_write_encoded_ref(buffer, total_len, &offset,
|
||||||
|
desc->opreg_ref)) {
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out_bytes->data = buffer;
|
||||||
|
out_bytes->len = total_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduat_enc_pel_program_dag_desc_decode_v1(
|
||||||
|
amduat_octets_t bytes,
|
||||||
|
amduat_pel_dag_scheme_descriptor_t *out_desc) {
|
||||||
|
amduat_cursor_t cur;
|
||||||
|
uint16_t pel1_version;
|
||||||
|
uint32_t scheme_name_len;
|
||||||
|
uint32_t program_type_tag_id;
|
||||||
|
uint16_t program_enc_profile;
|
||||||
|
uint8_t has_trace_profile;
|
||||||
|
uint8_t has_opreg_ref;
|
||||||
|
uint8_t *scheme_name_copy = NULL;
|
||||||
|
|
||||||
|
if (out_desc == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bytes.len != 0 && bytes.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(out_desc, 0, sizeof(*out_desc));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &scheme_name_len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cur.len - cur.offset < scheme_name_len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (scheme_name_len != 0) {
|
||||||
|
scheme_name_copy = (uint8_t *)malloc(scheme_name_len);
|
||||||
|
if (scheme_name_copy == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(scheme_name_copy, cur.data + cur.offset, scheme_name_len);
|
||||||
|
}
|
||||||
|
cur.offset += scheme_name_len;
|
||||||
|
if (!amduat_utf8_is_valid(
|
||||||
|
amduat_octets(scheme_name_copy, scheme_name_len))) {
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u32(&cur, &program_type_tag_id)) {
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduat_read_u16(&cur, &program_enc_profile)) {
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u8(&cur, &has_trace_profile)) {
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_trace_profile != 0x00u && has_trace_profile != 0x01u) {
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_trace_profile == 0x01u) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_desc->trace_profile_ref)) {
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_desc->has_trace_profile_ref = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_read_u8(&cur, &has_opreg_ref)) {
|
||||||
|
amduat_reference_free(&out_desc->trace_profile_ref);
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_opreg_ref != 0x00u && has_opreg_ref != 0x01u) {
|
||||||
|
if (out_desc->has_trace_profile_ref) {
|
||||||
|
amduat_reference_free(&out_desc->trace_profile_ref);
|
||||||
|
}
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_opreg_ref == 0x01u) {
|
||||||
|
if (!amduat_read_encoded_ref(&cur, &out_desc->opreg_ref)) {
|
||||||
|
if (out_desc->has_trace_profile_ref) {
|
||||||
|
amduat_reference_free(&out_desc->trace_profile_ref);
|
||||||
|
}
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out_desc->has_opreg_ref = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur.offset != cur.len) {
|
||||||
|
amduat_enc_pel_program_dag_desc_free(out_desc);
|
||||||
|
free(scheme_name_copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_desc->pel1_version = pel1_version;
|
||||||
|
out_desc->scheme_name = amduat_octets(scheme_name_copy, scheme_name_len);
|
||||||
|
out_desc->program_type_tag = amduat_type_tag(program_type_tag_id);
|
||||||
|
out_desc->program_enc_profile = program_enc_profile;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "amduat/enc/pel1_result.h"
|
#include "amduat/enc/pel1_result.h"
|
||||||
#include "amduat/enc/pel_program_dag.h"
|
#include "amduat/enc/pel_program_dag.h"
|
||||||
|
#include "amduat/enc/pel_program_dag_desc.h"
|
||||||
#include "amduat/enc/pel_trace_dag.h"
|
#include "amduat/enc/pel_trace_dag.h"
|
||||||
#include "amduat/pel/program_dag_desc.h"
|
#include "amduat/pel/program_dag_desc.h"
|
||||||
|
|
||||||
|
|
@ -20,6 +21,20 @@ bool amduat_pel_program_decode_artifact(const amduat_artifact_t *artifact,
|
||||||
return amduat_enc_pel_program_dag_decode_v1(artifact->bytes, out_program);
|
return amduat_enc_pel_program_dag_decode_v1(artifact->bytes, out_program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool amduat_pel_program_dag_desc_decode_artifact(
|
||||||
|
const amduat_artifact_t *artifact,
|
||||||
|
amduat_pel_dag_scheme_descriptor_t *out_desc) {
|
||||||
|
if (artifact == NULL || out_desc == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (artifact->has_type_tag &&
|
||||||
|
artifact->type_tag.tag_id != AMDUAT_PEL_TYPE_TAG_SCHEME_DESC_1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(out_desc, 0, sizeof(*out_desc));
|
||||||
|
return amduat_enc_pel_program_dag_desc_decode_v1(artifact->bytes, out_desc);
|
||||||
|
}
|
||||||
|
|
||||||
bool amduat_pel_trace_decode_artifact(const amduat_artifact_t *artifact,
|
bool amduat_pel_trace_decode_artifact(const amduat_artifact_t *artifact,
|
||||||
amduat_pel_trace_dag_value_t *out_trace) {
|
amduat_pel_trace_dag_value_t *out_trace) {
|
||||||
if (artifact == NULL || out_trace == NULL) {
|
if (artifact == NULL || out_trace == NULL) {
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ static void amduat_pel_cli_print_usage(FILE *stream) {
|
||||||
"commands:\n"
|
"commands:\n"
|
||||||
" run Execute a PEL/PROGRAM-DAG/1 program via PEL/1-SURF (store-backed).\n"
|
" run Execute a PEL/PROGRAM-DAG/1 program via PEL/1-SURF (store-backed).\n"
|
||||||
" exec Execute a PEL/PROGRAM-DAG/1 program in-memory (no store writes).\n"
|
" exec Execute a PEL/PROGRAM-DAG/1 program in-memory (no store writes).\n"
|
||||||
" validate Validate a Program artifact (decode + DAG checks + params).\n"
|
" validate Validate a Program or Scheme Descriptor artifact.\n"
|
||||||
" program Program DAG tools (decode, normalize).\n"
|
" program Program DAG tools (decode, normalize).\n"
|
||||||
" trace Trace DAG tools (decode, from-result).\n"
|
" trace Trace DAG tools (decode, from-result).\n"
|
||||||
" result Surface result tools (decode).\n"
|
" result Surface result tools (decode).\n"
|
||||||
|
|
@ -1155,17 +1155,38 @@ static int amduat_pel_cli_cmd_validate(
|
||||||
return AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
|
return AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (artifact.has_type_tag &&
|
{
|
||||||
artifact.type_tag.tag_id != AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1) {
|
bool expect_desc = has_expect_type_tag &&
|
||||||
fprintf(stderr, "error: type-tag mismatch\n");
|
expect_type_tag.tag_id ==
|
||||||
amduat_asl_artifact_free(&artifact);
|
AMDUAT_PEL_TYPE_TAG_SCHEME_DESC_1;
|
||||||
return AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
|
bool is_desc = (artifact.has_type_tag &&
|
||||||
}
|
artifact.type_tag.tag_id ==
|
||||||
|
AMDUAT_PEL_TYPE_TAG_SCHEME_DESC_1) ||
|
||||||
|
expect_desc;
|
||||||
|
|
||||||
if (!amduat_pel_program_validate_artifact(&artifact, &valid)) {
|
if (is_desc) {
|
||||||
fprintf(stderr, "error: invalid program encoding\n");
|
amduat_pel_dag_scheme_descriptor_t desc;
|
||||||
amduat_asl_artifact_free(&artifact);
|
if (!amduat_pel_program_dag_desc_decode_artifact(&artifact, &desc)) {
|
||||||
return AMDUAT_PEL_CLI_EXIT_CODEC;
|
fprintf(stderr, "error: invalid scheme descriptor encoding\n");
|
||||||
|
amduat_asl_artifact_free(&artifact);
|
||||||
|
return AMDUAT_PEL_CLI_EXIT_CODEC;
|
||||||
|
}
|
||||||
|
amduat_enc_pel_program_dag_desc_free(&desc);
|
||||||
|
valid = true;
|
||||||
|
} else {
|
||||||
|
if (artifact.has_type_tag &&
|
||||||
|
artifact.type_tag.tag_id != AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1) {
|
||||||
|
fprintf(stderr, "error: type-tag mismatch\n");
|
||||||
|
amduat_asl_artifact_free(&artifact);
|
||||||
|
return AMDUAT_PEL_CLI_EXIT_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_pel_program_validate_artifact(&artifact, &valid)) {
|
||||||
|
fprintf(stderr, "error: invalid program encoding\n");
|
||||||
|
amduat_asl_artifact_free(&artifact);
|
||||||
|
return AMDUAT_PEL_CLI_EXIT_CODEC;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
amduat_asl_artifact_free(&artifact);
|
amduat_asl_artifact_free(&artifact);
|
||||||
|
|
|
||||||
92
tests/pel/test_pel_program_dag_desc.c
Normal file
92
tests/pel/test_pel_program_dag_desc.c
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include "amduat/enc/pel_program_dag_desc.h"
|
||||||
|
#include "amduat/enc/pel_program_dag.h"
|
||||||
|
#include "amduat/pel/program_dag_desc.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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_descriptor_round_trip(void) {
|
||||||
|
static const uint8_t k_desc_bytes[] = {
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x50, 0x45,
|
||||||
|
0x4c, 0x2f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x41,
|
||||||
|
0x4d, 0x2d, 0x44, 0x41, 0x47, 0x2f, 0x31, 0x00,
|
||||||
|
0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const char k_scheme_name[] = "PEL/PROGRAM-DAG/1";
|
||||||
|
amduat_pel_dag_scheme_descriptor_t desc;
|
||||||
|
amduat_pel_dag_scheme_descriptor_t decoded;
|
||||||
|
amduat_octets_t encoded = amduat_octets(NULL, 0);
|
||||||
|
amduat_octets_t encoded_roundtrip = amduat_octets(NULL, 0);
|
||||||
|
int exit_code = 1;
|
||||||
|
|
||||||
|
memset(&desc, 0, sizeof(desc));
|
||||||
|
desc.pel1_version = 1;
|
||||||
|
desc.scheme_name = amduat_octets(k_scheme_name, strlen(k_scheme_name));
|
||||||
|
desc.program_type_tag = amduat_type_tag(AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1);
|
||||||
|
desc.program_enc_profile = AMDUAT_PEL_ENC_PROGRAM_DAG_V1;
|
||||||
|
desc.has_trace_profile_ref = false;
|
||||||
|
desc.has_opreg_ref = false;
|
||||||
|
|
||||||
|
if (!amduat_enc_pel_program_dag_desc_encode_v1(&desc, &encoded)) {
|
||||||
|
fprintf(stderr, "encode failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (!bytes_equal(encoded, k_desc_bytes, sizeof(k_desc_bytes))) {
|
||||||
|
fprintf(stderr, "encoded bytes mismatch\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&decoded, 0, sizeof(decoded));
|
||||||
|
if (!amduat_enc_pel_program_dag_desc_decode_v1(
|
||||||
|
amduat_octets(k_desc_bytes, sizeof(k_desc_bytes)), &decoded)) {
|
||||||
|
fprintf(stderr, "decode failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (decoded.pel1_version != 1 ||
|
||||||
|
decoded.program_type_tag.tag_id != AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1 ||
|
||||||
|
decoded.program_enc_profile != AMDUAT_PEL_ENC_PROGRAM_DAG_V1 ||
|
||||||
|
decoded.has_trace_profile_ref || decoded.has_opreg_ref) {
|
||||||
|
fprintf(stderr, "decoded fields mismatch\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (!bytes_equal(decoded.scheme_name,
|
||||||
|
(const uint8_t *)k_scheme_name,
|
||||||
|
strlen(k_scheme_name))) {
|
||||||
|
fprintf(stderr, "decoded scheme name mismatch\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_enc_pel_program_dag_desc_encode_v1(&decoded,
|
||||||
|
&encoded_roundtrip)) {
|
||||||
|
fprintf(stderr, "roundtrip encode failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (!bytes_equal(encoded_roundtrip, k_desc_bytes, sizeof(k_desc_bytes))) {
|
||||||
|
fprintf(stderr, "roundtrip bytes mismatch\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_code = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
amduat_octets_free(&encoded);
|
||||||
|
amduat_octets_free(&encoded_roundtrip);
|
||||||
|
amduat_enc_pel_program_dag_desc_free(&decoded);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
return test_descriptor_round_trip();
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue