[PATCH 3/4] test: firmwware: add signature test to driver_data loader test
From: AKASHI Takahiro
Date: Thu May 25 2017 - 23:03:29 EST
Add the following tests:
No.15 - verify loaded data witha signature
No.16 - verify loaded data witha signature under signature enforcing
For each test, there are several test cases:
* no signature provided
* valid signature provided
* invalid signature provided
Signed-off-by: AKASHI Takahiro <takahiro.akashi@xxxxxxxxxx>
Cc: Luis R. Rodriguez <mcgrof@xxxxxxxx>
---
lib/test_driver_data.c | 56 ++++-
tools/testing/selftests/firmware/driver_data.sh | 265 +++++++++++++++++++++++-
2 files changed, 315 insertions(+), 6 deletions(-)
diff --git a/lib/test_driver_data.c b/lib/test_driver_data.c
index 422ea6289396..660cf9ff9ac0 100644
--- a/lib/test_driver_data.c
+++ b/lib/test_driver_data.c
@@ -85,6 +85,9 @@ int num_test_devs;
* @api_min: API min version to use for the test.
* @api_max: API max version to use for the test.
* @api_name_postfix: API name postfix
+ * @no_sig_check: whether or not we wish to verify the driver_data with its
+ * signature. If CONFIG_FIRMWARE_SIG_ENFORCE, passing the verification
+ * is mandatory.
* @test_result: a test may use this to collect the result from the call
* of the driver_data_request_async() or driver_data_request_sync() calls
* used in their tests. Note that for async calls this typically will be a
@@ -125,6 +128,7 @@ struct test_config {
u8 api_min;
u8 api_max;
char *api_name_postfix;
+ bool no_sig_check;
int test_result;
};
@@ -345,6 +349,9 @@ static ssize_t config_show(struct device *dev,
len += snprintf(buf+len, PAGE_SIZE,
"keep:\t\t%s\n",
config->keep ? "true" : "false");
+ len += snprintf(buf+len, PAGE_SIZE,
+ "no_sig_check:\t%s\n",
+ config->no_sig_check ? "true" : "false");
mutex_unlock(&test_dev->config_mutex);
@@ -443,6 +450,9 @@ static int config_sync_req_cb(void *context,
{
struct driver_data_test_device *test_dev = context;
+ if (unused_error)
+ return unused_error;
+
return config_load_data(test_dev, driver_data);
}
@@ -455,14 +465,19 @@ static int trigger_config_sync(struct driver_data_test_device *test_dev)
(config->optional ?
DRIVER_DATA_REQ_OPTIONAL : 0) |
(config->keep ?
- DRIVER_DATA_REQ_KEEP : 0)),
+ DRIVER_DATA_REQ_KEEP : 0) |
+ (config->no_sig_check ?
+ DRIVER_DATA_REQ_NO_SIG_CHECK :
+ 0)),
};
const struct driver_data_req_params req_params_opt_cb = {
DRIVER_DATA_DEFAULT_SYNC(config_sync_req_cb, test_dev),
DRIVER_DATA_SYNC_OPT_CB(config_sync_req_default_cb,
test_dev),
.reqs = (config->optional ? DRIVER_DATA_REQ_OPTIONAL : 0) |
- (config->keep ? DRIVER_DATA_REQ_KEEP : 0),
+ (config->keep ? DRIVER_DATA_REQ_KEEP : 0) |
+ (config->no_sig_check ? DRIVER_DATA_REQ_NO_SIG_CHECK :
+ 0),
};
const struct driver_data_req_params *req_params;
@@ -528,20 +543,26 @@ static int trigger_config_async(struct driver_data_test_device *test_dev)
const struct driver_data_req_params req_params_default = {
DRIVER_DATA_DEFAULT_ASYNC(config_async_req_cb, test_dev),
.reqs = (config->optional ? DRIVER_DATA_REQ_OPTIONAL : 0) |
- (config->keep ? DRIVER_DATA_REQ_KEEP : 0),
+ (config->keep ? DRIVER_DATA_REQ_KEEP : 0) |
+ (config->no_sig_check ? DRIVER_DATA_REQ_NO_SIG_CHECK :
+ 0),
};
const struct driver_data_req_params req_params_opt_cb = {
DRIVER_DATA_DEFAULT_ASYNC(config_async_req_cb, test_dev),
DRIVER_DATA_ASYNC_OPT_CB(config_async_req_default_cb, test_dev),
.reqs = (config->optional ? DRIVER_DATA_REQ_OPTIONAL : 0) |
- (config->keep ? DRIVER_DATA_REQ_KEEP : 0),
+ (config->keep ? DRIVER_DATA_REQ_KEEP : 0) |
+ (config->no_sig_check ? DRIVER_DATA_REQ_NO_SIG_CHECK :
+ 0),
};
const struct driver_data_req_params req_params_api = {
DRIVER_DATA_API_CB(config_async_req_api_cb, test_dev),
DRIVER_DATA_API(config->api_min, config->api_max, config->api_name_postfix),
.reqs = (config->optional ? DRIVER_DATA_REQ_OPTIONAL : 0) |
(config->keep ? DRIVER_DATA_REQ_KEEP : 0) |
- (config->use_api_versioning ? DRIVER_DATA_REQ_USE_API_VERSIONING : 0),
+ (config->use_api_versioning ? DRIVER_DATA_REQ_USE_API_VERSIONING : 0) |
+ (config->no_sig_check ? DRIVER_DATA_REQ_NO_SIG_CHECK :
+ 0),
};
const struct driver_data_req_params *req_params;
@@ -670,6 +691,7 @@ static int __driver_data_config_init(struct test_config *config)
config->use_api_versioning = false;
config->api_min = 0;
config->api_max = 0;
+ config->no_sig_check = false;
config->test_result = 0;
return 0;
@@ -1108,6 +1130,29 @@ static ssize_t config_api_name_postfix_show(struct device *dev,
static DEVICE_ATTR(config_api_name_postfix, 0644, config_api_name_postfix_show,
config_api_name_postfix_store);
+static ssize_t config_no_sig_check_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct driver_data_test_device *test_dev = dev_to_test_dev(dev);
+ struct test_config *config = &test_dev->config;
+
+ return test_dev_config_update_bool(test_dev, buf, count,
+ &config->no_sig_check);
+}
+
+static ssize_t config_no_sig_check_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct driver_data_test_device *test_dev = dev_to_test_dev(dev);
+ struct test_config *config = &test_dev->config;
+
+ return test_dev_config_show_bool(test_dev, buf, config->no_sig_check);
+}
+static DEVICE_ATTR(config_no_sig_check, 0644, config_no_sig_check_show,
+ config_no_sig_check_store);
+
static ssize_t test_result_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -1147,6 +1192,7 @@ static struct attribute *test_dev_attrs[] = {
TEST_DRIVER_DATA_DEV_ATTR(config_api_min),
TEST_DRIVER_DATA_DEV_ATTR(config_api_max),
TEST_DRIVER_DATA_DEV_ATTR(config_api_name_postfix),
+ TEST_DRIVER_DATA_DEV_ATTR(config_no_sig_check),
TEST_DRIVER_DATA_DEV_ATTR(test_result),
NULL,
diff --git a/tools/testing/selftests/firmware/driver_data.sh b/tools/testing/selftests/firmware/driver_data.sh
index bfd0436cce47..f9c52a87b9d0 100755
--- a/tools/testing/selftests/firmware/driver_data.sh
+++ b/tools/testing/selftests/firmware/driver_data.sh
@@ -54,6 +54,10 @@ ALL_TESTS="$ALL_TESTS 0013:1:1"
# system_wakeupakeup | socat - /dev/pts/7,raw,echo=0,crnl
#ALL_TESTS="$ALL_TESTS 0014:0:1"
+# Before running these tests, we must prepare an appropriate signature.
+#ALL_TESTS="$ALL_TESTS 0015:1:1"
+#ALL_TESTS="$ALL_TESTS 0016:1:1"
+
test_modprobe()
{
if [ ! -d $DIR ]; then
@@ -100,6 +104,10 @@ function allow_user_defaults()
# This is an unlikely real-world firmware content. :)
echo "ABCD0123" >"$FW"
+
+ # TODO: some set-up is necessary in advance
+ cp ${TEST_DIR}/fwbin/*sig*-*.bin ${FWPATH}
+ cp ${TEST_DIR}/fwbin/*sig*-*.bin.p7s ${FWPATH}
}
test_reqs()
@@ -133,7 +141,7 @@ test_finish()
{
echo -n "$OLD_PATH" >/sys/module/firmware_class/parameters/path
rm -f "$FW"
- rmdir "$FWPATH"
+ rm -rf "$FWPATH"
}
errno_name_to_val()
@@ -147,6 +155,12 @@ errno_name_to_val()
echo -2;;
-EINVAL)
echo -22;;
+ -EBADMSG)
+ echo -74;;
+ -ENOKEY)
+ echo -126;;
+ -EKEYREJECTED)
+ echo -129;;
-ERR_ANY)
echo -123456;;
*)
@@ -164,12 +178,37 @@ errno_val_to_name()
echo -ENOENT;;
-22)
echo -EINVAL;;
+ -74)
+ echo -EBADMSG;;
+ -126)
+ echo -ENOKEY;;
+ -129)
+ echo -EKEYREJECTED;;
-123456)
echo -ERR_ANY;;
*)
echo invalid;;
esac
+is_not_sig_enforced()
+{
+ if [ "Y" == \
+ $(cat /sys/module/firmware_class/parameters/fw_sig_enforce) ]
+ then
+ echo "$0: Signature enforced. Cannot run this test." >&2
+ exit 1
+ fi
+}
+
+enforce_sig_check()
+{
+ if ! echo -n 1 >/sys/module/firmware_class/parameters/fw_sig_enforce
+ then
+ echo "$0: Unable to set to fw_sig_enforce" >&2
+ exit 1
+ fi
+}
+
config_set_async()
{
if ! echo -n 1 >$DIR/config_async ; then
@@ -202,6 +241,22 @@ config_disable_optional()
fi
}
+config_set_sig_check()
+{
+ if ! echo -n 0 >$DIR/config_no_sig_check ; then
+ echo "$0: Unable to set to sig_check" >&2
+ exit 1
+ fi
+}
+
+config_disable_sig_check()
+{
+ if ! echo -n 1 >$DIR/config_no_sig_check ; then
+ echo "$0: Unable to disable sig_check" >&2
+ exit 1
+ fi
+}
+
config_set_keep()
{
if ! echo -n 1 >$DIR/config_keep; then
@@ -820,6 +875,212 @@ driver_data_test_0014()
driver_data_test_0014a
}
+# no signature provided, with driver not requiring it
+driver_data_test_0015_1_1()
+{
+ NAME=nosig-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_disable_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+# good signature, with driver not requiring it
+driver_data_test_0015_1_2()
+{
+ NAME=goodsig-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_disable_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+# no signature provided (ENOENT)
+driver_data_test_0015_2()
+{
+ NAME=nosig-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+# good signature
+driver_data_test_0015_3()
+{
+ NAME=goodsig-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+# signature not signed with a trusted key (ENOKEY)
+driver_data_test_0015_4()
+{
+ NAME=badsig1-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+# digest doens't match (wrong hash value) (EKEYREJECTED)
+driver_data_test_0015_5()
+{
+ NAME=badsig2-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+# signature corrupted/parsing error (EBADMSG)
+driver_data_test_0015_6()
+{
+ NAME=badsig3-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+driver_data_test_0015()
+{
+ is_not_sig_enforced
+
+ driver_data_test_0015_1_1
+ driver_data_test_0015_1_2
+ driver_data_test_0015_2
+ driver_data_test_0015_3
+ driver_data_test_0015_4
+ driver_data_test_0015_5
+ driver_data_test_0015_6
+}
+
+# no signature provided, with driver not requiring it
+driver_data_test_0016_1_1()
+{
+ NAME=nosig-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_disable_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+# good signature, with driver not requiring it
+driver_data_test_0016_1_2()
+{
+ NAME=goodsig-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_disable_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+# no signature provided (ENOENT)
+driver_data_test_0016_2()
+{
+ NAME=nosig-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger_want_fail ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} -ENOENT
+}
+
+# good signature
+driver_data_test_0016_3()
+{
+ NAME=goodsig-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger ${FUNCNAME[0]}
+ config_file_should_match ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} SUCCESS
+}
+
+# signature not signed with a trusted key (ENOKEY)
+driver_data_test_0016_4()
+{
+ NAME=badsig1-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger_want_fail ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} -ENOKEY
+}
+
+# digest doens't match (wrong hash value) (EKEYREJECTED)
+driver_data_test_0016_5()
+{
+ NAME=badsig2-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger_want_fail ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} -EKEYREJECTED
+}
+
+# signature corrupted/parsing error (EBADMSG)
+driver_data_test_0016_6()
+{
+ NAME=badsig3-$DEFAULT_DRIVER_DATA
+
+ driver_data_set_sync_defaults
+ config_set_name $NAME
+ config_set_sig_check
+ config_trigger_want_fail ${FUNCNAME[0]}
+ config_expect_result ${FUNCNAME[0]} -EBADMSG
+}
+
+# This test case must be run at the last.
+# Otherwe we must reboot the kernel to reset fw_sig_enforce.
+driver_data_test_0016()
+{
+ enforce_sig_check
+
+ driver_data_test_0016_1_1
+ driver_data_test_0016_1_2
+ driver_data_test_0016_2
+ driver_data_test_0016_3
+ driver_data_test_0016_4
+ driver_data_test_0016_5
+ driver_data_test_0016_6
+}
+
list_tests()
{
echo "Test ID list:"
@@ -842,6 +1103,8 @@ list_tests()
echo "0012 x $(get_test_count 0012) - Verify api call wills will hunt for files, ignore file"
echo "0013 x $(get_test_count 0013) - Verify api call works"
echo "0014 x $(get_test_count 0013) - Verify api call works with suspend + resume"
+ echo "0015 x $(get_test_count 0015) - Verify loaded data with signature"
+ echo "0016 x $(get_test_count 0016) - Verify loaded data with signature under signature enforcing"
}
test_reqs
--
2.11.1