[U-Boot] [PATCH 0/2] rsa signature: check that required key is really mandatory

This serie fix an issue with the required key on rsa signature. If a required key is defined, only FIT signed with this key should be accepted. right now, there is an issue with required key, u-boot may used others key than required key.
The first commit add a test in vboot to check that u-boot don't allow FIT with another key than the required key. This test fails and show the issue. The second commit fix this issue with required key, so the test with required key succeed.
Daniele Alessandrelli (1): rsa: Return immediately if required-key verification fails
Philippe Reynes (1): pytest: vboot: add a test for required key
lib/rsa/rsa-verify.c | 3 +- test/py/tests/test_vboot.py | 57 ++++++++++++++++++++++ .../tests/vboot/sign-configs-sha256-pss-prod.its | 46 +++++++++++++++++ 3 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 test/py/tests/vboot/sign-configs-sha256-pss-prod.its

This commit add a test in the vboot test to check that when a required key is asked, only FIT signed with this key is used/accepted by u-boot.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- test/py/tests/test_vboot.py | 57 ++++++++++++++++++++++ .../tests/vboot/sign-configs-sha256-pss-prod.its | 46 +++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 test/py/tests/vboot/sign-configs-sha256-pss-prod.its
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py index 4627ceb..9c41ee5 100644 --- a/test/py/tests/test_vboot.py +++ b/test/py/tests/test_vboot.py @@ -80,6 +80,8 @@ def test_vboot(u_boot_console): assert(expect_string in ''.join(output)) if boots: assert('sandbox: continuing, as we cannot run' in ''.join(output)) + else: + assert('sandbox: continuing, as we cannot run' not in ''.join(output))
def make_fit(its): """Make a new FIT from the .its source file. @@ -106,6 +108,20 @@ def test_vboot(u_boot_console): util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb, '-r', fit])
+ def sign_fit_norequire(sha_algo): + """Sign the FIT + + Signs the FIT and writes the signature into it. It also writes the + public key into the dtb. + + Args: + sha_algo: Either 'sha1' or 'sha256', to select the algorithm to + use. + """ + cons.log.action('%s: Sign images' % sha_algo) + util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb, + fit]) + def replace_fit_totalsize(size): """Replace FIT header's totalsize with something greater.
@@ -195,6 +211,35 @@ def test_vboot(u_boot_console): util.run_and_log_expect_exception(cons, [fit_check_sign, '-f', fit, '-k', dtb], 1, 'Failed to verify required signature')
+ def test_required_key(sha_algo, padding): + """Test verified boot with the given hash algorithm. + + This function test if u-boot reject an image when a required + key isn't used to sign a FIT. + + Args: + sha_algo: Either 'sha1' or 'sha256', to select the algorithm to + use. + """ + # Compile our device tree files for kernel and U-Boot. These are + # regenerated here since mkimage will modify them (by adding a + # public key) below. + dtc('sandbox-kernel.dts') + dtc('sandbox-u-boot.dts') + + # Build the FIT with prod key (keys required) + # Build the FIT with dev key (keys NOT required) + # The dtb contain the key prod and dev and the key prod are set as required. + # Then try to boot the FIT with dev key + # This FIT should not be accepted by u-boot because the key prod is required + cons.log.action('%s: Test FIT with configs images' % sha_algo) + make_fit('sign-configs-%s%s-prod.its' % (sha_algo , padding)) + sign_fit(sha_algo) + make_fit('sign-configs-%s%s.its' % (sha_algo , padding)) + sign_fit(sha_algo) + + run_bootm(sha_algo, 'signed configs', '', False) + cons = u_boot_console tmpdir = cons.config.result_dir + '/' tmp = tmpdir + 'vboot.tmp' @@ -217,6 +262,17 @@ def test_vboot(u_boot_console): util.run_and_log(cons, 'openssl req -batch -new -x509 -key %sdev.key -out ' '%sdev.crt' % (tmpdir, tmpdir))
+ # Create an RSA key pair (prod) + public_exponent = 65537 + util.run_and_log(cons, 'openssl genpkey -algorithm RSA -out %sprod.key ' + '-pkeyopt rsa_keygen_bits:2048 ' + '-pkeyopt rsa_keygen_pubexp:%d' % + (tmpdir, public_exponent)) + + # Create a certificate containing the public key (prod) + util.run_and_log(cons, 'openssl req -batch -new -x509 -key %sprod.key -out ' + '%sprod.crt' % (tmpdir, tmpdir)) + # Create a number kernel image with zeroes with open('%stest-kernel.bin' % tmpdir, 'w') as fd: fd.write(5000 * chr(0)) @@ -230,6 +286,7 @@ def test_vboot(u_boot_console): test_with_algo('sha1','-pss') test_with_algo('sha256','') test_with_algo('sha256','-pss') + test_required_key('sha256','-pss') finally: # Go back to the original U-Boot with the correct dtb. cons.config.dtb = old_dtb diff --git a/test/py/tests/vboot/sign-configs-sha256-pss-prod.its b/test/py/tests/vboot/sign-configs-sha256-pss-prod.its new file mode 100644 index 0000000..aac732e --- /dev/null +++ b/test/py/tests/vboot/sign-configs-sha256-pss-prod.its @@ -0,0 +1,46 @@ +/dts-v1/; + +/ { + description = "Chrome OS kernel image with one or more FDT blobs"; + #address-cells = <1>; + + images { + kernel { + data = /incbin/("test-kernel.bin"); + type = "kernel_noload"; + arch = "sandbox"; + os = "linux"; + compression = "none"; + load = <0x4>; + entry = <0x8>; + kernel-version = <1>; + hash-1 { + algo = "sha256"; + }; + }; + fdt-1 { + description = "snow"; + data = /incbin/("sandbox-kernel.dtb"); + type = "flat_dt"; + arch = "sandbox"; + compression = "none"; + fdt-version = <1>; + hash-1 { + algo = "sha256"; + }; + }; + }; + configurations { + default = "conf-1"; + conf-1 { + kernel = "kernel"; + fdt = "fdt-1"; + signature { + algo = "sha256,rsa2048"; + padding = "pss"; + key-name-hint = "prod"; + sign-images = "fdt", "kernel"; + }; + }; + }; +};

On Wed, 18 Sep 2019 at 08:05, Philippe Reynes philippe.reynes@softathome.com wrote:
This commit add a test in the vboot test to check that when a required key is asked, only FIT signed with this key is used/accepted by u-boot.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
test/py/tests/test_vboot.py | 57 ++++++++++++++++++++++ .../tests/vboot/sign-configs-sha256-pss-prod.its | 46 +++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 test/py/tests/vboot/sign-configs-sha256-pss-prod.its
Reviewed-by: Simon Glass sjg@chromium.org

On Wed, 18 Sep 2019 at 08:05, Philippe Reynes philippe.reynes@softathome.com wrote:
This commit add a test in the vboot test to check that when a required key is asked, only FIT signed with this key is used/accepted by u-boot.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
test/py/tests/test_vboot.py | 57 ++++++++++++++++++++++ .../tests/vboot/sign-configs-sha256-pss-prod.its | 46 +++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 test/py/tests/vboot/sign-configs-sha256-pss-prod.its
Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm/next, thanks!

From: Daniele Alessandrelli daniele.alessandrelli@gmail.com
Currently, if image verification with a required key fails, rsa_verify() code tries to find another key to verify the FIT image. This however, is not the intended behavior as the documentation says that required keys "must be verified for the image / configuration to be considered valid".
This patch fixes the issue by making rsa_verify() return immediately if the verification of a required key fails.
Signed-off-by: Daniele Alessandrelli daniele.alessandrelli@gmail.com --- lib/rsa/rsa-verify.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 287fcc4..82dc513 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -437,8 +437,7 @@ int rsa_verify(struct image_sign_info *info, if (info->required_keynode != -1) { ret = rsa_verify_with_keynode(info, hash, sig, sig_len, info->required_keynode); - if (!ret) - return ret; + return ret; }
/* Look for a key that matches our hint */

On Wed, 18 Sep 2019 at 08:05, Philippe Reynes philippe.reynes@softathome.com wrote:
From: Daniele Alessandrelli daniele.alessandrelli@gmail.com
Currently, if image verification with a required key fails, rsa_verify() code tries to find another key to verify the FIT image. This however, is not the intended behavior as the documentation says that required keys "must be verified for the image / configuration to be considered valid".
This patch fixes the issue by making rsa_verify() return immediately if the verification of a required key fails.
Signed-off-by: Daniele Alessandrelli daniele.alessandrelli@gmail.com
lib/rsa/rsa-verify.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Wed, 18 Sep 2019 at 08:05, Philippe Reynes philippe.reynes@softathome.com wrote:
From: Daniele Alessandrelli daniele.alessandrelli@gmail.com
Currently, if image verification with a required key fails, rsa_verify() code tries to find another key to verify the FIT image. This however, is not the intended behavior as the documentation says that required keys "must be verified for the image / configuration to be considered valid".
This patch fixes the issue by making rsa_verify() return immediately if the verification of a required key fails.
Signed-off-by: Daniele Alessandrelli daniele.alessandrelli@gmail.com
lib/rsa/rsa-verify.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm/next, thanks!
participants (3)
-
Philippe Reynes
-
Simon Glass
-
sjg@google.com