/** * @file ex_misc.c * @author NXP Semiconductors * @version 1.0 * @par License * * Copyright 2016 NXP * SPDX-License-Identifier: Apache-2.0 * * @par Description */ #include #include #include #include #include "a71ch_ex.h" #include "ax_util.h" #include "a71_debug.h" #include "sm_types.h" #include "sm_apdu.h" #include "tst_sm_util.h" #include "tst_a71ch_util.h" #include "axHostCrypto.h" static U8 exGetModuleInfo(U8 initMode); static U8 exGetRandom(U8 initMode); static U8 exGetSha256(void); static U8 exSendApdu(void); static U8 exGetUniqueID(U8 initMode); static U8 exCredentialInfo(U8 initMode); // #define WORKAROUND_SHA256_BUG /** * Demonstrate miscelaneous module functionality: * - ::exGetModuleInfo * - ::exGetRandom * - ::exGetUniqueID * - ::exGetSha256 * - ::exSendApdu * - ::exCredentialInfo * */ U8 exMisc() { U8 result = 1; sm_printf(CONSOLE, "\r\n-----------\r\nStart exMisc()\r\n------------\r\n"); DEV_ClearChannelState(); // Without channel encryption result &= exGetRandom(INIT_MODE_RESET); result &= exGetUniqueID(INIT_MODE_RESET); result &= exGetModuleInfo(INIT_MODE_NO_RESET); result &= exGetSha256(); result &= exSendApdu(); result &= exCredentialInfo(INIT_MODE_NO_RESET); // With channel encryption result &= exGetRandom(INIT_MODE_NO_RESET_DO_SCP03); result &= exGetUniqueID(INIT_MODE_NO_RESET); result &= exGetModuleInfo(INIT_MODE_NO_RESET); result &= exCredentialInfo(INIT_MODE_NO_RESET); sm_printf(CONSOLE, "\r\n-----------\r\nEnd exMisc(), result = %s\r\n------------\r\n", ((result == 1)? "OK": "FAILED")); return result; } /// @cond #define BLOCKSIZE_RND_ARRAY 64 #define BLOCKS_RND_ARRAY 4 #define MAX_RND_ARRAY (BLOCKSIZE_RND_ARRAY * BLOCKS_RND_ARRAY) /// @endcond /** * Demonstrate requesting a byte array with random data from the A71CH * * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter */ static U8 exGetRandom(U8 initMode) { U8 result = 1; U16 err; U8 random[MAX_RND_ARRAY]; int j = 0; sm_printf(CONSOLE, "\r\n-----------\r\nStart exGetRandom(%s)\r\n------------\r\n", getInitModeAsString(initMode)); // Initialize the A71CH (Debug mode restrictions may apply) result &= a71chInitModule(initMode); assert(result); for (j=1; j<=BLOCKS_RND_ARRAY; j++) { U16 swExpected = SW_OK; U16 maxPayload = ( a71chScp03Requested(initMode) == 1 ) ? A71CH_SCP03_MAX_PAYLOAD_SIZE : 255; U8 randomLen = (U8)(j*BLOCKSIZE_RND_ARRAY - 1); sm_printf(CONSOLE, "A71_GetRandom(%d)\r\n", randomLen); err = A71_GetRandom(random, randomLen); swExpected = (randomLen <= maxPayload) ? SW_OK : SW_WRONG_DATA; result &= AX_CHECK_SW(err, swExpected, "err"); if (err == SW_OK) { axPrintByteArray("random", random, randomLen, AX_COLON_32); } } // Run border cases for (j=(A71CH_SCP03_MAX_PAYLOAD_SIZE-2); j<(A71CH_SCP03_MAX_PAYLOAD_SIZE+2); j++) { U16 swExpected = SW_OK; U16 maxPayload = ( a71chScp03Requested(initMode) == 1 ) ? A71CH_SCP03_MAX_PAYLOAD_SIZE : 255; U8 randomLen = (U8)(j); sm_printf(CONSOLE, "A71_GetRandom(%d)\r\n", randomLen); err = A71_GetRandom(random, randomLen); swExpected = (randomLen <= maxPayload) ? SW_OK : SW_WRONG_DATA; result &= AX_CHECK_SW(err, swExpected, "err"); if (err == SW_OK) { axPrintByteArray("random", random, randomLen, AX_COLON_32); } } sm_printf(CONSOLE, "\r\n-----------\r\nEnd exGetRandom(%s), result = %s\r\n------------\r\n", getInitModeAsString(initMode), ((result == 1)? "OK": "FAILED")); assert(result); return result; } /** * Demonstrate requesting the A71CH's unique identifier and the cert uid (which is derived from the A71CH unique identifier) * * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter */ static U8 exGetUniqueID(U8 initMode) { U8 result = 1; U16 err; U8 uid[A71CH_MODULE_UNIQUE_ID_LEN] = {0}; U16 uidLen = sizeof(uid); U8 certUid[A71CH_MODULE_CERT_UID_LEN] = {0}; U16 certUidLen = sizeof(certUid); sm_printf(CONSOLE, "\r\n-----------\r\nStart exGetUniqueID(%s)\r\n------------\r\n", getInitModeAsString(initMode)); // Initialize the A71CH (Debug mode restrictions may apply) result &= a71chInitModule(initMode); assert(result); sm_printf(CONSOLE, "A71_GetUniqueID().\r\n"); err = A71_GetUniqueID(uid, &uidLen); result &= AX_CHECK_SW(err, SW_OK, "err"); axPrintByteArray("uid", uid, uidLen, AX_COLON_32); sm_printf(CONSOLE, "A71_GetCertUid().\r\n"); err = A71_GetCertUid(certUid, &certUidLen); result &= AX_CHECK_SW(err, SW_OK, "err"); axPrintByteArray("certUid", certUid, certUidLen, AX_COLON_32); sm_printf(CONSOLE, "\r\n-----------\r\nEnd exGetUniqueID(%s), result = %s\r\n------------\r\n", getInitModeAsString(initMode), ((result == 1)? "OK": "FAILED")); assert(result); return result; } /** * Demonstrate requesting the A71CH's module info * * @param[in] initMode Visit the documentation of ::a71chInitModule for more information on this parameter */ static U8 exGetModuleInfo(U8 initMode) { U8 result = 1; U8 scpChannelStateDummy = 0; sm_printf(CONSOLE, "\r\n-----------\r\nStart exGetModuleInfo(%s)\r\n------------\r\n", getInitModeAsString(initMode)); // Initialize the A71CH (Debug mode restrictions may apply) result &= a71chInitModule(initMode); assert(result); result &= a71chShowModuleInfo(&scpChannelStateDummy); sm_printf(CONSOLE, "\r\n-----------\r\nEnd exGetModuleInfo(%s), result = %s\r\n------------\r\n", getInitModeAsString(initMode), ((result == 1)? "OK": "FAILED")); assert(result); return result; } /// @cond #define BLOCKSIZE_DATA_ARRAY 64 #ifdef WORKAROUND_SHA256_BUG #define BLOCKS_DATA_ARRAY 3 #else #define BLOCKS_DATA_ARRAY 10 #endif #define MAX_DATA_ARRAY (BLOCKSIZE_DATA_ARRAY * BLOCKS_DATA_ARRAY) /// @endcond /** * Demonstrate calculating a SHA256 on the A71CH * */ static U8 exGetSha256() { U8 result = 1; U16 err; U8 data[MAX_DATA_ARRAY]; U8 shaBuf[32]; U16 shaBufLen = sizeof(shaBuf); U8 shaHostBuf[32]; U16 shaHostBufLen = sizeof(shaHostBuf); int j = 0; int i = 0; int nRet; sm_printf(CONSOLE, "\r\n-----------\r\nStart exGetSha256()\r\n------------\r\n"); for (j=1; j<=BLOCKS_DATA_ARRAY; j++) { U16 dataLen = (U16)(j*BLOCKSIZE_DATA_ARRAY - 1); for (i=0; i