Add PSKc API (#1635)

* add pskc api

* add pskc cli

* add NCP api of PSKc

* apply PSKc from network

* implement PSKC api for windows

* add name for pskc property

* clear active and pending dataset when settings pskc
This commit is contained in:
Buke Po
2017-04-27 16:32:34 -07:00
committed by Jonathan Hui
parent 0759f874e0
commit 024c44de5c
18 changed files with 396 additions and 4 deletions
+9 -1
View File
@@ -55,8 +55,16 @@ Values:
The partition ID of the partition that this node is a member of.
### PROP 73: PROP_NET_KEY_SWITCH_GUARDTIME {#prop-net-key-swtich-guardtime}
### PROP 73: PROP_NET_REQUIRE_JOIN_EXISTING {#prop-net-require-join-existing}
* Type: Read-Write
* Packed-Encoding: `b`
### PROP 74: PROP_NET_KEY_SWITCH_GUARDTIME {#prop-net-key-swtich-guardtime}
* Type: Read-Write
* Packed-Encoding: `L`
### PROP 75: PROP_NET_PSKC {#prop-net-pskc}
* Type: Read-Write
* Packed-Encoding: `D`
@@ -689,8 +689,13 @@ typedef struct otCommissionConfig
// GUID - InterfaceGuid
// uint8_t - aRouterId
#define IOCTL_OTLWF_OT_PSKC \
OTLWF_CTL_CODE(195, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
// GUID - InterfaceGuid
// otPSKc - aPSKc
// OpenThread function IOCTL codes
#define MIN_OTLWF_IOCTL_FUNC_CODE 100
#define MAX_OTLWF_IOCTL_FUNC_CODE 194
#define MAX_OTLWF_IOCTL_FUNC_CODE 195
#endif //__OTLWFIOCTL_H__
+36
View File
@@ -1646,6 +1646,42 @@ otThreadSetMasterKey(
return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_MASTER_KEY, Buffer, sizeof(Buffer), nullptr, 0));
}
OTAPI
const uint8_t *
OTCALL
otThreadGetPSKc(
_In_ otInstance *aInstance
)
{
if (aInstance == nullptr) return nullptr;
uint8_t *Result = (uint8_t*)malloc(sizeof(otPSKc));
if (Result == nullptr) return nullptr;
if (QueryIOCTL(aInstance, IOCTL_OTLWF_OT_PSKC, Result) != ERROR_SUCCESS)
{
free(Result);
return nullptr;
}
return Result;
}
OTAPI
ThreadError
OTCALL
otThreadSetPSKc(
_In_ otInstance *aInstance,
const uint8_t *aPSKc
)
{
if (aInstance == nullptr) return kThreadError_InvalidArgs;
BYTE Buffer[sizeof(GUID) + sizeof(otPSKc)];
memcpy_s(Buffer, sizeof(Buffer), &aInstance->InterfaceGuid, sizeof(GUID));
memcpy_s(Buffer + sizeof(GUID), sizeof(Buffer) - sizeof(GUID), aPSKc, sizeof(otPSKc));
return DwordToThreadError(SendIOCTL(aInstance->ApiHandle, IOCTL_OTLWF_OT_PSKC, Buffer, sizeof(Buffer), nullptr, 0));
}
OTAPI
int8_t
OTCALL
+105
View File
@@ -140,6 +140,7 @@ OTLWF_IOCTL_HANDLER IoCtls[] =
{ "IOCTL_OTLWF_OT_FACTORY_RESET", REF_IOCTL_FUNC(otFactoryReset) },
{ "IOCTL_OTLWF_OT_THREAD_AUTO_START", REF_IOCTL_FUNC(otThreadAutoStart) },
{ "IOCTL_OTLWF_OT_PREFERRED_ROUTER_ID", REF_IOCTL_FUNC(otThreadPreferredRouterId) },
{ "IOCTL_OTLWF_OT_PSKC", REF_IOCTL_FUNC_WITH_TUN(otPSKc) },
};
static_assert(ARRAYSIZE(IoCtls) == (MAX_OTLWF_IOCTL_FUNC_CODE - MIN_OTLWF_IOCTL_FUNC_CODE) + 1,
@@ -1725,6 +1726,110 @@ otLwfTunIoCtl_otMasterKey_Handler(
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfIoCtl_otPSKc(
_In_ PMS_FILTER pFilter,
_In_reads_bytes_(InBufferLength)
PUCHAR InBuffer,
_In_ ULONG InBufferLength,
_Out_writes_bytes_(*OutBufferLength)
PVOID OutBuffer,
_Inout_ PULONG OutBufferLength
)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
if (InBufferLength >= sizeof(otPSKc))
{
status = ThreadErrorToNtstatus(otThreadSetPSKc(pFilter->otCtx, InBuffer));
*OutBufferLength = 0;
}
else if (*OutBufferLength >= sizeof(otPSKc))
{
const uint8_t* aPSKc = otThreadGetPSKc(pFilter->otCtx);
memcpy(OutBuffer, aPSKc, sizeof(otPSKc));
*OutBufferLength = sizeof(otPSKc);
status = STATUS_SUCCESS;
}
else
{
*OutBufferLength = 0;
}
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfTunIoCtl_otPSKc(
_In_ PMS_FILTER pFilter,
_In_ PIRP pIrp,
_In_reads_bytes_(InBufferLength)
PUCHAR InBuffer,
_In_ ULONG InBufferLength,
_In_ ULONG OutBufferLength
)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
if (InBufferLength >= sizeof(otPSKc))
{
status =
otLwfTunSendCommandForIrp(
pFilter,
pIrp,
NULL,
SPINEL_CMD_PROP_VALUE_SET,
SPINEL_PROP_NET_PSKC,
sizeof(otPSKc) + sizeof(uint16_t),
SPINEL_DATATYPE_DATA_S,
(otPSKc*)InBuffer,
OT_PSKC_MAX_SIZE);
}
else if (OutBufferLength >= sizeof(otPSKc))
{
status =
otLwfTunSendCommandForIrp(
pFilter,
pIrp,
otLwfTunIoCtl_otPSKc_Handler,
SPINEL_CMD_PROP_VALUE_GET,
SPINEL_PROP_NET_PSKC,
0,
NULL);
}
return status;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
otLwfTunIoCtl_otPSKc_Handler(
_In_ spinel_prop_key_t Key,
_In_reads_bytes_(DataLength) const uint8_t* Data,
_In_ spinel_size_t DataLength,
_Out_writes_bytes_(*OutBufferLength)
PVOID OutBuffer,
_Inout_ PULONG OutBufferLength
)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
if (Key == SPINEL_PROP_NET_PSKC)
{
uint8_t *data = NULL;
spinel_size_t aPSKcLength;
if (try_spinel_datatype_unpack(Data, DataLength, SPINEL_DATATYPE_DATA_S, &data, &aPSKcLength) && data != NULL &&
aPSKcLength == sizeof(otPSKc))
{
memcpy(OutBuffer, data, sizeof(otPSKc));
*OutBufferLength = sizeof(otPSKc);
status = STATUS_SUCCESS;
}
}
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
otLwfIoCtl_otMeshLocalEid(
@@ -226,5 +226,6 @@ DECL_IOCTL_FUNC_WITH_TUN2(otKeySwitchGuardtime);
DECL_IOCTL_FUNC(otFactoryReset);
DECL_IOCTL_FUNC(otThreadAutoStart);
DECL_IOCTL_FUNC(otThreadPreferredRouterId);
DECL_IOCTL_FUNC_WITH_TUN2(otPSKc);
#endif // _IOCONTROL_H
@@ -1231,6 +1231,41 @@ OTNODEAPI const char* OTCALL otNodeGetMasterkey(otNode* aNode)
return str;
}
OTNODEAPI int32_t OTCALL otNodeSetPSKc(otNode* aNode, const char *aPSKc)
{
otLogFuncEntryMsg("[%d] %s", aNode->mId, aPSKc);
printf("%d: pskc %s\r\n", aNode->mId, aPSKc);
uint8_t pskc[OT_PSKC_MAX_SIZE];
if (Hex2Bin(aPSKc, pskc, sizeof(pskc)) != OT_PSKC_MAX_SIZE)
{
printf("invalid pskc %s\r\n", aPSKc);
return kThreadError_Parse;
}
auto error = otThreadSetPSKc(aNode->mInstance, pskc);
otLogFuncExit();
return error;
}
OTNODEAPI const char* OTCALL otNodeGetPSKc(otNode* aNode)
{
otLogFuncEntryMsg("[%d]", aNode->mId);
auto aPSKc = otThreadGetPSKc(aNode->mInstance);
uint8_t strLength = 2 * OT_PSKC_MAX_SIZE + 1;
char* str = (char*)malloc(strLength);
if (str != nullptr)
{
aNode->mMemoryToFree.push_back(str);
for (int i = 0; i < OT_PSKC_MAX_SIZE; i++)
sprintf_s(str + i * 2, strLength - (2 * i), "%02x", aPSKc[i]);
printf("%d: pskc\r\n%s\r\n", aNode->mId, str);
}
otFreeMemory(aPSKc);
otLogFuncExit();
return str;
}
OTNODEAPI uint32_t OTCALL otNodeGetKeySequenceCounter(otNode* aNode)
{
otLogFuncEntryMsg("[%d]", aNode->mId);
+28
View File
@@ -288,6 +288,34 @@ OTAPI const uint8_t *OTCALL otThreadGetMasterKey(otInstance *aInstance, uint8_t
*/
OTAPI ThreadError OTCALL otThreadSetMasterKey(otInstance *aInstance, const uint8_t *aKey, uint8_t aKeyLength);
/**
* Get the thrPSKc.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns A pointer to a buffer containing the thrPSKc.
*
* @sa otThreadSetPSKc
*/
OTAPI const uint8_t *OTCALL otThreadGetPSKc(otInstance *aInstance);
/**
* Set the thrPSKc.
*
* This function will only succeed when Thread protocols are disabled. A successful
* call to this function will also invalidate the Active and Pending Operational Datasets in
* non-volatile memory.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPSKc A pointer to a buffer containing the thrPSKc.
*
* @retval kThreadError_None Successfully set the thrPSKc.
* @retval kThreadError_InvalidState Thread protocols are enabled.
*
* @sa otThreadGetPSKc
*/
OTAPI ThreadError OTCALL otThreadSetPSKc(otInstance *aInstance, const uint8_t *aPSKc);
/**
* This function returns a pointer to the Mesh Local EID.
*
+32
View File
@@ -156,6 +156,9 @@ const struct Command Interpreter::sCommands[] =
{ "promiscuous", &Interpreter::ProcessPromiscuous },
#endif
{ "prefix", &Interpreter::ProcessPrefix },
#if OPENTHREAD_FTD
{ "pskc", &Interpreter::ProcessPSKc },
#endif
{ "releaserouterid", &Interpreter::ProcessReleaseRouterId },
{ "reset", &Interpreter::ProcessReset },
{ "rloc16", &Interpreter::ProcessRloc16 },
@@ -1292,6 +1295,35 @@ exit:
AppendResult(error);
}
#if OPENTHREAD_FTD
void Interpreter::ProcessPSKc(int argc, char *argv[])
{
ThreadError error = kThreadError_None;
if (argc == 0)
{
const uint8_t *currentPSKc = otThreadGetPSKc(mInstance);
for (int i = 0; i < OT_PSKC_MAX_SIZE; i++)
{
sServer->OutputFormat("%02x", currentPSKc[i]);
}
sServer->OutputFormat("\r\n");
}
else
{
uint8_t newPSKc[OT_PSKC_MAX_SIZE];
VerifyOrExit(Hex2Bin(argv[0], newPSKc, sizeof(newPSKc)) == OT_PSKC_MAX_SIZE, error = kThreadError_Parse);
SuccessOrExit(error = otThreadSetPSKc(mInstance, newPSKc));
}
exit:
AppendResult(error);
}
#endif
void Interpreter::ProcessMasterKey(int argc, char *argv[])
{
ThreadError error = kThreadError_None;
+3
View File
@@ -226,6 +226,9 @@ private:
ThreadError ProcessPrefixRemove(int argc, char *argv[]);
ThreadError ProcessPrefixList(void);
void ProcessPromiscuous(int argc, char *argv[]);
#if OPENTHREAD_FTD
void ProcessPSKc(int argc, char *argv[]);
#endif
void ProcessReleaseRouterId(int argc, char *argv[]);
void ProcessReset(int argc, char *argv[]);
void ProcessRoute(int argc, char *argv[]);
+21
View File
@@ -163,6 +163,27 @@ ThreadError otThreadSetLinkMode(otInstance *aInstance, otLinkModeConfig aConfig)
return aInstance->mThreadNetif.GetMle().SetDeviceMode(mode);
}
#if OPENTHREAD_FTD
const uint8_t *otThreadGetPSKc(otInstance *aInstance)
{
return aInstance->mThreadNetif.GetKeyManager().GetPSKc();
}
ThreadError otThreadSetPSKc(otInstance *aInstance, const uint8_t *aPSKc)
{
ThreadError error = kThreadError_None;
VerifyOrExit(aInstance->mThreadNetif.GetMle().GetDeviceState() == Mle::kDeviceStateDisabled,
error = kThreadError_InvalidState);
aInstance->mThreadNetif.GetKeyManager().SetPSKc(aPSKc);
aInstance->mThreadNetif.GetActiveDataset().Clear(false);
aInstance->mThreadNetif.GetPendingDataset().Clear(false);
exit:
return error;
}
#endif
const uint8_t *otThreadGetMasterKey(otInstance *aInstance, uint8_t *aKeyLength)
{
return aInstance->mThreadNetif.GetKeyManager().GetMasterKey(aKeyLength);
+11
View File
@@ -135,6 +135,17 @@ ThreadError DatasetManager::ApplyConfiguration(void)
break;
}
#if OPENTHREAD_FTD
case Tlv::kPSKc:
{
const PSKcTlv *pskc = static_cast<const PSKcTlv *>(cur);
mNetif.GetKeyManager().SetPSKc(pskc->GetPSKc());
break;
}
#endif
case Tlv::kMeshLocalPrefix:
{
const MeshLocalPrefixTlv *prefix = static_cast<const MeshLocalPrefixTlv *>(cur);
+1 -2
View File
@@ -162,10 +162,9 @@ ThreadError ActiveDataset::GenerateLocal(void)
// PSKc
if (!IsTlvInitialized(Tlv::kPSKc))
{
const uint8_t pskc[OT_PSKC_MAX_SIZE] = {0};
PSKcTlv tlv;
tlv.Init();
tlv.SetPSKc(pskc);
tlv.SetPSKc(mNetif.GetKeyManager().GetPSKc());
mLocal.Set(tlv);
}
+12
View File
@@ -80,6 +80,18 @@ void KeyManager::Stop(void)
mKeyRotationTimer.Stop();
}
#if OPENTHREAD_FTD
const uint8_t *KeyManager::GetPSKc(void) const
{
return mPSKc;
}
void KeyManager::SetPSKc(const uint8_t *aPSKc)
{
memcpy(mPSKc, aPSKc, sizeof(mPSKc));
}
#endif
const uint8_t *KeyManager::GetMasterKey(uint8_t *aKeyLength) const
{
if (aKeyLength)
+19
View File
@@ -104,6 +104,22 @@ public:
*/
ThreadError SetMasterKey(const void *aKey, uint8_t aKeyLength);
/**
* This method returns a pointer to the PSKc.
*
* @returns A pointer to the PSKc.
*
*/
const uint8_t *GetPSKc(void) const;
/**
* This method sets the PSKc.
*
* @param[in] aPSKc A pointer to the PSKc.
*
*/
void SetPSKc(const uint8_t *aPSKc);
/**
* This method returns the current key sequence value.
*
@@ -346,6 +362,9 @@ private:
bool mKeySwitchGuardEnabled;
Timer mKeyRotationTimer;
#if OPENTHREAD_FTD
uint8_t mPSKc[kMaxKeyLength];
#endif
uint8_t mKek[kMaxKeyLength];
uint32_t mKekFrameCounter;
+59
View File
@@ -141,6 +141,9 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
{ SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER, &NcpBase::GetPropertyHandler_NET_KEY_SEQUENCE_COUNTER },
{ SPINEL_PROP_NET_PARTITION_ID, &NcpBase::GetPropertyHandler_NET_PARTITION_ID },
{ SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME, &NcpBase::GetPropertyHandler_NET_KEY_SWITCH_GUARDTIME},
#if OPENTHREAD_FTD
{ SPINEL_PROP_NET_PSKC, &NcpBase::GetPropertyHandler_NET_PSKC },
#endif
{ SPINEL_PROP_THREAD_LEADER_ADDR, &NcpBase::GetPropertyHandler_THREAD_LEADER_ADDR },
{ SPINEL_PROP_THREAD_PARENT, &NcpBase::GetPropertyHandler_THREAD_PARENT },
@@ -280,6 +283,9 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] =
{ SPINEL_PROP_NET_MASTER_KEY, &NcpBase::SetPropertyHandler_NET_MASTER_KEY },
{ SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER, &NcpBase::SetPropertyHandler_NET_KEY_SEQUENCE_COUNTER },
{ SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME, &NcpBase::SetPropertyHandler_NET_KEY_SWITCH_GUARDTIME},
#if OPENTHREAD_FTD
{ SPINEL_PROP_NET_PSKC, &NcpBase::SetPropertyHandler_NET_PSKC },
#endif
{ SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT, &NcpBase::SetPropertyHandler_THREAD_LOCAL_LEADER_WEIGHT },
{ SPINEL_PROP_THREAD_ASSISTING_PORTS, &NcpBase::SetPropertyHandler_THREAD_ASSISTING_PORTS },
@@ -3336,6 +3342,20 @@ ThreadError NcpBase::GetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, sp
);
}
#if OPENTHREAD_FTD
ThreadError NcpBase::GetPropertyHandler_NET_PSKC(uint8_t header, spinel_prop_key_t key)
{
return SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_IS,
key,
SPINEL_DATATYPE_DATA_S,
otThreadGetPSKc(mInstance),
sizeof(spinel_net_pskc_t)
);
}
#endif // OPENTHREAD_FTD
ThreadError NcpBase::GetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_key_t key)
{
uint8_t numeric_mode(0);
@@ -5275,6 +5295,45 @@ exit:
#endif
#if OPENTHREAD_FTD
ThreadError NcpBase::SetPropertyHandler_NET_PSKC(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len)
{
const uint8_t *ptr = NULL;
spinel_size_t len;
spinel_ssize_t parsedLength;
ThreadError errorCode = kThreadError_None;
parsedLength = spinel_datatype_unpack(
value_ptr,
value_len,
SPINEL_DATATYPE_DATA_S,
&ptr,
&len
);
if ((parsedLength > 0) && (len == sizeof(spinel_net_pskc_t)))
{
errorCode = otThreadSetPSKc(mInstance, ptr);
if (errorCode == kThreadError_None)
{
errorCode = HandleCommandPropertyGet(header, key);
}
if (errorCode)
{
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
}
}
else
{
errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR);
}
return errorCode;
}
#endif // OPENTHREAD_FTD
ThreadError NcpBase::SetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len)
{
+7
View File
@@ -393,6 +393,9 @@ private:
ThreadError GetPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_key_t key);
#if OPENTHREAD_FTD
ThreadError GetPropertyHandler_NET_PSKC(uint8_t header, spinel_prop_key_t key);
#endif
ThreadError GetPropertyHandler_THREAD_CHILD_COUNT_MAX(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_THREAD_CHILD_TIMEOUT(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_THREAD_RLOC16(uint8_t header, spinel_prop_key_t key);
@@ -500,6 +503,10 @@ private:
const uint8_t *value_ptr, uint16_t value_len);
ThreadError SetPropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
#endif
#if OPENTHREAD_FTD
ThreadError SetPropertyHandler_NET_PSKC(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
#endif
ThreadError SetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
+4
View File
@@ -1068,6 +1068,10 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
ret = "PROP_NET_KEY_SWITCH_GUARDTIME";
break;
case SPINEL_PROP_NET_PSKC:
ret = "PROP_NET_PSKC";
break;
case SPINEL_PROP_THREAD_LEADER_ADDR:
ret = "PROP_THREAD_LEADER_ADDR";
break;
+7
View File
@@ -251,6 +251,11 @@ typedef struct
uint8_t bytes[8];
} spinel_net_xpanid_t;
typedef struct
{
uint8_t bytes[16];
} spinel_net_pskc_t;
typedef struct
{
uint8_t bytes[6];
@@ -688,6 +693,8 @@ typedef enum
SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME
= SPINEL_PROP_NET__BEGIN + 10, ///< [L]
SPINEL_PROP_NET_PSKC = SPINEL_PROP_NET__BEGIN + 11, ///< [D]
SPINEL_PROP_NET__END = 0x50,
SPINEL_PROP_THREAD__BEGIN = 0x50,