Files
Linehu ba16217afe feat: U3 @sealed optional segment marking - phase 2 complete
- UTSM_SEG_F_UNSEALED: plaintext direct-store segments (zero crypto overhead) while keeping capability checks, dirty tracking, intent/commit log and seqlock protocol; default remains sealed
- linker.ld: .sealed output section with __sealed_start/__sealed_end symbols for future static sealed data
- selftest: unsealed segment stores plaintext verifiably + read-back, full SELFTEST PASS (.build_tmp/qemu_serial_u3sealed.log)
- phase 2 (UTSM/UTRW) now complete in ROADMAP_INSANE
2026-10-02 15:30:25 +08:00

76 lines
2.5 KiB
C

#include <utsm/utrw.h>
#include <utsm/segment.h>
#include <utsm/pckc.h>
#include <utsm/crypto.h>
#include <utsm/config.h>
#include <utsm/drr.h>
void *memcpy(void *dst, const void *src, usize len);
int utsm_write(utsm_capability cap, u64 offset, const void *src, u64 len) {
if (!src && len != 0) {
return UTSM_ERR_INVALID;
}
if (len == 0) {
return UTSM_OK;
}
utsm_segment_desc *desc = NULL;
int status = utsm_cap_validate(cap, UTSM_RIGHT_WRITE, offset, len, &desc);
if (status != UTSM_OK) {
return status;
}
/* U3: @unsealed 段 —— 明文直存,0 加解密开销;dirty/seqlock/log 照走,
* checkpoint 路径对明文页同样适用(页 MAC 语义由 DRR 侧统一处理)。 */
if (desc->flags & UTSM_SEG_F_UNSEALED) {
drr_log_write_intent(cap.segment_slot, offset, len);
desc->writer_seq++;
memcpy(desc->cipher_base + offset, src, len);
utsm_mark_dirty(desc, offset, len);
desc->writer_seq++;
drr_log_write_commit(cap.segment_slot, offset, len);
return UTSM_OK;
}
utsm_key_material key;
status = utsm_pckc_get_or_derive(cap.segment_slot, desc, &key);
if (status != UTSM_OK) {
return status;
}
drr_log_write_intent(cap.segment_slot, offset, len);
desc->writer_seq++;
u8 line_plain[UTSM_CACHE_LINE_SIZE];
u8 line_cipher[UTSM_CACHE_LINE_SIZE];
u64 written = 0;
while (written < len) {
u64 absolute = offset + written;
u64 line_start = (absolute / UTSM_CACHE_LINE_SIZE) * UTSM_CACHE_LINE_SIZE;
u64 in_line = absolute - line_start;
u64 chunk = UTSM_CACHE_LINE_SIZE - in_line;
if (chunk > len - written) {
chunk = len - written;
}
u64 line_index = line_start / UTSM_CACHE_LINE_SIZE;
u64 tweak = utsm_make_tweak(desc->tweak_seed, line_index, desc->key_epoch);
if (chunk == UTSM_CACHE_LINE_SIZE && in_line == 0) {
memcpy(line_plain, (const u8 *)src + written, UTSM_CACHE_LINE_SIZE);
} else {
utsm_crypt_line(&key, tweak, desc->cipher_base + line_start, line_plain);
memcpy(line_plain + in_line, (const u8 *)src + written, chunk);
}
utsm_crypt_line(&key, tweak, line_plain, line_cipher);
memcpy(desc->cipher_base + line_start, line_cipher, UTSM_CACHE_LINE_SIZE);
written += chunk;
}
utsm_mark_dirty(desc, offset, len);
desc->writer_seq++;
drr_log_write_commit(cap.segment_slot, offset, len);
return UTSM_OK;
}