aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/dm/pmic.c68
-rwxr-xr-xtest/fs/fs-test.sh2
-rw-r--r--test/py/tests/test_tpm2.py233
3 files changed, 301 insertions, 2 deletions
diff --git a/test/dm/pmic.c b/test/dm/pmic.c
index b2061178fc..b582329a9c 100644
--- a/test/dm/pmic.c
+++ b/test/dm/pmic.c
@@ -19,11 +19,12 @@
#include <power/pmic.h>
#include <power/sandbox_pmic.h>
#include <test/ut.h>
+#include <fsl_pmic.h>
/* Test PMIC get method */
-static int dm_test_power_pmic_get(struct unit_test_state *uts)
+
+static inline int power_pmic_get(struct unit_test_state *uts, char *name)
{
- const char *name = "sandbox_pmic";
struct udevice *dev;
ut_assertok(pmic_get(name, &dev));
@@ -34,8 +35,26 @@ static int dm_test_power_pmic_get(struct unit_test_state *uts)
return 0;
}
+
+/* Test PMIC get method */
+static int dm_test_power_pmic_get(struct unit_test_state *uts)
+{
+ power_pmic_get(uts, "sandbox_pmic");
+
+ return 0;
+}
DM_TEST(dm_test_power_pmic_get, DM_TESTF_SCAN_FDT);
+/* PMIC get method - MC34708 - for 3 bytes transmission */
+static int dm_test_power_pmic_mc34708_get(struct unit_test_state *uts)
+{
+ power_pmic_get(uts, "pmic@41");
+
+ return 0;
+}
+
+DM_TEST(dm_test_power_pmic_mc34708_get, DM_TESTF_SCAN_FDT);
+
/* Test PMIC I/O */
static int dm_test_power_pmic_io(struct unit_test_state *uts)
{
@@ -64,3 +83,48 @@ static int dm_test_power_pmic_io(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_power_pmic_io, DM_TESTF_SCAN_FDT);
+
+#define MC34708_PMIC_REG_COUNT 64
+#define MC34708_PMIC_TEST_VAL 0x125534
+static int dm_test_power_pmic_mc34708_regs_check(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ int reg_count;
+
+ ut_assertok(pmic_get("pmic@41", &dev));
+
+ /* Check number of PMIC registers */
+ reg_count = pmic_reg_count(dev);
+ ut_asserteq(reg_count, MC34708_PMIC_REG_COUNT);
+
+ return 0;
+}
+
+DM_TEST(dm_test_power_pmic_mc34708_regs_check, DM_TESTF_SCAN_FDT);
+
+static int dm_test_power_pmic_mc34708_rw_val(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ int val;
+
+ ut_assertok(pmic_get("pmic@41", &dev));
+
+ /* Check if single 3 byte read is successful */
+ val = pmic_reg_read(dev, REG_POWER_CTL2);
+ ut_asserteq(val, 0x422100);
+
+ /* Check if RW works */
+ val = 0;
+ ut_assertok(pmic_reg_write(dev, REG_RTC_TIME, val));
+ ut_assertok(pmic_reg_write(dev, REG_RTC_TIME, MC34708_PMIC_TEST_VAL));
+ val = pmic_reg_read(dev, REG_RTC_TIME);
+ ut_asserteq(val, MC34708_PMIC_TEST_VAL);
+
+ pmic_clrsetbits(dev, REG_POWER_CTL2, 0x3 << 8, 1 << 9);
+ val = pmic_reg_read(dev, REG_POWER_CTL2);
+ ut_asserteq(val, (0x422100 & ~(0x3 << 8)) | (1 << 9));
+
+ return 0;
+}
+
+DM_TEST(dm_test_power_pmic_mc34708_rw_val, DM_TESTF_SCAN_FDT);
diff --git a/test/fs/fs-test.sh b/test/fs/fs-test.sh
index b6b9461a10..2e8d5ee4df 100755
--- a/test/fs/fs-test.sh
+++ b/test/fs/fs-test.sh
@@ -223,6 +223,8 @@ setenv bind 'if test "\$sb" != sb; then sb bind 0 "$1"; fi'
run bind
# Test Case 1 - ls
${PREFIX}ls host${SUFFIX} $6
+# In addition, test with a nonexistent directory to see if we crash.
+${PREFIX}ls host${SUFFIX} invalid_d
#
# We want ${PREFIX}size host 0:0 $3 for host commands and
# sb size hostfs - $3 for hostfs commands.
diff --git a/test/py/tests/test_tpm2.py b/test/py/tests/test_tpm2.py
new file mode 100644
index 0000000000..01ffb3178d
--- /dev/null
+++ b/test/py/tests/test_tpm2.py
@@ -0,0 +1,233 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2018, Bootlin
+# Author: Miquel Raynal <miquel.raynal@bootlin.com>
+
+import os.path
+import pytest
+import u_boot_utils
+import re
+import time
+
+"""
+Test the TPMv2.x related commands. You must have a working hardware setup in
+order to do these tests.
+
+Notes:
+* These tests will prove the password mechanism. The TPM chip must be cleared of
+any password.
+* Commands like pcr_setauthpolicy and pcr_resetauthpolicy are not implemented
+here because they would fail the tests in most cases (TPMs do not implement them
+and return an error).
+"""
+
+updates = 0
+
+def force_init(u_boot_console, force=False):
+ """When a test fails, U-Boot is reset. Because TPM stack must be initialized
+ after each reboot, we must ensure these lines are always executed before
+ trying any command or they will fail with no reason. Executing 'tpm init'
+ twice will spawn an error used to detect that the TPM was not reset and no
+ initialization code should be run.
+ """
+ output = u_boot_console.run_command('tpm init')
+ if force or not 'Error' in output:
+ u_boot_console.run_command('echo --- start of init ---')
+ u_boot_console.run_command('tpm startup TPM2_SU_CLEAR')
+ u_boot_console.run_command('tpm self_test full')
+ u_boot_console.run_command('tpm clear TPM2_RH_LOCKOUT')
+ output = u_boot_console.run_command('echo $?')
+ if not output.endswith('0'):
+ u_boot_console.run_command('tpm clear TPM2_RH_PLATFORM')
+ u_boot_console.run_command('echo --- end of init ---')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_init(u_boot_console):
+ """Init the software stack to use TPMv2 commands."""
+
+ u_boot_console.run_command('tpm init')
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_startup(u_boot_console):
+ """Execute a TPM2_Startup command.
+
+ Initiate the TPM internal state machine.
+ """
+
+ u_boot_console.run_command('tpm startup TPM2_SU_CLEAR')
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_self_test_full(u_boot_console):
+ """Execute a TPM2_SelfTest (full) command.
+
+ Ask the TPM to perform all self tests to also enable full capabilities.
+ """
+
+ u_boot_console.run_command('tpm self_test full')
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_continue_self_test(u_boot_console):
+ """Execute a TPM2_SelfTest (continued) command.
+
+ Ask the TPM to finish its self tests (alternative to the full test) in order
+ to enter a fully operational state.
+ """
+
+ u_boot_console.run_command('tpm self_test continue')
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_clear(u_boot_console):
+ """Execute a TPM2_Clear command.
+
+ Ask the TPM to reset entirely its internal state (including internal
+ configuration, passwords, counters and DAM parameters). This is half of the
+ TAKE_OWNERSHIP command from TPMv1.
+
+ Use the LOCKOUT hierarchy for this. The LOCKOUT/PLATFORM hierarchies must
+ not have a password set, otherwise this test will fail. ENDORSEMENT and
+ PLATFORM hierarchies are also available.
+ """
+
+ u_boot_console.run_command('tpm clear TPM2_RH_LOCKOUT')
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+ u_boot_console.run_command('tpm clear TPM2_RH_PLATFORM')
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_change_auth(u_boot_console):
+ """Execute a TPM2_HierarchyChangeAuth command.
+
+ Ask the TPM to change the owner, ie. set a new password: 'unicorn'
+
+ Use the LOCKOUT hierarchy for this. ENDORSEMENT and PLATFORM hierarchies are
+ also available.
+ """
+
+ force_init(u_boot_console)
+
+ u_boot_console.run_command('tpm change_auth TPM2_RH_LOCKOUT unicorn')
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+ u_boot_console.run_command('tpm clear TPM2_RH_LOCKOUT unicorn')
+ output = u_boot_console.run_command('echo $?')
+ u_boot_console.run_command('tpm clear TPM2_RH_PLATFORM')
+ assert output.endswith('0')
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_get_capability(u_boot_console):
+ """Execute a TPM_GetCapability command.
+
+ Display one capability. In our test case, let's display the default DAM
+ lockout counter that should be 0 since the CLEAR:
+ - TPM_CAP_TPM_PROPERTIES = 0x6
+ - TPM_PT_LOCKOUT_COUNTER (1st parameter) = PTR_VAR + 14
+
+ There is no expected default values because it would depend on the chip
+ used. We can still save them in order to check they have changed later.
+ """
+
+ force_init(u_boot_console)
+ ram = u_boot_utils.find_ram_base(u_boot_console)
+
+ read_cap = u_boot_console.run_command('tpm get_capability 0x6 0x20e 0x200 1') #0x%x 1' % ram)
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+ assert 'Property 0x0000020e: 0x00000000' in read_cap
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_dam_parameters(u_boot_console):
+ """Execute a TPM2_DictionaryAttackParameters command.
+
+ Change Dictionary Attack Mitigation (DAM) parameters. Ask the TPM to change:
+ - Max number of failed authentication before lockout: 3
+ - Time before the failure counter is automatically decremented: 10 sec
+ - Time after a lockout failure before it can be attempted again: 0 sec
+
+ For an unknown reason, the DAM parameters must be changed before changing
+ the authentication, otherwise the lockout will be engaged after the first
+ failed authentication attempt.
+ """
+
+ force_init(u_boot_console)
+ ram = u_boot_utils.find_ram_base(u_boot_console)
+
+ # Set the DAM parameters to known values
+ u_boot_console.run_command('tpm dam_parameters 3 10 0')
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+ # Check the values have been saved
+ read_cap = u_boot_console.run_command('tpm get_capability 0x6 0x20f 0x%x 3' % ram)
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+ assert 'Property 0x0000020f: 0x00000003' in read_cap
+ assert 'Property 0x00000210: 0x0000000a' in read_cap
+ assert 'Property 0x00000211: 0x00000000' in read_cap
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_pcr_read(u_boot_console):
+ """Execute a TPM2_PCR_Read command.
+
+ Perform a PCR read of the 0th PCR. Must be zero.
+ """
+
+ force_init(u_boot_console)
+ ram = u_boot_utils.find_ram_base(u_boot_console) + 1024
+
+ read_pcr = u_boot_console.run_command('tpm pcr_read 0 0x%x' % ram)
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+ # Save the number of PCR updates
+ str = re.findall(r'\d+ known updates', read_pcr)[0]
+ global updates
+ updates = int(re.findall(r'\d+', str)[0])
+
+ # Check the output value
+ assert 'PCR #0 content' in read_pcr
+ assert '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' in read_pcr
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_pcr_extend(u_boot_console):
+ """Execute a TPM2_PCR_Extend command.
+
+ Perform a PCR extension with a known hash in memory (zeroed since the board
+ must have been rebooted).
+
+ No authentication mechanism is used here, not protecting against packet
+ replay, yet.
+ """
+
+ force_init(u_boot_console)
+ ram = u_boot_utils.find_ram_base(u_boot_console) + 1024
+
+ u_boot_console.run_command('tpm pcr_extend 0 0x%x' % ram)
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+ read_pcr = u_boot_console.run_command('tpm pcr_read 0 0x%x' % ram)
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+ assert 'f5 a5 fd 42 d1 6a 20 30 27 98 ef 6e d3 09 97 9b' in read_pcr
+ assert '43 00 3d 23 20 d9 f0 e8 ea 98 31 a9 27 59 fb 4b' in read_pcr
+
+ str = re.findall(r'\d+ known updates', read_pcr)[0]
+ new_updates = int(re.findall(r'\d+', str)[0])
+ assert (updates + 1) == new_updates
+
+@pytest.mark.buildconfigspec('cmd_tpm_v2')
+def test_tpm2_cleanup(u_boot_console):
+ """Ensure the TPM is cleared from password or test related configuration."""
+
+ force_init(u_boot_console, True)