/** * @file configCliSet.c * @author NXP Semiconductors * @version 1.0 * @par License * * Copyright 2017 NXP * SPDX-License-Identifier: Apache-2.0 * * @par Description * Command line handling 'set' entry */ #include #include #include #include // project specific include files #include "sm_types.h" #include "sm_apdu.h" #include "tst_sm_util.h" #include "tst_a71ch_util.h" #include "probeAxUtil.h" #include "configCli.h" #include "configCmd.h" #include "axHostCrypto.h" #include "tstHostCrypto.h" #define FLOW_VERBOSE_PROBE_A70 #ifdef FLOW_VERBOSE_PROBE_A70 #define FPRINTF(...) printf (__VA_ARGS__) #else #define FPRINTF(...) #endif // #define DBG_PROBE_A70 #ifdef DBG_PROBE_A70 #define DBGPRINTF(...) printf (__VA_ARGS__) #else #define DBGPRINTF(...) #endif int a7xConfigCmdCheckWrapping(U8 * key, U16 * keyLen, int argc, char **argv, int * argCurrent) { int nRet; U8 wrapKey[32]; U16 wrapKeyLen = sizeof(wrapKey); U8 wrappedKey[72]; U16 wrappedKeyLen = sizeof(wrappedKey); U16 ret = 0; nRet = 0; nRet = axCliGetHexString("w", "", wrapKey, &wrapKeyLen, 16, 32, argc, argv, argCurrent); if (nRet != AX_CLI_EXEC_OK) { wrapKeyLen = 0; } if (wrapKeyLen != 0) { if (*keyLen == 65) { // public key ret = HOSTCRYPTO_AesWrapKeyRFC3394(wrapKey, wrapKeyLen, wrappedKey, &wrappedKeyLen, key+1, (*keyLen)-1); } else { ret = HOSTCRYPTO_AesWrapKeyRFC3394(wrapKey, wrapKeyLen, wrappedKey, &wrappedKeyLen, key, *keyLen); } if (ret == SW_OK) { *keyLen = wrappedKeyLen; memcpy(key, wrappedKey, wrappedKeyLen); } else { return AX_CLI_WRAP_ERROR; } } return AX_CLI_EXEC_OK; } // printf(" set cnt -x -h \n"); // printf(" set gp -h -h \n"); // printf(" set gp -h -c \n"); // printf(" set pair -x [-k | -h -h ]\n"); // printf(" set pub -x [-k | -h ]\n"); // printf(" set sym -x -h \n"); int a7xConfigCliCmdSet(int argc, char **argv, U16 *sw) { int nRet = AX_CLI_EXEC_FAILED; int argCurrent = 1; int index = 0; U8 offsetArray[4]; U16 offsetArrayLen = sizeof(offsetArray); U16 offset = 0; U8 gpData[32]; U16 gpDataLen = sizeof(gpData); eccKeyComponents_t eccKcTls; U8 cnt[4]; U16 cntLen = sizeof(cnt); U8 symSecret[24+8]; // + 8 for wrapping U16 symSecretLen = sizeof(symSecret); U8 configKey[24+8]; // + 8 for wrapping U16 configKeyLen = sizeof(configKey); a71_SecureStorageClass_t ssc = A71_SSC_UNDEF; *sw = 0x0000; // Initialize eccKeyPair eccKcTls.bits = 256; eccKcTls.curve = ECCCurve_NIST_P256; eccKcTls.privLen = 0; eccKcTls.pubLen = 0; // Do not go beyond the last argument when parsing if (argCurrent >= argc) { a7xConfigCliHelp("a71chConfig"); return AX_CLI_ARG_COUNT_MISTAKE; } if (strcmp(argv[argCurrent], "cfg") == 0) { ssc = A71_SSC_CONFIG_KEY; } else if (strcmp(argv[argCurrent], "cnt") == 0) { ssc = A71_SSC_COUNTER; } else if (strcmp(argv[argCurrent], "gp") == 0) { ssc = A71_SSC_GP_DATA; } else if (strcmp(argv[argCurrent], "pair") == 0) { ssc = A71_SSC_KEY_PAIR; } else if (strcmp(argv[argCurrent], "pub") == 0) { ssc = A71_SSC_PUBLIC_KEY; } else if (strcmp(argv[argCurrent], "sym") == 0) { ssc = A71_SSC_SYM_KEY; } else { printf("%s is an unknown command option.\n", argv[argCurrent]); return a7xConfigCliHelp("a71chConfig"); } argCurrent++; if (ssc == A71_SSC_GP_DATA) { nRet = axCliGetHexString("h", "", offsetArray, &offsetArrayLen, 2, 2, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } offset = (offsetArray[0] << 8) + (offsetArray[1]); } else { // Get Index nRet = axCliGetInteger("x", "", &index, 0, MAX_OBJECTS_NUM-1, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } } switch (ssc) { case A71_SSC_GP_DATA: nRet = axCliGetHexString("h", "", gpData, &gpDataLen, 1, 32, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { if (nRet == AX_CLI_ARG_OPTION_ERROR) { char szFilename[MAX_FILE_PATH]; int bufLen = sizeof(szFilename) - 1; nRet = axCliGetString("c", "", szFilename, bufLen, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } nRet = a7xConfigCmdSetGpFromPemfile(offset, szFilename, sw); return nRet; } else { return nRet; } } else { nRet = a7xConfigCmdSetGp(offset, gpData, gpDataLen, sw); } break; case A71_SSC_KEY_PAIR: nRet = axCliGetHexString("h", "", eccKcTls.pub, &(eccKcTls.pubLen), 65, 65, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { if (nRet == AX_CLI_ARG_OPTION_ERROR) { char szFilename[MAX_FILE_PATH]; int bufLen = sizeof(szFilename) - 1; nRet = axCliGetString("k", "", szFilename, bufLen, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } nRet = a7xConfigCmdSetEccFromPemfile(ssc, (U8)index, szFilename, argc, argv, &argCurrent, sw); return nRet; } else { return nRet; } } // Both plain and wrapped private keys are accepted nRet = axCliGetHexString("h", "", eccKcTls.priv, &(eccKcTls.privLen), 32, 40, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } // Check if wrapping should take place nRet = a7xConfigCmdCheckWrapping(eccKcTls.priv, &eccKcTls.privLen, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } // Set key nRet = a7xConfigCmdSetEcc(ssc, (U8)index, &eccKcTls, sw); break; case A71_SSC_PUBLIC_KEY: // Both plain and wrapped keys are accepted (please check APDU spec for wrapping approach) nRet = axCliGetHexString("h", "", eccKcTls.pub, &(eccKcTls.pubLen), 65, 72, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { if (nRet == AX_CLI_ARG_OPTION_ERROR) { char szFilename[MAX_FILE_PATH]; int bufLen = sizeof(szFilename) - 1; nRet = axCliGetString("k", "", szFilename, bufLen, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } nRet = a7xConfigCmdSetEccFromPemfile(ssc, (U8)index, szFilename, argc, argv, &argCurrent, sw); return nRet; } else { return nRet; } } // Check if wrapping should take place nRet = a7xConfigCmdCheckWrapping(eccKcTls.pub, &eccKcTls.pubLen, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } // Set key nRet = a7xConfigCmdSetEcc(ssc, (U8)index, &eccKcTls, sw); break; case A71_SSC_COUNTER: nRet = axCliGetHexString("h", "", cnt, &(cntLen), 4, 4, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } nRet = a7xConfigCmdSetCnt((U8)index, cnt, cntLen, sw); break; case A71_SSC_SYM_KEY: // Both plain and wrapped keys are accepted nRet = axCliGetHexString("h", "", symSecret, &(symSecretLen), 16, 24, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } // Check if wrapping should take place nRet = a7xConfigCmdCheckWrapping(symSecret, &symSecretLen, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } // Set key nRet = a7xConfigCmdSetSym((U8)index, symSecret, symSecretLen, sw); break; case A71_SSC_CONFIG_KEY: // Both plain and wrapped keys are accepted nRet = axCliGetHexString("h", "", configKey, &(configKeyLen), 16, 24, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } // Check if wrapping should take place nRet = a7xConfigCmdCheckWrapping(configKey, &configKeyLen, argc, argv, &argCurrent); if (nRet != AX_CLI_EXEC_OK) { return nRet; } // Set key nRet = a7xConfigCmdSetConfigKey((U8)index, configKey, configKeyLen, sw); break; default: // Cannot be triggered return AX_CLI_NOT_IMPLEMENTED; } return nRet; }