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 # Make sure testlab mode is enabled, so we can guarantee the password 25 # can be cleared. 26 if not self.faft_config.has_powerbutton: 27 raise error.TestNAError('Can not run test without power button') 28 return 29 30 self.fast_ccd_open(enable_testlab=True) 31 self.cr50.send_command('ccd reset') 32 # Set the password 33 self.set_ccd_password(self.CCD_PASSWORD) 34 if self.cr50.password_is_reset(): 35 raise error.TestFail('Failed to set password') 36 37 # Test the ccd password rate limit. 38 self.cr50.set_ccd_level('lock') 39 # Wait long enough to ensure that the failed ccd unlock command starts 40 # the rate limit. 41 time.sleep(5) 42 self.cr50.send_command('ccd unlock ' + self.CCD_PASSWORD.lower()) 43 # Cr50 should reject the correct ccd unlock because of the rate limit. 44 self.cr50.send_command_get_output('ccd unlock ' + self.CCD_PASSWORD, 45 ['Busy']) 46 if self.cr50.get_ccd_level() == 'unlock': 47 raise error.TestFail('Rate limit did not prevent unlock.') 48 logging.info('Verified password rate limit.') 49 50 # Verify unlock from the cr50 console. 51 self.cr50.set_ccd_level('lock') 52 self.send_unlock_console_command(self.CCD_PASSWORD) 53 if self.cr50.get_ccd_level() != 'unlock': 54 raise error.TestFail('Could not unlock cr50 with the password') 55 56 self.cr50.set_ccd_level('lock') 57 # Try with the lowercase version of the passsword. Make sure it doesn't 58 # work. 59 self.send_unlock_console_command(self.CCD_PASSWORD.lower()) 60 if self.cr50.get_ccd_level() != 'lock': 61 raise error.TestFail('Unlocked cr50 from AP with incorrect ' 62 'password') 63 64 # Verify unlock from the AP. 65 self.ccd_unlock_from_ap(self.CCD_PASSWORD) 66 if self.cr50.get_ccd_level() != 'unlock': 67 raise error.TestFail('Could not unlock cr50 from the AP with the ' 68 'password.') 69 70 self.cr50.set_ccd_level('lock') 71 self.ccd_unlock_from_ap(self.CCD_PASSWORD.lower(), expect_error=True) 72 if self.cr50.get_ccd_level() != 'lock': 73 raise error.TestFail('Unlocked cr50 from AP with incorrect ' 74 'password') 75 76 # CCD needs to be unlocked to clear the password. 77 self.ccd_unlock_from_ap(self.CCD_PASSWORD) 78 # Clear the password which has set at the beginning of this test. 79 self.set_ccd_password('clear:' + self.CCD_PASSWORD) 80 if not self.cr50.password_is_reset(): 81 raise error.TestFail('Unable to clear password') 82