Hi Łukasz,
On 25/04/19 17:48, Łukasz Zemła wrote:
> On Wednesday, April 24, 2019 at 3:04:06 PM UTC+2, Stefano Babic wrote:
> [...]
>> Let's start with the history. A thread on both U-Boot and SWUpdate MLs :
>>
>>
>
http://u-boot.10912.n7.nabble.com/SWUpdate-U-Boot-environment-library-dependency-td340530.html#a348700
>>
>> This has already touched some of this requiremennts. The thing is not
>> only that the MTD are writable. An attacker can take the device and via
>> a flash programmer change it (or destroying) to change the behavior.
>
> Well... I am afraid mostly of ability to modify remotely 'bootcmd',
> 'bootargs' and 'verify'.> If someone has physical access to flash memory, then device
> is in big troubles and almost everything may happen.
Not true - if someone can do remotely, you have another problem that is
not addressed here. That meansm your device is not safe enough and it
gets exploited. These are two different topic: in fact, if an attacker
gets a root shell remotely, he can also write to any MTD partition he
wants. If a real "secure boot" is provided, the whole trust of chain
must not be broken, starting from the bootloader that *must* be verified
by the SOC.
>
> [...]
>> To ensure that the environment is not touched by attacker, I have used
>> environment flags. In fact, each variable has some associate flags and
>> it is possible to set variable / scripts as readonly. This forbids that
>> a variable can be changed from the default, even if the environment in
>> flash contains a new value.
>> flags can set the type for a variable (integer/string/boolean). Setting
>> most variable as integer (strings is default) avoids that an attacker
>> can insert an own script in the boot process.
>>
>> Just one variable indicating which software-set must be booted can be
>> modified by SWUpdate. But again, this variable is of type "int", and no
>> script can be inserted by malware.
>>
>> However, this process requires a high effort - I had to check each
>> variable, and the device was then reviewed by an external company (they
>> do review for security) to verify that there are no leaks.
>>
>> Not only, a patch (not applied to U-Boot because conflicts with other
>> things..) must be applied to U-Boot to be sure that the default
>> environment is always loaded before the environment in flash - this
>> allows to verify the flags for each variable.
>
> Is everything in the quoted block above (starting with 'To ensure that
> environment
> is not touched') part of your U-boot patch?
The patch just loads the "initial" environment (that means, the
environment if flash is corrupted) *before* loading the environment from
flash. In this way, flags are active and verified. If an attacker has
changed the environment on flash, this has no consequence because ro
variable are checked before applying the loaded env.
>
> As far as I know U-Boot, access flags are only gentleman agreement which
> are promised to be obeyed by fw_setenv/libubootenv and U-Boot itself.
flags are verified by U-Boot, they are not just something cosmetic in
fw_setenv
> Intruder may use
> his own version of fw_setenv/library which will just ignore flags.
And ? It does not matter. As I say, he could also turn off the device,
rewrite the MTD partitions with an external programmer. But his
environment is not taken, even if it has a valid CRC (the trick is the
patch I mentioned before).
> Eventually he may overwrite complete ENV by image with all flags as he
> wishes.
It does not matter, his environment has no worth. flags are set in the
initial environment, that means together with CONFIG_EXTRA_ENV. And if
secure boot is active, this image is verified by the SOC itself.
He can replace completeley the environment in flasg, U-Boot will discard
it if it does not comply to the linked flags.
>
>> Another option I would like to propose (and you gave me the chance,
>> thanks !) is to sign the environment. U-Boot has already the possibility
>> to verify an image (a public key is not a problem). Such as extension
>> could flow easy into U-Boot. The environment must then be signed in user
>> space by SWUpdate. It remains the general problem how to hide the key,
>> but this can be done with TPM or if rootfs is encrypted.
>
> Most probably/precisely signing environment should be done in libubootenv -
> to be able to share this functionality to custom userspacve programs.
That is correct - libubootenv should sign, and U-Boot can verify it. The
code to verify an image signed with a RSA key is already in U-Boot to
verify the kernel, so this looks to me a straightforward change.
>
>> This is also a reason for me to start the "libubootenv" project, because
>> it is independent from U-Boot (it could be extended to other
>> bootloaders, too) and it is easier to add new features.
>
> Just a stupid question - is U-Boot environment format portable across all
> U-Boot versions? Let's say 2014.10 and latest master?
>
Yes, it is. Even an older U-Boot 200X.XX is compatible. The format on
the storage is the same and part of U-Boot API. How the environment is
handled internally, is changed with the time - the big change was with
the introduction of the "env" command.
> [...]
>> >
>> > From Security point of view, the best would be to configure U-Boot with
>> > CONFIG_ENV_IS_NOWHERE,
>>
>> This does not work in case of update because there is no way to
>> communicate with the bootloader.
>
> For that purpose, we may use another MTD partition (where critical
> U-Boot variables
> are not stored)
You are just adding complexity without solving the problem - in some
way, U-Boot must load both environment, and an attacker can change both
of them.
>
>> > but then we have to write own Linux '(swupdate)
>> > <-> U-Boo't communication mechanism by hand
>>
>> By hand ?
>
> I meant 'manually implement/duplicate environment functions to operate
> on separate MTD partition'.
I do not see that you increase security.
>
>> Anyway, you are just moving the problem away. You still need a
>> safe way that U-Boot can trust it. Then this can be solved by verifying
>> the environment, isn't it ?
>
> Then I am making some step - modification of critical U-Boot variables
> is not possible.
> There is still problem of trust, but side effects are a way smaller: in
> symmetric mode
> intruder may force to run older version of the system.
True - where "--no-downgrading" is requested, the stand-by copy after a
successful update is made invalid. That means system cannot boot from
that and the attacker cannot switch.
> In asymmetric
> mode, force system
> to boot and stay in recovery waiting for new .swu file.
Treu, but this is a use case - ther eis no risk. The condition to avoid
is that an attacker can load and start its own software replacing the
delivered.
> In my case, recovery system expects to find already downloaded swu file
> at known location.
> If file is missing or authentication fails, then recovery may switch the
> gear again and reboot
> to Linux.
> But in general - yes, you are absolutely right about signing environment.
Yes
>
> The other workaround which came to my mind is to patch U-Boot to ignore
> completely
> bootcmd/bootargs and just hardcode equivalent actions in C code.
It is still not enough if you have a symmetric approach because the
software set to be booted is not fixed.
And to make the update power-cut safe, you need also to evaluate the
"recovery_status" variable set by SWUpdate in asymmetric mode.
> This
> way U-Boot reads
> swupdate flags only (yes - we have again mentioned by you 'trust'
> problem) and then makes
> approporiate C-only actions. But I am not sure about overall effort
> (don't know how deeply
> environment variables are tight into U-Boot.).
Best regards,