1# Copyright 2021 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 re 7import time 8 9from autotest_lib.client.common_lib import error 10from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 11 12 13class firmware_Cr50Keygen(FirmwareTest): 14 """Verify cr50 can tell the state of the dev mode switch.""" 15 version = 1 16 17 RUNS = 20 18 TIME_RE = r'KeyPair took (\d+) ' 19 TRUNKS_BASE = ( 20 'trunks_client --key_create --key_blob=/tmp/key --print_time ' 21 '--usage=decrypt ') 22 RSA_CMD_ARGS = '--rsa=2048' 23 # TODO(mruthven): look at results to see if 5000 is a reasonable average and 24 # 30s is a reasonable max across the test devices. Start a low threshold to 25 # get an idea for how the lab devices are operating. 26 # Raise an error if the average RSA key generation time takes longer than 27 # this threshold in ms. 28 RSA_AVG_THRESHOLD = 8000 29 # Raise an error if the max RSA key generation time takes longer than this 30 # threshold in ms. 31 RSA_MAX_THRESHOLD = 30000 32 ECC_CMD_ARGS = '--ecc' 33 # TODO(mruthven): look at results to see if 150 is a reasonable average and 34 # 500 is a reasonable max across the test devices. Start a low threshold to 35 # get an idea for how the lab devices are operating. 36 # Raise an error if the average ECC key generation time takes longer than 37 # this threshold. 38 ECC_AVG_THRESHOLD = 150 39 # Raise an error if the max ECC key generation time takes longer than this 40 # threshold in ms. 41 ECC_MAX_THRESHOLD = 500 42 43 def wait_for_client_after_changing_ccd(self, enable): 44 """Change CCD and wait for client. 45 46 @param enable: True to enable ccd. False to disable it. 47 @raises TestError if the DUT isn't pingable after changing ccd. 48 """ 49 if not hasattr(self, 'cr50') or not self.cr50: 50 return 51 52 if enable: 53 self.cr50.ccd_enable() 54 else: 55 self.cr50.ccd_disable() 56 57 time.sleep(5) 58 59 if self.host.ping_wait_up(180): 60 return 61 msg = ('DUT is not pingable after %sabling ccd' % 62 'en' if enable else 'dis') 63 logging.info(msg) 64 logging.info('Resetting DUT') 65 self.host.reset_via_servo() 66 if not self.host.ping_wait_up(180): 67 raise error.TestError(msg) 68 69 def get_key_attr(self, attr): 70 """Get the attribute for the type of key the test is generating.""" 71 return getattr(self, self.key_type + '_' + attr) 72 73 def get_keygen_cmd(self): 74 """Generate the trunks_client key_create command.""" 75 return self.TRUNKS_BASE + self.get_key_attr('CMD_ARGS') 76 77 def run_once(self, host, key_type='RSA'): 78 """Check ECC and RSA Keygen times.""" 79 self.host = host 80 self.key_type = key_type.upper() 81 82 # TODO(b/218492933) : find better way to disable rddkeepalive 83 # Disable rddkeepalive, so the test can disable ccd. 84 self.cr50.send_command('ccd testlab open') 85 self.cr50.send_command('rddkeepalive disable') 86 # Lock cr50 so the console will be restricted 87 self.cr50.set_ccd_level('lock') 88 89 self.wait_for_client_after_changing_ccd(False) 90 91 cmd = self.get_keygen_cmd() 92 logging.info(cmd) 93 full_cmd = ('for i in {1..%d} ; do echo $i ; %s || break; done' % 94 (self.RUNS, cmd)) 95 response = host.run(full_cmd) 96 logging.debug(response.stdout) 97 times = [int(t) for t in re.findall(self.TIME_RE, response.stdout)] 98 logging.info(times) 99 avg_time = sum(times) / len(times) 100 max_time = max(times) 101 logging.info('Average time: %s', avg_time) 102 logging.info('Max time: %s', max_time) 103 self.wait_for_client_after_changing_ccd(True) 104 if len(times) != self.RUNS: 105 raise error.TestFail('did not generate %d keys' % self.RUNS) 106 max_threshold = self.get_key_attr('MAX_THRESHOLD') 107 if max_time > max_threshold: 108 raise error.TestFail('MAX time %r is over the acceptable ' 109 'threshold(%dms)' % (max_time, max_threshold)) 110 avg_threshold = self.get_key_attr('AVG_THRESHOLD') 111 if avg_time > avg_threshold: 112 raise error.TestFail('Average time %r is over the acceptable ' 113 'threshold(%dms)' % (avg_time, avg_threshold)) 114