| /* |
| * |
| * Copyright (c) 2013-2017 Nest Labs, Inc. |
| * All rights reserved. |
| * |
| * 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. |
| */ |
| |
| /** |
| * @file |
| * This file implements a process to effect a functional test for |
| * the Weave Token Authenticated Key Exchange (TAKE) protocol |
| * engine. |
| * |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include "ToolCommon.h" |
| #include <Weave/Support/ErrorStr.h> |
| #include <Weave/Profiles/security/WeaveSecurity.h> |
| #include <Weave/Profiles/security/WeaveTAKE.h> |
| #include <Weave/Support/crypto/AESBlockCipher.h> |
| #include "TAKEOptions.h" |
| |
| #if WEAVE_SYSTEM_CONFIG_USE_LWIP |
| #include "lwip/tcpip.h" |
| #endif // WEAVE_SYSTEM_CONFIG_USE_LWIP |
| |
| using namespace nl::Inet; |
| using namespace nl::Weave::Profiles::Security; |
| using namespace nl::Weave::Profiles::Security::TAKE; |
| |
| #define DEBUG_PRINT_ENABLE 0 |
| #define DEBUG_PRINT_MESSAGE_LENGTH 0 |
| |
| #define Clean() \ |
| do { \ |
| if (encodedMsg) \ |
| PacketBuffer::Free(encodedMsg); \ |
| } while (0) |
| |
| #define VerifyOrFail(TST, MSG) \ |
| do { \ |
| if (!(TST)) \ |
| { \ |
| fprintf(stderr, "%s FAILED: ", __FUNCTION__); \ |
| fputs(MSG, stderr); \ |
| Clean(); \ |
| exit(-1); \ |
| } \ |
| } while (0) |
| |
| #define SuccessOrFail(ERR, MSG) \ |
| do { \ |
| if ((ERR) != WEAVE_NO_ERROR) \ |
| { \ |
| fprintf(stderr, "%s FAILED: ", __FUNCTION__); \ |
| fputs(MSG, stderr); \ |
| fputs(ErrorStr(ERR), stderr); \ |
| fputs("\n", stderr); \ |
| Clean(); \ |
| exit(-1); \ |
| } \ |
| } while (0) |
| |
| class TAKEConfigNoAuthorized : public MockTAKEChallengerDelegate |
| { |
| public: |
| |
| WEAVE_ERROR GetNextIdentificationKey(uint64_t & tokenId, uint8_t *identificationKey, uint16_t & identificationKeyLen) |
| { |
| tokenId = kNodeIdNotSpecified; |
| return WEAVE_NO_ERROR; |
| } |
| }; |
| |
| uint8_t junk0[] = { 0x6a, 0x75, 0x6e, 0x6b, 0x6a, 0x75, 0x6e, 0x6b, 0x6a, 0x75, 0x6e, 0x6b, 0x6a, 0x75, 0x6e, 0x6b }; |
| uint8_t junk1[] = { 0x74, 0x72, 0x61, 0x73, 0x68, 0x74, 0x72, 0x61, 0x73, 0x68, 0x74, 0x72, 0x61, 0x73, 0x68, 0x74 }; |
| uint8_t junk2[] = { 0x74, 0x68, 0x69, 0x73, 0x69, 0x73, 0x61, 0x70, 0x69, 0x6c, 0x65, 0x6f, 0x73, 0x68, 0x69, 0x74 }; |
| |
| class TAKEConfigJunkAuthorized : public MockTAKEChallengerDelegate |
| { |
| int position; |
| public: |
| |
| TAKEConfigJunkAuthorized() : position(0) { } |
| |
| WEAVE_ERROR RewindIdentificationKeyIterator() |
| { |
| position = 0; |
| return WEAVE_NO_ERROR; |
| } |
| |
| // Get next {tokenId, IK} pair. |
| // returns tokenId = kNodeIdNotSpecified if no more IKs are available. |
| WEAVE_ERROR GetNextIdentificationKey(uint64_t & tokenId, uint8_t *identificationKey, uint16_t & identificationKeyLen) |
| { |
| if (identificationKeyLen < kIdentificationKeySize) |
| return WEAVE_ERROR_BUFFER_TOO_SMALL; |
| identificationKeyLen = kIdentificationKeySize; |
| |
| switch (position) |
| { |
| case 0: |
| memcpy(identificationKey, junk0, identificationKeyLen); |
| break; |
| case 1: |
| memcpy(identificationKey, junk1, identificationKeyLen); |
| break; |
| case 2: |
| memcpy(identificationKey, junk2, identificationKeyLen); |
| break; |
| default: |
| tokenId = kNodeIdNotSpecified; |
| break; |
| } |
| position++; |
| return WEAVE_NO_ERROR; |
| } |
| }; |
| |
| |
| // This IK correspond to an IK generated with takeTime = 17167, (number of days til 01/01/2017) which is the value used by the test Token auth delegate |
| uint8_t IK_timeLimited[] = { 0x0F, 0x8E, 0x23, 0x34, 0xA4, 0xA1, 0xF7, 0x60, 0x29, 0x42, 0xB3, 0x4C, 0xA5, 0x28, 0xC5, 0xA9 }; |
| |
| class TAKEConfigTimeLimitedIK : public MockTAKEChallengerDelegate |
| { |
| public: |
| |
| // Get next {tokenId, IK} pair. |
| // returns tokenId = kNodeIdNotSpecified if no more IKs are available. |
| WEAVE_ERROR GetNextIdentificationKey(uint64_t & tokenId, uint8_t *identificationKey, uint16_t & identificationKeyLen) |
| { |
| if (Rewinded) |
| { |
| if (identificationKeyLen < kIdentificationKeySize) |
| return WEAVE_ERROR_BUFFER_TOO_SMALL; |
| tokenId = 1; |
| identificationKeyLen = kIdentificationKeySize; |
| memcpy(identificationKey, IK_timeLimited, identificationKeyLen); |
| Rewinded = false; |
| } |
| else |
| { |
| tokenId = nl::Weave::kNodeIdNotSpecified; |
| } |
| return WEAVE_NO_ERROR; |
| } |
| }; |
| |
| uint8_t IK_ChallengerIdIsNodeId[] = { 0xAE, 0x2D, 0xD8, 0x16, 0x4B, 0xAE, 0x1A, 0x77, 0xB8, 0xCF, 0x52, 0x0D, 0x20, 0x21, 0xE2, 0x45 }; |
| class TAKEConfigChallengerIdIsNodeId : public MockTAKEChallengerDelegate |
| { |
| public: |
| |
| // Get next {tokenId, IK} pair. |
| // returns tokenId = kNodeIdNotSpecified if no more IKs are available. |
| WEAVE_ERROR GetNextIdentificationKey(uint64_t & tokenId, uint8_t *identificationKey, uint16_t & identificationKeyLen) |
| { |
| if (Rewinded) |
| { |
| if (identificationKeyLen < kIdentificationKeySize) |
| return WEAVE_ERROR_BUFFER_TOO_SMALL; |
| tokenId = 1; |
| identificationKeyLen = kIdentificationKeySize; |
| memcpy(identificationKey, IK_ChallengerIdIsNodeId, identificationKeyLen); |
| Rewinded = false; |
| } |
| else |
| { |
| tokenId = nl::Weave::kNodeIdNotSpecified; |
| } |
| return WEAVE_NO_ERROR; |
| } |
| }; |
| |
| |
| uint8_t MasterKey[] = { 0x11, 0xFF, 0xF1, 0x1F, 0xD1, 0x3F, 0xB1, 0x5F, 0x91, 0x7F, 0x71, 0x9F, 0x51, 0xBF, 0x31, 0xDF, 0x11, 0xFF, 0xF1, 0x1F, 0xD1, 0x3F, 0xB1, 0x5F, 0x91, 0x7F, 0x71, 0x9F, 0x51, 0xBF, 0x31, 0xDF }; |
| |
| void TestTAKEEngine(WeaveTAKEChallengerAuthDelegate& ChallengerAuthDelegate, bool authorized = true, uint8_t config = kTAKEConfig_Config1, bool encryptAuthPhase = false, bool encryptCommPhase = true, bool timeLimitedIK = false, bool canDoReauth = false, bool sendChallengerId = true) |
| { |
| WEAVE_ERROR err; |
| WeaveTAKEEngine initEng; |
| WeaveTAKEEngine respEng; |
| uint16_t sessionKeyIdInitiator = sTestDefaultSessionKeyId; |
| MockTAKETokenDelegate takeTokenAuthDelegate; |
| uint64_t challengerNodeId = 1337; |
| |
| PacketBuffer *encodedMsg = NULL; |
| const WeaveEncryptionKey *initSessionKey; |
| const WeaveEncryptionKey *respSessionKey; |
| |
| // Init TAKE Engines |
| initEng.Init(); |
| respEng.Init(); |
| |
| initEng.ChallengerAuthDelegate = &ChallengerAuthDelegate; |
| respEng.TokenAuthDelegate = &takeTokenAuthDelegate; |
| |
| // Initiator generates and sends Identify Token message. |
| { |
| encodedMsg = PacketBuffer::New(); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateIdentifyTokenMessage (Started):\n"); |
| #endif |
| err = initEng.GenerateIdentifyTokenMessage(sessionKeyIdInitiator, config, encryptAuthPhase, encryptCommPhase, timeLimitedIK, sendChallengerId, kWeaveEncryptionType_AES128CTRSHA1, challengerNodeId, encodedMsg); |
| if (config != kTAKEConfig_Config1) |
| { |
| VerifyOrFail(err == WEAVE_ERROR_UNSUPPORTED_TAKE_CONFIGURATION, "GenerateIdentifyTokenMessage: should have returned an error"); |
| Clean(); |
| return; |
| } |
| SuccessOrFail(err, "WeaveTAKEEngine::GenerateIdentifyTokenMessage failed\n"); |
| |
| #if DEBUG_PRINT_MESSAGE_LENGTH |
| fprintf(stdout, "GenerateIdentifyTokenMessage: Message Size = %d \n", encodedMsg->DataLength()); |
| #endif |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateIdentifyTokenMessage (Finished):\n"); |
| #endif |
| } |
| |
| // Responder receives and processes Identify Token message. |
| { |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessIdentifyTokenMessage (Started):\n"); |
| #endif |
| |
| err = respEng.ProcessIdentifyTokenMessage(challengerNodeId, encodedMsg); // peerNodeId parameter is not used |
| if (err == WEAVE_ERROR_TAKE_RECONFIGURE_REQUIRED) |
| { |
| VerifyOrFail(config != kTAKEConfig_Config1, "WeaveTAKEEngine::ProcessIdentifyTokenMessage asks for unescessary reconfigure"); |
| Clean(); |
| return; |
| } |
| else |
| { |
| VerifyOrFail(config == kTAKEConfig_Config1, "WeaveTAKEEngine::ProcessIdentifyTokenMessage do not asks for reconfigure"); |
| SuccessOrFail(err, "WeaveTAKEEngine::ProcessIdentifyTokenMessage failed\n"); |
| } |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessIdentifyTokenMessage (Finished):\n"); |
| #endif |
| PacketBuffer::Free(encodedMsg); |
| encodedMsg = NULL; |
| } |
| |
| // Responder generates and sends Identify Token Response message. |
| { |
| encodedMsg = PacketBuffer::New(); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateIdentifyTokenResponseMessage (Started):\n"); |
| #endif |
| err = respEng.GenerateIdentifyTokenResponseMessage(encodedMsg); |
| SuccessOrFail(err, "WeaveTAKEEngine::GenerateIdentifyTokenResponseMessage failed\n"); |
| |
| #if DEBUG_PRINT_MESSAGE_LENGTH |
| fprintf(stdout, "GenerateIdentifyTokenResponseMessage: Message Size = %d \n", encodedMsg->DataLength()); |
| #endif |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateIdentifyTokenResponseMessage (Finished):\n"); |
| #endif |
| } |
| |
| // Initiator receives and processes Identify token Response message. |
| { |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessIdentifyTokenResponseMessage (Started):\n"); |
| #endif |
| |
| err = initEng.ProcessIdentifyTokenResponseMessage(encodedMsg); |
| if (!authorized) |
| { |
| VerifyOrFail(err == WEAVE_ERROR_TAKE_TOKEN_IDENTIFICATION_FAILED, "Initiator accepted key, but shouldn't have done so\n"); |
| Clean(); |
| return; |
| } |
| if (canDoReauth) |
| { |
| VerifyOrFail(err == WEAVE_ERROR_TAKE_REAUTH_POSSIBLE, "Initiator should have initiated a Reauth\n"); |
| } |
| else |
| { |
| SuccessOrFail(err, "WeaveTAKEEngine::ProcessIdentifyTokenResponseMessage failed\n"); |
| } |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessIdentifyTokenResponseMessage (Finished):\n"); |
| #endif |
| PacketBuffer::Free(encodedMsg); |
| encodedMsg = NULL; |
| } |
| |
| VerifyOrFail(initEng.SessionKeyId == respEng.SessionKeyId, "Initiator SessionKeyId != Responder SessionKeyId\n"); |
| VerifyOrFail(initEng.ControlHeader == respEng.ControlHeader, "Initiator controlHeader != Responder controlHeader\n"); |
| VerifyOrFail(initEng.EncryptionType == respEng.EncryptionType, "Initiator encryptionType != Responder encryptionType\n"); |
| VerifyOrFail(initEng.ProtocolConfig == respEng.ProtocolConfig, "Initiator protocolConfig != Responder protocolConfig\n"); |
| VerifyOrFail(initEng.GetNumOptionalConfigurations() == respEng.GetNumOptionalConfigurations(), "Initiator numOptionalConfigurations != Responder numOptionalConfigurations\n"); |
| VerifyOrFail(initEng.ProtocolConfig == respEng.ProtocolConfig, "Initiator protocolConfig != Responder protocolConfig\n"); |
| VerifyOrFail(memcmp(initEng.OptionalConfigurations, respEng.OptionalConfigurations, respEng.GetNumOptionalConfigurations()*sizeof(uint8_t)) == 0, "Initiator optionalConfigurations != Responder optionalConfigurations\n"); |
| |
| VerifyOrFail(initEng.IsEncryptAuthPhase() == respEng.IsEncryptAuthPhase(), "Initiator EAP != Responder EAP\n"); |
| VerifyOrFail(initEng.IsEncryptCommPhase() == respEng.IsEncryptCommPhase(), "Initiator ECP != Responder ECP\n"); |
| VerifyOrFail(initEng.IsTimeLimitedIK() == respEng.IsTimeLimitedIK(), "Initiator TL != Responder TL\n"); |
| |
| VerifyOrFail(initEng.ChallengerIdLen == respEng.ChallengerIdLen, "Initiator ChallengerIdLen != Responder ChallengerIdLen\n"); |
| VerifyOrFail(memcmp(initEng.ChallengerId, respEng.ChallengerId, initEng.ChallengerIdLen) == 0, "Initiator ChallengerId != Responder ChallengerId\n"); |
| VerifyOrFail(memcmp(initEng.ChallengerNonce, respEng.ChallengerNonce, kNonceSize) == 0, "Initiator ChallengerNonce != Responder ChallengerNonce\n"); |
| VerifyOrFail(memcmp(initEng.TokenNonce, respEng.TokenNonce, kNonceSize) == 0, "Initiator TokenNonce != Responder TokenNonce\n"); |
| |
| if (encryptAuthPhase) |
| { |
| err = initEng.GetSessionKey(initSessionKey); |
| SuccessOrFail(err, "WeaveTAKEEngine::GetSessionKey() failed\n"); |
| |
| err = respEng.GetSessionKey(respSessionKey); |
| SuccessOrFail(err, "WeaveTAKEEngine::GetSessionKey() failed\n"); |
| |
| VerifyOrFail(memcmp(initSessionKey->AES128CTRSHA1.DataKey, respSessionKey->AES128CTRSHA1.DataKey, WeaveEncryptionKey_AES128CTRSHA1::DataKeySize) == 0, |
| "Data key mismatch\n"); |
| |
| VerifyOrFail(memcmp(initSessionKey->AES128CTRSHA1.IntegrityKey, respSessionKey->AES128CTRSHA1.IntegrityKey, WeaveEncryptionKey_AES128CTRSHA1::IntegrityKeySize) == 0, |
| "Integrity key mismatch\n"); |
| } |
| |
| if (canDoReauth) |
| { |
| // Initiator generates and sends ReAuthenticate Token message. |
| { |
| encodedMsg = PacketBuffer::New(); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateReAuthenticateTokenMessage (Started):\n"); |
| #endif |
| err = initEng.GenerateReAuthenticateTokenMessage(encodedMsg); |
| SuccessOrFail(err, "WeaveTAKEEngine::GenerateReAuthenticateTokenMessage failed\n"); |
| |
| #if DEBUG_PRINT_MESSAGE_LENGTH |
| fprintf(stdout, "GenerateReAuthenticateTokenMessage: Message Size = %d \n", encodedMsg->DataLength()); |
| #endif |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateReAuthenticateTokenMessage (Finished):\n"); |
| #endif |
| } |
| |
| // Responder receives and processes REAuthenticate Token message. |
| { |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessReAuthenticateTokenMessage (Started):\n"); |
| #endif |
| |
| err = respEng.ProcessReAuthenticateTokenMessage(encodedMsg); |
| SuccessOrFail(err, "WeaveTAKEEngine::ProcessReAuthenticateTokenMessage failed\n"); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessReAuthenticateTokenMessage (Finished):\n"); |
| #endif |
| PacketBuffer::Free(encodedMsg); |
| encodedMsg = NULL; |
| } |
| |
| // Responder generates and sends ReAuthenticate Token Response message. |
| { |
| encodedMsg = PacketBuffer::New(); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateReAuthenticateTokenResponseMessage (Started):\n"); |
| #endif |
| err = respEng.GenerateReAuthenticateTokenResponseMessage(encodedMsg); |
| SuccessOrFail(err, "WeaveTAKEEngine::GenerateReAuthenticateTokenResponseMessage failed\n"); |
| |
| #if DEBUG_PRINT_MESSAGE_LENGTH |
| fprintf(stdout, "GenerateReAuthenticateTokenResponseMessage: Message Size = %d \n", encodedMsg->DataLength()); |
| #endif |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateReAuthenticateTokenResponseMessage (Finished):\n"); |
| #endif |
| } |
| |
| // Initiator receives and processes ReAuthenticate Token Response message. |
| { |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessReAuthenticateTokenResponseMessage (Started):\n"); |
| #endif |
| |
| err = initEng.ProcessReAuthenticateTokenResponseMessage(encodedMsg); |
| SuccessOrFail(err, "WeaveTAKEEngine::ProcessReAuthenticateTokenResponseMessage failed\n"); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessReAuthenticateTokenResponseMessage (Finished):\n"); |
| #endif |
| PacketBuffer::Free(encodedMsg); |
| encodedMsg = NULL; |
| } |
| |
| } |
| else |
| { |
| // Initiator generates and sends Authenticate Token message. |
| { |
| encodedMsg = PacketBuffer::New(); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateAuthenticateTokenMessage (Started):\n"); |
| #endif |
| err = initEng.GenerateAuthenticateTokenMessage(encodedMsg); |
| SuccessOrFail(err, "WeaveTAKEEngine::GenerateAuthenticateTokenMessage failed\n"); |
| |
| #if DEBUG_PRINT_MESSAGE_LENGTH |
| fprintf(stdout, "GenerateAuthenticateTokenMessage: Message Size = %d \n", encodedMsg->DataLength()); |
| #endif |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateAuthenticateTokenMessage (Finished):\n"); |
| #endif |
| } |
| |
| // Responder receives and processes Authenticate Token message. |
| { |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessAuthenticateTokenMessage (Started):\n"); |
| #endif |
| |
| err = respEng.ProcessAuthenticateTokenMessage(encodedMsg); |
| SuccessOrFail(err, "WeaveTAKEEngine::ProcessAuthenticateTokenMessage failed\n"); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessAuthenticateTokenMessage (Finished):\n"); |
| #endif |
| PacketBuffer::Free(encodedMsg); |
| encodedMsg = NULL; |
| } |
| |
| // Responder generates and sends Authenticate Token Response message. |
| { |
| encodedMsg = PacketBuffer::New(); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateAuthenticateTokenResponseMessage (Started):\n"); |
| #endif |
| err = respEng.GenerateAuthenticateTokenResponseMessage(encodedMsg); |
| SuccessOrFail(err, "WeaveTAKEEngine::GenerateAuthenticateTokenResponseMessage failed\n"); |
| |
| #if DEBUG_PRINT_MESSAGE_LENGTH |
| fprintf(stdout, "GenerateAuthenticateTokenResponseMessage: Message Size = %d \n", encodedMsg->DataLength()); |
| #endif |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "GenerateAuthenticateTokenResponseMessage (Finished):\n"); |
| #endif |
| } |
| |
| // Initiator receives and processes Authenticate Token Response message. |
| { |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessAuthenticateTokenResponseMessage (Started):\n"); |
| #endif |
| |
| err = initEng.ProcessAuthenticateTokenResponseMessage(encodedMsg); |
| SuccessOrFail(err, "WeaveTAKEEngine::ProcessAuthenticateTokenResponseMessage failed\n"); |
| |
| #if DEBUG_PRINT_ENABLE |
| fprintf(stdout, "ProcessAuthenticateTokenResponseMessage (Finished):\n"); |
| #endif |
| PacketBuffer::Free(encodedMsg); |
| encodedMsg = NULL; |
| } |
| } |
| |
| if (encryptCommPhase) |
| { |
| err = initEng.GetSessionKey(initSessionKey); |
| SuccessOrFail(err, "WeaveTAKEEngine::GetSessionKey() failed\n"); |
| |
| err = respEng.GetSessionKey(respSessionKey); |
| SuccessOrFail(err, "WeaveTAKEEngine::GetSessionKey() failed\n"); |
| |
| VerifyOrFail(memcmp(initSessionKey->AES128CTRSHA1.DataKey, respSessionKey->AES128CTRSHA1.DataKey, WeaveEncryptionKey_AES128CTRSHA1::DataKeySize) == 0, |
| "Data key mismatch\n"); |
| |
| VerifyOrFail(memcmp(initSessionKey->AES128CTRSHA1.IntegrityKey, respSessionKey->AES128CTRSHA1.IntegrityKey, WeaveEncryptionKey_AES128CTRSHA1::IntegrityKeySize) == 0, |
| "Integrity key mismatch\n"); |
| } |
| } |
| |
| void test1(bool EAP, bool ECP) |
| { |
| // Standard test, Authenticate |
| MockTAKEChallengerDelegate config; |
| TestTAKEEngine(config, true, kTAKEConfig_Config1, EAP, ECP); |
| } |
| |
| void test2(bool EAP, bool ECP) |
| { |
| // No authorised Tokens |
| TAKEConfigNoAuthorized config; |
| TestTAKEEngine(config, false, kTAKEConfig_Config1, EAP, ECP); |
| } |
| void test3(bool EAP, bool ECP) |
| { |
| // 3 authorised tokens, none of them are the correct one |
| TAKEConfigJunkAuthorized config; |
| TestTAKEEngine(config, false, kTAKEConfig_Config1, EAP, ECP); |
| } |
| void test4(bool EAP, bool ECP) |
| { |
| // Tries to use an invalid config |
| MockTAKEChallengerDelegate config; |
| TestTAKEEngine(config, true, 27, EAP, ECP); |
| } |
| void test5(bool EAP, bool ECP) |
| { |
| // TL is true, invalid argument |
| TAKEConfigTimeLimitedIK config; |
| TestTAKEEngine(config, true, kTAKEConfig_Config1, EAP, ECP, true); // TL is true => error |
| } |
| |
| void test6(bool EAP, bool ECP) |
| { |
| uint8_t AK[] = { 0x9F, 0x0F, 0x92, 0xE3, 0xB9, 0x04, 0x96, 0xA1, 0xCB, 0x7C, 0x94, 0x99, 0xAB, 0x34, 0xDD, 0x04 }; |
| uint8_t ENC_AK[] = { 0xE6, 0xC4, 0x03, 0xE8, 0xEE, 0xA3, 0x80, 0x56, 0xE0, 0xB1, 0x9C, 0xE9, 0xE3, 0xA6, 0xD8, 0x3A }; |
| |
| MockTAKEChallengerDelegate config; |
| uint16_t authKeyLen = TAKE::kAuthenticationKeySize; |
| uint16_t encryptedAuthKeyLen = kTokenEncryptedStateSize; |
| WEAVE_ERROR err = config.StoreTokenAuthData(1, kTAKEConfig_Config1, AK, authKeyLen, ENC_AK, encryptedAuthKeyLen); |
| if (err != WEAVE_NO_ERROR) |
| { |
| fprintf(stderr, "%s FAILED: ", __FUNCTION__); |
| fputs("TAKEConfig::UpdateAuthenticationKeys", stderr); |
| fputs(ErrorStr(err), stderr); |
| fputs("\n", stderr); |
| exit(-1); |
| } |
| TestTAKEEngine(config, true, kTAKEConfig_Config1, EAP, ECP, false, true); |
| } |
| |
| void test7(bool EAP, bool ECP) |
| { |
| // Standard test, Authenticate |
| TAKEConfigChallengerIdIsNodeId config; |
| TestTAKEEngine(config, true, kTAKEConfig_Config1, EAP, ECP, false, false, false); |
| } |
| |
| // Parameters are EAP and ECP |
| typedef void(*testFunction)(bool, bool); |
| |
| int main(int argc, char *argv[]) |
| { |
| WEAVE_ERROR err; |
| int i; |
| time_t sec_now; |
| time_t sec_last; |
| |
| #if WEAVE_SYSTEM_CONFIG_USE_LWIP |
| tcpip_init(NULL, NULL); |
| #endif // WEAVE_SYSTEM_CONFIG_USE_LWIP |
| |
| err = nl::Weave::Platform::Security::InitSecureRandomDataSource(NULL, 64, NULL, 0); |
| FAIL_ERROR(err, "InitSecureRandomDataSource() failed"); |
| |
| #define NUMBER_OF_ITERATIONS 1 |
| #define NUMBER_OF_TESTS 7 |
| #define NUMBER_OF_CONFIGS 4 |
| |
| testFunction tests[NUMBER_OF_TESTS] = { test1, test2, test3, test4, test5, test6, test7 }; |
| bool configs[NUMBER_OF_CONFIGS][2] = { { false, false }, { true, false }, { false, true }, { true, true } }; |
| |
| for (int test = 0; test < NUMBER_OF_TESTS; test++) |
| { |
| for (int conf = 0; conf < NUMBER_OF_CONFIGS; conf++) |
| { |
| bool EAP = configs[conf][0]; |
| bool ECP = configs[conf][1]; |
| printf("\nTEST%d, EAP = %s, ECP = %s (%d iterations)\n", test+1, EAP ? "true" : "false", ECP ? "true" : "false", NUMBER_OF_ITERATIONS); |
| sec_last = time(NULL); |
| for (i=0; i < NUMBER_OF_ITERATIONS; i++) |
| { |
| tests[test](EAP, ECP); |
| } |
| sec_now = time(NULL); |
| printf("TIME DELTA (sec) = %ld sec\n", (sec_now - sec_last)); |
| } |
| } |
| |
| printf("All tests succeeded\n"); |
| } |