diff --git a/CMakeLists.txt b/CMakeLists.txt index 7671101c9..5051626d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 2.6.4) project (cryptoauthlib C) # Set the current release version -set(VERSION "3.2.5") +set(VERSION "3.3.0") set(VERSION_MAJOR 3) -set(VERSION_MINOR 2) -set(VERSION_PATCH 5) +set(VERSION_MINOR 3) +set(VERSION_PATCH 0) # Build Options option(BUILD_TESTS "Create Test Application with library" OFF) diff --git a/README.md b/README.md index 0ab081a91..5cb80a1e4 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,15 @@ configuration is well tested, then you can commit it to a CryptoAuth Xplained Pro Extension, for example. Keep in mind that once you lock a device, it will not be changeable. +Licensing +--------------------------- + +The CryptoAuthLib license can be found in the accompaning [license.txt](https://github.com/MicrochipTech/cryptoauthlib/blob/main/license.txt) +file. + +Cryptoauthlib also includes optional third party software subject to their own licensing terms. If you are using one of these optional components please +verify the terms of those licenses as well in the third_party/ directories. + Examples ----------- diff --git a/app/api_206a/api_206a.h b/app/api_206a/api_206a.h index 00e73673a..e665e0294 100644 --- a/app/api_206a/api_206a.h +++ b/app/api_206a/api_206a.h @@ -33,7 +33,6 @@ extern "C" { #endif #include "atca_status.h" -#include "atca_command.h" #define ATCA_SHA206A_ZONE_WRITE_LOCK 0x20 #define ATCA_SHA206A_DKEY_CONSUMPTION_MASK 0x01 @@ -68,4 +67,4 @@ ATCA_STATUS sha206a_get_data_store_lock_status(uint8_t slot, uint8_t* is_locked) } #endif -#endif \ No newline at end of file +#endif diff --git a/cryptoauthlib-manual.pdf b/cryptoauthlib-manual.pdf index 349456733..28e166a64 100644 Binary files a/cryptoauthlib-manual.pdf and b/cryptoauthlib-manual.pdf differ diff --git a/harmony/config/cryptoauthlib.py b/harmony/config/cryptoauthlib.py index 8682ca291..c38150671 100644 --- a/harmony/config/cryptoauthlib.py +++ b/harmony/config/cryptoauthlib.py @@ -61,12 +61,22 @@ def updateHalTracker(id, inc): calHalTracker[id] = cnt elif cnt > 0: cnt -= 1 - - symbol = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_FILE_SRC_HAL_' + id.upper()) + + print('updateHalTracker', id) + + symbol = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_FILE_SRC_HAL_' + id) symbol.setEnabled(cnt > 0) + calHalList = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_HAL_LIST_ENTRIES') + + if cnt == 0: + del_value_from_list(calHalList, id) + else: + add_value_to_list(calHalList, id) + def updatePlibTracker(id, inc): + # id is of the form: __ global calPlibTracker cnt = calPlibTracker.pop(id, 0) if inc: @@ -75,7 +85,12 @@ def updatePlibTracker(id, inc): elif cnt > 0: cnt -= 1 - updateHalTracker(id.split('_')[1], inc) + hal_ids = id.upper().split('_')[1:] + if len(hal_ids) > 1: + updateHalTracker('_'.join(hal_ids), inc) + updateHalTracker(hal_ids[1], inc) + else: + updateHalTracker(hal_ids[0], inc) calPlibList = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_PLIB_LIST_ENTRIES') @@ -134,6 +149,15 @@ def updateFileEnable(component, pattern, enable): srcFile.setEnabled(enable) +def check_if_file_exists(component, pattern): + global numFileCntr + for x in range(numFileCntr): + srcFile = component.getSymbolByID(fileSymbolName + str(x)) + if srcFile is not None: + if pattern.replace('/*','') in srcFile.getOutputName(): + return True + return False + def onAttachmentConnected(source, target): global _ca_dev_cnt @@ -150,6 +174,9 @@ def onAttachmentConnected(source, target): if 'TA100' in targetComponentID: _ta_dev_cnt += 1 updateFileEnable(srcComponent, _TA_PATHS, True) + if check_if_file_exists(srcComponent, 'talib_fce'): + calTaEnableFce = srcComponent.getSymbolByID('CAL_ENABLE_TA100_FCE') + calTaEnableFce.setValue(True) else: _ca_dev_cnt += 1 updateFileEnable(srcComponent, _CA_PATHS, True) @@ -167,7 +194,9 @@ def onAttachmentConnected(source, target): WolfCrypto = srcComponent.getSymbolByID('CAL_FILE_SRC_WOLFSSL_WRAPPER') WolfCrypto.setEnabled(True) - print('connected lib_wolfcrypt') + + calTaEnableAesAuth = srcComponent.getSymbolByID('CAL_ENABLE_TA100_AES_AUTH') + calTaEnableAesAuth.setValue(True) def onAttachmentDisconnected(source, target): @@ -185,6 +214,10 @@ def onAttachmentDisconnected(source, target): _ta_dev_cnt -= 1 if 0 == _ta_dev_cnt: updateFileEnable(srcComponent, _TA_PATHS, False) + calTaEnableFce = srcComponent.getSymbolByID('CAL_ENABLE_TA100_FCE') + calTaEnableFce.setValue(False) + calTaEnableAesAuth = srcComponent.getSymbolByID('CAL_ENABLE_TA100_AES_AUTH') + calTaEnableAesAuth.setValue(False) else: _ca_dev_cnt -= 1 if 0 == _ca_dev_cnt: @@ -204,6 +237,9 @@ def onAttachmentDisconnected(source, target): WolfCrypto = srcComponent.getSymbolByID('CAL_FILE_SRC_WOLFSSL_WRAPPER') WolfCrypto.setEnabled(False) + + calTaEnableAesAuth = srcComponent.getSymbolByID('CAL_ENABLE_TA100_AES_AUTH') + calTaEnableAesAuth.setValue(False) print('disconnected lib_wolfcrypt') @@ -307,6 +343,38 @@ def instantiateComponent(calComponent): calLibI2cHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") calLibI2cHalSrcFile.setType('SOURCE') calLibI2cHalSrcFile.setEnabled(False) + + calLibUartHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_UART", None) + calLibUartHalSrcFile.setSourcePath("lib/hal/hal_uart_harmony.c") + calLibUartHalSrcFile.setOutputName("hal_uart_harmony.c") + calLibUartHalSrcFile.setDestPath("library/cryptoauthlib/hal") + calLibUartHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") + calLibUartHalSrcFile.setType('SOURCE') + calLibUartHalSrcFile.setEnabled(False) + + calLibSwiUartHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_SWI_UART", None) + calLibSwiUartHalSrcFile.setSourcePath("lib/hal/hal_swi_uart.c") + calLibSwiUartHalSrcFile.setOutputName("hal_swi_uart.c") + calLibSwiUartHalSrcFile.setDestPath("library/cryptoauthlib/hal") + calLibSwiUartHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") + calLibSwiUartHalSrcFile.setType('SOURCE') + calLibSwiUartHalSrcFile.setEnabled(False) + + calLibSwiBBHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_BB", None) + calLibSwiBBHalSrcFile.setSourcePath("lib/hal/hal_gpio_harmony.c") + calLibSwiBBHalSrcFile.setOutputName("hal_gpio_harmony.c") + calLibSwiBBHalSrcFile.setDestPath("library/cryptoauthlib/hal") + calLibSwiBBHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") + calLibSwiBBHalSrcFile.setType('SOURCE') + calLibSwiBBHalSrcFile.setEnabled(False) + + calLibSwiBBHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_SWI_BB", None) + calLibSwiBBHalSrcFile.setSourcePath("lib/hal/hal_swi_bitbang_harmony.c") + calLibSwiBBHalSrcFile.setOutputName("hal_swi_bitbang_harmony.c") + calLibSwiBBHalSrcFile.setDestPath("library/cryptoauthlib/hal") + calLibSwiBBHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") + calLibSwiBBHalSrcFile.setType('SOURCE') + calLibSwiBBHalSrcFile.setEnabled(False) calLibSpiHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_SPI", None) calLibSpiHalSrcFile.setSourcePath("lib/hal/hal_spi_harmony.c") @@ -317,6 +385,10 @@ def instantiateComponent(calComponent): calLibSpiHalSrcFile.setEnabled(False) # List of HALs that will be included based on device connections + calHalList = calComponent.createListSymbol('CAL_HAL_LIST', None) + calHalList = calComponent.createListEntrySymbol('CAL_HAL_LIST_ENTRIES', None) + calHalList.setTarget('cryptoauthlib.CAL_HAL_LIST') + calPlibList = calComponent.createListSymbol('CAL_PLIB_LIST', None) calPlibList = calComponent.createListEntrySymbol('CAL_PLIB_LIST_ENTRIES', None) calPlibList.setTarget('cryptoauthlib.CAL_PLIB_LIST') @@ -325,6 +397,15 @@ def instantiateComponent(calComponent): calDeviceList = calComponent.createListSymbol('CAL_DEVICE_LIST', None) calDeviceList = calComponent.createListEntrySymbol('CAL_DEVICE_LIST_ENTRIES', None) calDeviceList.setTarget('cryptoauthlib.CAL_DEVICE_LIST') + + # Add device specific options + calTaEnableAesAuth = calComponent.createBooleanSymbol('CAL_ENABLE_TA100_AES_AUTH', None) + calTaEnableAesAuth.setValue(False) + calTaEnableAesAuth.setVisible(True) + + calTaEnableFce = calComponent.createBooleanSymbol('CAL_ENABLE_TA100_FCE', None) + calTaEnableFce.setValue(False) + calTaEnableFce.setVisible(True) ################# Templated files to be included ####################### diff --git a/harmony/config/device_instance.py b/harmony/config/device_instance.py index e2a6cf4aa..8afc5076b 100644 --- a/harmony/config/device_instance.py +++ b/harmony/config/device_instance.py @@ -23,8 +23,8 @@ *****************************************************************************""" _DEFAULT_I2C_ADDRESS = {'ecc': 0xC0, 'sha': 0xC8, 'ta100': 0x2e} -_SWI_DEVICES = ['ATSHA204A', 'ATSHA206A', 'ATECC108A', 'ATECC508A', 'ATECC608'] -_I2C_DEVICES = ['ATSHA204A', 'ATECC108A', 'ATECC508A', 'ATECC608', 'TA100'] +_SWI_DEVICES = ['ATSHA204A', 'ATSHA206A', 'ATECC108A', 'ATECC508A', 'ATECC608', 'ECC204'] +_I2C_DEVICES = ['ATSHA204A', 'ATECC108A', 'ATECC508A', 'ATECC608', 'TA100', 'ECC204'] _SPI_DEVICES = ['TA100'] @@ -36,29 +36,56 @@ def updateTngCapability(id, src): Database.sendMessage('cryptoauthlib_tng', 'UPDATE_TNG_TYPE', {'id': id, 'src': src}) +def updateSwiBbInterfaceSettings(symbol, swi_bb_iface): + if swi_bb_iface: + symbol.getComponent().getSymbolByID('HAL_INTERFACE').setValue("GPIO") + updateSercomPlibList("GPIO_SWI_BB", swi_bb_iface) + else: + if symbol.getComponent().getSymbolByID('INTERFACE').getReadOnly(): + pass + else: + try: + symbol.getComponent().getSymbolByID('HAL_INTERFACE').clearValue() + except AttributeError: + pass + updateSercomPlibList("GPIO_SWI_BB", swi_bb_iface) + + def updatePartInterfaceSettings(symbol, event): symObj = event['symbol'] updateId = event['id'].upper() selected_key = symObj.getSelectedKey() + SWI_BB_IFACE = False if updateId == 'INTERFACE': if selected_key == 'ATCA_SPI_IFACE': symbol.setVisible('SPI' in symbol.getID()) + symbol.getComponent().getSymbolByID('I2C_ADDR').setVisible(False) elif selected_key == 'ATCA_I2C_IFACE': symbol.setVisible('I2C' in symbol.getID()) + elif selected_key == 'ATCA_SWI_IFACE': + symbol.setVisible('SWI_UART' in symbol.getID()) + symbol.getComponent().getSymbolByID('I2C_ADDR').setVisible(False) + elif selected_key == 'ATCA_SWI_BB_IFACE': + SWI_BB_IFACE = True + symbol.setVisible('SWIBB' in symbol.getID()) + symbol.getComponent().getSymbolByID('I2C_ADDR').setVisible(False) + + updateSwiBbInterfaceSettings(symbol, SWI_BB_IFACE) elif updateId == 'PART_TYPE': if selected_key == "TNGTLS": Database.activateComponents(['cryptoauthlib_tng']) - symbol.setValue(0x6A) + i2c_addr = 0x6A elif selected_key == "TFLEX": Database.activateComponents(['cryptoauthlib_tng']) - symbol.setValue(0x6C) + i2c_addr = 0x6C elif selected_key == "TNGLORA": Database.activateComponents(['cryptoauthlib_tng']) - symbol.setValue(0xB2) + i2c_addr = 0xB2 else: - symbol.setValue(0xC0) + i2c_addr = 0xC0 + symbol.getComponent().getSymbolByID('I2C_ADDR').setValue(i2c_addr) updateTngCapability(selected_key, event['namespace']) @@ -84,10 +111,11 @@ def instantiateComponent(deviceComponent, index): interfaceType.setLabel('Interface Type') if deviceType in _I2C_DEVICES: interfaceType.addKey("ATCA_I2C_IFACE", "0", "I2C") -# if deviceType in _SWI_DEVICES: -# interfaceType.addKey("ATCA_SWI_IFACE", "1", "SWI") + if deviceType in _SWI_DEVICES: + interfaceType.addKey("ATCA_SWI_IFACE", "1", "SWI") + interfaceType.addKey("ATCA_SWI_BB_IFACE", "2", "SWI_BB") if deviceType in _SPI_DEVICES: - interfaceType.addKey("ATCA_SPI_IFACE", "2", "SPI") + interfaceType.addKey("ATCA_SPI_IFACE", "3", "SPI") interfaceType.setDefaultValue(0) interfaceType.setOutputMode("Key") interfaceType.setDisplayMode("Description") @@ -102,22 +130,25 @@ def instantiateComponent(deviceComponent, index): devicePartType.setDefaultValue(0) devicePartType.setOutputMode("Key") devicePartType.setDisplayMode("Description") - - deviceAddress = deviceComponent.createHexSymbol("I2C_ADDR", devicePartType) - deviceAddress.setLabel("I2C Address") - deviceAddress.setDefaultValue(0xC0) - else: - deviceAddress = deviceComponent.createHexSymbol("I2C_ADDR", interfaceType) - deviceAddress.setLabel("I2C Address") - - if 'ECC' in deviceID: - deviceAddress.setDefaultValue(_DEFAULT_I2C_ADDRESS['ecc']) - elif 'SHA' in deviceID: - deviceAddress.setDefaultValue(_DEFAULT_I2C_ADDRESS['sha']) - elif 'TA' in deviceID: - deviceAddress.setDefaultValue(_DEFAULT_I2C_ADDRESS['ta100']) - - deviceAddress.setDependencies(updatePartInterfaceSettings, ["PART_TYPE"]) + devicePartType.setDependencies(updatePartInterfaceSettings, ["PART_TYPE"]) + + deviceAddress = deviceComponent.createHexSymbol("I2C_ADDR", interfaceType) + deviceAddress.setLabel("I2C Address") + + if 'ECC' in deviceID: + deviceAddress.setDefaultValue(_DEFAULT_I2C_ADDRESS['ecc']) + elif 'SHA' in deviceID: + deviceAddress.setDefaultValue(_DEFAULT_I2C_ADDRESS['sha']) + elif 'TA' in deviceID: + deviceAddress.setDefaultValue(_DEFAULT_I2C_ADDRESS['ta100']) + + deviceAddress.setDependencies(updatePartInterfaceSettings, ["INTERFACE"]) + deviceAddress.setVisible(True) + + swiUartComment = deviceComponent.createCommentSymbol("SWI_UART_COMMENT", interfaceType) + swiUartComment.setLabel("!!! Select UART Ring buffer mode in UART configuration.!!! ") + swiUartComment.setDependencies(updatePartInterfaceSettings, ["INTERFACE"]) + swiUartComment.setVisible(False) spiCsComment = deviceComponent.createCommentSymbol("SPI_CS_PINS_COMMENT", interfaceType) spiCsComment.setLabel("!!! Configure the Chip Select pin as GPIO OUTPUT in Pin Settings.!!! ") @@ -132,6 +163,20 @@ def instantiateComponent(deviceComponent, index): spiChipSelectPin.setDependencies(updatePartInterfaceSettings, ["INTERFACE"]) spiChipSelectPin.setVisible(False) + swibbPinComment = deviceComponent.createCommentSymbol("SWIBB_PIN_COMMENT", interfaceType) + swibbPinComment.setLabel("!!! Configure the SWI Crypto pin as GPIO INPUT.!!! ") + swibbPinComment.setDependencies(updatePartInterfaceSettings, ["INTERFACE"]) + swibbPinComment.setVisible(False) + + # Gpio pin configuration for swi bitbang + swibbCryptoPin = deviceComponent.createKeyValueSetSymbol("SWIBB_CRYPTO_PIN", interfaceType) + swibbCryptoPin.setLabel("SWIBB Crypto Pin") + swibbCryptoPin.setDefaultValue(0) + swibbCryptoPin.setOutputMode("Key") + swibbCryptoPin.setDisplayMode("Description") + swibbCryptoPin.setDependencies(updatePartInterfaceSettings, ["INTERFACE"]) + swibbCryptoPin.setVisible(False) + availablePinDictionary = {} availablePinDictionary = Database.sendMessage("core", "PIN_LIST", availablePinDictionary) @@ -140,6 +185,7 @@ def instantiateComponent(deviceComponent, index): value = list(availablePinDictionary.keys())[list(availablePinDictionary.values()).index(pad)] description = pad spiChipSelectPin.addKey(key, value, description) + swibbCryptoPin.addKey(key, value, description) wakeupDelay = deviceComponent.createIntegerSymbol("WAKEUP_DELAY", None) wakeupDelay.setLabel("Wakeup Delay (us)") @@ -179,7 +225,14 @@ def onAttachmentConnected(source, target): elif 'SPI' in sourceID: source['component'].getSymbolByID('HAL_INTERFACE').setValue(targetID) source['component'].getSymbolByID('INTERFACE').setReadOnly(True) - source['component'].getSymbolByID('INTERFACE').setSelectedKey('ATCA_SPI_IFACE', 1) + source['component'].getSymbolByID('INTERFACE').setSelectedKey('ATCA_SPI_IFACE', 3) + updateSercomPlibList(target['id'], True) + elif 'SWI' in sourceID: + source['component'].getSymbolByID('HAL_INTERFACE').setValue(targetID) + source['component'].getSymbolByID('INTERFACE').setReadOnly(True) + source['component'].getSymbolByID('INTERFACE').setSelectedKey('ATCA_SWI_IFACE', 1) + if "uart" in target['id'].lower(): + target['id'] = target['id'].replace("UART", "SWI_UART") updateSercomPlibList(target['id'], True) @@ -205,5 +258,16 @@ def onAttachmentDisconnected(source, target): # Happens when the instance is deleted while attached pass updateSercomPlibList(target['id'], False) + elif 'SWI' in sourceID: + try: + source['component'].getSymbolByID('HAL_INTERFACE').clearValue() + source['component'].getSymbolByID('INTERFACE').clearValue() + source['component'].getSymbolByID('INTERFACE').setReadOnly(False) + except AttributeError: + # Happens when the instance is deleted while attached + pass + if "uart" in target['id'].lower(): + target['id'] = target['id'].replace("UART", "SWI_UART") + updateSercomPlibList(target['id'], False) diff --git a/harmony/module.py b/harmony/module.py index 1874d132e..a85e19e00 100644 --- a/harmony/module.py +++ b/harmony/module.py @@ -23,7 +23,7 @@ import os -_CALIB_SUPPORTED_DEVICES = ['ATECC108A', 'ATECC508A', 'ATECC608', 'ATSHA204A'] +_CALIB_SUPPORTED_DEVICES = ['ATECC108A', 'ATECC508A', 'ATECC608', 'ATSHA204A', 'ATSHA206A', 'ECC204'] _TALIB_SUPPORTED_DEVICES = ['TA100'] def loadModule(): @@ -45,10 +45,16 @@ def loadModule(): cryptoAuthLibTest.setDisplayType("Library Testing Application") cryptoAuthLibTest.addDependency("CAL_LIB_CAP", "CA_LIB", True, False) + # cryptoAuthLibSwiBB = Module.CreateSharedComponent("cryptoauthlib_swibb", "SWI_BB", "/Libraries/Cryptoauthlib", "/harmony/config/swi_bb.py") + # cryptoAuthLibSwiBB.setDisplayType("SWI BitBang Hal Interface") + # cryptoAuthLibSwiBB.addDependency("CAL_LIB_CAP", "CA_LIB", True, False) + # cryptoAuthLibSwiBB.addCapability("GPIO_SWI_BB", "UART", "SWI_BB", False) + for dev in _CALIB_SUPPORTED_DEVICES: comp = Module.CreateGeneratorComponent(dev.lower(), dev, "/Harmony/Drivers/Crypto", "/harmony/config/device_common.py", "/harmony/config/device_instance.py") comp.addDependency("cryptoauthlib", "CA_LIB", True, False) - comp.addMultiDependency('{}_DEP_PLIB_I2C'.format(dev.upper()), 'I2C', 'I2C', True) + comp.addMultiDependency('{}_DEP_PLIB_I2C'.format(dev.upper()), 'I2C', 'I2C', False) + comp.addMultiDependency('{}_DEP_PLIB_SWI'.format(dev.upper()), 'UART', 'SWI', False) if os.path.exists(Module.getPath() + 'lib/talib/talib_basic.h'): for dev in _TALIB_SUPPORTED_DEVICES: diff --git a/harmony/templates/atca_config.h.ftl b/harmony/templates/atca_config.h.ftl index 66dccae60..384d22dcd 100644 --- a/harmony/templates/atca_config.h.ftl +++ b/harmony/templates/atca_config.h.ftl @@ -5,28 +5,16 @@ /* MPLAB Harmony Common Include */ #include "definitions.h" -<#assign pliblist = CAL_PLIB_LIST?word_list> +<#assign pliblist = CAL_HAL_LIST?word_list> <#if pliblist?size != 0> <#list pliblist as plib_id> -<#assign plib_info = plib_id?split("_")> -<#if plib_info?size == 1 || plib_info[1] == "i2c"> -<#assign atca_hal_i2c = true> -<#elseif plib_info[1] == "spi"> -<#assign atca_hal_spi = true> - +#ifndef ATCA_HAL_${plib_id} +#define ATCA_HAL_${plib_id} +#endif + -<#if atca_hal_i2c??> -#ifndef ATCA_HAL_I2C -#define ATCA_HAL_I2C -#endif - -<#if atca_hal_spi??> -#ifndef ATCA_HAL_SPI -#define ATCA_HAL_SPI -#endif - <#assign devices = CAL_DEVICE_LIST?word_list> <#if devices?size != 0> @@ -36,6 +24,17 @@ +<#if CAL_ENABLE_TA100_AES_AUTH> +/** TA100 Specific - Enable auth sessions that require AES (CMAC/GCM) from + an external library */ +#define ATCA_TA100_AES_AUTH_SUPPORT + + +<#if CAL_ENABLE_TA100_FCE> +/** TA100 Specific - Enable support for the FCE APIs for the TA100 */ +#define ATCA_TA100_FCE_SUPPORT + + <#if !CAL_ENABLE_POLLING> /** Define if cryptoauthlib is to use the maximum execution time method */ #ifndef ATCA_NO_POLL @@ -91,23 +90,24 @@ /* Define generic interfaces to the processor libraries */ <#assign pliblist = CAL_PLIB_LIST?word_list> <#if pliblist?size != 0> +<#list pliblist as plib_id> +<#assign plib_info = plib_id?split("_", 1)> +<#if plib_info[1] == "i2c"> <#assign size_var = "size_t"> - -<#if atca_hal_i2c??> -<#if pliblist[0]?contains("sercom")> +<#if plib_id?contains("sercom")> #define PLIB_I2C_ERROR SERCOM_I2C_ERROR #define PLIB_I2C_ERROR_NONE SERCOM_I2C_ERROR_NONE #define PLIB_I2C_TRANSFER_SETUP SERCOM_I2C_TRANSFER_SETUP <#assign size_var = "uint32_t"> -<#elseif pliblist[0]?contains("flexcom")> +<#elseif plib_id?contains("flexcom")> #define PLIB_I2C_ERROR FLEXCOM_TWI_ERROR #define PLIB_I2C_ERROR_NONE FLEXCOM_TWI_ERROR_NONE #define PLIB_I2C_TRANSFER_SETUP FLEXCOM_TWI_TRANSFER_SETUP -<#elseif pliblist[0]?contains("twihs")> +<#elseif plib_id?contains("twihs")> #define PLIB_I2C_ERROR TWIHS_ERROR #define PLIB_I2C_ERROR_NONE TWIHS_ERROR_NONE #define PLIB_I2C_TRANSFER_SETUP TWIHS_TRANSFER_SETUP -<#elseif pliblist[0]?contains("i2c")> +<#elseif plib_id?contains("i2c")> #define PLIB_I2C_ERROR I2C_ERROR #define PLIB_I2C_ERROR_NONE I2C_ERROR_NONE #define PLIB_I2C_TRANSFER_SETUP I2C_TRANSFER_SETUP @@ -128,7 +128,8 @@ typedef struct atca_plib_api atca_i2c_plib_transfer_setup transfer_setup; } atca_plib_i2c_api_t; -<#if atca_hal_spi??> + +<#if plib_info[1] == "spi"> typedef bool (* atca_spi_plib_read)( void * , size_t ); typedef bool (* atca_spi_plib_write)( void *, size_t ); typedef bool (* atca_spi_plib_is_busy)( void ); @@ -143,12 +144,115 @@ typedef struct atca_plib_spi_api } atca_plib_spi_api_t; -<#list pliblist as plib_id> -<#assign plib_info = plib_id?split("_")> -extern atca_plib_${plib_info[1]!"i2c"}_api_t ${plib_info[0]}_plib_${plib_info[1]!"i2c"}_api; +<#if plib_info[1] == "swi"> +<#if plib_info[2] == "uart"> +<#if plib_id?contains("flexcom")> +#define PLIB_SWI_ERROR FLEXCOM_USART_ERROR +#define PLIB_SWI_SERIAL_SETUP FLEXCOM_USART_SERIAL_SETUP +#define PLIB_SWI_READ_ERROR FLEXCOM_USART_EVENT_READ_ERROR +#define PLIB_SWI_READ_CALLBACK FLEXCOM_USART_RING_BUFFER_CALLBACK +#define PLIB_SWI_PARITY_NONE FLEXCOM_USART_PARITY_NONE +#define PLIB_SWI_DATA_WIDTH FLEXCOM_USART_DATA_7_BIT +#define PLIB_SWI_STOP_BIT FLEXCOM_USART_STOP_1_BIT +#define PLIB_SWI_EVENT FLEXCOM_USART_EVENT +<#elseif plib_id?contains("sercom")> +#define PLIB_SWI_ERROR USART_ERROR +#define PLIB_SWI_SERIAL_SETUP USART_SERIAL_SETUP +#define PLIB_SWI_READ_ERROR SERCOM_USART_EVENT_READ_ERROR +#define PLIB_SWI_READ_CALLBACK SERCOM_USART_RING_BUFFER_CALLBACK +#define PLIB_SWI_PARITY_NONE USART_PARITY_NONE +#define PLIB_SWI_DATA_WIDTH USART_DATA_7_BIT +#define PLIB_SWI_STOP_BIT USART_STOP_1_BIT +#define PLIB_SWI_EVENT SERCOM_USART_EVENT +<#elseif plib_id?contains("usart")> +#define PLIB_SWI_ERROR USART_ERROR +#define PLIB_SWI_SERIAL_SETUP USART_SERIAL_SETUP +#define PLIB_SWI_READ_ERROR USART_EVENT_READ_ERROR +#define PLIB_SWI_READ_CALLBACK USART_RING_BUFFER_CALLBACK +#define PLIB_SWI_PARITY_NONE USART_PARITY_NONE +#define PLIB_SWI_DATA_WIDTH USART_DATA_7_BIT +#define PLIB_SWI_STOP_BIT USART_STOP_1_BIT +#define PLIB_SWI_EVENT USART_EVENT + + +typedef size_t (* atca_swi_plib_read)( uint8_t *, const size_t ); +typedef size_t (* atca_swi_plib_write)( uint8_t *, const size_t ); +typedef PLIB_SWI_ERROR (* atca_swi_error_get)( void ); +typedef bool (* atca_swi_plib_serial_setup)(PLIB_SWI_SERIAL_SETUP* , uint32_t ); +typedef size_t (* atca_swi_plib_readcount_get)( void ); +typedef void (* atca_swi_plib_readcallbackreg)(PLIB_SWI_READ_CALLBACK, uintptr_t ); + +typedef struct atca_plib_swi_api +{ + atca_swi_plib_read read; + atca_swi_plib_write write; + atca_swi_error_get error_get; + atca_swi_plib_serial_setup serial_setup; + atca_swi_plib_readcount_get readcount_get; + atca_swi_plib_readcallbackreg readcallback_reg; +} atca_plib_swi_uart_api_t; + +/** SWI Transmit delay */ +#define SWI_TX_DELAY ((uint32_t)90) +<#elseif plib_info[2] == "bb"> +typedef bool (* atca_swi_plib_read)( uint8_t ); +typedef void (* atca_swi_plib_write)( uint8_t, bool ); +typedef void (* atca_swi_set_pin_output)( uint8_t ); +typedef void (* atca_swi_set_pin_input)( uint8_t ); + +typedef struct atca_plib_swi_api +{ + atca_swi_plib_read read; + atca_swi_plib_write write; + atca_swi_set_pin_output set_pin_output_dir; + atca_swi_set_pin_input set_pin_input_dir; +}atca_plib_swi_bb_api_t; + +/** + * \name Macros for Bit-Banged SWI Timing + * + * Times to drive bits at 230.4 kbps. + @{ */ + +//! delay macro for width of one pulse (start pulse or zero pulse) +//! should be 4.34 us, is 4.05 us + +#define BIT_DELAY_1L atca_delay_us(4) +//! should be 4.34 us, is 4.05us +#define BIT_DELAY_1H atca_delay_us(4) + +//! time to keep pin high for five pulses plus stop bit (used to bit-bang CryptoAuth 'zero' bit) +//! should be 26.04 us, is 26.92 us +#define BIT_DELAY_5 atca_delay_us(26) // considering pin set delay + +//! time to keep pin high for seven bits plus stop bit (used to bit-bang CryptoAuth 'one' bit) +//! should be 34.72 us, is 35.13 us +#define BIT_DELAY_7 atca_delay_us(34) // considering pin set delay + +//! turn around time when switching from receive to transmit +//! should be 93 us (Setting little less value as there would be other process before these steps) +#define RX_TX_DELAY atca_delay_us(65) + + + +<#if atca_hal_swi??> +/** SWI Flags */ +#define SWI_WAKE_TOKEN ((uint8_t)0x00) +#define SWI_FLAG_CMD ((uint8_t)0x77) +#define SWI_FLAG_TX ((uint8_t)0x88) +#define SWI_FLAG_IDLE ((uint8_t)0xBB) +#define SWI_FLAG_SLEEP ((uint8_t)0xCC) + + +<#list pliblist as plib_id> +<#assign plib_info = plib_id?split("_", 1)> +<#assign plib_drv = plib_id?substring(plib_id?index_of("_") + 1)> +extern atca_plib_${plib_drv!"i2c"}_api_t ${plib_info[0]}_plib_${plib_drv!"i2c"}_api; + + <#if cryptoauthlib_tng??> /** Define certificate templates to be supported. */ <#if cryptoauthlib_tng.CAL_TNGTLS_SUPPORT> diff --git a/harmony/templates/device_instance.c.ftl b/harmony/templates/device_instance.c.ftl index 1185bf2b2..44a176434 100644 --- a/harmony/templates/device_instance.c.ftl +++ b/harmony/templates/device_instance.c.ftl @@ -9,24 +9,38 @@ #include "cryptoauthlib.h" <#assign PLIB_NAME = core.PORT_API_PREFIX?string> - ATCAIfaceCfg ${NAME?lower_case}_${INDEX?string}_init_data = { +<#if INTERFACE == "ATCA_SWI_BB_IFACE"> +<#assign INTERFACE = "ATCA_SWI_IFACE"> + .iface_type = ${INTERFACE}, .devtype = ${NAME?upper_case}, <#if INTERFACE == "ATCA_I2C_IFACE"> <#assign plib_type = "i2c"> - .atcai2c.slave_address = 0x${I2C_ADDR?upper_case}, + .atcai2c.address = 0x${I2C_ADDR?upper_case}, .atcai2c.bus = 0, +<#if HAL_INTERFACE?contains("FLEXCOM") || HAL_INTERFACE?contains("SERCOM")> .atcai2c.baud = ${.vars["${HAL_INTERFACE?lower_case}"].I2C_CLOCK_SPEED}000, +<#else> + .atcai2c.baud = ${.vars["${HAL_INTERFACE?lower_case}"].I2C_CLOCK_SPEED}, + <#elseif INTERFACE == "ATCA_SPI_IFACE"> <#assign plib_type = "spi"> .atcaspi.bus = 0, - .atcaspi.select_pin = ${PLIB_NAME}_PIN_${SPI_CS_PIN?upper_case}, + .atcaspi.select_pin = ${PLIB_NAME}_PIN_${SPI_CS_PIN?upper_case}, <#if HAL_INTERFACE?contains("FLEXCOM")> - .atcaspi.baud = ${.vars["${HAL_INTERFACE?lower_case}"].FLEXCOM_SPI_BAUD_RATE}, + .atcaspi.baud = ${.vars["${HAL_INTERFACE?lower_case}"].FLEXCOM_SPI_BAUD_RATE}, <#else> .atcaspi.baud = ${.vars["${HAL_INTERFACE?lower_case}"].SPI_BAUD_RATE}, +<#elseif INTERFACE == "ATCA_SWI_IFACE"> +<#if HAL_INTERFACE?contains("GPIO")> +<#assign plib_type = "swi_bb"> + .atcaswi.bus = ${PLIB_NAME}_PIN_${SWIBB_CRYPTO_PIN?upper_case}, +<#else> +<#assign plib_type = "swi_uart"> + .atcaswi.bus = 0, + .wake_delay = ${WAKEUP_DELAY}, .rx_retries = ${RECEIVE_RETRY}, diff --git a/harmony/templates/hal_harmony_init.c.ftl b/harmony/templates/hal_harmony_init.c.ftl index 85485fb66..2d4e77973 100644 --- a/harmony/templates/hal_harmony_init.c.ftl +++ b/harmony/templates/hal_harmony_init.c.ftl @@ -55,12 +55,42 @@ atca_plib_spi_api_t ${plib_info[0]}_plib_spi_api = { .write = ${.vars["${plib_info[0]}"].SPI_PLIB_API_PREFIX}_Write, .is_busy = ${.vars["${plib_info[0]}"].SPI_PLIB_API_PREFIX}_IsBusy, .select = &${plib_info[0]}_select_pin -<#elseif plib_info[1] == "uart"> -atca_plib_swi_api_t ${plib_info[0]}_plib_swi_api = { +<#elseif plib_info[1] == "swi"> +<#if plib_info[2] == "uart"> +atca_plib_swi_uart_api_t ${plib_info[0]}_plib_swi_uart_api = { .read = ${.vars["${plib_info[0]}"].USART_PLIB_API_PREFIX}_Read, .write = ${.vars["${plib_info[0]}"].USART_PLIB_API_PREFIX}_Write, .error_get = ${.vars["${plib_info[0]}"].USART_PLIB_API_PREFIX}_ErrorGet, - .transfer_setup = ${.vars["${plib_info[0]}"].USART_PLIB_API_PREFIX}_SerialSetup + .serial_setup = ${.vars["${plib_info[0]}"].USART_PLIB_API_PREFIX}_SerialSetup, + .readcount_get = ${.vars["${plib_info[0]}"].USART_PLIB_API_PREFIX}_ReadCountGet, + .readcallback_reg = ${.vars["${plib_info[0]}"].USART_PLIB_API_PREFIX}_ReadCallbackRegister +<#elseif plib_info[1] == "gpio"> +static void ${plib_info[0]}_SetupPinDirection(uint32_t pin, uint8_t pin_dir) +{ + if (pin_dir == 0) { + ${PLIB_NAME}_PinInputEnable(pin); + } + else + { + ${PLIB_NAME}_PinOutputEnable(pin); + } +} + +static void ${plib_info[0]}_Write(uint32_t pin, bool value) +{ + ${PLIB_NAME}_PinWrite(pin, value); +} + +static bool ${plib_info[0]}_Read(uint32_t pin) +{ + return ${PLIB_NAME}_PinRead(pin); +} + +atca_plib_gpio_api_t ${plib_info[0]}_plib_gpio_api = { + .read = ${.vars["${plib_info[0]}"].GPIO_PLIB_API_PREFIX}_Read, + .write = ${.vars["${plib_info[0]}"].GPIO_PLIB_API_PREFIX}_Write, + .pin_setup = ${.vars["${plib_info[0]}"].GPIO_PLIB_API_PREFIX}_SetupPinDirection + }; diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 57cb39593..69657eb28 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -4,31 +4,45 @@ project(cryptoauth C) include(CMakeDependentOption) include(CheckSymbolExists) -# Various Options for Build +# HAL Selection option(ATCA_HAL_KIT_HID "Include the HID HAL Driver") option(ATCA_HAL_KIT_BRIDGE "General purpose kit protocol (Packet and Stream)") option(ATCA_HAL_I2C "Include the I2C Hal Driver - Linux & MCU only") option(ATCA_HAL_SPI "Include the SPI HAL Driver - Linux & MCU only") option(ATCA_HAL_CUSTOM "Include support for Custom/Plug-in Hal Driver") + +# Library Options option(ATCA_PRINTF "Enable Debug print statements in library") option(ATCA_PKCS11 "Build PKCS11 Library") +option(ATCA_BUILD_SHARED_LIBS "Build CryptoAuthLib as shared library" ON) +option(ATCA_NO_HEAP "Do not use dynamic (heap) allocation functions" OFF) +option(ATCA_USE_ATCAB_FUNCTIONS "Build the atcab_ api functions rather than using macros" OFF) +option(ATCA_ENABLE_DEPRECATED "Enable the use of older APIs that that been replaced" OFF) + +# Software Cryptographic backend for host crypto abstractions option(ATCA_MBEDTLS "Integrate with mbedtls" OFF) option(ATCA_WOLFSSL "Integrate with WolfSSL" OFF) option(ATCA_OPENSSL "Integration with OpenSSL" OFF) + +# Trust Platform Options option(ATCA_TNGTLS_SUPPORT "Include Trust & Go TLS Certificates") option(ATCA_TNGLORA_SUPPORT "Include Trust & Go LORA Certificates") option(ATCA_TFLEX_SUPPORT "Include Trust Flex Certificates") option(ATCA_TNG_LEGACY_SUPPORT "Include previous version of Trust & Go Certificates") + +# Device enablement option(ATCA_ATSHA204A_SUPPORT "Include support for ATSHA204A device" ON) option(ATCA_ATSHA206A_SUPPORT "Include support for ATSHA206A device" ON) option(ATCA_ATECC108A_SUPPORT "Include support for ATECC108A device" ON) option(ATCA_ATECC508A_SUPPORT "Include support for ATECC508A device" ON) option(ATCA_ATECC608_SUPPORT "Include support for ATECC608 device" ON) option(ATCA_TA100_SUPPORT "Include support for TA100 device" OFF) +option(ATCA_ECC204_SUPPORT "Include support for ECC204 device" ON) + + +# TA100 Dependent Configuration options cmake_dependent_option(ATCA_TA100_AES_AUTH_SUPPORT "Include Encrypted (GCM) and CMAC Auth session support" ON "ATCA_TA100_SUPPORT" OFF) -option(ATCA_BUILD_SHARED_LIBS "Build CryptoAuthLib as shared library" ON) -option(ATCA_NO_HEAP "Do not use dynamic (heap) allocation functions" OFF) -option(ATCA_USE_ATCAB_FUNCTIONS "Build the atcab_ api functions rather than using macros" OFF) +cmake_dependent_option(ATCA_TA100_FCE_SUPPORT "Include FCE Support for the TA100" ON "ATCA_TA100_SUPPORT" OFF) # Check Options if (ATCA_MBEDTLS AND (ATCA_WOLFSSL OR ATCA_OPENSSL)) @@ -120,15 +134,30 @@ execute_process(COMMAND ${CMAKE_COMMAND} --build . #file(GLOB WOLFSSL_LIB_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../third_party/wolfssl/wolfcrypt/src/*.c") set(WOLFSSL_LIB_SRC ../third_party/wolfssl/wolfcrypt/src/aes.c + ../third_party/wolfssl/wolfcrypt/src/arc4.c + ../third_party/wolfssl/wolfcrypt/src/asn.c ../third_party/wolfssl/wolfcrypt/src/cmac.c + ../third_party/wolfssl/wolfcrypt/src/coding.c + ../third_party/wolfssl/wolfcrypt/src/des3.c + ../third_party/wolfssl/wolfcrypt/src/ecc.c + ../third_party/wolfssl/wolfcrypt/src/hash.c ../third_party/wolfssl/wolfcrypt/src/hmac.c + ../third_party/wolfssl/wolfcrypt/src/integer.c + ../third_party/wolfssl/wolfcrypt/src/memory.c + ../third_party/wolfssl/wolfcrypt/src/pwdbased.c + ../third_party/wolfssl/wolfcrypt/src/random.c + ../third_party/wolfssl/wolfcrypt/src/rsa.c ../third_party/wolfssl/wolfcrypt/src/sha.c ../third_party/wolfssl/wolfcrypt/src/sha256.c + ../third_party/wolfssl/wolfcrypt/src/tfm.c + ../third_party/wolfssl/wolfcrypt/src/wc_encrypt.c + ../third_party/wolfssl/wolfcrypt/src/wc_port.c + ../third_party/wolfssl/wolfcrypt/src/wolfmath.c ) add_library(wolfssl STATIC ${WOLFSSL_LIB_SRC}) -target_compile_definitions(wolfssl PRIVATE -DWC_NO_RNG -DWOLFSSL_AES_DIRECT -DHAVE_AESGCM -DWOLFSSL_CMAC -DNO_OLD_TLS -DNO_MD5) +target_compile_definitions(wolfssl PRIVATE -DWC_NO_HARDEN -DHAVE_ECC -DHAVE_ALL_CURVES -DWOLFCRYPT_ONLY -DWOLFSSL_PEM_TO_DER -DWOLFSSL_VALIDATE_ECC_IMPORT -DWOLFSSL_AES_DIRECT -DHAVE_AESGCM -DWOLFSSL_CMAC -DNO_OLD_TLS -DNO_MD5) include_directories(wolfssl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/wolfssl) @@ -149,7 +178,7 @@ endif(ATCA_OPENSSL) if (ATCA_ATSHA204A_SUPPORT OR ATCA_ATSHA206A_SUPPORT OR ATCA_ATECC108A_SUPPORT OR ATCA_ATECC508A_SUPPORT OR - ATCA_ATECC608_SUPPORT) + ATCA_ATECC608_SUPPORT OR ATCA_ECC204_SUPPORT) set(LIB_SRC ${LIB_SRC} ${CALIB_SRC} ${HOST_SRC}) endif() diff --git a/lib/atca_basic.c b/lib/atca_basic.c index 015a3121b..58308e662 100644 --- a/lib/atca_basic.c +++ b/lib/atca_basic.c @@ -40,7 +40,6 @@ const char atca_version[] = ATCA_LIBRARY_VERSION_DATE; ATCADevice _gDevice = NULL; #ifdef ATCA_NO_HEAP -SHARED_LIB_EXPORT struct atca_command g_atcab_command; SHARED_LIB_EXPORT struct atca_iface g_atcab_iface; SHARED_LIB_EXPORT struct atca_device g_atcab_device; #endif @@ -82,8 +81,7 @@ ATCA_STATUS atcab_init_ext(ATCADevice* device, ATCAIfaceCfg *cfg) } #ifdef ATCA_NO_HEAP - g_atcab_device.mCommands = &g_atcab_command; - g_atcab_device.mIface = &g_atcab_iface; + g_atcab_device.mIface = g_atcab_iface; status = initATCADevice(cfg, &g_atcab_device); if (status != ATCA_SUCCESS) { @@ -101,11 +99,11 @@ ATCA_STATUS atcab_init_ext(ATCADevice* device, ATCAIfaceCfg *cfg) #ifdef ATCA_ATECC608_SUPPORT if (cfg->devtype == ATECC608) { - if ((status = calib_read_bytes_zone(*device, ATCA_ZONE_CONFIG, 0, ATCA_CHIPMODE_OFFSET, &(*device)->mCommands->clock_divider, 1)) != ATCA_SUCCESS) + if ((status = calib_read_bytes_zone(*device, ATCA_ZONE_CONFIG, 0, ATCA_CHIPMODE_OFFSET, &(*device)->clock_divider, 1)) != ATCA_SUCCESS) { return status; } - (*device)->mCommands->clock_divider &= ATCA_CHIPMODE_CLOCK_DIV_MASK; + (*device)->clock_divider &= ATCA_CHIPMODE_CLOCK_DIV_MASK; } #endif } @@ -142,11 +140,6 @@ ATCA_STATUS atcab_init_device(ATCADevice ca_device) return ATCA_BAD_PARAM; } - if (atGetCommands(ca_device) == NULL || atGetIFace(ca_device) == NULL) - { - return ATCA_GEN_FAIL; - } - // if there's already a device created, release it if (_gDevice) { @@ -203,9 +196,9 @@ ATCADeviceType atcab_get_device_type_ext(ATCADevice device) { ATCADeviceType ret = ATCA_DEV_UNKNOWN; - if (device && device->mIface && device->mIface->mIfaceCFG) + if (device && device->mIface.mIfaceCFG) { - ret = device->mIface->mIfaceCFG->devtype; + ret = device->mIface.mIfaceCFG->devtype; } return ret; } @@ -218,6 +211,26 @@ ATCADeviceType atcab_get_device_type(void) return atcab_get_device_type_ext(_gDevice); } +/** \brief Get the current device address based on the configured device + * and interface + * \return the device address if applicable else 0xFF + */ +uint8_t atcab_get_device_address(ATCADevice device) +{ + if (device && device->mIface.mIfaceCFG) + { + switch (device->mIface.mIfaceCFG->iface_type) + { + case ATCA_I2C_IFACE: + return device->mIface.mIfaceCFG->atcai2c.address; + default: + break; + } + } + return 0xFF; +} + + /** \brief Check whether the device is cryptoauth device * \return True if device is cryptoauth device or False. */ @@ -234,7 +247,7 @@ bool atcab_is_ta_device(ATCADeviceType dev_type) return (dev_type == TA100) ? true : false; } -#if (ATCA_CA_SUPPORT && ATCA_TA_SUPPORT) || defined(ATCA_USE_ATCAB_FUNCTIONS) +#if (ATCA_CA_SUPPORT && ATCA_TA_SUPPORT) || defined(ATCA_USE_ATCAB_FUNCTIONS) || defined(ATCA_ECC204_SUPPORT) /** \brief wakeup the CryptoAuth device * \return ATCA_SUCCESS on success, otherwise an error code. @@ -1552,7 +1565,16 @@ ATCA_STATUS atcab_lock_config_zone(void) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_lock_config_zone(_gDevice); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_lock_config_zone(_gDevice); +#endif + } + else + { + status = calib_lock_config_zone(_gDevice); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -1683,7 +1705,16 @@ ATCA_STATUS atcab_lock_data_slot(uint16_t slot) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_lock_data_slot(_gDevice, slot); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_lock_data_slot(_gDevice, slot); +#endif + } + else + { + status = calib_lock_data_slot(_gDevice, slot); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -2061,7 +2092,16 @@ ATCA_STATUS atcab_read_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_read_zone(_gDevice, zone, slot, block, offset, data, len); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_read_zone(_gDevice, zone, slot, block, offset, data, len); +#endif + } + else + { + status = calib_read_zone(_gDevice, zone, slot, block, offset, data, len); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -2091,7 +2131,16 @@ ATCA_STATUS atcab_is_locked(uint8_t zone, bool* is_locked) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_is_locked(_gDevice, zone, is_locked); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_is_locked(_gDevice, zone, is_locked); +#endif + } + else + { + status = calib_is_locked(_gDevice, zone, is_locked); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -2131,7 +2180,16 @@ ATCA_STATUS atcab_is_config_locked(bool* is_locked) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_is_locked(_gDevice, LOCK_ZONE_CONFIG, is_locked); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_is_locked(_gDevice, ATCA_ECC204_ZONE_CONFIG, is_locked); +#endif + } + else + { + status = calib_is_locked(_gDevice, LOCK_ZONE_CONFIG, is_locked); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -2160,7 +2218,16 @@ ATCA_STATUS atcab_is_data_locked(bool* is_locked) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_is_locked(_gDevice, LOCK_ZONE_DATA, is_locked); +#if defined(ATCA_ECC204_SUPPORT) + if (ECC204 == dev_type) + { + status = calib_ecc204_is_locked(_gDevice, ATCA_ECC204_ZONE_DATA, is_locked); + } + else +#endif + { + status = calib_is_locked(_gDevice, LOCK_ZONE_DATA, is_locked); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -2230,7 +2297,16 @@ ATCA_STATUS atcab_read_bytes_zone(uint8_t zone, uint16_t slot, size_t offset, ui if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_read_bytes_zone(_gDevice, zone, slot, offset, data, length); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_read_bytes_zone(_gDevice, zone, slot, offset, data, length); +#endif + } + else + { + status = calib_read_bytes_zone(_gDevice, zone, slot, offset, data, length); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -2260,7 +2336,16 @@ ATCA_STATUS atcab_read_serial_number(uint8_t* serial_number) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_read_serial_number(_gDevice, serial_number); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_read_serial_number(_gDevice, serial_number); +#endif + } + else + { + status = calib_read_serial_number(_gDevice, serial_number); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -2365,7 +2450,16 @@ ATCA_STATUS atcab_read_config_zone(uint8_t* config_data) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_read_config_zone(_gDevice, config_data); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_read_config_zone(_gDevice, config_data); +#endif + } + else + { + status = calib_read_config_zone(_gDevice, config_data); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -2403,7 +2497,16 @@ ATCA_STATUS atcab_cmp_config_zone(uint8_t* config_data, bool* same_config) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_cmp_config_zone(_gDevice, config_data, same_config); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_cmp_config_zone(_gDevice, config_data, same_config); +#endif + } + else + { + status = calib_cmp_config_zone(_gDevice, config_data, same_config); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -3132,7 +3235,16 @@ ATCA_STATUS atcab_sign_ext(ATCADevice device, uint16_t key_id, const uint8_t* ms if (atcab_is_ca_device(dev_type)) { #ifdef ATCA_ECC_SUPPORT - status = calib_sign(_gDevice, key_id, msg, signature); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_sign(_gDevice, key_id, msg, signature); +#endif + } + else + { + status = calib_sign(_gDevice, key_id, msg, signature); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -3617,7 +3729,16 @@ ATCA_STATUS atcab_write(uint8_t zone, uint16_t address, const uint8_t* value, co if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_write(_gDevice, zone, address, value, mac); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_write(_gDevice, zone, address, value, mac); +#endif + } + else + { + status = calib_write(_gDevice, zone, address, value, mac); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -3653,7 +3774,16 @@ ATCA_STATUS atcab_write_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_write_zone(_gDevice, zone, slot, block, offset, data, len); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_write_zone(_gDevice, zone, slot, block, offset, data, len); +#endif + } + else + { + status = calib_write_zone(_gDevice, zone, slot, block, offset, data, len); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -3697,7 +3827,16 @@ ATCA_STATUS atcab_write_bytes_zone(uint8_t zone, uint16_t slot, size_t offset_by if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_write_bytes_zone(_gDevice, zone, slot, offset_bytes, data, length); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_write_bytes_zone(_gDevice, zone, slot, offset_bytes, data, length); +#endif + } + else + { + status = calib_write_bytes_zone(_gDevice, zone, slot, offset_bytes, data, length); + } #endif } else if (atcab_is_ta_device(dev_type)) @@ -3771,7 +3910,16 @@ ATCA_STATUS atcab_write_config_zone(const uint8_t* config_data) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_write_config_zone(_gDevice, config_data); + if (ECC204 == dev_type) + { +#if defined(ATCA_ECC204_SUPPORT) + status = calib_ecc204_write_config_zone(_gDevice, config_data); +#endif + } + else + { + status = calib_write_config_zone(_gDevice, config_data); + } #endif } else if (atcab_is_ta_device(dev_type)) diff --git a/lib/atca_basic.h b/lib/atca_basic.h index 1d93aa8f5..f23713c21 100644 --- a/lib/atca_basic.h +++ b/lib/atca_basic.h @@ -57,11 +57,11 @@ ATCA_STATUS atcab_release(void); ATCADevice atcab_get_device(void); ATCADeviceType atcab_get_device_type_ext(ATCADevice device); ATCADeviceType atcab_get_device_type(void); +uint8_t atcab_get_device_address(ATCADevice device); bool atcab_is_ca_device(ATCADeviceType dev_type); bool atcab_is_ta_device(ATCADeviceType dev_type); -#define atcab_cfg_discover(...) calib_cfg_discover(__VA_ARGS__) #define atcab_get_addr(...) calib_get_addr(__VA_ARGS__) #define atca_execute_command(...) calib_execute_command(__VA_ARGS__) @@ -105,7 +105,7 @@ ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* -#if ATCA_CA_SUPPORT && !ATCA_TA_SUPPORT && !defined(ATCA_USE_ATCAB_FUNCTIONS) +#if ATCA_CA_SUPPORT && !ATCA_TA_SUPPORT && !defined(ATCA_USE_ATCAB_FUNCTIONS) && !defined(ATCA_ECC204_SUPPORT) #define atcab_wakeup() calib_wakeup(_gDevice) #define atcab_idle() calib_idle(_gDevice) @@ -273,7 +273,6 @@ ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* #define atcab_sleep(...) (0) #define _atcab_exit(...) (1) #define atcab_get_zone_size(...) talib_get_zone_size(_gDevice, __VA_ARGS__) -//#define atcab_cfg_discover(...) (1) //#define atcab_get_addr(...) (1) // AES command functions @@ -431,14 +430,13 @@ ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* #endif -#if (ATCA_TA_SUPPORT && ATCA_CA_SUPPORT) || defined(ATCA_USE_ATCAB_FUNCTIONS) +#if (ATCA_TA_SUPPORT && ATCA_CA_SUPPORT) || defined(ATCA_USE_ATCAB_FUNCTIONS) || defined(ATCA_ECC204_SUPPORT) /* Basic global methods */ ATCA_STATUS _atcab_exit(void); ATCA_STATUS atcab_wakeup(void); ATCA_STATUS atcab_idle(void); ATCA_STATUS atcab_sleep(void); -//ATCA_STATUS atcab_cfg_discover(ATCAIfaceCfg cfg_array[], int max); //ATCA_STATUS atcab_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr); ATCA_STATUS atcab_get_zone_size(uint8_t zone, uint16_t slot, size_t* size); diff --git a/lib/atca_cfgs.c b/lib/atca_cfgs.c index 81026c037..0ad7a7e77 100644 --- a/lib/atca_cfgs.c +++ b/lib/atca_cfgs.c @@ -43,7 +43,11 @@ ATCAIfaceCfg cfg_ateccx08a_i2c_default = { .iface_type = ATCA_I2C_IFACE, .devtype = ATECC608, { +#ifdef ATCA_ENABLE_DEPRECATED .atcai2c.slave_address = 0xC0, +#else + .atcai2c.address = 0xC0, +#endif .atcai2c.bus = 2, .atcai2c.baud = 400000, //.atcai2c.baud = 100000, @@ -104,7 +108,11 @@ ATCAIfaceCfg cfg_atsha20xa_i2c_default = { .iface_type = ATCA_I2C_IFACE, .devtype = ATSHA204A, { +#ifdef ATCA_ENABLE_DEPRECATED .atcai2c.slave_address = 0xC8, +#else + .atcai2c.address = 0xC8, +#endif .atcai2c.bus = 2, .atcai2c.baud = 400000, }, @@ -156,4 +164,53 @@ ATCAIfaceCfg cfg_atsha20xa_kithid_default = { }; #endif +#if defined(ATCA_ECC_SUPPORT) && defined(ATCA_HAL_I2C) +/** \brief default configuration for an ECC204 device on the first logical I2C bus */ +ATCAIfaceCfg cfg_ecc204_i2c_default = { + .iface_type = ATCA_I2C_IFACE, + .devtype = ECC204, + { +#ifdef ATCA_ENABLE_DEPRECATED + .atcai2c.slave_address = 0x33, +#else + .atcai2c.address = 0x33, +#endif + .atcai2c.bus = 2, + .atcai2c.baud = 400000, + //.atcai2c.baud = 100000, + }, + .wake_delay = 1500, + .rx_retries = 20 +}; +#endif + +#if defined(ATCA_ECC_SUPPORT) && defined(ATCA_HAL_SWI) +/** \brief default configuration for an ECC204 device on the logical SWI over GPIO*/ +ATCAIfaceCfg cfg_ecc204_swi_default = { + .iface_type = ATCA_SWI_IFACE, + .devtype = ECC204, + { + .atcaswi.bus = 4, + }, + .wake_delay = 1500, + .rx_retries = 10 +}; +#endif + +#if defined(ATCA_ECC_SUPPORT) && defined(ATCA_HAL_KIT_HID) +/** \brief default configuration for Kit protocol over the device's async interface */ +ATCAIfaceCfg cfg_ecc204_kithid_default = { + .iface_type = ATCA_HID_IFACE, + .devtype = ECC204, + { + .atcahid.dev_interface = ATCA_KIT_AUTO_IFACE, + .atcahid.dev_identity = 0, + .atcahid.idx = 0, + .atcahid.vid = 0x03EB, + .atcahid.pid = 0x2312, + .atcahid.packetsize = 64, + } +}; +#endif + /** @} */ diff --git a/lib/atca_cfgs.h b/lib/atca_cfgs.h index 662638fc8..c6b4077e0 100644 --- a/lib/atca_cfgs.h +++ b/lib/atca_cfgs.h @@ -61,6 +61,17 @@ extern ATCAIfaceCfg cfg_atsha20xa_kitcdc_default; /** \brief default configuration for Kit protocol over a HID interface for SHA204 */ extern ATCAIfaceCfg cfg_atsha20xa_kithid_default; + +/** \brief default configuration for an ECC204 device on the first logical I2C bus */ +extern ATCAIfaceCfg cfg_ecc204_i2c_default; + +/** \brief default configuration for an ECC204 device on the logical SWI over GPIO*/ +extern ATCAIfaceCfg cfg_ecc204_swi_default; + +/** \brief default configuration for Kit protocol over the device's async interface */ +extern ATCAIfaceCfg cfg_ecc204_kithid_default; + + #ifdef __cplusplus } #endif diff --git a/lib/atca_command.c b/lib/atca_command.c deleted file mode 100644 index 9dfc7934c..000000000 --- a/lib/atca_command.c +++ /dev/null @@ -1,98 +0,0 @@ -/** - * \file - * \brief Microchip CryptoAuthentication device command builder - this is the main object that builds the command - * byte strings for the given device. It does not execute the command. The basic flow is to call - * a command method to build the command you want given the parameters and then send that byte string - * through the device interface. - * - * The primary goal of the command builder is to wrap the given parameters with the correct packet size and CRC. - * The caller should first fill in the parameters required in the ATCAPacket parameter given to the command. - * The command builder will deal with the mechanics of creating a valid packet using the parameter information. - * - * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. - * - * \page License - * - * Subject to your compliance with these terms, you may use Microchip software - * and any derivatives exclusively with Microchip products. It is your - * responsibility to comply with third party license terms applicable to your - * use of third party software (including open source software) that may - * accompany Microchip software. - * - * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER - * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED - * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, - * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE - * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF - * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE - * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL - * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED - * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR - * THIS SOFTWARE. - */ - -#include -#include -#include "atca_command.h" -#include "cryptoauthlib.h" - - -/** \brief Initializer for ATCACommand - * \param[in] device_type Specifies which set of commands and execution times - * should be associated with this command object. - * \param[in] ca_cmd Pre-allocated command structure to initialize. - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS initATCACommand(ATCADeviceType device_type, ATCACommand ca_cmd) -{ - if (ca_cmd == NULL) - { - return ATCA_BAD_PARAM; - } - - ca_cmd->dt = device_type; - ca_cmd->clock_divider = 0; - - return ATCA_SUCCESS; -} - -#ifndef ATCA_NO_HEAP -/** \brief constructor for ATCACommand - * \param[in] device_type Specifies which set of commands and execution times - * should be associated with this command object. - * \return Initialized object on success. NULL on failure. - */ -ATCACommand newATCACommand(ATCADeviceType device_type) -{ - ATCACommand ca_cmd; - ATCA_STATUS status; - - ca_cmd = (ATCACommand)malloc(sizeof(*ca_cmd)); - status = initATCACommand(device_type, ca_cmd); - if (status != ATCA_SUCCESS) - { - free(ca_cmd); - ca_cmd = NULL; - return NULL; - } - - return ca_cmd; -} -#endif - -#ifndef ATCA_NO_HEAP -/** \brief ATCACommand destructor - * \param[in] ca_cmd instance of a command object - */ -void deleteATCACommand(ATCACommand *ca_cmd) -{ - if (ca_cmd == NULL) - { - return; - } - - free(*ca_cmd); - *ca_cmd = NULL; -} -#endif diff --git a/lib/atca_command.h b/lib/atca_command.h deleted file mode 100644 index 855c07516..000000000 --- a/lib/atca_command.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * \file - * \brief Microchip Crypto Auth device command object - this is a command builder only, it does - * not send the command. The result of a command method is a fully formed packet, ready to send - * to the ATCAIFace object to dispatch. - * - * This command object supports the ATSHA and ATECC device family. - * The command list is a superset of all device commands for this family. The command object - * differentiates the packet contents based on specific device type within the family. - * - * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. - * - * \page License - * - * Subject to your compliance with these terms, you may use Microchip software - * and any derivatives exclusively with Microchip products. It is your - * responsibility to comply with third party license terms applicable to your - * use of third party software (including open source software) that may - * accompany Microchip software. - * - * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER - * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED - * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, - * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE - * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF - * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE - * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL - * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED - * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR - * THIS SOFTWARE. - */ -/* lint --e{755} */ - -#ifndef ATCA_COMMAND_H -#define ATCA_COMMAND_H - -#include "atca_compiler.h" -#include "atca_status.h" -#include "atca_devtypes.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup command ATCACommand (atca_) - \brief CryptoAuthLib command builder object, ATCACommand. Member functions for the ATCACommand object. - @{ - */ - -/** \brief atca_command is the C object backing ATCACommand. - */ -struct atca_command -{ - ATCADeviceType dt; - uint8_t clock_divider; - uint16_t execution_time_msec; -}; - -/*--- ATCACommand ---------*/ -typedef struct atca_command* ATCACommand; - -ATCA_STATUS initATCACommand(ATCADeviceType device_type, ATCACommand ca_cmd); -ATCACommand newATCACommand(ATCADeviceType device_type); -void deleteATCACommand(ATCACommand *ca_cmd); - - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif - diff --git a/lib/atca_config.h.in b/lib/atca_config.h.in index 04fa81db7..379b4eba8 100644 --- a/lib/atca_config.h.in +++ b/lib/atca_config.h.in @@ -4,11 +4,18 @@ /* Included HALS */ #cmakedefine ATCA_HAL_KIT_HID -#cmakedefine ATCA_HAL_KIT_CDC #cmakedefine ATCA_HAL_I2C #cmakedefine ATCA_HAL_SPI #cmakedefine ATCA_HAL_KIT_BRIDGE #cmakedefine ATCA_HAL_CUSTOM +#cmakedefine ATCA_HAL_SWI +#cmakedefine ATCA_HAL_1WIRE + + +/** Define to enable compatibility with legacy HALs + (HALs with embedded device logic)*/ +#cmakedefine ATCA_HAL_LEGACY_API + /* Included device support */ #cmakedefine ATCA_ATSHA204A_SUPPORT @@ -17,13 +24,12 @@ #cmakedefine ATCA_ATECC508A_SUPPORT #cmakedefine ATCA_ATECC608_SUPPORT #cmakedefine ATCA_TA100_SUPPORT +#cmakedefine ATCA_ECC204_SUPPORT /** Device Override - Library Assumes ATECC608B support in checks */ #cmakedefine ATCA_ATECC608A_SUPPORT -#ifdef ATCA_TA100_SUPPORT -#cmakedefine ATCA_TA100_AES_AUTH_SUPPORT -#endif + /** Define if cryptoauthlib is to use the maximum execution time method */ #cmakedefine ATCA_NO_POLL @@ -66,6 +72,16 @@ /** Define to build atcab_ functions rather that defining them as macros */ #cmakedefine ATCA_USE_ATCAB_FUNCTIONS +/** Define to enable older API forms that have been replaced */ +#cmakedefine ATCA_ENABLE_DEPRECATED + +/** TA100 Specific - Enable auth sessions that require AES (CMAC/GCM) from + an external library */ +#cmakedefine ATCA_TA100_AES_AUTH_SUPPORT + +/** TA100 Specific - Enable support for the FCE APIs for the TA100 */ +#cmakedefine ATCA_TA100_FCE_SUPPORT + /******************** Platform Configuration Section ***********************/ /** Define if the library is not to use malloc/free */ diff --git a/lib/atca_device.c b/lib/atca_device.c index a4f094d79..5ab897070 100644 --- a/lib/atca_device.c +++ b/lib/atca_device.c @@ -55,28 +55,9 @@ ATCADevice newATCADevice(ATCAIfaceCfg *cfg) memset(ca_dev, 0, sizeof(struct atca_device)); - ca_dev->mCommands = (ATCACommand)malloc(sizeof(*(ca_dev->mCommands))); - if (ca_dev->mCommands == NULL) - { - free(ca_dev); - ca_dev = NULL; - return NULL; - } - - ca_dev->mIface = (ATCAIface)malloc(sizeof(*(ca_dev->mIface))); - if (ca_dev->mIface == NULL) - { - free(ca_dev->mCommands); - free(ca_dev); - ca_dev = NULL; - return NULL; - } - status = initATCADevice(cfg, ca_dev); if (status != ATCA_SUCCESS) { - free(ca_dev->mIface); - free(ca_dev->mCommands); free(ca_dev); ca_dev = NULL; return NULL; @@ -96,13 +77,6 @@ void deleteATCADevice(ATCADevice *ca_dev) } releaseATCADevice(*ca_dev); - deleteATCACommand(&(*ca_dev)->mCommands); - // Free iface manually as we don't want to call releaseATCAIface twice - if ((*ca_dev)->mIface) - { - free((*ca_dev)->mIface); - (*ca_dev)->mIface = NULL; - } free(*ca_dev); *ca_dev = NULL; @@ -120,18 +94,12 @@ ATCA_STATUS initATCADevice(ATCAIfaceCfg *cfg, ATCADevice ca_dev) { ATCA_STATUS status; - if (cfg == NULL || ca_dev == NULL || ca_dev->mCommands == NULL || ca_dev->mIface == NULL) + if (cfg == NULL || ca_dev == NULL) { return ATCA_BAD_PARAM; } - status = initATCACommand(cfg->devtype, ca_dev->mCommands); - if (status != ATCA_SUCCESS) - { - return status; - } - - status = initATCAIface(cfg, ca_dev->mIface); + status = initATCAIface(cfg, &ca_dev->mIface); if (status != ATCA_SUCCESS) { return status; @@ -140,22 +108,13 @@ ATCA_STATUS initATCADevice(ATCAIfaceCfg *cfg, ATCADevice ca_dev) return ATCA_SUCCESS; } -/** \brief returns a reference to the ATCACommand object for the device - * \param[in] dev reference to a device - * \return reference to the ATCACommand object for the device - */ -ATCACommand atGetCommands(ATCADevice dev) -{ - return dev->mCommands; -} - /** \brief returns a reference to the ATCAIface interface object for the device * \param[in] dev reference to a device * \return reference to the ATCAIface object for the device */ ATCAIface atGetIFace(ATCADevice dev) { - return dev->mIface; + return &dev->mIface; } /** \brief Release any resources associated with the device. @@ -169,7 +128,7 @@ ATCA_STATUS releaseATCADevice(ATCADevice ca_dev) return ATCA_BAD_PARAM; } - return releaseATCAIface(ca_dev->mIface); + return releaseATCAIface(&ca_dev->mIface); } /** @} */ diff --git a/lib/atca_device.h b/lib/atca_device.h index d52c543b5..ea9a60e20 100644 --- a/lib/atca_device.h +++ b/lib/atca_device.h @@ -30,7 +30,6 @@ #define ATCA_DEVICE_H /*lint +flb */ -#include "atca_command.h" #include "atca_iface.h" /** \defgroup device ATCADevice (atca_) @{ */ @@ -131,21 +130,36 @@ typedef struct ATCA_PACKED _atecc608_config #pragma pack(pop) #endif +/** \brief ATCADeviceState says about device state + */ +typedef enum +{ + ATCA_DEVICE_STATE_UNKNOWN = 0, + ATCA_DEVICE_STATE_SLEEP, + ATCA_DEVICE_STATE_IDLE, + ATCA_DEVICE_STATE_ACTIVE +} ATCADeviceState; + + /** \brief atca_device is the C object backing ATCADevice. See the atca_device.h file for * details on the ATCADevice methods */ struct atca_device { - ATCACommand mCommands; //!< Command set for a given CryptoAuth device - ATCAIface mIface; //!< Physical interface + atca_iface_t mIface; /**< Physical interface */ + uint8_t device_state; /**< Device Power State */ + + uint8_t clock_divider; + uint16_t execution_time_msec; + + uint8_t session_state; /**< Secure Session State */ + uint16_t session_counter; /**< Secure Session Message Count */ + uint16_t session_key_id; /**< Key ID used for a secure sesison */ + uint8_t* session_key; /**< Session Key */ + uint8_t session_key_len; /**< Length of key used for the session in bytes */ - uint8_t session_state; /**< Secure Session State */ - uint16_t session_counter; /**< Secure Session Message Count */ - uint16_t session_key_id; /**< Key ID used for a secure sesison */ - uint8_t* session_key; /**< Session Key */ - uint8_t session_key_len; /**< Length of key used for the session in bytes */ + uint16_t options; /**< Nested command details parameter */ - uint16_t options; /**< Nested command details parameter */ }; typedef struct atca_device * ATCADevice; @@ -155,7 +169,6 @@ ATCADevice newATCADevice(ATCAIfaceCfg *cfg); ATCA_STATUS releaseATCADevice(ATCADevice ca_dev); void deleteATCADevice(ATCADevice *ca_dev); -ATCACommand atGetCommands(ATCADevice dev); ATCAIface atGetIFace(ATCADevice dev); diff --git a/lib/atca_devtypes.h b/lib/atca_devtypes.h index 7d7f03a4f..4c24e39ee 100644 --- a/lib/atca_devtypes.h +++ b/lib/atca_devtypes.h @@ -47,6 +47,7 @@ typedef enum ATECC608B = 3, ATECC608 = 3, ATSHA206A = 4, + ECC204 = 5, TA100 = 0x10, ATCA_DEV_UNKNOWN = 0x20 } ATCADeviceType; diff --git a/lib/atca_helpers.c b/lib/atca_helpers.c index 9bc4bc079..ec68f1c5b 100644 --- a/lib/atca_helpers.c +++ b/lib/atca_helpers.c @@ -321,11 +321,11 @@ bool isDigit(char c) } /** - * \brief Checks to see if a character is whitespace + * \brief Checks to see if a character is blank space * \param[in] c character to check - * \return True if the character is whitespace + * \return True if the character is blankspace */ -bool isWhiteSpace(char c) +bool isBlankSpace(char c) { return (c == '\n') || (c == '\r') || (c == '\t') || (c == ' '); } @@ -351,14 +351,14 @@ bool isHexAlpha(char c) } /** - * \brief Returns true if this character is a valid hex character or if this is whitespace (The character can be + * \brief Returns true if this character is a valid hex character or if this is blankspace (The character can be * included in a valid hexstring). * \param[in] c character to check * \return True if the character can be included in a valid hexstring */ bool isHex(char c) { - return isHexDigit(c) || isWhiteSpace(c); + return isHexDigit(c) || isBlankSpace(c); } /** @@ -372,10 +372,10 @@ bool isHexDigit(char c) } /** - * \brief Remove white space from a ASCII hex string. - * \param[in] ascii_hex Initial hex string to remove white space from + * \brief Remove spaces from a ASCII hex string. + * \param[in] ascii_hex Initial hex string to remove blankspace from * \param[in] ascii_hex_len Length of the initial hex string - * \param[in] packed_hex Resulting hex string without white space + * \param[in] packed_hex Resulting hex string without blankspace * \param[in,out] packed_len In: Size to packed_hex buffer * Out: Number of bytes in the packed hex string * \return ATCA_SUCCESS on success, otherwise an error code. @@ -483,7 +483,7 @@ ATCA_STATUS atcab_printbin(uint8_t* binary, size_t bin_len, bool add_space) #define B64_IS_INVALID (uint8_t)0xFF /** - * \brief Returns true if this character is a valid base 64 character or if this is whitespace (A character can be + * \brief Returns true if this character is a valid base 64 character or if this is space (A character can be * included in a valid base 64 string). * \param[in] c character to check * \param[in] rules base64 ruleset to use @@ -491,7 +491,7 @@ ATCA_STATUS atcab_printbin(uint8_t* binary, size_t bin_len, bool add_space) */ bool isBase64(char c, const uint8_t * rules) { - return isBase64Digit(c, rules) || isWhiteSpace(c); + return isBase64Digit(c, rules) || isBlankSpace(c); } /** @@ -662,9 +662,9 @@ ATCA_STATUS atcab_base64decode_(const char* encoded, size_t encoded_size, uint8_ // Start decoding the input data for (enc_index = 0; enc_index < encoded_size; enc_index++) { - if (isWhiteSpace(encoded[enc_index])) + if (isBlankSpace(encoded[enc_index])) { - continue; // Skip any whitespace characters + continue; // Skip any empty characters } if (!isBase64Digit(encoded[enc_index], rules)) { diff --git a/lib/atca_helpers.h b/lib/atca_helpers.h index d8dcf4278..447f84702 100644 --- a/lib/atca_helpers.h +++ b/lib/atca_helpers.h @@ -49,7 +49,7 @@ ATCA_STATUS atcab_printbin_label(const char* label, uint8_t* binary, size_t bin_ ATCA_STATUS packHex(const char* ascii_hex, size_t ascii_hex_len, char* packed_hex, size_t* packed_len); bool isDigit(char c); -bool isWhiteSpace(char c); +bool isBlankSpace(char c); bool isAlpha(char c); bool isHexAlpha(char c); bool isHex(char c); diff --git a/lib/atca_iface.c b/lib/atca_iface.c index 746120084..617cf087a 100644 --- a/lib/atca_iface.c +++ b/lib/atca_iface.c @@ -26,10 +26,7 @@ * THIS SOFTWARE. */ -#include -#include "atca_iface.h" -#include "hal/atca_hal.h" -#include "atca_config.h" +#include "cryptoauthlib.h" /** \defgroup interface ATCAIface (atca_) * \brief Abstract interface to all CryptoAuth device types. This interface @@ -38,26 +35,6 @@ @{ */ -static ATCA_STATUS _atinit(ATCAIface ca_iface, ATCAHAL_t **hal) -{ - // get method mapping to HAL methods for this interface - ATCA_STATUS status = hal_iface_init(ca_iface->mIfaceCFG, hal); - - if (ATCA_SUCCESS == status) - { - ca_iface->atinit = (*hal)->halinit; - ca_iface->atpostinit = (*hal)->halpostinit; - ca_iface->atsend = (*hal)->halsend; - ca_iface->atreceive = (*hal)->halreceive; - ca_iface->atwake = (*hal)->halwake; - ca_iface->atsleep = (*hal)->halsleep; - ca_iface->atidle = (*hal)->halidle; - ca_iface->hal_data = (*hal)->hal_data; - } - - return status; -} - /** \brief Initializer for ATCAIface objects * \param[in] cfg Logical configuration for the interface * \param[in] ca_iface Interface structure to initialize. @@ -72,10 +49,9 @@ ATCA_STATUS initATCAIface(ATCAIfaceCfg *cfg, ATCAIface ca_iface) return ATCA_BAD_PARAM; } - ca_iface->mType = cfg->iface_type; ca_iface->mIfaceCFG = cfg; - status = atinit(ca_iface); + status = ATCA_TRACE(atinit(ca_iface), "atinit"); if (status != ATCA_SUCCESS) { return status; @@ -116,21 +92,42 @@ ATCAIface newATCAIface(ATCAIfaceCfg *cfg) ATCA_STATUS atinit(ATCAIface ca_iface) { ATCA_STATUS status = ATCA_COMM_FAIL; - ATCAHAL_t * hal; - status = _atinit(ca_iface, &hal); - - if (ATCA_SUCCESS == status) - { - status = ca_iface->atinit(hal, ca_iface->mIfaceCFG); - } - if (status == ATCA_SUCCESS) + if (ca_iface) { - ca_iface->hal_data = hal->hal_data; - hal->hal_data = NULL; + status = ATCA_TRACE(hal_iface_init(ca_iface->mIfaceCFG, &ca_iface->hal, &ca_iface->phy), "Failed to configure HAL"); + + /* Initialize the physical interface if one is required for the hal */ + if (ATCA_SUCCESS == status && ca_iface->phy) + { + if (ca_iface->phy->halinit && ca_iface->phy->halpostinit) + { + if (ATCA_SUCCESS == (status = ATCA_TRACE(ca_iface->phy->halinit(ca_iface, ca_iface->mIfaceCFG), "phyinit"))) + { + status = ATCA_TRACE(ca_iface->phy->halpostinit(ca_iface), "phypostinit"); + } + } + else + { + status = ATCA_TRACE(ATCA_ASSERT_FAILURE, "phy is invalid"); + } + } - // Perform the post init - status = ca_iface->atpostinit(ca_iface); + /* Initialize the hal itself */ + if (ATCA_SUCCESS == status) + { + if (ca_iface->hal->halinit && ca_iface->hal->halpostinit) + { + if (ATCA_SUCCESS == (status = ATCA_TRACE(ca_iface->hal->halinit(ca_iface, ca_iface->mIfaceCFG), "halinit"))) + { + status = ATCA_TRACE(ca_iface->hal->halpostinit(ca_iface), "halpostinit"); + } + } + else + { + status = ATCA_TRACE(ATCA_ASSERT_FAILURE, "hal is invalid"); + } + } } return status; @@ -144,16 +141,23 @@ ATCA_STATUS atinit(ATCAIface ca_iface) * \param[in] txlength Number of bytes to be transmitted to the device. * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS atsend(ATCAIface ca_iface, uint8_t word_address, uint8_t *txdata, int txlength) +ATCA_STATUS atsend(ATCAIface ca_iface, uint8_t address, uint8_t *txdata, int txlength) { if (!ca_iface) { return ATCA_BAD_PARAM; } - if (ca_iface->atsend) + if (ca_iface->hal && ca_iface->hal->halsend) { - return ca_iface->atsend(ca_iface, word_address, txdata, txlength); +#ifdef ATCA_HAL_I2C + if (ATCA_I2C_IFACE == ca_iface->mIfaceCFG->iface_type && 0xFF == address) + { + address = ca_iface->mIfaceCFG->atcai2c.address; + } +#endif + + return ca_iface->hal->halsend(ca_iface, address, txdata, txlength); } else { @@ -177,9 +181,35 @@ ATCA_STATUS atreceive(ATCAIface ca_iface, uint8_t word_address, uint8_t *rxdata, return ATCA_BAD_PARAM; } - if (ca_iface->atreceive) + if (ca_iface->hal && ca_iface->hal->halreceive) + { + return ca_iface->hal->halreceive(ca_iface, word_address, rxdata, rxlength); + } + else + { + return ATCA_NOT_INITIALIZED; + } +} + + +/** \brief Perform control operations with the underlying hal driver + * \param[in] ca_iface Device to interact with. + * \param[in] option Control parameter identifier + * \param[in] param Optional pointer to parameter value + * \param[in] paramlen Length of the parameter + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcontrol(ATCAIface ca_iface, uint8_t option, void* param, size_t paramlen) +{ + if (!ca_iface) + { + return ATCA_BAD_PARAM; + } + + + if (ca_iface->hal && ca_iface->hal->halcontrol) { - return ca_iface->atreceive(ca_iface, word_address, rxdata, rxlength); + return ca_iface->hal->halcontrol(ca_iface, option, param, paramlen); } else { @@ -187,9 +217,11 @@ ATCA_STATUS atreceive(ATCAIface ca_iface, uint8_t word_address, uint8_t *rxdata, } } -/** \brief Wakes up the device by calling intermediate HAL wrapper function. - * If using the basic API, the atcab_wakeup() function should be used - * instead. +/** \brief Wakes up the device by calling intermediate HAL wrapper function. The + * atcab_wakeup() function should be used instead. + * \deprecated This function does not have defined behavior when ATCA_HAL_LEGACY_API + * is undefined. + * * \param[in] ca_iface Device to interact with. * \return ATCA_SUCCESS on success, otherwise an error code. */ @@ -200,9 +232,10 @@ ATCA_STATUS atwake(ATCAIface ca_iface) return ATCA_BAD_PARAM; } - if (ca_iface->atwake) + + if (ca_iface->hal && ca_iface->hal->halcontrol) { - ATCA_STATUS status = ca_iface->atwake(ca_iface); + ATCA_STATUS status = ca_iface->hal->halcontrol(ca_iface, ATCA_HAL_CONTROL_WAKE, NULL, 0); if (ATCA_WAKE_FAILED == status) { @@ -210,7 +243,7 @@ ATCA_STATUS atwake(ATCAIface ca_iface) // and try again. atca_delay_ms(ATCA_POST_DELAY_MSEC); - status = ca_iface->atwake(ca_iface); + status = ca_iface->hal->halcontrol(ca_iface, ATCA_HAL_CONTROL_WAKE, NULL, 0); } return status; } @@ -222,8 +255,9 @@ ATCA_STATUS atwake(ATCAIface ca_iface) /** \brief Puts the device into idle state by calling intermediate HAL wrapper - * function. If using the basic API, the atcab_idle() function should - * be used instead. + * function. The atcab_idle() function should be used instead. + * \deprecated This function does not have defined behavior when ATCA_HAL_LEGACY_API + * is undefined. * \param[in] ca_iface Device to interact with. * \return ATCA_SUCCESS on success, otherwise an error code. */ @@ -234,9 +268,9 @@ ATCA_STATUS atidle(ATCAIface ca_iface) return ATCA_BAD_PARAM; } - if (ca_iface->atidle) + if (ca_iface->hal && ca_iface->hal->halcontrol) { - ATCA_STATUS status = ca_iface->atidle(ca_iface); + ATCA_STATUS status = ca_iface->hal->halcontrol(ca_iface, ATCA_HAL_CONTROL_IDLE, NULL, 0); atca_delay_ms(1); return status; } @@ -247,8 +281,9 @@ ATCA_STATUS atidle(ATCAIface ca_iface) } /** \brief Puts the device into sleep state by calling intermediate HAL wrapper - * function. If using the basic API, the atcab_sleep() function should - * be used instead. + * function. The atcab_sleep() function should be used instead. + * \deprecated This function does not have defined behavior when ATCA_HAL_LEGACY_API + * is undefined. * \param[in] ca_iface Device to interact with. * \return ATCA_SUCCESS on success, otherwise an error code. */ @@ -259,9 +294,9 @@ ATCA_STATUS atsleep(ATCAIface ca_iface) return ATCA_BAD_PARAM; } - if (ca_iface->atsleep) + if (ca_iface->hal && ca_iface->hal->halcontrol) { - ATCA_STATUS status = ca_iface->atsleep(ca_iface); + ATCA_STATUS status = ca_iface->hal->halcontrol(ca_iface, ATCA_HAL_CONTROL_SLEEP, NULL, 0); atca_delay_ms(1); return status; } @@ -291,6 +326,51 @@ void* atgetifacehaldat(ATCAIface ca_iface) return ca_iface ? ca_iface->hal_data : NULL; } +/** \brief Check if the given interface is configured as a "kit protocol" one where + * transactions are atomic + * \return true if the interface is considered a kit + */ +bool atca_iface_is_kit(ATCAIface ca_iface) +{ + bool ret = false; + + if (ca_iface && ca_iface->mIfaceCFG) + { + if (ATCA_HID_IFACE == ca_iface->mIfaceCFG->iface_type || ATCA_KIT_IFACE == ca_iface->mIfaceCFG->iface_type) + { + ret = true; + } + } + return ret; +} + +/** \brief Retrive the number of retries for a configured interface */ +int atca_iface_get_retries(ATCAIface ca_iface) +{ + if (ca_iface && ca_iface->mIfaceCFG) + { + return ca_iface->mIfaceCFG->rx_retries; + } + else + { + return 0; + } +} + +/** \brief Retrive the wake/retry delay for a configured interface/device */ +uint16_t atca_iface_get_wake_delay(ATCAIface ca_iface) +{ + if (ca_iface && ca_iface->mIfaceCFG) + { + return ca_iface->mIfaceCFG->wake_delay; + } + else + { + return 1500; + } +} + + /** \brief Instruct the HAL driver to release any resources associated with * this interface. * \param[in] ca_iface Device interface. @@ -298,12 +378,21 @@ void* atgetifacehaldat(ATCAIface ca_iface) */ ATCA_STATUS releaseATCAIface(ATCAIface ca_iface) { - if (ca_iface == NULL) + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (ca_iface && ca_iface->mIfaceCFG) { - return ATCA_BAD_PARAM; + if (ATCA_SUCCESS == (status = hal_iface_release(ca_iface->mIfaceCFG->iface_type, ca_iface->hal_data))) + { + ca_iface->hal_data = NULL; + } + if (ATCA_CUSTOM_IFACE == ca_iface->mIfaceCFG->iface_type) + { + hal_free(ca_iface->hal); + ca_iface->hal = NULL; + } } - - return hal_iface_release(ca_iface->mType, ca_iface->hal_data); + return status; } #ifndef ATCA_NO_HEAP diff --git a/lib/atca_iface.h b/lib/atca_iface.h index 80789d0dc..f98e1fe4e 100644 --- a/lib/atca_iface.h +++ b/lib/atca_iface.h @@ -44,17 +44,22 @@ extern "C" { #include #include "atca_status.h" + typedef enum { - ATCA_I2C_IFACE, - ATCA_SWI_IFACE, - ATCA_UART_IFACE, - ATCA_SPI_IFACE, - ATCA_HID_IFACE, - ATCA_KIT_IFACE, - ATCA_CUSTOM_IFACE, + ATCA_I2C_IFACE = 0, /**< Native I2C Driver */ + ATCA_SWI_IFACE = 1, /**< SWI or 1-Wire over UART/USART */ + ATCA_UART_IFACE = 2, /**< Kit v1 over UART/USART */ + ATCA_SPI_IFACE = 3, /**< Native SPI Driver */ + ATCA_HID_IFACE = 4, /**< Kit v1 over HID */ + ATCA_KIT_IFACE = 5, /**< Kit v2 (Binary/Bridging) */ + ATCA_CUSTOM_IFACE = 6, /**< Custom HAL functions provided during interface init */ + ATCA_I2C_GPIO_IFACE = 7, /**< I2C "Bitbang" Driver */ + ATCA_SWI_GPIO_IFACE = 8, /**< SWI or 1-Wire using a GPIO */ + ATCA_SPI_GPIO_IFACE = 9, /**< SWI or 1-Wire using a GPIO */ + // additional physical interface types here - ATCA_UNKNOWN_IFACE + ATCA_UNKNOWN_IFACE = 0xFE } ATCAIfaceType; @@ -64,19 +69,10 @@ typedef enum ATCA_KIT_I2C_IFACE, ATCA_KIT_SWI_IFACE, ATCA_KIT_SPI_IFACE, - ATCA_KIT_UNKNOWN_IFACE -} ATCAKitType; - - + ATCA_KIT_UNKNOWN_IFACE } ATCAKitType; -/* ATCAIfaceCfg is a mediator object between a completely abstract notion of a - physical interface and an actual physical interface. - The main purpose of it is to keep hardware specifics from bleeding into the - higher levels - hardware specifics could include things like framework - specific items (ASF SERCOM) vs a non-Microchip I2C library constant that - defines an I2C port. But I2C has roughly the same parameters regardless of - architecture and framework. +/* ATCAIfaceCfg is the configuration object for a device */ typedef struct @@ -89,14 +85,19 @@ typedef struct { struct { - uint8_t slave_address; // 8-bit slave address +#ifdef ATCA_ENABLE_DEPRECATED + uint8_t slave_address; // 8-bit slave address +#else + uint8_t address; /**< Device address - the upper 7 bits are the I2c address bits */ +#endif uint8_t bus; // logical i2c bus number, 0-based - HAL will map this to a pin pair for SDA SCL uint32_t baud; // typically 400000 } atcai2c; struct { - uint8_t bus; // logical SWI bus - HAL will map this to a pin or uart port + uint8_t address; // 7-bit device address + uint8_t bus; // logical SWI bus - HAL will map this to a pin or uart port } atcaswi; struct @@ -150,30 +151,32 @@ typedef struct int rx_retries; // the number of retries to attempt for receiving bytes void * cfg_data; // opaque data used by HAL in device discovery } ATCAIfaceCfg; -typedef struct atca_iface * ATCAIface; -/** \brief atca_iface is the C object backing ATCAIface. See the atca_iface.h file for - * details on the ATCAIface methods - */ -struct atca_iface +typedef struct atca_iface * ATCAIface; + +/** \brief HAL Driver Structure + */ +typedef struct +{ + ATCA_STATUS (*halinit)(ATCAIface iface, ATCAIfaceCfg* cfg); + ATCA_STATUS (*halpostinit)(ATCAIface iface); + ATCA_STATUS (*halsend)(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int txlength); + ATCA_STATUS (*halreceive)(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxlength); + ATCA_STATUS (*halcontrol)(ATCAIface iface, uint8_t option, void* param, size_t paramlen); + ATCA_STATUS (*halrelease)(void* hal_data); +} ATCAHAL_t; + +/** \brief atca_iface is the context structure for a configured interface + */ +typedef struct atca_iface { - ATCAIfaceType mType; - ATCAIfaceCfg *mIfaceCFG; // points to previous defined/given Cfg object, caller manages this - - ATCA_STATUS (*atinit)(void *hal, ATCAIfaceCfg *); - ATCA_STATUS (*atpostinit)(ATCAIface hal); - ATCA_STATUS (*atsend)(ATCAIface hal, uint8_t word_address, uint8_t *txdata, int txlength); - ATCA_STATUS (*atreceive)(ATCAIface hal, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength); - ATCA_STATUS (*atwake)(ATCAIface hal); - ATCA_STATUS (*atidle)(ATCAIface hal); - ATCA_STATUS (*atsleep)(ATCAIface hal); - - // treat as private - void *hal_data; // generic pointer used by HAL to point to architecture specific structure - // no ATCA object should touch this except HAL, HAL manages this pointer and memory it points to -}; + ATCAIfaceCfg* mIfaceCFG; /**< Points to previous defined/given Cfg object, the caller manages this */ + ATCAHAL_t* hal; /**< The configured HAL for the interface */ + ATCAHAL_t* phy; /**< When a HAL is not a "native" hal it needs a physical layer to be associated with it */ + void* hal_data; /**< Pointer to HAL specific context/data */ +} atca_iface_t; ATCA_STATUS initATCAIface(ATCAIfaceCfg *cfg, ATCAIface ca_iface); ATCAIface newATCAIface(ATCAIfaceCfg *cfg); @@ -182,9 +185,9 @@ void deleteATCAIface(ATCAIface *ca_iface); // IFace methods ATCA_STATUS atinit(ATCAIface ca_iface); -ATCA_STATUS atpostinit(ATCAIface ca_iface); ATCA_STATUS atsend(ATCAIface ca_iface, uint8_t word_address, uint8_t *txdata, int txlength); ATCA_STATUS atreceive(ATCAIface ca_iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS atcontrol(ATCAIface ca_iface, uint8_t option, void* param, size_t paramlen); ATCA_STATUS atwake(ATCAIface ca_iface); ATCA_STATUS atidle(ATCAIface ca_iface); ATCA_STATUS atsleep(ATCAIface ca_iface); @@ -193,6 +196,10 @@ ATCA_STATUS atsleep(ATCAIface ca_iface); ATCAIfaceCfg * atgetifacecfg(ATCAIface ca_iface); void* atgetifacehaldat(ATCAIface ca_iface); +/* Utilities */ +bool atca_iface_is_kit(ATCAIface ca_iface); +int atca_iface_get_retries(ATCAIface ca_iface); +uint16_t atca_iface_get_wake_delay(ATCAIface ca_iface); #ifdef __cplusplus } diff --git a/lib/atca_utils_sizes.c b/lib/atca_utils_sizes.c index 03e8f2101..0b1002b1b 100644 --- a/lib/atca_utils_sizes.c +++ b/lib/atca_utils_sizes.c @@ -26,13 +26,13 @@ */ #include "cryptoauthlib.h" -#include "atcacert/atcacert_date.h" -#include "atcacert/atcacert_def.h" -#include "host/atca_host.h" #define SIZE_OF_API_T(x) size_t x ## _size(void); size_t x ## _size(void) { return sizeof( x ); } #define SIZE_OF_API_S(x) size_t x ## _size(void); size_t x ## _size(void) { return sizeof(struct x ); } +#if ATCA_CA_SUPPORT +#include "atcacert/atcacert_date.h" +#include "atcacert/atcacert_def.h" /* atcacert_date.h */ SIZE_OF_API_T(atcacert_tm_utc_t) SIZE_OF_API_T(atcacert_date_format_t) @@ -47,12 +47,16 @@ SIZE_OF_API_T(atcacert_cert_loc_t) SIZE_OF_API_T(atcacert_cert_element_t) SIZE_OF_API_T(atcacert_def_t) SIZE_OF_API_T(atcacert_build_state_t) +#endif /* atcab.h */ SIZE_OF_API_T(atca_aes_cbc_ctx_t) SIZE_OF_API_T(atca_aes_cmac_ctx_t) SIZE_OF_API_T(atca_aes_ctr_ctx_t) +#if ATCA_CA_SUPPORT +#include "host/atca_host.h" + /* atca_host.h */ SIZE_OF_API_T(atca_temp_key_t) SIZE_OF_API_S(atca_include_data_in_out) @@ -72,13 +76,13 @@ SIZE_OF_API_T(atca_check_mac_in_out_t) SIZE_OF_API_T(atca_verify_in_out_t) SIZE_OF_API_T(atca_gen_key_in_out_t) SIZE_OF_API_T(atca_sign_internal_in_out_t) +#endif /* atca_bool.h */ SIZE_OF_API_T(bool) /* atca_command.h */ #if ATCA_CA_SUPPORT -SIZE_OF_API_S(atca_command) SIZE_OF_API_T(ATCAPacket) #endif diff --git a/lib/atca_version.h b/lib/atca_version.h index 893bb4f9b..f46f169a1 100644 --- a/lib/atca_version.h +++ b/lib/atca_version.h @@ -30,9 +30,9 @@ #define _ATCA_VERSION_H // Version format yyyymmdd -#define ATCA_LIBRARY_VERSION_DATE "20201130" +#define ATCA_LIBRARY_VERSION_DATE "20210126" #define ATCA_LIBRARY_VERSION_MAJOR 3 -#define ATCA_LIBRARY_VERSION_MINOR 2 -#define ATCA_LIBRARY_VERSION_BUILD 5 +#define ATCA_LIBRARY_VERSION_MINOR 3 +#define ATCA_LIBRARY_VERSION_BUILD 0 #endif /* _ATCA_VERSION_H */ diff --git a/lib/calib/calib_aes.c b/lib/calib/calib_aes.c index 6e1a345d8..2979ac92c 100644 --- a/lib/calib/calib_aes.c +++ b/lib/calib/calib_aes.c @@ -49,7 +49,6 @@ ATCA_STATUS calib_aes(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* aes_in, uint8_t* aes_out) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; do @@ -60,7 +59,6 @@ ATCA_STATUS calib_aes(ATCADevice device, uint8_t mode, uint16_t key_id, const ui break; } - ca_cmd = device->mCommands; // build a AES command packet.param1 = mode; packet.param2 = key_id; @@ -73,7 +71,7 @@ ATCA_STATUS calib_aes(ATCADevice device, uint8_t mode, uint16_t key_id, const ui memcpy(packet.data, aes_in, AES_DATA_SIZE); } - if ((status = atAES(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atAES(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atAES - failed"); break; diff --git a/lib/calib/calib_basic.c b/lib/calib/calib_basic.c index e075f3de7..8db368ab9 100644 --- a/lib/calib/calib_basic.c +++ b/lib/calib/calib_basic.c @@ -34,150 +34,167 @@ * one global device is the one to operate on. */ -/** \brief wakeup the CryptoAuth device - * \param[in] device Device context pointer - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS calib_wakeup(ATCADevice device) +ATCA_STATUS calib_wakeup_i2c(ATCADevice device) { - if (device == NULL) + ATCA_STATUS status = ATCA_BAD_PARAM; + ATCAIface iface = atGetIFace(device); + + if (iface) { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } + uint8_t retries = atca_iface_get_retries(iface); + uint8_t address = atcab_get_device_address(device); + uint32_t temp; + uint16_t rxlen; - return atwake(device->mIface); -} + do + { + if (100000UL < iface->mIfaceCFG->atcai2c.baud) + { + temp = 100000UL; + status = atcontrol(iface, ATCA_HAL_CHANGE_BAUD, &temp, sizeof(temp)); + if (ATCA_UNIMPLEMENTED == status) + { + status = atcontrol(iface, ATCA_HAL_CONTROL_WAKE, NULL, 0); + break; + } + } + else + { + status = ATCA_SUCCESS; + } -/** \brief idle the CryptoAuth device - * \param[in] device Device context pointer - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS calib_idle(ATCADevice device) -{ - if (device == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } + #ifdef ATCA_ECC204_SUPPORT + if (ECC204 == atcab_get_device_type_ext(device)) + { + (void)atsend(iface, address, NULL, 0); + } + else + { - return atidle(device->mIface); -} + (void)atsend(iface, 0x00, NULL, 0); + } + #else + (void)atsend(iface, 0x00, NULL, 0); + #endif + atca_delay_us(atca_iface_get_wake_delay(iface)); -/** \brief invoke sleep on the CryptoAuth device - * \param[in] device Device context pointer - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS calib_sleep(ATCADevice device) -{ - if (device == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } + rxlen = sizeof(temp); + if (ATCA_SUCCESS == status) + { + status = atreceive(iface, address, (uint8_t*)&temp, &rxlen); + } - return atsleep(device->mIface); + if ((ATCA_SUCCESS == status) && (100000UL < iface->mIfaceCFG->atcai2c.baud)) + { + temp = iface->mIfaceCFG->atcai2c.baud; + status = atcontrol(iface, ATCA_HAL_CHANGE_BAUD, &temp, sizeof(temp)); + } + + if (ATCA_SUCCESS == status) + { + status = hal_check_wake((uint8_t*)&temp, rxlen); + } + } + while (0 < retries-- && ATCA_SUCCESS != status); + } + return status; } -/** \brief auto discovery of crypto auth devices - * - * Calls interface discovery functions and fills in cfg_array up to the maximum - * number of configurations either found or the size of the array. The cfg_array - * can have a mixture of interface types (ie: some I2C, some SWI or UART) depending upon - * which interfaces you've enabled - * - * \param[out] cfg_array ptr to an array of interface configs - * \param[in] max_ifaces maximum size of cfg_array - * \return ATCA_SUCCESS on success, otherwise an error code. +/** \brief wakeup the CryptoAuth device + * \param[in] device Device context pointer + * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS calib_cfg_discover(ATCAIfaceCfg cfg_array[], int max_ifaces) +ATCA_STATUS calib_wakeup(ATCADevice device) { - int iface_num = 0; - int found = 0; - int i = 0; + ATCA_STATUS status = ATCA_BAD_PARAM; + ATCAIface iface = atGetIFace(device); -// this cumulatively gathers all the interfaces enabled by #defines -#define MAX_BUSES 4 - -#ifdef ATCA_HAL_I2C - int i2c_buses[MAX_BUSES]; - memset(i2c_buses, -1, sizeof(i2c_buses)); - hal_i2c_discover_buses(i2c_buses, MAX_BUSES); - - for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) + if (iface && iface->mIfaceCFG) { - if (i2c_buses[i] != -1) +#ifdef ATCA_HAL_LEGACY_API + status = atwake(iface); +#else + if (atca_iface_is_kit(iface) || (ATCA_SWI_IFACE == iface->mIfaceCFG->iface_type)) { - hal_i2c_discover_devices(i2c_buses[i], &cfg_array[iface_num], &found); - iface_num += found; + status = atwake(iface); } - } -#endif - -#ifdef ATCA_HAL_SWI - int swi_buses[MAX_BUSES]; - memset(swi_buses, -1, sizeof(swi_buses)); - hal_swi_discover_buses(swi_buses, MAX_BUSES); - for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) - { - if (swi_buses[i] != -1) + else if (ATCA_I2C_IFACE == iface->mIfaceCFG->iface_type) { - hal_swi_discover_devices(swi_buses[i], &cfg_array[iface_num], &found); - iface_num += found; + status = calib_wakeup_i2c(device); + } + else + { + status = ATCA_SUCCESS; } } #endif + return status; + } -#ifdef ATCA_HAL_UART - int uart_buses[MAX_BUSES]; - memset(uart_buses, -1, sizeof(uart_buses)); - hal_uart_discover_buses(uart_buses, MAX_BUSES); - for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) +/** \brief idle the CryptoAuth device + * \param[in] device Device context pointer + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + ATCA_STATUS calib_idle(ATCADevice device) { - if (uart_buses[i] != -1) + ATCA_STATUS status = ATCA_BAD_PARAM; + +#ifdef ATCA_HAL_LEGACY_API + status = atidle(device->mIface); +#else + if (atca_iface_is_kit(&device->mIface) || (ATCA_SWI_IFACE == device->mIface.mIfaceCFG->iface_type)) { - hal_uart_discover_devices(uart_buses[i], &cfg_array[iface_num], &found); - iface_num += found; + status = atidle(&device->mIface); } - } -#endif - -#ifdef ATCA_HAL_KIT_CDC - int cdc_buses[MAX_BUSES]; - memset(cdc_buses, -1, sizeof(cdc_buses)); - hal_kit_cdc_discover_buses(cdc_buses, MAX_BUSES); - for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) - { - if (cdc_buses[i] != -1) + else { - hal_kit_cdc_discover_devices(cdc_buses[i], &cfg_array[iface_num++], &found); - iface_num += found; + if (ECC204 != atcab_get_device_type_ext(device)) + { + uint8_t command = 0x02; + status = atsend(&device->mIface, atcab_get_device_address(device), &command, 1); + } + else + { + status = ATCA_SUCCESS; + } } - } #endif + return status; + } -#ifdef ATCA_HAL_KIT_HID - int hid_buses[MAX_BUSES]; - memset(hid_buses, -1, sizeof(hid_buses)); - hal_kit_hid_discover_buses(hid_buses, MAX_BUSES); - for (i = 0; i < MAX_BUSES && iface_num < max_ifaces; i++) +/** \brief invoke sleep on the CryptoAuth device + * \param[in] device Device context pointer + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + ATCA_STATUS calib_sleep(ATCADevice device) { - if (hid_buses[i] != -1) + ATCA_STATUS status = ATCA_BAD_PARAM; + +#ifdef ATCA_HAL_LEGACY_API + status = atsleep(device->mIface); +#else + if (atca_iface_is_kit(&device->mIface) || (ATCA_SWI_IFACE == device->mIface.mIfaceCFG->iface_type)) { - hal_kit_hid_discover_devices(hid_buses[i], &cfg_array[iface_num++], &found); - iface_num += found; + status = atsleep(&device->mIface); + } + else + { + uint8_t command = 0x01; + status = atsend(&device->mIface, atcab_get_device_address(device), &command, 1); } - } #endif - return ATCA_SUCCESS; -} + return status; + } /** \brief common cleanup code which idles the device after any operation * \param[in] device Device context pointer * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS _calib_exit(ATCADevice device) -{ - return calib_idle(device); -} + ATCA_STATUS _calib_exit(ATCADevice device) + { + return calib_idle(device); + } /** \brief Compute the address given the zone, slot, block, and offset @@ -189,41 +206,70 @@ ATCA_STATUS _calib_exit(ATCADevice device) * \param[out] addr Pointer to the address of data or configuration or OTP zone. * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS calib_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr) -{ - ATCA_STATUS status = ATCA_SUCCESS; - uint8_t mem_zone = zone & 0x03; - - if (addr == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } - if ((mem_zone != ATCA_ZONE_CONFIG) && (mem_zone != ATCA_ZONE_DATA) && (mem_zone != ATCA_ZONE_OTP)) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); - } - do + ATCA_STATUS calib_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr) { - // Initialize the addr to 00 - *addr = 0; - // Mask the offset - offset = offset & (uint8_t)0x07; - if ((mem_zone == ATCA_ZONE_CONFIG) || (mem_zone == ATCA_ZONE_OTP)) + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t mem_zone = zone & 0x03; + + if (addr == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + if ((mem_zone != ATCA_ZONE_CONFIG) && (mem_zone != ATCA_ZONE_DATA) && (mem_zone != ATCA_ZONE_OTP)) { - *addr = block << 3; - *addr |= offset; + return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); } - else // ATCA_ZONE_DATA + do { - *addr = slot << 3; - *addr |= offset; - *addr |= block << 8; + // Initialize the addr to 00 + *addr = 0; + // Mask the offset + offset = offset & (uint8_t)0x07; + if ((mem_zone == ATCA_ZONE_CONFIG) || (mem_zone == ATCA_ZONE_OTP)) + { + *addr = block << 3; + *addr |= offset; + } + else // ATCA_ZONE_DATA + { + *addr = slot << 3; + *addr |= offset; + *addr |= block << 8; + } } + while (0); + + return status; } - while (0); - return status; -} +/** \brief Compute the address given the zone, slot, block, and offset for ECC204 device + * \param[in] zone Zone to get address from. Config(1) or + * Data(0) which requires a slot. + * \param[in] slot Slot Id number for data zone and zero for other zones. + * \param[in] block Block number within the data zone . + * \param[in] offset Aalways zero. + * \param[out] addr Pointer to the address of data or configuration zone. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + ATCA_STATUS calib_ecc204_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr) + { + ATCA_STATUS status = ATCA_SUCCESS; + + (void)offset; + + if (addr == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + + // Initialize the addr to 00 + *addr = 0; + *addr = slot << 3; + *addr |= block << 8; + + return status; + } /** \brief Gets the size of the specified zone in bytes. * @@ -235,62 +281,90 @@ ATCA_STATUS calib_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t o * * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS calib_get_zone_size(ATCADevice device, uint8_t zone, uint16_t slot, size_t* size) -{ - ATCA_STATUS status = ATCA_SUCCESS; - - if ((device == NULL) || (size == NULL)) + ATCA_STATUS calib_get_zone_size(ATCADevice device, uint8_t zone, uint16_t slot, size_t* size) { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } + ATCA_STATUS status = ATCA_SUCCESS; - if (device->mIface->mIfaceCFG->devtype == ATSHA204A) - { - switch (zone) - { - case ATCA_ZONE_CONFIG: *size = 88; break; - case ATCA_ZONE_OTP: *size = 64; break; - case ATCA_ZONE_DATA: *size = 32; break; - default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; - } - } - else if (device->mIface->mIfaceCFG->devtype == ATSHA206A) - { - switch (zone) + if ((device == NULL) || (size == NULL)) { - case ATCA_ZONE_CONFIG: *size = 88; break; - case ATCA_ZONE_OTP: *size = 0; break; - case ATCA_ZONE_DATA: *size = 32; break; - default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); } - } - else - { - switch (zone) + + if (device->mIface.mIfaceCFG->devtype == ATSHA204A) { - case ATCA_ZONE_CONFIG: *size = 128; break; - case ATCA_ZONE_OTP: *size = 64; break; - case ATCA_ZONE_DATA: - if (slot < 8) + switch (zone) { - *size = 36; + case ATCA_ZONE_CONFIG: *size = 88; break; + case ATCA_ZONE_OTP: *size = 64; break; + case ATCA_ZONE_DATA: *size = 32; break; + default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } - else if (slot == 8) + } + else if (device->mIface.mIfaceCFG->devtype == ATSHA206A) + { + switch (zone) { - *size = 416; + case ATCA_ZONE_CONFIG: *size = 88; break; + case ATCA_ZONE_OTP: *size = 0; break; + case ATCA_ZONE_DATA: *size = 32; break; + default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } - else if (slot < 16) + } +#ifdef ATCA_ECC204_SUPPORT + else if (ECC204 == device->mIface.mIfaceCFG->devtype) + { + switch (zone) { - *size = 72; + case ATCA_ECC204_ZONE_CONFIG: *size = 16; break; + case ATCA_ECC204_ZONE_DATA: + if ((0 == slot) || (3 == slot)) + { + *size = 32; + } + else if (1 == slot) + { + *size = 320; + } + else if (2 == slot) + { + *size = 64; + } + else + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); + } + break; + default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } - else + } +#endif + else + { + switch (zone) { - status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); + case ATCA_ZONE_CONFIG: *size = 128; break; + case ATCA_ZONE_OTP: *size = 64; break; + case ATCA_ZONE_DATA: + if (slot < 8) + { + *size = 36; + } + else if (slot == 8) + { + *size = 416; + } + else if (slot < 16) + { + *size = 72; + } + else + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); + } + break; + default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } - break; - default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } - } - return status; -} + return status; + } diff --git a/lib/calib/calib_basic.h b/lib/calib/calib_basic.h index 1cf67bd11..af8e580eb 100644 --- a/lib/calib/calib_basic.h +++ b/lib/calib/calib_basic.h @@ -19,10 +19,9 @@ ATCA_STATUS calib_wakeup(ATCADevice device); ATCA_STATUS calib_idle(ATCADevice device); ATCA_STATUS calib_sleep(ATCADevice device); ATCA_STATUS _calib_exit(ATCADevice device); -ATCA_STATUS calib_cfg_discover(ATCAIfaceCfg cfg_array[], int max); ATCA_STATUS calib_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr); ATCA_STATUS calib_get_zone_size(ATCADevice device, uint8_t zone, uint16_t slot, size_t* size); - +ATCA_STATUS calib_ecc204_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr); //AES command functions ATCA_STATUS calib_aes(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* aes_in, uint8_t* aes_out); @@ -62,6 +61,7 @@ ATCA_STATUS calib_gendig(ATCADevice device, uint8_t zone, uint16_t key_id, const ATCA_STATUS calib_genkey_base(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* other_data, uint8_t* public_key); ATCA_STATUS calib_genkey(ATCADevice device, uint16_t key_id, uint8_t* public_key); ATCA_STATUS calib_get_pubkey(ATCADevice device, uint16_t key_id, uint8_t* public_key); +ATCA_STATUS calib_genkey_mac(ATCADevice device, uint8_t* public_key, uint8_t* mac); // HMAC command functions ATCA_STATUS calib_hmac(ATCADevice device, uint8_t mode, uint16_t key_id, uint8_t* digest); @@ -71,6 +71,11 @@ ATCA_STATUS calib_info_base(ATCADevice device, uint8_t mode, uint16_t param2, ui ATCA_STATUS calib_info(ATCADevice device, uint8_t* revision); ATCA_STATUS calib_info_set_latch(ATCADevice device, bool state); ATCA_STATUS calib_info_get_latch(ATCADevice device, bool* state); +ATCA_STATUS calib_info_privkey_valid(ATCADevice device, uint16_t key_id, uint8_t* is_valid); +ATCA_STATUS calib_info_lock_status(ATCADevice device, uint16_t param2, uint8_t* is_locked); +ATCA_STATUS calib_ecc204_is_locked(ATCADevice device, uint8_t zone, bool* is_locked); +ATCA_STATUS calib_ecc204_is_data_locked(ATCADevice device, bool* is_locked); +ATCA_STATUS calib_ecc204_is_config_locked(ATCADevice device, bool* is_locked); // KDF command functions ATCA_STATUS calib_kdf(ATCADevice device, uint8_t mode, uint16_t key_id, const uint32_t details, const uint8_t* message, uint8_t* out_data, uint8_t* out_nonce); @@ -82,6 +87,10 @@ ATCA_STATUS calib_lock_config_zone_crc(ATCADevice device, uint16_t summary_crc); ATCA_STATUS calib_lock_data_zone(ATCADevice device); ATCA_STATUS calib_lock_data_zone_crc(ATCADevice device, uint16_t summary_crc); ATCA_STATUS calib_lock_data_slot(ATCADevice device, uint16_t slot); +// Lock ECC204 command functions +ATCA_STATUS calib_ecc204_lock_config_slot(ATCADevice device, uint8_t slot, uint16_t summary_crc); +ATCA_STATUS calib_ecc204_lock_config_zone(ATCADevice device); +ATCA_STATUS calib_ecc204_lock_data_slot(ATCADevice device, uint8_t slot); // MAC command functions ATCA_STATUS calib_mac(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* challenge, uint8_t* digest); @@ -93,6 +102,8 @@ ATCA_STATUS calib_nonce_load(ATCADevice device, uint8_t target, const uint8_t *n ATCA_STATUS calib_nonce_rand(ATCADevice device, const uint8_t *num_in, uint8_t* rand_out); ATCA_STATUS calib_challenge(ATCADevice device, const uint8_t *num_in); ATCA_STATUS calib_challenge_seed_update(ATCADevice device, const uint8_t *num_in, uint8_t* rand_out); +ATCA_STATUS calib_nonce_gen_session_key(ATCADevice device, uint16_t param2, uint8_t* num_in, + uint8_t* rand_out); // PrivWrite command functions @@ -114,7 +125,14 @@ ATCA_STATUS calib_read_pubkey(ATCADevice device, uint16_t slot, uint8_t *public_ ATCA_STATUS calib_read_sig(ATCADevice device, uint16_t slot, uint8_t *sig); ATCA_STATUS calib_read_config_zone(ATCADevice device, uint8_t* config_data); ATCA_STATUS calib_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* same_config); - +// ECC204 Read command functions +ATCA_STATUS calib_ecc204_read_zone(ATCADevice device, uint8_t zone, uint8_t slot, uint8_t block, size_t offset, + uint8_t* data, uint8_t len); +ATCA_STATUS calib_ecc204_read_config_zone(ATCADevice device, uint8_t* config_data); +ATCA_STATUS calib_ecc204_read_serial_number(ATCADevice device, uint8_t* serial_number); +ATCA_STATUS calib_ecc204_read_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, + size_t block, uint8_t* data, size_t length); +ATCA_STATUS calib_ecc204_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* same_config); #if defined(ATCA_USE_CONSTANT_HOST_NONCE) ATCA_STATUS calib_read_enc(ATCADevice device, uint16_t key_id, uint8_t block, uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id); @@ -159,6 +177,8 @@ ATCA_STATUS calib_sha_hmac(ATCADevice device, const uint8_t * data, size_t data_ ATCA_STATUS calib_sign_base(ATCADevice device, uint8_t mode, uint16_t key_id, uint8_t *signature); ATCA_STATUS calib_sign(ATCADevice device, uint16_t key_id, const uint8_t *msg, uint8_t *signature); ATCA_STATUS calib_sign_internal(ATCADevice device, uint16_t key_id, bool is_invalidate, bool is_full_sn, uint8_t *signature); +// ECC204 Sign command functions +ATCA_STATUS calib_ecc204_sign(ATCADevice device, uint16_t key_id, const uint8_t* msg, uint8_t* signature); // UpdateExtra command functions ATCA_STATUS calib_updateextra(ATCADevice device, uint8_t mode, uint16_t new_value); @@ -178,6 +198,14 @@ ATCA_STATUS calib_write_zone(ATCADevice device, uint8_t zone, uint16_t slot, uin ATCA_STATUS calib_write_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t *data, size_t length); ATCA_STATUS calib_write_pubkey(ATCADevice device, uint16_t slot, const uint8_t *public_key); ATCA_STATUS calib_write_config_zone(ATCADevice device, const uint8_t* config_data); +// ECC204 Write command functions +ATCA_STATUS calib_ecc204_write(ATCADevice device, uint8_t zone, uint16_t address, const uint8_t *value, + const uint8_t *mac); +ATCA_STATUS calib_ecc204_write_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, + uint8_t offset, const uint8_t *data, uint8_t len); +ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, uint8_t* config_data); +ATCA_STATUS calib_ecc204_write_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t block, + const uint8_t *data, size_t length); #if defined(ATCA_USE_CONSTANT_HOST_NONCE) ATCA_STATUS calib_write_enc(ATCADevice device, uint16_t key_id, uint8_t block, const uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id); @@ -185,6 +213,14 @@ ATCA_STATUS calib_write_enc(ATCADevice device, uint16_t key_id, uint8_t block, c ATCA_STATUS calib_write_enc(ATCADevice device, uint16_t key_id, uint8_t block, const uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id, const uint8_t num_in[NONCE_NUMIN_SIZE]); #endif +#if defined(ATCA_USE_CONSTANT_HOST_NONCE) +ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint8_t slot, uint8_t* data, uint8_t* transport_key, + uint8_t key_id); +#else +ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint8_t slot, uint8_t* data, uint8_t* transport_key, + uint8_t key_id, uint8_t num_in[NONCE_NUMIN_SIZE]); +#endif + ATCA_STATUS calib_write_config_counter(ATCADevice device, uint16_t counter_id, uint32_t counter_value); #ifdef __cplusplus diff --git a/lib/calib/calib_checkmac.c b/lib/calib/calib_checkmac.c index 5440a4805..d0cf73daf 100644 --- a/lib/calib/calib_checkmac.c +++ b/lib/calib/calib_checkmac.c @@ -50,7 +50,6 @@ ATCA_STATUS calib_checkmac(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t *challenge, const uint8_t *response, const uint8_t *other_data) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; // Verify the inputs @@ -62,7 +61,6 @@ ATCA_STATUS calib_checkmac(ATCADevice device, uint8_t mode, uint16_t key_id, con do { - ca_cmd = device->mCommands; // build Check MAC command packet.param1 = mode; packet.param2 = key_id; @@ -77,7 +75,7 @@ ATCA_STATUS calib_checkmac(ATCADevice device, uint8_t mode, uint16_t key_id, con memcpy(&packet.data[32], response, CHECKMAC_CLIENT_RESPONSE_SIZE); memcpy(&packet.data[64], other_data, CHECKMAC_OTHER_DATA_SIZE); - if ((status = atCheckMAC(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atCheckMAC(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atCheckMAC - failed"); break; diff --git a/lib/calib/calib_command.c b/lib/calib/calib_command.c index 43130c9b0..8d2171c67 100644 --- a/lib/calib/calib_command.c +++ b/lib/calib/calib_command.c @@ -39,7 +39,7 @@ * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atCheckMAC(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atCheckMAC(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_CHECKMAC; @@ -53,7 +53,7 @@ ATCA_STATUS atCheckMAC(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS atCounter(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atCounter(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_COUNTER; @@ -68,7 +68,7 @@ ATCA_STATUS atCounter(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] has_mac hasMAC determines if MAC data is present in the packet input * \return ATCA_SUCCESS */ -ATCA_STATUS atDeriveKey(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac) +ATCA_STATUS atDeriveKey(ATCADeviceType device_type, ATCAPacket *packet, bool has_mac) { // Set the opcode & parameters packet->opcode = ATCA_DERIVE_KEY; @@ -92,7 +92,7 @@ ATCA_STATUS atDeriveKey(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atECDH(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atECDH(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_ECDH; @@ -107,7 +107,7 @@ ATCA_STATUS atECDH(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] is_no_mac_key Should be true if GenDig is being run on a slot that has its SlotConfig.NoMac bit set * \return ATCA_SUCCESS */ -ATCA_STATUS atGenDig(ATCACommand ca_cmd, ATCAPacket *packet, bool is_no_mac_key) +ATCA_STATUS atGenDig(ATCADeviceType device_type, ATCAPacket *packet, bool is_no_mac_key) { // Set the opcode & parameters packet->opcode = ATCA_GENDIG; @@ -133,7 +133,7 @@ ATCA_STATUS atGenDig(ATCACommand ca_cmd, ATCAPacket *packet, bool is_no_mac_key) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atGenKey(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atGenKey(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_GENKEY; @@ -155,7 +155,7 @@ ATCA_STATUS atGenKey(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atHMAC(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atHMAC(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_HMAC; @@ -169,7 +169,7 @@ ATCA_STATUS atHMAC(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atInfo(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atInfo(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_INFO; @@ -183,7 +183,7 @@ ATCA_STATUS atInfo(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atLock(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atLock(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_LOCK; @@ -197,7 +197,7 @@ ATCA_STATUS atLock(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atMAC(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atMAC(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters // variable packet size @@ -219,7 +219,7 @@ ATCA_STATUS atMAC(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS atNonce(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atNonce(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters // variable packet size @@ -259,7 +259,7 @@ ATCA_STATUS atNonce(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atPause(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atPause(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_PAUSE; @@ -273,7 +273,7 @@ ATCA_STATUS atPause(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atPrivWrite(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atPrivWrite(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_PRIVWRITE; @@ -287,7 +287,7 @@ ATCA_STATUS atPrivWrite(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atRandom(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atRandom(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_RANDOM; @@ -301,7 +301,7 @@ ATCA_STATUS atRandom(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atRead(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atRead(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_READ; @@ -315,7 +315,7 @@ ATCA_STATUS atRead(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atSecureBoot(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atSecureBoot(ATCADeviceType device_type, ATCAPacket *packet) { packet->opcode = ATCA_SECUREBOOT; packet->txsize = ATCA_CMD_SIZE_MIN; @@ -346,7 +346,7 @@ ATCA_STATUS atSecureBoot(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] write_context_size the length of the sha write_context data * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS atSHA(ATCACommand ca_cmd, ATCAPacket *packet, uint16_t write_context_size) +ATCA_STATUS atSHA(ATCADeviceType device_type, ATCAPacket *packet, uint16_t write_context_size) { // Set the opcode & parameters packet->opcode = ATCA_SHA; @@ -355,7 +355,7 @@ ATCA_STATUS atSHA(ATCACommand ca_cmd, ATCAPacket *packet, uint16_t write_context { case SHA_MODE_SHA256_START: // START case SHA_MODE_HMAC_START: - case SHA_MODE_SHA256_PUBLIC: + case 0x03: // SHA_MODE_SHA256_PUBLIC || SHA_MODE_ECC204_HMAC_START packet->txsize = ATCA_CMD_SIZE_MIN; break; @@ -388,11 +388,15 @@ ATCA_STATUS atSHA(ATCACommand ca_cmd, ATCAPacket *packet, uint16_t write_context * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atSign(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atSign(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_SIGN; packet->txsize = SIGN_COUNT; + if (ECC204 == device_type) + { + packet->txsize += ATCA_SHA_DIGEST_SIZE; + } atCalcCrc(packet); return ATCA_SUCCESS; } @@ -402,7 +406,7 @@ ATCA_STATUS atSign(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atUpdateExtra(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atUpdateExtra(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_UPDATE_EXTRA; @@ -416,7 +420,7 @@ ATCA_STATUS atUpdateExtra(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS atVerify(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atVerify(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_VERIFY; @@ -455,20 +459,39 @@ ATCA_STATUS atVerify(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] has_mac Flag to indicate whether a mac is present or not * \return ATCA_SUCCESS */ -ATCA_STATUS atWrite(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac) +ATCA_STATUS atWrite(ATCADeviceType device_type, ATCAPacket *packet, bool has_mac) { // Set the opcode & parameters packet->opcode = ATCA_WRITE; packet->txsize = 7; - if (packet->param1 & ATCA_ZONE_READWRITE_32) + if (ECC204 == device_type) { - packet->txsize += ATCA_BLOCK_SIZE; +#ifdef ATCA_ECC204_SUPPORT + if (ATCA_ECC204_ZONE_CONFIG == packet->param1) + { + packet->txsize += 16; + } + else if (ATCA_ECC204_ZONE_DATA == packet->param1) + { + packet->txsize += ATCA_BLOCK_SIZE; + } +#else + return ATCA_UNIMPLEMENTED; +#endif } else { - packet->txsize += ATCA_WORD_SIZE; + if (packet->param1 & ATCA_ZONE_READWRITE_32) + { + packet->txsize += ATCA_BLOCK_SIZE; + } + else + { + packet->txsize += ATCA_WORD_SIZE; + } } + if (has_mac) { packet->txsize += WRITE_MAC_SIZE; @@ -482,7 +505,7 @@ ATCA_STATUS atWrite(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atAES(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atAES(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_AES; @@ -505,7 +528,7 @@ ATCA_STATUS atAES(ATCACommand ca_cmd, ATCAPacket *packet) * \param[in] packet pointer to the packet containing the command being built * \return ATCA_SUCCESS */ -ATCA_STATUS atSelfTest(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atSelfTest(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_SELFTEST; @@ -522,7 +545,7 @@ ATCA_STATUS atSelfTest(ATCACommand ca_cmd, ATCAPacket *packet) * built. * \return ATCA_SUCCESS */ -ATCA_STATUS atKDF(ATCACommand ca_cmd, ATCAPacket *packet) +ATCA_STATUS atKDF(ATCADeviceType device_type, ATCAPacket *packet) { // Set the opcode & parameters packet->opcode = ATCA_KDF; @@ -644,6 +667,7 @@ bool atIsECCFamily(ATCADeviceType device_type) case ATECC108A: case ATECC508A: case ATECC608: + case ECC204: return true; break; default: diff --git a/lib/calib/calib_command.h b/lib/calib/calib_command.h index 90b5e3e87..5fcac6d7b 100644 --- a/lib/calib/calib_command.h +++ b/lib/calib/calib_command.h @@ -36,7 +36,6 @@ #define CALIB_COMMAND_H #include -#include "atca_command.h" #ifdef __cplusplus extern "C" { #endif @@ -104,30 +103,30 @@ typedef struct #endif -ATCA_STATUS atCheckMAC(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atCounter(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atDeriveKey(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac); -ATCA_STATUS atECDH(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atGenDig(ATCACommand ca_cmd, ATCAPacket *packet, bool is_no_mac_key); -ATCA_STATUS atGenKey(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atHMAC(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atInfo(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atLock(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atMAC(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atNonce(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atPause(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atPrivWrite(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atRandom(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atRead(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atSecureBoot(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atSHA(ATCACommand ca_cmd, ATCAPacket *packet, uint16_t write_context_size); -ATCA_STATUS atSign(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atUpdateExtra(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atVerify(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atWrite(ATCACommand ca_cmd, ATCAPacket *packet, bool has_mac); -ATCA_STATUS atAES(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atSelfTest(ATCACommand ca_cmd, ATCAPacket *packet); -ATCA_STATUS atKDF(ATCACommand ca_cmd, ATCAPacket *packet); +ATCA_STATUS atCheckMAC(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atCounter(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atDeriveKey(ATCADeviceType device_type, ATCAPacket *packet, bool has_mac); +ATCA_STATUS atECDH(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atGenDig(ATCADeviceType device_type, ATCAPacket *packet, bool is_no_mac_key); +ATCA_STATUS atGenKey(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atHMAC(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atInfo(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atLock(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atMAC(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atNonce(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atPause(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atPrivWrite(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atRandom(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atRead(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atSecureBoot(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atSHA(ATCADeviceType device_type, ATCAPacket *packet, uint16_t write_context_size); +ATCA_STATUS atSign(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atUpdateExtra(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atVerify(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atWrite(ATCADeviceType device_type, ATCAPacket *packet, bool has_mac); +ATCA_STATUS atAES(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atSelfTest(ATCADeviceType device_type, ATCAPacket *packet); +ATCA_STATUS atKDF(ATCADeviceType device_type, ATCAPacket *packet); bool atIsSHAFamily(ATCADeviceType device_type); bool atIsECCFamily(ATCADeviceType device_type); @@ -202,6 +201,8 @@ ATCA_STATUS atCheckCrc(const uint8_t *response); #define ATCA_KEY_COUNT (16) //!< number of keys #define ATCA_ECC_CONFIG_SIZE (128) //!< size of configuration zone #define ATCA_SHA_CONFIG_SIZE (88) //!< size of configuration zone +#define ATCA_ECC204_CONFIG_SIZE (64) //!< size of ECC204 configuration zone +#define ATCA_ECC204_CONFIG_SLOT_SIZE (16) //!< size of ECC204 configuration slot size #define ATCA_OTP_SIZE (64) //!< size of OTP zone #define ATCA_DATA_SIZE (ATCA_KEY_COUNT * ATCA_KEY_SIZE) //!< size of data zone #define ATCA_AES_GFM_SIZE ATCA_BLOCK_SIZE //!< size of GFM data @@ -386,6 +387,7 @@ ATCA_STATUS atCheckCrc(const uint8_t *response); #define GENKEY_MODE_PUBLIC ((uint8_t)0x00) //!< GenKey mode: public key calculation #define GENKEY_MODE_DIGEST ((uint8_t)0x08) //!< GenKey mode: PubKey digest will be created after the public key is calculated #define GENKEY_MODE_PUBKEY_DIGEST ((uint8_t)0x10) //!< GenKey mode: Calculate PubKey digest on the public key in KeyId +#define GENKEY_MODE_MAC ((uint8_t)0x20) //!< Genkey mode: Calculate MAC of public key + session key #define GENKEY_PRIVATE_TO_TEMPKEY ((uint16_t)0xFFFF) //!< GenKey Create private key and store to tempkey (608 only) #define GENKEY_RSP_SIZE_SHORT ATCA_RSP_SIZE_MIN //!< GenKey response packet size in Digest mode #define GENKEY_RSP_SIZE_LONG ATCA_RSP_SIZE_64 //!< GenKey response packet size when returning a public key @@ -414,6 +416,7 @@ ATCA_STATUS atCheckCrc(const uint8_t *response); #define INFO_MODE_REVISION ((uint8_t)0x00) //!< Info mode Revision #define INFO_MODE_KEY_VALID ((uint8_t)0x01) //!< Info mode KeyValid #define INFO_MODE_STATE ((uint8_t)0x02) //!< Info mode State +#define INFO_MODE_LOCK_STATUS ((uint8_t)0x02) //!< Info mode Lock status for ECC204 device #define INFO_MODE_GPIO ((uint8_t)0x03) //!< Info mode GPIO #define INFO_MODE_VOL_KEY_PERMIT ((uint8_t)0x04) //!< Info mode GPIO #define INFO_MODE_MAX ((uint8_t)0x03) //!< Info mode maximum value @@ -486,6 +489,8 @@ ATCA_STATUS atCheckCrc(const uint8_t *response); #define LOCK_ZONE_CONFIG ((uint8_t)0x00) //!< Lock zone is Config #define LOCK_ZONE_DATA ((uint8_t)0x01) //!< Lock zone is OTP or Data #define LOCK_ZONE_DATA_SLOT ((uint8_t)0x02) //!< Lock slot of Data +#define LOCK_ECC204_ZONE_DATA ((uint8_t)0x00) //!< Lock ECC204 Data zone by slot +#define LOCK_ECC204_ZONE_CONFIG ((uint8_t)0x01) //!< Lock ECC204 configuration zone by slot #define LOCK_ZONE_NO_CRC ((uint8_t)0x80) //!< Lock command: Ignore summary. #define LOCK_ZONE_MASK (0xBF) //!< Lock parameter 1 bits 6 are 0. #define ATCA_UNLOCKED (0x55) //!< Value indicating an unlocked zone @@ -528,6 +533,7 @@ ATCA_STATUS atCheckCrc(const uint8_t *response); #define NONCE_MODE_NO_SEED_UPDATE ((uint8_t)0x01) //!< Nonce mode: do not update seed #define NONCE_MODE_INVALID ((uint8_t)0x02) //!< Nonce mode 2 is invalid. #define NONCE_MODE_PASSTHROUGH ((uint8_t)0x03) //!< Nonce mode: pass-through +#define NONCE_MODE_GEN_SESSION_KEY ((uint8_t)0x02) //!< NOnce mode: Generate session key in ECC204 device #define NONCE_MODE_INPUT_LEN_MASK ((uint8_t)0x20) //!< Nonce mode: input size mask #define NONCE_MODE_INPUT_LEN_32 ((uint8_t)0x00) //!< Nonce mode: input size is 32 bytes @@ -642,9 +648,11 @@ ATCA_STATUS atCheckCrc(const uint8_t *response); #define SHA_MODE_SHA256_END ((uint8_t)0x02) //!< Complete the calculation and return the digest #define SHA_MODE_SHA256_PUBLIC ((uint8_t)0x03) //!< Add 64 byte ECC public key in the slot to the SHA context #define SHA_MODE_HMAC_START ((uint8_t)0x04) //!< Initialization, HMAC calculation +#define SHA_MODE_ECC204_HMAC_START ((uint8_t)0x03) //!< Initialization, HMAC calculation for ECC204 #define SHA_MODE_HMAC_UPDATE ((uint8_t)0x01) //!< Add 64 bytes in the meesage to the SHA context #define SHA_MODE_HMAC_END ((uint8_t)0x05) //!< Complete the HMAC computation and return digest #define SHA_MODE_608_HMAC_END ((uint8_t)0x02) //!< Complete the HMAC computation and return digest... Different command on 608 +#define SHA_MODE_ECC204_HMAC_END ((uint8_t)0x02) //!< Complete the HMAC computation and return digest... Different mode on ECC204 #define SHA_MODE_READ_CONTEXT ((uint8_t)0x06) //!< Read current SHA-256 context out of the device #define SHA_MODE_WRITE_CONTEXT ((uint8_t)0x07) //!< Restore a SHA-256 context into the device #define SHA_MODE_TARGET_MASK ((uint8_t)0xC0) //!< Resulting digest target location mask diff --git a/lib/calib/calib_counter.c b/lib/calib/calib_counter.c index 9bc44d173..32c39d1ab 100644 --- a/lib/calib/calib_counter.c +++ b/lib/calib/calib_counter.c @@ -44,7 +44,6 @@ ATCA_STATUS calib_counter(ATCADevice device, uint8_t mode, uint16_t counter_id, uint32_t *counter_value) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; do @@ -55,12 +54,11 @@ ATCA_STATUS calib_counter(ATCADevice device, uint8_t mode, uint16_t counter_id, break; } - ca_cmd = device->mCommands; // build a Counter command packet.param1 = mode; packet.param2 = counter_id; - if ((status = atCounter(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atCounter(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atCounter - failed"); break; diff --git a/lib/calib/calib_derivekey.c b/lib/calib/calib_derivekey.c index 2979f5bba..dfc388105 100644 --- a/lib/calib/calib_derivekey.c +++ b/lib/calib/calib_derivekey.c @@ -48,7 +48,6 @@ ATCA_STATUS calib_derivekey(ATCADevice device, uint8_t mode, uint16_t target_key, const uint8_t* mac) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; do @@ -59,7 +58,6 @@ ATCA_STATUS calib_derivekey(ATCADevice device, uint8_t mode, uint16_t target_key break; } - ca_cmd = device->mCommands; // build a deriveKey command (pass through mode) packet.param1 = mode; packet.param2 = target_key; @@ -69,7 +67,7 @@ ATCA_STATUS calib_derivekey(ATCADevice device, uint8_t mode, uint16_t target_key memcpy(packet.data, mac, MAC_SIZE); } - if ((status = atDeriveKey(ca_cmd, &packet, mac != NULL)) != ATCA_SUCCESS) + if ((status = atDeriveKey(atcab_get_device_type_ext(device), &packet, mac != NULL)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atDeriveKey - failed"); break; diff --git a/lib/calib/calib_ecdh.c b/lib/calib/calib_ecdh.c index 032cb3c8f..b0f67d1a8 100644 --- a/lib/calib/calib_ecdh.c +++ b/lib/calib/calib_ecdh.c @@ -67,7 +67,7 @@ ATCA_STATUS calib_ecdh_base(ATCADevice device, uint8_t mode, uint16_t key_id, co packet.param2 = key_id; memcpy(packet.data, public_key, ATCA_PUB_KEY_SIZE); - if ((status = atECDH(device->mCommands, &packet)) != ATCA_SUCCESS) + if ((status = atECDH(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atECDH - failed"); break; diff --git a/lib/calib/calib_execution.c b/lib/calib/calib_execution.c index d4e94d205..b83e55252 100644 --- a/lib/calib/calib_execution.c +++ b/lib/calib/calib_execution.c @@ -31,15 +31,7 @@ * THIS SOFTWARE. */ -#include "atca_config.h" - -#include -#include -#include "atca_command.h" -#include "atca_device.h" -#include "calib_execution.h" -#include "atca_devtypes.h" -#include "hal/atca_hal.h" +#include "cryptoauthlib.h" #if defined(ATCA_NO_POLL) && defined(ATCA_ATECC608_SUPPORT) && !defined(ATCA_ATECC608A_SUPPORT) @@ -200,6 +192,20 @@ static const device_execution_time_t device_execution_time_608_m2[] = { { ATCA_VERIFY, 1085}, { ATCA_WRITE, 45} }; + +/*Execution times for ECC204 supported commands...*/ +static const device_execution_time_t device_execution_time_ecc204[] = { + { ATCA_COUNTER, 1}, + { ATCA_GENKEY, 100}, + { ATCA_INFO, 1}, + { ATCA_LOCK, 6}, + { ATCA_NONCE, 35}, + { ATCA_READ, 1}, + { ATCA_SELFTEST, 110}, + { ATCA_SHA, 4}, + { ATCA_SIGN, 100}, + { ATCA_WRITE, 10} +}; // *INDENT-ON* #endif @@ -257,6 +263,11 @@ ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCACommand ca_cmd) } break; + case ECC204: + execution_times = device_execution_time_ecc204; + no_of_commands = sizeof(device_execution_time_ecc204) / sizeof(device_execution_time_t); + break; + default: no_of_commands = 0; execution_times = NULL; @@ -283,6 +294,127 @@ ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCACommand ca_cmd) } #endif +ATCA_STATUS calib_execute_send(ATCADevice device, uint8_t device_address, uint8_t* txdata, uint16_t txlength) +{ + ATCA_STATUS status = ATCA_COMM_FAIL; + + if (!txdata || !txlength) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + +#ifdef ATCA_HAL_LEGACY_API + status = atsend(device->mIface, 0xFF, (uint8_t*)txdata, txlength - 1); +#else + if (atca_iface_is_kit(&device->mIface)) + { + status = atsend(&device->mIface, 0xFF, (uint8_t*)txdata, txlength - 1); + } + else + { + status = atcontrol(&device->mIface, ATCA_HAL_CONTROL_SELECT, NULL, 0); + if (ATCA_UNIMPLEMENTED == status || ATCA_SUCCESS == status) + { + /* Send the command packet to the device */ + status = atsend(&device->mIface, device_address, (uint8_t*)txdata, txlength); + } + (void)atcontrol(&device->mIface, ATCA_HAL_CONTROL_DESELECT, NULL, 0); + } +#endif + + return status; +} + + +ATCA_STATUS calib_execute_receive(ATCADevice device, uint8_t device_address, uint8_t* rxdata, uint16_t* rxlength) +{ + ATCA_STATUS status = ATCA_COMM_FAIL; + uint16_t read_length = 1; + uint8_t word_address; + + if ((NULL == rxlength) || (NULL == rxdata)) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + +#ifdef ATCA_HAL_LEGACY_API + status = atsend(device->mIface, txdata[0], (uint8_t*)txdata, txlength); +#else + if (atca_iface_is_kit(&device->mIface)) + { + status = atreceive(&device->mIface, 0, rxdata, rxlength); + } + else + { + do + { + status = atcontrol(&device->mIface, ATCA_HAL_CONTROL_SELECT, NULL, 0); + if (ATCA_UNIMPLEMENTED != status && ATCA_SUCCESS != status) + { + break; + } + + /*Send Word address to device...*/ + if (ATCA_SWI_IFACE == device->mIface.mIfaceCFG->iface_type) + { + word_address = CALIB_SWI_FLAG_TX; + } + else + { + word_address = 0; + } + + if (ATCA_SUCCESS != (status = atsend(&device->mIface, device_address, &word_address, sizeof(word_address)))) + { + break; + } + + /* Read length bytes to know number of bytes to read */ + status = atreceive(&device->mIface, device_address, rxdata, &read_length); + if (ATCA_SUCCESS != status) + { + ATCA_TRACE(status, "atreceive - failed"); + break; + } + + /*Calculate bytes to read based on device response*/ + read_length = rxdata[0]; + + if (read_length > *rxlength) + { + status = ATCA_TRACE(ATCA_SMALL_BUFFER, "rxdata is small buffer"); + break; + } + + if (read_length < 4) + { + status = ATCA_TRACE(ATCA_RX_FAIL, "packet size is invalid"); + break; + } + + /* Read given length bytes from device */ + read_length -= 1; + status = atreceive(&device->mIface, device_address, &rxdata[1], &read_length); + + if (ATCA_SUCCESS != status) + { + status = ATCA_TRACE(status, "atreceive - failed"); + break; + } + + read_length += 1; + + *rxlength = read_length; + } + while (0); + + (void)atcontrol(&device->mIface, ATCA_HAL_CONTROL_DESELECT, NULL, 0); + } +#endif + + return status; +} + /** \brief Wakes up device, sends the packet, waits for command completion, * receives response, and puts the device into the idle state. * @@ -299,7 +431,8 @@ ATCA_STATUS calib_execute_command(ATCAPacket* packet, ATCADevice device) uint32_t execution_or_wait_time; uint32_t max_delay_count; uint16_t rxsize; - uint8_t word_address = 0xFF; + uint8_t device_address = atcab_get_device_address(device); + int retries = 1; do { @@ -314,19 +447,39 @@ ATCA_STATUS calib_execute_command(ATCAPacket* packet, ATCADevice device) execution_or_wait_time = ATCA_POLLING_INIT_TIME_MSEC; max_delay_count = ATCA_POLLING_MAX_TIME_MSEC / ATCA_POLLING_FREQUENCY_TIME_MSEC; #endif - - if ((status = atwake(device->mIface)) != ATCA_SUCCESS) + retries = atca_iface_get_retries(&device->mIface); + do { - break; - } + if (ATCA_DEVICE_STATE_ACTIVE != device->device_state) + { + if (ATCA_SUCCESS == (status = calib_wakeup(device))) + { + device->device_state = ATCA_DEVICE_STATE_ACTIVE; + } + } + + /* Send the command packet to the device */ + if (ATCA_I2C_IFACE == device->mIface.mIfaceCFG->iface_type) + { + packet->_reserved = 0x03; + } + else if (ATCA_SWI_IFACE == device->mIface.mIfaceCFG->iface_type) + { + packet->_reserved = CALIB_SWI_FLAG_CMD; + } + if (ATCA_RX_NO_RESPONSE == (status = calib_execute_send(device, device_address, (uint8_t*)packet, packet->txsize + 1))) + { + device->device_state = ATCA_DEVICE_STATE_UNKNOWN; + } + else + { + retries = 0; + } - if (ATCA_I2C_IFACE == device->mIface->mIfaceCFG->iface_type) - { - word_address = 0x03; // insert the Word Address Value, Command token } + while (0 < retries--); - // send the command - if ((status = atsend(device->mIface, word_address, (uint8_t*)packet, packet->txsize)) != ATCA_SUCCESS) + if (ATCA_SUCCESS != status) { break; } @@ -339,7 +492,8 @@ ATCA_STATUS calib_execute_command(ATCAPacket* packet, ATCADevice device) memset(packet->data, 0, sizeof(packet->data)); // receive the response rxsize = sizeof(packet->data); - if ((status = atreceive(device->mIface, 0, packet->data, &rxsize)) == ATCA_SUCCESS) + + if (ATCA_SUCCESS == (status = calib_execute_receive(device, device_address, packet->data, &rxsize))) { break; } @@ -350,6 +504,7 @@ ATCA_STATUS calib_execute_command(ATCAPacket* packet, ATCADevice device) #endif } while (max_delay_count-- > 0); + if (status != ATCA_SUCCESS) { break; @@ -381,6 +536,12 @@ ATCA_STATUS calib_execute_command(ATCAPacket* packet, ATCADevice device) } while (0); - atidle(device->mIface); + // Skip Idle for ECC204 device + if (ECC204 != device->mIface.mIfaceCFG->devtype) + { + (void)calib_idle(device); + device->device_state = ATCA_DEVICE_STATE_IDLE; + } + return status; -} \ No newline at end of file +} diff --git a/lib/calib/calib_execution.h b/lib/calib/calib_execution.h index e5e2122a8..11c69acad 100644 --- a/lib/calib/calib_execution.h +++ b/lib/calib/calib_execution.h @@ -47,6 +47,12 @@ extern "C" { #define ATCA_UNSUPPORTED_CMD ((uint16_t)0xFFFF) +#define CALIB_SWI_FLAG_WAKE 0x00 //!< flag preceding a command +#define CALIB_SWI_FLAG_CMD 0x77 //!< flag preceding a command +#define CALIB_SWI_FLAG_TX 0x88 //!< flag requesting a response +#define CALIB_SWI_FLAG_IDLE 0xBB //!< flag requesting to go into Idle mode +#define CALIB_SWI_FLAG_SLEEP 0xCC //!< flag requesting to go into Sleep mode + #ifdef ATCA_NO_POLL /** \brief Structure to hold the device execution time and the opcode for the * corresponding command @@ -60,6 +66,10 @@ typedef struct ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCACommand ca_cmd); #endif +#ifndef ATCA_HAL_LEGACY_API +ATCA_STATUS calib_execute_receive(ATCADevice device, uint8_t device_address, uint8_t* rxdata, uint16_t* rxlength); +#endif + ATCA_STATUS calib_execute_command(ATCAPacket* packet, ATCADevice device); #ifdef __cplusplus diff --git a/lib/calib/calib_gendig.c b/lib/calib/calib_gendig.c index 92ed8bebd..ec00966b6 100644 --- a/lib/calib/calib_gendig.c +++ b/lib/calib/calib_gendig.c @@ -49,7 +49,6 @@ ATCA_STATUS calib_gendig(ATCADevice device, uint8_t zone, uint16_t key_id, const uint8_t *other_data, uint8_t other_data_size) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; bool is_no_mac_key = false; @@ -60,7 +59,6 @@ ATCA_STATUS calib_gendig(ATCADevice device, uint8_t zone, uint16_t key_id, const do { - ca_cmd = device->mCommands; // build gendig command packet.param1 = zone; packet.param2 = key_id; @@ -75,7 +73,7 @@ ATCA_STATUS calib_gendig(ATCADevice device, uint8_t zone, uint16_t key_id, const is_no_mac_key = true; } - if ((status = atGenDig(ca_cmd, &packet, is_no_mac_key)) != ATCA_SUCCESS) + if ((status = atGenDig(atcab_get_device_type_ext(device), &packet, is_no_mac_key)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atGenDig - failed"); break; diff --git a/lib/calib/calib_genkey.c b/lib/calib/calib_genkey.c index ee3f0cd90..82562b065 100644 --- a/lib/calib/calib_genkey.c +++ b/lib/calib/calib_genkey.c @@ -54,7 +54,6 @@ ATCA_STATUS calib_genkey_base(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* other_data, uint8_t* public_key) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; do @@ -65,7 +64,6 @@ ATCA_STATUS calib_genkey_base(ATCADevice device, uint8_t mode, uint16_t key_id, break; } - ca_cmd = device->mCommands; // Build GenKey command packet.param1 = mode; packet.param2 = key_id; @@ -74,7 +72,7 @@ ATCA_STATUS calib_genkey_base(ATCADevice device, uint8_t mode, uint16_t key_id, memcpy(packet.data, other_data, GENKEY_OTHER_DATA_SIZE); } - if ((status = atGenKey(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atGenKey(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atGenKey - failed"); break; @@ -137,4 +135,65 @@ ATCA_STATUS calib_genkey(ATCADevice device, uint16_t key_id, uint8_t *public_key ATCA_STATUS calib_get_pubkey(ATCADevice device, uint16_t key_id, uint8_t *public_key) { return calib_genkey_base(device, GENKEY_MODE_PUBLIC, key_id, NULL, public_key); +} + +/** \brief Uses Genkey command to calculate SHA256 digest MAC of combining public key + * and session key + * + * \param[in] device Device Context pointer + * \param[out] public_key Public key will be returned here. Format will be + * the X and Y integers in big-endian format. + * 64 bytes for P256 curve. + * \param[out] mac Combine public key referenced by keyID with current value + * of session key, calculate a SHA256 digest and return that MAC here. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_genkey_mac(ATCADevice device, uint8_t* public_key, uint8_t* mac) +{ + ATCAPacket packet; + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (device) + { + packet.param1 = GENKEY_MODE_MAC; + packet.param2 = (uint16_t)0x00; + + status = atGenKey(atcab_get_device_type_ext(device), &packet); + if (ATCA_SUCCESS == status) + { + status = atca_execute_command(&packet, device); + } + + if (ATCA_SUCCESS == status) + { + if ((ATCA_PUB_KEY_SIZE + ATCA_PACKET_OVERHEAD + MAC_SIZE) == packet.data[ATCA_COUNT_IDX]) + { + if (public_key) + { + memcpy(public_key, &packet.data[ATCA_RSP_DATA_IDX], ATCA_PUB_KEY_SIZE); + } + if (mac) + { + memcpy(mac, &packet.data[ATCA_RSP_DATA_IDX + ATCA_PUB_KEY_SIZE], MAC_SIZE); + } + } + else + { + status = ATCA_TRACE(ATCA_RX_FAIL, "Received response failure"); + } + + } + else + { + ATCA_TRACE(status, "calib_genkey_mac - failed"); + } + + } + else + { + ATCA_TRACE(status, "NULL pointer encountered"); + } + + return status; } \ No newline at end of file diff --git a/lib/calib/calib_hmac.c b/lib/calib/calib_hmac.c index 13fd23125..058218317 100644 --- a/lib/calib/calib_hmac.c +++ b/lib/calib/calib_hmac.c @@ -52,7 +52,6 @@ ATCA_STATUS calib_hmac(ATCADevice device, uint8_t mode, uint16_t key_id, uint8_t* digest) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; do @@ -63,12 +62,11 @@ ATCA_STATUS calib_hmac(ATCADevice device, uint8_t mode, uint16_t key_id, uint8_t break; } - ca_cmd = device->mCommands; // build HMAC command packet.param1 = mode; packet.param2 = key_id; - if ((status = atHMAC(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atHMAC(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atHMAC - failed"); break; diff --git a/lib/calib/calib_info.c b/lib/calib/calib_info.c index 9af59143e..d289b5507 100644 --- a/lib/calib/calib_info.c +++ b/lib/calib/calib_info.c @@ -51,7 +51,6 @@ ATCA_STATUS calib_info_base(ATCADevice device, uint8_t mode, uint16_t param2, uint8_t* out_data) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; if (device == NULL) @@ -59,7 +58,6 @@ ATCA_STATUS calib_info_base(ATCADevice device, uint8_t mode, uint16_t param2, ui return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); } - ca_cmd = device->mCommands; // build an info command packet.param1 = mode; packet.param2 = param2; @@ -67,7 +65,7 @@ ATCA_STATUS calib_info_base(ATCADevice device, uint8_t mode, uint16_t param2, ui do { - if ((status = atInfo(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atInfo(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atInfo - failed"); break; @@ -79,9 +77,24 @@ ATCA_STATUS calib_info_base(ATCADevice device, uint8_t mode, uint16_t param2, ui break; } - if (out_data != NULL && packet.data[ATCA_COUNT_IDX] >= 7) + uint8_t response = packet.data[ATCA_COUNT_IDX]; + + if (response && out_data) { - memcpy(out_data, &packet.data[ATCA_RSP_DATA_IDX], 4); + if (((INFO_MODE_LOCK_STATUS == mode) || (INFO_MODE_KEY_VALID == mode)) + && (ECC204 == device->mIface.mIfaceCFG->devtype)) + { + memcpy(out_data, &packet.data[ATCA_RSP_DATA_IDX], 1); + } + else if (response >= 7) + { + memcpy(out_data, &packet.data[ATCA_RSP_DATA_IDX], 4); + } + else + { + // do nothing + } + } } while (0); @@ -148,3 +161,141 @@ ATCA_STATUS calib_info_set_latch(ATCADevice device, bool state) param2 |= state ? INFO_PARAM2_LATCH_SET : INFO_PARAM2_LATCH_CLEAR; return calib_info_base(device, INFO_MODE_VOL_KEY_PERMIT, param2, NULL); } + +/** \brief Use Info command to check ECC Private key stored in key slot is valid or not + * + * \param[in] device Device context pointer + * \param[in] key_id ECC private key slot id + * For ECC204, key_id is 0x00 + * \param[out] is_valid return private key is valid or invalid + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_info_privkey_valid(ATCADevice device, uint16_t key_id, uint8_t* is_valid) +{ + return calib_info_base(device, INFO_MODE_KEY_VALID, key_id, is_valid); +} + +#if defined(ATCA_ECC204_SUPPORT) +/** \brief Use Info command to ECC204 config/data zone lock status + * + * \param[in] device Device context pointer + * \param[in] param2 selects the zone and slot + * \param[out] is_locked return lock status here + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_info_lock_status(ATCADevice device, uint16_t param2, uint8_t* is_locked) +{ + return calib_info_base(device, INFO_MODE_LOCK_STATUS, param2, is_locked); +} + +/** \brief Use Info command to check ECC204 Config zone lock status + * + * \param[in] device Device context pointer + * \param[out] is_locked return lock status + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_is_config_locked(ATCADevice device, bool* is_locked) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint16_t param2; + uint8_t slot = 0; + + if (NULL == is_locked) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + while (slot <= 3) + { + param2 = ATCA_ECC204_ZONE_CONFIG | (slot << 1); + if (ATCA_SUCCESS != (status = calib_info_lock_status(device, param2, (uint8_t*)is_locked))) + { + *is_locked = false; + break; + } + + if (*is_locked) + { + slot += 1; // increment slot + } + else + { + break; + } + } + + return status; +} + +/** \brief Use Info command to check ECC204 Data zone lock status + * + * \param[in] device Device context pointer + * \param[out] is_locked return lock status + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_is_data_locked(ATCADevice device, bool* is_locked) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint16_t param2; + uint8_t slot = 0; + + if (NULL == is_locked) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + while (slot <= 3) + { + param2 = ATCA_ECC204_ZONE_DATA | (slot << 1); + if (ATCA_SUCCESS != (status = calib_info_lock_status(device, param2, (uint8_t*)is_locked))) + { + *is_locked = false; + break; + } + + if (*is_locked) + { + slot += 1; // increment slot + } + else + { + break; + } + } + + return status; +} + +/** \brief Use Info command to check config/data is locked or not + * + * \param[in] device Device contect pointer + * \param[in] zone Config/Data zone + * \param[out] is_locked return lock status here + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_is_locked(ATCADevice device, uint8_t zone, bool* is_locked) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if (ATCA_ECC204_ZONE_CONFIG == zone) + { + status = calib_ecc204_is_config_locked(device, is_locked); + } + else if (ATCA_ECC204_ZONE_DATA == zone) + { + status = calib_ecc204_is_data_locked(device, is_locked); + } + else + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); + } + + return status; +} + +#endif \ No newline at end of file diff --git a/lib/calib/calib_kdf.c b/lib/calib/calib_kdf.c index 325573789..293056284 100644 --- a/lib/calib/calib_kdf.c +++ b/lib/calib/calib_kdf.c @@ -64,7 +64,6 @@ ATCA_STATUS calib_kdf(ATCADevice device, uint8_t mode, uint16_t key_id, const uint32_t details, const uint8_t* message, uint8_t* out_data, uint8_t* out_nonce) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; uint16_t out_data_size = 0; @@ -76,7 +75,6 @@ ATCA_STATUS calib_kdf(ATCADevice device, uint8_t mode, uint16_t key_id, const ui break; } - ca_cmd = device->mCommands; // Build the KDF command packet.param1 = mode; packet.param2 = key_id; @@ -100,7 +98,7 @@ ATCA_STATUS calib_kdf(ATCADevice device, uint8_t mode, uint16_t key_id, const ui } // Build command - if ((status = atKDF(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atKDF(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atKDF - failed"); break; diff --git a/lib/calib/calib_lock.c b/lib/calib/calib_lock.c index 91727456a..defb6e317 100644 --- a/lib/calib/calib_lock.c +++ b/lib/calib/calib_lock.c @@ -50,7 +50,6 @@ ATCA_STATUS calib_lock(ATCADevice device, uint8_t mode, uint16_t summary_crc) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; if (device == NULL) @@ -58,7 +57,6 @@ ATCA_STATUS calib_lock(ATCADevice device, uint8_t mode, uint16_t summary_crc) return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); } - ca_cmd = device->mCommands; // build command for lock zone and send memset(&packet, 0, sizeof(packet)); packet.param1 = mode; @@ -66,7 +64,7 @@ ATCA_STATUS calib_lock(ATCADevice device, uint8_t mode, uint16_t summary_crc) do { - if ((status = atLock(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atLock(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atLock - failed"); break; @@ -151,3 +149,64 @@ ATCA_STATUS calib_lock_data_slot(ATCADevice device, uint16_t slot) { return calib_lock(device, ((uint8_t)slot << 2) | LOCK_ZONE_DATA_SLOT, 0); } + +/** \brief Use Lock command to lock individual configuration zone slots + * + * \param[in] device Device context pointer + * \param[in] slot The slot number to be locked + * \param[in] summary_crc CRC calculated over all 16 bytes within the selected + * slot of the configuration zone. + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_lock_config_slot(ATCADevice device, uint8_t slot, uint16_t summary_crc) +{ + uint8_t mode = LOCK_ECC204_ZONE_CONFIG | (slot << 1); + + if (!summary_crc) + { + mode |= LOCK_ZONE_NO_CRC; + } + + return calib_lock(device, mode, summary_crc); +} + +/** \brief Use lock command to lock complete configuration zone + * + * \param[in] device Device context pointer + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_lock_config_zone(ATCADevice device) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t slot = 0; + uint8_t mode; + + while (slot <= 3) + { + mode = LOCK_ZONE_NO_CRC | LOCK_ECC204_ZONE_CONFIG | (slot << 1); + + if (ATCA_SUCCESS != (status = calib_lock(device, mode, 0))) + { + ATCA_TRACE(status, "calib_ecc204_lock_config_zone - failed"); + break; + } + + slot += 1; //Increment slot + } + + return status; +} + +/** \brief Use lock command to lock data zone slot + * + * \param[in] device Device context pointer + * \param[in] slot The slot number to be locked + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_lock_data_slot(ATCADevice device, uint8_t slot) +{ + return calib_lock(device, LOCK_ECC204_ZONE_DATA | (slot << 1), 0); +} \ No newline at end of file diff --git a/lib/calib/calib_mac.c b/lib/calib/calib_mac.c index 9e831864b..1c362204d 100644 --- a/lib/calib/calib_mac.c +++ b/lib/calib/calib_mac.c @@ -52,7 +52,6 @@ ATCA_STATUS calib_mac(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* challenge, uint8_t* digest) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; do @@ -63,7 +62,6 @@ ATCA_STATUS calib_mac(ATCADevice device, uint8_t mode, uint16_t key_id, const ui break; } - ca_cmd = device->mCommands; // build mac command packet.param1 = mode; packet.param2 = key_id; @@ -76,7 +74,7 @@ ATCA_STATUS calib_mac(ATCADevice device, uint8_t mode, uint16_t key_id, const ui memcpy(&packet.data[0], challenge, 32); // a 32-byte challenge } - if ((status = atMAC(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atMAC(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atMAC - failed"); break; diff --git a/lib/calib/calib_nonce.c b/lib/calib/calib_nonce.c index b1a26e567..9f134e4d4 100644 --- a/lib/calib/calib_nonce.c +++ b/lib/calib/calib_nonce.c @@ -41,8 +41,10 @@ * \param[in] device Device context pointer * \param[in] mode Controls the mechanism of the internal RNG or fixed * write. - * \param[in] zero Param2, normally 0, but can be used to indicate a + * \param[in] param2 Param2, normally 0, but can be used to indicate a * nonce calculation mode (bit 15). + * For ECC204, represent tarnsport key id greater than + * or equal to 0x8000 * \param[in] num_in Input value to either be included in the nonce * calculation in random modes (20 bytes) or to be * written directly (32 bytes or 64 bytes(ATECC608)) @@ -54,10 +56,9 @@ * * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS calib_nonce_base(ATCADevice device, uint8_t mode, uint16_t zero, const uint8_t *num_in, uint8_t* rand_out) +ATCA_STATUS calib_nonce_base(ATCADevice device, uint8_t mode, uint16_t param2, const uint8_t *num_in, uint8_t* rand_out) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; uint8_t nonce_mode = mode & NONCE_MODE_MASK; @@ -69,13 +70,13 @@ ATCA_STATUS calib_nonce_base(ATCADevice device, uint8_t mode, uint16_t zero, con break; } - ca_cmd = device->mCommands; // build a nonce command packet.param1 = mode; - packet.param2 = zero; + packet.param2 = param2; // Copy the right amount of NumIn data - if ((nonce_mode == NONCE_MODE_SEED_UPDATE || nonce_mode == NONCE_MODE_NO_SEED_UPDATE)) + if ((nonce_mode == NONCE_MODE_SEED_UPDATE) || (nonce_mode == NONCE_MODE_NO_SEED_UPDATE) + || (NONCE_MODE_GEN_SESSION_KEY == nonce_mode)) { memcpy(packet.data, num_in, NONCE_NUMIN_SIZE); } @@ -95,7 +96,7 @@ ATCA_STATUS calib_nonce_base(ATCADevice device, uint8_t mode, uint16_t zero, con return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid nonce mode received"); } - if ((status = atNonce(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atNonce(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atNonce - failed"); break; @@ -216,4 +217,20 @@ ATCA_STATUS calib_challenge(ATCADevice device, const uint8_t *num_in) ATCA_STATUS calib_challenge_seed_update(ATCADevice device, const uint8_t *num_in, uint8_t* rand_out) { return calib_nonce_base(device, NONCE_MODE_SEED_UPDATE, 0, num_in, rand_out); +} + +/** \brief Use Nonce command to generate session key for use by a subsequent write command + * This Mode only supports in ECC204 device. + * \param[in] device Device context pointer + * \param[in] param2 Key id points to transport key + * \param[in] num_in Input value from host system + * \param[out] rand_out Internally generate random number of 32 bytes + * returned here + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_nonce_gen_session_key(ATCADevice device, uint16_t param2, uint8_t* num_in, + uint8_t* rand_out) +{ + return calib_nonce_base(device, NONCE_MODE_GEN_SESSION_KEY, param2, num_in, rand_out); } \ No newline at end of file diff --git a/lib/calib/calib_privwrite.c b/lib/calib/calib_privwrite.c index f6f5d243c..448acbd7d 100644 --- a/lib/calib/calib_privwrite.c +++ b/lib/calib/calib_privwrite.c @@ -60,7 +60,6 @@ ATCA_STATUS calib_priv_write(ATCADevice device, uint16_t key_id, const uint8_t p { #endif ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; atca_nonce_in_out_t nonce_params; atca_gen_dig_in_out_t gen_dig_param; @@ -79,8 +78,6 @@ ATCA_STATUS calib_priv_write(ATCADevice device, uint16_t key_id, const uint8_t p do { - ca_cmd = device->mCommands; - if (write_key == NULL) { // Caller requested an unencrypted PrivWrite, which is only allowed when the data zone is unlocked @@ -174,7 +171,7 @@ ATCA_STATUS calib_priv_write(ATCADevice device, uint16_t key_id, const uint8_t p memcpy(&packet.data[sizeof(cipher_text)], host_mac, sizeof(host_mac)); } - if ((status = atPrivWrite(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atPrivWrite(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atPrivWrite - failed"); break; diff --git a/lib/calib/calib_random.c b/lib/calib/calib_random.c index 97b22d0ec..90516a13c 100644 --- a/lib/calib/calib_random.c +++ b/lib/calib/calib_random.c @@ -44,7 +44,6 @@ ATCA_STATUS calib_random(ATCADevice device, uint8_t *rand_out) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; do @@ -55,12 +54,11 @@ ATCA_STATUS calib_random(ATCADevice device, uint8_t *rand_out) break; } - ca_cmd = device->mCommands; // build an random command packet.param1 = RANDOM_SEED_UPDATE; packet.param2 = 0x0000; - if ((status = atRandom(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atRandom(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atRandom - failed"); break; diff --git a/lib/calib/calib_read.c b/lib/calib/calib_read.c index 94bd541e8..b1196b210 100644 --- a/lib/calib/calib_read.c +++ b/lib/calib/calib_read.c @@ -57,7 +57,6 @@ ATCA_STATUS calib_read_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint8_t *data, uint8_t len) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; uint16_t addr; @@ -89,12 +88,11 @@ ATCA_STATUS calib_read_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint zone = zone | ATCA_ZONE_READWRITE_32; } - ca_cmd = device->mCommands; // build a read command packet.param1 = zone; packet.param2 = addr; - if ((status = atRead(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atRead(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atRead - failed"); break; @@ -368,7 +366,7 @@ ATCA_STATUS calib_read_config_zone(ATCADevice device, uint8_t* config_data) break; } - if (atIsSHAFamily(device->mIface->mIfaceCFG->devtype)) + if (atIsSHAFamily(device->mIface.mIfaceCFG->devtype)) { status = calib_read_bytes_zone(device, ATCA_ZONE_CONFIG, 0, 0x00, config_data, ATCA_SHA_CONFIG_SIZE); } @@ -440,7 +438,7 @@ ATCA_STATUS calib_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* break; } - if (ATECC608 == device->mIface->mIfaceCFG->devtype) + if (ATECC608 == device->mIface.mIfaceCFG->devtype) { /* Skip Counter[0], Counter[1], which can change during operation */ @@ -741,3 +739,230 @@ ATCA_STATUS calib_read_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot return status; } + +#if defined(ATCA_ECC204_SUPPORT) +/** \brief Use Read command to reads words 16 bytes from one of the slots in the EEPROM Configuration + * zone or 32 bytes in Data zone. + * + * \param[in] device Device context pointer + * \param[in] zone Selects config or data zone + * \param[in] slot select slot in config or data zone + * \param[in] block select the lock in given slot + * \param[in] offset 16 byte work index within the block. Ignored for 32 byte + * reads. + * \param[out] data Read data is returned here. + * \param[in] len Length of the data to be read. Must be either 16 or 32. + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_read_zone(ATCADevice device, uint8_t zone, uint8_t slot, uint8_t block, size_t offset, + uint8_t* data, uint8_t len) +{ + ATCA_STATUS status = ATCA_SUCCESS; + ATCAPacket packet; + uint16_t addr; + + (void)offset; + + if ((NULL == device) || (NULL == data)) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Encountered Null pointer"); + } + else if (((ATCA_ECC204_ZONE_CONFIG == zone) && (16 != len)) || + ((ATCA_ECC204_ZONE_DATA == zone) && (32 != len))) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid parameter received"); + } + else if ((ATCA_ECC204_ZONE_DATA == zone) && ((0x00 == slot) || (0x01 == slot))) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot number received"); + } + + if (ATCA_SUCCESS == status) + { + if (ATCA_SUCCESS != (status = calib_ecc204_get_addr(zone, slot, block, 0, &addr))) + { + ATCA_TRACE(status, "Address Encoding failed"); + } + + if (ATCA_SUCCESS == status) + { + // Build packets + packet.param1 = zone; + packet.param2 = addr; + + (void)atRead(atcab_get_device_type_ext(device), &packet); + + // Execute read command + if (ATCA_SUCCESS != (status = atca_execute_command(&packet, device))) + { + ATCA_TRACE(status, "Read command failed"); + } + else + { + memcpy(data, &packet.data[ATCA_RSP_DATA_IDX], len); + } + + } + } + + return status; +} + +/** \brief Use Read command to read configuration zone of ECC204 device + * + * \param[in] device Device context pointer + * \param[out] config_data returns config data of 64 bytes + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_read_config_zone(ATCADevice device, uint8_t* config_data) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t slot = 0; + + while (slot <= 3) + { + if (ATCA_SUCCESS != (status = calib_ecc204_read_zone(device, ATCA_ECC204_ZONE_CONFIG, + slot, 0, 0, + &config_data[ATCA_ECC204_CONFIG_SLOT_SIZE * slot], + ATCA_ECC204_CONFIG_SLOT_SIZE))) + { + ATCA_TRACE(status, "calib_ecc204_read_zone - failed"); + break; + } + slot += 1; // Increment slot to read next slot + } + + return status; +} + +/** \brief Use Read command to read serial number of device + * + * \param[in] device Device context pointer + * \param[in] serial_number 9 bytes ECC204 device serial number return here + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_read_serial_number(ATCADevice device, uint8_t* serial_number) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t read_buf[ATCA_ECC204_CONFIG_SLOT_SIZE]; + + + status = calib_ecc204_read_zone(device, ATCA_ECC204_ZONE_CONFIG, 0, 0, 0, read_buf, + ATCA_ECC204_CONFIG_SLOT_SIZE); + + if (ATCA_SUCCESS == status) + { + memcpy(serial_number, read_buf, ATCA_SERIAL_NUM_SIZE); + } + + return status; +} + +/** \brief Used to read an arbitrary number of bytes from any zone configured + * for clear reads. This function supports only for ECC204 device. + * + * This function will issue the Read command as many times as is required to + * read the requested data. + * + * \param[in] device Device context pointer + * \param[in] zone Zone to read data from. Option are ATCA_ZONE_CONFIG(0), + * ATCA_ZONE_OTP(1), or ATCA_ZONE_DATA(2). + * \param[in] slot Slot number to read from if zone is ATCA_ZONE_DATA(2). + * Ignored for all other zones. + * \param[in] block Byte offset within the zone to read from. + * \param[out] data Read data is returned here. + * \param[in] length Number of bytes to read starting from the offset. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_ecc204_read_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, + size_t block, uint8_t* data, size_t length) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t block_size = (zone == ATCA_ECC204_ZONE_CONFIG) ? ATCA_ECC204_CONFIG_SLOT_SIZE : ATCA_BLOCK_SIZE; + uint8_t no_of_blocks; + uint8_t data_idx = 0; + + if ((NULL == device) || (NULL == data)) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "Encountered NULL pointer"); + } + else if ((ATCA_ECC204_ZONE_DATA == zone) && (((length > 64) && (2 == slot)) || + ((length > 320) && (3 == slot)) || (1 == slot) || (0 == slot))) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid parameter received"); + } + else if (0 == length) + { + return ATCA_SUCCESS; + } + + no_of_blocks = length / block_size; + while (no_of_blocks--) + { + if (ATCA_SUCCESS != (status = calib_ecc204_read_zone(device, zone, slot, block, 0, + &data[block_size * data_idx], + block_size))) + { + ATCA_TRACE(status, "calib_ecc204_read_zone failed"); + break; + } + + block += 1; // Read next block + data_idx += 1; // increment data index + } + + return status; +} + +/** \brief Compares a specified configuration zone with the configuration zone + * currently on the ECC204 device. + * + * This only compares the static portions of the configuration zone and skips + * those that are unique per device (first 16 bytes) and areas that can change + * after the configuration zone has been locked (e.g. Counter). + * + * \param[in] device Device context pointer + * \param[in] config_data Full configuration data to compare the device + * against. + * \param[out] same_config Result is returned here. True if the static portions + * on the configuration zones are the same. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_ecc204_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* same_config) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t device_config_data[ATCA_ECC204_CONFIG_SIZE]; + + if ((NULL == device) || (NULL == config_data) || (NULL == same_config)) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + if (ATCA_SUCCESS == status) + { + *same_config = false; + if (ATCA_SUCCESS != (status = calib_ecc204_read_config_zone(device, device_config_data))) + { + ATCA_TRACE(status, "calib_ecc204_read_config_zone - failed"); + } + } + + if (ATCA_SUCCESS == status) + { + // compare slot 1 and slot 3 data && skip first 16 bytes and counter value + if (!((memcmp(&device_config_data[16], &config_data[16], ATCA_ECC204_CONFIG_SLOT_SIZE)) || + (memcmp(&device_config_data[48], &config_data[48], ATCA_ECC204_CONFIG_SLOT_SIZE)))) + { + *same_config = true; + } + } + + return status; +} + +#endif \ No newline at end of file diff --git a/lib/calib/calib_secureboot.c b/lib/calib/calib_secureboot.c index ebe43939b..2f0e882bf 100644 --- a/lib/calib/calib_secureboot.c +++ b/lib/calib/calib_secureboot.c @@ -52,7 +52,6 @@ ATCA_STATUS calib_secureboot(ATCADevice device, uint8_t mode, uint16_t param2, const uint8_t* digest, const uint8_t* signature, uint8_t* mac) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; if ((device == NULL) || (digest == NULL)) @@ -62,7 +61,6 @@ ATCA_STATUS calib_secureboot(ATCADevice device, uint8_t mode, uint16_t param2, c do { - ca_cmd = device->mCommands; packet.param1 = mode; packet.param2 = param2; @@ -73,7 +71,7 @@ ATCA_STATUS calib_secureboot(ATCADevice device, uint8_t mode, uint16_t param2, c memcpy(&packet.data[SECUREBOOT_DIGEST_SIZE], signature, SECUREBOOT_SIGNATURE_SIZE); } - if ((status = atSecureBoot(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atSecureBoot(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atSecureBoot - failed"); break; diff --git a/lib/calib/calib_selftest.c b/lib/calib/calib_selftest.c index 9211c386a..c23fb27a6 100644 --- a/lib/calib/calib_selftest.c +++ b/lib/calib/calib_selftest.c @@ -50,7 +50,6 @@ ATCA_STATUS calib_selftest(ATCADevice device, uint8_t mode, uint16_t param2, uint8_t* result) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; uint8_t response = 0; @@ -62,12 +61,11 @@ ATCA_STATUS calib_selftest(ATCADevice device, uint8_t mode, uint16_t param2, uin break; } - ca_cmd = device->mCommands; // build a SelfTest command packet.param1 = mode; packet.param2 = param2; - if ((status = atSelfTest(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atSelfTest(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atSelfTest - failed"); break; diff --git a/lib/calib/calib_sha.c b/lib/calib/calib_sha.c index c4a6daf65..05a27c29b 100644 --- a/lib/calib/calib_sha.c +++ b/lib/calib/calib_sha.c @@ -69,7 +69,6 @@ typedef struct ATCA_STATUS calib_sha_base(ATCADevice device, uint8_t mode, uint16_t length, const uint8_t* message, uint8_t* data_out, uint16_t* data_out_size) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; uint8_t cmd_mode = (mode & SHA_MODE_MASK); @@ -77,7 +76,8 @@ ATCA_STATUS calib_sha_base(ATCADevice device, uint8_t mode, uint16_t length, con { return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); } - if (cmd_mode != SHA_MODE_SHA256_PUBLIC && cmd_mode != SHA_MODE_HMAC_START && length > 0 && message == NULL) + if (cmd_mode != SHA_MODE_SHA256_PUBLIC && cmd_mode != SHA_MODE_HMAC_START && + cmd_mode != SHA_MODE_ECC204_HMAC_START && length > 0 && message == NULL) { return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); // message data indicated, but nothing provided } @@ -88,17 +88,17 @@ ATCA_STATUS calib_sha_base(ATCADevice device, uint8_t mode, uint16_t length, con do { - ca_cmd = device->mCommands; //Build Command packet.param1 = mode; packet.param2 = length; - if (cmd_mode != SHA_MODE_SHA256_PUBLIC && cmd_mode != SHA_MODE_HMAC_START) + if (cmd_mode != SHA_MODE_SHA256_PUBLIC && cmd_mode != SHA_MODE_HMAC_START && + cmd_mode != SHA_MODE_ECC204_HMAC_START) { memcpy(packet.data, message, length); } - if ((status = atSHA(ca_cmd, &packet, length)) != ATCA_SUCCESS) + if ((status = atSHA(atcab_get_device_type_ext(device), &packet, length)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atSHA - failed"); break; @@ -298,7 +298,7 @@ ATCA_STATUS calib_hw_sha2_256_finish(ATCADevice device, atca_sha256_ctx_t* ctx, return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); } - if (device->mIface->mIfaceCFG->devtype == ATSHA204A) + if (device->mIface.mIfaceCFG->devtype == ATSHA204A) { // ATSHA204A only implements the raw 64-byte block operation, but // doesn't add in the final footer information. So we do that manually @@ -393,8 +393,21 @@ ATCA_STATUS calib_hw_sha2_256(ATCADevice device, const uint8_t * data, size_t da */ ATCA_STATUS calib_sha_hmac_init(ATCADevice device, atca_hmac_sha256_ctx_t* ctx, uint16_t key_slot) { + uint8_t mode = SHA_MODE_HMAC_START; + + if ((NULL == ctx) || (NULL == device)) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + memset(ctx, 0, sizeof(*ctx)); - return calib_sha_base(device, SHA_MODE_HMAC_START, key_slot, NULL, NULL, NULL); + + if (ECC204 == device->mIface.mIfaceCFG->devtype) + { + mode = SHA_MODE_ECC204_HMAC_START; + } + + return calib_sha_base(device, mode, key_slot, NULL, NULL, NULL); } /** \brief Executes SHA command to add an arbitrary amount of message data to @@ -460,6 +473,7 @@ ATCA_STATUS calib_sha_hmac_update(ATCADevice device, atca_hmac_sha256_ctx_t* ctx * SHA_MODE_TARGET_MSGDIGBUF, or SHA_MODE_TARGET_OUT_ONLY. * For all other devices, SHA_MODE_TARGET_TEMPKEY is the * only option. + * For ECC204, target is ignored (0x00) * * \return ATCA_SUCCESS on success, otherwise an error code. */ @@ -473,10 +487,14 @@ ATCA_STATUS calib_sha_hmac_finish(ATCADevice device, atca_hmac_sha256_ctx_t *ctx return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); } - if (ATECC608A == device->mIface->mIfaceCFG->devtype) + if (ATECC608A == device->mIface.mIfaceCFG->devtype) { mode = SHA_MODE_608_HMAC_END; } + else if (ECC204 == device->mIface.mIfaceCFG->devtype) + { + mode = SHA_MODE_ECC204_HMAC_END; + } else if (target != SHA_MODE_TARGET_TEMPKEY) { return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid target received"); diff --git a/lib/calib/calib_sign.c b/lib/calib/calib_sign.c index 7cbf6a346..e2075d601 100644 --- a/lib/calib/calib_sign.c +++ b/lib/calib/calib_sign.c @@ -50,7 +50,6 @@ ATCA_STATUS calib_sign_base(ATCADevice device, uint8_t mode, uint16_t key_id, uint8_t *signature) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; if ((device == NULL) || (signature == NULL)) @@ -60,11 +59,10 @@ ATCA_STATUS calib_sign_base(ATCADevice device, uint8_t mode, uint16_t key_id, ui do { - ca_cmd = device->mCommands; // Build sign command packet.param1 = mode; packet.param2 = key_id; - if ((status = atSign(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atSign(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atSign - failed"); break; @@ -126,7 +124,7 @@ ATCA_STATUS calib_sign(ATCADevice device, uint16_t key_id, const uint8_t *msg, u } // Load message into device - if (ATECC608 == device->mIface->mIfaceCFG->devtype) + if (ATECC608 == device->mIface.mIfaceCFG->devtype) { // Use the Message Digest Buffer for the ATECC608 nonce_target = NONCE_MODE_TARGET_MSGDIGBUF; @@ -195,3 +193,60 @@ ATCA_STATUS calib_sign_internal(ATCADevice device, uint16_t key_id, bool is_inva return status; } + +/** \brief Execute sign command to sign the 32 bytes message digest using private key + * mentioned in slot. + * + * \param[in] device Device context pointer + * \param[in] key_id points to private key slot + * \param[in] msg 32 bytes message digest + * \param[out] signature Signature is returned here. Format is R and S + * integers in big-endian format. 64 bytes for + * P256 curve. + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_sign(ATCADevice device, uint16_t key_id, const uint8_t* msg, uint8_t* signature) +{ + ATCA_STATUS status = ATCA_SUCCESS; + ATCAPacket packet; + + if ((NULL == device) || (NULL == msg)) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + if (ATCA_SUCCESS == status) + { + packet.param1 = 0x00; + packet.param2 = key_id; + + // copy message digest into i/o buffer + memcpy(packet.data, msg, ATCA_SHA256_DIGEST_SIZE); + + (void)atSign(atcab_get_device_type_ext(device), &packet); + + if (ATCA_SUCCESS != (status = atca_execute_command(&packet, device))) + { + ATCA_TRACE(status, "calib_ecc204_sign - execution failed"); + } + } + + if (ATCA_SUCCESS == status) + { + if (NULL == signature) + { + if (packet.data[ATCA_COUNT_IDX] == (ATCA_SIG_SIZE + ATCA_PACKET_OVERHEAD)) + { + memcpy(signature, &packet.data[ATCA_RSP_DATA_IDX], ATCA_SIG_SIZE); + } + else + { + status = ATCA_RX_FAIL; + } + + } + } + + return status; +} diff --git a/lib/calib/calib_updateextra.c b/lib/calib/calib_updateextra.c index c5c0f4575..7f55bea2f 100644 --- a/lib/calib/calib_updateextra.c +++ b/lib/calib/calib_updateextra.c @@ -50,7 +50,6 @@ ATCA_STATUS calib_updateextra(ATCADevice device, uint8_t mode, uint16_t new_value) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; do @@ -61,13 +60,12 @@ ATCA_STATUS calib_updateextra(ATCADevice device, uint8_t mode, uint16_t new_valu break; } - ca_cmd = device->mCommands; // Build command memset(&packet, 0, sizeof(packet)); packet.param1 = mode; packet.param2 = new_value; - if ((status = atUpdateExtra(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atUpdateExtra(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atUpdateExtra - failed"); break; diff --git a/lib/calib/calib_verify.c b/lib/calib/calib_verify.c index 160f8685a..241cc9d35 100644 --- a/lib/calib/calib_verify.c +++ b/lib/calib/calib_verify.c @@ -69,7 +69,6 @@ ATCA_STATUS calib_verify(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* signature, const uint8_t* public_key, const uint8_t* other_data, uint8_t* mac) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; uint8_t verify_mode = (mode & VERIFY_MODE_MASK); @@ -88,7 +87,6 @@ ATCA_STATUS calib_verify(ATCADevice device, uint8_t mode, uint16_t key_id, const break; } - ca_cmd = device->mCommands; // Build the verify command packet.param1 = mode; packet.param2 = key_id; @@ -102,7 +100,7 @@ ATCA_STATUS calib_verify(ATCADevice device, uint8_t mode, uint16_t key_id, const memcpy(&packet.data[ATCA_SIG_SIZE], other_data, VERIFY_OTHER_DATA_SIZE); } - if ((status = atVerify(ca_cmd, &packet)) != ATCA_SUCCESS) + if ((status = atVerify(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) { ATCA_TRACE(status, "atVerify - failed"); break; @@ -252,7 +250,7 @@ ATCA_STATUS calib_verify_extern(ATCADevice device, const uint8_t *message, const do { // Load message into device - if (ATECC608 == device->mIface->mIfaceCFG->devtype) + if (ATECC608 == device->mIface.mIfaceCFG->devtype) { // Use the Message Digest Buffer for the ATECC608 nonce_target = NONCE_MODE_TARGET_MSGDIGBUF; @@ -338,7 +336,7 @@ ATCA_STATUS calib_verify_stored(ATCADevice device, const uint8_t *message, const do { // Load message into device - if (ATECC608 == device->mIface->mIfaceCFG->devtype) + if (ATECC608 == device->mIface.mIfaceCFG->devtype) { // Use the Message Digest Buffer for the ATECC608 nonce_target = NONCE_MODE_TARGET_MSGDIGBUF; diff --git a/lib/calib/calib_write.c b/lib/calib/calib_write.c index 999dadd8d..e69731385 100644 --- a/lib/calib/calib_write.c +++ b/lib/calib/calib_write.c @@ -59,7 +59,6 @@ ATCA_STATUS calib_write(ATCADevice device, uint8_t zone, uint16_t address, const uint8_t *value, const uint8_t *mac) { ATCAPacket packet; - ATCACommand ca_cmd = NULL; ATCA_STATUS status = ATCA_GEN_FAIL; if ((device == NULL) || (value == NULL)) @@ -69,7 +68,6 @@ ATCA_STATUS calib_write(ATCADevice device, uint8_t zone, uint16_t address, const do { - ca_cmd = device->mCommands; // Build the write command packet.param1 = zone; packet.param2 = address; @@ -89,7 +87,7 @@ ATCA_STATUS calib_write(ATCADevice device, uint8_t zone, uint16_t address, const memcpy(packet.data, value, 4); } - if ((status = atWrite(ca_cmd, &packet, mac && (zone & ATCA_ZONE_READWRITE_32))) != ATCA_SUCCESS) + if ((status = atWrite(atcab_get_device_type_ext(device), &packet, mac && (zone & ATCA_ZONE_READWRITE_32))) != ATCA_SUCCESS) { ATCA_TRACE(status, "atWrite - failed"); break; @@ -558,3 +556,320 @@ ATCA_STATUS calib_write_config_counter(ATCADevice device, uint16_t counter_id, u return status; } + +#if defined(ATCA_ECC204_SUPPORT) +/** \brief Execute write command to write either 16 byte or 32 byte to one of the EEPROM zones + * on the ECC204 device. + * + * \param[in] device Device context pointer + * \param[in] zone Zone/Param1 for the write command. + * \param[in] address Address/Param2 for the write command. + * \param[in] value Plain-text data to be written or cipher-text for + * encrypted writes. 32 or 16 bytes depending on zone. + * \param[in] mac MAC required for encrypted writes (32 bytes). Set to NULL + * if not required. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_ecc204_write(ATCADevice device, uint8_t zone, uint16_t address, const uint8_t *value, + const uint8_t *mac) +{ + ATCA_STATUS status = ATCA_SUCCESS; + ATCAPacket packet; + + if ((NULL == device) && (NULL == value)) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + if (ATCA_SUCCESS == status) + { + packet.param1 = zone; + packet.param2 = address; + + if (ATCA_ECC204_ZONE_CONFIG == zone) + { + memcpy(packet.data, value, 16); + } + else if (ATCA_ECC204_ZONE_DATA == zone) + { + memcpy(packet.data, value, ATCA_BLOCK_SIZE); + } + else + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); + } + + if (ATCA_SUCCESS == status) + { + if (mac && (ATCA_ECC204_ZONE_DATA == zone)) + { + memcpy(&packet.data[ATCA_BLOCK_SIZE], mac, MAC_SIZE); + } + + (void)atWrite(atcab_get_device_type_ext(device), &packet, mac && (ATCA_ECC204_ZONE_DATA == zone)); + } + } + + if (ATCA_SUCCESS == status) + { + if (ATCA_SUCCESS != (status = atca_execute_command(&packet, device))) + { + ATCA_TRACE(status, "calib_ecc204_write - execution failed"); + } + } + + return status; + +} + +/** \brief Execute write command to write data into configuration zone or data zone + * This function only support ECC204 device + * + * \param[in] device Device context pointer + * \param[in] zone Device zone to write (config=1, data=0) + * \param[in] slot the slot number to be witten + * \param[in] block 32-byte block to write + * \param[in] offset ignore for ECC204 device + * \param[in] data Data to be written into slot + * \param[in] len Number of bytes to be written. Must be either 16 or 32. + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_write_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, + uint8_t offset, const uint8_t *data, uint8_t len) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint16_t addr; + + if ((NULL == device) && (NULL == data)) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + else if (((ATCA_ECC204_ZONE_CONFIG == zone) && (16 != len)) || + ((ATCA_ECC204_ZONE_DATA == zone) && (ATCA_BLOCK_SIZE != len))) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid length received"); + } + + if (ATCA_SUCCESS == status) + { + if (ATCA_SUCCESS != (status = calib_ecc204_get_addr(zone, slot, block, 0, &addr))) + { + ATCA_TRACE(status, "calib_ecc204_get_addr - failed"); + } + + if (ATCA_SUCCESS == status) + { + status = calib_ecc204_write(device, zone, addr, data, NULL); + } + } + + return status; +} + +/** \brief Use write command to write configuration data into ECC204 config zone + * + * \param[in] device Device context pointer + * \param[in] config_data configuration data + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, uint8_t* config_data) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t slot = 1; + + if ((NULL == device) || (NULL == config_data)) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + if (ATCA_SUCCESS == status) + { + while (slot <= 3) + { + if (ATCA_SUCCESS != (status = calib_ecc204_write_zone(device, ATCA_ECC204_ZONE_CONFIG, slot, + 0, 0, &config_data[16 * slot], 16))) + { + ATCA_TRACE(status, "calib_ecc204_write_zone - failed"); + } + slot += 1; // Increment slot + } + } + + return status; +} + +/** \brief Executes write command, performs an encrypted write of a 32 byte block into given slot. + * + * \param[in] device Device context pointer + * \param[in] slot key slot to be written + * \param[in] data 32 bytes of clear text data + * \param[in] transport_key Transport key + * \param[in] key_id Transport key id + * \param[in] num_in 20 byte host nonce to inject into Nonce calculation + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +#if defined(ATCA_USE_CONSTANT_HOST_NONCE) +ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint8_t slot, uint8_t* data, uint8_t* transport_key, + uint8_t transport_key_id) +{ + uint8_t num_in[NONCE_NUMIN_SIZE] = { 0 }; + +#else +ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint8_t slot, uint8_t* data, uint8_t* transport_key, + uint8_t transport_key_id, uint8_t num_in[NONCE_NUMIN_SIZE]) +{ +#endif + ATCA_STATUS status = ATCA_SUCCESS; + atca_nonce_in_out_t nonce_params; + atca_write_mac_in_out_t write_mac_param; + atca_temp_key_t temp_key; + atca_session_key_in_out_t session_key_params; + uint8_t rand_out[RANDOM_NUM_SIZE] = { 0 }; + uint8_t serial_number[ATCA_SERIAL_NUM_SIZE] = { 0 }; + uint8_t session_key[ATCA_KEY_SIZE] = { 0 }; + uint8_t cipher_text[ATCA_KEY_SIZE] = { 0 }; + uint8_t mac[WRITE_MAC_SIZE] = { 0 }; + uint16_t addr; + + if ((NULL == data) || (NULL == transport_key)) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encounteed"); + } + + do + { + // Read device serial number + if (ATCA_SUCCESS != (status = calib_ecc204_read_serial_number(device, serial_number))) + { + ATCA_TRACE(status, "Read serial number failed"); + break; + } + + // Generate session key on device + if (ATCA_SUCCESS != (status = calib_nonce_gen_session_key(device, transport_key_id, num_in, rand_out))) + { + ATCA_TRACE(status, "Session key generation failed"); + break; + } + + // Random Nonce inputs + memset(&temp_key, 0, sizeof(temp_key)); + memset(&nonce_params, 0, sizeof(nonce_params)); + nonce_params.mode = NONCE_MODE_SEED_UPDATE; + nonce_params.zero = transport_key_id; + nonce_params.num_in = &num_in[0]; + nonce_params.rand_out = rand_out; + nonce_params.temp_key = &temp_key; + + // Calculate Nonce + if ((status = atcah_nonce(&nonce_params)) != ATCA_SUCCESS) + { + ATCA_TRACE(status, "Calculate nonce failed"); + break; + } + + // Session key inputs + memset(&session_key_params, 0, sizeof(session_key_params)); + session_key_params.transport_key = transport_key; + session_key_params.transport_key_id = transport_key_id; + session_key_params.sn = serial_number; + session_key_params.nonce = temp_key.value; + session_key_params.session_key = session_key; + + // calculate session key on host + if (ATCA_SUCCESS != (status = atcah_gen_session_key(&session_key_params))) + { + ATCA_TRACE(status, "Host session key generation failed"); + break; + } + + if (ATCA_SUCCESS != (status = calib_ecc204_get_addr(ATCA_ECC204_ZONE_DATA, slot, 0, 0, &addr))) + { + ATCA_TRACE(status, "Calculate slot address failed"); + break; + } + + // copy session key into temp variable + memcpy(temp_key.value, session_key, ATCA_KEY_SIZE); + + // Write mac inputs + write_mac_param.zone = ATCA_ECC204_ZONE_DATA; + write_mac_param.key_id = addr; + write_mac_param.sn = serial_number; + write_mac_param.input_data = data; + write_mac_param.encrypted_data = cipher_text; + write_mac_param.auth_mac = mac; + write_mac_param.temp_key = &temp_key; + + // calculate MAC on host + if (ATCA_SUCCESS != (status = atcah_ecc204_write_auth_mac(&write_mac_param))) + { + ATCA_TRACE(status, "Data encryption failed"); + break; + } + + status = calib_ecc204_write(device, write_mac_param.zone, write_mac_param.key_id, write_mac_param.encrypted_data, write_mac_param.auth_mac); + } + while (0); + + return status; +} + +/** \brief Use Write command to write bytes + * + * This function will issue the write command as many times as is required to + * read the requested data. + * + * \param[in] device Device context pointer + * \param[in] zone zone to write data to. Option are + * ATCA_ECC204_ZONE_CONFIG(1), ATCA_ECC204_ZONE_DATA(0) + * \param[in] slot slot number to write to. + * \param[in] block offset bytes ignored + * \param[in] data data to be written + * \param[in] length number of bytes to e written + * + * \return ATCA_SUCCESS on success, otheriwse an error code + */ +ATCA_STATUS calib_ecc204_write_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t block, + const uint8_t *data, size_t length) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t block_size = (zone == ATCA_ECC204_ZONE_CONFIG) ? ATCA_ECC204_CONFIG_SLOT_SIZE : ATCA_BLOCK_SIZE; + uint8_t no_of_blocks; + uint8_t data_idx = 0; + + if ((NULL == device) || (NULL == data)) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "Encountered NULL pointer"); + } + else if ((ATCA_ECC204_ZONE_DATA == zone) && (((length > 64) && (2 == slot)) || + ((length > 320) && (3 == slot)) || (1 == slot) || (0 == slot))) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid parameter received"); + } + else if (0 == length) + { + return ATCA_SUCCESS; + } + + no_of_blocks = length / block_size; + while (no_of_blocks--) + { + if (ATCA_SUCCESS != (status = calib_ecc204_write_zone(device, zone, slot, (uint8_t)block, 0, + &data[block_size * data_idx], + block_size))) + { + ATCA_TRACE(status, "calib_ecc204_write_zone failed"); + break; + } + + block += 1; // Read next block + data_idx += 1; // increment data index + } +} + +#endif \ No newline at end of file diff --git a/lib/crypto/atca_crypto_hw_aes_cbcmac.c b/lib/crypto/atca_crypto_hw_aes_cbcmac.c index a8f472bba..ced6dd818 100644 --- a/lib/crypto/atca_crypto_hw_aes_cbcmac.c +++ b/lib/crypto/atca_crypto_hw_aes_cbcmac.c @@ -91,7 +91,7 @@ ATCA_STATUS atcab_aes_cbcmac_update(atca_aes_cbcmac_ctx_t* ctx, const uint8_t* d { ATCA_STATUS status = ATCA_SUCCESS; size_t i; - uint8_t ciphertext[AES_DATA_SIZE]; + uint8_t ciphertext[ATCA_AES128_BLOCK_SIZE]; if (data_size == 0) { @@ -105,9 +105,9 @@ ATCA_STATUS atcab_aes_cbcmac_update(atca_aes_cbcmac_ctx_t* ctx, const uint8_t* d } // Process full blocks of data with AES-CBC - for (i = 0; i < data_size / AES_DATA_SIZE; i++) + for (i = 0; i < data_size / ATCA_AES128_BLOCK_SIZE; i++) { - status = atcab_aes_cbc_encrypt_block(&ctx->cbc_ctx, &data[i * AES_DATA_SIZE], ciphertext); + status = atcab_aes_cbc_encrypt_block(&ctx->cbc_ctx, &data[i * ATCA_AES128_BLOCK_SIZE], ciphertext); if (status != ATCA_SUCCESS) { return status; @@ -115,10 +115,10 @@ ATCA_STATUS atcab_aes_cbcmac_update(atca_aes_cbcmac_ctx_t* ctx, const uint8_t* d } // Store incomplete block to context structure - if ((i * AES_DATA_SIZE) < data_size) + if ((i * ATCA_AES128_BLOCK_SIZE) < data_size) { - memcpy(ctx->block, &data[i * AES_DATA_SIZE], data_size - i * AES_DATA_SIZE); - ctx->block_size = (uint8_t)(data_size - i * AES_DATA_SIZE); + memcpy(ctx->block, &data[i * ATCA_AES128_BLOCK_SIZE], data_size - i * ATCA_AES128_BLOCK_SIZE); + ctx->block_size = (uint8_t)(data_size - i * ATCA_AES128_BLOCK_SIZE); } else { @@ -140,7 +140,7 @@ ATCA_STATUS atcab_aes_cbcmac_update(atca_aes_cbcmac_ctx_t* ctx, const uint8_t* d */ ATCA_STATUS atcab_aes_cbcmac_finish(atca_aes_cbcmac_ctx_t* ctx, uint8_t* mac, uint32_t mac_size) { - if (ctx == NULL || mac == NULL || mac_size > AES_DATA_SIZE) + if (ctx == NULL || mac == NULL || mac_size > ATCA_AES128_BLOCK_SIZE) { return ATCA_BAD_PARAM; } diff --git a/lib/crypto/atca_crypto_sw.h b/lib/crypto/atca_crypto_sw.h index 29c8f6784..85b098f5b 100644 --- a/lib/crypto/atca_crypto_sw.h +++ b/lib/crypto/atca_crypto_sw.h @@ -88,6 +88,9 @@ typedef atca_evp_ctx atcac_pk_ctx; #include "wolfssl/wolfcrypt/sha.h" #include "wolfssl/wolfcrypt/sha256.h" #include "wolfssl/wolfcrypt/error-crypt.h" +#include "wolfssl/wolfcrypt/asn_public.h" +#include "wolfssl/wolfcrypt/asn.h" +#include "wolfssl/wolfcrypt/ecc.h" typedef struct { @@ -95,10 +98,17 @@ typedef struct uint8_t iv[AES_BLOCK_SIZE]; uint16_t iv_len; } atcac_aes_gcm_ctx; + +typedef struct +{ + void* ptr; +} atca_wc_ctx; + typedef wc_Sha atcac_sha1_ctx; typedef wc_Sha256 atcac_sha2_256_ctx; typedef Cmac atcac_aes_cmac_ctx; typedef Hmac atcac_hmac_sha256_ctx; +typedef atca_wc_ctx atcac_pk_ctx; #else #ifndef ATCA_ENABLE_SHA1_IMPL @@ -135,9 +145,7 @@ ATCA_STATUS atcac_aes_gcm_decrypt_start(atcac_aes_gcm_ctx* ctx, const uint8_t* k ATCA_STATUS atcac_aes_cmac_init(atcac_aes_cmac_ctx* ctx, const uint8_t* key, const uint8_t key_len); ATCA_STATUS atcac_aes_cmac_update(atcac_aes_cmac_ctx* ctx, const uint8_t* data, const size_t data_size); ATCA_STATUS atcac_aes_cmac_finish(atcac_aes_cmac_ctx* ctx, uint8_t* cmac, size_t* cmac_size); -#endif -#ifdef ATCA_MBEDTLS ATCA_STATUS atcac_pk_init(atcac_pk_ctx* ctx, uint8_t* buf, size_t buflen, uint8_t key_type, bool pubkey); ATCA_STATUS atcac_pk_init_pem(atcac_pk_ctx* ctx, uint8_t* buf, size_t buflen, bool pubkey); ATCA_STATUS atcac_pk_free(atcac_pk_ctx* ctx); diff --git a/lib/cryptoauthlib.h b/lib/cryptoauthlib.h index b7eef0345..0839afdfc 100644 --- a/lib/cryptoauthlib.h +++ b/lib/cryptoauthlib.h @@ -57,7 +57,7 @@ #endif /* Classic Cryptoauth Devices */ -#if defined(ATCA_SHA_SUPPORT) || defined(ATCA_ECC_SUPPORT) +#if defined(ATCA_SHA_SUPPORT) || defined(ATCA_ECC_SUPPORT) || defined(ATCA_ECC204_SUPPORT) #define ATCA_CA_SUPPORT 1 #else #define ATCA_CA_SUPPORT 0 @@ -91,6 +91,11 @@ #define ATCA_ZONE_OTP ((uint8_t)0x01) #define ATCA_ZONE_DATA ((uint8_t)0x02) +#if defined(ATCA_ECC204_SUPPORT) +#define ATCA_ECC204_ZONE_DATA ((uint8_t)0x00) +#define ATCA_ECC204_ZONE_CONFIG ((uint8_t)0x01) +#endif + /** Place resulting digest both in Output buffer and TempKey */ #define SHA_MODE_TARGET_TEMPKEY ((uint8_t)0x00) /** Place resulting digest both in Output buffer and Message Digest Buffer */ diff --git a/lib/hal/README.md b/lib/hal/README.md index 882649b67..1a3715bb5 100644 --- a/lib/hal/README.md +++ b/lib/hal/README.md @@ -8,18 +8,54 @@ specific hardware platforms. **Include just those HAL files you require based on platform type.** -CryptoAuthLib Supported HAL Layers +Cryptoauthlib HAL Architecture ============================================= -HAL Layers files are combined into groups. Initial group is generic files that are typically included in a project. -Files are then broken out by uController Family and or Operating System Interface. +Cryptoauthlib has several intermediate conceptual layers +1. The highest layer of cryptoauthlib (outside of integration APIS) that may be used with an application is the atcab_ + api functions. These are general purpose functions that present a simple and consistent crypto interface to the application + regardless of the device being used. -| Protocol Files | Interface | Files | API | Notes | -|----------------|------------|------------------------------|-------------|------------------------------------| -|atca | | atca_hal.c/h | | For all projects | -|kit protocol | | kit_protocol.c/h | | For all Kit Protocol projects | -| | | kit_phy.h | | | +2. calib_, talib_ APIs are the library functions behind atcab_ ones that generate the correct command packets and process the + received responses. Device specific logic is handled by the library here + +3. hal_ these functions perform the transmit/recieve of data for a given interface. These are split into sublayers + * The HAL layer is the first hal layer that presents the interface expected by the higher level library. When using a native + driver and no further interpretation is required this layer is all that is required. + * The PHY layer if for hals that perform an interpretation or additional protocol logic. In this situation the HAL performs + protocol interpretation while the phy performs the physical communication + + +### HAL and PHY Requirements + +The hal and phy layers have the same construction. A hal or phy must have the following functions and their signatures + +* ATCA_STATUS hal__init(ATCAIface iface, ATCAIfaceCfg *cfg); +* ATCA_STATUS hal__post_init(ATCAIface iface); +* ATCA_STATUS hal__send(ATCAIface iface, uint8_t address, uint8_t *txdata, int txlength); +* ATCA_STATUS hal__receive(ATCAIface iface, uint8_t address, uint8_t *rxdata, uint16_t *rxlength); +* ATCA_STATUS hal__control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); +* ATCA_STATUS hal__release(void *hal_data); + +If the hal is a native driver no phy is required. See the tables below for which hal is required to be ported based on a configured +interface + + +CryptoAuthLib Supported HAL Layers +============================================= + + +| Device Interface | Physical Interface | HAL | PHY | +|-------------------|----------------------|----------------|-----------| +| i2c | i2c | hal_i2c | | +| | gpio | hal_i2c_gpio | hal_gpio | +| spi | spi | hal_spi | | +| swi | uart | hal_swi | hal_uart | +| | gpio | hal_swi_gpio | hal_gpio | +| any | uart | kit | hal_uart | +| | hid | kit | hal_hid | +| | any (user provided) | kit_bridge | | Microchip Harmony 3 for all PIC32 & ARM products - Use the Harmony 3 Configurator to generate and configure prjects @@ -30,6 +66,7 @@ Obtain library and configure using [Harmony 3](https://github.com/Microchip-MPLA |------------|------------------------------|-------------|-------------------------------------------------| | I2C | hal_i2c_harmony.c | plib.h | For all Harmony 3 based projects | | SPI | hal_spi_harmony.c | plib.h | | +| UART | hal_uart_harmony.c | plib.h | } Microchip 8 & 16 bit products - AVR, PIC16/18, PIC24/DSPIC -------------------------------------------- diff --git a/lib/hal/atca_hal.c b/lib/hal/atca_hal.c index 2fa18d06e..a0e063ec9 100644 --- a/lib/hal/atca_hal.c +++ b/lib/hal/atca_hal.c @@ -35,93 +35,97 @@ #include "cryptoauthlib.h" #include "atca_hal.h" +#ifndef ATCA_MAX_HAL_CACHE +#define ATCA_MAX_HAL_CACHE +#endif + #ifdef ATCA_HAL_I2C static ATCAHAL_t hal_i2c = { hal_i2c_init, hal_i2c_post_init, hal_i2c_send, hal_i2c_receive, - hal_i2c_wake, - hal_i2c_idle, - hal_i2c_sleep, + hal_i2c_control, hal_i2c_release }; #endif -#ifdef ATCA_HAL_SWI -static ATCAHAL_t hal_swi = { +#ifdef ATCA_HAL_SWI_UART +static ATCAHAL_t hal_swi_uart = { hal_swi_init, hal_swi_post_init, hal_swi_send, hal_swi_receive, - hal_swi_wake, - hal_swi_idle, - hal_swi_sleep, + hal_swi_control, hal_swi_release }; #endif -#if defined(ATCA_HAL_UART) && !defined(ATCA_HAL_KIT_CDC) +#ifdef ATCA_HAL_UART static ATCAHAL_t hal_uart = { hal_uart_init, hal_uart_post_init, hal_uart_send, hal_uart_receive, - hal_uart_wake, - hal_uart_idle, - hal_uart_sleep, + hal_uart_control, hal_uart_release }; #endif -#if !defined(ATCA_HAL_UART) && defined(ATCA_HAL_KIT_CDC) -static ATCAHAL_t hal_uart = { - hal_kit_cdc_init, - hal_kit_cdc_post_init, - hal_kit_cdc_send, - hal_kit_cdc_receive, - hal_kit_cdc_wake, - hal_kit_cdc_idle, - hal_kit_cdc_sleep, - hal_kit_cdc_release -}; -#endif - #ifdef ATCA_HAL_SPI static ATCAHAL_t hal_spi = { hal_spi_init, hal_spi_post_init, hal_spi_send, hal_spi_receive, - hal_spi_wake, - hal_spi_idle, - hal_spi_sleep, + hal_spi_control, hal_spi_release }; #endif +#ifdef ATCA_HAL_GPIO +static ATCAHAL_t hal_gpio = { + hal_gpio_init, + hal_gpio_post_init, + hal_gpio_send, + hal_gpio_receive, + hal_gpio_wake, + hal_gpio_idle, + hal_gpio_sleep, + hal_gpio_release +}; +#endif + #ifdef ATCA_HAL_KIT_HID static ATCAHAL_t hal_hid = { hal_kit_hid_init, hal_kit_hid_post_init, hal_kit_hid_send, hal_kit_hid_receive, - hal_kit_hid_wake, - hal_kit_hid_idle, - hal_kit_hid_sleep, + hal_kit_hid_control, hal_kit_hid_release }; #endif +#if defined(ATCA_HAL_KIT_HID) || defined(ATCA_HAL_KIT_UART) +#include "kit_protocol.h" +static ATCAHAL_t hal_kit_v1 = { + kit_init, + kit_post_init, + kit_send, + kit_receive, + kit_control, + kit_release +}; +#endif + #ifdef ATCA_HAL_KIT_BRIDGE static ATCAHAL_t hal_kit_bridge = { hal_kit_init, hal_kit_post_init, hal_kit_send, hal_kit_receive, - hal_kit_wake, - hal_kit_idle, - hal_kit_sleep, + hal_kit_control, hal_kit_release }; #endif @@ -130,57 +134,73 @@ static ATCAHAL_t hal_kit_bridge = { static ATCAHAL_t hal_custom; #endif -static ATCAHAL_t * atca_registered_hal_list[ATCA_UNKNOWN_IFACE] = { +/** \brief Structure that holds the hal/phy maping for different interface types + */ +typedef struct +{ + uint8_t iface_type; /**< */ + ATCAHAL_t* hal; /**< */ + ATCAHAL_t* phy; /**< Physical interface for the specific HAL*/ +} atca_hal_list_entry_t; + + +static atca_hal_list_entry_t atca_registered_hal_list[ATCA_MAX_HAL_CACHE] = { #ifdef ATCA_HAL_I2C - &hal_i2c, -#else - NULL, + { ATCA_I2C_IFACE, &hal_i2c, NULL }, #endif #ifdef ATCA_HAL_SWI - &hal_swi, -#else - NULL, + { ATCA_SWI_IFACE, &hal_swi_uart, &hal_uart }, #endif -#if defined(ATCA_HAL_UART) || defined(ATCA_HAL_KIT_CDC) - &hal_uart, -#else - NULL, +#ifdef ATCA_HAL_KIT_UART + { ATCA_UART_IFACE, &hal_kit_v1, &hal_uart }, #endif #ifdef ATCA_HAL_SPI - &hal_spi, -#else - NULL, + { ATCA_SPI_IFACE, &hal_spi, NULL }, #endif #ifdef ATCA_HAL_KIT_HID - &hal_hid, -#else - NULL, + { ATCA_HID_IFACE, &hal_kit_v1, &hal_hid }, #endif #ifdef ATCA_HAL_KIT_BRIDGE - &hal_kit_bridge, -#else - NULL, + { ATCA_KIT_IFACE, &hal_kit_bridge, NULL }, #endif -#ifdef ATCA_HAL_CUSTOM - &hal_custom, -#else - NULL +#if ATCA_HAL_SWI_GPIO + { ATCA_SWI_GPIO_IFACE, &hal_gpio, NULL }, #endif }; +static const size_t atca_registered_hal_list_size = sizeof(atca_registered_hal_list) / sizeof(atca_hal_list_entry_t); + + /** \brief Internal function to get a value from the hal cache * \param[in] iface_type - the type of physical interface to register * \param[out] hal pointer to the existing ATCAHAL_t structure * \return ATCA_SUCCESS on success, otherwise an error code. */ -static ATCA_STATUS hal_iface_get_registered(ATCAIfaceType iface_type, ATCAHAL_t** hal) +static ATCA_STATUS hal_iface_get_registered(ATCAIfaceType iface_type, ATCAHAL_t** hal, ATCAHAL_t **phy) { ATCA_STATUS status = ATCA_BAD_PARAM; - if ((ATCA_UNKNOWN_IFACE > iface_type) && hal) + if (hal && phy) { - *hal = atca_registered_hal_list[iface_type]; - status = ATCA_SUCCESS; + int i; + for (i = 0; i < atca_registered_hal_list_size; i++) + { + if (iface_type == atca_registered_hal_list[i].iface_type) + { + break; + } + } + + if (i < atca_registered_hal_list_size) + { + *hal = atca_registered_hal_list[i].hal; + *phy = atca_registered_hal_list[i].phy; + status = ATCA_SUCCESS; + } + else + { + status = ATCA_GEN_FAIL; + } } return status; @@ -191,14 +211,46 @@ static ATCA_STATUS hal_iface_get_registered(ATCAIfaceType iface_type, ATCAHAL_t* * \param[in] hal pointer to the existing ATCAHAL_t structure * \return ATCA_SUCCESS on success, otherwise an error code. */ -static ATCA_STATUS hal_iface_set_registered(ATCAIfaceType iface_type, ATCAHAL_t* hal) +static ATCA_STATUS hal_iface_set_registered(ATCAIfaceType iface_type, ATCAHAL_t* hal, ATCAHAL_t* phy) { ATCA_STATUS status = ATCA_BAD_PARAM; - if ((ATCA_UNKNOWN_IFACE > iface_type) && hal) + if (hal) { - atca_registered_hal_list[iface_type] = hal; - status = ATCA_SUCCESS; + int i; + int empty = atca_registered_hal_list_size; + for (i = 0; i < atca_registered_hal_list_size; i++) + { + if (iface_type == atca_registered_hal_list[i].iface_type) + { + break; + } + else if (empty == atca_registered_hal_list_size) + { + if (!atca_registered_hal_list[i].hal && !atca_registered_hal_list[i].phy) + { + empty = i; + } + } + } + + if (i < atca_registered_hal_list_size) + { + atca_registered_hal_list[i].hal = hal; + atca_registered_hal_list[i].phy = phy; + status = ATCA_SUCCESS; + } + else if (empty < atca_registered_hal_list_size) + { + atca_registered_hal_list[empty].hal = hal; + atca_registered_hal_list[empty].hal = phy; + status = ATCA_SUCCESS; + } + else + { + status = ATCA_ALLOC_FAILURE; + } + } return status; @@ -210,15 +262,15 @@ static ATCA_STATUS hal_iface_set_registered(ATCAIfaceType iface_type, ATCAHAL_t* * \param[out] old pointer to the existing ATCAHAL_t structure * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_iface_register_hal(ATCAIfaceType iface_type, ATCAHAL_t *hal, ATCAHAL_t **old) +ATCA_STATUS hal_iface_register_hal(ATCAIfaceType iface_type, ATCAHAL_t *hal, ATCAHAL_t **old_hal, ATCAHAL_t* phy, ATCAHAL_t** old_phy) { ATCA_STATUS status; - status = old ? hal_iface_get_registered(iface_type, old) : ATCA_SUCCESS; + status = (old_hal && old_phy) ? hal_iface_get_registered(iface_type, old_hal, old_phy) : ATCA_SUCCESS; if (ATCA_SUCCESS == status) { - status = hal_iface_set_registered(iface_type, hal); + status = hal_iface_set_registered(iface_type, hal, phy); } return ATCA_SUCCESS; @@ -229,26 +281,32 @@ ATCA_STATUS hal_iface_register_hal(ATCAIfaceType iface_type, ATCAHAL_t *hal, ATC * \param[in] hal pointer to ATCAHAL_t intermediate data structure * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_iface_init(ATCAIfaceCfg *cfg, ATCAHAL_t **hal) +ATCA_STATUS hal_iface_init(ATCAIfaceCfg *cfg, ATCAHAL_t **hal, ATCAHAL_t **phy) { ATCA_STATUS status = ATCA_BAD_PARAM; if (cfg && hal) { - status = hal_iface_get_registered(cfg->iface_type, hal); + status = hal_iface_get_registered(cfg->iface_type, hal, phy); #ifdef ATCA_HAL_CUSTOM if (ATCA_CUSTOM_IFACE == cfg->iface_type) { - (*hal)->halinit = cfg->atcacustom.halinit; - (*hal)->halpostinit = cfg->atcacustom.halpostinit; - (*hal)->halreceive = cfg->atcacustom.halreceive; - (*hal)->halsend = cfg->atcacustom.halsend; - (*hal)->halsleep = cfg->atcacustom.halsleep; - (*hal)->halwake = cfg->atcacustom.halwake; - (*hal)->halidle = cfg->atcacustom.halidle; - (*hal)->halrelease = cfg->atcacustom.halrelease; - (*hal)->hal_data = NULL; + *hal = hal_malloc(sizeof(ATCAHAL_t)); + if (*hal) + { + (*hal)->halinit = cfg->atcacustom.halinit; + (*hal)->halpostinit = cfg->atcacustom.halpostinit; + (*hal)->halreceive = cfg->atcacustom.halreceive; + (*hal)->halsend = cfg->atcacustom.halsend; + (*hal)->halcontrol = hal_custom_control; + (*hal)->halrelease = cfg->atcacustom.halrelease; + status = ATCA_SUCCESS; + } + else + { + status = ATCA_ALLOC_FAILURE; + } } #endif } @@ -266,8 +324,9 @@ ATCA_STATUS hal_iface_release(ATCAIfaceType iface_type, void *hal_data) { ATCA_STATUS status; ATCAHAL_t * hal; + ATCAHAL_t* phy; - status = hal_iface_get_registered(iface_type, &hal); + status = hal_iface_get_registered(iface_type, &hal, &phy); if (ATCA_SUCCESS == status) { @@ -303,6 +362,16 @@ ATCA_STATUS hal_check_wake(const uint8_t* response, int response_size) return ATCA_WAKE_FAILED; } +/** \brief Utility function for hal_wake to check the reply. + * \param[in] word_address Command to check + * \return true if the word_address is considered a command + */ +uint8_t hal_is_command_word(uint8_t word_address) +{ + return 0xFF == word_address || 0x03 == word_address || 0x10 == word_address; +} + + #if !defined(ATCA_NO_HEAP) && defined(ATCA_TESTS_ENABLED) && defined(ATCA_PLATFORM_MALLOC) void* (*g_hal_malloc_f)(size_t) = ATCA_PLATFORM_MALLOC; @@ -325,3 +394,131 @@ void hal_test_set_memory_f(void* (*malloc_func)(size_t), void (*free_func)(void* } #endif + +#if defined(ATCA_HAL_LEGACY_API) && defined(ATCA_HAL_I2C) +ATCA_STATUS hal_i2c_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) +{ + (void)param; + (void)paramlen; + + switch (option) + { + case ATCA_HAL_CONTROL_WAKE: + return hal_i2c_wake(iface); + case ATCA_HAL_CONTROL_IDLE: + return hal_i2c_idle(iface); + case ATCA_HAL_CONTROL_SLEEP: + return hal_i2c_sleep(iface); + case ATCA_HAL_CONTROL_SELECT: + /* fallthrough */ + case ATCA_HAL_CONTROL_DESELECT: + return ATCA_SUCCESS; + default: + return ATCA_BAD_PARAM; + } +} +#endif + +#if defined(ATCA_HAL_LEGACY_API) && defined(ATCA_HAL_SWI) +ATCA_STATUS hal_swi_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) +{ + (void)param; + (void)paramlen; + + switch (option) + { + case ATCA_HAL_CONTROL_WAKE: + return hal_swi_wake(iface); + case ATCA_HAL_CONTROL_IDLE: + return hal_swi_idle(iface); + case ATCA_HAL_CONTROL_SLEEP: + return hal_swi_sleep(iface); + case ATCA_HAL_CONTROL_SELECT: + /* fallthrough */ + case ATCA_HAL_CONTROL_DESELECT: + return ATCA_SUCCESS; + default: + return ATCA_BAD_PARAM; + } +} +#endif + +#if defined(ATCA_HAL_LEGACY_API) && defined(ATCA_HAL_UART) +ATCA_STATUS hal_uart_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) +{ + (void)param; + (void)paramlen; + + switch (option) + { + case ATCA_HAL_CONTROL_WAKE: + return hal_uart_wake(iface); + case ATCA_HAL_CONTROL_IDLE: + return hal_uart_idle(iface); + case ATCA_HAL_CONTROL_SLEEP: + return hal_uart_sleep(iface); + case ATCA_HAL_CONTROL_SELECT: + /* fallthrough */ + case ATCA_HAL_CONTROL_DESELECT: + return ATCA_SUCCESS; + default: + return ATCA_BAD_PARAM; + } +} +#endif + +#if defined(ATCA_HAL_LEGACY_API) && defined(ATCA_HAL_SPI) +ATCA_STATUS hal_spi_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) +{ + (void)param; + (void)paramlen; + + if (iface) + { + switch (option) + { + case ATCA_HAL_CONTROL_WAKE: + return hal_spi_wake(iface); + case ATCA_HAL_CONTROL_IDLE: + return hal_spi_idle(iface); + case ATCA_HAL_CONTROL_SLEEP: + return hal_spi_sleep(iface); + case ATCA_HAL_CONTROL_SELECT: + /* fallthrough */ + case ATCA_HAL_CONTROL_DESELECT: + return ATCA_SUCCESS; + default: + break; + } + } + return ATCA_BAD_PARAM; +} +#endif + +#if defined(ATCA_HAL_CUSTOM) +ATCA_STATUS hal_custom_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) +{ + (void)param; + (void)paramlen; + + if (iface && iface->mIfaceCFG) + { + switch (option) + { + case ATCA_HAL_CONTROL_WAKE: + return iface->mIfaceCFG->atcacustom.halwake(iface); + case ATCA_HAL_CONTROL_IDLE: + return iface->mIfaceCFG->atcacustom.halidle(iface); + case ATCA_HAL_CONTROL_SLEEP: + return iface->mIfaceCFG->atcacustom.halsleep(iface); + case ATCA_HAL_CONTROL_SELECT: + /* fallthrough */ + case ATCA_HAL_CONTROL_DESELECT: + return ATCA_SUCCESS; + default: + break; + } + } + return ATCA_BAD_PARAM; +} +#endif diff --git a/lib/hal/atca_hal.h b/lib/hal/atca_hal.h index 53abd7ee0..50175592b 100644 --- a/lib/hal/atca_hal.h +++ b/lib/hal/atca_hal.h @@ -38,6 +38,7 @@ #include "atca_start_config.h" #include "atca_start_iface.h" + /** \defgroup hal_ Hardware abstraction layer (hal_) * * \brief @@ -45,28 +46,6 @@ * @{ */ -/** \brief an intermediary data structure to allow the HAL layer to point the standard API functions - used by the upper layers to the HAL implementation for the interface. This isolates the upper layers - and loosely couples the ATCAIface object from the physical implementation. - */ - -typedef struct -{ - // interface is a group of function pointers to a specific HAL implementation for this interface type - // so these function pointers are initialized in the HAL layer in order to help keep the ATCAIface object - // from needing to know the low-level details, including global naming of HAL methods and physical implementation. - ATCA_STATUS (*halinit)(void *hal, ATCAIfaceCfg *cfg); - ATCA_STATUS (*halpostinit)(ATCAIface iface); - ATCA_STATUS (*halsend)(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength); - ATCA_STATUS (*halreceive)(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxlength); - ATCA_STATUS (*halwake)(ATCAIface iface); - ATCA_STATUS (*halidle)(ATCAIface iface); - ATCA_STATUS (*halsleep)(ATCAIface iface); - ATCA_STATUS (*halrelease)(void* hal_data); - - void *hal_data; // points to whatever the HAL implementation for this interface wants it to, HAL manages. -} ATCAHAL_t; - typedef struct { ATCA_STATUS (*send)(void* ctx, uint8_t* txdata, uint16_t txlen); /**< Must be a blocking send */ @@ -80,100 +59,100 @@ typedef struct extern "C" { #endif -extern ATCA_STATUS hal_iface_init(ATCAIfaceCfg *, ATCAHAL_t** hal); -extern ATCA_STATUS hal_iface_release(ATCAIfaceType, void* hal_data); +ATCA_STATUS hal_iface_init(ATCAIfaceCfg *, ATCAHAL_t** hal, ATCAHAL_t** phy); +ATCA_STATUS hal_iface_release(ATCAIfaceType, void* hal_data); ATCA_STATUS hal_check_wake(const uint8_t* response, int response_size); #ifdef ATCA_HAL_I2C -ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_i2c_init(ATCAIface iface, ATCAIfaceCfg *cfg); ATCA_STATUS hal_i2c_post_init(ATCAIface iface); ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength); ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_i2c_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); +#ifdef ATCA_LEGACY_HAL ATCA_STATUS hal_i2c_wake(ATCAIface iface); ATCA_STATUS hal_i2c_idle(ATCAIface iface); ATCA_STATUS hal_i2c_sleep(ATCAIface iface); +#endif ATCA_STATUS hal_i2c_release(void *hal_data); -ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses); -ATCA_STATUS hal_i2c_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); #endif #ifdef ATCA_HAL_SWI -ATCA_STATUS hal_swi_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_swi_init(ATCAIface iface, ATCAIfaceCfg *cfg); ATCA_STATUS hal_swi_post_init(ATCAIface iface); ATCA_STATUS hal_swi_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength); ATCA_STATUS hal_swi_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_swi_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); +#ifdef ATCA_LEGACY_HAL ATCA_STATUS hal_swi_wake(ATCAIface iface); ATCA_STATUS hal_swi_idle(ATCAIface iface); ATCA_STATUS hal_swi_sleep(ATCAIface iface); +#endif ATCA_STATUS hal_swi_release(void *hal_data); -ATCA_STATUS hal_swi_discover_buses(int swi_buses[], int max_buses); -ATCA_STATUS hal_swi_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); +#endif + + +#if defined(ATCA_HAL_1WIRE) || defined(ATCA_HAL_SWI) +ATCA_STATUS hal_gpio_init(void *hal, ATCAIfaceCfg* cfg); +ATCA_STATUS hal_gpio_post_init(ATCAIface iface); +ATCA_STATUS hal_gpio_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int txlength); +ATCA_STATUS hal_gpio_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxlength); +ATCA_STATUS hal_gpio_idle(ATCAIface iface); +ATCA_STATUS hal_gpio_sleep(ATCAIface iface); +ATCA_STATUS hal_gpio_wake(ATCAIface iface); +ATCA_STATUS hal_gpio_release(void *hal_data); +ATCA_STATUS hal_gpio_device_discovery(ATCAIface iface); #endif #ifdef ATCA_HAL_UART -ATCA_STATUS hal_uart_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_uart_init(ATCAIface iface, ATCAIfaceCfg *cfg); ATCA_STATUS hal_uart_post_init(ATCAIface iface); ATCA_STATUS hal_uart_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength); ATCA_STATUS hal_uart_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_uart_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); +#ifdef ATCA_LEGACY_HAL ATCA_STATUS hal_uart_wake(ATCAIface iface); ATCA_STATUS hal_uart_idle(ATCAIface iface); ATCA_STATUS hal_uart_sleep(ATCAIface iface); +#endif ATCA_STATUS hal_uart_release(ATCAIface iface); -ATCA_STATUS hal_uart_discover_buses(int uart_buses[], int max_buses); -ATCA_STATUS hal_uart_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); #endif #ifdef ATCA_HAL_SPI -ATCA_STATUS hal_spi_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_spi_init(ATCAIface iface, ATCAIfaceCfg *cfg); ATCA_STATUS hal_spi_post_init(ATCAIface iface); ATCA_STATUS hal_spi_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength); ATCA_STATUS hal_spi_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength); +ATCA_STATUS hal_spi_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); +#ifdef ATCA_LEGACY_HAL ATCA_STATUS hal_spi_wake(ATCAIface iface); ATCA_STATUS hal_spi_idle(ATCAIface iface); ATCA_STATUS hal_spi_sleep(ATCAIface iface); -ATCA_STATUS hal_spi_release(void *hal_data); -ATCA_STATUS hal_spi_discover_buses(int spi_buses[], int max_buses); -ATCA_STATUS hal_spi_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); #endif - -#ifdef ATCA_HAL_KIT_CDC -ATCA_STATUS hal_kit_cdc_init(void *hal, ATCAIfaceCfg *cfg); -ATCA_STATUS hal_kit_cdc_post_init(ATCAIface iface); -ATCA_STATUS hal_kit_cdc_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength); -ATCA_STATUS hal_kit_cdc_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength); -ATCA_STATUS hal_kit_cdc_wake(ATCAIface iface); -ATCA_STATUS hal_kit_cdc_idle(ATCAIface iface); -ATCA_STATUS hal_kit_cdc_sleep(ATCAIface iface); -ATCA_STATUS hal_kit_cdc_release(void *hal_data); -ATCA_STATUS hal_kit_cdc_discover_buses(int cdc_buses[], int max_buses); -ATCA_STATUS hal_kit_cdc_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); +ATCA_STATUS hal_spi_release(void *hal_data); #endif #ifdef ATCA_HAL_KIT_HID -ATCA_STATUS hal_kit_hid_init(void *hal, ATCAIfaceCfg *cfg); +ATCA_STATUS hal_kit_hid_init(ATCAIface iface, ATCAIfaceCfg *cfg); ATCA_STATUS hal_kit_hid_post_init(ATCAIface iface); ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength); ATCA_STATUS hal_kit_hid_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength); -ATCA_STATUS hal_kit_hid_wake(ATCAIface iface); -ATCA_STATUS hal_kit_hid_idle(ATCAIface iface); -ATCA_STATUS hal_kit_hid_sleep(ATCAIface iface); +ATCA_STATUS hal_kit_hid_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); ATCA_STATUS hal_kit_hid_release(void *hal_data); -ATCA_STATUS hal_kit_hid_discover_buses(int hid_buses[], int max_buses); -ATCA_STATUS hal_kit_hid_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found); #endif #ifdef ATCA_HAL_KIT_BRIDGE -ATCA_STATUS hal_kit_init(void* hal, ATCAIfaceCfg* cfg); +ATCA_STATUS hal_kit_init(ATCAIface iface, ATCAIfaceCfg* cfg); ATCA_STATUS hal_kit_post_init(ATCAIface iface); ATCA_STATUS hal_kit_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int txlength); ATCA_STATUS hal_kit_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxlength); -ATCA_STATUS hal_kit_wake(ATCAIface iface); -ATCA_STATUS hal_kit_idle(ATCAIface iface); -ATCA_STATUS hal_kit_sleep(ATCAIface iface); +ATCA_STATUS hal_kit_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); ATCA_STATUS hal_kit_release(void* hal_data); -ATCA_STATUS hal_kit_discover_buses(int hid_buses[], int max_buses); -ATCA_STATUS hal_kit_discover_devices(int bus_num, ATCAIfaceCfg* cfg, int* found); +#endif + +#ifdef ATCA_HAL_CUSTOM +ATCA_STATUS hal_custom_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); #endif /* Polling defaults if not overwritten by the configuration */ @@ -189,6 +168,18 @@ ATCA_STATUS hal_kit_discover_devices(int bus_num, ATCAIfaceCfg* cfg, int* found) #define ATCA_POLLING_MAX_TIME_MSEC 2500 #endif +/* */ +typedef enum +{ + ATCA_HAL_CONTROL_WAKE = 0, + ATCA_HAL_CONTROL_IDLE = 1, + ATCA_HAL_CONTROL_SLEEP = 2, + ATCA_HAL_CONTROL_RESET = 3, + ATCA_HAL_CONTROL_SELECT = 4, + ATCA_HAL_CONTROL_DESELECT = 5, + ATCA_HAL_CHANGE_BAUD = 6 +} ATCA_HAL_CONTROL; + /** \brief Timer API for legacy implementations */ #ifndef atca_delay_ms void atca_delay_ms(uint32_t ms); @@ -230,7 +221,8 @@ void hal_free(void* ptr); #endif -ATCA_STATUS hal_iface_register_hal(ATCAIfaceType iface_type, ATCAHAL_t *hal, ATCAHAL_t **old); +ATCA_STATUS hal_iface_register_hal(ATCAIfaceType iface_type, ATCAHAL_t *hal, ATCAHAL_t **old_hal, ATCAHAL_t* phy, ATCAHAL_t** old_phy); +uint8_t hal_is_command_word(uint8_t word_address); #ifdef __cplusplus } diff --git a/lib/hal/hal_all_platforms_kit_hidapi.c b/lib/hal/hal_all_platforms_kit_hidapi.c index 931853712..5de4fa2b7 100644 --- a/lib/hal/hal_all_platforms_kit_hidapi.c +++ b/lib/hal/hal_all_platforms_kit_hidapi.c @@ -42,42 +42,18 @@ #define HID_PACKET_MAX 512 //! Maximum number of bytes for a HID send/receive packet (typically 64) -/** \brief discover cdc buses available for this hardware - * this maintains a list of logical to physical bus mappings freeing the application - * of the a-priori knowledge - * \param[in] hid_buses - an array of logical bus numbers - * \param[in] max_buses - maximum number of buses the app wants to attempt to discover - */ - -ATCA_STATUS hal_kit_hid_discover_buses(int hid_buses[], int max_buses) -{ - return ATCA_UNIMPLEMENTED; -} - -/** \brief discover any CryptoAuth devices on a given logical bus number - * \param[in] bus_num - logical bus number on which to look for CryptoAuth devices - * \param[out] cfg[] - pointer to head of an array of interface config structures which get filled in by this method - * \param[out] *found - number of devices found on this bus - */ -ATCA_STATUS hal_kit_hid_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found) -{ - return ATCA_UNIMPLEMENTED; -} - /** \brief HAL implementation of Kit USB HID init * \param[in] hal pointer to HAL specific data that is maintained by this HAL * \param[in] cfg pointer to HAL specific configuration data that is used to initialize this HAL * \return ATCA_STATUS */ -ATCA_STATUS hal_kit_hid_init(void* hal, ATCAIfaceCfg* cfg) +ATCA_STATUS hal_kit_hid_init(ATCAIface iface, ATCAIfaceCfg* cfg) { - ATCAHAL_t *phal = (ATCAHAL_t*)hal; - int i = 0; int index = 0; // Check the input variables - if ((cfg == NULL) || (phal == NULL)) + if ((cfg == NULL) || (iface == NULL)) { return ATCA_BAD_PARAM; } @@ -88,9 +64,9 @@ ATCA_STATUS hal_kit_hid_init(void* hal, ATCAIfaceCfg* cfg) #endif hid_init(); - phal->hal_data = hid_open(cfg->atcahid.vid, cfg->atcahid.pid, NULL); + iface->hal_data = hid_open(cfg->atcahid.vid, cfg->atcahid.pid, NULL); - return (phal->hal_data) ? ATCA_SUCCESS : ATCA_COMM_FAIL; + return (iface->hal_data) ? ATCA_SUCCESS : ATCA_COMM_FAIL; } /** \brief HAL implementation of Kit HID post init @@ -99,36 +75,17 @@ ATCA_STATUS hal_kit_hid_init(void* hal, ATCAIfaceCfg* cfg) */ ATCA_STATUS hal_kit_hid_post_init(ATCAIface iface) { - ATCA_STATUS status = ATCA_SUCCESS; - - hid_device* pHid = (hid_device*)atgetifacehaldat(iface); - ATCAIfaceCfg *pCfg = atgetifacecfg(iface); - int i = 0; - - if ((pHid == NULL) || (pCfg == NULL)) - { - return ATCA_BAD_PARAM; - } - - status = kit_init(iface); - if (status != ATCA_SUCCESS) -#ifdef KIT_DEBUG - { printf("kit_init() Failed"); } -#endif - { - ATCA_TRACE(status, "kit_init() failed"); - } - - return status; + return ATCA_SUCCESS; } -/** \brief HAL implementation of send over USB HID - * \param[in] iface instance - * \param[in] txdata pointer to bytes to send - * \param[in] txlength number of bytes to send +/** \brief HAL implementation of kit protocol send over USB HID + * \param[in] iface instance + * \param[in] word_address determine device transaction type + * \param[in] txdata pointer to bytes to send + * \param[in] txlength number of bytes to send * \return ATCA_STATUS */ -ATCA_STATUS kit_phy_send(ATCAIface iface, uint8_t* txdata, int txlength) +ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int txlength) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); hid_device* pHid = (hid_device*)atgetifacehaldat(iface); @@ -175,13 +132,14 @@ ATCA_STATUS kit_phy_send(ATCAIface iface, uint8_t* txdata, int txlength) return ATCA_SUCCESS; } -/** \brief HAL implementation of kit protocol send over USB HID - * \param[in] iface instance - * \param[out] rxdata pointer to space to receive the data - * \param[in,out] rxsize ptr to expected number of receive bytes to request +/** \brief HAL implementation of send over USB HID + * \param[in] iface instance + * \param[in] word_address determine device transaction type + * \param[in] rxdata pointer to space to receive the data + * \param[in,out] rxsize ptr to expected number of receive bytes to request * \return ATCA_STATUS */ -ATCA_STATUS kit_phy_receive(ATCAIface iface, uint8_t* rxdata, int* rxsize) +ATCA_STATUS hal_kit_hid_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxsize) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); hid_device* pHid = (hid_device*)atgetifacehaldat(iface); @@ -230,70 +188,25 @@ ATCA_STATUS kit_phy_receive(ATCAIface iface, uint8_t* rxdata, int* rxsize) return ATCA_SUCCESS; } -/** \brief Number of USB HID devices found - * \param[out] num_found return number of USB HID devices found - * \return ATCA_STATUS - */ -ATCA_STATUS kit_phy_num_found(int8_t* num_found) -{ - return ATCA_UNIMPLEMENTED; -} - -/** \brief HAL implementation of kit protocol send over USB HID - * \param[in] iface instance - * \param[in] word_address determine device transaction type - * \param[in] txdata pointer to bytes to send - * \param[in] txlength number of bytes to send - * \return ATCA_STATUS - */ -ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int txlength) -{ - // Call the kit_send() function that will call phy_send() implemented below - return kit_send(iface, word_address, txdata, txlength); -} - -/** \brief HAL implementation of send over USB HID - * \param[in] iface instance - * \param[in] word_address determine device transaction type - * \param[in] rxdata pointer to space to receive the data - * \param[in,out] rxsize ptr to expected number of receive bytes to request - * \return ATCA_STATUS - */ -ATCA_STATUS hal_kit_hid_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxsize) -{ - // Call the kit_receive() function that will call phy_receive() implemented below - return kit_receive(iface, word_address, rxdata, rxsize); -} - -/** \brief Call the wake for kit protocol - * \param[in] iface ATCAIface instance that is the interface object to send the bytes over - * \return ATCA_STATUS +/** \brief Perform control operations for the kit protocol + * \param[in] iface Interface to interact with. + * \param[in] option Control parameter identifier + * \param[in] param Optional pointer to parameter value + * \param[in] paramlen Length of the parameter + * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_kit_hid_wake(ATCAIface iface) +ATCA_STATUS hal_kit_hid_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { - // Call the kit_wake() function that will call phy_send() and phy_receive() - return kit_wake(iface); -} + (void)param; + (void)paramlen; -/** \brief Call the idle for kit protocol - * \param[in] iface ATCAIface instance that is the interface object to send the bytes over - * \return ATCA_STATUS - */ -ATCA_STATUS hal_kit_hid_idle(ATCAIface iface) -{ - // Call the kit_idle() function that will call phy_send() and phy_receive() - return kit_idle(iface); + if (iface && iface->mIfaceCFG) + { + return ATCA_UNIMPLEMENTED; + } + return ATCA_BAD_PARAM; } -/** \brief Call the sleep for kit protocol - * \param[in] iface ATCAIface instance that is the interface object to send the bytes over - * \return ATCA_STATUS - */ -ATCA_STATUS hal_kit_hid_sleep(ATCAIface iface) -{ - // Call the kit_sleep() function that will call phy_send() and phy_receive() - return kit_sleep(iface); -} /** \brief Close the physical port for HID * \param[in] hal_data The hardware abstraction data specific to this HAL diff --git a/lib/hal/hal_gpio_harmony.c b/lib/hal/hal_gpio_harmony.c new file mode 100644 index 000000000..3ea40e197 --- /dev/null +++ b/lib/hal/hal_gpio_harmony.c @@ -0,0 +1,788 @@ +/** + * \file + * \brief ATCA Hardware abstraction layer for 1WIRE or SWI over GPIO. + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "hal_gpio_harmony.h" + +static ATCA_STATUS gpio_receive_bytes(ATCAIfaceCfg *cfg, uint8_t *rxdata, uint16_t rxlength); +static ATCA_STATUS gpio_send_bytes(ATCAIfaceCfg *cfg, uint8_t *txdata, uint16_t txlength); +static ATCA_STATUS send_logic_bit(ATCAIfaceCfg *cfg, bool bit_value); + +#ifdef ATCA_HAL_1WIRE +static ATCA_STATUS start_stop_cond_1wire(ATCAIfaceCfg *cfg); +static ATCA_STATUS read_data_ACK_1wire(ATCAIfaceCfg *cfg, bool* bit_value); +static ATCA_STATUS device_discovery_1wire(ATCAIfaceCfg *cfg); +static ATCA_STATUS generate_wake_condition(ATCAIfaceCfg *cfg); +static ATCA_STATUS check_wake_1wire(ATCAIfaceCfg *cfg); +static uint8_t get_slave_addr_1wire(uint8_t dev_addr, uint8_t oper); +static ATCA_STATUS read_logic_bit_1wire(ATCAIfaceCfg *cfg, bool *bit_value); +#endif + +#ifdef ATCA_HAL_SWI +static ATCA_STATUS read_logic_bit_swi(ATCAIfaceCfg *cfg, bool *bit_value); +static ATCA_STATUS check_wake_swi(ATCAIfaceCfg *cfg); +#endif + +/** \brief initialize an GPIO interface using given config + * \param[in] cfg - interface configuration + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_gpio_init(void *hal, ATCAIfaceCfg *cfg) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + atca_plib_gpio_api_t* plib; + + if (cfg) + { + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + + if (plib) + { + /* GPIO direction as output */ + plib->pin_setup(cfg->atcaswi.bus, ATCA_GPIO_OUTPUT_DIR); + /* by default, driving high */ + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + status = ATCA_SUCCESS; + } + } + return status; +} + +/** + * \brief HAL implementation of GPIO post init. + * + * \param[in] iface ATCAIface instance + * + * \return ATCA_SUCCESS + */ +ATCA_STATUS hal_gpio_post_init(ATCAIface iface) +{ + return ATCA_SUCCESS; +} + +/** \brief Discovery Response sequence is used by the master to perform a general + bus call to determine if a device is present on the bus + * \param[in] iface Device to interact with. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_gpio_device_discovery(ATCAIface iface) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + atca_plib_gpio_api_t* plib; + + if (cfg) + { + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if (plib) + { + status = ATCA_UNIMPLEMENTED; + if (cfg->devtype == ATECC204A) + { + #ifdef ATCA_HAL_1WIRE + status = device_discovery_1wire(cfg); + #endif + } + } + } + + return status; +} + +/** \brief HAL implementation of bit banging send over Harmony + * \param[in] iface instance + * \param[in] word_address device transaction type + * \param[in] txdata pointer to space to bytes to send + * \param[in] txlength number of bytes to send + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_gpio_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + ATCA_STATUS status = ATCA_BAD_PARAM; + + #ifdef ATCA_HAL_1WIRE + uint8_t dev_write_addr; + #endif + + if (!cfg) + { + return status; + } + + if (cfg->devtype == ATECC204A) + { + #ifdef ATCA_HAL_1WIRE + if (ATCA_SUCCESS == (status = start_stop_cond_1wire(cfg))) + { + dev_write_addr = get_slave_addr_1wire(cfg->atcaswi.slave_address, ATCA_GPIO_WRITE); + if (ATCA_SUCCESS == (status = gpio_send_bytes(cfg, &dev_write_addr, sizeof(dev_write_addr)))) + { + if (ATCA_SUCCESS == (status = gpio_send_bytes(cfg, &word_address, sizeof(word_address)))) + { + status = gpio_send_bytes(cfg, txdata, txlength); + } + } + status = start_stop_cond_1wire(cfg); + } + #endif + } + else + { + #ifdef ATCA_HAL_SWI + if (ATCA_SUCCESS == (status = gpio_send_bytes(cfg, &word_address, sizeof(word_address)))) + { + status = gpio_send_bytes(cfg, txdata, txlength); + } + #endif + } + + return status; +} + +/** \brief HAL implementation of bit banging receive from HARMONY + * \param[in] iface Device to interact with. + * \param[in] word_address device transaction type + * \param[out] rxdata Data received will be returned here. + * \param[in,out] rxlength As input, the size of the rxdata buffer. + * As output, the number of bytes received. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_gpio_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + ATCA_STATUS status; + int retries; + + if ((NULL == cfg) || (NULL == rxlength) || (NULL == rxdata)) + { + return ATCA_BAD_PARAM; + } + + if (cfg->devtype == ATECC204A) + { + #ifdef ATCA_HAL_1WIRE + word_address = get_slave_addr_1wire(cfg->atcaswi.slave_address, ATCA_GPIO_READ); + if (ATCA_SUCCESS != (status = start_stop_cond_1wire(cfg))) + { + return status; + } + #endif + } + else + { + word_address = ATCA_SWI_TX_WORD_ADDR; + } + + retries = cfg->rx_retries; + do + { + if (ATCA_SUCCESS == (status = gpio_send_bytes(cfg, &word_address, sizeof(word_address)))) + { + /* Reading response length byte */ + if (ATCA_SUCCESS == (status = gpio_receive_bytes(cfg, &rxdata[0], ATCA_1WIRE_RESPONSE_LENGTH_SIZE))) + { + #ifdef ATCA_HAL_1WIRE + if (cfg->devtype == ATECC204A) + { + (void)send_ACK_1wire(cfg); + } + #endif + if (rxdata[0] >= ATCA_MIN_RESPONSE_LENGTH) + { + if (*rxlength < rxdata[0]) + { + status = ATCA_TRACE(ATCA_SMALL_BUFFER, "rxdata is small buffer"); + break; + } + else + { + /* Reading remaining response */ + if (ATCA_SUCCESS == (status = gpio_receive_bytes(cfg, &rxdata[1], rxdata[0] - ATCA_1WIRE_RESPONSE_LENGTH_SIZE))) + { + #ifdef ATCA_HAL_1WIRE + if (cfg->devtype == ATECC204A) + { + (void)send_NACK_1wire(cfg); + } + #endif + *rxlength = rxdata[0]; + } + } + } + else + { + status = ATCA_TRACE(ATCA_COMM_FAIL, "invalid response length"); + } + } + } + } + while ((retries-- > 0) && (status == ATCA_COMM_FAIL)); + +#ifdef ATCA_HAL_1WIRE + status = start_stop_cond_1wire(cfg); +#endif + + return status; +} + +/** \brief Put the device in idle mode + * \param[in] iface interface to logical device to idle + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_gpio_idle(ATCAIface iface) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + + if (cfg) + { + if (cfg->devtype == ATECC204A) + { + return ATCA_SUCCESS; + } + else + { + return hal_gpio_send(iface, ATCA_SWI_IDLE_WORD_ADDR, NULL, 0); + } + } + + return ATCA_BAD_PARAM; +} + +/** \brief send sleep command + * \param[in] iface interface to logical device to sleep + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_gpio_sleep(ATCAIface iface) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + uint8_t word_address; + + if (cfg) + { + word_address = (cfg->devtype == ATECC204A) ? ATCA_1WIRE_SLEEP_WORD_ADDR : \ + ATCA_SWI_SLEEP_WORD_ADDR; + + return hal_gpio_send(iface, word_address, NULL, 0); + } + + return ATCA_BAD_PARAM; +} + +/** \brief send wake token + * \param[in] iface interface to logical device to wakeup + * \return ATCA_WAKE_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_gpio_wake(ATCAIface iface) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + atca_plib_gpio_api_t* plib; + ATCA_STATUS status = ATCA_WAKE_FAILED; + + if (NULL == cfg) + { + return ATCA_BAD_PARAM; + } + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_BAD_PARAM; + } + + if (cfg->devtype == ATECC204A) + { + #ifdef ATCA_HAL_1WIRE + status = check_wake_1wire(cfg); + #endif + } + else + { + #ifdef ATCA_HAL_SWI + (void)generate_wake_condition(cfg); + status = check_wake_swi(cfg); + #endif + } + + return status; +} + +/** \brief releases resource if no more communication + * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_gpio_release(void *hal_data) +{ + return ATCA_SUCCESS; +} + +/** \brief Function to send the specified number of bytes through GPIO bit banging + * \param[in] cfg Driver interface configurations + * \param[in] txdata pointer pointing bytes to send + * \param[in] txlength number of bytes to send + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS gpio_send_bytes(ATCAIfaceCfg *cfg, uint8_t *txdata, uint16_t txlength) +{ + uint8_t bit_mask; + uint8_t count; + + #ifdef ATCA_HAL_1WIRE + bool bit_value; + #endif + protocol_type proto_type; + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (txdata == NULL) + { + return status; + } + + proto_type = (cfg->devtype == ATECC204A) ? ATCA_PROTOCOL_1WIRE : ATCA_PROTOCOL_SWI; + /* Disabling interrupts */ + __disable_irq(); + for (count = 0; count < txlength; count++) + { + bit_mask = (cfg->devtype == ATECC204A) ? ATCA_1WIRE_BIT_MASK : ATCA_SWI_BIT_MASK; + while (bit_mask > 0) + { + /* if the next bit transmitted is a logic '1' */ + if (bit_mask & txdata[count]) + { + status = send_logic_bit(cfg, ATCA_GPIO_LOGIC_BIT1); + } + /* if the next bit transmitted is a logic '0' */ + else + { + status = send_logic_bit(cfg, ATCA_GPIO_LOGIC_BIT0); + } + + bit_mask = (proto_type == ATCA_PROTOCOL_1WIRE) ? bit_mask >> 1 : bit_mask << 1; + } + #ifdef ATCA_HAL_1WIRE + if ((status == ATCA_SUCCESS) && (proto_type == ATCA_PROTOCOL_1WIRE)) + { + (void)read_data_ACK_1wire(cfg, &bit_value); + /* check for ACK/NACK */ + if (bit_value) /* if a NAK is detected */ + { + /* device failed to send ACK */ + status = ATCA_COMM_FAIL; + break; + } + tRCV0_DLY; /* slave recovery time delay (same for logic'0' and logic '1') */ + } + #endif + } + /* Enabling interrupts */ + __enable_irq(); + + return status; +} + +/** \brief Function to send logic bit 1 or 0 over GPIO using 1WIRE + * \param[in] cfg Driver interface configurations + * \param[in] bit_value Logical bit value to be send + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS send_logic_bit(ATCAIfaceCfg *cfg, bool bit_value) +{ + atca_plib_gpio_api_t* plib; + const uint8_t* timings; + const uint8_t logic1_swi_timings[] = { 4, 26 }; + const uint8_t logic1_1wire_timings[] = { 1, 41 }; + const uint8_t logic0_swi_timings[] = { 4, 34, 4, 4 }; + const uint8_t logic0_1wire_timings[] = { 11, 31 }; + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_BAD_PARAM; + } + + if (bit_value == ATCA_GPIO_LOGIC_BIT1) + { + timings = (cfg->devtype == ATECC204A) ? logic1_1wire_timings : logic1_swi_timings; + plib->write(cfg->atcaswi.bus, ATCA_GPIO_CLEAR); + atca_delay_us(*timings++); + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + atca_delay_us(*timings++); + } + else + { + timings = (cfg->devtype == ATECC204A) ? logic0_1wire_timings : logic0_swi_timings; + plib->write(cfg->atcaswi.bus, ATCA_GPIO_CLEAR); + atca_delay_us(*timings++); + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + atca_delay_us(*timings++); + #ifdef ATCA_HAL_SWI + if (cfg->devtype != ATECC204A) + { + plib->write(cfg->atcaswi.bus, ATCA_GPIO_CLEAR); + atca_delay_us(*timings++); + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + atca_delay_us(*timings++); + } + #endif + } + + return ATCA_SUCCESS; +} + +/** \brief Function to receive the response bytes through GPIO bit banging + * \param[in] cfg Driver interface configurations + * \param[in] rxdata pointer pointing where received bytes to be stored + * \param[in] rxlength number of bytes to receive + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS gpio_receive_bytes(ATCAIfaceCfg *cfg, uint8_t *rxdata, uint16_t rxlength) +{ + uint8_t bit_mask; + uint8_t count; + atca_plib_gpio_api_t* plib; + protocol_type proto_type; + bool bit_value = 1; + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if ((plib == NULL) || (rxdata == NULL)) + { + return ATCA_BAD_PARAM; + } + + proto_type = (cfg->devtype == ATECC204A) ? ATCA_PROTOCOL_1WIRE : ATCA_PROTOCOL_SWI; + + __disable_irq(); + for (count = 0; count < rxlength; count++) + { + bit_mask = (cfg->devtype == ATECC204A) ? ATCA_1WIRE_BIT_MASK : ATCA_SWI_BIT_MASK; + while (bit_mask >= 1) + { + #ifdef ATCA_HAL_1WIRE + if (proto_type == ATCA_PROTOCOL_1WIRE) + { + plib->write(cfg->atcaswi.bus, ATCA_GPIO_CLEAR); + /* device is set for high-speed communication */ + tHIGH_SPEED_DLY; + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + tSWIN_DLY; /* delay to put master read inside the master sampling window */ + (void)read_logic_bit_1wire(cfg, &bit_value); + } + #endif + + #ifdef ATCA_HAL_SWI + if (proto_type == ATCA_PROTOCOL_SWI) + { + (void)read_logic_bit_swi(cfg, &bit_value); + } + #endif + if (bit_value) /* if a logic '1' is detected; received "one" bit */ + { + rxdata[count] |= bit_mask; + } + if (proto_type == ATCA_PROTOCOL_1WIRE) + { + tBIT_DLY;//bit frame duration (tBIT) before reading the next bit + bit_mask >>= 1; + } + else + { + bit_mask <<= 1; + } + } + #ifdef ATCA_HAL_1WIRE + /* send ACK except for last byte of read --> GO TO send_ACK() */ + if ((count < (rxlength - 1)) && (proto_type == ATCA_PROTOCOL_1WIRE)) + { + (void)send_ACK_1wire(cfg); + } + #endif + } + __enable_irq(); + + return ATCA_SUCCESS; +} + +#ifdef ATCA_HAL_1WIRE +/** \brief Function to generate start or stop condition + * \param[in] cfg Driver interface configurations + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS start_stop_cond_1wire(ATCAIfaceCfg *cfg) +{ + atca_plib_gpio_api_t* plib; + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if (plib) + { + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + tHTSS_DLY; + return ATCA_SUCCESS; + } + + return ATCA_BAD_PARAM; +} + +/** \brief Function to read the data ACK for the transmitted byte + * \param[in] cfg Driver interface configurations + * \param[in] bit_value Contains logical bit value(ACK or NACK) to be received + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS read_data_ACK_1wire(ATCAIfaceCfg *cfg, bool *bit_value) +{ + atca_plib_gpio_api_t* plib; + ATCA_STATUS status = ATCA_BAD_PARAM; + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + + if (plib) + { + /* this checks for an ACK or NACK from device */ + plib->write(cfg->atcaswi.bus, ATCA_GPIO_CLEAR); + tRD_DLY; + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + tLOW1_DLY; + + status = read_logic_bit_1wire(cfg, bit_value); + } + + return status; +} + +/** \brief Function to discover the available devices in the bus + * \param[in] cfg Driver interface configurations + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS device_discovery_1wire(ATCAIfaceCfg *cfg) +{ + atca_plib_gpio_api_t* plib; + bool bit_value; + ATCA_STATUS status = ATCA_BAD_PARAM; + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if (plib) + { + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + tRRT_DLY; + plib->write(cfg->atcaswi.bus, ATCA_GPIO_CLEAR); + tDRR_DLY; + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + tDACK_DLY; + + (void)read_logic_bit_1wire(cfg, &bit_value); + status = (bit_value == ((bool)ATCA_GPIO_ACK)) ? ATCA_SUCCESS : ATCA_NO_DEVICES; + } + + return status; +} + +/** \brief Function to generate wake condition + * \param[in] cfg Driver interface configurations + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS generate_wake_condition(ATCAIfaceCfg *cfg) +{ + atca_plib_gpio_api_t* plib; + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if (plib) + { + plib->write(cfg->atcaswi.bus, ATCA_GPIO_CLEAR); + atca_delay_us(60); + plib->write(cfg->atcaswi.bus, ATCA_GPIO_SET); + atca_delay_us(cfg->wake_delay); + return ATCA_SUCCESS; + } + return ATCA_BAD_PARAM; +} + +/** \brief Function to check wake condition for 1WIRE + * \param[in] cfg Driver interface configurations + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS check_wake_1wire(ATCAIfaceCfg *cfg) +{ + ATCA_STATUS status; + uint8_t dev_addr; + + status = device_discovery_1wire(cfg); + if (status == ATCA_NO_DEVICES) + { + (void)generate_wake_condition(cfg); + status = start_stop_cond_1wire(cfg); + dev_addr = get_slave_addr_1wire(cfg->atcaswi.slave_address, ATCA_GPIO_WRITE); + status = gpio_send_bytes(cfg, &dev_addr, sizeof(dev_addr)); + (void)start_stop_cond_1wire(cfg); + } + + return status; +} + +/** \brief Function to read the data ACK for the transmitted byte + * \param[in] dev_addr 7 bit device address + * \param[in] oper indicates read or write operation + * \return 8 bit device address for write or read operation + */ +static uint8_t get_slave_addr_1wire(uint8_t dev_addr, uint8_t oper) +{ + return (dev_addr << 1) | oper; +} + +/** \brief Function to read the logic bit 1 or 0 + * \param[in] cfg Driver interface configurations + * \param[in] bit_value Contains hogical bit value to be received + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS read_logic_bit_1wire(ATCAIfaceCfg *cfg, bool *bit_value) +{ + atca_plib_gpio_api_t* plib; + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if (plib) + { + /* Changing the PIN direction as Input */ + plib->pin_setup(cfg->atcaswi.bus, ATCA_GPIO_INPUT_DIR); + *bit_value = plib->read(cfg->atcaswi.bus); + /* Changing the PIN direction as Output */ + plib->pin_setup(cfg->atcaswi.bus, ATCA_GPIO_OUTPUT_DIR); + return ATCA_SUCCESS; + } + + return ATCA_BAD_PARAM; +} +#endif /* End of ATCA_HAL_1WIRE */ + +#ifdef ATCA_HAL_SWI +/** \brief Function to read the logic bit 1 or 0 + * \param[in] cfg Driver interface configurations + * \param[in] bit_value Contains logical bit value to be received + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS read_logic_bit_swi(ATCAIfaceCfg *cfg, bool *bit_value) +{ + atca_plib_gpio_api_t* plib; + int8_t timeout_count; + bool current_state = true, prev_state = true; + uint8_t bit_count = 0; + ATCA_STATUS status = ATCA_BAD_PARAM; + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return status; + } + + do + { + //wait for start bit + timeout_count = 90 / 2; + while (timeout_count-- >= 0) + { + current_state = plib->read(cfg->atcaswi.bus); + if (current_state != prev_state) + { + prev_state = current_state; + if (!current_state) + { + break; + } + + } + atca_delay_us(2); + } + + if (timeout_count <= 0) + { + status = ATCA_TRACE(ATCA_RX_NO_RESPONSE, "No response is received"); + break; + } + + //Read bit + timeout_count = 40 / 2; + while (timeout_count-- >= 0) + { + current_state = plib->read(cfg->atcaswi.bus); + if (current_state != prev_state) + { + prev_state = current_state; + if (current_state) + { + bit_count++; + } + + } + atca_delay_us(2); + } + + if (bit_count == 2) + { + *bit_value = 0; + } + else if (bit_count == 1) + { + *bit_value = 1; + } + else + { + status = ATCA_TRACE(ATCA_RX_FAIL, "Rx Receive - failed"); + } + } + while (0); + + return status; +} + +/** \brief Function to check wake condition for SWI + * \param[in] cfg Driver interface configurations + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS check_wake_swi(ATCAIfaceCfg *cfg) +{ + atca_plib_gpio_api_t* plib; + uint8_t data[4] = { 0x00, 0x00, 0x00, 0x00 }; + uint16_t rxlength = sizeof(data); + const uint8_t expected_response[4] = { 0x04, 0x11, 0x33, 0x43 }; + const uint8_t selftest_fail_resp[4] = { 0x04, 0x07, 0xC4, 0x40 }; + + plib = (atca_plib_gpio_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_BAD_PARAM; + } + + if (gpio_receive_bytes(cfg, data, rxlength) == ATCA_SUCCESS) + { + if (memcmp(data, expected_response, 4) == 0) + { + return ATCA_SUCCESS; + } + if (memcmp(data, selftest_fail_resp, 4) == 0) + { + return ATCA_STATUS_SELFTEST_ERROR; + } + } + return ATCA_WAKE_FAILED; +} +#endif /* ATCA_HAL_SWI */ diff --git a/lib/hal/hal_gpio_harmony.h b/lib/hal/hal_gpio_harmony.h new file mode 100644 index 000000000..4583fe24a --- /dev/null +++ b/lib/hal/hal_gpio_harmony.h @@ -0,0 +1,170 @@ +/** + * \file + * \brief ATCA Hardware abstraction layer for SWI over GPIO drivers. + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef HAL_GPIO_HARMONY +#define HAL_GPIO_HARMONY + +#include +#include "cryptoauthlib.h" +#include "atca_status.h" +#include "atca_hal.h" +#include "atca_config.h" + +/** + * \name Macros for Bit-Banged 1WIRE Timing + * + * Times to drive bits at 230.4 kbps. + @{ */ + +#define tPUP 0 +#define tDSCHG 150 //min spec = 150us +#define tRESET 96 //min spec = 480us (STD Speed) +#define tRRT 1 //min spec = 1ms +#define tDRR 1 //min spec = 1us; max spec = 2us +#define tMSDR 2 //min spec = 2us; max spec = 6us +#define tHTSS 150 //min spec = 150us +#define tDACK 2 //min spec = 2us; max spec = 6 + +#define tDACK_DLY atca_delay_us(tDACK) +#define tRRT_DLY atca_delay_ms(tRRT) +#define tDRR_DLY atca_delay_us(tDRR) +#define tMSDR_DLY atca_delay_us(tMSDR) +#define tDSCHG_DLY atca_delay_us(tDSCHG) +#define tRESET_DLY atca_delay_us(tRESET) +#define tHTSS_DLY atca_delay_us(tHTSS) + +#define tLOW0_MIN 6 +#define tLOW0_MAX 16 +#define tLOW1_MIN 1 +#define tLOW1_MAX 2 + +#define tRCV_MIN 4 +#define tRCV_MAX 6 + +#define tBIT_MIN (tLOW0_MIN + tPUP + tRCV_MIN) +#define tBIT_MAX 75 +#define tWAKEUP 1 //min spec = 1ms + +#define tLOW0_TYPICAL (tLOW0_MIN + ((tLOW0_MAX - tLOW0_MIN) / 2)) //creates typical data timing (AVG of Min and Max) +#define tLOW1_TYPICAL (tLOW1_MIN + ((tLOW1_MAX - tLOW1_MIN) / 2)) //creates typical data timing (AVG of Min and Max) +#define tBIT_TYPICAL (tBIT_MIN + ((tBIT_MAX - tBIT_MIN) / 2 )) //creates typical data timing (AVG of Min and Max) + +#define tLOW0_HDLY atca_delay_us(11) //min spec = 6us; max spec = 16us +#define tRD_HDLY atca_delay_us(1) //min spec = 1us; max spec = 2us +#define tLOW1_HDLY atca_delay_us(1) //min spec = 1us; max spec = 2us +#define tRCV0_HDLY atca_delay_us(11) +#define tRCV1_HDLY atca_delay_us(14) + +#define tRD_DLY atca_delay_us(1) //min spec = 1us; max spec = 2us +#define tHIGH_SPEED_DLY atca_delay_us(1) +#define tSWIN_DLY atca_delay_us(1) //delay to put master strobe within sample window + +#define tLOW0_DLY atca_delay_us(tLOW0_TYPICAL) +#define tLOW1_DLY atca_delay_us(tLOW1_TYPICAL) + +#define tBIT_DLY atca_delay_us(tBIT_TYPICAL) +#define tRCV0_DLY atca_delay_us(tBIT_TYPICAL - tLOW0_TYPICAL) +#define tRCV1_DLY atca_delay_us(tBIT_TYPICAL - tLOW1_TYPICAL) + +#define send_logic0_1wire(...) send_logic_bit(__VA_ARGS__, ATCA_GPIO_LOGIC_BIT0) +#define send_logic1_1wire(...) send_logic_bit(__VA_ARGS__, ATCA_GPIO_LOGIC_BIT1) +#define send_ACK_1wire(...) send_logic0_1wire(__VA_ARGS__) +#define send_NACK_1wire(...) send_logic1_1wire(__VA_ARGS__) + +#define ATCA_1WIRE_RESET_WORD_ADDR 0x00 +#define ATCA_1WIRE_SLEEP_WORD_ADDR 0x01 +#define ATCA_1WIRE_SLEEP_WORD_ADDR_ALTERNATE 0x02 +#define ATCA_1WIRE_COMMAND_WORD_ADDR 0x03 + +#define ATCA_1WIRE_RESPONSE_LENGTH_SIZE 0x01 +#define ATCA_1WIRE_BIT_MASK 0x80 + +#define ATCA_GPIO_WRITE 0 +#define ATCA_GPIO_READ 1 +#define ATCA_GPIO_INPUT_DIR 0 +#define ATCA_GPIO_OUTPUT_DIR 1 +#define ATCA_GPIO_LOGIC_BIT0 0 +#define ATCA_GPIO_LOGIC_BIT1 1 +#define ATCA_GPIO_ACK ATCA_GPIO_LOGIC_BIT0 +#define ATCA_GPIO_CLEAR 0 +#define ATCA_GPIO_SET 1 +#define ATCA_MIN_RESPONSE_LENGTH 4 + + +/** + * \name Macros for Bit-Banged SWI Timing + * + * Times to drive bits at 230.4 kbps. + @{ */ + +//! delay macro for width of one pulse (start pulse or zero pulse) +//! should be 4.34 us, is 4.05 us + +#define BIT_DELAY_1L atca_delay_us(4) +//! should be 4.34 us, is 4.05us +#define BIT_DELAY_1H atca_delay_us(4) + +//! time to keep pin high for five pulses plus stop bit (used to bit-bang CryptoAuth 'zero' bit) +//! should be 26.04 us, is 26.92 us +#define BIT_DELAY_5 atca_delay_us(26) // considering pin set delay + +//! time to keep pin high for seven bits plus stop bit (used to bit-bang CryptoAuth 'one' bit) +//! should be 34.72 us, is 35.13 us +#define BIT_DELAY_7 atca_delay_us(34) // considering pin set delay + +//! turn around time when switching from receive to transmit +//! should be 93 us (Setting little less value as there would be other process before these steps) +#define RX_TX_DELAY atca_delay_us(65) + + +/** SWI WORD Address */ +#define ATCA_SWI_WAKE_WORD_ADDR ((uint8_t)0x00) +#define ATCA_SWI_CMD_WORD_ADDR ((uint8_t)0x77) +#define ATCA_SWI_TX_WORD_ADDR ((uint8_t)0x88) +#define ATCA_SWI_IDLE_WORD_ADDR ((uint8_t)0xBB) +#define ATCA_SWI_SLEEP_WORD_ADDR ((uint8_t)0xCC) +#define ATCA_SWI_BIT_MASK 0x01 + +typedef enum +{ + ATCA_PROTOCOL_1WIRE, + ATCA_PROTOCOL_SWI, + NO_OF_PROTOCOL +} protocol_type; + +typedef enum +{ + LOGIC0_1, + LOGIC0_2, + LOGIC0_3, + LOGIC0_4, + LOGIC1_1, + LOGIC1_2, + NO_OF_DELAYS +} delay_type; + +#endif diff --git a/lib/hal/hal_i2c_harmony.c b/lib/hal/hal_i2c_harmony.c index 1d326b15d..c1aca2f93 100644 --- a/lib/hal/hal_i2c_harmony.c +++ b/lib/hal/hal_i2c_harmony.c @@ -34,6 +34,7 @@ #include "cryptoauthlib.h" + /** \defgroup hal_ Hardware abstraction layer (hal_) * * \brief @@ -119,7 +120,7 @@ static ATCA_STATUS hal_i2c_wait(atca_plib_i2c_api_t* plib, uint32_t rate, uint16 * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg) +ATCA_STATUS hal_i2c_init(ATCAIface iface, ATCAIfaceCfg *cfg) { return ATCA_SUCCESS; } @@ -141,7 +142,7 @@ ATCA_STATUS hal_i2c_post_init(ATCAIface iface) * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength) +ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t address, uint8_t *txdata, int txlength) { ATCAIfaceCfg* cfg = atgetifacecfg(iface); atca_plib_i2c_api_t * plib; @@ -158,13 +159,6 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, return ATCA_BAD_PARAM; } - - if (0xFF != word_address) - { - txdata[0] = word_address; // insert the Word Address Value, Command token - txlength++; // account for word address value byte. - } - /* Wait for the I2C bus to be ready */ /* Since the wait time is unknown, waiting for 30 bytes duration */ status = hal_i2c_wait(plib, cfg->atcai2c.baud, 30); @@ -172,7 +166,7 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, if (ATCA_SUCCESS == status) { status = ATCA_COMM_FAIL; - if (plib->write(cfg->atcai2c.slave_address >> 1, txdata, txlength) == true) + if (plib->write(address >> 1, txdata, txlength) == true) { /* Wait for the I2C transfer to complete */ status = hal_i2c_wait(plib, cfg->atcai2c.baud, txlength); @@ -199,15 +193,11 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, * As output, the number of bytes received. * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength) +ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t address, uint8_t *rxdata, uint16_t *rxlength) { ATCA_STATUS status = ATCA_COMM_FAIL; ATCAIfaceCfg* cfg = atgetifacecfg(iface); - uint16_t rxdata_max_size; - uint16_t read_length = 2; - uint8_t min_resp_size = 4; atca_plib_i2c_api_t * plib; - int retries; if ((NULL == cfg) || (NULL == rxlength) || (NULL == rxdata)) { @@ -219,104 +209,25 @@ ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxda return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); } - rxdata_max_size = *rxlength; - *rxlength = 0; - - do + /* Read given length bytes from device */ + status = ATCA_COMM_FAIL; + if (plib->read(address >> 1, rxdata, *rxlength) == true) { - /*Send Word address to device...*/ - retries = cfg->rx_retries; - while (retries-- > 0 && status != ATCA_SUCCESS) + /* Wait for the I2C transfer to complete */ + if (ATCA_SUCCESS == (status = hal_i2c_wait(plib, cfg->atcai2c.baud, *rxlength))) { - status = hal_i2c_send(iface, word_address, &word_address, 0); - } - if (ATCA_SUCCESS != status) - { - ATCA_TRACE(status, "hal_i2c_send - failed"); - break; - } - -#if ATCA_TA_SUPPORT - /*Set read length.. Check for register reads or 1 byte reads*/ - if ((word_address == ATCA_MAIN_PROCESSOR_RD_CSR) || (word_address == ATCA_FAST_CRYPTO_RD_FSR) - || (rxdata_max_size == 1)) - { - read_length = 1; - } -#endif - - /* Read length bytes to know number of bytes to read */ - status = ATCA_COMM_FAIL; - if (plib->read(cfg->atcai2c.slave_address >> 1, rxdata, read_length) == true) - { - /* Wait for the I2C transfer to complete */ - if (ATCA_SUCCESS == (status = hal_i2c_wait(plib, cfg->atcai2c.baud, read_length))) + /* Transfer complete. Check if the transfer was successful */ + if (plib->error_get() != PLIB_I2C_ERROR_NONE) { - /* Transfer complete. Check if the transfer was successful */ - if (plib->error_get() != PLIB_I2C_ERROR_NONE) - { - status = ATCA_COMM_FAIL; - } - } - } - if (ATCA_SUCCESS != status) - { - ATCA_TRACE(status, "plib->read - failed"); - break; - } - - if (1 == read_length) - { - ATCA_TRACE(status, "1 byte read completed"); - break; - } - - /*Calculate bytes to read based on device response*/ - if (cfg->devtype == TA100) - { - read_length = ((uint16_t)rxdata[0] * 256) + rxdata[1]; - min_resp_size += 1; - } - else - { - read_length = rxdata[0]; - } - - if (read_length > rxdata_max_size) - { - status = ATCA_TRACE(ATCA_SMALL_BUFFER, "rxdata is small buffer"); - break; - } - - if (read_length < min_resp_size) - { - status = ATCA_TRACE(ATCA_RX_FAIL, "packet size is invalid"); - break; - } - - /* Read given length bytes from device */ - status = ATCA_COMM_FAIL; - if (plib->read(cfg->atcai2c.slave_address >> 1, &rxdata[2], read_length - 2) == true) - { - /* Wait for the I2C transfer to complete */ - if (ATCA_SUCCESS == (status = hal_i2c_wait(plib, cfg->atcai2c.baud, read_length - 2))) - { - /* Transfer complete. Check if the transfer was successful */ - if (plib->error_get() != PLIB_I2C_ERROR_NONE) - { - status = ATCA_COMM_FAIL; - } + status = ATCA_COMM_FAIL; } } - if (ATCA_SUCCESS != status) - { - status = ATCA_TRACE(status, "plib->read - failed"); - break; - } } - while (0); + if (ATCA_SUCCESS != status) + { + status = ATCA_TRACE(status, "plib->read - failed"); + } - *rxlength = read_length; return status; } @@ -356,195 +267,30 @@ ATCA_STATUS change_i2c_speed(ATCAIface iface, uint32_t speed) return status; } -/** \brief wake up CryptoAuth device using I2C bus - * \param[in] iface interface to logical device to wakeup - * \return ATCA_SUCCESS on success, otherwise an error code. - */ - -ATCA_STATUS hal_i2c_wake(ATCAIface iface) -{ - ATCA_STATUS status = ATCA_SUCCESS; - ATCAIfaceCfg* cfg = atgetifacecfg(iface); - atca_plib_i2c_api_t * plib; - int retries; - uint32_t bdrt; - uint8_t data[4] = { 0 }; - - if (!cfg) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } - - plib = (atca_plib_i2c_api_t*)cfg->cfg_data; - if (!plib) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } - - - retries = cfg->rx_retries; - - bdrt = cfg->atcai2c.baud; - if (bdrt != 100000) // if not already at 100KHz, change it - { - status = change_i2c_speed(iface, 100000); - } - - if (ATCA_SUCCESS == status) - { - /* Wait for the I2C bus to be ready */ - /* Since the wait time is unknown, waiting for 30 bytes duration */ - if (ATCA_SUCCESS == (status = hal_i2c_wait(plib, 100000, 30))) - { - // Send the 00 address as the wake pulse; part will NACK, so don't check for status - (void)plib->write(0x00, (uint8_t*)&data[0], 1); - - /* Wait for the I2C transfer to complete */ - status = hal_i2c_wait(plib, 100000, 1); - } - } - - if (ATCA_SUCCESS == status) - { - // wait tWHI + tWLO which is configured based on device type and configuration structure - atca_delay_us(cfg->wake_delay); - - status = ATCA_COMM_FAIL; - while (retries-- > 0 && status == ATCA_COMM_FAIL) - { - if (plib->read(cfg->atcai2c.slave_address >> 1, (uint8_t*)&data[0], 4) == true) - { - /* Wait for the I2C transfer to complete */ - status = hal_i2c_wait(plib, 100000, 4); - - if (ATCA_SUCCESS == status) - { - /* Transfer complete. Check if the transfer was successful */ - if (plib->error_get() != PLIB_I2C_ERROR_NONE) - { - status = ATCA_COMM_FAIL; - } - } - } - } - if (ATCA_SUCCESS == status) - { - // if necessary, revert baud rate to what came in. - if (bdrt != 100000) - { - status = change_i2c_speed(iface, bdrt); - } - } - - if (ATCA_SUCCESS == status) - { - status = hal_check_wake(data, 4); - } - } - - return status; -} - -/** \brief idle CryptoAuth device using I2C bus - * \param[in] iface interface to logical device to idle +/** \brief Perform control operations for the kit protocol + * \param[in] iface Interface to interact with. + * \param[in] option Control parameter identifier + * \param[in] param Optional pointer to parameter value + * \param[in] paramlen Length of the parameter * \return ATCA_SUCCESS on success, otherwise an error code. */ - -ATCA_STATUS hal_i2c_idle(ATCAIface iface) +ATCA_STATUS hal_i2c_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { - ATCA_STATUS status = ATCA_COMM_FAIL; - ATCAIfaceCfg* cfg = atgetifacecfg(iface); - atca_plib_i2c_api_t * plib; - uint8_t data[1]; + (void)param; + (void)paramlen; - if (!cfg) + if (iface && iface->mIfaceCFG) { - return ATCA_BAD_PARAM; - } - - plib = (atca_plib_i2c_api_t*)cfg->cfg_data; - if (!plib) - { - return ATCA_BAD_PARAM; - } - - data[0] = 0x02; // idle word address value - - /* Wait for the I2C bus to be ready */ - /* Since wait time is unknown, wait for 30 bytes time */ - status = hal_i2c_wait(plib, cfg->atcai2c.baud, 30); - - if (ATCA_SUCCESS == status) - { - status = ATCA_COMM_FAIL; - if (plib->write(cfg->atcai2c.slave_address >> 1, (uint8_t*)&data[0], 1) == true) + if (ATCA_HAL_CHANGE_BAUD == option) { - /* Wait for the I2C transfer to complete */ - status = hal_i2c_wait(plib, cfg->atcai2c.baud, 1); - - if (ATCA_SUCCESS == status) - { - /* Transfer complete. Check if the transfer was successful */ - if (plib->error_get() != PLIB_I2C_ERROR_NONE) - { - status = ATCA_TRACE(ATCA_COMM_FAIL, "plib->write failed"); - } - } + return change_i2c_speed(iface, *(uint32_t*)param); } - } - - return status; -} - -/** \brief sleep CryptoAuth device using I2C bus - * \param[in] iface interface to logical device to sleep - * \return ATCA_SUCCESS on success, otherwise an error code. - */ - -ATCA_STATUS hal_i2c_sleep(ATCAIface iface) -{ - ATCA_STATUS status = ATCA_COMM_FAIL; - ATCAIfaceCfg* cfg = atgetifacecfg(iface); - atca_plib_i2c_api_t * plib; - uint8_t data[4]; - - if (!cfg) - { - return ATCA_BAD_PARAM; - } - - plib = (atca_plib_i2c_api_t*)cfg->cfg_data; - if (!plib) - { - return ATCA_BAD_PARAM; - } - - data[0] = 0x01; // sleep word address value - - /* Wait for the I2C bus to be ready */ - /* Since wait time is unknown, wait for 30 bytes time */ - status = hal_i2c_wait(plib, cfg->atcai2c.baud, 30); - - if (ATCA_SUCCESS == status) - { - status = ATCA_COMM_FAIL; - if (plib->write(cfg->atcai2c.slave_address >> 1, (uint8_t*)&data[0], 1) == true) + else { - /* Wait for the I2C transfer to complete */ - status = hal_i2c_wait(plib, cfg->atcai2c.baud, 1); - - if (ATCA_SUCCESS == status) - { - /* Transfer complete. Check if the transfer was successful */ - if (plib->error_get() != PLIB_I2C_ERROR_NONE) - { - status = ATCA_TRACE(ATCA_COMM_FAIL, "plib->write failed"); - } - } + return ATCA_UNIMPLEMENTED; } } - - return status; + return ATCA_BAD_PARAM; } /** \brief manages reference count on given bus and releases resource if no more refences exist diff --git a/lib/hal/hal_i2c_start.c b/lib/hal/hal_i2c_start.c index c267eeabb..124716f94 100644 --- a/lib/hal/hal_i2c_start.c +++ b/lib/hal/hal_i2c_start.c @@ -39,6 +39,10 @@ #include "atca_start_iface.h" #include "cryptoauthlib.h" +#ifndef ATCA_HAL_LEGACY_API +#error "The use of this hal requires the ATCA_HAL_LEGACY_API option to be enabled. +#endif + /** \defgroup hal_ Hardware abstraction layer (hal_) * * \brief diff --git a/lib/hal/hal_kit_bridge.c b/lib/hal/hal_kit_bridge.c index 17c4dbe52..9dcee638c 100644 --- a/lib/hal/hal_kit_bridge.c +++ b/lib/hal/hal_kit_bridge.c @@ -250,7 +250,7 @@ ATCA_STATUS hal_kit_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxda * \param[in] iface ATCAIface instance that is the interface object to send the bytes over * \return ATCA_STATUS */ -ATCA_STATUS hal_kit_wake(ATCAIface iface) +static ATCA_STATUS hal_kit_wake(ATCAIface iface) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -290,7 +290,7 @@ ATCA_STATUS hal_kit_wake(ATCAIface iface) * \param[in] iface ATCAIface instance that is the interface object to send the bytes over * \return ATCA_STATUS */ -ATCA_STATUS hal_kit_idle(ATCAIface iface) +static ATCA_STATUS hal_kit_idle(ATCAIface iface) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -330,7 +330,7 @@ ATCA_STATUS hal_kit_idle(ATCAIface iface) * \param[in] iface ATCAIface instance that is the interface object to send the bytes over * \return ATCA_STATUS */ -ATCA_STATUS hal_kit_sleep(ATCAIface iface) +static ATCA_STATUS hal_kit_sleep(ATCAIface iface) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -366,6 +366,27 @@ ATCA_STATUS hal_kit_sleep(ATCAIface iface) return status; } +/** \brief Kit Protocol Control + * \param[in] iface ATCAIface instance that is the interface object to send the bytes over + * \param[in] option Control option to use + * \return ATCA_STATUS + */ +ATCA_STATUS hal_kit_control(ATCAIface iface, uint8_t option) +{ + switch (option) + { + case ATCA_HAL_CONTROL_WAKE: + return hal_kit_wake(iface); + case ATCA_HAL_CONTROL_IDLE: + return hal_kit_idle(iface); + case ATCA_HAL_CONTROL_SLEEP: + return hal_kit_sleep(iface); + default: + return ATCA_BAD_PARAM; + } +} + + /** \brief Close the physical port for HID * \param[in] hal_data The hardware abstraction data specific to this HAL * \return ATCA_STATUS diff --git a/lib/hal/hal_linux_i2c_userspace.c b/lib/hal/hal_linux_i2c_userspace.c index ed378aa36..da3212b6e 100644 --- a/lib/hal/hal_linux_i2c_userspace.c +++ b/lib/hal/hal_linux_i2c_userspace.c @@ -40,7 +40,6 @@ #include #include "atca_hal.h" -#include "hal_linux_i2c_userspace.h" /** \defgroup hal_ Hardware abstraction layer (hal_) * @@ -49,30 +48,11 @@ * @{ */ -/** \brief discover i2c buses available for this hardware - * this maintains a list of logical to physical bus mappings freeing the application - * of the a-priori knowledge.This function is not implemented. - * \param[in] i2c_buses - an array of logical bus numbers - * \param[in] max_buses - maximum number of buses the app wants to attempt to discover - * \return ATCA_UNIMPLEMENTED - */ - -ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses) +typedef struct atca_i2c_host_s { - return ATCA_UNIMPLEMENTED; -} - -/** \brief discover any CryptoAuth devices on a given logical bus number - * \param[in] bus_num logical bus number on which to look for CryptoAuth devices - * \param[out] cfg pointer to head of an array of interface config structures which get filled in by this method - * \param[out] found number of devices found on this bus - * \return ATCA_UNIMPLEMENTED - */ - -ATCA_STATUS hal_i2c_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found) -{ - return ATCA_UNIMPLEMENTED; -} + char i2c_file[16]; + int ref_ct; +} atca_i2c_host_t; /** \brief HAL implementation of I2C init * @@ -84,19 +64,18 @@ ATCA_STATUS hal_i2c_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_init(void* hal, ATCAIfaceCfg* cfg) +ATCA_STATUS hal_i2c_init(ATCAIface iface, ATCAIfaceCfg* cfg) { - ATCAHAL_t *pHal = (ATCAHAL_t*)hal; ATCA_STATUS ret = ATCA_BAD_PARAM; - if (!pHal || !cfg) + if (!iface || !cfg) { return ret; } - if (pHal->hal_data) + if (iface->hal_data) { - ATCAI2CMaster_t * hal_data = (ATCAI2CMaster_t*)pHal->hal_data; + atca_i2c_host_t * hal_data = (atca_i2c_host_t*)iface->hal_data; // Assume the bus had already been initialized hal_data->ref_ct++; @@ -105,7 +84,7 @@ ATCA_STATUS hal_i2c_init(void* hal, ATCAIfaceCfg* cfg) } else { - ATCAI2CMaster_t * hal_data = malloc(sizeof(ATCAI2CMaster_t)); + atca_i2c_host_t * hal_data = malloc(sizeof(atca_i2c_host_t)); int bus = cfg->atcai2c.bus; // 0-based logical bus number if (hal_data) @@ -114,7 +93,7 @@ ATCA_STATUS hal_i2c_init(void* hal, ATCAIfaceCfg* cfg) (void)snprintf(hal_data->i2c_file, sizeof(hal_data->i2c_file) - 1, "/dev/i2c-%d", bus); - pHal->hal_data = hal_data; + iface->hal_data = hal_data; ret = ATCA_SUCCESS; } @@ -145,26 +124,20 @@ ATCA_STATUS hal_i2c_post_init(ATCAIface iface) * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength) +ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t address, uint8_t *txdata, int txlength) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); - ATCAI2CMaster_t * hal_data = (ATCAI2CMaster_t*)atgetifacehaldat(iface); + atca_i2c_host_t * hal_data = (atca_i2c_host_t*)atgetifacehaldat(iface); int f_i2c; // I2C file descriptor - if (0xFF != word_address) - { - txdata[0] = word_address; // insert the Word Address Value, Command token - txlength++; // account for word address value byte. - } - // Initiate I2C communication if ( (f_i2c = open(hal_data->i2c_file, O_RDWR)) < 0) { return ATCA_COMM_FAIL; } - // Set Slave Address - if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0) + // Set Device Address + if (ioctl(f_i2c, I2C_SLAVE, address >> 1) < 0) { close(f_i2c); return ATCA_COMM_FAIL; @@ -192,17 +165,8 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); - ATCAI2CMaster_t * hal_data = (ATCAI2CMaster_t*)atgetifacehaldat(iface); + atca_i2c_host_t * hal_data = (atca_i2c_host_t*)atgetifacehaldat(iface); int f_i2c; // I2C file descriptor - uint16_t read_length = 2; - uint8_t min_resp_size = 4; - uint16_t rxdata_max_size = *rxlength; - - *rxlength = 0; - if (rxdata_max_size < 1) - { - return ATCA_SMALL_BUFFER; - } // Initiate I2C communication if ( (f_i2c = open(hal_data->i2c_file, O_RDWR)) < 0) @@ -210,215 +174,41 @@ ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxda return ATCA_COMM_FAIL; } - // Set Slave Address - if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0) - { - close(f_i2c); - return ATCA_COMM_FAIL; - } - - // Send data - if (write(f_i2c, &word_address, 1) != 1) + // Set Device Address + if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.address >> 1) < 0) { close(f_i2c); return ATCA_COMM_FAIL; } -#if ATCA_TA_SUPPORT - /*Set read length.. Check for register reads or 1 byte reads*/ - if ((word_address == ATCA_MAIN_PROCESSOR_RD_CSR) || (word_address == ATCA_FAST_CRYPTO_RD_FSR) - || (rxdata_max_size == 1)) - { - read_length = 1; - } -#endif - - if (read(f_i2c, rxdata, read_length) != read_length) + if (read(f_i2c, rxdata, *rxlength) != *rxlength) { close(f_i2c); return ATCA_COMM_FAIL; } - if (1 == read_length) - { - close(f_i2c); - *rxlength = read_length; - return ATCA_SUCCESS; - } - - /*Calculate bytes to read based on device response*/ - if (cfg->devtype == TA100) - { - read_length = ((uint16_t)rxdata[0] * 256) + rxdata[1]; - min_resp_size += 1; - } - else - { - read_length = rxdata[0]; - } - - if (read_length > rxdata_max_size) - { - close(f_i2c); - return ATCA_SMALL_BUFFER; - } - - if (read_length < min_resp_size) - { - close(f_i2c); - return ATCA_RX_FAIL; - } - - // Receive data - if (read(f_i2c, &rxdata[2], read_length - 2) != read_length - 2) - { - close(f_i2c); - return ATCA_COMM_FAIL; - } - - *rxlength = read_length; - close(f_i2c); return ATCA_SUCCESS; } -/** \brief method to change the bus speed of I2C.This function is not used in Linux. - * \param[in] iface interface on which to change bus speed - * \param[in] speed baud rate (typically 100000 or 400000) - */ - -void change_i2c_speed(ATCAIface iface, uint32_t speed) -{ - -} - -/** \brief wake up CryptoAuth device using I2C bus - * \param[in] iface interface to logical device to wakeup +/** \brief Perform control operations for the kit protocol + * \param[in] iface Interface to interact with. + * \param[in] option Control parameter identifier + * \param[in] param Optional pointer to parameter value + * \param[in] paramlen Length of the parameter * \return ATCA_SUCCESS on success, otherwise an error code. */ - -ATCA_STATUS hal_i2c_wake(ATCAIface iface) +ATCA_STATUS hal_i2c_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { - ATCAIfaceCfg *cfg = atgetifacecfg(iface); - ATCAI2CMaster_t * hal_data = (ATCAI2CMaster_t*)atgetifacehaldat(iface); - int f_i2c; // I2C file descriptor - uint8_t data[4]; - uint8_t dummy_byte = 0x00; - - // Initiate I2C communication - if ( (f_i2c = open(hal_data->i2c_file, O_RDWR)) < 0) - { - return ATCA_COMM_FAIL; - } - - // Send the wake by writing to an address of 0x00 - // Create wake up pulse by sending a slave address 0f 0x00. - // This slave address is sent to device by using a dummy write command. - if (ioctl(f_i2c, I2C_SLAVE, 0x00) < 0) - { - close(f_i2c); - return ATCA_COMM_FAIL; - } + (void)param; + (void)paramlen; - // Dummy Write - if (write(f_i2c, &dummy_byte, 1) < 0) + if (iface && iface->mIfaceCFG) { - // This command will always return NACK. - // So, the return code is being ignored. + /* This HAL does not support any of the control functions */ + return ATCA_UNIMPLEMENTED; } - - atca_delay_us(cfg->wake_delay); // wait tWHI + tWLO which is configured based on device type and configuration structure - - // Set Slave Address - if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0) - { - close(f_i2c); - return ATCA_COMM_FAIL; - } - - // Receive data - if (read(f_i2c, data, 4) != 4) - { - close(f_i2c); - return ATCA_RX_NO_RESPONSE; - } - - close(f_i2c); - // if necessary, revert baud rate to what came in. - - return hal_check_wake(data, 4); -} - -/** \brief idle CryptoAuth device using I2C bus - * \param[in] iface interface to logical device to idle - * \return ATCA_SUCCESS on success, otherwise an error code. - */ - -ATCA_STATUS hal_i2c_idle(ATCAIface iface) -{ - ATCAIfaceCfg *cfg = atgetifacecfg(iface); - ATCAI2CMaster_t * hal_data = (ATCAI2CMaster_t*)atgetifacehaldat(iface); - uint8_t data = 0x02; // idle word address value - int f_i2c; // I2C file descriptor - - // Initiate I2C communication - if ( (f_i2c = open(hal_data->i2c_file, O_RDWR) ) < 0) - { - return ATCA_COMM_FAIL; - } - - // Set Slave Address - if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0) - { - close(f_i2c); - return ATCA_COMM_FAIL; - } - - // Send data - if (write(f_i2c, &data, 1) != 1) - { - close(f_i2c); - return ATCA_COMM_FAIL; - } - - close(f_i2c); - return ATCA_SUCCESS; -} - -/** \brief sleep CryptoAuth device using I2C bus - * \param[in] iface interface to logical device to sleep - * \return ATCA_SUCCESS on success, otherwise an error code. - */ - -ATCA_STATUS hal_i2c_sleep(ATCAIface iface) -{ - ATCAIfaceCfg *cfg = atgetifacecfg(iface); - ATCAI2CMaster_t * hal_data = (ATCAI2CMaster_t*)atgetifacehaldat(iface); - uint8_t data = 0x01; // sleep word address value - int f_i2c; // I2C file descriptor - - // Initiate I2C communication - if ( (f_i2c = open(hal_data->i2c_file, O_RDWR)) < 0) - { - return ATCA_COMM_FAIL; - } - - // Set Slave Address - if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.slave_address >> 1) < 0) - { - close(f_i2c); - return ATCA_COMM_FAIL; - } - - // Send data - if (write(f_i2c, &data, 1) != 1) - { - close(f_i2c); - return ATCA_COMM_FAIL; - } - - close(f_i2c); - return ATCA_SUCCESS; + return ATCA_BAD_PARAM; } /** \brief manages reference count on given bus and releases resource if no more refences exist @@ -428,7 +218,7 @@ ATCA_STATUS hal_i2c_sleep(ATCAIface iface) ATCA_STATUS hal_i2c_release(void *hal_data) { - ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*)hal_data; + atca_i2c_host_t *hal = (atca_i2c_host_t*)hal_data; // if the use count for this bus has gone to 0 references, disable it. protect against an unbracketed release if (hal && --(hal->ref_ct) <= 0) diff --git a/lib/hal/hal_linux_i2c_userspace.h b/lib/hal/hal_linux_i2c_userspace.h deleted file mode 100644 index 137624f59..000000000 --- a/lib/hal/hal_linux_i2c_userspace.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * \file - * \brief ATCA Hardware abstraction layer for Linux using I2C. - * - * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. - * - * \page License - * - * Subject to your compliance with these terms, you may use Microchip software - * and any derivatives exclusively with Microchip products. It is your - * responsibility to comply with third party license terms applicable to your - * use of third party software (including open source software) that may - * accompany Microchip software. - * - * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER - * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED - * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, - * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE - * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF - * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE - * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL - * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED - * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR - * THIS SOFTWARE. - */ - -#ifndef HAL_LINUX_I2C_USERSPACE_H_ -#define HAL_LINUX_I2C_USERSPACE_H_ - -/** \defgroup hal_ Hardware abstraction layer (hal_) - * - * \brief - * These methods define the hardware abstraction layer for communicating with a CryptoAuth device - * - @{ */ - -#define MAX_I2C_BUSES 2 // Raspberry Pi has 2 TWI - -// A structure to hold I2C information -typedef struct atcaI2Cmaster -{ - char i2c_file[16]; - int ref_ct; -} ATCAI2CMaster_t; - -/** @} */ - -#endif /* HAL_LINUX_I2C_H_ */ diff --git a/lib/hal/hal_linux_spi_userspace.c b/lib/hal/hal_linux_spi_userspace.c index 004591951..b69719081 100644 --- a/lib/hal/hal_linux_spi_userspace.c +++ b/lib/hal/hal_linux_spi_userspace.c @@ -1,30 +1,17 @@ /**/ #include "cryptoauthlib.h" #include "atca_hal.h" -#include "hal_linux_spi_userspace.h" #include #include #include #include - -ATCA_STATUS hal_spi_discover_buses(int spi_buses[], int max_buses) -{ - return ATCA_UNIMPLEMENTED; -} - -/** \brief discover any TA100 devices on a given logical bus number - * \param[in] bus_num logical bus number on which to look for TA100 devices - * \param[out] cfg pointer to head of an array of interface config structures which get filled in by this method - * \param[out] found number of devices found on this bus - * \return ATCA_SUCCESS - */ - -ATCA_STATUS hal_spi_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found) +typedef struct atca_spi_host_s { - return ATCA_UNIMPLEMENTED; -} + char spi_file[20]; + int f_spi; +} atca_spi_host_t; /** \brief Open and configure the SPI device * \param[in] dev_name File name in the form /dev/spidevX.Y @@ -83,43 +70,35 @@ ATCA_STATUS hal_spi_open_file(const char * dev_name, uint32_t speed, int * fd) * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_spi_init(void *hal, ATCAIfaceCfg *cfg) +ATCA_STATUS hal_spi_init(ATCAIface iface, ATCAIfaceCfg *cfg) { int f_spi; - ATCAHAL_t *pHal = (ATCAHAL_t*)hal; - ATCA_STATUS status = ATCA_SUCCESS; + ATCA_STATUS status = ATCA_BAD_PARAM; - if (!pHal || !cfg) - { - status = ATCA_BAD_PARAM; - } - else + if (iface && cfg) { - if (pHal->hal_data) - { - ATCASPIMaster_t * hal_data = (ATCASPIMaster_t*)pHal->hal_data; - - // Assume the bus had already been initialized - hal_data->ref_ct++; - } - else + if (!iface->hal_data) { - ATCASPIMaster_t * hal_data = malloc(sizeof(ATCASPIMaster_t)); + atca_spi_host_t * hal_data = malloc(sizeof(atca_spi_host_t)); if (hal_data) { - hal_data->ref_ct = 1; // buses are shared, this is the first instance - (void)snprintf(hal_data->spi_file, sizeof(hal_data->spi_file) - 1, "/dev/spidev%d.%d", (uint8_t)cfg->atcaspi.bus, (uint8_t)cfg->atcaspi.select_pin); - pHal->hal_data = hal_data; + iface->hal_data = hal_data; + status = ATCA_SUCCESS; } else { status = ATCA_ALLOC_FAILURE; } } + else + { + status = ATCA_SUCCESS; + } + } return status; } @@ -129,6 +108,50 @@ ATCA_STATUS hal_spi_post_init(ATCAIface iface) return ATCA_SUCCESS; } + +/** \brief HAL implementation to assert the device chip select + * \param[in] iface Device to interact with. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_spi_select(ATCAIface iface) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + atca_spi_host_t * hal_data = (atca_spi_host_t*)atgetifacehaldat(iface); + + if (hal_data && cfg) + { + return hal_spi_open_file(hal_data->spi_file, cfg->atcaspi.baud, &hal_data->f_spi); + } + else + { + return ATCA_BAD_PARAM; + } +} + + +/** \brief HAL implementation to deassert the device chip select + * \param[in] iface Device to interact with. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_spi_deselect(ATCAIface iface) +{ + atca_spi_host_t * hal_data = (atca_spi_host_t*)atgetifacehaldat(iface); + + if (hal_data) + { + struct spi_ioc_transfer spi_xfer = { 0 }; + + (void)ioctl(hal_data->f_spi, SPI_IOC_MESSAGE(1), &spi_xfer); + + return close(hal_data->f_spi); + } + else + { + return ATCA_BAD_PARAM; + } +} + + /** \brief HAL implementation of SPI receive function * \param[in] iface Device to interact with. * \param[in] word_address device transaction type @@ -137,81 +160,27 @@ ATCA_STATUS hal_spi_post_init(ATCAIface iface) * As output, the number of bytes received. * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_spi_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *len) +ATCA_STATUS hal_spi_receive(ATCAIface iface, uint8_t flags, uint8_t *rxdata, uint16_t *rxlength) { int f_spi; - uint8_t response_len[3] = { 0 }; - uint16_t read_length = 2u; //to read length bytes - uint16_t rx_max_data = *len; ATCA_STATUS status = ATCA_BAD_PARAM; - ATCAIfaceCfg *cfg = atgetifacecfg(iface); - ATCASPIMaster_t * hal_data = (ATCASPIMaster_t*)atgetifacehaldat(iface); - - struct spi_ioc_transfer spi_xfer = { 0 }; + atca_spi_host_t * hal_data = (atca_spi_host_t*)atgetifacehaldat(iface); - *len = 0; - rxdata[0] = word_address; - - if (hal_data && cfg) + if (hal_data) { - status = hal_spi_open_file(hal_data->spi_file, cfg->atcaspi.baud, &f_spi); - } + struct spi_ioc_transfer spi_xfer = { 0 }; + spi_xfer.rx_buf = (unsigned long)rxdata; + spi_xfer.len = *rxlength; + spi_xfer.cs_change = true; - if (status == ATCA_SUCCESS) - { - /*check for READ_CSR or RD_FSR transaction*/ - if ((0x30 == word_address) || (0xB0 == word_address )) + if (*rxlength == ioctl(hal_data->f_spi, SPI_IOC_MESSAGE(1), &spi_xfer)) { - read_length = 1; + status = ATCA_SUCCESS; } - - spi_xfer.tx_buf = (unsigned long)rxdata; - spi_xfer.rx_buf = (unsigned long)response_len; - spi_xfer.len = read_length + 1; - - if (ioctl(f_spi, SPI_IOC_MESSAGE(1), &spi_xfer) == 1) + else { status = ATCA_COMM_FAIL; } - - if (status == ATCA_SUCCESS) - { - *rxdata = response_len[1]; - if (read_length == 2u) //if length bytes are read - { - read_length = response_len[1] << 8; - read_length |= response_len[2]; - - if (read_length >= ATCA_RSP_SIZE_MIN) - { - if (read_length <= rx_max_data) - { - rxdata[0] = word_address; - spi_xfer.tx_buf = (unsigned long)rxdata; - spi_xfer.rx_buf = (unsigned long)(rxdata + 1); - spi_xfer.len = read_length - 1; - - if (ioctl(f_spi, SPI_IOC_MESSAGE(1), &spi_xfer) == 1) - { - status = ATCA_COMM_FAIL; - } - - *rxdata = response_len[1]; - *(rxdata + 1) = response_len[2]; - } - else - { - status = ATCA_SMALL_BUFFER; - } - } - else - { - status = ATCA_INVALID_SIZE; - } - } - *len = read_length; - } - close(f_spi); } return status; } @@ -226,122 +195,72 @@ ATCA_STATUS hal_spi_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxda * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_spi_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int len) +ATCA_STATUS hal_spi_send(ATCAIface iface, uint8_t flags, uint8_t *txdata, int txlen) { int f_spi; ATCA_STATUS status = ATCA_SUCCESS; - ATCAIfaceCfg *cfg = atgetifacecfg(iface); - ATCASPIMaster_t * hal_data = (ATCASPIMaster_t*)atgetifacehaldat(iface); - - if (hal_data && cfg) - { - status = hal_spi_open_file(hal_data->spi_file, cfg->atcaspi.baud, &f_spi); - } - - if (status == ATCA_SUCCESS) - { - txdata[0] = word_address; - - status = (write(f_spi, txdata, len + 1) != (len + 1)) ? ATCA_COMM_FAIL : ATCA_SUCCESS; - - close(f_spi); - } - return status; -} - -/** \brief wake up CryptoAuth device using SPI bus - * \param[in] iface interface to logical device to wakeup - * \return ATCA_SUCCESS on success, otherwise an error code. - */ - -ATCA_STATUS hal_spi_wake(ATCAIface iface) -{ - ATCAIfaceCfg *cfg = atgetifacecfg(iface); - ATCA_STATUS status = ATCA_SUCCESS; - uint16_t len = 1u; // sleep command packet length - uint8_t word_address = 0x30u; // word address indicating RD_CSR - uint8_t csr_reg; - int delay_timeout = (int)cfg->wake_delay; - + atca_spi_host_t * hal_data = (atca_spi_host_t*)atgetifacehaldat(iface); + int ret; - do + if (hal_data) { - status = hal_spi_receive(iface, word_address, &csr_reg, &len); + struct spi_ioc_transfer spi_xfer = { 0 }; + spi_xfer.tx_buf = (unsigned long)txdata; + spi_xfer.len = txlen; + spi_xfer.cs_change = true; - if (status == ATCA_SUCCESS) + if (txlen == ioctl(hal_data->f_spi, SPI_IOC_MESSAGE(1), &spi_xfer)) { -#ifdef ATCA_TA100_SUPPORT - /*status bit check in CSR register*/ - if ((len == 1) && (((csr_reg >> 1) & 0x03 ) != 0x03)) - { - status = ATCA_SUCCESS; - /*self test bit check*/ - if (csr_reg & 0x01) - { - status = TA_SELF_TEST_FAILURE; - } - - break; - } -#else - break; -#endif - + status = ATCA_SUCCESS; + } + else + { + status = ATCA_COMM_FAIL; } - /*poll csr register for every 100us*/ - atca_delay_us(100); - delay_timeout = delay_timeout - 100; - - } - while (delay_timeout > 0); - - if (delay_timeout < 0) - { - status = ATCA_TIMEOUT; } return status; } -/** \brief idle TA100 device using SPI bus - * \param[in] iface interface to logical device to idle - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS hal_spi_idle(ATCAIface iface) -{ - return ATCA_UNIMPLEMENTED; -} - -/** \brief sleep TA100 device using SPI bus - * \param[in] iface interface to logical device to sleep +/** \brief Perform control operations for the kit protocol + * \param[in] iface Interface to interact with. + * \param[in] option Control parameter identifier + * \param[in] param Optional pointer to parameter value + * \param[in] paramlen Length of the parameter * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_spi_sleep(ATCAIface iface) +ATCA_STATUS hal_spi_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { + (void)param; + (void)paramlen; - uint16_t len = 10u; // sleep command packet length - uint8_t word_address = 0x00u; // word address indicating WR_command - /*2byte -length , opcode,mode,param2,crc*/ - uint8_t sleep_cmd[10] = { 0x00, 0x0a, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xc1 }; - - return hal_spi_send(iface, word_address, sleep_cmd, len); - + if (iface && iface->mIfaceCFG) + { + switch (option) + { + case ATCA_HAL_CONTROL_SELECT: + return hal_spi_select(iface); + case ATCA_HAL_CONTROL_DESELECT: + return hal_spi_deselect(iface); + default: + return ATCA_UNIMPLEMENTED; + } + } + return ATCA_BAD_PARAM; } /** \brief manages reference count on given bus and releases resource if no more refences exist * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation * \return ATCA_SUCCESS on success, otherwise an error code. */ - - ATCA_STATUS hal_spi_release(void *hal_data) { - ATCASPIMaster_t *hal = (ATCASPIMaster_t*)hal_data; + atca_spi_host_t *hal = (atca_spi_host_t*)hal_data; - // if the use count for this bus has gone to 0 references, disable it. protect against an unbracketed release - if (hal && --(hal->ref_ct) <= 0) + if (hal) { + close(hal->f_spi); free(hal); } diff --git a/lib/hal/hal_linux_spi_userspace.h b/lib/hal/hal_linux_spi_userspace.h deleted file mode 100644 index a5e275696..000000000 --- a/lib/hal/hal_linux_spi_userspace.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * \file - * \brief ATCA Hardware abstraction layer for Linux using SPI. - * - * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. - * - * \page License - * - * Subject to your compliance with these terms, you may use Microchip software - * and any derivatives exclusively with Microchip products. It is your - * responsibility to comply with third party license terms applicable to your - * use of third party software (including open source software) that may - * accompany Microchip software. - * - * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER - * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED - * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, - * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE - * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF - * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE - * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL - * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED - * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR - * THIS SOFTWARE. - */ - -#ifndef HAL_LINUX_SPI_USERSPACE_H_ -#define HAL_LINUX_SPI_USERSPACE_H_ - -/** \defgroup hal_ Hardware abstraction layer (hal_) - * - * \brief - * These methods define the hardware abstraction layer for communicating with a CryptoAuth device - * - @{ */ - -#define MAX_SPI_BUSES 2 // Raspberry Pi & SAMA5D2-XULT has 2 SPI - -// A structure to hold I2C information -typedef struct atcaSPImaster -{ - char spi_file[20]; - int ref_ct; -} ATCASPIMaster_t; - -/** @} */ - -#endif /* HAL_LINUX_SPI_USERSPACE_H_ */ diff --git a/lib/hal/hal_sam0_i2c_asf.c b/lib/hal/hal_sam0_i2c_asf.c index 259ff7787..c48b30c53 100644 --- a/lib/hal/hal_sam0_i2c_asf.c +++ b/lib/hal/hal_sam0_i2c_asf.c @@ -37,6 +37,10 @@ #include "hal_sam0_i2c_asf.h" #include "cryptoauthlib.h" +#ifndef ATCA_HAL_LEGACY_API +#error "The use of this hal requires the ATCA_HAL_LEGACY_API option to be enabled. +#endif + /** \defgroup hal_ Hardware abstraction layer (hal_) * * \brief diff --git a/lib/hal/hal_sam_i2c_asf.c b/lib/hal/hal_sam_i2c_asf.c index f84786e8c..542c8fe72 100644 --- a/lib/hal/hal_sam_i2c_asf.c +++ b/lib/hal/hal_sam_i2c_asf.c @@ -36,6 +36,9 @@ #include "cryptoauthlib.h" #include "hal_sam_i2c_asf.h" +#ifndef ATCA_HAL_LEGACY_API +#error "The use of this hal requires the ATCA_HAL_LEGACY_API option to be enabled. +#endif //!< Uncomment when debugging /*#define DEBUG_HAL*/ diff --git a/lib/hal/hal_spi_harmony.c b/lib/hal/hal_spi_harmony.c index 77deedd43..e7aaf763c 100644 --- a/lib/hal/hal_spi_harmony.c +++ b/lib/hal/hal_spi_harmony.c @@ -38,6 +38,7 @@ #include "atca_device.h" #include "definitions.h" #include "talib/talib_defines.h" +#include "talib/talib_fce.h" /** \defgroup hal_ Hardware abstraction layer (hal_) * @@ -108,7 +109,7 @@ static ATCA_STATUS hal_spi_wait(atca_plib_spi_api_t * plib, uint32_t rate, uint1 * \param[in] cfg - interface configuration * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_spi_init(void *hal, ATCAIfaceCfg *cfg) +ATCA_STATUS hal_spi_init(ATCAIface iface, ATCAIfaceCfg *cfg) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -137,6 +138,51 @@ ATCA_STATUS hal_spi_post_init(ATCAIface iface) return ATCA_SUCCESS; } +/** \brief HAL implementation to assert the device chip select + * \param[in] iface Device to interact with. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_spi_select(ATCAIface iface) +{ + ATCAIfaceCfg* cfg = atgetifacecfg(iface); + + if (cfg) + { + atca_plib_spi_api_t * plib = (atca_plib_spi_api_t*)cfg->cfg_data; + + plib->select(cfg->atcaspi.select_pin, 0); + + return ATCA_SUCCESS; + } + else + { + return ATCA_BAD_PARAM; + } +} + + +/** \brief HAL implementation to deassert the device chip select + * \param[in] iface Device to interact with. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_spi_deselect(ATCAIface iface) +{ + ATCAIfaceCfg* cfg = atgetifacecfg(iface); + + if (cfg) + { + atca_plib_spi_api_t * plib = (atca_plib_spi_api_t*)cfg->cfg_data; + + plib->select(cfg->atcaspi.select_pin, 1); + + return ATCA_SUCCESS; + } + else + { + return ATCA_BAD_PARAM; + } +} + /** \brief HAL implementation of SPI send over Harmony * \param[in] iface instance * \param[in] word_address device transaction type @@ -167,14 +213,6 @@ ATCA_STATUS hal_spi_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, do { - if (0xFF != word_address) - { - txdata[0] = word_address; // insert the Word Address Value, Command token - txlength++; // account for word address value byte. - } - - plib->select(cfg->atcaspi.select_pin, 0); - /* Wait for the SPI bus to be ready */ if (ATCA_SUCCESS != (status = hal_spi_wait(plib, cfg->atcaspi.baud, 0)) ) { @@ -193,7 +231,6 @@ ATCA_STATUS hal_spi_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, } while (0); - plib->select(cfg->atcaspi.select_pin, 1); return status; } @@ -209,8 +246,6 @@ ATCA_STATUS hal_spi_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxda { ATCA_STATUS status = ATCA_COMM_FAIL; ATCAIfaceCfg* cfg = atgetifacecfg(iface); - uint16_t rxdata_max_size; - uint16_t read_length = 2; atca_plib_spi_api_t * plib; if ((NULL == cfg) || (NULL == rxlength) || (NULL == rxdata)) @@ -223,122 +258,42 @@ ATCA_STATUS hal_spi_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxda return ATCA_TRACE(ATCA_INVALID_POINTER, "NULL pointer encountered"); } - rxdata_max_size = *rxlength; - *rxlength = 0; - - do + /* read status register/length bytes to know number of bytes to read */ + status = ATCA_COMM_FAIL; + if (true == plib->read(rxdata, *rxlength) ) { - - /*Set read length.. Check for register reads or 1 byte reads*/ - if ((ATCA_MAIN_PROCESSOR_RD_CSR == word_address) || (ATCA_FAST_CRYPTO_RD_FSR == word_address ) - || ( 1 == rxdata_max_size)) - { - read_length = 1; - } - - plib->select(cfg->atcaspi.select_pin, 0); - - /*Send Word address to device...*/ - if (true == plib->write(&word_address, sizeof(word_address))) - { - /* Wait for the SPI transfer to complete */ - status = hal_spi_wait(plib, cfg->atcaspi.baud, sizeof(word_address)); - - } - if (ATCA_SUCCESS != status) - { - ATCA_TRACE(status, "plib->write - failed"); - break; - } - - /* read status register/length bytes to know number of bytes to read */ - status = ATCA_COMM_FAIL; - if (true == plib->read(rxdata, read_length) ) - { - /* Wait for the SPI transfer to complete */ - status = hal_spi_wait(plib, cfg->atcaspi.baud, read_length); - - } - if (ATCA_SUCCESS != status) - { - ATCA_TRACE(status, "plib->read - failed"); - break; - } - - if (1 == read_length) - { - ATCA_TRACE(status, "1 byte read completed"); - break; - } - - /*Calculate bytes to read based on device response*/ - read_length = ((uint16_t)rxdata[0] * 256) + rxdata[1]; - - if (read_length > rxdata_max_size) - { - status = ATCA_TRACE(ATCA_SMALL_BUFFER, "rxdata is small buffer"); - break; - } - - if (read_length < 5) - { - status = ATCA_TRACE(ATCA_RX_FAIL, "packet size is invalid"); - break; - } - - /* Read given length bytes from device */ - status = ATCA_COMM_FAIL; - if (true == plib->read(&rxdata[2], read_length - 2)) - { - /* Wait for the SPI transfer to complete */ - status = hal_spi_wait(plib, cfg->atcaspi.baud, read_length - 2); - - } - if (ATCA_SUCCESS != status) - { - ATCA_TRACE(status, "plib->read - failed"); - break; - } - + /* Wait for the SPI transfer to complete */ + status = hal_spi_wait(plib, cfg->atcaspi.baud, *rxlength); } - while (0); - - plib->select(cfg->atcaspi.select_pin, 1); - *rxlength = read_length; return status; } - - -/** \brief wake up TA100 device using SPI bus - * \param[in] iface interface to logical device to wakeup +/** \brief Perform control operations for the kit protocol + * \param[in] iface Interface to interact with. + * \param[in] option Control parameter identifier + * \param[in] param Optional pointer to parameter value + * \param[in] paramlen Length of the parameter * \return ATCA_SUCCESS on success, otherwise an error code. */ - -ATCA_STATUS hal_spi_wake(ATCAIface iface) +ATCA_STATUS hal_spi_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { - return ATCA_UNIMPLEMENTED; -} - -/** \brief idle TA100 device using SPI bus - * \param[in] iface interface to logical device to idle - * \return ATCA_SUCCESS on success, otherwise an error code. - */ + (void)param; + (void)paramlen; -ATCA_STATUS hal_spi_idle(ATCAIface iface) -{ - return ATCA_UNIMPLEMENTED; -} - -/** \brief sleep TA100 device using SPI bus - * \param[in] iface interface to logical device to sleep - * \return ATCA_SUCCESS on success, otherwise an error code. - */ - -ATCA_STATUS hal_spi_sleep(ATCAIface iface) -{ - return ATCA_UNIMPLEMENTED; + if (iface && iface->mIfaceCFG) + { + switch (option) + { + case ATCA_HAL_CONTROL_SELECT: + return hal_spi_select(iface); + case ATCA_HAL_CONTROL_DESELECT: + return hal_spi_deselect(iface); + default: + return ATCA_UNIMPLEMENTED; + } + } + return ATCA_BAD_PARAM; } /** \brief manages reference count on given bus and releases resource if no more refences exist diff --git a/lib/hal/hal_swi_bitbang_harmony.c b/lib/hal/hal_swi_bitbang_harmony.c new file mode 100644 index 000000000..b709a8aea --- /dev/null +++ b/lib/hal/hal_swi_bitbang_harmony.c @@ -0,0 +1,588 @@ +/** + * \file + * \brief ATCA Hardware abstraction layer for SWI bit banging. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "cryptoauthlib.h" +#include "atca_config.h" + +/** + * \defgroup hal_ Hardware abstraction layer (hal_) + * + * \brief These methods define the hardware abstraction layer for + * communicating with a CryptoAuth device using SWI bit banging. + @{ */ + +/** \brief discover swi buses available for this hardware + * this maintains a list of logical to physical bus mappings freeing the application.This function is currently not supported. + * of the a-priori knowledge + * \param[in] swi_buses - an array of logical bus numbers + * \param[in] max_buses - maximum number of buses the app wants to attempt to discover + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS hal_swi_discover_buses(int swi_buses[], int max_buses) +{ + return ATCA_UNIMPLEMENTED; +} + +/** \brief discover any CryptoAuth devices on a given logical bus number.This function is curently not supported. + * \param[in] bus_num - logical bus number on which to look for CryptoAuth devices + * \param[out] cfg[] - pointer to head of an array of interface config structures which get filled in by this method + * \param[out] *found - number of devices found on this bus + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS hal_swi_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found) +{ + return ATCA_UNIMPLEMENTED; +} + +/** + * \brief Send a Wake Token. + */ +static ATCA_STATUS swi_send_wake_token(atca_plib_swi_bb_api_t* plib, uint8_t pin) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (plib) + { +#ifdef __arm__ + __disable_irq(); +#else + __builtin_disable_interrupts(); +#endif + + plib->write(pin, false); + atca_delay_us(60); + plib->write(pin, true); + status = ATCA_SUCCESS; + +#ifdef __arm__ + __enable_irq(); +#else + __builtin_enable_interrupts(); +#endif + } + + return status; +} + +/** + * \brief Send a number of bytes.This function should not be called directly ,instead should use hal_swi_send() which call this function. + * + * \param[in] count number of bytes to send. + * \param[in] buffer pointer to buffer containing bytes to send + */ +static ATCA_STATUS swi_send_bytes(atca_plib_swi_bb_api_t* plib, uint8_t pin, uint8_t count, + uint8_t *buffer) +{ + uint8_t i, bit_mask; + + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + //set port direction to output + plib->set_pin_output_dir(pin); + +#ifdef __arm__ + __disable_irq(); +#else + __builtin_disable_interrupts(); +#endif + for (i = 0; i < count; i++) + { + for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) + { + if (bit_mask & buffer[i]) //!< Send Logic 1 (7F) + { + plib->write(pin, false); + BIT_DELAY_1L; + plib->write(pin, true); + BIT_DELAY_7; + } + else //!< Send Logic 0 (7D) + { + plib->write(pin, false); + BIT_DELAY_1L; + plib->write(pin, true); + BIT_DELAY_1H; + plib->write(pin, false); + BIT_DELAY_1L; + plib->write(pin, true); + BIT_DELAY_5; + } + } + } +#ifdef __arm__ + __enable_irq(); +#else + __builtin_enable_interrupts(); +#endif + + return ATCA_SUCCESS; +} + +/** + * \brief Send one byte. + * + * \param[in] byte byte to send + */ +static ATCA_STATUS swi_send_byte(atca_plib_swi_bb_api_t* plib, uint8_t pin, uint8_t byte) +{ + return swi_send_bytes(plib, pin, 1, &byte); +} + +/** + * \brief Receive one bit as byte using SWI bitbang + * \param[in] bit_data byte equivalent of bit data on SWI + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS swi_receive_bit(atca_plib_swi_bb_api_t* plib, uint8_t pin, uint8_t *bit_data) +{ + int8_t timeout_count; + bool current_state = true, prev_state = true; + uint8_t bit_count = 0; + ATCA_STATUS status = ATCA_SUCCESS; + + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + do + { + //wait for start bit + timeout_count = 90 / 2; + while (timeout_count-- >= 0) + { + current_state = plib->read(pin); + if (current_state != prev_state) + { + prev_state = current_state; + if (!current_state) + { + break; + } + + } + atca_delay_us(2); + } + + if (timeout_count <= 0) + { + status = ATCA_TRACE(ATCA_RX_NO_RESPONSE, "No response is received"); + break; + } + + //Read bit + timeout_count = 40 / 2; + while (timeout_count-- >= 0) + { + current_state = plib->read(pin); + if (current_state != prev_state) + { + prev_state = current_state; + if (current_state) + { + bit_count++; + } + + } + atca_delay_us(2); + } + + if (bit_count == 2) + { + *bit_data = 0; + } + else if (bit_count == 1) + { + *bit_data = 1; + } + else + { + status = ATCA_TRACE(ATCA_RX_FAIL, "Rx Receive - failed"); + } + } + while (0); + + return status; +} + +/** + * \brief Receive a number of bytes.This function should not be called directly ,instead should use hal_swi_receive() which call this function. + * + * \param[in] count number of bytes to receive + * \param[out] buffer pointer to receive buffer + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS swi_receive_bytes(atca_plib_swi_bb_api_t* plib, uint8_t pin, uint8_t count, + uint8_t *buffer) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t i; + uint8_t bit_mask, bit_data; + + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + //set port direction to input to receive response + plib->set_pin_input_dir(pin); + +#ifdef __arm__ + __disable_irq(); +#else + __builtin_disable_interrupts(); +#endif + //! Receive bits and store in buffer. + for (i = 0; i < count; i++) + { + *buffer = 0; + for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) + { + bit_data = 0; + if (ATCA_SUCCESS != (status = swi_receive_bit(plib, pin, &bit_data))) + { + break; + } + + + if (bit_data == 1) + { + *buffer |= bit_mask; + } + + } + + if (status != ATCA_SUCCESS) + { + break; + } + + + if (i == 0) + { + if (*buffer < ATCA_RSP_SIZE_MIN) + { + status = ATCA_TRACE(ATCA_RX_FAIL, "packet size is invalid"); + break; + } + else if (*buffer > count) + { + status = ATCA_TRACE(ATCA_SMALL_BUFFER, "rxdata is small buffer"); + break; + } + else + { + count = *buffer; + status = ATCA_SUCCESS; + } + } + buffer++; + } + +#ifdef __arm__ + __enable_irq(); +#else + __builtin_enable_interrupts(); +#endif + RX_TX_DELAY; + + return status; +} + +/** + * \brief hal_swi_init manages requests to initialize a physical + * interface. It manages use counts so when an interface has + * released the physical layer, it will disable the interface for + * some other use. You can have multiple ATCAIFace instances using + * the same bus, and you can have multiple ATCAIFace instances on + * multiple swi buses, so hal_swi_init manages these things and + * ATCAIFace is abstracted from the physical details. + */ + +/** + * \brief Initialize an SWI interface using given config. + * + * \param[in] hal opaque pointer to HAL data + * \param[in] cfg interface configuration + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_swi_init(void *hal, ATCAIfaceCfg *cfg) +{ + atca_plib_swi_bb_api_t* plib = NULL; + + if (cfg == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + plib = (atca_plib_swi_bb_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + // Set crypto pin direction as output + plib->set_pin_output_dir(cfg->atcaswi.bus); + + // Set the crypto pin + plib->write(cfg->atcaswi.bus, true); + + return ATCA_SUCCESS; +} + +/** + * \brief HAL implementation of SWI post init. + * + * \param[in] iface ATCAIface instance + * + * \return ATCA_SUCCESS + */ +ATCA_STATUS hal_swi_post_init(ATCAIface iface) +{ + return ATCA_SUCCESS; +} + +/** + * \brief Send byte(s) via SWI. + * + * \param[in] iface interface of the logical device to send data to + * \param[in] word_address device transaction type + * \param[in] txdata pointer to bytes to send + * \param[in] txlength number of bytes to send + * \return ATCA_SUCCESS + */ +ATCA_STATUS hal_swi_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + ATCA_STATUS status = ATCA_COMM_FAIL; + atca_plib_swi_bb_api_t* plib = NULL; + + if ((cfg == NULL) || (txdata == NULL) || (txlength < 1)) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + plib = (atca_plib_swi_bb_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + (void)word_address; + + //! Send Command Flag + if ((status = swi_send_byte(plib, cfg->atcaswi.bus, SWI_FLAG_CMD)) == ATCA_SUCCESS) + { + //! Skip the Word Address data as SWI doesn't use it + txdata++; + + //! Send the remaining bytes + status = swi_send_bytes(plib, cfg->atcaswi.bus, txlength, txdata); + } + + return status; +} + +/** + * \brief Receive byte(s) via SWI. + * \param[in] iface Device to interact with. + * \param[in] word_address device transaction type + * \param[out] rxdata Data received will be returned here. + * \param[in,out] rxlength As input, the size of the rxdata buffer. + * As output, the number of bytes received. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_swi_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + ATCA_STATUS status = ATCA_COMM_FAIL; + int retries; + uint16_t rxdata_max_size; + atca_plib_swi_bb_api_t* plib = NULL; + + if ((cfg == NULL) || (rxdata == NULL) || (rxlength == NULL) || (*rxlength < 1)) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + plib = (atca_plib_swi_bb_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + (void)word_address; + retries = cfg->rx_retries; + rxdata_max_size = *rxlength; + *rxlength = 0; + do + { + while (retries-- > 0 && status != ATCA_SUCCESS) + { + if ((status = swi_send_byte(plib, cfg->atcaswi.bus, SWI_FLAG_TX)) == ATCA_SUCCESS) + { + status = swi_receive_bytes(plib, cfg->atcaswi.bus, rxdata_max_size, rxdata); + } + } + + if (status != ATCA_SUCCESS) + { + break; + } + + *rxlength = rxdata[0]; + + } + while (0); + + + return status; +} + +/** + * \brief Send Wake flag via SWI. + * + * \param[in] iface interface of the logical device to wake up + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_swi_wake(ATCAIface iface) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + ATCA_STATUS status = ATCA_WAKE_FAILED; + uint8_t data[4] = { 0x00, 0x00, 0x00, 0x00 }; + uint16_t rxlength = sizeof(data); + atca_plib_swi_bb_api_t* plib = NULL; + + if (cfg == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + plib = (atca_plib_swi_bb_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + do + { + //! Generate Wake Token + if (ATCA_SUCCESS != (status = swi_send_wake_token(plib, cfg->atcaswi.bus))) + { + break; + } + + //! Wait tWHI + tWLO + atca_delay_us(cfg->wake_delay); + + // Read Wake response + if (ATCA_SUCCESS != (status = hal_swi_receive(iface, 0x00, data, &rxlength))) + { + break; + } + + status = hal_check_wake(data, rxlength); + + } + while (0); + + return status; +} + +/** + * \brief Send Idle flag via SWI. + * + * \param[in] iface interface of the logical device to idle + * + * \return ATCA_SUCCES + */ +ATCA_STATUS hal_swi_idle(ATCAIface iface) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + atca_plib_swi_bb_api_t* plib = NULL; + + if (cfg == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + plib = (atca_plib_swi_bb_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + return swi_send_byte(plib, cfg->atcaswi.bus, SWI_FLAG_IDLE); +} + +/** + * \brief Send Sleep flag via SWI. + * + * \param[in] iface interface of the logical device to sleep + * + * \return ATCA_SUCCESS + */ +ATCA_STATUS hal_swi_sleep(ATCAIface iface) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + atca_plib_swi_bb_api_t* plib = NULL; + + if (cfg == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + plib = (atca_plib_swi_bb_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + return swi_send_byte(plib, cfg->atcaswi.bus, SWI_FLAG_SLEEP); +} + +/** + * \brief Manages reference count on given bus and releases resource if + * no more reference(s) exist. + * + * \param[in] hal_data opaque pointer to hal data structure - known only + * to the HAL implementation + * + * \return ATCA_SUCCESS + */ +ATCA_STATUS hal_swi_release(void *hal_data) +{ + return ATCA_SUCCESS; +} + +/** @} */ \ No newline at end of file diff --git a/lib/hal/hal_swi_uart.c b/lib/hal/hal_swi_uart.c index 4c250037c..352ce010b 100644 --- a/lib/hal/hal_swi_uart.c +++ b/lib/hal/hal_swi_uart.c @@ -25,12 +25,7 @@ * THIS SOFTWARE. */ -#include -#include -#include "atca_hal.h" -#include "hal_swi_uart.h" -#include "atca_device.h" -#include "calib/calib_execution.h" +#include "cryptoauthlib.h" /** \defgroup hal_ Hardware abstraction layer (hal_) * @@ -40,216 +35,14 @@ * @{ */ -/** \brief logical to physical bus mapping structure */ -static ATCASWIMaster_t swi_hal_data[MAX_SWI_BUSES]; // map logical, 0-based bus number to index - -#ifdef DEBUG_HAL -static void print_array(uint8_t *data, uint32_t data_size) -{ - // printf("%.4x\r\n", data_size); - - uint32_t n; - - for (n = 0; n < data_size; n++) - { - printf("%.2x ", data[n]); - if (((n + 1) % 16) == 0) - { - printf("\r\n"); - if ((n + 1) != data_size) - { - printf(" "); - } - } - } - if (data_size % 16 != 0) - { - printf("\r\n"); - } -} -#endif - - -/** \brief discover swi buses available for this hardware - * this maintains a list of logical to physical bus mappings freeing the application - * of the a-priori knowledge - * \param[in] swi_buses - an array of logical bus numbers - * \param[in] max_buses - maximum number of buses the app wants to attempt to discover - * \return ATCA_SUCCESS - */ - -ATCA_STATUS hal_swi_discover_buses(int swi_buses[], int max_buses) -{ - swi_uart_discover_buses(swi_buses, max_buses); - - return ATCA_SUCCESS; -} - -/** \brief discover any CryptoAuth devices on a given logical bus number - * \param[in] bus_num - logical bus number on which to look for CryptoAuth devices - * \param[out] cfg[] - pointer to head of an array of interface config structures which get filled in by this method - * \param[out] *found - number of devices found on this bus - * \return ATCA_SUCCESS - */ - -ATCA_STATUS hal_swi_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found) -{ - ATCAIfaceCfg *head = cfg; - ATCADevice device; - -#ifdef ATCA_NO_HEAP - struct atca_device disc_device; - struct atca_command disc_command; - struct atca_iface disc_iface; -#endif - ATCAPacket packet; - ATCA_STATUS status; - uint8_t revs608[][4] = { { 0x00, 0x00, 0x60, 0x01 }, { 0x00, 0x00, 0x60, 0x02 }, { 0x00, 0x00, 0x60, 0x03 } }; - uint8_t revs508[][4] = { { 0x00, 0x00, 0x50, 0x00 } }; - uint8_t revs108[][4] = { { 0x80, 0x00, 0x10, 0x01 } }; - uint8_t revs204[][4] = { { 0x00, 0x02, 0x00, 0x08 }, { 0x00, 0x02, 0x00, 0x09 }, { 0x00, 0x04, 0x05, 0x00 } }; - unsigned int i; - - /** \brief default configuration, to be reused during discovery process */ - ATCAIfaceCfg discoverCfg = { - .iface_type = ATCA_SWI_IFACE, - .devtype = ATECC508A, - .atcaswi.bus = bus_num, - .wake_delay = 800, - .rx_retries = 3 - }; - - if (bus_num < 0) - { - return ATCA_COMM_FAIL; - } - -#ifdef ATCA_NO_HEAP - disc_device.mCommands = &disc_command; - disc_device.mIface = &disc_iface; - status = initATCADevice(&discoverCfg, &disc_device); - if (status != ATCA_SUCCESS) - { - return status; - } - device = &disc_device; -#else - device = newATCADevice(&discoverCfg); - if (device == NULL) - { - return ATCA_COMM_FAIL; - } -#endif - - - memset(packet.data, 0x00, sizeof(packet.data)); - - // build an info command - packet.param1 = INFO_MODE_REVISION; - packet.param2 = 0; - atInfo(device->mCommands, &packet); - if ((status = atca_execute_command(&packet, device)) != ATCA_SUCCESS) - { - return status; - } - - // determine device type from common info and dev rev response byte strings... start with unknown - discoverCfg.devtype = ATCA_DEV_UNKNOWN; - - for (i = 0; i < (int)sizeof(revs608) / 4; i++) - { - if (memcmp(&packet.data[1], &revs608[i], 4) == 0) - { - discoverCfg.devtype = ATECC608; - break; - } - } - - for (i = 0; i < sizeof(revs508) / 4; i++) - { - if (memcmp(&packet.data[1], &revs508[i], 4) == 0) - { - discoverCfg.devtype = ATECC508A; - break; - } - } - - for (i = 0; i < sizeof(revs204) / 4; i++) - { - if (memcmp(&packet.data[1], &revs204[i], 4) == 0) - { - discoverCfg.devtype = ATSHA204A; - break; - } - } - - for (i = 0; i < sizeof(revs108) / 4; i++) - { - if (memcmp(&packet.data[1], &revs108[i], 4) == 0) - { - discoverCfg.devtype = ATECC108A; - break; - } - } - - if (discoverCfg.devtype != ATCA_DEV_UNKNOWN) - { - // now the device type is known, so update the caller's cfg array element with it - (*found)++; - memcpy( (uint8_t*)head, (uint8_t*)&discoverCfg, sizeof(ATCAIfaceCfg)); - head->devtype = discoverCfg.devtype; - head++; - } - - atca_delay_ms(15); - -#ifdef ATCA_NO_HEAP - releaseATCADevice(device); -#else - deleteATCADevice(&device); -#endif - - return ATCA_SUCCESS; -} - -/** \brief hal_swi_init manages requests to initialize a physical interface. it manages use counts so when an interface - * has released the physical layer, it will disable the interface for some other use. - * You can have multiple ATCAIFace instances using the same bus, and you can have multiple ATCAIFace instances on - * multiple swi buses, so hal_swi_init manages these things and ATCAIFace is abstracted from the physical details. - */ - /** \brief initialize an SWI interface using given config * \param[in] hal - opaque ptr to HAL data * \param[in] cfg - interface configuration * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_swi_init(void *hal, ATCAIfaceCfg *cfg) +ATCA_STATUS hal_swi_init(ATCAIface iface, ATCAIfaceCfg *cfg) { - if (cfg->atcaswi.bus >= MAX_SWI_BUSES) - { - return ATCA_COMM_FAIL; - } - ATCASWIMaster_t* data = &swi_hal_data[cfg->atcaswi.bus]; - - if (data->ref_ct <= 0) - { - // initialize the bus index - data->bus_index = cfg->atcaswi.bus; - - // initialize UART module for SWI interface - swi_uart_init(data); - - // buses are shared, this is the first instance - data->ref_ct = 1; - } - else - { - // Bus is already is use, increment reference counter - data->ref_ct++; - } - - ((ATCAHAL_t*)hal)->hal_data = data; return ATCA_SUCCESS; } @@ -264,34 +57,42 @@ ATCA_STATUS hal_swi_post_init(ATCAIface iface) return ATCA_SUCCESS; } -/** \brief HAL implementation of SWI send one byte over UART - * \param[in] iface instance - * \param[in] data bytes to send +/** + * \brief Receive one bit as byte using uart for SWI + * \param[in] bit_data byte equivalent of bit data on SWI * \return ATCA_SUCCESS on success, otherwise an error code. */ - -ATCA_STATUS hal_swi_send_flag(ATCAIface iface, uint8_t data) +static ATCA_STATUS hal_swi_uart_receive_bit(ATCAIface iface, uint8_t *bit_data) { - ATCA_STATUS status = ATCA_SUCCESS; - ATCAIfaceCfg *cfg = atgetifacecfg(iface); - uint8_t bit_mask, bit_data; + uint16_t rxlen = 1; - for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) - { - // Send one byte that represent one bit, 0x7F for one or 0x7D for zero - // The LSB (least significant bit) is sent first. - bit_data = (bit_mask & data) ? 0x7F : 0x7D; - status |= swi_uart_send_byte(&swi_hal_data[cfg->atcaswi.bus], bit_data); + return iface->phy->halreceive(iface, 0, bit_data, &rxlen); +} - } - if (status != ATCA_SUCCESS) - { - return ATCA_COMM_FAIL; - } - else +/** + * \brief Send one bit as byte using uart for SWI + * \param[in] bit_data byte equivalent of bit data on SWI + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS hal_swi_uart_send_bit(ATCAIface iface, uint8_t data) +{ + ATCA_STATUS status; + uint8_t read_data; + + if (ATCA_SUCCESS == (status = iface->phy->halsend(iface, 0xFF, &data, 1))) { - return ATCA_SUCCESS; + //Nothing to process... Reading to ensure write is complete + status = hal_swi_uart_receive_bit(iface, &read_data); + if (ATCA_SUCCESS == status) + { + if (read_data != data) + { + status = ATCA_TRACE(ATCA_TX_FAIL, "Tx send failed"); + } + } } + + return status; } /** \brief HAL implementation of SWI send command over UART @@ -304,51 +105,29 @@ ATCA_STATUS hal_swi_send_flag(ATCAIface iface, uint8_t data) ATCA_STATUS hal_swi_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength) { - -#ifdef DEBUG_HAL - printf("hal_swi_send()\r\n"); - - printf("\r\nCommand Packet (size:0x%.4x)\r\n", txlength); - printf("Count : %.2x\r\n", txdata[1]); - printf("Opcode : %.2x\r\n", txdata[2]); - printf("Param1 : %.2x\r\n", txdata[3]); - printf("Param2 : "); print_array(&txdata[4], 2); - if (txdata[1] > 7) - { - printf("Data : "); print_array(&txdata[6], txdata[1] - 7); - } - printf("CRC : "); print_array(&txdata[txdata[1] - 1], 2); - printf("\r\n"); -#endif (void)word_address; ATCA_STATUS status = ATCA_SUCCESS; - ATCAIfaceCfg *cfg = atgetifacecfg(iface); uint8_t i, bit_mask, bit_data; - //Skip the Word Address data as SWI doesn't use it - txdata++; + (void)iface->phy->halcontrol(iface, ATCA_HAL_FLUSH_BUFFER, NULL, 0); - status = hal_swi_send_flag(iface, SWI_FLAG_CMD); - if (status == ATCA_SUCCESS) + for (i = 0; i < txlength; i++) { - for (i = 0; i < txlength; i++) + for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) { - for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) + // Send one byte that represent one bit, 0x7F for one or 0x7D for zero + // The LSB (least significant bit) is sent first. + bit_data = (bit_mask & *txdata) ? 0x7F : 0x7D; + status = hal_swi_uart_send_bit(iface, bit_data); + if (status != ATCA_SUCCESS) { - // Send one byte that represent one bit, 0x7F for one or 0x7D for zero - // The LSB (least significant bit) is sent first. - bit_data = (bit_mask & *txdata) ? 0x7F : 0x7D; - status = swi_uart_send_byte(&swi_hal_data[cfg->atcaswi.bus], bit_data); - if (status != ATCA_SUCCESS) - { - return ATCA_COMM_FAIL; - } + return ATCA_COMM_FAIL; } - txdata++; } - return ATCA_SUCCESS; + txdata++; } - return ATCA_COMM_FAIL; + + return ATCA_SUCCESS; } /** \brief HAL implementation of SWI receive function over UART @@ -361,187 +140,151 @@ ATCA_STATUS hal_swi_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, */ ATCA_STATUS hal_swi_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength) { -#ifdef DEBUG_HAL - printf("hal_swi_receive()\r\n"); -#endif - (void)word_address; - ATCA_STATUS status = !ATCA_SUCCESS; ATCAIfaceCfg *cfg = atgetifacecfg(iface); - int bus = cfg->atcaswi.bus; - int retries = cfg->rx_retries; - uint8_t bit_mask, *head_buff, bit_data, count; - uint8_t i = 0; - uint16_t rxdata_max_size = *rxlength; - - *rxlength = 0; - if (rxdata_max_size < 1) - { - return ATCA_SMALL_BUFFER; - } - - head_buff = rxdata; + ATCA_STATUS status = ATCA_COMM_FAIL; + uint8_t bit_mask, bit_data = 0; - while (retries-- > 0 && status != ATCA_SUCCESS) + if ((cfg == NULL) || (rxlength == NULL) || (rxdata == NULL) || (*rxlength < 1)) { - if ((status = hal_swi_send_flag(iface, SWI_FLAG_TX)) == ATCA_SUCCESS) - { - swi_uart_mode(&swi_hal_data[bus], RECEIVE_MODE); - - *head_buff = 0x00; - for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) - { - bit_data = 0; - status = swi_uart_receive_byte(&swi_hal_data[bus], &bit_data); - if (status != ATCA_SUCCESS) - { - break; - } - // Sometimes bit data from device is stretched - // When the device sends a "one" bit, it is read as 0x7E or 0x7F. - // When the device sends a "zero" bit, it is read as 0x7A, 0x7B, or 7D. - if ((bit_data ^ 0x7F) < 2) - { - // Received "one" bit. - *head_buff |= bit_mask; - } - } - - if (status == ATCA_SUCCESS) - { - if (*head_buff < ATCA_RSP_SIZE_MIN) - { - // Set SWI to transmit mode. - swi_uart_mode(&swi_hal_data[bus], TRANSMIT_MODE); - atca_delay_us(TX_DELAY); - return ATCA_INVALID_SIZE; - } - if (*head_buff > rxdata_max_size) - { - // Set SWI to transmit mode. - swi_uart_mode(&swi_hal_data[bus], TRANSMIT_MODE); - atca_delay_us(TX_DELAY); - return ATCA_SMALL_BUFFER; - } - break; - } - else - { - swi_uart_mode(&swi_hal_data[bus], TRANSMIT_MODE); - } - - } + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); } - count = (*head_buff) - 1; - head_buff++; + (void)word_address; - for (i = 0; i < count; i++) + for (int i = 0; i < *rxlength; i++, rxdata++) { - *head_buff = 0x00; for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) { bit_data = 0; - status = swi_uart_receive_byte(&swi_hal_data[bus], &bit_data); + status = hal_swi_uart_receive_bit(iface, &bit_data); if (status != ATCA_SUCCESS) { - // Set SWI to transmit mode. - swi_uart_mode(&swi_hal_data[bus], TRANSMIT_MODE); - atca_delay_us(TX_DELAY); - return status; + break; } - // Sometimes bit data from device is stretched - // When the device sends a "one" bit, it is read as 0x7E or 0x7F. - // When the device sends a "zero" bit, it is read as 0x7A, 0x7B, or 7D. if ((bit_data ^ 0x7F) < 2) { - // Received "one" bit. - *head_buff |= bit_mask; + *rxdata |= bit_mask; } } - head_buff++; } - *rxlength = rxdata[0]; - - // Set SWI to transmit mode. - swi_uart_mode(&swi_hal_data[bus], TRANSMIT_MODE); - atca_delay_us(TX_DELAY); - -#ifdef DEBUG_HAL - printf("\r\nResponse Packet (size:0x%.4x)\r\n", *rxlength); - printf("Count : %.2x\r\n", rxdata[0]); - if (rxdata[0] > 3) - { - printf("Data : "); print_array(&rxdata[1], rxdata[0] - 3); - printf("CRC : "); print_array(&rxdata[rxdata[0] - 2], 2); - } - printf("\r\n"); -#endif - return status; } - -/** \brief wake up CryptoAuth device using SWI interface - * \param[in] iface interface to logical device to wakeup +/** + * \brief Send Wake flag via SWI. + * + * \param[in] iface interface of the logical device to wake up + * * \return ATCA_SUCCESS on success, otherwise an error code. */ - ATCA_STATUS hal_swi_wake(ATCAIface iface) { -#ifdef DEBUG_HAL - printf("hal_swi_wake()\r\n"); -#endif - ATCA_STATUS status = ATCA_COMM_FAIL; ATCAIfaceCfg *cfg = atgetifacecfg(iface); - int bus = cfg->atcaswi.bus; - int retries = cfg->rx_retries; - uint16_t datalength = 4; - uint8_t data[4] = { 0x00, 0x00, 0x00, 0x00 }; + ATCA_STATUS status = ATCA_COMM_FAIL; + uint32_t temp; + uint16_t rxlength = 4; - while ((status != ATCA_SUCCESS) && (retries >= 0x00)) + if (cfg == NULL) { - retries--; - // Change baudrate to 115200 to get low signal more than 60us - swi_uart_setbaud(&swi_hal_data[bus], 115200); - // Send byte 0x00 - status = swi_uart_send_byte(&swi_hal_data[bus], SWI_WAKE_TOKEN); - // Change baudrate back to 230400 - swi_uart_setbaud(&swi_hal_data[bus], 230400); + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); } - if (!status) - { - atca_delay_us(cfg->wake_delay); // wait tWHI + tWLO which is configured based on device type and configuration structure - status = hal_swi_receive(iface, 0, data, &datalength); - } + // Clear the rx ring buffer, before transmitting any data, because Tx and Rx are short + // Tx data will be appeared in Rx ring buffer + (void)iface->phy->halcontrol(iface, ATCA_HAL_FLUSH_BUFFER, NULL, 0); - if ((retries == 0x00) && (status != ATCA_SUCCESS) ) + do { - return ATCA_TIMEOUT; + temp = 115200UL; + (void)iface->phy->halcontrol(iface, ATCA_HAL_CHANGE_BAUD, (uint8_t*)&temp, rxlength); + + status = hal_swi_uart_send_bit(iface, CALIB_SWI_FLAG_WAKE); + + //Reset to Normal baud rate + temp = 230400UL; + (void)iface->phy->halcontrol(iface, ATCA_HAL_CHANGE_BAUD, (uint8_t*)&temp, rxlength); + + // Wait tWHI + tWLO + atca_delay_us(cfg->wake_delay); + + temp = CALIB_SWI_FLAG_TX; + hal_swi_send(iface, 0xFF, (uint8_t*)&temp, 1); + + // Read Wake response + temp = 0; + if (ATCA_SUCCESS == (status = hal_swi_receive(iface, 0x00, (uint8_t*)&temp, &rxlength))) + { + status = hal_check_wake((uint8_t*)&temp, sizeof(temp)); + } } + while (0); - return hal_check_wake(data, 4); + return status; } -/** \brief idle CryptoAuth device using SWI interface - * \param[in] iface interface to logical device to idle - * \return ATCA_SUCCESS on success, otherwise an error code. +/** + * \brief Send Sleep flag via SWI. + * + * \param[in] iface interface of the logical device to sleep + * + * \return ATCA_SUCCESS */ +ATCA_STATUS hal_swi_sleep(ATCAIface iface) +{ + uint8_t temp = CALIB_SWI_FLAG_SLEEP; + return hal_swi_send(iface, 0xFF, &temp, sizeof(temp)); +} + +/** + * \brief Send Idle flag via SWI. + * + * \param[in] iface interface of the logical device to idle + * + * \return ATCA_SUCCES + */ ATCA_STATUS hal_swi_idle(ATCAIface iface) { - return hal_swi_send_flag(iface, SWI_FLAG_IDLE); + uint8_t temp = CALIB_SWI_FLAG_IDLE; + + return hal_swi_send(iface, 0xFF, &temp, sizeof(temp)); } -/** \brief sleep CryptoAuth device using SWI interface - * \param[in] iface interface to logical device to sleep + +/** \brief Perform control operations for the kit protocol + * \param[in] iface Interface to interact with. + * \param[in] option Control parameter identifier + * \param[in] param Optional pointer to parameter value + * \param[in] paramlen Length of the parameter * \return ATCA_SUCCESS on success, otherwise an error code. */ - -ATCA_STATUS hal_swi_sleep(ATCAIface iface) +ATCA_STATUS hal_swi_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { - return hal_swi_send_flag(iface, SWI_FLAG_SLEEP); + (void)param; + (void)paramlen; + + if (iface && iface->mIfaceCFG) + { + switch (option) + { + case ATCA_HAL_CONTROL_WAKE: + return hal_swi_wake(iface); + case ATCA_HAL_CONTROL_IDLE: + return hal_swi_idle(iface); + case ATCA_HAL_CONTROL_SLEEP: + return hal_swi_sleep(iface); + case ATCA_HAL_CHANGE_BAUD: + return iface->phy->halcontrol(iface, ATCA_HAL_CHANGE_BAUD, param, paramlen); + case ATCA_HAL_CONTROL_SELECT: + /* fallthrough */ + case ATCA_HAL_CONTROL_DESELECT: + return ATCA_SUCCESS; + default: + return ATCA_UNIMPLEMENTED; + } + } + return ATCA_BAD_PARAM; } /** \brief manages reference count on given bus and releases resource if no more refences exist @@ -551,14 +294,7 @@ ATCA_STATUS hal_swi_sleep(ATCAIface iface) ATCA_STATUS hal_swi_release(void *hal_data) { - ATCASWIMaster_t *hal = (ATCASWIMaster_t*)hal_data; - // if the use count for this bus has gone to 0 references, disable it. protect against an unbracketed release - if (hal && --(hal->ref_ct) <= 0) - { - swi_uart_deinit(&swi_hal_data[hal->bus_index]); - hal->ref_ct = 0; - } return ATCA_SUCCESS; } diff --git a/lib/hal/hal_uart_harmony.c b/lib/hal/hal_uart_harmony.c new file mode 100644 index 000000000..a3e2c0da7 --- /dev/null +++ b/lib/hal/hal_uart_harmony.c @@ -0,0 +1,235 @@ +/** + * \file + * \brief ATCA Hardware abstraction layer for SWI uart over Harmony PLIB. + * + * This code is structured in two parts. Part 1 is the connection of the ATCA HAL API to the physical I2C + * implementation. Part 2 is the Harmony UART (ring buffer mode) primitives to set up the interface. + * + * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + * + */ + +#include "atca_config.h" +#include "cryptoauthlib.h" + +PLIB_SWI_SERIAL_SETUP serial_setup = { + .parity = PLIB_SWI_PARITY_NONE, + .dataWidth = PLIB_SWI_DATA_WIDTH, + .stopBits = PLIB_SWI_STOP_BIT +}; + + +/** \brief The function flush the unread data from rx ring buffer + */ +static ATCA_STATUS hal_uart_flush_buffer(ATCAIface iface) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + atca_plib_swi_uart_api_t* plib; + uint8_t dummy_read; + + if (cfg && cfg->cfg_data) + { + plib = (atca_plib_swi_uart_api_t*)cfg->cfg_data; + + // Until rx ring buffer gets cleared, read out all data from rx buffer + while (plib->readcount_get() >= 1) + { + plib->read(&dummy_read, 1); + } + } + return ATCA_SUCCESS; +} + +/** + * \brief Set baudrate default is 230KHz. + * + * \param[in] baudrate contain new baudrate + * + * \return true on success, otherwise false. + */ +static ATCA_STATUS hal_uart_set_baudrate(ATCAIface iface, uint32_t baudrate) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + atca_plib_swi_uart_api_t* plib; + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (cfg && cfg->cfg_data) + { + plib = (atca_plib_swi_uart_api_t*)cfg->cfg_data; + + serial_setup.baudRate = baudrate; + + status = plib->serial_setup(&serial_setup, 0) ? ATCA_SUCCESS : ATCA_GEN_FAIL; + } + + return status; +} + +/** + * \brief Initialize an uart interface using given config. + * + * \param[in] hal opaque pointer to HAL data + * \param[in] cfg interface configuration + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_uart_init(ATCAIface iface, ATCAIfaceCfg *cfg) +{ + atca_plib_swi_uart_api_t* plib; + + if (cfg == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + plib = (atca_plib_swi_uart_api_t*)cfg->cfg_data; + if (plib == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + return ATCA_SUCCESS; +} + +/** + * \brief HAL implementation of SWI post init. + * + * \param[in] iface ATCAIface instance + * + * \return ATCA_SUCCESS + */ +ATCA_STATUS hal_uart_post_init(ATCAIface iface) +{ + return ATCA_SUCCESS; +} + +/** + * \brief Send byte(s) via SWI. + * + * \param[in] iface interface of the logical device to send data to + * \param[in] word_address device transaction type + * \param[in] txdata pointer to bytes to send + * \param[in] txlength number of bytes to send + * \return ATCA_SUCCESS + */ +ATCA_STATUS hal_uart_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int txlength) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + atca_plib_swi_uart_api_t* plib; + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (cfg && cfg->cfg_data && txdata && txlength) + { + plib = (atca_plib_swi_uart_api_t*)cfg->cfg_data; + + (void)plib->error_get(); + if (txlength == plib->write(txdata, txlength)) + { + status = ATCA_SUCCESS; + } + else + { + status = ATCA_RX_FAIL; + } + } + + return status; +} + + +/** + * \brief Receive byte(s) via SWI. + * \param[in] iface Device to interact with. + * \param[in] word_address device transaction type + * \param[out] rxdata Data received will be returned here. + * \param[in,out] rxlength As input, the size of the rxdata buffer. + * As output, the number of bytes received. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS hal_uart_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t* rxlength) +{ + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + atca_plib_swi_uart_api_t* plib; + ATCA_STATUS status = ATCA_BAD_PARAM; + int16_t timeout = 300; + + if (cfg && cfg->cfg_data && rxdata && rxlength) + { + plib = (atca_plib_swi_uart_api_t*)cfg->cfg_data; + + while ((plib->readcount_get() < *rxlength) && (timeout > 0)) + { + atca_delay_us(25); + timeout -= 25; + } + + if (*rxlength == plib->read(rxdata, *rxlength)) + { + status = ATCA_SUCCESS; + } + else + { + status = ATCA_RX_FAIL; + } + } + + return status; +} + +ATCA_STATUS hal_uart_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) +{ + (void)param; + (void)paramlen; + + if (iface && iface->mIfaceCFG) + { + switch (option) + { + case ATCA_HAL_CHANGE_BAUD: + return hal_uart_set_baudrate(iface, *(uint32_t*)param); + case ATCA_HAL_FLUSH_BUFFER: + return hal_uart_flush_buffer(iface); + case ATCA_HAL_CONTROL_SELECT: + /* fallthrough */ + case ATCA_HAL_CONTROL_DESELECT: + return ATCA_SUCCESS; + default: + return ATCA_UNIMPLEMENTED; + } + } + return ATCA_BAD_PARAM; +} + +/** + * \brief Manages reference count on given bus and releases resource if + * no more reference(s) exist. + * + * \param[in] hal_data opaque pointer to hal data structure - known only + * to the HAL implementation + * + * \return ATCA_SUCCESS + */ +ATCA_STATUS hal_uart_release(void *hal_data) +{ + return ATCA_SUCCESS; +} diff --git a/lib/hal/hal_uc3_i2c_asf.c b/lib/hal/hal_uc3_i2c_asf.c index 2e2915c72..107a27602 100644 --- a/lib/hal/hal_uc3_i2c_asf.c +++ b/lib/hal/hal_uc3_i2c_asf.c @@ -36,6 +36,10 @@ #include "cryptoauthlib.h" #include "hal_uc3_i2c_asf.h" +#ifndef ATCA_HAL_LEGACY_API +#error "The use of this hal requires the ATCA_HAL_LEGACY_API option to be enabled. +#endif + /** \defgroup hal_ Hardware abstraction layer (hal_) * * \brief diff --git a/lib/hal/kit_protocol.c b/lib/hal/kit_protocol.c index 0085d74e4..bf2c7a38f 100644 --- a/lib/hal/kit_protocol.c +++ b/lib/hal/kit_protocol.c @@ -29,7 +29,6 @@ #include #include #include "atca_compiler.h" -#include "kit_phy.h" #include "kit_protocol.h" #include "atca_helpers.h" @@ -79,6 +78,8 @@ const char * kit_id_from_devtype(ATCADeviceType devtype) return "SHA206A"; case TA100: return "TA100"; + case ECC204: + return "ECC204"; default: return "unknown"; } @@ -101,6 +102,46 @@ const char * kit_interface_from_kittype(ATCAKitType kittype) } } +/** \brief HAL implementation of send over USB HID + * \param[in] iface instance + * \param[in] txdata pointer to bytes to send + * \param[in] txlength number of bytes to send + * \return ATCA_STATUS + */ +ATCA_STATUS kit_phy_send(ATCAIface iface, uint8_t* txdata, int txlength) +{ + if (iface && iface->phy && iface->phy->halsend) + { + return iface->phy->halsend(iface, 0xFF, txdata, txlength); + } + else + { + return ATCA_BAD_PARAM; + } +} + +/** \brief HAL implementation of kit protocol send over USB HID + * \param[in] iface instance + * \param[out] rxdata pointer to space to receive the data + * \param[in,out] rxsize ptr to expected number of receive bytes to request + * \return ATCA_STATUS + */ +ATCA_STATUS kit_phy_receive(ATCAIface iface, uint8_t* rxdata, int* rxsize) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (iface && iface->phy && iface->phy->halreceive && rxsize) + { + uint16_t rxlen = (uint16_t)*rxsize; + if (ATCA_SUCCESS == (status = iface->phy->halreceive(iface, 0, rxdata, &rxlen))) + { + *rxsize = rxlen; + } + } + + return status; +} + /** \brief HAL implementation of kit protocol init. This function calls back to the physical protocol to send the bytes * \param[in] iface instance * \return ATCA_SUCCESS on success, otherwise an error code. @@ -227,6 +268,15 @@ ATCA_STATUS kit_init(ATCAIface iface) return status; } +/** \brief HAL implementation of Kit HID post init + * \param[in] iface instance + * \return ATCA_STATUS + */ +ATCA_STATUS kit_post_init(ATCAIface iface) +{ + return ATCA_SUCCESS; +} + /** \brief The function send word address byte of atreceive to kit protocol to receive * response from device. This function call takes place only when target device is TA100. * \param[in] iface instance @@ -671,4 +721,43 @@ ATCA_STATUS kit_parse_rsp(const char* pkitbuf, int nkitbuf, uint8_t* kitstatus, return status; } + +/** \brief Perform control operations for the kit protocol + * \param[in] iface Interface to interact with. + * \param[in] option Control parameter identifier + * \param[in] param Optional pointer to parameter value + * \param[in] paramlen Length of the parameter + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS kit_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) +{ + (void)param; + (void)paramlen; + + if (iface && iface->mIfaceCFG) + { + switch (option) + { + case ATCA_HAL_CONTROL_WAKE: + return kit_wake(iface); + case ATCA_HAL_CONTROL_IDLE: + return kit_idle(iface); + case ATCA_HAL_CONTROL_SLEEP: + return kit_sleep(iface); + case ATCA_HAL_CONTROL_SELECT: + /* fallthrough */ + case ATCA_HAL_CONTROL_DESELECT: + return ATCA_SUCCESS; + default: + break; + } + } + return ATCA_BAD_PARAM; +} + +ATCA_STATUS kit_release(void* hal_data) +{ + return ATCA_SUCCESS; +} + /** @} */ diff --git a/lib/hal/kit_protocol.h b/lib/hal/kit_protocol.h index 7740c92d7..b2bea0ec1 100644 --- a/lib/hal/kit_protocol.h +++ b/lib/hal/kit_protocol.h @@ -53,9 +53,11 @@ extern "C" { #endif ATCA_STATUS kit_init(ATCAIface iface); - +ATCA_STATUS kit_post_init(ATCAIface iface); ATCA_STATUS kit_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int txlength); ATCA_STATUS kit_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxsize); +ATCA_STATUS kit_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); +ATCA_STATUS kit_release(void* hal_data); ATCA_STATUS kit_wrap_cmd(const uint8_t* txdata, int txlength, char* pkitbuf, int* nkitbuf, char target); ATCA_STATUS kit_parse_rsp(const char* pkitbuf, int nkitbuf, uint8_t* kitstatus, uint8_t* rxdata, int* nrxdata); diff --git a/lib/hal/swi_uart_samd21_asf.c b/lib/hal/swi_uart_samd21_asf.c index e9536a80c..d3911697d 100644 --- a/lib/hal/swi_uart_samd21_asf.c +++ b/lib/hal/swi_uart_samd21_asf.c @@ -32,6 +32,10 @@ #include "swi_uart_samd21_asf.h" #include "atca_helpers.h" +#ifndef ATCA_HAL_LEGACY_API +#error "The use of this hal requires the ATCA_HAL_LEGACY_API option to be enabled. +#endif + /** \defgroup hal_ Hardware abstraction layer (hal_) * * \brief diff --git a/lib/hal/swi_uart_start.c b/lib/hal/swi_uart_start.c index 76a445c4a..946a826d6 100644 --- a/lib/hal/swi_uart_start.c +++ b/lib/hal/swi_uart_start.c @@ -32,6 +32,10 @@ #include "swi_uart_start.h" #include "atca_helpers.h" +#ifndef ATCA_HAL_LEGACY_API +#error "The use of this hal requires the ATCA_HAL_LEGACY_API option to be enabled. +#endif + #define USART_BAUD_RATE(baud, sercom_freq) (65536 - ((65536 * 16.0F * baud) / sercom_freq)) /** \defgroup hal_ Hardware abstraction layer (hal_) diff --git a/lib/host/atca_host.c b/lib/host/atca_host.c index 61ad61234..cd03a306d 100644 --- a/lib/host/atca_host.c +++ b/lib/host/atca_host.c @@ -187,6 +187,24 @@ ATCA_STATUS atcah_nonce(struct atca_nonce_in_out *param) } } + else if ((NONCE_MODE_GEN_SESSION_KEY == calc_mode) && (param->zero >= 0x8000)) + { + // Calculate nonce using SHA-256 (refer to data sheet) + p_temp = temporary; + + memcpy(p_temp, param->rand_out, RANDOM_NUM_SIZE); + p_temp += RANDOM_NUM_SIZE; + + memcpy(p_temp, param->num_in, NONCE_NUMIN_SIZE); + p_temp += NONCE_NUMIN_SIZE; + + *p_temp++ = ATCA_NONCE; + *p_temp++ = param->mode; + *p_temp++ = (param->zero) & 0xFF; + + // Calculate SHA256 to get the nonce + atcac_sw_sha2_256(temporary, ATCA_MSG_SIZE_NONCE, param->temp_key->value); + } else { return ATCA_BAD_PARAM; @@ -1560,4 +1578,121 @@ ATCA_STATUS atcah_encode_counter_match(uint32_t counter_value, uint8_t * counter return ATCA_SUCCESS; } +/** \brief This function calculates the input MAC for the ECC204 Write command. + + The Write command will need an input MAC if SlotConfig3.bit0 is set. + + * \param[in,out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_ecc204_write_auth_mac(struct atca_write_mac_in_out *param) +{ + uint8_t mac_input[ATCA_MSG_SIZE_ENCRYPT_MAC]; + uint8_t i; + uint8_t *p_temp; + + // Check parameters + if ((NULL == param->input_data) || (NULL == param->temp_key)) + { + return ATCA_BAD_PARAM; + } + + // Encrypt by XOR-ing Data with the session key + for (i = 0; i < 32; i++) + { + param->encrypted_data[i] = param->input_data[i] ^ param->temp_key->value[i]; + } + + // If the pointer *mac is provided by the caller then calculate input MAC + if (param->auth_mac) + { + // Start calculation + p_temp = mac_input; + + // (1) 32 bytes TempKey + memcpy(p_temp, param->temp_key->value, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + // (2) 1 byte Opcode + *p_temp++ = ATCA_WRITE; + + // (3) 1 byte Param1 (zone) + *p_temp++ = param->zone; + + // (4) 2 bytes Param2 (keyID) + *p_temp++ = (param->key_id >> 8) & 0xFF; + *p_temp++ = param->key_id & 0xFF; + + // (5) 1 byte SN[8] + *p_temp++ = param->sn[8]; + + // (6) 2 bytes SN[0:1] + *p_temp++ = param->sn[0]; + *p_temp++ = param->sn[1]; + + // (7) 25 zeros + memset(p_temp, 0, ATCA_WRITE_MAC_ZEROS_SIZE); + p_temp += ATCA_WRITE_MAC_ZEROS_SIZE; + + // (8) 32 bytes PlainText + memcpy(p_temp, param->input_data, ATCA_KEY_SIZE); + + // Calculate SHA256 to get MAC + atcac_sw_sha2_256(mac_input, sizeof(mac_input), param->auth_mac); + } + + return ATCA_SUCCESS; +} + +/** \brief This function calculates the session key for the ECC204. + * + * \param[in,out] param pointer to parameter structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcah_gen_session_key(struct atca_session_key_in_out *param) +{ + uint8_t session_key_input[ATCA_MSG_SIZE_SESSION_KEY]; + uint8_t *p_temp; + + if ((NULL == param->transport_key) || (NULL == param->nonce) || (NULL == param->session_key)) + { + return ATCA_BAD_PARAM; + } + + p_temp = session_key_input; + + // (1) 32 bytes of transport key + memcpy(p_temp, param->transport_key, ATCA_KEY_SIZE); + p_temp += ATCA_KEY_SIZE; + + // (2) 0x15 + *p_temp++ = 0x15; + + // (3) 0x00 + *p_temp++ = 0x00; + + // (4) 2bytes of transport key id + *p_temp++ = param->transport_key_id & 0xFF; + *p_temp++ = (param->transport_key_id >> 8) & 0xFF; + + // (5) 1 byte SN[8] + *p_temp++ = param->sn[8]; + + // (6) 2 bytes SN[0:1] + *p_temp++ = param->sn[0]; + *p_temp++ = param->sn[1]; + + // (7) 25 zeros + memset(p_temp, 0, ATCA_WRITE_MAC_ZEROS_SIZE); + p_temp += ATCA_WRITE_MAC_ZEROS_SIZE; + + // (8) 32 bytes nonce + memcpy(p_temp, param->nonce, 32); + + // Calculate SHA256 to get MAC + atcac_sw_sha2_256(session_key_input, sizeof(session_key_input), param->session_key); + + return ATCA_SUCCESS; +} + #endif diff --git a/lib/host/atca_host.h b/lib/host/atca_host.h index 057e4fb3d..2cfcc95f2 100644 --- a/lib/host/atca_host.h +++ b/lib/host/atca_host.h @@ -76,6 +76,9 @@ //! KeyId{32} || OpCode{1} || Param1{1} || Param2{2}|| SN8{1} || SN0_1{2} || 0{25} || TempKey{32} #define ATCA_MSG_SIZE_ENCRYPT_MAC (96) +//! TransportKey{32} || 0x15{1} || 0x00{1} || KeyId{2} || SN8{1} || SN0_1{2} || 0{25} || Nonce{32} +#define ATCA_MSG_SIZE_SESSION_KEY (96) + //! KeyId{32} || OpCode{1} || Param1{1} || Param2{2}|| SN8{1} || SN0_1{2} || 0{21} || PlainText{36} #define ATCA_MSG_SIZE_PRIVWRITE_MAC (96) @@ -414,6 +417,18 @@ typedef struct atca_sign_internal_in_out uint8_t* digest; //!< [out] SHA256 digest of the full 55 byte message. Can be NULL if not required. } atca_sign_internal_in_out_t; +/** \brief Input/Output paramters for calculating the session key + * by the nonce command. Used with the atcah_gen_session_key() function. + */ +typedef struct atca_session_key_in_out +{ + uint8_t* transport_key; + uint16_t transport_key_id; + const uint8_t* sn; + uint8_t* nonce; + uint8_t* session_key; +}atca_session_key_in_out_t; + #ifdef __cplusplus extern "C" { #endif @@ -439,6 +454,8 @@ ATCA_STATUS atcah_secureboot_enc(atca_secureboot_enc_in_out_t* param); ATCA_STATUS atcah_secureboot_mac(atca_secureboot_mac_in_out_t *param); ATCA_STATUS atcah_encode_counter_match(uint32_t counter, uint8_t * counter_match); ATCA_STATUS atcah_io_decrypt(struct atca_io_decrypt_in_out *param); +ATCA_STATUS atcah_ecc204_write_auth_mac(struct atca_write_mac_in_out *param); +ATCA_STATUS atcah_gen_session_key(atca_session_key_in_out_t *param); #ifdef __cplusplus } #endif diff --git a/lib/openssl/atca_openssl_interface.c b/lib/openssl/atca_openssl_interface.c index 62341b641..bc9817303 100644 --- a/lib/openssl/atca_openssl_interface.c +++ b/lib/openssl/atca_openssl_interface.c @@ -678,13 +678,45 @@ ATCA_STATUS atcac_pk_free( { if (ctx->ptr) { - EVP_PKEY_free(ctx->ptr); + EVP_PKEY_free((EVP_PKEY*)ctx->ptr); } status = ATCA_SUCCESS; } return status; } +/** \brief Get the public key from the context + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pk_public( + atcac_pk_ctx* ctx, + uint8_t* buf, + size_t* buflen + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (ctx && buf && ctx->ptr) + { + int ret = -1; + if (EVP_PKEY_EC == EVP_PKEY_id((EVP_PKEY*)ctx->ptr)) + { + unsigned char pbuf[65]; // UNCOMPRESSED format + unsigned char *out = pbuf; + + ret = i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY((EVP_PKEY*)ctx->ptr), &out); + + if (ret > 0) + { + memcpy(buf, &pbuf[1], *buflen); + } + } + status = (ret > 0) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + } + return status; +} + /** \brief Perform a signature with the private key in the context * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -817,4 +849,45 @@ ATCA_STATUS atcac_pk_verify( return status; } +/** \brief Execute the key agreement protocol for the provided keys (if they can) + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pk_derive( + atcac_pk_ctx* private_ctx, + atcac_pk_ctx* public_ctx, + uint8_t* buf, + size_t* buflen + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if ((private_ctx != NULL) && (public_ctx != NULL) && (buf != NULL) && (buflen != NULL)) + { + int keytype = EVP_PKEY_id((EVP_PKEY*)private_ctx->ptr); + + if (keytype == EVP_PKEY_id((EVP_PKEY*)public_ctx->ptr)) + { + int ret = -1; + switch (keytype) + { + case EVP_PKEY_EC: + { + const EC_POINT *pub_key = EC_KEY_get0_public_key( + EVP_PKEY_get0_EC_KEY((EVP_PKEY*)public_ctx->ptr)); + + ret = ECDH_compute_key(buf, *buflen, pub_key, + EVP_PKEY_get0_EC_KEY((EVP_PKEY*)private_ctx->ptr), NULL); + break; + } + default: + break; + } + status = (ret > 0) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + } + } + + return status; +} + #endif /* ATCA_OPENSSL */ diff --git a/lib/pkcs11/pkcs11_config.c b/lib/pkcs11/pkcs11_config.c index 79ca27f29..4c91c456a 100644 --- a/lib/pkcs11/pkcs11_config.c +++ b/lib/pkcs11/pkcs11_config.c @@ -282,7 +282,7 @@ static CK_RV pkcs11_config_parse_interface(pkcs11_slot_ctx_ptr slot_ctx, char* c slot_ctx->interface_config.iface_type = ATCA_I2C_IFACE; if (argc > 1) { - slot_ctx->interface_config.atcai2c.slave_address = (uint8_t)strtol(argv[1], NULL, 16); + slot_ctx->interface_config.atcai2c.address = (uint8_t)strtol(argv[1], NULL, 16); } if (argc > 2) { diff --git a/lib/pkcs11/pkcs11_slot.c b/lib/pkcs11/pkcs11_slot.c index 4e6aed02f..015db7144 100644 --- a/lib/pkcs11/pkcs11_slot.c +++ b/lib/pkcs11/pkcs11_slot.c @@ -191,10 +191,10 @@ CK_RV pkcs11_slot_init(CK_SLOT_ID slotID) #ifdef ATCA_HAL_I2C if (ATCA_SUCCESS != status) { - if (0xC0 != ifacecfg->atcai2c.slave_address) + if (0xC0 != ifacecfg->atcai2c.address) { /* Try the default address */ - ifacecfg->atcai2c.slave_address = 0xC0; + ifacecfg->atcai2c.address = 0xC0; atcab_release(); atca_delay_ms(1); retries = 2; diff --git a/lib/wolfssl/atca_wolfssl_interface.c b/lib/wolfssl/atca_wolfssl_interface.c index 24dac3cd6..4beb2cc08 100644 --- a/lib/wolfssl/atca_wolfssl_interface.c +++ b/lib/wolfssl/atca_wolfssl_interface.c @@ -312,4 +312,296 @@ ATCA_STATUS atcac_sha256_hmac_finish( return (!ret) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; } +/** \brief Set up a public/private key structure for use in asymmetric cryptographic functions + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pk_init( + atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ + uint8_t* buf, /**< [in] buffer containing a pem encoded key */ + size_t buflen, /**< [in] length of the input buffer */ + uint8_t key_type, + bool pubkey /**< [in] buffer is a public key */ + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (ctx) + { + if (!key_type) + { + (ecc_key*)ctx->ptr = wc_ecc_key_new(NULL); + + if (ctx->ptr) + { + int ret = wc_ecc_set_curve((ecc_key*)ctx->ptr, 32, ECC_SECP256R1); + + if (!ret) + { + if (pubkey) + { + /* Configure the public key */ + ret = wc_ecc_import_unsigned((ecc_key*)ctx->ptr, buf, &buf[32], NULL, ECC_SECP256R1); + } + else + { + /* Configure a private key */ + ret = wc_ecc_import_private_key((byte*)buf, 32, NULL, 0, (ecc_key*)ctx->ptr); + } + + if (!ret) + { + status = ATCA_SUCCESS; + } + else + { + wc_ecc_key_free((ecc_key*)(ctx->ptr)); + status = ATCA_GEN_FAIL; + } + } + } + } + } + return status; +} + +/** \brief Set up a public/private key structure for use in asymmetric cryptographic functions + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pk_init_pem( + atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ + uint8_t * buf, /**< [in] buffer containing a pem encoded key */ + size_t buflen, /**< [in] length of the input buffer */ + bool pubkey /**< [in] buffer is a public key */ + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (ctx && buf) + { + int ret = -1; + int ecckey = 0; + int type = ECC_PRIVATEKEY_TYPE; + word32 inOutIdx = 0; + DerBuffer* der = NULL; + status = ATCA_FUNC_FAIL; + + if (pubkey) + { + type = ECC_PUBLICKEY_TYPE; + } + + ret = PemToDer((char*)buf, (long)buflen, type, &der, NULL, NULL, &ecckey); + + if ((ret >= 0) && (der != NULL)) + { + (ecc_key*)ctx->ptr = wc_ecc_key_new(NULL); + + if (ctx->ptr) + { + ret = wc_ecc_set_curve((ecc_key*)ctx->ptr, 32, ECC_SECP256R1); + + if (!ret) + { + if (pubkey) + { + ret = wc_EccPublicKeyDecode(der->buffer, &inOutIdx, (ecc_key*)ctx->ptr, der->length); + } + else + { + ret = wc_EccPrivateKeyDecode(der->buffer, &inOutIdx, (ecc_key*)ctx->ptr, der->length); + } + status = (0 == ret) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + } + } + } + } + return status; +} + +/** \brief Get the public key from the context + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pk_public( + atcac_pk_ctx* ctx, + uint8_t* buf, + size_t* buflen + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (ctx && ctx->ptr && buf) + { + if (buflen) + { + (void)*buflen; + } + + int ret = -1; + + if (!wc_ecc_check_key((ecc_key*)ctx->ptr)) + { + word32 xlen = 32; + word32 ylen = 32; + + ret = wc_ecc_export_public_raw((ecc_key*)ctx->ptr, (byte*)buf, &xlen, (byte*)&buf[32], &ylen); + } + + status = (0 == ret) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + } + return status; +} + +/** \brief Free a public/private key structure + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pk_free( + atcac_pk_ctx* ctx /**< [in] pointer to a pk context */ + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (ctx) + { + if (ctx->ptr) + { + wc_ecc_key_free((ecc_key*)(ctx->ptr)); + } + status = ATCA_SUCCESS; + } + return status; +} + +/** \brief Perform a signature with the private key in the context + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pk_sign( + atcac_pk_ctx* ctx, + uint8_t * digest, + size_t dig_len, + uint8_t* signature, + size_t* sig_len + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + int ret = 0; + WC_RNG rng; + + if (ctx && ctx->ptr && signature && digest && sig_len) + { + int ret = wc_InitRng(&rng); + + if (!ret) + { + if (!wc_ecc_check_key((ecc_key*)ctx->ptr)) + { + uint8_t sig[72]; + word32 siglen = sizeof(sig); + word32 rlen = 32; + word32 slen = 32; + + ret = wc_ecc_sign_hash((byte*)digest, (word32)dig_len, (byte*)sig, &siglen, &rng, (ecc_key*)ctx->ptr); + if (!ret) + { + ret = wc_ecc_sig_to_rs((byte*)sig, siglen, (byte*)signature, &rlen, (byte*)&signature[32], &slen); + } + + if (!ret) + { + *sig_len = 64; + } + } + else + { + // ret = wc_SignatureGenerateHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, digest, dig_len, signature, + // *sig_len, (RsaKey*)ctx->ptr, 32, &rng); + } + wc_FreeRng(&rng); + } + status = (0 == ret) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + } + return status; +} + +/** \brief Perform a verify using the public key in the provided context + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pk_verify( + atcac_pk_ctx* ctx, + uint8_t* digest, + size_t dig_len, + uint8_t* signature, + size_t sig_len + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (ctx && ctx->ptr && signature && digest) + { + int ret = -1; + int res = 0; + if (!wc_ecc_check_key((ecc_key*)ctx->ptr)) + { + uint8_t sig[72]; + sig_len = sizeof(sig); + + ret = wc_ecc_rs_raw_to_sig(signature, 32, &signature[32], 32, (byte*)sig, (word32*)&sig_len); + + if (!ret) + { + ret = wc_ecc_verify_hash((byte*)sig, (word32)sig_len, (byte*)digest, (word32)dig_len, &res, (ecc_key*)ctx->ptr); + } + } + else + { + // ret = wc_SignatureVerifyHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, digest, 32, signature, + // &sig_len, ctx->ptr, 64); + } + + status = ATCA_FUNC_FAIL; + if (!ret) + { + if (res) + { + status = ATCA_SUCCESS; + } + } + } + + return status; + +} + +/** \brief Execute the key agreement protocol for the provided keys (if they can) + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pk_derive( + atcac_pk_ctx* private_ctx, + atcac_pk_ctx* public_ctx, + uint8_t* buf, + size_t* buflen + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if ((private_ctx != NULL) && (public_ctx != NULL) && (buf != NULL) && (buflen != NULL)) + { + int ret = -1; + + if (!wc_ecc_check_key((ecc_key*)public_ctx->ptr)) + { + ret = wc_ecc_shared_secret((ecc_key*)private_ctx->ptr, (ecc_key*)public_ctx->ptr, (byte*)buf, (word32*)buflen); + } + status = (0 == ret) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + } + + return status; +} + #endif /* ATCA_WOLFSSL */ diff --git a/license.txt b/license.txt index f28218b5d..138dd90fd 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -(c) 2015-2020 Microchip Technology Inc. and its subsidiaries. +(c) 2015-2021 Microchip Technology Inc. and its subsidiaries. Subject to your compliance with these terms, you may use the Microchip Software and any derivatives exclusively with Microchip products. It is your @@ -20,79 +20,3 @@ MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. - - - -=============================================================================== -If using the cross-platform HID driver (lib/hal/hal_all_platforms_kit_hidapi.c) -this code depends on the hidapi library with the following license: - -Copyright (c) 2010, Alan Ott, Signal 11 Software -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Signal 11 Software nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -=============================================================================== -If using the Espressif ESP32 I2C driver (lib/hal/hal_esp32_i2c.c), this code -has the following license: - -Copyright 2018 Espressif Systems (Shanghai) PTE LTD -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -=============================================================================== -If using the unit test code in the test folder, this code depends on the unity -library with the following license: - -The MIT License (MIT) - -Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/module.xml b/module.xml index 6c49da8e3..a4a287f8c 100644 --- a/module.xml +++ b/module.xml @@ -1,4 +1,4 @@ - + diff --git a/python/README.md b/python/README.md index faabff282..46b4775b7 100644 --- a/python/README.md +++ b/python/README.md @@ -178,3 +178,8 @@ has details for how to run the tests. The module tests are not comprehensive for of cryptoauthlib but rather are meant to test the python module code only against the library to ensure the interfaces are correct and ctypes structures match the platform. +Release notes +----------- +See [Release Notes](release_notes.md) + + diff --git a/python/cryptoauthlib/__init__.py b/python/cryptoauthlib/__init__.py index d8debb905..be60b4622 100644 --- a/python/cryptoauthlib/__init__.py +++ b/python/cryptoauthlib/__init__.py @@ -5,6 +5,8 @@ import sys import json import ctypes +import inspect +import textwrap # All modules are setup to be import * safe so the following is an exception to # the python coding standard. Also the library has to be loaded before loading @@ -34,22 +36,63 @@ pass -def __update_signature(func, attributes): - for k, v in attributes.items(): - if isinstance(v, list): - setattr(func, k, [eval(x) for x in v]) +def __create_wrapper(name, attrs, ctypes_func, *args, **kwargs): + def f(*args): + return ctypes_func(*args) + + try: + f.__name__ = name + except TypeError: + f.__name__ = name.encode() + + f.__doc__ = attrs.get('docstring', '') + + paramlist = attrs.get('parameters', []) + + f.__doc__ = os.linesep.join(textwrap.wrap(f.__doc__, width=70)) + os.linesep + + for n, d in paramlist: + f.__doc__ += os.linesep + n + ':' + os.linesep + textwrap.indent(d, ' ') + os.linesep + + try: + if len(paramlist) > 0: + p = [inspect.Parameter(k, inspect.Parameter.POSITIONAL_ONLY) for k, v in attrs['parameters']] + f.__signature__ = inspect.Signature(parameters=p) else: - setattr(func, k, eval(v)) + f.__signature__ = inspect.Signature() + except: + # Python 2 & < 3.4 skip the function signature updates + pass + + return f + + +def __add_function(this_package, name, attrs, func): + if not hasattr(this_package, name): + setattr(this_package, name, __create_wrapper(name, attrs, func)) + + +def __update_signature(func, name, attr): + if isinstance(attr, list): + setattr(func, name, [eval(x) for x in attr]) + elif attr is not None: + setattr(func, name, eval(attr)) def __update_signatures(lib, filename): + this_package = sys.modules[__package__] sig_info = json.load(open(filename, 'r')) for k, v in sig_info.items(): try: - __update_signature(getattr(lib, k), v) + func = getattr(lib, k) + __update_signature(func, 'restype', v['restype']) + __update_signature(func, 'argtypes', v['argtypes']) + __add_function(this_package, k, v, func) except AttributeError: pass -if os.path.exists('cryptoauth.json'): - __update_signatures(get_cryptoauthlib(), os.path.join(os.path.dirname(__file__), 'cryptoauth.json')) +_lib_definition_file = os.path.join(os.path.dirname(__file__), 'cryptoauth.json') + +if os.path.exists(_lib_definition_file): + __update_signatures(get_cryptoauthlib(), _lib_definition_file) diff --git a/python/cryptoauthlib/atcab.py b/python/cryptoauthlib/atcab.py index fc1bae205..4d082aca7 100644 --- a/python/cryptoauthlib/atcab.py +++ b/python/cryptoauthlib/atcab.py @@ -21,7 +21,7 @@ # THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR # THIS SOFTWARE. -from ctypes import c_uint8, c_uint32, byref, create_string_buffer, Structure, c_char, c_uint16, c_void_p, c_bool +from ctypes import c_uint8, c_uint32, byref, create_string_buffer, Structure, c_char, c_uint16, c_bool from .status import Status from .library import get_cryptoauthlib, AtcaReference diff --git a/python/cryptoauthlib/exceptions.py b/python/cryptoauthlib/exceptions.py index 0bea64ee6..835da216d 100644 --- a/python/cryptoauthlib/exceptions.py +++ b/python/cryptoauthlib/exceptions.py @@ -161,3 +161,6 @@ class NoUseFlagError(CryptoError): class LibraryNotInitialized(CryptoError): """Indication that library or context was not initialized prior to an API call""" + +class UnsupportedInterface(CryptoError): + """"The selected interface is not supported by the library""" diff --git a/python/cryptoauthlib/iface.py b/python/cryptoauthlib/iface.py index 49a0e1f73..76950e258 100644 --- a/python/cryptoauthlib/iface.py +++ b/python/cryptoauthlib/iface.py @@ -24,6 +24,7 @@ from ctypes import Structure, Union, c_uint16, c_int, c_uint8, c_uint32, c_void_p from .library import get_cryptoauthlib, get_ctype_by_name from .atcaenum import AtcaEnum +from .exceptions import UnsupportedInterface # Because this module directly mirrors the C api the following is an exception to the python coding standard # pylint: disable-msg=too-few-public-methods @@ -38,6 +39,12 @@ class ATCAIfaceType(AtcaEnum): ATCA_UART_IFACE = 2 ATCA_SPI_IFACE = 3 ATCA_HID_IFACE = 4 + ATCA_KIT_IFACE = 5 + ATCA_CUSTOM_IFACE = 6 + ATCA_I2C_GPIO_IFACE = 7 + ATCA_SWI_GPIO_IFACE = 8 + ATCA_SPI_GPIO_IFACE = 9 + ATCA_UNKNOWN_IFACE = 0xFE class ATCAKitType(AtcaEnum): @@ -47,7 +54,8 @@ class ATCAKitType(AtcaEnum): ATCA_KIT_AUTO_IFACE = 0 ATCA_KIT_I2C_IFACE = 1 ATCA_KIT_SWI_IFACE = 2 - ATCA_KIT_UNKNOWN_IFACE = 3 + ATCA_KIT_SPI_IFACE = 3 + ATCA_KIT_UNKNOWN_IFACE = 4 class ATCADeviceType(AtcaEnum): @@ -61,6 +69,7 @@ class ATCADeviceType(AtcaEnum): ATECC608B = 3 ATECC608 = 3 ATSHA206A = 4 + ECC204 = 5 ATCA_DEV_UNKNOWN = 0x20 @@ -76,7 +85,8 @@ class _ATCAI2C(Structure): class _ATCASWI(Structure): """SWI (Atmel Single Wire Interface) HAL configuration""" - _fields_ = [('bus', c_uint8)] + _fields_ = [('address', c_uint8), + ('bus', c_uint8)] class _ATCAUART(Structure): @@ -129,34 +139,42 @@ class ATCAIfaceCfg(Structure): ('cfg_data', c_void_p)] +def _iface_load_default_config(name): + """"Attempt to load the default configuration structure from the library by name""" + try: + return ATCAIfaceCfg.in_dll(get_cryptoauthlib(), name) + except ValueError: + raise UnsupportedInterface('The selected interface specified by {} is not supported by this version of the library'.format(name)) + + def cfg_ateccx08a_i2c_default(): """Default configuration for an ECCx08A device on the first logical I2C bus""" - return ATCAIfaceCfg.in_dll(get_cryptoauthlib(), 'cfg_ateccx08a_i2c_default') + return _iface_load_default_config('cfg_ateccx08a_i2c_default') def cfg_ateccx08a_swi_default(): """Default configuration for an ECCx08A device on the logical SWI bus over UART""" - return ATCAIfaceCfg.in_dll(get_cryptoauthlib(), 'cfg_ateccx08a_swi_default') + return _iface_load_default_config('cfg_ateccx08a_swi_default') def cfg_ateccx08a_kithid_default(): """Default configuration for Kit protocol over a HID interface""" - return ATCAIfaceCfg.in_dll(get_cryptoauthlib(), 'cfg_ateccx08a_kithid_default') + return _iface_load_default_config('cfg_ateccx08a_kithid_default') def cfg_atsha20xa_i2c_default(): """Default configuration for a SHA204A device on the first logical I2C bus""" - return ATCAIfaceCfg.in_dll(get_cryptoauthlib(), 'cfg_atsha20xa_i2c_default') + return _iface_load_default_config('cfg_atsha20xa_i2c_default') def cfg_atsha20xa_swi_default(): """Default configuration for an SHA204A device on the logical SWI bus over UART""" - return ATCAIfaceCfg.in_dll(get_cryptoauthlib(), 'cfg_atsha20xa_swi_default') + return _iface_load_default_config('cfg_atsha20xa_swi_default') def cfg_atsha20xa_kithid_default(): """Default configuration for Kit protocol over a HID interface for SHA204""" - return ATCAIfaceCfg.in_dll(get_cryptoauthlib(), 'cfg_atsha20xa_kithid_default') + return _iface_load_default_config('cfg_atsha20xa_kithid_default') # Make module import * safe - keep at the end of the file diff --git a/python/cryptoauthlib/library.py b/python/cryptoauthlib/library.py index b5d1e3006..8465d2740 100644 --- a/python/cryptoauthlib/library.py +++ b/python/cryptoauthlib/library.py @@ -108,6 +108,7 @@ def get_device_name(revision): devices = {0x10: 'ATECC108A', 0x50: 'ATECC508A', 0x60: 'ATECC608', + 0x20: 'ECC204', 0x00: 'ATSHA204A', 0x02: 'ATSHA204A', 0x40: 'ATSHA206A'} @@ -126,6 +127,7 @@ def get_device_type_id(name): 'ATECC608B': 3, 'ATECC608': 3, 'ATSAH206A': 4, + 'ECC204': 5, 'UNKNOWN': 0x20} return devices.get(name.upper()) diff --git a/python/setup.py b/python/setup.py index 21354182e..296f23945 100644 --- a/python/setup.py +++ b/python/setup.py @@ -149,7 +149,11 @@ def build_extension(self, ext): '-DATCA_TNG_LEGACY_SUPPORT=ON', '-DATCA_USE_ATCAB_FUNCTIONS=ON'] if os.path.exists('../lib/talib' if not _sdist_build else 'lib/talib'): - cmake_args += ['-DATCA_TA100_SUPPORT=ON', '-DATCA_OPENSSL=ON'] + cmake_args += ['-DATCA_TA100_SUPPORT=ON'] + if sys.platform.startswith('linux'): + cmake_args += ['-DATCA_OPENSSL=ON'] + else: + cmake_args += ['-DATCA_TA100_AES_AUTH_SUPPORT=OFF'] if not nousb: cmake_args += ['-DATCA_HAL_KIT_HID=ON'] diff --git a/python/tests/cryptoauthlib_mock.py b/python/tests/cryptoauthlib_mock.py index 803062595..1f22ded40 100644 --- a/python/tests/cryptoauthlib_mock.py +++ b/python/tests/cryptoauthlib_mock.py @@ -1,4 +1,4 @@ -from ctypes import c_uint8, create_string_buffer, memmove, byref, cast, c_void_p, c_uint32, POINTER, c_size_t, sizeof +from ctypes import c_uint8, create_string_buffer, memmove, byref, cast, c_void_p, c_uint32, POINTER, c_size_t, sizeof, c_int from cryptoauthlib import * c_ptr = type(byref(create_string_buffer(1))) diff --git a/python/tests/test_iface.py b/python/tests/test_iface.py index 3986cc824..4c3e83a55 100644 --- a/python/tests/test_iface.py +++ b/python/tests/test_iface.py @@ -6,6 +6,7 @@ """ import pytest import ctypes +from cryptoauthlib.exceptions import UnsupportedInterface from cryptoauthlib.iface import * from cryptoauthlib.library import load_cryptoauthlib, get_size_by_name @@ -22,7 +23,7 @@ def test_iface_cfg_size(test_iface_init): def test_iface_cfg_ateccx08a_i2c(test_iface_init): try: cfg = cfg_ateccx08a_i2c_default() - except ValueError: + except UnsupportedInterface: pass else: assert cfg.iface_type == ATCAIfaceType.ATCA_I2C_IFACE @@ -35,7 +36,7 @@ def test_iface_cfg_ateccx08a_i2c(test_iface_init): def test_iface_cfg_ateccx08a_swi(test_iface_init): try: cfg = cfg_ateccx08a_swi_default() - except ValueError: + except UnsupportedInterface: pass else: assert cfg.iface_type == ATCAIfaceType.ATCA_SWI_IFACE @@ -46,7 +47,7 @@ def test_iface_cfg_ateccx08a_swi(test_iface_init): def test_iface_cfg_ateccx08a_kithid(test_iface_init): try: cfg = cfg_ateccx08a_kithid_default() - except ValueError: + except UnsupportedInterface: pass else: assert cfg.iface_type == ATCAIfaceType.ATCA_HID_IFACE @@ -58,7 +59,7 @@ def test_iface_cfg_ateccx08a_kithid(test_iface_init): def test_iface_cfg_atsha20xa_i2c(test_iface_init): try: cfg = cfg_atsha20xa_i2c_default() - except ValueError: + except UnsupportedInterface: pass else: assert cfg.iface_type == ATCAIfaceType.ATCA_I2C_IFACE @@ -71,7 +72,7 @@ def test_iface_cfg_atsha20xa_i2c(test_iface_init): def test_iface_cfg_atsha20xa_swi(test_iface_init): try: cfg = cfg_atsha20xa_swi_default() - except ValueError: + except UnsupportedInterface: pass else: assert cfg.iface_type == ATCAIfaceType.ATCA_SWI_IFACE @@ -82,7 +83,7 @@ def test_iface_cfg_atsha20xa_swi(test_iface_init): def test_iface_cfg_atsha20xa_kithid(test_iface_init): try: cfg = cfg_atsha20xa_kithid_default() - except ValueError: + except UnsupportedInterface: pass else: assert cfg.iface_type == ATCAIfaceType.ATCA_HID_IFACE diff --git a/release_notes.md b/release_notes.md index e655af62e..ae0231d28 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,6 +1,33 @@ # Microchip Cryptoauthlib Release Notes +## Release v3.3.0 (01/22/2021) + +### API Updates + - HAL API has been signifiantly revised to improve portability. This update + simplies the requirements of each HAL to only the physical transport + mechanisms. Please see the hal porting and library upgrading notes: + https://github.com/MicrochipTech/cryptoauthlib/wiki/Upgrading-to-v3.3 + - Internal structures have been updated by removing obsolete elements and + combining mandatory fields. This saves significant memory in both program + and data regions. + - Inclusive language update: all remaining legacy language elements have + been updated. Where this impacts the external API there is the option + ATCA_ENABLE_DEPRECATED to use the previous names. + +### New features + - ECC204 support has been added with one wire HAL support. + - ECC204, SHA206, one wire and single wire (uart and gpio) hals have been + added to the Harmony 3 configurator. + - PKCS11 support for symmetric (AES & HMAC) keys has been added and enabled + for additional mechanisms such as HMAC signing and AES encrypt/decrypt + +### Fixes + - pkcs11_token_init had several conditions that were corrected + - fix to detect differences in i2c clock rate specifications between flexcom + and sercom configurators in Harmony 3 and the emit the correct value for + the cryptoauthlib interface config structure. + ## Release v3.2.5 (11/30/2020) ### New features diff --git a/test/api_atcab/atca_tests_aes_ccm.c b/test/api_atcab/atca_tests_aes_ccm.c index 9b4f46f38..4debd6273 100644 --- a/test/api_atcab/atca_tests_aes_ccm.c +++ b/test/api_atcab/atca_tests_aes_ccm.c @@ -339,10 +339,10 @@ TEST(atca_cmd_basic_test, aes_ccm_auth_decrypt_partial) t_test_case_info aes_ccm_basic_test_info[] = { #ifdef ATCA_ATECC608_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_encrypt), DEVICE_MASK(ATECC608A) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_encrypt_partial), DEVICE_MASK(ATECC608A) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_decrypt), DEVICE_MASK(ATECC608A) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_decrypt_partial), DEVICE_MASK(ATECC608A) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_encrypt), DEVICE_MASK(ATECC608A) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_encrypt_partial), DEVICE_MASK(ATECC608A) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_decrypt), DEVICE_MASK(ATECC608A) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_decrypt_partial), DEVICE_MASK(ATECC608A) }, #endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; diff --git a/test/api_atcab/atca_tests_startup.c b/test/api_atcab/atca_tests_startup.c index e1b3397d6..caae71a0d 100644 --- a/test/api_atcab/atca_tests_startup.c +++ b/test/api_atcab/atca_tests_startup.c @@ -27,28 +27,6 @@ #include #include "atca_test.h" -TEST(atca_cmd_unit_test, wake_sleep) -{ - ATCA_STATUS status; - - status = atwake(_gDevice->mIface); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - status = atsleep(_gDevice->mIface); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -} - -TEST(atca_cmd_unit_test, wake_idle) -{ - ATCA_STATUS status; - - status = atwake(_gDevice->mIface); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - status = atidle(_gDevice->mIface); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -} - TEST(atca_cmd_basic_test, version) { char ver_str[20]; @@ -97,12 +75,5 @@ t_test_case_info startup_basic_test_info[] = { REGISTER_TEST_CASE(atca_cmd_basic_test, doubleinit), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, { (fp_test_case)NULL, (uint8_t)0 },/* Array Termination element*/ }; - -t_test_case_info startup_unit_test_info[] = -{ - { REGISTER_TEST_CASE(atca_cmd_unit_test, wake_sleep), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, wake_idle), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, - { (fp_test_case)NULL, (uint8_t)0 },/* Array Termination element*/ -}; // *INDENT-ON* diff --git a/test/api_calib/test_calib_commands.c b/test/api_calib/test_calib_commands.c deleted file mode 100644 index 2254068dd..000000000 --- a/test/api_calib/test_calib_commands.c +++ /dev/null @@ -1,1155 +0,0 @@ -/** - * \file - * \brief Cryptoauthlib Testing: CALIB "Unit" Tests - * - * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. - * - * \page License - * - * Subject to your compliance with these terms, you may use Microchip software - * and any derivatives exclusively with Microchip products. It is your - * responsibility to comply with third party license terms applicable to your - * use of third party software (including open source software) that may - * accompany Microchip software. - * - * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER - * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED - * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, - * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE - * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF - * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE - * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL - * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED - * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR - * THIS SOFTWARE. - */ - -#include "atca_test.h" -#include "test_calib.h" - -#if ATCA_CA_SUPPORT - -extern const uint8_t g_aes_keys[4][16]; -extern const uint8_t g_plaintext[64]; -extern const uint8_t g_ciphertext_ecb[4][64]; - -TEST(atca_cmd_unit_test, aes) -{ - ATCA_STATUS status; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - // build read command - packet.param1 = ATCA_ZONE_CONFIG; - packet.param2 = 0x0003; - - status = atRead(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - if ((packet.data[2] & AES_CONFIG_ENABLE_BIT_MASK) == 0) //packet.data[2] contains the AES enable bit - { - TEST_IGNORE_MESSAGE("Ignoring the test ,AES is not enabled in Configuration zone"); - } - - //build a nonce command (pass through mode) to store the aes key in tempkey - packet.param1 = NONCE_MODE_PASSTHROUGH; - packet.param2 = 0x0000; - memcpy(packet.data, g_aes_keys[0], ATCA_KEY_SIZE); // a 32-byte nonce - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_COUNT_LONG, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - // check for nonce response for pass through mode - TEST_ASSERT_EQUAL_INT8(ATCA_SUCCESS, packet.data[ATCA_RSP_DATA_IDX]); - - packet.param1 = AES_MODE_ENCRYPT; //selects encrypt mode and use first 16 byte data in tempkey as key - packet.param2 = 0xFFFF; - memcpy(packet.data, g_plaintext, AES_DATA_SIZE); // a 16-byte data to be encrypted - - status = atAES(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - TEST_ASSERT_EQUAL_MEMORY(g_ciphertext_ecb[0], &packet.data[ATCA_RSP_DATA_IDX], AES_DATA_SIZE); - - packet.param1 = AES_MODE_DECRYPT; //selects decrypt mode and use first 16 byte data in tempkey as key - packet.param2 = 0xFFFF; - memcpy(packet.data, g_ciphertext_ecb[0], AES_DATA_SIZE); // a 16-byte data to be encrypted - - status = atAES(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - TEST_ASSERT_EQUAL_MEMORY(g_plaintext, &packet.data[ATCA_RSP_DATA_IDX], AES_DATA_SIZE); -} - -TEST(atca_cmd_unit_test, checkmac) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint16_t keyID = 0x0004; - static uint8_t response_mac[MAC_RSP_SIZE]; // Make the response buffer the size of a MAC response. - static uint8_t other_data[CHECKMAC_OTHER_DATA_SIZE]; // First four bytes of Mac command are needed for CheckMac command. - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - unit_test_assert_data_is_locked(); - - if (_gDevice->mIface->mIfaceCFG->devtype == ATSHA204A) - { - keyID = 0x0001; - } - else - { - keyID = 0x0004; - } - - // build a mac command - packet.param1 = MAC_MODE_CHALLENGE; - packet.param2 = keyID; - memset(packet.data, 0x55, 32); // a 32-byte challenge - - status = atMAC(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_RSP_SIZE_32, packet.data[ATCA_COUNT_IDX]); - memcpy(response_mac, packet.data, sizeof(response_mac)); - - // build a checkmac command - packet.param1 = MAC_MODE_CHALLENGE; - packet.param2 = keyID; - memset(packet.data, 0x55, 32); // a 32-byte challenge - memcpy(&packet.data[32], &response_mac[1], 32); - memset(other_data, 0, sizeof(other_data)); - other_data[0] = ATCA_MAC; - other_data[2] = (uint8_t)keyID; - memcpy(&packet.data[64], other_data, sizeof(other_data)); - - status = atCheckMAC(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(CHECKMAC_RSP_SIZE, packet.data[ATCA_COUNT_IDX]); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); -} - -TEST(atca_cmd_unit_test, counter) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint8_t increased_bin_val[4] = { 0x00 }; - uint32_t test; - ATCACommand ca_cmd = _gDevice->mCommands; - - // build a counter command - packet.param1 = COUNTER_MODE_INCREMENT; - packet.param2 = 0x0000; - status = atCounter(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(COUNTER_RSP_SIZE, packet.data[ATCA_COUNT_IDX]); - memcpy(increased_bin_val, &packet.data[ATCA_RSP_DATA_IDX], sizeof(increased_bin_val)); - - // build a counter command - packet.param1 = COUNTER_MODE_READ; - packet.param2 = 0x0000; - status = atCounter(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_MEMORY(increased_bin_val, &packet.data[ATCA_RSP_DATA_IDX], 4); - memcpy(&test, &packet.data[ATCA_RSP_DATA_IDX], 4); -} - -TEST(atca_cmd_unit_test, derivekey) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint16_t keyID = 9; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - - //build a nonce command - packet.param1 = NONCE_MODE_SEED_UPDATE; - packet.param2 = 0x0000; - memset(packet.data, 0x00, 32); - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_COUNT_SHORT, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_LONG, packet.data[ATCA_COUNT_IDX]); - - // build a deriveKey command (Roll Key operation) - packet.param1 = 0; - packet.param2 = keyID; - status = atDeriveKey(ca_cmd, &packet, true); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - // check for derive key response if it's success or not - TEST_ASSERT_EQUAL_INT8(ATCA_SUCCESS, packet.data[ATCA_RSP_DATA_IDX]); -} - -TEST(atca_cmd_unit_test, ecdh) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint8_t sn[9]; - uint16_t private_key_id_bob = 0; - uint8_t public_key_bob[ATCA_PUB_KEY_SIZE]; - uint8_t pms_bob[ATCA_KEY_SIZE]; - uint16_t pms_read_key_id_bob = 4; - uint16_t private_key_id_alice = 2; - uint8_t public_key_alice[ATCA_PUB_KEY_SIZE]; - uint8_t pms_alice[ATCA_KEY_SIZE]; - uint8_t num_in[NONCE_NUMIN_SIZE]; - uint8_t rand_out[RANDOM_NUM_SIZE]; - atca_temp_key_t temp_key; - atca_nonce_in_out_t nonce_params; - atca_gen_dig_in_out_t gen_dig_params; - int i; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_data_is_locked(); - - // Read SN - packet.param1 = ATCA_ZONE_CONFIG | ATCA_ZONE_READWRITE_32; - packet.param2 = 0; - status = atRead(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_KEY_SIZE + 3, packet.data[ATCA_COUNT_IDX]); - - memcpy(&sn[0], &packet.data[ATCA_RSP_DATA_IDX], 4); - memcpy(&sn[4], &packet.data[ATCA_RSP_DATA_IDX + 8], 5); - - // Generate key pair for bob - packet.param1 = GENKEY_MODE_PRIVATE; - packet.param2 = private_key_id_bob; - status = atGenKey(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_PUB_KEY_SIZE + 3, packet.data[ATCA_COUNT_IDX]); - memcpy(public_key_bob, &packet.data[ATCA_RSP_DATA_IDX], ATCA_PUB_KEY_SIZE); - - // Generate key pair for alice - packet.param1 = GENKEY_MODE_PRIVATE; - packet.param2 = private_key_id_alice; - status = atGenKey(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_PUB_KEY_SIZE + 3, packet.data[ATCA_COUNT_IDX]); - memcpy(public_key_alice, &packet.data[ATCA_RSP_DATA_IDX], ATCA_PUB_KEY_SIZE); - - // Perform ECDH operation on bob's side - packet.param1 = ECDH_PREFIX_MODE; - packet.param2 = private_key_id_bob; - memcpy(packet.data, public_key_alice, sizeof(public_key_alice)); - status = atECDH(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(4, packet.data[ATCA_COUNT_IDX]); - - // Bob's PMS is written to the next slot, read that value - - //packet.param1 = ATCA_ZONE_DATA | ATCA_ZONE_READWRITE_32; - //packet.param2 = 4 << 3; - //memcpy(packet.data, g_slot4_key, 32); - //status = atWrite(ca_cmd, &packet); - //TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - //status = atca_execute_command(&packet, _gDevice); - //TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - // Random nonce - memset(&temp_key, 0, sizeof(temp_key)); - memset(num_in, 0, sizeof(num_in)); - memset(&nonce_params, 0, sizeof(nonce_params)); - nonce_params.mode = NONCE_MODE_SEED_UPDATE; - nonce_params.zero = 0; - nonce_params.num_in = num_in; - nonce_params.rand_out = rand_out; - nonce_params.temp_key = &temp_key; - packet.param1 = nonce_params.mode; - packet.param2 = nonce_params.zero; - memcpy(packet.data, nonce_params.num_in, NONCE_NUMIN_SIZE); - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(RANDOM_NUM_SIZE + 3, packet.data[ATCA_COUNT_IDX]); - memcpy(rand_out, &packet.data[ATCA_RSP_DATA_IDX], RANDOM_NUM_SIZE); - - // Perform host-side nonce calculation - status = atcah_nonce(&nonce_params); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - // GenDig with Bob's PMS Read Key - memset(&gen_dig_params, 0, sizeof(gen_dig_params)); - gen_dig_params.zone = ATCA_ZONE_DATA; - gen_dig_params.key_id = pms_read_key_id_bob; - gen_dig_params.is_key_nomac = false; - gen_dig_params.sn = sn; - gen_dig_params.stored_value = g_slot4_key; - gen_dig_params.other_data = NULL; - gen_dig_params.temp_key = &temp_key; - packet.param1 = gen_dig_params.zone; - packet.param2 = gen_dig_params.key_id; - status = atGenDig(ca_cmd, &packet, false); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - // Perform host-side nonce calculation - status = atcah_gen_dig(&gen_dig_params); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - // Encrypted read - packet.param1 = ATCA_ZONE_DATA | ATCA_ZONE_READWRITE_32; - packet.param2 = (private_key_id_bob + 1) << 3; - status = atRead(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_KEY_SIZE + 3, packet.data[ATCA_COUNT_IDX]); - - // Decrypt bob's PMS - for (i = 0; i < ATCA_KEY_SIZE; i++) - { - pms_bob[i] = packet.data[ATCA_RSP_DATA_IDX + i] ^ temp_key.value[i]; - } - - // Perform ECDH operation on alice's side - packet.param1 = ECDH_PREFIX_MODE; - packet.param2 = private_key_id_alice; - memcpy(packet.data, public_key_bob, sizeof(public_key_bob)); - status = atECDH(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_KEY_SIZE + 3, packet.data[ATCA_COUNT_IDX]); - - // Alice's PMS is returned in the clear - memcpy(pms_alice, &packet.data[ATCA_RSP_DATA_IDX], ATCA_KEY_SIZE); - - TEST_ASSERT_EQUAL_MEMORY(pms_bob, pms_alice, ATCA_KEY_SIZE); -} - -TEST(atca_cmd_unit_test, gendig) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint16_t keyID = 0x0004; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - - //build a nonce command (pass through mode) - packet.param1 = NONCE_MODE_PASSTHROUGH; - packet.param2 = 0x0000; - memset(packet.data, 0x55, 32); // a 32-byte nonce - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL_INT(NONCE_COUNT_LONG, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - // check for nonce response for pass through mode - TEST_ASSERT_EQUAL_INT8(ATCA_SUCCESS, packet.data[ATCA_RSP_DATA_IDX]); - - //build a gendig command - packet.param1 = GENDIG_ZONE_DATA; - packet.param2 = keyID; - - status = atGenDig(ca_cmd, &packet, false); - TEST_ASSERT_EQUAL_INT(GENDIG_COUNT, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); -} - -TEST(atca_cmd_unit_test, genkey) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint16_t keyID = 0; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - - // build a genkey command - packet.param1 = 0x04; // a random private key is generated and stored in slot keyID - packet.param2 = keyID; - status = atGenKey(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_PUB_KEY_SIZE + 3, packet.data[ATCA_COUNT_IDX]); -} - -TEST(atca_cmd_unit_test, hmac) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint16_t keyID = 0x01; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - - //-- Start Optionally run GenDig command - packet.param1 = NONCE_MODE_PASSTHROUGH; - packet.param2 = 0x0000; - memset(packet.data, 0x55, 32); - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_COUNT_LONG, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - TEST_ASSERT_EQUAL_INT8(ATCA_SUCCESS, packet.data[ATCA_RSP_DATA_IDX]); - - packet.param1 = GENDIG_ZONE_DATA; - packet.param2 = keyID; - status = atGenDig(ca_cmd, &packet, false); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(GENDIG_COUNT, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - //-- Option Test End - - // build a random command - packet.param1 = RANDOM_SEED_UPDATE; - packet.param2 = 0x0000; - status = atRandom(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_RSP_SIZE_32, packet.data[ATCA_COUNT_IDX]); - - - //build a nonce command - packet.param1 = NONCE_MODE_SEED_UPDATE; - packet.param2 = 0x0000; - memset(packet.data, 0x55, 32); // a 32-byte nonce - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - // build a HMAC command - packet.param1 = ATCA_ZONE_DATA; - packet.param2 = keyID; - status = atHMAC(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - // check if the response has the 32 bytes HMAC digest - TEST_ASSERT_EQUAL(ATCA_RSP_SIZE_32, packet.data[ATCA_COUNT_IDX]); - - atca_delay_ms(1); -} - -TEST(atca_cmd_unit_test, info) -{ - ATCA_STATUS status; - ATCAPacket packet; - - uint32_t devrev = 0; - uint32_t devrev_min = 0; - uint32_t devrev_max = 0; - ATCACommand ca_cmd = _gDevice->mCommands; - - // build an info command - packet.param1 = INFO_MODE_REVISION; // these tests are for communication testing mainly, - // but if testing the entire chip, would need to go through all the modes. - // this tests version mode only - status = atInfo(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_RSP_SIZE_4, packet.data[ATCA_COUNT_IDX]); - - switch (gCfg->devtype) - { - case ATSHA204A: - devrev_min = 0x00020008; - devrev_max = 0x000200FF; - break; - case ATECC108A: - devrev_min = 0x00001002; - devrev_max = 0x000010FF; - break; - case ATECC508A: - devrev_min = 0x00005000; - devrev_max = 0x000050FF; - break; - case ATECC608: - devrev_min = 0x00006000; - devrev_max = 0x000060FF; - break; - default: - TEST_FAIL_MESSAGE("Unknown device type"); - break; - } - - devrev = ((uint32_t)packet.data[1] << 24) | - ((uint32_t)packet.data[2] << 16) | - ((uint32_t)packet.data[3] << 8) | - ((uint32_t)packet.data[4] << 0); - - if (devrev < devrev_min || devrev > devrev_max) - { - TEST_FAIL_MESSAGE("Unexpected DevRev"); - } -} - -TEST(atca_cmd_unit_test, kdf) -{ - - ATCA_STATUS status = ATCA_GEN_FAIL; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - uint8_t data_input_32[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; - - uint8_t nonce[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; - - unit_test_assert_data_is_locked(); - - // build read command - packet.param1 = ATCA_ZONE_CONFIG; - packet.param2 = 0x0003; - - status = atRead(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - if ((packet.data[2] & AES_CONFIG_ENABLE_BIT_MASK) == 0) //packet.data[2] contains the AES enable bit - { - TEST_IGNORE_MESSAGE("Ignoring the test, AES is not enabled in Configuration zone"); - } - - //32 bytes key in Alternate key buffer ,32 bytes data in and 32 byte data out in tempkey - packet.param1 = NONCE_MODE_PASSTHROUGH | NONCE_MODE_TARGET_ALTKEYBUF; - packet.param2 = 0x0000; - memcpy(packet.data, nonce, 32); // a 32-byte nonce - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(NONCE_COUNT_LONG, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - // check for nonce response for pass through mode - TEST_ASSERT_EQUAL(ATCA_SUCCESS, packet.data[1]); - - packet.param1 = KDF_MODE_ALG_AES | KDF_MODE_SOURCE_ALTKEYBUF | KDF_MODE_TARGET_TEMPKEY; - packet.param2 = 0x0000; - memset(packet.data, 0x00, 4); // a 4 byte details related to AES - memcpy(&packet.data[4], data_input_32, 32); // a 32 byte input data to AES KDF - packet.txsize = ATCA_CMD_SIZE_MIN + KDF_DETAILS_SIZE + AES_DATA_SIZE; - status = atKDF(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -} - -TEST(atca_cmd_unit_test, lock) -{ - /* Implementation not available at this time */ -} - -TEST(atca_cmd_unit_test, mac) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint16_t keyID = 0x01; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - - // build a mac command - packet.param1 = MAC_MODE_CHALLENGE; - packet.param2 = keyID; - memset(packet.data, 0x55, 32); // a 32-byte challenge - - //memcpy(packet.data, challenge, sizeof(challenge)); - status = atMAC(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - atca_delay_ms(1); -} - -TEST(atca_cmd_unit_test, nonce) -{ - ATCA_STATUS status; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - //build a nonce command (pass through mode) - packet.param1 = NONCE_MODE_PASSTHROUGH; - packet.param2 = 0x0000; - memset(packet.data, 0x55, 32); // a 32-byte nonce - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_COUNT_LONG, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - // check for nonce response for pass through mode - TEST_ASSERT_EQUAL_INT8(ATCA_SUCCESS, packet.data[ATCA_RSP_DATA_IDX]); -} - -TEST(atca_cmd_unit_test, otp_zero) -{ - /* Not applicable... Leaving it as place holder */ -} - -TEST(atca_cmd_unit_test, pause) -{ - ATCA_STATUS status; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - // build a pause command - packet.param1 = 0x00; - packet.param2 = 0x0000; - - status = atPause(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(PAUSE_COUNT, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(PAUSE_RSP_SIZE, packet.data[ATCA_COUNT_IDX]); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); - - atca_delay_ms(1); -} - -TEST(atca_cmd_unit_test, privwrite) -{ - ATCA_STATUS status; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - unit_test_assert_data_is_unlocked(); - - // build an PrivWrite command - packet.param1 = 0x00; - packet.param2 = 0x0000; - memset(&packet.data[4], 0x55, 32); - - status = atPrivWrite(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(PRIVWRITE_RSP_SIZE, packet.data[ATCA_COUNT_IDX]); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); - - atca_delay_ms(1); -} - -TEST(atca_cmd_unit_test, random) -{ - ATCA_STATUS status; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - // build an random command - packet.param1 = RANDOM_SEED_UPDATE; - packet.param2 = 0x0000; - status = atRandom(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_RSP_SIZE_32, packet.data[ATCA_COUNT_IDX]); - - atca_delay_ms(1); -} - -TEST(atca_cmd_unit_test, read) -{ - ATCA_STATUS status; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - // build read command - packet.param1 = ATCA_ZONE_CONFIG; - packet.param2 = 0x0000; - - status = atRead(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(0x07, packet.data[ATCA_COUNT_IDX]); -} - -#ifdef ATCA_ATECC608_SUPPORT -extern const uint8_t sboot_dummy_image[]; - -TEST(atca_cmd_unit_test, sboot) -{ - - ATCA_STATUS status; - ATCAPacket packet; - const uint16_t private_key_id = 2; - uint8_t public_key[72]; - uint8_t zone; - uint16_t addr = 0x00; - uint8_t digest[ATCA_KEY_SIZE]; - uint8_t signature[ATCA_SIG_SIZE]; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_data_is_locked(); - - - //Generating the public key with the private key in slot - packet.param1 = GENKEY_MODE_PRIVATE; - packet.param2 = private_key_id; - status = atGenKey(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_PUB_KEY_SIZE + 3, packet.data[ATCA_COUNT_IDX]); - memcpy(public_key, &packet.data[ATCA_RSP_DATA_IDX], ATCA_PUB_KEY_SIZE); - - // Reformat public key into padded format - memmove(&public_key[40], &public_key[32], 32); // Move Y to padded position - memset(&public_key[36], 0, 4); // Add Y padding bytes - memmove(&public_key[4], &public_key[0], 32); // Move X to padded position - memset(&public_key[0], 0, 4); // Add X padding bytes - - //Writing the first 32 bytes of padded public key to slot 11 - zone = ATCA_ZONE_DATA | ATCA_ZONE_READWRITE_32; - addr = 0x58; - // build a write command to the data zone - packet.param1 = zone; - packet.param2 = addr; - memset(packet.data, 0x00, sizeof(packet.data)); - memcpy(packet.data, public_key, 32); - - status = atWrite(ca_cmd, &packet, false); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); - - //Writing the second 32 bytes of padded public key to slot 11 - zone = ATCA_ZONE_DATA | ATCA_ZONE_READWRITE_32; - addr = 0x158; - // build a write command to the data zone - packet.param1 = zone; - packet.param2 = addr; - memset(packet.data, 0x00, sizeof(packet.data)); - memcpy(packet.data, &public_key[32], 32); - - status = atWrite(ca_cmd, &packet, false); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); - - //Writing the next 4 bytes of padded public key to slot 11 - zone = ATCA_ZONE_DATA; - addr = 0x258; - // build a write command to the data zone - packet.param1 = zone; - packet.param2 = addr; - memset(packet.data, 0x00, sizeof(packet.data)); - memcpy(packet.data, &public_key[64], 4); - - status = atWrite(ca_cmd, &packet, false); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); - - - //Writing the next 4 bytes of padded public key to slot 11 - zone = ATCA_ZONE_DATA; - addr = 0x259; - // build a write command to the data zone - packet.param1 = zone; - packet.param2 = addr; - memset(packet.data, 0x00, sizeof(packet.data)); - memcpy(packet.data, &public_key[68], 4); - - status = atWrite(ca_cmd, &packet, false); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); - - - - // initialize SHA calculation engine, initializes TempKey - packet.param1 = SHA_MODE_SHA256_START; - packet.param2 = 0x0000; - - status = atSHA(ca_cmd, &packet, 0); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(SHA_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, packet.data[ATCA_RSP_DATA_IDX]); - - - - // Update SHA calculation engine - packet.param1 = SHA_MODE_SHA256_UPDATE; - packet.param2 = 0x0000; - memcpy(packet.data, sboot_dummy_image, 64); - status = atSHA(ca_cmd, &packet, 64); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(SHA_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, packet.data[ATCA_RSP_DATA_IDX]); - - // Compute the SHA 256 digest if TempKey is loaded correctly - packet.param1 = SHA_MODE_SHA256_END; - packet.param2 = 0x0000; - status = atSHA(ca_cmd, &packet, 0); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(SHA_RSP_SIZE_LONG, packet.data[ATCA_COUNT_IDX]); - - // Copy the response into digest - memcpy(&digest[0], &packet.data[ATCA_RSP_DATA_IDX], SECUREBOOT_DIGEST_SIZE); - - - // build an random command - packet.param1 = RANDOM_SEED_UPDATE; - packet.param2 = 0x0000; - status = atRandom(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(ATCA_RSP_SIZE_32, packet.data[ATCA_COUNT_IDX]); - - // set up message to sign - //build a nonce command (pass through mode) - packet.param1 = NONCE_MODE_PASSTHROUGH; - packet.param2 = 0x0000; - memcpy(packet.data, digest, 32); // a 32-byte nonce - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_COUNT_LONG, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - // check for nonce response for pass through mode - TEST_ASSERT_EQUAL_INT8(ATCA_SUCCESS, packet.data[ATCA_RSP_DATA_IDX]); - - - // build a sign command - packet.param1 = SIGN_MODE_EXTERNAL; - packet.param2 = private_key_id; - status = atSign(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - // Copy the signature - memcpy(signature, &packet.data[ATCA_RSP_DATA_IDX], ATCA_SIG_SIZE); - - - // build a sboot command - packet.param1 = SECUREBOOT_MODE_FULL; - packet.param2 = 0; - memcpy(packet.data, digest, SECUREBOOT_DIGEST_SIZE); // a 32-byte Digest is copied to packet - memcpy(&packet.data[SECUREBOOT_DIGEST_SIZE], signature, ATCA_SIG_SIZE); // a 64-byte signature is copied to packet - status = atSecureBoot(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -} - -TEST(atca_cmd_unit_test, selftest) -{ - ATCA_STATUS status; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - packet.param1 = SELFTEST_MODE_RNG; - packet.param2 = 0x0000; - status = atSelfTest(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(SELFTEST_RSP_SIZE, packet.data[ATCA_COUNT_IDX]); -} -#endif - -TEST(atca_cmd_unit_test, sha) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint8_t sha_success = 0x00; - uint8_t sha_digest_out[ATCA_SHA_DIGEST_SIZE]; - ATCACommand ca_cmd = _gDevice->mCommands; - - // initialize SHA calculation engine, initializes TempKey - packet.param1 = SHA_MODE_SHA256_START; - packet.param2 = 0x0000; - - status = atSHA(ca_cmd, &packet, 0); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(SHA_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - // check the response, if error then TempKey not initialized - TEST_ASSERT_EQUAL_INT8(sha_success, packet.data[ATCA_RSP_DATA_IDX]); - - // Compute the SHA 256 digest if TempKey is loaded correctly - packet.param1 = SHA_MODE_SHA256_END; - packet.param2 = 0x0000; - - status = atSHA(ca_cmd, &packet, 0); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(SHA_RSP_SIZE_LONG, packet.data[ATCA_COUNT_IDX]); - - // Copy the response into digest_out - memcpy(&sha_digest_out[0], &packet.data[ATCA_RSP_DATA_IDX], ATCA_SHA_DIGEST_SIZE); -} - -TEST(atca_cmd_unit_test, sign) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint16_t keyID = 0; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - - // set up message to sign - //build a nonce command (pass through mode) - packet.param1 = NONCE_MODE_PASSTHROUGH; - packet.param2 = 0x0000; - memset(packet.data, 0x55, 32); // a 32-byte nonce - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL_INT(NONCE_COUNT_LONG, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - // check for nonce response for pass through mode - TEST_ASSERT_EQUAL_INT8(ATCA_SUCCESS, packet.data[ATCA_RSP_DATA_IDX]); - - // build a sign command - packet.param1 = SIGN_MODE_EXTERNAL; - packet.param2 = keyID; - status = atSign(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -} - -TEST(atca_cmd_unit_test, updateextra) -{ - ATCA_STATUS status; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - - // build a UpdateExtra command - packet.param1 = UPDATE_MODE_USER_EXTRA; - packet.param2 = 0x0000; - - status = atUpdateExtra(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(UPDATE_RSP_SIZE, packet.data[ATCA_COUNT_IDX]); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); -} - -TEST(atca_cmd_unit_test, verify) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint16_t keyID = 0x00; - uint8_t public_key[ATCA_PUB_KEY_SIZE]; - uint8_t signature[VERIFY_256_SIGNATURE_SIZE]; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - - // build a genkey command - packet.param1 = 0x04; // a random private key is generated and stored in slot keyID - packet.param2 = keyID; - status = atGenKey(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(GENKEY_RSP_SIZE_LONG, packet.data[ATCA_COUNT_IDX]); - - // copy the data response into the public key - memcpy(&public_key[0], &packet.data[ATCA_RSP_DATA_IDX], ATCA_PUB_KEY_SIZE); - - // build a random command - packet.param1 = RANDOM_SEED_UPDATE; - packet.param2 = 0x0000; - status = atRandom(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - - // build a nonce command (pass through mode) - packet.param1 = NONCE_MODE_PASSTHROUGH; - packet.param2 = 0x0000; - memset(packet.data, 0x55, 32); // a 32-byte nonce - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_COUNT_LONG, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - - // build a sign command - packet.param1 = SIGN_MODE_EXTERNAL; //verify the signature - packet.param2 = keyID; - status = atSign(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - // copy the data response into the signature - memcpy(&signature[0], &packet.data[ATCA_RSP_DATA_IDX], ATCA_SIG_SIZE); - - // build an random command - packet.param1 = RANDOM_SEED_UPDATE; - packet.param2 = 0x0000; - status = atRandom(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - - // build a nonce command (pass through mode) - packet.param1 = NONCE_MODE_PASSTHROUGH; - packet.param2 = 0x0000; - memset(packet.data, 0x55, 32); // a 32-byte nonce - - status = atNonce(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_COUNT_LONG, packet.txsize); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_INT(NONCE_RSP_SIZE_SHORT, packet.data[ATCA_COUNT_IDX]); - - - // build a verify command - packet.param1 = VERIFY_MODE_EXTERNAL; //verify the signature - packet.param2 = VERIFY_KEY_P256; - memcpy(&packet.data[0], signature, sizeof(signature)); - memcpy(&packet.data[64], public_key, sizeof(public_key)); - - status = atVerify(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); -} - -TEST(atca_cmd_unit_test, write) -{ - ATCA_STATUS status; - ATCAPacket packet; - uint8_t zone; - uint16_t addr = 0x00; - ATCACommand ca_cmd = _gDevice->mCommands; - - unit_test_assert_config_is_locked(); - - - zone = ATCA_ZONE_DATA | ATCA_ZONE_READWRITE_32; - addr = 0x20; // slot 4 - always writable per the config - - // build a write command to the data zone - packet.param1 = zone; - packet.param2 = addr; - memset(packet.data, 0x00, sizeof(packet.data)); - memcpy(packet.data, g_slot4_key, 32); - - status = atWrite(ca_cmd, &packet, false); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(0x00, packet.data[ATCA_RSP_DATA_IDX]); -} - - -t_test_case_info calib_commands_info[] = -{ - { REGISTER_TEST_CASE(atca_cmd_unit_test, aes), DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, checkmac), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, counter), DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, derivekey), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, ecdh), DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, gendig), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, genkey), DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, hmac), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, info), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, kdf), DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, mac), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, nonce), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, pause), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, privwrite), DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, random), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, read), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, -#ifdef ATCA_ATECC608_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_unit_test, sboot), DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, selftest), DEVICE_MASK(ATECC608) }, -#endif - { REGISTER_TEST_CASE(atca_cmd_unit_test, sha), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, sign), DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, updateextra), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, verify), DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_unit_test, write), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - /* Array Termination element*/ - { (fp_test_case)NULL, (uint8_t)0 }, -}; - -#endif diff --git a/test/api_calib/test_calib_config.c b/test/api_calib/test_calib_config.c index 53d1344b3..eeffd05c3 100644 --- a/test/api_calib/test_calib_config.c +++ b/test/api_calib/test_calib_config.c @@ -40,7 +40,7 @@ const uint8_t g_slot4_key[] = { uint8_t test_ecc608_configdata[ATCA_ECC_CONFIG_SIZE] = { 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x04, 0x05, 0x06, 0x07, 0xEE, 0x01, 0x01, 0x00, //15 - 0xC0, 0x00, 0xA1, 0x00, 0xAF, 0x2F, 0xC4, 0x44, 0x87, 0x20, 0xC4, 0xF4, 0x8F, 0x0F, 0x0F, 0x0F, //31, + 0xC0, 0x00, 0xA1, 0x00, 0xAF, 0x2F, 0xC4, 0x44, 0x87, 0x20, 0xC4, 0xF4, 0x8F, 0x0F, 0x0F, 0x0F, //31, 0x9F, 0x8F, 0x83, 0x64, 0xC4, 0x44, 0xC4, 0x64, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, //47 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, //63 0x00, 0x00, 0x00, 0x00, 0xFF, 0x84, 0x03, 0xBC, 0x09, 0x69, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, //79 @@ -62,14 +62,14 @@ const uint8_t test_ecc_configdata[ATCA_ECC_CONFIG_SIZE] = { static device_object_meta_t calib_config_object_data[] = { - {TEST_TYPE_ECC_SIGN, 2, NULL}, - {TEST_TYPE_ECC_VERIFY, 15, NULL}, - {TEST_TYPE_ECC_GENKEY, 2, NULL}, - {TEST_TYPE_ECDH, 0, NULL}, - {TEST_TYPE_AES, 10, NULL}, - {TEST_TYPE_HMAC, 4, NULL}, - {TEST_TYPE_DATA, 11, NULL}, - {0, 0, NULL} + { TEST_TYPE_ECC_SIGN, 2, NULL }, + { TEST_TYPE_ECC_VERIFY, 15, NULL }, + { TEST_TYPE_ECC_GENKEY, 2, NULL }, + { TEST_TYPE_ECDH, 0, NULL }, + { TEST_TYPE_AES, 10, NULL }, + { TEST_TYPE_HMAC, 4, NULL }, + { TEST_TYPE_DATA, 11, NULL }, + { 0, 0, NULL } }; ATCA_STATUS calib_config_get_slot_by_test(uint8_t test_type, uint16_t* handle) diff --git a/test/api_calib/test_calib_packet.c b/test/api_calib/test_calib_packet.c deleted file mode 100644 index ade68c909..000000000 --- a/test/api_calib/test_calib_packet.c +++ /dev/null @@ -1,71 +0,0 @@ -/** - * \file - * \brief Cryptoauthlib Testing: CALIB Packet Construction Tests - * - * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. - * - * \page License - * - * Subject to your compliance with these terms, you may use Microchip software - * and any derivatives exclusively with Microchip products. It is your - * responsibility to comply with third party license terms applicable to your - * use of third party software (including open source software) that may - * accompany Microchip software. - * - * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER - * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED - * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, - * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE - * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF - * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE - * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL - * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED - * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR - * THIS SOFTWARE. - */ - -#include "atca_test.h" -#include "test_calib.h" - -#if ATCA_CA_SUPPORT -TEST(atca_cmd_unit_test, crcerror) -{ - ATCA_STATUS status; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - if (_gDevice->mIface->mIfaceCFG->iface_type == ATCA_HID_IFACE) - { - TEST_IGNORE_MESSAGE("Kit protocol corrects CRC errors."); - } - if (_gDevice->mIface->mIfaceCFG->iface_type == ATCA_UART_IFACE) - { - TEST_IGNORE_MESSAGE("Kit protocol corrects CRC errors."); - } - - // build an info command - packet.param1 = INFO_MODE_REVISION; // these tests are for communication testing mainly, - // but if testing the entire chip, would need to go through all the modes. - // this tests version mode only - status = atInfo(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - // simulate the packet so CRC is broken - packet.data[0] = 0xff; - packet.data[1] = 0xff; - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_STATUS_CRC, status); - - // test to make sure CRC error is in the packet - TEST_ASSERT_EQUAL_INT8_MESSAGE(0x04, packet.data[0], "Failed error response length test"); - TEST_ASSERT_EQUAL_INT8_MESSAGE(0xff, packet.data[1], "Failed bad CRC test"); -} - - -t_test_case_info calib_packet_info[] = -{ - { REGISTER_TEST_CASE(atca_cmd_unit_test, crcerror), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, - /* Array Termination element*/ - { (fp_test_case)NULL, (uint8_t)0 }, -}; -#endif \ No newline at end of file diff --git a/test/atca_crypto_sw_tests.c b/test/atca_crypto_sw_tests.c index f444772bc..d6e4de2cc 100644 --- a/test/atca_crypto_sw_tests.c +++ b/test/atca_crypto_sw_tests.c @@ -70,9 +70,7 @@ int atca_crypto_sw_tests(int argc, char * argv[]) #if defined(ATCA_MBEDTLS) || defined(ATCA_OPENSSL) || defined(ATCA_WOLFSSL) RUN_TEST(test_atcac_aes128_gcm); RUN_TEST(test_atcac_aes128_cmac); -#endif -#ifdef ATCA_MBEDTLS RUN_TEST(test_atcac_public); /* Because it is not realistic to perform signature vector tests on real systems the verify test is executed first to ensure verify is working @@ -839,9 +837,7 @@ void test_atcac_verify_nist(void) } } } -#endif -#ifdef ATCA_MBEDTLS static uint8_t private_key_pem[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEICFZhAyzqkUgyheo51bhg3mcp+qwfl+koE+Mhs/sRyzBoAoGCCqGSM49\n" diff --git a/test/atca_test.c b/test/atca_test.c index ae028388c..d506ff3fa 100644 --- a/test/atca_test.c +++ b/test/atca_test.c @@ -40,7 +40,6 @@ const char* ATCA_TEST_HELPER_FILE = "In helper: " __FILE__; const char* TEST_GROUP_atca_cmd_basic_test = "atca_cmd_basic_test"; -const char* TEST_GROUP_atca_cmd_unit_test = "atca_cmd_unit_test"; bool g_atca_test_quiet_mode = false; @@ -139,15 +138,6 @@ t_test_case_info* basic_tests[] = (t_test_case_info*)NULL, /* Array Termination element*/ }; -#if ATCA_CA_SUPPORT -t_test_case_info* unit_tests[] = -{ - calib_commands_info, - calib_packet_info, - (t_test_case_info*)NULL, /* Array Termination element*/ -}; -#endif - t_test_case_info* otpzero_tests[] = { otpzero_basic_test_info, @@ -211,13 +201,6 @@ void RunAllBasicTests(void) RunAllTests(basic_tests); }; -void RunAllFeatureTests(void) -{ -#if ATCA_CA_SUPPORT - RunAllTests(unit_tests); -#endif -} - void RunBasicOtpZero(void) { RunAllTests(otpzero_tests); @@ -233,37 +216,6 @@ void RunTNGTests(void) RunAllTests(tng_tests); } -#if 0 // ATCA_CA_SUPPORT -static bool atcau_is_locked(uint8_t zone) -{ - ATCA_STATUS status = ATCA_GEN_FAIL; - ATCAPacket packet; - ATCACommand ca_cmd = _gDevice->mCommands; - - // build an read command - packet.param1 = 0x00; - packet.param2 = 0x15; - status = atRead(ca_cmd, &packet); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - status = atca_execute_command(&packet, _gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - switch (zone) - { - case LOCK_ZONE_DATA: - return packet.data[ATCA_RSP_DATA_IDX + 2] == 0; - break; - case LOCK_ZONE_CONFIG: - return packet.data[ATCA_RSP_DATA_IDX + 3] == 0; - break; - default: - TEST_FAIL_MESSAGE("Invalid lock zone"); - break; - } - return false; -} -#endif #ifdef ATCA_NO_HEAP ATCA_DLL ATCADevice _gDevice; @@ -272,72 +224,6 @@ ATCA_DLL struct atca_command g_atcab_command; ATCA_DLL struct atca_iface g_atcab_iface; #endif -/** - * \brief Initialize the interface and check it was successful - */ -void test_assert_interface_init() -{ -#ifdef ATCA_NO_HEAP - ATCA_STATUS status; -#endif - - // If the device is still connected - disconnect it - if (_gDevice) - { -#ifdef ATCA_NO_HEAP - status = releaseATCADevice(_gDevice); - _gDevice = NULL; -#else - deleteATCADevice(&_gDevice); - TEST_ASSERT_NULL_MESSAGE(_gDevice, ATCA_TEST_HELPER_FILE); -#endif - } - - // Get the device -#ifdef ATCA_NO_HEAP - g_atcab_device.mCommands = &g_atcab_command; - g_atcab_device.mIface = &g_atcab_iface; - status = initATCADevice(gCfg, &g_atcab_device); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - _gDevice = &g_atcab_device; -#else - _gDevice = newATCADevice(gCfg); - TEST_ASSERT_NOT_NULL_MESSAGE(_gDevice, ATCA_TEST_HELPER_FILE); -#endif - -#ifdef ATCA_ATECC608_SUPPORT - if (ATECC608 == (_gDevice->mCommands->dt)) - { - // Set the clock divider, which should be the same value as the test config - _gDevice->mCommands->clock_divider = test_ecc608_configdata[ATCA_CHIPMODE_OFFSET] & ATCA_CHIPMODE_CLOCK_DIV_MASK; - } -#endif -} - -/** - * \brief Clean up the allocated interface - */ -void test_assert_interface_deinit(void) -{ - ATCA_STATUS status; - - TEST_ASSERT((_gDevice != NULL) && (_gDevice->mIface != NULL)); - - status = atwake(_gDevice->mIface); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - status = atsleep(_gDevice->mIface); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - -#ifdef ATCA_NO_HEAP - status = releaseATCADevice(_gDevice); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - _gDevice = NULL; -#else - deleteATCADevice(&_gDevice); - TEST_ASSERT_NULL(_gDevice); -#endif -} void atca_test_assert_config_is_unlocked(UNITY_LINE_TYPE from_line) { @@ -472,6 +358,8 @@ ATCA_STATUS atca_test_config_get_id(uint8_t test_type, uint16_t* handle) case ATECC508A: /* fallthrough */ case ATECC608: + /* fallthrough */ + case ECC204: status = calib_config_get_slot_by_test(test_type, handle); break; #endif @@ -518,12 +406,3 @@ TEST_TEAR_DOWN(atca_cmd_basic_test) UnityMalloc_EndTest(); } -TEST_SETUP(atca_cmd_unit_test) -{ - test_assert_interface_init(); -} - -TEST_TEAR_DOWN(atca_cmd_unit_test) -{ - test_assert_interface_deinit(); -} diff --git a/test/atca_test.h b/test/atca_test.h index 72c7a05ed..a015db657 100644 --- a/test/atca_test.h +++ b/test/atca_test.h @@ -209,6 +209,7 @@ int select_108(int argc, char* argv[]); int select_508(int argc, char* argv[]); int select_608(int argc, char* argv[]); int select_ta100(int argc, char* argv[]); +int select_ecc204(int argc, char* argv[]); int certdata_unit_tests(int argc, char* argv[]); int certio_unit_tests(int argc, char* argv[]); diff --git a/test/atca_test_config.c b/test/atca_test_config.c index 61bbbb970..2566de7aa 100644 --- a/test/atca_test_config.c +++ b/test/atca_test_config.c @@ -34,6 +34,7 @@ extern int select_108_custom(int argc, char* argv[]); extern int select_508_custom(int argc, char* argv[]); extern int select_608_custom(int argc, char* argv[]); extern int select_ta100_custom(int argc, char* argv[]); +extern int select_ecc204_custom(int argc, char* argv[]); #endif /** gCfg must point to one of the cfg_ structures for any unit test to work. this allows @@ -56,7 +57,11 @@ ATCAIfaceCfg g_iface_config = { }, #else .atcai2c = { +#ifdef ATCA_ENABLE_DEPRECATED .slave_address = 0xC0, +#else + .address = 0xC0, +#endif .bus = 2, .baud = 400000, }, @@ -141,6 +146,15 @@ int select_ta100(int argc, char* argv[]) #endif } +int select_ecc204(int argc, char* argv[]) +{ +#if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ECC204_SUPPORT) + return select_ecc204_custom(argc, argv); +#else + return select_device(ECC204, NULL != argv); +#endif +} + /** \brief Sets the device the command or test suite will use * * \param[in] argc Number of arguments in the arg list @@ -314,7 +328,11 @@ static int opt_address(int argc, char* argv[]) } else if (ATCA_I2C_IFACE == gCfg->iface_type) { +#ifdef ATCA_ENABLE_DEPRECATED gCfg->atcai2c.slave_address = (uint8_t)val; +#else + gCfg->atcai2c.address = (uint8_t)val; +#endif } ret = 2; diff --git a/test/atca_test_console.c b/test/atca_test_console.c index b61e0cac7..4c5d75194 100644 --- a/test/atca_test_console.c +++ b/test/atca_test_console.c @@ -48,17 +48,6 @@ int run_basic_tests(int argc, char* argv[]) return run_test(argc, argv, RunAllBasicTests); } -int run_unit_tests(int argc, char* argv[]) -{ -#ifdef ATCA_ATECC608_SUPPORT - if (ATECC608 == (gCfg->devtype)) - { - check_clock_divider(argc, argv); - } -#endif - return run_test(argc, argv, RunAllFeatureTests); -} - int run_otpzero_tests(int argc, char* argv[]) { return run_test(argc, argv, RunBasicOtpZero); @@ -170,9 +159,9 @@ int do_randoms(int argc, char* argv[]) size_t displen = sizeof(displayStr); int i; - if (gCfg->devtype == ATSHA206A) + if ((gCfg->devtype == ATSHA206A) || (ECC204 == gCfg->devtype)) { - printf("ATSHA206A doesn't support random command\r\n"); + printf("Selected Device doesn't support random command\r\n"); return ATCA_GEN_FAIL; } @@ -205,41 +194,6 @@ int do_randoms(int argc, char* argv[]) return status; } -#if ATCA_CA_SUPPORT -int discover(int argc, char* argv[]) -{ - ATCAIfaceCfg ifaceCfgs[10]; - int i; - const char* devname[] = { "ATSHA204A", "ATECC108A", "ATECC508A", "ATECC608", "ATSHA206A" }; // indexed by ATCADeviceType - - for (i = 0; i < (int)(sizeof(ifaceCfgs) / sizeof(ATCAIfaceCfg)); i++) - { - ifaceCfgs[i].devtype = ATCA_DEV_UNKNOWN; - ifaceCfgs[i].iface_type = ATCA_UNKNOWN_IFACE; - } - - printf("Searching...\r\n"); - atcab_cfg_discover(ifaceCfgs, sizeof(ifaceCfgs) / sizeof(ATCAIfaceCfg)); - for (i = 0; i < (int)(sizeof(ifaceCfgs) / sizeof(ATCAIfaceCfg)); i++) - { - if (ifaceCfgs[i].devtype != ATCA_DEV_UNKNOWN) - { - printf("Found %s ", devname[ifaceCfgs[i].devtype]); - if (ifaceCfgs[i].iface_type == ATCA_I2C_IFACE) - { - printf("@ bus %d addr %02x", ifaceCfgs[i].atcai2c.bus, ifaceCfgs[i].atcai2c.slave_address); - } - if (ifaceCfgs[i].iface_type == ATCA_SWI_IFACE) - { - printf("@ bus %d", ifaceCfgs[i].atcaswi.bus); - } - printf("\r\n"); - } - } - - return 0; -} -#endif int info(int argc, char* argv[]) { @@ -521,13 +475,6 @@ int run_all_tests(int argc, char* argv[]) #ifndef DO_NOT_TEST_BASIC_UNIT if (!config_locked) { - fails += run_test(argc, argv, RunAllFeatureTests); - if (fails > 0) - { - printf("unit tests with config zone unlocked failed.\r\n"); - return status; - } - fails += run_test(argc, argv, RunAllBasicTests); if (fails > 0) { @@ -551,13 +498,6 @@ int run_all_tests(int argc, char* argv[]) if (!data_locked) { - fails += run_test(argc, argv, RunAllFeatureTests); - if (fails > 0) - { - printf("unit tests with data zone unlocked failed.\r\n"); - return status; - } - fails += run_test(argc, argv, RunAllBasicTests); if (fails > 0) { @@ -579,13 +519,6 @@ int run_all_tests(int argc, char* argv[]) } } - fails += run_test(argc, argv, RunAllFeatureTests); - if (fails > 0) - { - printf("unit tests with data zone locked failed.\r\n"); - return status; - } - fails += run_test(argc, argv, RunAllBasicTests); if (fails > 0) { diff --git a/test/cmd-processor.c b/test/cmd-processor.c index 86cba9ead..a5f42685c 100644 --- a/test/cmd-processor.c +++ b/test/cmd-processor.c @@ -61,23 +61,23 @@ static void call_exit(int argc, char* argv[]); static t_menu_info mas_menu_info[] = { { "help", "Display Menu", (fp_menu_handler)help }, -#if ATCA_CA_SUPPORT - { "discover", "Discover Buses and Devices", discover }, -#endif #ifdef ATCA_ATSHA204A_SUPPORT - { "204", "Set Target Device to ATSHA204A", select_204 }, + { "sha204", "Set Target Device to ATSHA204A", select_204 }, #endif #ifdef ATCA_ATSHA206A_SUPPORT - { "206", "Set Target Device to ATSHA206A", select_206 }, + { "sha206", "Set Target Device to ATSHA206A", select_206 }, #endif #ifdef ATCA_ATECC108A_SUPPORT - { "108", "Set Target Device to ATECC108A", select_108 }, + { "ecc108", "Set Target Device to ATECC108A", select_108 }, +#endif +#ifdef ATCA_ECC204_SUPPORT + { "ecc204", "Set Target Device to ECC204", select_ecc204 }, #endif #ifdef ATCA_ATECC508A_SUPPORT - { "508", "Set Target Device to ATECC508A", select_508 }, + { "ecc508", "Set Target Device to ATECC508A", select_508 }, #endif #ifdef ATCA_ATECC608_SUPPORT - { "608", "Set Target Device to ATECC608", select_608 }, + { "ecc608", "Set Target Device to ATECC608", select_608 }, #endif #ifdef ATCA_TA100_SUPPORT { "ta100", "Set Target Device to TA100", select_ta100 }, @@ -95,7 +95,6 @@ static t_menu_info mas_menu_info[] = { "tng", "Run unit tests on TNG type part.", (fp_menu_handler)run_tng_tests }, #ifndef DO_NOT_TEST_BASIC_UNIT { "basic", "Run Basic Test on Selected Device", (fp_menu_handler)run_basic_tests }, - { "unit", "Run Unit Test on Selected Device", (fp_menu_handler)run_unit_tests }, #ifdef ATCA_TEST_LOCK_ENABLE { "otpzero", "Zero Out OTP Zone", (fp_menu_handler)run_otpzero_tests }, #endif @@ -150,7 +149,7 @@ int parse_cmd_string(char* buffer, const size_t buf_len, const int argc, char* a { break; } - else if (isWhiteSpace(*c_ptr)) + else if (isBlankSpace(*c_ptr)) { *c_ptr = '\0'; if (in_arg) diff --git a/third_party/hal/esp32/LICENSE.txt b/third_party/hal/esp32/LICENSE.txt new file mode 100644 index 000000000..2d6ee55fa --- /dev/null +++ b/third_party/hal/esp32/LICENSE.txt @@ -0,0 +1,12 @@ +Copyright 2018 Espressif Systems (Shanghai) PTE LTD +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/lib/hal/hal_esp32_i2c.c b/third_party/hal/esp32/hal_esp32_i2c.c similarity index 100% rename from lib/hal/hal_esp32_i2c.c rename to third_party/hal/esp32/hal_esp32_i2c.c diff --git a/lib/hal/hal_esp32_timer.c b/third_party/hal/esp32/hal_esp32_timer.c similarity index 100% rename from lib/hal/hal_esp32_timer.c rename to third_party/hal/esp32/hal_esp32_timer.c