first commit
This commit is contained in:
86
docs/security-stack/security/tpm-struct/src/buffer/buffer.md
Normal file
86
docs/security-stack/security/tpm-struct/src/buffer/buffer.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# `buffer` — TPM 2.0 octet-stream reader and writer
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
The `buffer` module provides the lowest layer of `@suaveplan/tpm-struct`: a
|
||||
strictly-bounded, big-endian byte reader (`TpmBufferReader`) and a matching
|
||||
growing-array writer (`TpmBufferWriter`) shaped to the TCG TPM 2.0 Library
|
||||
Part 2 §10.1 octet-stream conventions. Every higher-level parser in the
|
||||
package (the `TPMS_ATTEST` decoder, the `TPMT_PUBLIC` decoder, the name
|
||||
serialiser) builds on these primitives, which is why they receive their
|
||||
own subpath export. Keeping bounds enforcement, big-endian semantics, and
|
||||
the `TPM2B_*` size-prefix protocol in one place means the rest of the
|
||||
package can be written as straight-line code without per-field bounds
|
||||
checks or accidental little-endian reads.
|
||||
|
||||
## Features
|
||||
|
||||
- Big-endian readers for UINT8/16/32/64 (the 64-bit form returns a
|
||||
`bigint` so it never silently truncates).
|
||||
- `TPM2B_*` size-prefix reader and writer (UINT16 length + payload).
|
||||
- Cursor-stable error path: out-of-bounds reads raise
|
||||
`TpmStructError(TPM_STRUCT.TRUNCATED)` carrying `cursor` and `requested`
|
||||
on the cause chain so log adapters can format the failure.
|
||||
- `assertEnd()` rejects trailing bytes — guards against silent length
|
||||
drift between the wire format and consumers.
|
||||
- Constant-time-safe `peek(n)` (no advancing, never throws on clip).
|
||||
- Growing writer with geometric reallocation hint via `initialCapacity`.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { TpmBufferReader } from "@suaveplan/tpm-struct/buffer";
|
||||
|
||||
const reader = new TpmBufferReader(new Uint8Array([0x00, 0x04, 0xde, 0xad, 0xbe, 0xef]));
|
||||
const payload = reader.readTpm2b(); // Uint8Array[0xde, 0xad, 0xbe, 0xef]
|
||||
reader.assertEnd();
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { TpmBufferReader, TpmBufferWriter } from "@suaveplan/tpm-struct/buffer";
|
||||
|
||||
// Encode then decode an arbitrary TPMS_CLOCK_INFO substructure.
|
||||
const w = new TpmBufferWriter({ initialCapacity: 17 });
|
||||
w.writeUint64Be(100n); // clock
|
||||
w.writeUint32Be(5); // resetCount
|
||||
w.writeUint32Be(3); // restartCount
|
||||
w.writeUint8(1); // safe = true
|
||||
const bytes = w.toUint8Array();
|
||||
|
||||
const r = new TpmBufferReader(bytes);
|
||||
const clock = r.readUint64Be();
|
||||
const reset = r.readUint32Be();
|
||||
const restart = r.readUint32Be();
|
||||
const safe = r.readUint8() !== 0;
|
||||
r.assertEnd();
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- **`new TpmBufferReader(bytes, { cursor? })`** — construct over a
|
||||
`Uint8Array`. Out-of-range `cursor` raises `TPM_STRUCT.TRUNCATED`.
|
||||
- **`readUint8 / readUint16Be / readUint32Be`** — return `number`.
|
||||
- **`readUint64Be()`** — returns `bigint`.
|
||||
- **`readBytes(n)`** — returns a fresh `Uint8Array` copy (never aliases).
|
||||
- **`readTpm2b()`** / **`readTpm2bWithSize()`** — TCG `TPM2B_*` size-prefix.
|
||||
- **`peek(n)` / `remaining()` / `cursor()` / `assertEnd()`** — read-only
|
||||
introspection.
|
||||
- **`new TpmBufferWriter({ initialCapacity? })`** — growing writer.
|
||||
- **`writeUint8 / 16Be / 32Be / 64Be / Bytes / Tpm2b`** — mirror writes.
|
||||
- **`toUint8Array()`** — finalise into a fresh `Uint8Array`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The reader holds a single `DataView` over the supplied `Uint8Array`'s
|
||||
backing buffer and advances a private cursor by the exact bytes consumed.
|
||||
`readTpm2b` rewinds the cursor to the start of the size prefix on a
|
||||
short-read failure so callers can produce diagnostic dumps from the
|
||||
failing position. The writer grows its backing array by powers of two
|
||||
starting at `initialCapacity` (default 256) and reuses the same buffer
|
||||
across writes. Numeric range checks reject out-of-range writes at the
|
||||
boundary — this is cheaper than letting `DataView` truncate silently.
|
||||
Reference in New Issue
Block a user