|
| 1 | +### sqlite3 sqlite3_randomness |
| 2 | + |
| 3 | +As part of the extension, we provide `uuid()` and `gen_random_uuid()` functions, which generate a UUIDv4. We want reasonable guarantees that these uuids are unguessable, so we need to use a [cryptographically secure pseudorandom number generator](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) (CSPRNG). Additionally, we want this to be fast (generating uuids shouldn't be a bottleneck for inserting rows). |
| 4 | + |
| 5 | +We provide two options: |
| 6 | + |
| 7 | +1. The `getrandom` crate, via the `getrandom` feature (enabled by default). |
| 8 | +2. `sqlite3_randomness`, when `getradnom` feature is not enabled. |
| 9 | + |
| 10 | +Everywhere it's available, `getrandom` is recommended. One exception is WASI, where `sqlite3_randomness` is simpler. In that case, make sure the VFS xRandomness function provides secure random values. |
| 11 | + |
| 12 | +## Details |
| 13 | + |
| 14 | +SQLite has a sqlite3_randomness function, that does: |
| 15 | + |
| 16 | +1. Seed using the VFS xRandomness function. |
| 17 | +2. Generate a sequence using ChaCha20 (CSPRNG, as long as the seed is sufficiently random). |
| 18 | + |
| 19 | +The VFS implementations differ: |
| 20 | + |
| 21 | +1. For unix (Linux, macOS, Android and iOS), the default VFS uses `/dev/urandom` for the xRandomness seed above. This is generally secure. |
| 22 | +2. For Windows, the default VFS uses a some system state such as pid, current time, current tick count for the entropy. This is okay for generating random numbers, but not quite secure (may be possible to guess). |
| 23 | +3. For wa-sqlite, it defaults to the unix VFS. Emscripten intercepts the `/dev/urandom` call and provides values using `crypto.getRandomValues()`: https://github.com/emscripten-core/emscripten/blob/2a00e26013b0a02411af09352c6731b89023f382/src/library.js#L2151-L2163 |
| 24 | +4. Dart sqlite3 WASM uses `Random.secure()` to provide values. This is relatively slow, but only for the seed, so that's fine. This translates to `crypto.getRandomValues()` in JS. |
| 25 | + |
| 26 | +### getrandom crate |
| 27 | + |
| 28 | +The Rust uuid crate uses the getrandom crate for the "v4" feature by default. |
| 29 | + |
| 30 | +Full platform support is listed here: https://docs.rs/getrandom/latest/getrandom/ |
| 31 | + |
| 32 | +Summary: |
| 33 | + |
| 34 | +- Linux, Android: getrandom system call if available, falling batch to `/dev/urandom`. |
| 35 | +- Windows: [BCryptGenRandom](https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom) |
| 36 | +- macOS: [getentropy](https://www.unix.com/man-page/mojave/2/getentropy/) |
| 37 | +- iOS: [CCRandomGenerateBytes](https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html) |
| 38 | +- WASI (used for Dart sqlite3 WASM build): [random_get](https://wasix.org/docs/api-reference/wasi/random_get) |
| 39 | + |
| 40 | +The WASI one may be problematic, since that's not provided in all environments. |
0 commit comments