xref: /aosp_15_r20/external/autotest/server/site_tests/firmware_Cr50Unlock/firmware_Cr50Unlock.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Copyright 2018 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6import time
7
8from autotest_lib.client.common_lib import error
9from autotest_lib.server.cros.faft.cr50_test import Cr50Test
10
11
12class firmware_Cr50Unlock(Cr50Test):
13    """Verify cr50 unlock."""
14    version = 1
15
16
17    def send_unlock_console_command(self, password=''):
18        """Sent the unlock console command with the given password."""
19        time.sleep(self.cr50.CCD_PASSWORD_RATE_LIMIT)
20        self.cr50.send_command('ccd unlock ' + password)
21
22    def run_once(self):
23        """Check cr50 can see dev mode open works correctly"""
24
25        if not self.cr50.unlock_is_supported():
26            raise error.TestNAError('Unlock not supported')
27
28        if not self.faft_config.has_powerbutton:
29            raise error.TestNAError('Can not run test without power button')
30
31        # Make sure testlab mode is enabled, so we can guarantee the password
32        # can be cleared.
33        self.fast_ccd_open(enable_testlab=True)
34        self.cr50.ccd_reset()
35        # Set the password
36        self.set_ccd_password(self.CCD_PASSWORD)
37        if self.cr50.password_is_reset():
38            raise error.TestFail('Failed to set password')
39
40        # Test the ccd password rate limit.
41        self.cr50.set_ccd_level('lock')
42        # Wait long enough to ensure that the failed ccd unlock command starts
43        # the rate limit.
44        time.sleep(5)
45        self.cr50.send_command('ccd unlock ' + self.CCD_PASSWORD.lower())
46        # Cr50 should reject the correct ccd unlock because of the rate limit.
47        self.cr50.send_command_get_output('ccd unlock ' + self.CCD_PASSWORD,
48                    ['Busy'])
49        if self.cr50.get_ccd_level() == 'unlock':
50            raise error.TestFail('Rate limit did not prevent unlock.')
51        logging.info('Verified password rate limit.')
52
53        # Verify unlock from the cr50 console.
54        self.cr50.set_ccd_level('lock')
55        self.send_unlock_console_command(self.CCD_PASSWORD)
56        if self.cr50.get_ccd_level() != 'unlock':
57            raise error.TestFail('Could not unlock cr50 with the password')
58
59        self.cr50.set_ccd_level('lock')
60        # Try with the lowercase version of the passsword. Make sure it doesn't
61        # work.
62        self.send_unlock_console_command(self.CCD_PASSWORD.lower())
63        if self.cr50.get_ccd_level() != 'lock':
64            raise error.TestFail('Unlocked cr50 from AP with incorrect '
65                    'password')
66
67        # Verify unlock from the AP.
68        self.ccd_unlock_from_ap(self.CCD_PASSWORD)
69        if self.cr50.get_ccd_level() != 'unlock':
70            raise error.TestFail('Could not unlock cr50 from the AP with the '
71                    'password.')
72
73        self.cr50.set_ccd_level('lock')
74        self.ccd_unlock_from_ap(self.CCD_PASSWORD.lower(), expect_error=True)
75        if self.cr50.get_ccd_level() != 'lock':
76            raise error.TestFail('Unlocked cr50 from AP with incorrect '
77                    'password')
78
79        # CCD needs to be unlocked to clear the password.
80        self.ccd_unlock_from_ap(self.CCD_PASSWORD)
81        # Clear the password which has set at the beginning of this test.
82        self.set_ccd_password('clear:' + self.CCD_PASSWORD)
83        if not self.cr50.password_is_reset():
84            raise error.TestFail('Unable to clear password')
85