[00:00.000 --> 00:11.440] The presentation, so it's about de-embarity to establish root fascism integrity. [00:11.440 --> 00:19.760] My name is Renk Riewerger, I've got a small demonstrator following this link, so that's [00:19.760 --> 00:24.920] my sandbox to evaluate those techniques. [00:24.920 --> 00:28.520] So let's jump into the presentation, so what is de-embarity? [00:28.520 --> 00:37.680] So as already mentioned, it belongs to a family of kernel device-mapper modules. [00:37.680 --> 00:42.840] It's mapping a physical block device onto high-level virtual block devices, for example, [00:42.840 --> 00:47.400] first to mention part of this family is de-emcrypt. [00:47.400 --> 00:55.160] It's intended for encryption and realizing confidentiality of your partition or the data [00:55.160 --> 00:56.400] in your partition. [00:56.400 --> 01:05.680] It establishes a read-writeable access, de-emintegrity, it's kind of journaling, establishing a read-write [01:05.680 --> 01:13.720] access also, and there is de-embarity for authenticity or integrity and optional authenticity [01:13.720 --> 01:18.600] and establishing a read-only access to your device. [01:18.600 --> 01:25.440] De-emcrypt, as already mentioned, is all established confidentiality, that means the [01:25.440 --> 01:32.480] authenticity or integrity is not enforced, so it might be possible to modify your content [01:32.480 --> 01:40.160] of your encrypted file system and you would never notice if by luck the block or the file [01:40.160 --> 01:47.040] structures or the directory structures are met, you wouldn't notice. [01:47.040 --> 01:48.040] De-embarity is different. [01:48.040 --> 01:54.840] If you use de-embarity, any modification of your partition, file structure, content of [01:54.840 --> 02:02.560] your files will be noticed and the integrity of your partition is enforced. [02:02.560 --> 02:09.040] It's also possible to sign your de-embarity setup. [02:09.040 --> 02:14.600] In this case, you achieve authenticity, so you know for sure that whatever you delivered [02:14.600 --> 02:22.440] and the signature matches, your data has not been manipulated, so de-embarity is available [02:22.440 --> 02:29.040] since kernel 3.4 or Android 4.4, so it's quite old, late 2013, so it's not a new feature [02:29.040 --> 02:33.000] we're talking about. [02:33.000 --> 02:36.840] So how does de-embarity work? [02:36.840 --> 02:42.480] De-embarity is based on a hash tree, so you have got your block device contained, for [02:42.480 --> 02:50.120] example, containing your root file system, these are the blue boxes on the bottom, and [02:50.120 --> 02:56.480] for every block device, 1K, 4K, whatever you choose, a hash value is calculated and a group [02:56.480 --> 03:04.800] of hash values is forming one more hash value on a higher level and so on and so on until [03:04.800 --> 03:09.160] you reach a single hash value on top called the root hash value. [03:09.160 --> 03:15.720] And this root hash value represents the state of your partition. [03:15.720 --> 03:22.480] If you sign this root hash value, you achieve authenticity of your overall partition. [03:22.480 --> 03:27.080] The good thing is to achieve this, you don't need any secret on the target, you just have [03:27.080 --> 03:36.480] to ship assigned entity to your target and the public key, and using the public key, [03:36.480 --> 03:38.640] your authenticity of your partition can verify. [03:38.640 --> 03:46.160] So it's different to TPM achievements or de-emcrypt, for de-emcrypt you need a security, here [03:46.160 --> 03:51.800] you don't need a secret. [03:51.800 --> 03:52.800] So how does it work? [03:52.800 --> 04:02.360] So once you created this root hash tree, or this hash tree, you install your root file [04:02.360 --> 04:08.920] system, your partition, for example on SDA3, and your hash tree will be placed in the partition [04:08.920 --> 04:11.920] SDA4. [04:11.920 --> 04:19.360] The invarity in the kernel is set up using both partitions, and it's providing a virtual [04:19.360 --> 04:26.320] file system into user space, and every time user space a block is read from your partition, [04:26.320 --> 04:32.440] it will be verified with a corresponding hash tree. [04:32.440 --> 04:37.880] So each block from root file system in SDA3 will be hashed, and the hash is compared to [04:37.880 --> 04:42.360] the hash value in the hash tree. [04:42.360 --> 04:48.280] And it will be calculated, the hash will be verified up to the root hash. [04:48.280 --> 04:55.200] And as the root hash is signed, you are sure it's not only the integrity is given, but [04:55.200 --> 05:03.720] authenticity is given also, because of the signed root hash value. [05:03.720 --> 05:08.680] So what can we, so what do we achieve now using the invarity? [05:08.680 --> 05:14.760] So we, it's a counter measure against one of the major threats for embedded devices [05:14.760 --> 05:25.160] in the field, IoT devices, somewhere being installed along the roads or whatever, detecting [05:25.160 --> 05:28.480] manipulation during startup. [05:28.480 --> 05:34.240] You can detect manipulation during runtime, because every time a block is read from your [05:34.240 --> 05:42.440] root file system, it will be hashed again, and it will be compared to the signed hash [05:42.440 --> 05:44.600] tree. [05:44.600 --> 05:51.040] So this way, even after startup during runtime, it's not possible to modify the content of [05:51.040 --> 05:54.480] your partition. [05:54.480 --> 06:00.840] You can use the invarity to terminate the execution of your kernel and the overall operating [06:00.840 --> 06:05.680] system, in case manipulation has been detected. [06:05.680 --> 06:13.320] It can deal with forward error correction in case of outwearing of your hashed devices, [06:13.320 --> 06:27.800] re-arranging blocks on your flash, and it requires a minimal run time overhead and almost [06:27.800 --> 06:30.000] zero latency during startup. [06:30.000 --> 06:40.280] So compare it to a naive way to verify the integrity and authenticity of a hash file [06:40.280 --> 06:47.760] system, let's say 150 megabyte, and you hash the complete 150 megabyte during startup, [06:47.760 --> 06:53.280] 50 megabyte per second, so that will take 10 seconds, at least, to verify. [06:53.280 --> 07:00.760] So using this one, there is zero latency, almost zero, so it's not noticeable. [07:00.760 --> 07:06.000] It's just reading a few blocks, all the few blocks being read to startup your, to start [07:06.000 --> 07:15.560] system D, your basic services, the few blocks have got to be verified and compared with [07:15.560 --> 07:23.840] a corresponding hash tree managed by DM Verity. [07:23.840 --> 07:25.400] So where should I? [12:23.840 --> 12:53.640] In line 11, the signature of the root hash, it's about 560 bytes, so we are talking about [12:54.600 --> 13:01.560] half a K of command line parameters here. [13:01.560 --> 13:05.680] So what do we need in the kernel? [13:05.680 --> 13:11.840] We just need a few parameters, or we need some kernel features. [13:11.840 --> 13:20.560] We have got to tell or integrate into the kernel the device mapper init capability, Verity, [13:20.560 --> 13:30.320] of course, the root hash verification, a trusted key ring, and we have got to specify [13:30.320 --> 13:36.880] the root, the certificate being used to verify the root hash. [13:36.880 --> 13:42.480] And this is the only cryptographic item we need to compile into the binaries. [13:42.480 --> 13:53.640] It's a public key, it's a certificate required to verify the hash tree. [13:53.640 --> 14:00.880] So let's get me back to this one. [14:00.880 --> 14:10.320] As you know, we must make sure that we have got a secure boot process without gaps. [14:10.320 --> 14:25.480] So you showed that public key, is that public key compiled into your kernel, is that how [14:25.480 --> 14:26.480] it works? [14:26.480 --> 14:33.080] Yes, it's a certificate, but it contains public key, and that's all you need. [14:33.080 --> 14:39.520] So we have got to make sure that the boot process is secure. [14:39.520 --> 14:45.840] And the signed boot loader, for example, UBOOT, we must make sure that there's no escape, [14:45.840 --> 14:49.080] no possibility of escape, we have got to lock down UBOOT. [14:49.080 --> 14:56.760] This is difficult if we want to establish some kind of AB booting, booting to A, booting [14:56.760 --> 14:57.760] to B. [14:57.760 --> 15:02.880] So UBOOT must provide some support for UBOOT environment. [15:02.880 --> 15:13.240] So here we need some features to lock down UBOOT to allow only certain variables being [15:13.240 --> 15:16.440] read and evaluated from the environment. [15:16.440 --> 15:25.920] If we do AB booting, we will have two different kernel command lines. [15:25.920 --> 15:38.000] We have got to specify device or partition representing the slot A, and we need another [15:38.000 --> 15:40.960] command line representing slot B. [15:40.960 --> 15:53.160] So we can't manage this now in UBOOT as UBOOT environment, with the containing also the [15:53.160 --> 15:58.800] seed and the root hash value and the signature of the root hash. [15:58.800 --> 16:08.360] So for this reason, the device tree now contains the boot argument, and we can provide two [16:08.360 --> 16:12.280] different configurations in the fit image. [16:12.280 --> 16:18.160] One device tree containing the boot step, the boot commands for slot A, and one for [16:18.160 --> 16:27.960] slot B. And everything else, the only thing UBOOT has to specify now is should it boot [16:27.960 --> 16:31.400] to A, slot A, or should it boot to slot B? [16:31.400 --> 16:38.760] And it starts, so as it would look like, it works like UBOOT is loading the fit image [16:38.760 --> 16:41.000] and specifying which configuration it would boot. [16:41.000 --> 16:47.360] It would just specify boot configuration A, boot configuration or slot B. [16:47.360 --> 16:54.120] And then these would represent the device tree configurations either for slot A or for [16:54.120 --> 17:02.560] slot B. And that's the reason the boot arguments have been moved into the fit image. [17:02.560 --> 17:10.360] So we can provide two different device trees with two different boot arguments, either [17:10.360 --> 17:16.960] for slot A and for slot B booting. [17:16.960 --> 17:27.720] So the benefits, it's very, so the de-invarity introduced a very low overhead. [17:27.720 --> 17:36.320] It allows us to do root of its integrity, authenticity, it's terminating the application [17:36.320 --> 17:46.480] case, manipulation of the root file system has been detected, and it's, well, it's just [17:47.480 --> 17:51.760] it's nice, it's nice, it's a nice feature. [17:51.760 --> 17:59.120] And I wondered, there's little in, there's not a lot of documentation about this feature [17:59.120 --> 18:01.360] as far as I got to know. [18:01.360 --> 18:03.680] So is there any other questions? [18:03.680 --> 18:04.680] Yes. [18:04.680 --> 18:09.080] Yeah, thank you for your talk. [18:09.080 --> 18:12.840] I have a question about the verification. [18:12.840 --> 18:19.920] So how I understand it, it's an on-the-fly verification of the image, meaning that the [18:19.920 --> 18:29.720] system is already being in use when there are still some of those blocks to be verified, [18:29.720 --> 18:36.600] meaning that you, let's say, in a secure boot, you might have that condition that you say [18:36.600 --> 18:45.360] I only execute signed code, meaning that either I have the, either I know that this is all, [18:45.360 --> 18:50.360] that this all has integrity, or I'm not starting it up at all, right? [18:50.360 --> 18:51.360] Yeah. [18:51.360 --> 18:56.080] For, let's say, for some critical applications, this might be important because if you've some [18:56.080 --> 19:03.240] kind of control device for, yeah, I don't know, an autopilot or something like that, [19:03.240 --> 19:08.760] then maybe you don't want to get into that application if you're not, if you don't have [19:08.760 --> 19:10.880] the security that everything's okay. [19:10.880 --> 19:11.880] Yes. [19:11.880 --> 19:17.200] That's the reason the kernel is not allowed or must not be stored in the root FS. [19:17.200 --> 19:22.600] So for some embedded systems, you will find that our build root is putting the kernel [19:22.600 --> 19:27.040] into the root file system by default. [19:27.040 --> 19:31.240] That's not, you can't do it here because you have got to start the kernel, you have [19:31.240 --> 19:37.240] got to, you have got to start the kernel and then you are able to verify the dm-varity [19:37.240 --> 19:39.120] tree. [19:39.120 --> 19:43.800] For that reason, the kernel is located in the fit image and the fit image is verified [19:43.800 --> 19:45.120] by the bootloader. [19:45.120 --> 19:50.640] So once we start the kernel, we know that the kernel is, the integrity of the kernel [19:50.640 --> 19:52.560] is given. [19:52.560 --> 19:57.640] If you start an application from root file system, it's read block-wise and it must be [19:57.640 --> 20:02.000] read into the memory and linked. [20:02.000 --> 20:05.080] And if during reading block-wise, you have got to start the kernel, you have got to start [20:05.080 --> 20:05.080] the kernel.