nilaoda/N_m3u8DL-RE · error · ArgumentNullException
Key is null
Error message
Key is null
What it means
CSChaCha20.KeySetup validates the ChaCha20 key before initializing the cipher state. A null key is rejected with ArgumentNullException("Key is null"). This runs during ChaCha20 construction for every decryption using this class.
Solutions
- Check key != null before constructing the ChaCha20 cipher.
- Ensure the key-extraction/parse step succeeded and produced a byte[].
- Fail fast with a clear message upstream if the key is unavailable instead of passing null.
- In tests, assert keys are non-null before invoking decryption paths.
Example fix
// before
var cipher = new CSChaCha20(keyBytes, nonce, counter);
// after
if (keyBytes == null) throw new InvalidOperationException("decryption key missing");
var cipher = new CSChaCha20(keyBytes, nonce, counter); Defensive patterns
Strategy: type-guard
Validate before calling
if (keyBytes == null || keyBytes.Length == 0) throw new InvalidOperationException("no decryption key available"); Type guard
bool HasKey(byte[] k) => k is { Length: 32 }; Try / catch
try { new CSChaCha20(key, nonce, 0); }
catch (ArgumentNullException) { /* key missing — abort decryption */ } Prevention
- Check that key extraction succeeded before constructing the cipher.
- Never pass through a nullable key without a null check.
- Fail early with a clear message when the key option is absent.
When it happens
Trigger: Constructing CSChaCha20 (via the ChaCha20 entry) with key == null, typically when a key extraction step returned null (failed base64/hex decode, missing DRM key) and the null was passed through unchecked.
Common situations: A earlier parse step failed silently and returned null key bytes; config where the key option was omitted but decryption was still requested; tests passing null deliberately.
Related errors
- Nonce is null
- Key length must be . Actual
- Nonce length must be
- Key must be 32 bytes!
- Key must be 12 or 8 bytes!
AI-assisted analysis of nilaoda/N_m3u8DL-RE@e113dee70c (2026-09-13).
Data as JSON: /api/errors/a1c7dbf9817c4239.
Report an issue: GitHub.
Appendix: source
Thrown at src/N_m3u8DL-RE/Crypto/CSChaCha20.cs:125
}
// These are the same constants defined in the reference implementation.
// http://cr.yp.to/streamciphers/timings/estreambench/submissions/salsa20/chacha8/ref/chacha.c
private static readonly byte[] sigma = Encoding.ASCII.GetBytes("expand 32-byte k");
private static readonly byte[] tau = Encoding.ASCII.GetBytes("expand 16-byte k");
/// <summary>
/// Set up the ChaCha state with the given key. A 32-byte key is required and enforced.
/// </summary>
/// <param name="key">
/// A 32-byte (256-bit) key, treated as a concatenation of eight 32-bit little-endian integers
/// </param>
private void KeySetup(byte[] key)
{
if (key == null)
{
throw new ArgumentNullException("Key is null");
}
if (key.Length != allowedKeyLength)
{
throw new ArgumentException($"Key length must be {allowedKeyLength}. Actual: {key.Length}");
}
state[4] = Util.U8To32Little(key, 0);
state[5] = Util.U8To32Little(key, 4);
state[6] = Util.U8To32Little(key, 8);
state[7] = Util.U8To32Little(key, 12);
byte[] constants = (key.Length == allowedKeyLength) ? sigma : tau;
int keyIndex = key.Length - 16;
state[8] = Util.U8To32Little(key, keyIndex + 0);
state[9] = Util.U8To32Little(key, keyIndex + 4);
state[10] = Util.U8To32Little(key, keyIndex + 8);View on GitHub (pinned to e113dee70c)