def zha_security(controller=False): empty_key_data = t.EmberKeyData() empty_key_data.contents = t.fixed_list(16, t.uint8_t)([t.uint8_t(0)] * 16) zha_key = t.EmberKeyData() zha_key.contents = t.fixed_list( 16, t.uint8_t)([t.uint8_t(c) for c in b"ZigBeeAlliance09"]) isc = t.EmberInitialSecurityState() isc.bitmask = t.uint16_t( t.EmberInitialSecurityBitmask.HAVE_PRECONFIGURED_KEY | t.EmberInitialSecurityBitmask.REQUIRE_ENCRYPTED_KEY) isc.preconfiguredKey = zha_key isc.networkKey = empty_key_data isc.networkKeySequenceNumber = t.uint8_t(0) isc.preconfiguredTrustCenterEui64 = t.EmberEUI64([t.uint8_t(0)] * 8) if controller: isc.bitmask |= ( t.EmberInitialSecurityBitmask.TRUST_CENTER_GLOBAL_LINK_KEY | t.EmberInitialSecurityBitmask.HAVE_NETWORK_KEY) isc.bitmask = t.uint16_t(isc.bitmask) random_key = t.fixed_list( 16, t.uint8_t)([t.uint8_t(x) for x in os.urandom(16)]) isc.networkKey = random_key return isc
def zha_security(config: Dict[str, Any], controller: bool = False) -> None: isc = t.EmberInitialSecurityState() isc.bitmask = t.uint16_t( t.EmberInitialSecurityBitmask.HAVE_PRECONFIGURED_KEY | t.EmberInitialSecurityBitmask.REQUIRE_ENCRYPTED_KEY) isc.preconfiguredKey = t.EmberKeyData( config[zigpy.config.CONF_NWK_TC_LINK_KEY]) nwk_key = config[zigpy.config.CONF_NWK_KEY] if nwk_key is None: nwk_key = os.urandom(16) isc.networkKey = t.EmberKeyData(nwk_key) isc.networkKeySequenceNumber = t.uint8_t( config[zigpy.config.CONF_NWK_KEY_SEQ]) tc_addr = config[zigpy.config.CONF_NWK_TC_ADDRESS] if tc_addr is None: tc_addr = [0x00] * 8 isc.preconfiguredTrustCenterEui64 = t.EmberEUI64(tc_addr) if controller: isc.bitmask |= ( t.EmberInitialSecurityBitmask.TRUST_CENTER_GLOBAL_LINK_KEY | t.EmberInitialSecurityBitmask.HAVE_NETWORK_KEY) isc.bitmask = t.uint16_t(isc.bitmask) return isc
async def _restore(ezsp, backup_data, force, update_eui64_token=False, upg_tc_link_key=False): """Restore backup.""" (status, ) = await ezsp.networkInit() LOGGER.debug("Network init status: %s", status) assert status in (t.EmberStatus.SUCCESS, t.EmberStatus.NOT_JOINED) if status == t.EmberStatus.SUCCESS: if not force: click.echo("Network is up, not forcing restore") return try: (status, ) = await ezsp.leaveNetwork() if status != t.EmberStatus.NETWORK_DOWN: LOGGER.error("Couldn't leave network") return except asyncio.TimeoutError: LOGGER.error("Didn't not receive stack changed status callback") return if update_eui64_token: ncp_eui64 = t.EmberEUI64(backup_data[ATTR_NODE_EUI64]).serialize() (status, ) = await ezsp.setMfgToken(t.EzspMfgTokenId.MFG_CUSTOM_EUI_64, ncp_eui64) sec_bitmask = (t.EmberInitialSecurityBitmask.HAVE_PRECONFIGURED_KEY | t.EmberInitialSecurityBitmask.REQUIRE_ENCRYPTED_KEY | t.EmberInitialSecurityBitmask.TRUST_CENTER_GLOBAL_LINK_KEY | t.EmberInitialSecurityBitmask.HAVE_NETWORK_KEY | t.EmberInitialSecurityBitmask.NO_FRAME_COUNTER_RESET) if not is_well_known_key(backup_data[ATTR_KEY_GLOBAL][ATTR_KEY]): sec_bitmask |= t.EmberInitialSecurityBitmask.TRUST_CENTER_USES_HASHED_LINK_KEY init_sec_state = t.EmberInitialSecurityState( bitmask=sec_bitmask, preconfiguredKey=backup_data[ATTR_KEY_GLOBAL][ATTR_KEY], networkKey=backup_data[ATTR_KEY_NWK][ATTR_KEY], networkKeySequenceNumber=backup_data[ATTR_KEY_NWK][ATTR_KEY_SEQ], preconfiguredTrustCenterEui64=[0x00] * 8, ) if (upg_tc_link_key and t.EmberInitialSecurityBitmask.TRUST_CENTER_USES_HASHED_LINK_KEY not in sec_bitmask): init_sec_state.bitmask |= ( t.EmberInitialSecurityBitmask.TRUST_CENTER_USES_HASHED_LINK_KEY) init_sec_state.preconfiguredKey = t.EmberKeyData(os.urandom(16)) (status, ) = await ezsp.setInitialSecurityState(init_sec_state) LOGGER.debug("Set initial security state: %s", status) assert status == t.EmberStatus.SUCCESS if backup_data[ATTR_KEY_TABLE]: await _restore_keys(ezsp, backup_data[ATTR_KEY_TABLE]) network_key = backup_data[ATTR_KEY_NWK] (status, ) = await ezsp.setValue( ezsp.types.EzspValueId.VALUE_NWK_FRAME_COUNTER, t.uint32_t(network_key[ATTR_KEY_FRAME_COUNTER_OUT]).serialize(), ) LOGGER.debug("Set network frame counter: %s", status) assert status == t.EmberStatus.SUCCESS tc_key = backup_data[ATTR_KEY_GLOBAL] (status, ) = await ezsp.setValue( ezsp.types.EzspValueId.VALUE_APS_FRAME_COUNTER, t.uint32_t(tc_key[ATTR_KEY_FRAME_COUNTER_OUT]).serialize(), ) LOGGER.debug("Set network frame counter: %s", status) assert status == t.EmberStatus.SUCCESS await _form_network(ezsp, backup_data) await asyncio.sleep(2)