3 Commits

Author SHA1 Message Date
6056492128 tasks: mark vault/osrng-iv-generation completed 2026-06-23 13:12:10 +00:00
3a48b11e8b vault: use OsRng for AES-GCM IV and salt generation (task: vault/osrng-iv-generation)
Drift item #1: replace rand::random() thread-local RNG with rand::rngs::OsRng
CSPRNG for security-critical IV (12-byte GCM nonce) and salt (32-byte) generation.

Refs: docs/architecture/crates/vault/README.md drift #1
Implements: ADR-020
2026-06-23 13:11:42 +00:00
f43246b978 vault: use OsRng for AES-GCM IV and salt generation
Replace rand::random() with rand::rngs::OsRng for cryptographic nonce
and salt generation in encryption.rs. rand::random() uses thread-local
RNG which may not be a CSPRNG on all platforms; OsRng reads from the
OS entropy source, preventing catastrophic IV reuse under AES-GCM.

Drift item #1 (security-critical).
2026-06-23 13:09:07 +00:00
2 changed files with 11 additions and 5 deletions

View File

@@ -37,6 +37,7 @@ use aes_gcm::{
aead::{Aead, KeyInit},
Aes256Gcm, Nonce,
};
use rand::{rngs::OsRng, RngCore};
use serde::{Deserialize, Serialize};
use zeroize::Zeroize;
@@ -129,12 +130,14 @@ pub fn encrypt(plaintext: &str, key: &EncryptionKey) -> Result<EncryptedData, En
let cipher = Aes256Gcm::new_from_slice(&key.key_bytes)
.map_err(|e| EncryptionError::Encryption(format!("invalid key length: {e}")))?;
// Generate random IV (12 bytes for AES-GCM)
let iv_bytes: [u8; 12] = rand::random();
// Generate random IV (12 bytes for AES-GCM) using OsRng CSPRNG
let mut iv_bytes = [0u8; 12];
OsRng.fill_bytes(&mut iv_bytes);
let nonce = Nonce::from_slice(&iv_bytes);
// TODO(Phase B): Use salt in HKDF-based key derivation
let salt_bytes: [u8; 32] = rand::random();
let mut salt_bytes = [0u8; 32];
OsRng.fill_bytes(&mut salt_bytes);
let ciphertext = cipher
.encrypt(nonce, plaintext.as_bytes())

View File

@@ -1,7 +1,7 @@
---
id: vault/osrng-iv-generation
name: Replace rand::random() IV generation with OsRng in AES-GCM encryption
status: pending
status: completed
depends_on: []
scope: single
risk: medium
@@ -80,4 +80,7 @@ This task touches only `encryption.rs`. It does not depend on the irpc removal
## Summary
> To be filled on completion
Replaced `rand::random()` with `rand::rngs::OsRng` (`RngCore::fill_bytes`) for
both the 12-byte AES-GCM IV and the 32-byte salt in `encryption::encrypt()`.
Existing tests cover IV-freshness (`test_encrypted_data_has_different_iv_each_time`)
and round-trip (`test_encrypt_decrypt_round_trip`). Merged to develop as f43246b.