Fix trace DAG EncodedRef validation and test unknown hash ids
This commit is contained in:
parent
a4932b1217
commit
5b7d07e033
14
AUDITS.md
14
AUDITS.md
|
|
@ -37,7 +37,7 @@ Status legend: ✅ completed, ⬜ pending.
|
|||
9. ✅ `tier1/enc-pel-program-dag-1.md`
|
||||
10. ✅ `tier1/enc-pel1-result-1.md`
|
||||
11. ✅ `tier1/pel-trace-dag-1.md`
|
||||
12. ⬜ `tier1/enc-pel-trace-dag-1.md`
|
||||
12. ✅ `tier1/enc-pel-trace-dag-1.md`
|
||||
13. ⬜ `tier1/tgk-1-core.md`
|
||||
14. ⬜ `tier1/enc-tgk1-edge-1.md`
|
||||
15. ⬜ `tier1/tgk-store-1.md`
|
||||
|
|
@ -173,3 +173,15 @@ Status legend: ✅ completed, ⬜ pending.
|
|||
for failed nodes.
|
||||
- Tests: command not provided — pass (user reported “100% tests passed, 0 tests
|
||||
failed out of 14”).
|
||||
|
||||
## 2025-12-22 — ENC/PEL-TRACE-DAG/1 (`tier1/enc-pel-trace-dag-1.md`)
|
||||
- Scope: canonical TraceDAGBytes encoding, EncodedRef framing, and validation
|
||||
rules for trace payloads.
|
||||
- Findings: EncodedRef encoding rejected unknown `hash_id` values by requiring a
|
||||
registry-backed digest length, contradicting ENC/ASL1-CORE’s ReferenceBytes
|
||||
rules (which allow unknown hash IDs and variable digest lengths as long as
|
||||
they are not reserved).
|
||||
- Resolution: relaxed EncodedRef length validation to reject reserved hash IDs
|
||||
but permit unknown IDs and digest lengths, matching ENC/ASL1-CORE v1 behavior.
|
||||
- Tests: command not provided — pass (user reported “100% tests passed, 0 tests
|
||||
failed out of 14”).
|
||||
|
|
|
|||
|
|
@ -134,20 +134,26 @@ static bool amduat_utf8_is_valid(amduat_octets_t value) {
|
|||
|
||||
static bool amduat_reference_bytes_len(amduat_reference_t ref, size_t *out_len) {
|
||||
const amduat_hash_asl1_desc_t *desc;
|
||||
size_t digest_len;
|
||||
|
||||
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) {
|
||||
if (amduat_hash_asl1_is_reserved(ref.hash_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*out_len = 2 + desc->digest_len;
|
||||
desc = amduat_hash_asl1_desc_lookup(ref.hash_id);
|
||||
digest_len = ref.digest.len;
|
||||
if (desc != NULL && desc->digest_len != 0 && digest_len != desc->digest_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (digest_len > SIZE_MAX - 2) {
|
||||
return false;
|
||||
}
|
||||
*out_len = 2 + digest_len;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,14 @@ static amduat_reference_t make_ref(uint8_t value, uint8_t *storage) {
|
|||
return amduat_reference(0x0001, amduat_octets(storage, 32));
|
||||
}
|
||||
|
||||
static amduat_reference_t make_ref_custom(amduat_hash_id_t hash_id,
|
||||
uint8_t *storage,
|
||||
size_t len,
|
||||
uint8_t value) {
|
||||
memset(storage, value, len);
|
||||
return amduat_reference(hash_id, amduat_octets(storage, len));
|
||||
}
|
||||
|
||||
static bool bytes_equal(amduat_octets_t bytes,
|
||||
const uint8_t *expected,
|
||||
size_t expected_len) {
|
||||
|
|
@ -150,6 +158,80 @@ cleanup:
|
|||
return exit_code;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
return test_trace_encoding();
|
||||
static int test_trace_unknown_hash_id(void) {
|
||||
amduat_pel_trace_dag_value_t trace;
|
||||
amduat_pel_node_trace_dag_t node;
|
||||
amduat_reference_t input_refs[1];
|
||||
amduat_octets_t encoded;
|
||||
amduat_pel_trace_dag_value_t decoded;
|
||||
uint8_t s[32], p[32], r[32], i0[5];
|
||||
const char op_name[] = "noop";
|
||||
int exit_code = 1;
|
||||
|
||||
memset(&trace, 0, sizeof(trace));
|
||||
memset(&node, 0, sizeof(node));
|
||||
|
||||
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_custom(0x1234, i0, sizeof(i0), 0x5a);
|
||||
trace.input_refs = input_refs;
|
||||
trace.input_refs_len = 1;
|
||||
trace.has_params_ref = false;
|
||||
|
||||
node.node_id = 0;
|
||||
node.op_name = amduat_octets(op_name, strlen(op_name));
|
||||
node.op_version = 1;
|
||||
node.status = AMDUAT_PEL_NODE_TRACE_OK;
|
||||
node.status_code = 0;
|
||||
node.output_refs = NULL;
|
||||
node.output_refs_len = 0;
|
||||
node.diagnostics = NULL;
|
||||
node.diagnostics_len = 0;
|
||||
|
||||
trace.node_traces = &node;
|
||||
trace.node_traces_len = 1;
|
||||
|
||||
if (!amduat_enc_pel_trace_dag_encode_v1(&trace, &encoded)) {
|
||||
fprintf(stderr, "encode failed (unknown hash)\n");
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
if (!amduat_enc_pel_trace_dag_decode_v1(encoded, &decoded)) {
|
||||
fprintf(stderr, "decode failed (unknown hash)\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (decoded.input_refs_len != 1) {
|
||||
fprintf(stderr, "decoded input count mismatch\n");
|
||||
goto cleanup_decoded;
|
||||
}
|
||||
|
||||
if (decoded.input_refs[0].hash_id != 0x1234 ||
|
||||
decoded.input_refs[0].digest.len != sizeof(i0) ||
|
||||
memcmp(decoded.input_refs[0].digest.data, i0, sizeof(i0)) != 0) {
|
||||
fprintf(stderr, "decoded unknown hash 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) {
|
||||
if (test_trace_encoding() != 0) {
|
||||
return 1;
|
||||
}
|
||||
return test_trace_unknown_hash_id();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue