From b32c1643139de2fc252052aaf40d76c27caa4c2f Mon Sep 17 00:00:00 2001 From: Carl Niklas Rydberg Date: Fri, 19 Dec 2025 23:55:27 +0100 Subject: [PATCH] Add ASL/1 core codec and refactor fs store to use it --- CMakeLists.txt | 1 + include/amduat/enc/asl1_core_codec.h | 35 +++ src/adapters/asl_store_fs/asl_store_fs.c | 211 +++--------------- src/near_core/enc/asl1_core_codec.c | 264 +++++++++++++++++++++++ 4 files changed, 326 insertions(+), 185 deletions(-) create mode 100644 include/amduat/enc/asl1_core_codec.h create mode 100644 src/near_core/enc/asl1_core_codec.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ca06e68..de639c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,7 @@ set(AMDUAT_HASH_ASL1_SRCS set(AMDUAT_ENC_SRCS src/near_core/enc/asl1_core.c + src/near_core/enc/asl1_core_codec.c src/near_core/enc/pel_program_dag.c src/near_core/enc/pel_trace_dag.c src/near_core/enc/tgk1_edge.c diff --git a/include/amduat/enc/asl1_core_codec.h b/include/amduat/enc/asl1_core_codec.h new file mode 100644 index 0000000..fd2a1e2 --- /dev/null +++ b/include/amduat/enc/asl1_core_codec.h @@ -0,0 +1,35 @@ +#ifndef AMDUAT_ENC_ASL1_CORE_CODEC_H +#define AMDUAT_ENC_ASL1_CORE_CODEC_H + +#include "amduat/asl/core.h" + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Caller owns any heap allocations returned in out_bytes/out_artifact/out_reference. */ +bool amduat_enc_asl1_core_encode_artifact_v1( + amduat_artifact_t artifact, + amduat_octets_t *out_bytes); + +bool amduat_enc_asl1_core_decode_artifact_v1( + amduat_octets_t bytes, + amduat_artifact_t *out_artifact); + +bool amduat_enc_asl1_core_encode_reference_v1( + amduat_reference_t reference, + amduat_octets_t *out_bytes); + +bool amduat_enc_asl1_core_decode_reference_v1( + amduat_octets_t bytes, + amduat_reference_t *out_reference); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* AMDUAT_ENC_ASL1_CORE_CODEC_H */ diff --git a/src/adapters/asl_store_fs/asl_store_fs.c b/src/adapters/asl_store_fs/asl_store_fs.c index 44e04cd..d884010 100644 --- a/src/adapters/asl_store_fs/asl_store_fs.c +++ b/src/adapters/asl_store_fs/asl_store_fs.c @@ -2,6 +2,7 @@ #include "amduat/asl/core.h" #include "amduat/enc/asl1_core.h" +#include "amduat/enc/asl1_core_codec.h" #include "amduat/hash/asl1.h" #include @@ -11,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -21,10 +21,7 @@ #endif enum { - AMDUAT_ASL_STORE_FS_MIN_DIGEST_BYTES = 2, - AMDUAT_ASL_STORE_FS_HAS_TAG_LEN = 1, - AMDUAT_ASL_STORE_FS_TAG_LEN = 4, - AMDUAT_ASL_STORE_FS_LEN_LEN = 8 + AMDUAT_ASL_STORE_FS_MIN_DIGEST_BYTES = 2 }; typedef enum { @@ -39,157 +36,6 @@ typedef enum { AMDUAT_ASL_STORE_FS_READ_ERR = 2 } amduat_asl_store_fs_read_status_t; -static void amduat_asl_store_fs_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 void amduat_asl_store_fs_store_u64_be(uint8_t *out, uint64_t value) { - out[0] = (uint8_t)((value >> 56) & 0xffu); - out[1] = (uint8_t)((value >> 48) & 0xffu); - out[2] = (uint8_t)((value >> 40) & 0xffu); - out[3] = (uint8_t)((value >> 32) & 0xffu); - out[4] = (uint8_t)((value >> 24) & 0xffu); - out[5] = (uint8_t)((value >> 16) & 0xffu); - out[6] = (uint8_t)((value >> 8) & 0xffu); - out[7] = (uint8_t)(value & 0xffu); -} - -static uint32_t amduat_asl_store_fs_load_u32_be(const uint8_t *data) { - return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | - ((uint32_t)data[2] << 8) | (uint32_t)data[3]; -} - -static uint64_t amduat_asl_store_fs_load_u64_be(const uint8_t *data) { - return ((uint64_t)data[0] << 56) | ((uint64_t)data[1] << 48) | - ((uint64_t)data[2] << 40) | ((uint64_t)data[3] << 32) | - ((uint64_t)data[4] << 24) | ((uint64_t)data[5] << 16) | - ((uint64_t)data[6] << 8) | (uint64_t)data[7]; -} - -static bool amduat_asl_store_fs_encode_artifact_v1( - amduat_artifact_t artifact, - uint8_t **out_bytes, - size_t *out_len) { - size_t header_len; - size_t total_len; - size_t offset; - uint8_t *buffer; - - if (out_bytes == NULL || out_len == NULL) { - return false; - } - *out_bytes = NULL; - *out_len = 0; - - if (artifact.bytes.len != 0 && artifact.bytes.data == NULL) { - return false; - } - if (artifact.bytes.len > UINT64_MAX) { - return false; - } - - header_len = AMDUAT_ASL_STORE_FS_HAS_TAG_LEN + AMDUAT_ASL_STORE_FS_LEN_LEN; - if (artifact.has_type_tag) { - header_len += AMDUAT_ASL_STORE_FS_TAG_LEN; - } - if (artifact.bytes.len > SIZE_MAX - header_len) { - return false; - } - - total_len = header_len + artifact.bytes.len; - buffer = (uint8_t *)malloc(total_len); - if (buffer == NULL) { - return false; - } - - offset = 0; - buffer[offset++] = artifact.has_type_tag ? 0x01u : 0x00u; - if (artifact.has_type_tag) { - amduat_asl_store_fs_store_u32_be(buffer + offset, artifact.type_tag.tag_id); - offset += AMDUAT_ASL_STORE_FS_TAG_LEN; - } - amduat_asl_store_fs_store_u64_be(buffer + offset, - (uint64_t)artifact.bytes.len); - offset += AMDUAT_ASL_STORE_FS_LEN_LEN; - - if (artifact.bytes.len != 0) { - memcpy(buffer + offset, artifact.bytes.data, artifact.bytes.len); - } - - *out_bytes = buffer; - *out_len = total_len; - return true; -} - -static bool amduat_asl_store_fs_decode_artifact_v1( - const uint8_t *bytes, - size_t len, - amduat_artifact_t *out_artifact) { - size_t offset; - uint8_t has_type_tag; - uint32_t tag_id; - uint64_t payload_len_u64; - size_t payload_len; - uint8_t *payload; - - if (bytes == NULL || out_artifact == NULL) { - return false; - } - if (len < AMDUAT_ASL_STORE_FS_HAS_TAG_LEN + AMDUAT_ASL_STORE_FS_LEN_LEN) { - return false; - } - - offset = 0; - has_type_tag = bytes[offset++]; - if (has_type_tag != 0x00u && has_type_tag != 0x01u) { - return false; - } - - tag_id = 0; - if (has_type_tag == 0x01u) { - if (len < offset + AMDUAT_ASL_STORE_FS_TAG_LEN + - AMDUAT_ASL_STORE_FS_LEN_LEN) { - return false; - } - tag_id = amduat_asl_store_fs_load_u32_be(bytes + offset); - offset += AMDUAT_ASL_STORE_FS_TAG_LEN; - } - - if (len < offset + AMDUAT_ASL_STORE_FS_LEN_LEN) { - return false; - } - payload_len_u64 = amduat_asl_store_fs_load_u64_be(bytes + offset); - offset += AMDUAT_ASL_STORE_FS_LEN_LEN; - if (payload_len_u64 > SIZE_MAX) { - return false; - } - payload_len = (size_t)payload_len_u64; - if (len - offset != payload_len) { - return false; - } - - payload = NULL; - if (payload_len != 0) { - payload = (uint8_t *)malloc(payload_len); - if (payload == NULL) { - return false; - } - memcpy(payload, bytes + offset, payload_len); - } - - out_artifact->bytes = amduat_octets(payload, payload_len); - out_artifact->has_type_tag = has_type_tag == 0x01u; - if (out_artifact->has_type_tag) { - out_artifact->type_tag = amduat_type_tag(tag_id); - } else { - out_artifact->type_tag.tag_id = 0; - } - return true; -} - static void amduat_asl_store_fs_format_hex(const uint8_t *bytes, size_t count, char *out) { @@ -598,10 +444,8 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( amduat_reference_t *out_ref) { amduat_asl_store_fs_t *fs; const amduat_hash_asl1_desc_t *hash_desc; - uint8_t *artifact_bytes; - size_t artifact_len; + amduat_octets_t artifact_bytes; uint8_t *digest; - amduat_octets_t artifact_octets; bool ok; char *profile_path; char *hash_path; @@ -628,23 +472,20 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( return AMDUAT_ASL_STORE_ERR_UNSUPPORTED; } - artifact_bytes = NULL; - artifact_len = 0u; - if (!amduat_asl_store_fs_encode_artifact_v1(artifact, &artifact_bytes, - &artifact_len)) { + artifact_bytes = amduat_octets(NULL, 0u); + if (!amduat_enc_asl1_core_encode_artifact_v1(artifact, &artifact_bytes)) { return AMDUAT_ASL_STORE_ERR_INTEGRITY; } digest = (uint8_t *)malloc(hash_desc->digest_len); if (digest == NULL) { - free(artifact_bytes); + free((void *)artifact_bytes.data); return AMDUAT_ASL_STORE_ERR_INTEGRITY; } - artifact_octets = amduat_octets(artifact_bytes, artifact_len); - if (!amduat_hash_asl1_digest(hash_desc->hash_id, artifact_octets, digest, + if (!amduat_hash_asl1_digest(hash_desc->hash_id, artifact_bytes, digest, hash_desc->digest_len)) { - free(artifact_bytes); + free((void *)artifact_bytes.data); free(digest); return AMDUAT_ASL_STORE_ERR_INTEGRITY; } @@ -663,7 +504,7 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( &level2_path, &object_path); if (!ok) { - free(artifact_bytes); + free((void *)artifact_bytes.data); free(digest); return AMDUAT_ASL_STORE_ERR_INTEGRITY; } @@ -673,7 +514,7 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( !amduat_asl_store_fs_ensure_directory(hash_path) || !amduat_asl_store_fs_ensure_directory(level1_path) || !amduat_asl_store_fs_ensure_directory(level2_path)) { - free(artifact_bytes); + free((void *)artifact_bytes.data); free(digest); free(profile_path); free(hash_path); @@ -684,12 +525,12 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( } cmp_err = amduat_asl_store_fs_compare_existing(object_path, - artifact_bytes, - artifact_len); + artifact_bytes.data, + artifact_bytes.len); if (cmp_err == AMDUAT_ASL_STORE_OK) { out_ref->hash_id = fs->config.hash_id; out_ref->digest = amduat_octets(digest, hash_desc->digest_len); - free(artifact_bytes); + free((void *)artifact_bytes.data); free(profile_path); free(hash_path); free(level1_path); @@ -698,7 +539,7 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( return AMDUAT_ASL_STORE_OK; } if (cmp_err == AMDUAT_ASL_STORE_ERR_INTEGRITY) { - free(artifact_bytes); + free((void *)artifact_bytes.data); free(digest); free(profile_path); free(hash_path); @@ -710,14 +551,14 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( write_status = amduat_asl_store_fs_write_atomic(level2_path, object_path, - artifact_bytes, - artifact_len); + artifact_bytes.data, + artifact_bytes.len); if (write_status == AMDUAT_ASL_STORE_FS_WRITE_EXIST) { cmp_err = amduat_asl_store_fs_compare_existing(object_path, - artifact_bytes, - artifact_len); + artifact_bytes.data, + artifact_bytes.len); if (cmp_err != AMDUAT_ASL_STORE_OK) { - free(artifact_bytes); + free((void *)artifact_bytes.data); free(digest); free(profile_path); free(hash_path); @@ -727,7 +568,7 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( return AMDUAT_ASL_STORE_ERR_INTEGRITY; } } else if (write_status != AMDUAT_ASL_STORE_FS_WRITE_OK) { - free(artifact_bytes); + free((void *)artifact_bytes.data); free(digest); free(profile_path); free(hash_path); @@ -739,7 +580,7 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( if (!amduat_asl_store_fs_fsync_directory(level2_path)) { unlink(object_path); - free(artifact_bytes); + free((void *)artifact_bytes.data); free(digest); free(profile_path); free(hash_path); @@ -750,7 +591,7 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( } if (!amduat_asl_store_fs_fsync_directory(fs->root_path)) { unlink(object_path); - free(artifact_bytes); + free((void *)artifact_bytes.data); free(digest); free(profile_path); free(hash_path); @@ -762,7 +603,7 @@ static amduat_asl_store_error_t amduat_asl_store_fs_put_impl( out_ref->hash_id = fs->config.hash_id; out_ref->digest = amduat_octets(digest, hash_desc->digest_len); - free(artifact_bytes); + free((void *)artifact_bytes.data); free(profile_path); free(hash_path); free(level1_path); @@ -888,9 +729,9 @@ static amduat_asl_store_error_t amduat_asl_store_fs_get_impl( } free(computed_digest); - decoded = amduat_asl_store_fs_decode_artifact_v1(stored_bytes, - stored_len, - out_artifact); + decoded = amduat_enc_asl1_core_decode_artifact_v1( + amduat_octets(stored_bytes, stored_len), + out_artifact); free(stored_bytes); free(profile_path); free(hash_path); diff --git a/src/near_core/enc/asl1_core_codec.c b/src/near_core/enc/asl1_core_codec.c new file mode 100644 index 0000000..82fd7e5 --- /dev/null +++ b/src/near_core/enc/asl1_core_codec.c @@ -0,0 +1,264 @@ +#include "amduat/enc/asl1_core_codec.h" + +#include "amduat/hash/asl1.h" + +#include +#include +#include + +enum { + AMDUAT_ENC_ASL1_CORE_HAS_TAG_LEN = 1, + AMDUAT_ENC_ASL1_CORE_TAG_LEN = 4, + AMDUAT_ENC_ASL1_CORE_LEN_LEN = 8, + AMDUAT_ENC_ASL1_CORE_REF_HASH_LEN = 2 +}; + +static void amduat_enc_asl1_core_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_enc_asl1_core_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 void amduat_enc_asl1_core_store_u64_be(uint8_t *out, uint64_t value) { + out[0] = (uint8_t)((value >> 56) & 0xffu); + out[1] = (uint8_t)((value >> 48) & 0xffu); + out[2] = (uint8_t)((value >> 40) & 0xffu); + out[3] = (uint8_t)((value >> 32) & 0xffu); + out[4] = (uint8_t)((value >> 24) & 0xffu); + out[5] = (uint8_t)((value >> 16) & 0xffu); + out[6] = (uint8_t)((value >> 8) & 0xffu); + out[7] = (uint8_t)(value & 0xffu); +} + +static uint16_t amduat_enc_asl1_core_load_u16_be(const uint8_t *data) { + return ((uint16_t)data[0] << 8) | (uint16_t)data[1]; +} + +static uint32_t amduat_enc_asl1_core_load_u32_be(const uint8_t *data) { + return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | + ((uint32_t)data[2] << 8) | (uint32_t)data[3]; +} + +static uint64_t amduat_enc_asl1_core_load_u64_be(const uint8_t *data) { + return ((uint64_t)data[0] << 56) | ((uint64_t)data[1] << 48) | + ((uint64_t)data[2] << 40) | ((uint64_t)data[3] << 32) | + ((uint64_t)data[4] << 24) | ((uint64_t)data[5] << 16) | + ((uint64_t)data[6] << 8) | (uint64_t)data[7]; +} + +bool amduat_enc_asl1_core_encode_artifact_v1( + amduat_artifact_t artifact, + amduat_octets_t *out_bytes) { + size_t header_len; + size_t total_len; + size_t offset; + uint8_t *buffer; + + if (out_bytes == NULL) { + return false; + } + out_bytes->data = NULL; + out_bytes->len = 0; + + if (artifact.bytes.len != 0 && artifact.bytes.data == NULL) { + return false; + } + if (artifact.bytes.len > UINT64_MAX) { + return false; + } + + header_len = AMDUAT_ENC_ASL1_CORE_HAS_TAG_LEN + AMDUAT_ENC_ASL1_CORE_LEN_LEN; + if (artifact.has_type_tag) { + header_len += AMDUAT_ENC_ASL1_CORE_TAG_LEN; + } + if (artifact.bytes.len > SIZE_MAX - header_len) { + return false; + } + + total_len = header_len + artifact.bytes.len; + buffer = (uint8_t *)malloc(total_len); + if (buffer == NULL) { + return false; + } + + offset = 0; + buffer[offset++] = artifact.has_type_tag ? 0x01u : 0x00u; + if (artifact.has_type_tag) { + amduat_enc_asl1_core_store_u32_be(buffer + offset, artifact.type_tag.tag_id); + offset += AMDUAT_ENC_ASL1_CORE_TAG_LEN; + } + amduat_enc_asl1_core_store_u64_be(buffer + offset, + (uint64_t)artifact.bytes.len); + offset += AMDUAT_ENC_ASL1_CORE_LEN_LEN; + + if (artifact.bytes.len != 0) { + memcpy(buffer + offset, artifact.bytes.data, artifact.bytes.len); + } + + out_bytes->data = buffer; + out_bytes->len = total_len; + return true; +} + +bool amduat_enc_asl1_core_decode_artifact_v1( + amduat_octets_t bytes, + amduat_artifact_t *out_artifact) { + size_t offset; + uint8_t has_type_tag; + uint32_t tag_id; + uint64_t payload_len_u64; + size_t payload_len; + uint8_t *payload; + + if (out_artifact == NULL) { + return false; + } + if (bytes.len != 0 && bytes.data == NULL) { + return false; + } + if (bytes.len < + AMDUAT_ENC_ASL1_CORE_HAS_TAG_LEN + AMDUAT_ENC_ASL1_CORE_LEN_LEN) { + return false; + } + + offset = 0; + has_type_tag = bytes.data[offset++]; + if (has_type_tag != 0x00u && has_type_tag != 0x01u) { + return false; + } + + tag_id = 0; + if (has_type_tag == 0x01u) { + if (bytes.len < offset + AMDUAT_ENC_ASL1_CORE_TAG_LEN + + AMDUAT_ENC_ASL1_CORE_LEN_LEN) { + return false; + } + tag_id = amduat_enc_asl1_core_load_u32_be(bytes.data + offset); + offset += AMDUAT_ENC_ASL1_CORE_TAG_LEN; + } + + if (bytes.len < offset + AMDUAT_ENC_ASL1_CORE_LEN_LEN) { + return false; + } + payload_len_u64 = amduat_enc_asl1_core_load_u64_be(bytes.data + offset); + offset += AMDUAT_ENC_ASL1_CORE_LEN_LEN; + if (payload_len_u64 > SIZE_MAX) { + return false; + } + payload_len = (size_t)payload_len_u64; + if (bytes.len - offset != payload_len) { + return false; + } + + payload = NULL; + if (payload_len != 0) { + payload = (uint8_t *)malloc(payload_len); + if (payload == NULL) { + return false; + } + memcpy(payload, bytes.data + offset, payload_len); + } + + out_artifact->bytes = amduat_octets(payload, payload_len); + out_artifact->has_type_tag = has_type_tag == 0x01u; + if (out_artifact->has_type_tag) { + out_artifact->type_tag = amduat_type_tag(tag_id); + } else { + out_artifact->type_tag.tag_id = 0; + } + return true; +} + +bool amduat_enc_asl1_core_encode_reference_v1( + amduat_reference_t reference, + amduat_octets_t *out_bytes) { + const amduat_hash_asl1_desc_t *hash_desc; + size_t total_len; + uint8_t *buffer; + + if (out_bytes == NULL) { + return false; + } + out_bytes->data = NULL; + out_bytes->len = 0; + + if (reference.digest.len != 0 && reference.digest.data == NULL) { + return false; + } + + hash_desc = amduat_hash_asl1_desc_lookup(reference.hash_id); + if (hash_desc == NULL || hash_desc->digest_len == 0) { + return false; + } + if (reference.digest.len != hash_desc->digest_len) { + return false; + } + if (hash_desc->digest_len > SIZE_MAX - AMDUAT_ENC_ASL1_CORE_REF_HASH_LEN) { + return false; + } + + total_len = AMDUAT_ENC_ASL1_CORE_REF_HASH_LEN + hash_desc->digest_len; + buffer = (uint8_t *)malloc(total_len); + if (buffer == NULL) { + return false; + } + + amduat_enc_asl1_core_store_u16_be(buffer, reference.hash_id); + memcpy(buffer + AMDUAT_ENC_ASL1_CORE_REF_HASH_LEN, + reference.digest.data, + hash_desc->digest_len); + + out_bytes->data = buffer; + out_bytes->len = total_len; + return true; +} + +bool amduat_enc_asl1_core_decode_reference_v1( + amduat_octets_t bytes, + amduat_reference_t *out_reference) { + const amduat_hash_asl1_desc_t *hash_desc; + amduat_hash_id_t hash_id; + size_t digest_len; + uint8_t *digest; + + if (out_reference == NULL) { + return false; + } + if (bytes.len != 0 && bytes.data == NULL) { + return false; + } + if (bytes.len < AMDUAT_ENC_ASL1_CORE_REF_HASH_LEN) { + return false; + } + + hash_id = (amduat_hash_id_t)amduat_enc_asl1_core_load_u16_be(bytes.data); + hash_desc = amduat_hash_asl1_desc_lookup(hash_id); + if (hash_desc == NULL || hash_desc->digest_len == 0) { + return false; + } + digest_len = hash_desc->digest_len; + if (bytes.len - AMDUAT_ENC_ASL1_CORE_REF_HASH_LEN != digest_len) { + return false; + } + + digest = NULL; + if (digest_len != 0) { + digest = (uint8_t *)malloc(digest_len); + if (digest == NULL) { + return false; + } + memcpy(digest, + bytes.data + AMDUAT_ENC_ASL1_CORE_REF_HASH_LEN, + digest_len); + } + + out_reference->hash_id = hash_id; + out_reference->digest = amduat_octets(digest, digest_len); + return true; +}