Orthrus dramatically simplifies the problems of providing a securely encrypted data store. There are no passwords or key material to manage. The act of pairing two cards together automatically creates all of the key material necessary to secure the store without any human action (other than initiating the paring process by pressing and holding a single button). The security offered by Orthrus is simple to explain and trivial to use. It's simply that if you have both of the cards, you have the data. If you have only one of them, then it is cryptographically opaque.
The first block of each card is reserved as a key storage block. The size of the volume reported to the USB host is determined by taking the smaller of the two card sizes, subtracting one and doubling that. The first block on each card contains a structure with the following:
- A magic constant compiled into the firmware to identify the card as belonging to an Orthrus volume.
- A flag bit identifying the card as either the "A" or "B" card (the cards can be inserted in either order and it should still work).
- A 64 byte volume ID.
- A 32 byte card key value.
- A 16 byte nonce value for the block tweaking (of which 12 bytes are used).
When the device is initialized (either when its inserted into a host with two cards already installed or when the second card is inserted), each of the key blocks is checked. If the magic value is wrong, or if the two volume ID values don't match or if there isn't one "A" and one "B" card, then the error light is turned on and the volume isn't mounted. This prevents cards inserted mistakenly from being corrupted. To bootstrap, there's a button on the board. If the button is pushed while the error light is on, then the two key blocks are initialized and the device made ready.
If the pre-initialization checks succeed, then the two card key values are shuffled together (in "A" "B" order) to make a 64 byte buffer. The two halves of this shuffled data is fed through AES CMAC with an all-zero key, with the two results concatenated together. The result of that becomes the new AES key and the CMAC is run over the two halves of the volume ID, again, with the two results concatenated together. The result of that becomes the AES key for the volume. At that point, the drive is ready.
To read and write individual blocks, AES XEX mode is used. The incoming block number in the request is translated by using the LSB to select either the "A" or "B" card. The rest of the block number is right-shifted once and 1 is added to make the physical block number for the card. The XEX mode uses a 16 byte nonce. The nonce consists of the first 12 bytes of the nonce value stored on the opposite card from the one being read or written, concatenated with the (logical) block number. The nonce is encrypted with the volume key to form the first "tweak" block. For each 16 byte AES block of the disk sector, the plaintext is XORed with the tweak block, then encrypted with AES ECB mode, then XORed again with the tweak block to form the ciphertext. Decryption is the same, except that an AES ECB decryption operation is performed in the middle (the tweak is still formed with an ECB encryption). After each block is processed, the tweak block is transformed into a new tweak block by multiplying it by 2 within a Galois Field of 2^128 (I confess I don't really understand GF math properly - I just read a bunch of examples and pseudocode on the net) and then is ready for the next 16 byte block.
In an earlier iteration of Orthrus, AES counter mode was used, which allowed us to precompute the cipher stream bytes for XORing with the card data, but counter mode has some cryptographic weaknesses that make up for the speed advantage that background precomputation affords. XEX mode can't be precomputed, and unfortunately gives us a 33% speed penalty, but is the mode used almost universally for whole-disk encryption (most implementations actually use XTS, but if the sector size is divisible by the encryption block size, then the two are the same).
To initialize a card, 160 bytes of random data is needed for a full key generation - 64 bytes for a volume ID, 32 bytes for the key block for each card, and finally 16 bytes (of which only 12 is used) for each card nonce value. The controller has a built in true random number generator (TRNG) that can be used for this purpose.
If the button is pushed while the volume is mounted (or while unpaired cards are inserted), then the error light will begin blinking. If the button is released then nothing will happen, but if the button is held for 5 seconds, the error light stops blinking and the volume is forcibly unmounted, re-keyed and then re-mounted. The host sees a new disk filled with random garbage. The previous content of the volume is irretrievably lost.
The v3.0 hardware is centered around an ATSAMS70N19. It's an ARM processor with high speed (480 mb/sec) USB and a 4 bit transfer SD card (HSMCI) interface. It also has AES hardware acceleration built in and a true random number generator (it has a lot more than that, but that's all we need).
The v2 hardware was using SPI at 16 MHz for a theoretical raw throughput of 2 MB/sec, but given that SPI had some inter-byte gaps, that resulted in lower throughput. But what really killed things was interspersing AES operations. Even with them happening in hardware, they had to be serialized for XEX mode. On top of that, full speed USB has a theoretical limit of 1.5 MB/sec, but you rarely get even close to the theoretical max transfer for USB. For v3, HSMCI will be able to run at 50 MHz, which is a theoretical transfer rate of 25 MB/sec. The theoretical USB transfer rate is 60 MB/sec, so it should be able to keep up without any difficulty. The speed limitations that remain are those imposed by the encryption, plus the fact that we are limited to single block I/O operations on the cards because of the requirement for interleaving access.
Unfortunately, the HSMCI interface can only talk to a single card. We need to use a mechanism to switch it between two slots. The solution is the QS3VH257PAG8 bus multiplex chip. It's effectively a 4 bit bidirectional A/B switch. Unfortunately we need to switch 6 signals, so we need two of them, but it turns out that the pins for the HSMCI interface are in two groups on opposite sides of the controller chip, so from a layout perspective it's not so bad.
As with the v2 hardware, we have a GPIO pin acting as a power switch for the card power supply, and we have two more GPIOs acting on the bus switches - an enable pin (holding it high will disconnect both cards from the bus - we can use this to sequence power-up) and an !A/B signal to select which card to use. The power switch signal is connected to the gate of a P-channel MOSFET. The drain of the MOSFET goes straight into an AP2331 current limiting switch. The AP2331 protects the controller from inrush and possible short circuits presented by the SD cards. Both the card power pin and the card enable pin have hardware pull-ups to try to insure that the cards are kept powered off and off the bus while the controller is starting up.
The entire circuit runs on 3.3 volts, but USB device power is provided at 5 volts. A buck converter centered around the PAM2305 is used to make the 3.3 volt supply for the board.
The controller has a brownout detector that will hold the chip in RESET if the 3.3 volt bus is lower than 3 volts, but there is a race condition during startup - setting up the BOD detector happens after the chip starts executing code. If we limit an attacker to access only to the SD card slots, the button and the USB port, then just about every avenue for tampering can be avoided in firmware except for meddling with the power. Lowering the supply voltage is a technique often used to try and mess with secure systems, so it's worth the extra cost to add a UVLO supervisor chip. If the 3.3 volt bus is at or lower than 3 volts, the supervisor will hold NRST low, holding the chip in RESET. 3 volts is more than enough for the chip to function properly, even to the point of properly supporting USB. The only remaining attack vector is the ERASE jumper, and the amelioration for that is a case with tamper evident seals.
The intent is that as supplied the firmware will be loaded with the security bit in the GPNVM register set to 1. This will disable all debug interfaces and protect the system from the potential for rogue firmware to be installed. The only way to defeat the security bit is to hold the ERASE pin high at startup. This not only clears the security bit but erases the firmware. The ERASE pin will be left available on the board, but it will not be made conveniently available with the board in a case (tamper evident seals can be used to detect whether or not the case is secure). But any potential firmware update process would need to start with an ERASE operation. The new firmware could be uploaded (and the security bit set once again) using the SAM-BA ROM bootloader over USB.
The USB, power and SWD (programming) stuff for the controller is all straight from the datasheet. The PAM2305 buck converter is also straight from its own datasheet. Apart from the bus switching, the SD card connection is also straight from the datasheet. The TRNG and AES subsystem is built-in to the controller. From a hardware perspective, there's very little to v3.