Anti-forensics and deniability done right -- can we crowdsource it?

I think there is HUGE demand for it, could it be done properly?

We would need:

  • a way to mount detached luks partitions from dom0 with a separate storage pool on “free” space; (relatively easy, also, thanks to the way Qubes allocates disk it is not suspicious to have lots of “free” space)
  • a way to automatically make VMs residing there available to the app menu while it is mounted and remove it afterwards; (relatively easy)
  • “fully ephemeral DVMs”; (already discussed and in progress)
  • “failsafe firewall” (make sure nothing from deniable partition communicates via clearnet)
  • make this in a way that leaves no trace in dom0, logs and system journal; (HARD, we probably want to rework the whole logging system)
1 Like

Anti-forensics is a non-goal for the Qubes project, so the first thing is to make it a goal. This means it must be clearly understood and then defined technically. The subject is quite complex.

The goal must be feasible. Needs (or desires) are not enough. If not done right, it may have opposite effect by giving false sense of this or that.

Also, the goal must not put the Qubes project and users at risk. Considering how e.g. EU is working to decrypt all E2EE through regulations, having some software which would allow criminals and “criminals” to hide from the all-seeing eye, might be enough to put a black label on Qubes and anyone using it. Think hybrid.

Privacy is not a crime. And we should stand our ground here. What is “activist” in one jurisdiction is a “criminal” or even “terrorist” in another one.

Also, as of now I hardly imagine wide Qubes adoption among career criminals.

1 Like

This is being worked on. Sounds like Shufflecake is the best candidate so far, honestly.

Currently the situation is that in order for the “hidden in plain sight” to be effective, it has to be able to be overwritten by an adversary. Otherwise the plausible deniability doesn’t work. This means that any government with half a brain will present the following ultimatum at every checkpoint:

  1. Declare that it is, in fact, a file, and give yourself up.
    OR
  2. Give your device over, and let me write random data to anything that you have claimed is “free space”.

“Otherwise that laptop isn’t coming through, sir/madam.”

Declare it,or lose it. It’s that simple.

This means that this data has to be something that you’re prepared to sacrifice, or have a backup of somewhere.

Is there a place for this? Definitely. Is it a magic bullet? Sadly,no…

Would be interesting to see how this could be done. You either need to tell dom0 where it is every single time you mount it, or you have to leave some clues in dom0 that there could be “other partitions”…

Well, the simplest solution is to not give them any network access, or access through sys-whonix (or qrexec only, like a template)…

This is going to be the tricky part.

How do you get dom0 to automatically load something that it isn’t supposed to know anything about…?

I suppose you could put some kind of header on the VM stating “DO NOT LOG ME” or something…

If this wasn’t an option, one potential way would be to potentially lock up the entries with some kind of assymetric encryption, with the VM holding the private key. When the VM is not present, the journal entries are just random garbage.

Think “blockchain”-like, but not gimmicky and cringe like so many people have done eslewhere.

Each VM would be able to unlock their own entries on a common journal.

@qubist makes a good point. I’m sure the last thing any of us want is for good intentions to turn into extra scrutiny as soon as they find out you use Qubes OS. There are already countries where border agents are aware of (and probably trained on) Qubes OS

@arkenoi also a valid point.

A very good counterpoint.

This sort of thing most certainly has other applications:

  • keeping corporate information safe if a work machine was ever lost/sold
  • protecting unpatented designs
  • safeguarding unreleased novels
  • journalists safeguarding leaked sources
  • protecting unpublished research papers
  • “my secret diary” about the cute guy/girl I have a crush on
  • (There are definitely many more, but I can’t think of any more right now…)

…but it’s entirely possible that all people would think is “criminal! criminal! criminal! Why would you want to hide something? You’re obviously a criminal!”

This mentality can be contafious and threaten good projects like SecureDrop,

Maybe the reason we think that is because all the ones who were caught were found to be not using Qubes OS :wink:

But seriously, I’d wager there would be a few of them out there.

It’s not terrorism until the enemy’s blood is gloriously spilled. Right now this is a one-way massacre against liberty and privacy and nobody’s doing a god damned fucking thing to stop it.

1 Like

Sure. There is no better way :slight_smile:

A passphrase that decrypts the appropriate metadata and luks header from a “random” data block.

Also, a valid point.

Yes, that’s all well and good, but:

If you tell dom0 it’s there If you do NOT tell dom0 it’s there
This reference will show up on a forensic analysis on the drive You’ll have to do everything manually
Sure, you could potentially claim that “they’re qubes that I deleted a long time ago…”, but still…

An example of something that would make things convenient, but kill plausible deniability:

If you keep encrypted hidden qubes on a separate hidden partition that looks like empty space, but want dom0 to check whether it’s there or not, you first have to instruct dom0 to look for it.

Even the most innocent-looking instructions to look for and mount all qubes “from all partitions present” could potentially ruin plausible deniability.

Unless I’ve missed something? :slight_smile:

This is going to sound either really ingenious or really smooth brained and I’m personally split 50/50 on which, but here it goes:

Develop a custom encryption/obfuscation algorithm that can be implemented in about a page or two of code. It doesn’t have to be at all fancy, but it does need to be unique. Memorize the code to heart, and then delete all code along with any design documents and other R+D. Ensure the algorithm only lives in your head.

Encrypt your LUKS header (and/or any other pieces of data that can identify something as being a partition as opposed to random noise) with your personal algorithm. Make sure that the algorithm code never touches any disks. Use a ramdisk for this (or other RAM-based solutions you can think of). Yes you will have to memorize sector addresses too, but one could instead certainly think of ways to hide those “in plain sight”.

Voila now your whole disk is random noise. Don’t forget to re-encrypt the data before you leave for the border checkpoint (duh).

“Enkripshuhn? What is that? No madam, I just installed this cubes system thingy I found on the internet. They said it was super secure from hackermans, so feel free to check” :man_shrugging:

:ok_hand::policewoman::checkered_flag:

Of course this is all theory, and I have a feeling it’d be a pain in the :peach: to implement in Qubes.

The detached header may reside in a deniable data block that exists in any installation. Once properly initialized, you can use PBKDF to extract metadata from there. If the passphrase does not match, you just get garbage on decrypt. There could be more than one. There could be none. The opponent should not have means to find out.

Ensure the algorithm only lives in your head.

There are advanced hacks for that too. (chemical etc)
Consider also that human memory is not perfect, even for simple things.

1 Like

The honest truth is that you definitely have good methodology and logical thinking, but a few little things will get in the way. And I really do mean this as a compliment :slight_smile:.

But I’ll explain why this wouldn’t even get to step 1 (in it’s current form):

In cryptography, the best algorithms are the ones that everyone knows, but still can’t break.

That’s more or less why AES (Rijndael), RSA, Diffie-Hellmann, Kyber and Dilithium are all standardised. Because everyone knows exactly how they work, and people still can’t break them :slight_smile:

“Security through obscurity” will only get you so far (and I can promise you that they show patterns much more often that cryptographers would easily pick up on) :frowning:

Uniqueness isn’t the issue, it’s predictability.

Sure, it might fool those automated boxes at border checkpoints that customs officers might plug your drive into, that try the most common methods first…

…but give it to a cryptographer, and they may well be able to see right through your obfuscation… :laughing:

Ok, and how do you get it into the computer so that you can decrypt stuff? :laughing:

In order for the computer to be able to decrypt your stuff, it has to have readily available:

  • The decryption key
  • The algorithm

These are usually stored in RAM while the computer is on. (And yes, if you know where to look, you can get them in a RAM dump) :frowning:

Encrypt it with what? How does the computer know how to decrypt it if you’re not going to tell it the algorithm?

If you don’t decrypt the header, then the BIOS will likely say “No bootable device found” unless it knows that it’s a LUKS device.

This is what a LUKS header looks like:

LUKS header information for /dev/sdb

Version:        1
Cipher name:    aes
Cipher mode:    xts-plain64
Hash spec:      sha512
Payload offset: 4096
MK bits:        512
MK digest:      a5 2b 28 28 65 1b 72 47 b6 5e 13 03 53 d1 21 58 16 16 01 0e
MK salt:        2d 69 3a 58 a0 05 43 d4 c6 b3 12 fb 93 21 a1 0a
                3d 35 78 59 a6 48 48 e3 8c 8c 4a 27 93 ec a1 d6
MK iterations:  63750
UUID:           ecbc1d41-d1b6-4fc1-b2f0-7688c93cdc45

Key Slot 0: ENABLED
        Iterations:             2582695
        Salt:                   ab f9 18 8b 35 f9 f0 d6 fe a2 82 0a 08 1d 18 d9
                                b4 de 02 d8 71 8a a6 00 54 04 65 c5 75 66 91 8b
        Key material offset:    8
        AF stripes:             4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

All of this information is in plaintext. It has to be for LUKS to actually function…

So, you either have to detach the header (put it on another device that is only present at boot), or write some kind of code somewhere (initramfs, external block device, a remote server, etc.) that can tell the computer the algorithm needed to decrypt it, and put it somewhere the CPU can access it and understand it.

Also, for completeness, this header stays in RAM while the computer is on, even if you remove the detached header once you’ve booted. That’s how the CPU is able to keep track of where everything is among the cipherblocks on the drive.

Sources:
LUKS1 Specification v1.2.3
LUKS2 Specification v1.0.0

Ok, but where does the ramdisk come from? Does this mean that you’d have to compile the algorithm module from your brain straight to RAM every time you turn your computer on?

If you can do that, that is absolutely incredible, but I certainly do not have that kind of brain power. And even if I did, I might do it once or twice, and then it would become tedious… :stuck_out_tongue:

So basically you’d be decrypting every single byte/block manually, one by one, in your head? A LUKS header can be ~16MiB in length, or more.

That’s a lot of bytes to do manually… :frowning:

So, you want to put the header for the volume inside the cipher…?

You end up with the same chicken-and-egg problem as you do with the detached headers:

  • You can’t decrypt the drive without decrypting the headers
  • You can’t decrypt the headers without decrypting the drive

It would confuse the heck out of anyone analysing the drive, but it would likely prevent you from using it, too :frowning:


Detached headers already reasonably solve this problem.

You can have an internal hard drive that is seemingly full of random garbage, and the headers somewhere else (SD card, USB stick, remote server, RFID card, YubiKey, NFC reader, embedded in device firmware somewhere, TPM, etc.).

The detached header would often also include the boot partition(s).
A hard drive that is full of random garbage except for a boot partition would look very suspicious :rofl:.

LUKS logical volumes are interweaved with each other, as opposed to other filesystems where they will sequentially write to blocks next to each other, which makes it harder to tell which blocks belong to which partitions/volumes, let alone which individual files.


Like I said, I really do like the idea, but it needs a lot of work before it’s actually feasible :slight_smile:

I can see this method working for small files, but anything bigger than a few kilobytes would likely be beyond usability :frowning:

My idea is that dom0 always has a file on fs which may or may not contain encrypted volume headers.

I like that idea. So headers for a hidden volume other than the volume it’s located in, right?

You’ve basically described Shufflecake :slight_smile:

Of the whole topic, I only object on this - is this claim provable? If not, I’d edit my post to delete this (aren’t devs already “listening” their user and poll them from time to time?), so the rest of the topic would may seem non-frivolous. Otherwise, very interesting topic, although I think Qubes-Air would resolve many of similar issues, and the needs accordingly.