On Wed, 2018-08-22 at 13:27 -0700, Evan Edstrom wrote: > On Tue, Aug 21, 2018 at 1:03 AM, Jan Lübbe wrote: > > On Mon, 2018-08-20 at 11:39 -0700, Evan Edstrom wrote: > > > I am using RAUC for a commercial product, and one of the things we > > > need to accomplish is to encrypt our update bundles. I've manually > > > created an encrypted rauc bundle using a LUKS container. Once the > > > container is opened it can be mounted like normal as a squashfs > > > partition and used by RAUC. > > > > A normal RAUC bundle looks (mostly) like this: > > [ squashfs ][ CMS signature over hash of squashfs ] > > > > I expect that your LUKS container wraps both: > > [ LUKS header ][ LUKS encrpytion ( RAUC bundle ) ] > > > > So you get symmetric encryption of whole bundle with a password (i.e. a > > shared secret), right? > > Yes, I was using a keyfile with 1024 bytes of /dev/random to test with.
OK. > > While this setup is pretty straight forward, I see some downsides: > > - RAUC cannot read any information about the bundle before decryption > > - With a single shared secret, there is no way to revoke a compromised > > key (for example extracted from a single device in the field) > > > * Option 1: > > > Provide an optional "decryption handler"... If the config file defines > > > this handler, the update process would essentially run the handler > > > instead of r_mount_loop() in bundle.c. > > > > r_mount_loop() only runs after reading and verifying the bundle > > signature, so it would need a different layout than the one above. > > Something like: > > [ LUKS header ][ LUKS encrpytion ( squashfs ) ] CMS signature over hash > > of LUKS header+encrypted data ] > > Exactly what I was picturing. Filling the container, closing it, then > signing using the existing method so RAUC could verify the signature > before attempting to decrypt in the same way it currently would. > > > > This gives a user the most flexibility as they're not locked into any > > > particular encryption method or even bundle format. Bundle creation gets > > > a little more tricky as there isn't a concept of handlers built in. Could > > > have > > > an optional argument which provides a mounted and empty bundle. > > > > A squashfs is generated by using mksquashfs. The result would then be > > copied into a fresh LUKS container. So creating encrypted bundles would > > required root. > > Correct, this is a limitation of device-mapper which is used by > cryptsetup. This wasn't a show stopper for our particular case, but I > see how this could be an issue for other cases. It would be a show-stopper for most of our projects, because it would be hard to use securely on a CI server and not all developer have root access on the build machines. A lot of work went into build systems and image generation tools to avoid the root requirement. > > > * Option 2: > > > Implement encryption support directly into RAUC as a compile option. > > > This could create an encrypted bundle and decrypt and mount during > > > install time. > > > > I'd definitely prefer built-in encryption support. Mainly because: > > - It can be integrated with the existing CMS-based signatures, so we > > get support for multiple recipient devices with individual private > > keys. > > - It's easier to use (you don't need to write a handler). > > - By using dm-crypt without LUKS, we can generate the encrypted bundle > > without requiring root privileges (via OpenSSL). > > Would we be able to encrypt the squashfs partition using OpenSSL > without mounting it with dm-crypt? Or I suppose another way, can > dm-crypt mount a squashfs partition which was encrypted with OpenSSL? We'd need to implement aes-xts-plain64 or aes-cbc-essiv in user-space, but these modes are pretty straight forward. > > - When using per device private keys, we can also store them in a TPM > > or a PKCS#11 token/smartcard, so they can't be easily extracted. > > > > As we use CMS [1] for signing, we can potentially support everything > > the OpenSSL cms tool (see 'man cms') supports (N-of-M signatures, > > encryption with shared secrets and/or public/private keys). > > These are all good points. I am not too familiar with the abilities of > CMS. I will need to do some reading before I can give as thoughtful of > a response.test/openssl-ca.sh Maybe take a look at the OpenSSL CMS tool source and the end of test/openssl-ca.sh in RAUC. > > So my current concept would be to use a differemt payload in the CMS > > message (instead of a hash over the squashfs), consisting of > > information about the encryption (algorithm, parameters and payload > > key) and the payload hash (or dm-verity root hash). The CMS message > > would then be encrypted in addition to being signed. > > We don't have to use LUKS, but its header does include information > about the encryption method which is inspection without decrypting > first. It builds in a similar mechanism, though the header is only > signed, not encrypted. Of course a user of RAUC will need to store the > decryption key, but this could still leverage a TPM or secure storage > on whichever architecture they used. Yes. > > When opening the bundle, OpenSSL would detect that the CMS message is > > encrypted, look for the matching private key and decrypt. Then we have > > the information to configure dm-crypt and/or dm-verity on top of the > > loop device. The rest of the installation would proceed as usual. > > Are you suggesting: > [Arbitrary encryption method (squashfs)][CMS encrypted+signed > (squashfs encryption format + payload key)] Actually more like: [ squashfs hashed with dm-verity and encrypted in dm-crypt compatible format ][ CMS encrypted and signed (algorithm settings, dm-verity root hash, payload key) ] > So you would first decrypt the CMS message using OpenSSL with a > private key (optionally stored on a TPM or smartcard), use the newly > acquired information to setup dm-crypt, and mount the mapper device. > Am I understanding correctly? Yes. CMS can also use simple passwords (instead or as an additional recipient), not only public keys. > > So the only places that would need to change are bundle opening (setup > > OpenSSL for decryption and configure device mapper targets) and bundle > > creation (optionally encrypt, optionally use veritysetup and use > > OpenSSL for CMS encyption). > > > > What do you think about this apporach? > > I agree building in encryption support is nice, though successful > implementation of encryption and security for embedded devices > requires some level of custom hardware. What kind of custom hardware are you thinking about? I'd prefer to reuse and integrate with existing HW/SW as much as possible. > This is going to be very > device specific and I'm worried forcing the use of a specific > procedure may be too limiting. I wonder if we would still need to > provide some user customizability in the form of a handler somewhere. > Even without storing the payload key in a CMS message, it should be > possible for a user to securely implement a TPM to generate the > decryption key. You want to use a random payload key for every bundle to avoid problems with key/IV reuse. So I think the (encrypted) payload key needs to be contained in the bundle metadata. If you have a fixed (shared secret) key on the devices, this could still be handle by passing it as a password to the CMS decryption. > Let me do a little more reading on OpenSSL encryption and CMS messages. Sure, thanks for providing a concrete use-case so we can make progress on the design. Regards, Jan -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ RAUC mailing list
