#!/usr/bin/env python3
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Verify pairing between base and lid

   During pairing, the base computes it's public key from base_private key
   and authenticator is derived from shared secret. For the lid to verify the
   challenge, it needs to check whether base_public corresponds to one of
   the previously seen bases, and that the returned authenticator matches.
"""

from __future__ import print_function


import ctypes
import sys
import time

import common
import hammerd_api

PAIRING_RUNS = 10
INJECTION_RUNS = 10
PUBLIC_KEY_SIZE = 32

# Before this test, please flash staff.bin using servo

def main(argv):
  if argv:
    sys.exit('Test takes no args!')
  updater = hammerd_api.FirmwareUpdater(common.BASE_VENDOR_ID,
                                        common.BASE_PRODUCT_ID,
                                        common.BASE_USB_PATH)
  public_key_first = (ctypes.c_ubyte * PUBLIC_KEY_SIZE)()
  # Load EC image.
  with open(common.IMAGE, 'rb') as f:
    ec_image = f.read()
  updater.LoadEcImage(ec_image)

  common.disable_hammerd()

  print('Connect to base EC.')
  common.connect_usb(updater)
  print('EC information:')
  print('PDU Response: %s' % updater.GetFirstResponsePdu().contents)
  print('RO: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RO))
  print('RW: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RW))
  print('Current section : %s' % updater.CurrentSection())
  assert updater.CurrentSection() == 1, 'Running section should be 1 (RW)'

  # Sends 'Need to inject entropy' message if base is new
  pair_manager = hammerd_api.PairManager()
  challenge_status = pair_manager.PairChallenge(updater.object,
                                                public_key_first)
  print('Challenge status: %d' % challenge_status)
  # assert challenge_status == 9, 'Need to inject the entropy'

  for iteratn in range(INJECTION_RUNS):
    print('Jumping back to RO to inject entropy. Iteratn: %d' % (iteratn + 1))
    updater.SendSubcommand(hammerd_api.UpdateExtraCommand.UnlockRollback)
    updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset)
    updater.CloseUsb()
    time.sleep(0.5)
    updater.TryConnectUsb()
    updater.SendSubcommand(hammerd_api.UpdateExtraCommand.StayInRO)
    # Wait for RO to run, else SendFirstPdu() picks up RW
    time.sleep(1)
    # Verify that we're in RO
    assert updater.SendFirstPdu() is True, 'Error sending first PDU'
    updater.SendDone()
    assert updater.CurrentSection() == 0, 'Not in RO: Cannot inject entropy'

    print('Inject entropy and sys jump to RW')
    updater.InjectEntropyWithPayload(b'\x87' * hammerd_api.ENTROPY_SIZE)
    updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset)
    updater.CloseUsb()
    time.sleep(0.5)
    common.connect_usb(updater)
    updater.SendSubcommand(hammerd_api.UpdateExtraCommand.JumpToRW)
    # Wait for RW to run
    time.sleep(1)
    updater.CloseUsb()
    time.sleep(0.5)
    # Jump to RW resets the base. Need to reconnect
    common.connect_usb(updater)
    print('PDU Response: %s' % updater.GetFirstResponsePdu().contents)

    # Check that RW is running
    assert updater.SendFirstPdu() is True, 'Error sending first PDU'
    updater.SendDone()
    print('Current running section after jumping to RW: %s'
          % updater.CurrentSection())
    assert updater.CurrentSection() == 1, 'Running section should be 1 (RW)'
    # Autheticator should match for each pairing run
    for i in range(PAIRING_RUNS):
      public_key = (ctypes.c_ubyte * PUBLIC_KEY_SIZE)()
      pair_manager = hammerd_api.PairManager()
      challenge_status = pair_manager.PairChallenge(updater.object, public_key)
      print('Challenge status: %d' % challenge_status)
      assert challenge_status == 0, 'Pairing challenge failed!'
      if i == 0:
        same = True
        for j in range(0, PUBLIC_KEY_SIZE-1):
          if public_key_first[j] != public_key[j]:
            same = False
            assert not same, 'The key did not change after entropy injection!'
            public_key_first = public_key
      else:
        for j in range(0, PUBLIC_KEY_SIZE-1):
          assert public_key_first[j] == public_key[j], 'Key changed!'

  # Reset the base
  common.sim_disconnect_connect(updater)

if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
