peass-ng/PEASS-ng · error · ArgumentException

Personalization length must be exactly 8 bytes

Error message

Personalization length must be exactly 8 bytes

What it means

Blake2s reserves exactly 8 bytes for the personalization field in its parameter block. When a non-null personalization is supplied, the constructor requires it to be exactly 8 bytes and throws ArgumentException otherwise.

Source

Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/crypto/digests/Blake2sDigest.cs:227

        {
            if (digestBytes < 1 || digestBytes > 32)
                throw new ArgumentException("Invalid digest length (required: 1 - 32)");

            this.digestLength = digestBytes;
            this.buffer = new byte[BLOCK_LENGTH_BYTES];

            if (salt != null)
            {
                if (salt.Length != 8)
                    throw new ArgumentException("Salt length must be exactly 8 bytes");

                this.salt = new byte[8];
                Array.Copy(salt, 0, this.salt, 0, salt.Length);
            }
            if (personalization != null)
            {
                if (personalization.Length != 8)
                    throw new ArgumentException("Personalization length must be exactly 8 bytes");

                this.personalization = new byte[8];
                Array.Copy(personalization, 0, this.personalization, 0, personalization.Length);
            }
            if (key != null)
            {
                if (key.Length > 32)
                    throw new ArgumentException("Keys > 32 bytes are not supported");

                this.key = new byte[key.Length];
                Array.Copy(key, 0, this.key, 0, key.Length);

                keyLength = key.Length;
                Array.Copy(key, 0, buffer, 0, key.Length);
                bufferPos = BLOCK_LENGTH_BYTES; // zero padding
            }
            Init();
        }

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Encode the personalization context and truncate or zero-pad it to exactly 8 bytes before passing it.
  2. Pass null to leave the personalization field zeroed.
  3. Centralize creation of the 8-byte personalization block in one helper so callers cannot pass raw strings.

Example fix

// before
var digest = new Blake2sDigest(null, 32, null, Encoding.UTF8.GetBytes("MyApplication"));
// after
byte[] p = new byte[8];
byte[] raw = Encoding.UTF8.GetBytes("MyApp");
Array.Copy(raw, p, Math.Min(raw.Length, 8));
var digest = new Blake2sDigest(null, 32, null, p);
Defensive patterns

Strategy: validation

Validate before calling

if (personalization != null && personalization.Length != 8)
    throw new ArgumentException("Blake2s personalization must be exactly 8 bytes");
var digest = new Blake2sDigest(key, 32, salt, personalization);

Type guard

static bool IsValidPersonalization(byte[] p) => p == null || p.Length == 8;

Try / catch

try { var d = new Blake2sDigest(key, 32, salt, personalization); }
catch (ArgumentException ex) { /* zero-pad context to 8 bytes */ }

Prevention

When it happens

Trigger: Calling new Blake2sDigest(key, digestBytes, salt, personalization) with personalization.Length != 8 — e.g. an application name/domain string of arbitrary length, an empty array, or a longer context string.

Common situations: Passing a domain or app-name string directly ("myapp" = 5 bytes, or UTF-8 of a long product name) instead of a fixed 8-byte context identifier; padding mistakes when porting between Blake2 variants.

Related errors


AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02). Data as JSON: /api/errors/09be22a13d1f8b79. Report an issue: GitHub.