blob: 775145b60ac416eb8b92a7fd01fc1801d6fe5df2 [file] [log] [blame]
/**
* @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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
// 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 <int> -h <hexvalue>\n");
// printf(" set gp -h <hexvalue_offset:....> -h <hexvalue_data>\n");
// printf(" set gp -h <hexvalue_offset:....> -c <certfile.pem>\n");
// printf(" set pair -x <int> [-k <keyfile.pem> | -h <hexvalue_pub> -h <hexvalue_priv>]\n");
// printf(" set pub -x <int> [-k <keyfile.pem> | -h <hexvalue>]\n");
// printf(" set sym -x <int> -h <hexvalue>\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;
}