4 ms·
Simple, you just check whether the header, data structure, metadata, checksum, etc. in the trial-decrypted data in valid, no hack is needed. For example, someth
by segfaultbuserr 6y ago
Simple, you just check whether the header, data structure, metadata, checksum, etc. in the trial-decrypted data in valid, no hack is needed. For example, something as simple as a 16-byte magic number can ensure a false positive rate of 1/2^128. Since any arbitrary binary data can be encrypted, "this is mostly ASCII" is unusable.
In GPG:
/* if KeyID is empty... */
if (!k->keyid[0] && !k->keyid[1])
{
log_info (_("anonymous recipient; trying secret key %s ...\n"), keystr (keyid));
}
err = get_it (ctrl, k, dek, sk, keyid);
k->result = err;
if (!err)
{
/* If get_it() succeeds */
if (!opt.quiet && !k->keyid[0] && !k->keyid[1])
{
log_info (_("okay, we are the anonymous recipient.\n"));
}
}
And in get_it()...
if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
{
/* Now the frame are the bytes decrypted but padded session key. */
if (!nframe || nframe <= 8
|| frame[nframe-1] > nframe)
{
err = gpg_error (GPG_ERR_WRONG_SECKEY);
goto leave;
}
}
else
{
if (padding)
{
if (n + 7 > nframe)
{
err = gpg_error (GPG_ERR_WRONG_SECKEY);
goto leave;
}
}
if (n + 4 > nframe)
{
err = gpg_error (GPG_ERR_WRONG_SECKEY);
goto leave;
}
if (dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo))
{
err = gpg_error (GPG_ERR_WRONG_SECKEY);
goto leave;
}
/* Copy the key to DEK and compare the checksum. */
csum = buf16_to_u16 (frame+nframe-2);
memcpy (dek->key, frame + n, dek->keylen);
for (csum2 = 0, n = 0; n < dek->keylen; n++)
csum2 += dek->key[n];
if (csum != csum2)
{
err = gpg_error (GPG_ERR_WRONG_SECKEY);
goto leave;
}
}
You get the idea.
BTW, did I just "break GPG encryption and deanonymize users" according to Cellebrite because I found the correct function in the code? And no, I didn't "review dozens of code classes", I just grepped the word "anonymous"... /s
- wool_gather 6y agoAh, I see, I didn't realize there was that much structure to the payload. Thanks!