camera-trng/README.md

206 lines
6.8 KiB
Markdown

# Camera TRNG
> **[Read the Research & Science Behind This](RESEARCH.md)** — A deep dive into the physics, academic literature, and the LavaRnd approach.
A true random number generator that extracts entropy from camera sensor thermal noise, following the LavaRnd methodology.
## Setup Requirements
**Important**: Cover the camera lens for optimal operation.
1. **Cover the lens**: Use the lens cap, opaque tape, or place the camera in a light-proof enclosure
2. **Verify darkness**: The camera should capture pure black frames
3. **Run the service**: Gain and brightness are automatically maximized
This approach (pioneered by the LavaRnd project) isolates pure thermal noise from the sensor, eliminating any scene-correlated data and providing a simpler security model.
## How It Works
With the lens covered, camera sensors produce noise from thermal electron activity and dark current. This service:
1. Opens the camera and maximizes gain/brightness settings
2. Captures frames of pure sensor noise (no light = no scene data)
3. Extracts the 2 LSBs from each pixel (highest entropy density)
4. Hashes the LSBs with SHA-256 to condition the output
5. Mixes in timing entropy for additional randomness
## Build
```bash
cargo build --release
```
## Run
```bash
./target/release/camera-trng
# Or set a custom port
PORT=9000 ./target/release/camera-trng
```
## Docker
Pull the pre-built image:
```bash
docker pull git.nixc.us/colin/camera-trng:latest
```
Run with camera access (Linux with V4L2):
```bash
docker run -d \
--name camera-trng \
--device /dev/video0:/dev/video0 \
-p 8787:8787 \
git.nixc.us/colin/camera-trng:latest
```
**Note**: Ensure the camera lens is covered before starting the container.
### Available Tags
| Tag | Description |
|-----|-------------|
| `latest` | Latest build from master branch |
| `<commit-sha>` | Specific commit (first 8 chars) |
| `<version>` | Semantic version tags (e.g., `v1.0.0`) |
## API
### GET /random
Returns random bytes from camera thermal noise.
**Query Parameters:**
- `bytes` - Number of bytes to return (default: 32, max: 1024)
- `hex` - Return as hex string instead of raw bytes (default: false)
**Examples:**
```bash
# Get 32 random bytes as hex
curl "http://localhost:8787/random?hex=true"
# Get 64 raw random bytes
curl "http://localhost:8787/random?bytes=64" -o random.bin
# Get 256 bytes as hex
curl "http://localhost:8787/random?bytes=256&hex=true"
```
### GET /health
Returns `ok` if the server is running.
## Rate Limiting
- Maximum 4 concurrent requests
- Maximum 1024 bytes per request
- Returns 429 Too Many Requests when overloaded
## Cross-Platform Support
Uses `nokhwa` for camera access, supporting:
- macOS (AVFoundation)
- Windows (Media Foundation)
- Linux (V4L2)
## CI/CD Pipeline
This project uses Woodpecker CI to automatically build, test, and deploy.
### Pipeline Overview
```
┌─────────────────────────────────────────────────────────────────┐
│ Woodpecker CI │
├─────────────────────────────────────────────────────────────────┤
│ │
│ On Push/PR to master: │
│ ┌─────────┐ │
│ │ test │──┬──> build-linux-x86_64 ──> binary artifact │
│ └─────────┘ │ │
│ ├──> build-linux-aarch64 ──> binary artifact │
│ │ │
│ └──> build-image ──┬──> trivy-image (scan) │
│ └──> sbom-image (SBOM) │
│ │
│ Parallel checks: cargo-audit, trivy-fs, clippy, fmt-check │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Build Artifacts
| Artifact | Architecture | Description |
|----------|--------------|-------------|
| `camera-trng-linux-x86_64` | x86_64 | Linux AMD64 binary |
| `camera-trng-linux-aarch64` | aarch64 | Linux ARM64 binary (best-effort) |
| Docker Image | linux/amd64 | Container image |
### Docker Image Registry
Images are pushed to: `git.nixc.us/colin/camera-trng`
- **On push to master**: Tags `latest` and `<commit-sha>`
- **On version tag**: Tags `<version>` and `latest`
### Required Secrets
Configure these secrets in Woodpecker:
| Secret | Description |
|--------|-------------|
| `REGISTRY_USER` | Username for git.nixc.us registry |
| `REGISTRY_PASSWORD` | Password/token for git.nixc.us registry |
| `DOCKER_REGISTRY_USER` | Docker Hub username (for base images) |
| `DOCKER_REGISTRY_PASSWORD` | Docker Hub password/token |
### Security Scanning
The pipeline includes:
- **cargo-audit**: Scans Rust dependencies for known vulnerabilities
- **trivy-fs**: Scans filesystem and Cargo.lock for vulnerabilities
- **trivy-image**: Scans the built Docker image
- **SBOM generation**: Creates SPDX and CycloneDX SBOMs for dependencies
### Cross-Compilation Notes
**Linux x86_64**: Fully supported, built natively on CI runners.
**Linux aarch64**: Best-effort cross-compilation. May fail due to native camera library dependencies (libv4l). For production ARM64 builds, consider using native ARM64 runners.
**macOS/Windows**: Not built in CI due to native camera library requirements. Build locally:
```bash
# macOS
cargo build --release
# Windows (requires MSVC toolchain)
cargo build --release
```
### Local Docker Build
```bash
# Build locally
docker build -t camera-trng:local .
# Test locally (requires camera device with lens covered)
docker run --rm --device /dev/video0 -p 8787:8787 camera-trng:local
```
## Security Notes
This implementation follows the LavaRnd approach for thermal noise extraction:
- **Cover the lens**: Required for the intended security model
- **Gain maximized**: Software automatically configures camera for maximum noise amplification
- **No scene data**: With lens covered, there is no side-channel information leakage
- **SHA-256 conditioning**: Removes any bias and ensures uniform distribution
For high-security cryptographic applications, consider:
- Using dedicated hardware RNGs (HSMs)
- Mixing with system entropy (`/dev/urandom`)
- Verifying the camera is properly covered before deployment