|
34 | 34 | `hashavatar` cannot zeroize those codec-owned buffers. High-assurance |
35 | 35 | deployments should prefer WebP or PNG. |
36 | 36 | - Procedural RNG seeding uses 256 bits from the second half of the identity |
37 | | - digest, separate from the lower digest bytes commonly used for direct visual |
38 | | - parameters. |
| 37 | + digest. Most direct visual parameter lookups use lower digest bytes, but some |
| 38 | + established renderers also use selected upper digest bytes for visible |
| 39 | + geometry. This is accepted for `1.x` visual stability: avatars are |
| 40 | + digest-derived public artifacts, and removing those lookups would change |
| 41 | + golden output. Callers that treat identifiers as sensitive should prefer |
| 42 | + SHA-512 or BLAKE3 over XXH3 and follow the timing/output-size guidance below. |
39 | 43 | - The temporary 256-bit RNG seed copy is stored in `zeroize::Zeroizing`, so the |
40 | 44 | digest-derived seed copy is scrubbed on scope exit. The final value passed to |
41 | 45 | `StdRng::from_seed` is also held in a `Zeroizing` guard before the copy into |
|
53 | 57 | - `AvatarIdentity` has a redacted `Debug` implementation so accidental |
54 | 58 | `{:?}` logging does not print the raw digest. |
55 | 59 | - `AvatarBuilder` has a redacted `Debug` implementation so accidental builder |
56 | | - logging does not print the raw identity input. |
| 60 | + logging does not print the raw identity input, tenant, or style-version |
| 61 | + namespace values. |
57 | 62 | - `AvatarIdentity::cache_key()` derives an opaque display key by hashing the |
58 | 63 | internal identity digest under a cache-key domain instead of returning raw |
59 | 64 | digest bytes. Cache keys are still stable correlators for the same identity |
|
75 | 80 | BLAKE3 hasher and XOF reader after deriving the 64-byte digest. Tests assert |
76 | 81 | these upstream zeroization traits remain available. |
77 | 82 | - Identity hash preimage allocation is sized from the tenant, style-version, |
78 | | - and identity input lengths. The crate bounds and zeroizes those temporary |
79 | | - buffers, but it does not hide input length from the allocator, OS-level heap |
80 | | - profilers, or other same-process memory-observation tools. Very |
81 | | - high-assurance callers that treat identifier length as sensitive should |
82 | | - normalize or pad identifiers to a fixed length before calling this crate. |
| 83 | + and identity input lengths. Debug/test builds assert that preimage buffers do |
| 84 | + not reallocate before zeroization, so future component-size drift is caught by |
| 85 | + CI. The crate bounds and zeroizes those temporary buffers, but it does not |
| 86 | + hide input length from the allocator, OS-level heap profilers, or other |
| 87 | + same-process memory-observation tools. Very high-assurance callers that treat |
| 88 | + identifier length as sensitive should normalize or pad identifiers to a fixed |
| 89 | + length before calling this crate. |
83 | 90 | - The optional XXH3-128 mode derives the crate's 64-byte identity digest by |
84 | 91 | hashing four domain-separated chunks. Each chunk temporarily copies the |
85 | 92 | bounded preimage into a zeroized buffer, so peak preimage memory is higher |
|
93 | 100 | binary must configure and test `getrandom` for their target explicitly. |
94 | 101 | - Encode APIs wrap temporary owned raster buffers in RAII zeroization guards, so |
95 | 102 | pixel data is cleared during normal returns, encoder errors, and unwinding |
96 | | - panics. JPEG export also wraps the temporary RGB flattening buffer in |
| 103 | + panics. Encoded output is accumulated in a `Zeroizing<Vec<u8>>` until |
| 104 | + successful return, so partially encoded bytes are scrubbed on encoder errors. |
| 105 | + JPEG export also wraps the temporary RGB flattening buffer in |
97 | 106 | `zeroize::Zeroizing`. Returned encoded bytes and images returned by render |
98 | 107 | APIs are caller-owned and must be cleared by the caller if their environment |
99 | 108 | requires that. The README includes `zeroize` examples for returned `Vec<u8>` |
|
0 commit comments