uint32 FOnlineSessionNull::FindLANSession() { uint32 Return = ERROR_IO_PENDING; // Recreate the unique identifier for this client GenerateNonce((uint8*)&LANSessionManager.LanNonce, 8); FOnValidResponsePacketDelegate ResponseDelegate = FOnValidResponsePacketDelegate::CreateRaw(this, &FOnlineSessionNull::OnValidResponsePacketReceived); FOnSearchingTimeoutDelegate TimeoutDelegate = FOnSearchingTimeoutDelegate::CreateRaw(this, &FOnlineSessionNull::OnLANSearchTimeout); FNboSerializeToBufferNull Packet(LAN_BEACON_MAX_PACKET_SIZE); LANSessionManager.CreateClientQueryPacket(Packet, LANSessionManager.LanNonce); if (LANSessionManager.Search(Packet, ResponseDelegate, TimeoutDelegate) == false) { Return = E_FAIL; FinalizeLANSearch(); CurrentSessionSearch->SearchState = EOnlineAsyncTaskState::Failed; // Just trigger the delegate as having failed TriggerOnFindSessionsCompleteDelegates(false); } return Return; }
void Mac::ProcessTransmitSecurity(void) { uint8_t securityLevel; uint8_t nonce[kNonceSize]; uint8_t tagLength; Crypto::AesCcm aesCcm; if (mSendFrame.GetSecurityEnabled() == false) { ExitNow(); } mSendFrame.GetSecurityLevel(securityLevel); mSendFrame.SetFrameCounter(mKeyManager.GetMacFrameCounter()); mSendFrame.SetKeyId((mKeyManager.GetCurrentKeySequence() & 0x7f) + 1); GenerateNonce(mExtAddress, mKeyManager.GetMacFrameCounter(), securityLevel, nonce); aesCcm.SetKey(mKeyManager.GetCurrentMacKey(), 16); tagLength = mSendFrame.GetFooterLength() - Frame::kFcsSize; aesCcm.Init(mSendFrame.GetHeaderLength(), mSendFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce)); aesCcm.Header(mSendFrame.GetHeader(), mSendFrame.GetHeaderLength()); aesCcm.Payload(mSendFrame.GetPayload(), mSendFrame.GetPayload(), mSendFrame.GetPayloadLength(), true); aesCcm.Finalize(mSendFrame.GetFooter(), &tagLength); mKeyManager.IncrementMacFrameCounter(); exit: {} }
//----------------------------------------------------------- //----------------------------------------------------------- std::string GenerateAuthorisationHeader(RequestType in_requestType, const std::string& in_url, const std::string& in_rawData, const std::string& in_consumerKey, const std::string& in_consumerSecret, const std::string& in_oauthToken, const std::string& in_oauthTokenSecret, const std::string& in_oauthVerifier) { std::string pureUrl = in_url; //If URL itself contains "?key=value", then extract and put them in map size_t position = pureUrl.find_first_of("?"); std::unordered_map<std::string, std::string> urlParams; if(std::string::npos != position) { //Get only URL pureUrl = in_url.substr(0, position); //Get only key=value data part std::string dataPart = in_url.substr(position + 1); //This dataPart can contain many key value pairs: key1=value1&key2=value2&key3=value3 size_t sep = std::string::npos; size_t position2 = std::string::npos; std::string dataKeyVal; std::string dataKey; std::string dataVal; while(std::string::npos != (sep = dataPart.find_first_of("&"))) { //Extract first key=value pair dataKeyVal = dataPart.substr(0, sep); //Split them position2 = dataKeyVal.find_first_of("="); if(std::string::npos != position2) { dataKey = dataKeyVal.substr(0, position2); dataVal = dataKeyVal.substr(position2 + 1); //Put this key=value pair in map urlParams[dataKey] = StringUtils::URLEncode(dataVal); } dataPart = dataPart.substr(sep + 1); } //For the last key=value dataKeyVal = dataPart.substr(0, sep); //Split them position2 = dataKeyVal.find_first_of("="); if(std::string::npos != position2) { dataKey = dataKeyVal.substr(0, position2); dataVal = dataKeyVal.substr(position2 + 1); //Put this key=value pair in map urlParams[dataKey] = StringUtils::URLEncode(dataVal); } } //Generate nonce and timestamp if required TimeIntervalSecs timestamp = (TimeIntervalSecs)time(0); std::string nonce = GenerateNonce(timestamp); std::string timestampString = Core::ToString(timestamp); //Build key-value pairs needed for OAuth request token, without signature BuildOAuthTokenKeyValuePairs(in_rawData, "", timestampString, nonce, in_consumerKey, in_oauthToken, in_oauthVerifier, urlParams); //Get url encoded base64 signature using request type, url and parameters std::string oauthSignature = GetSignature(in_requestType, pureUrl, in_consumerSecret, in_oauthTokenSecret, urlParams); //Now, again build key-value pairs with signature this time BuildOAuthTokenKeyValuePairs("", oauthSignature, timestampString, nonce, in_consumerKey, in_oauthToken, in_oauthVerifier, urlParams); //Get OAuth header in string format std::string strRawParams = GetStringFromOAuthKeyValuePairs(urlParams, ","); //Build authorization header return k_authHeader + strRawParams; }
int crypto_aead_encrypt_no_nonce( unsigned char *c,unsigned long long *clen, const unsigned char *m,unsigned long long mlen, const unsigned char *ad,unsigned long long adlen, const unsigned char *nsec, unsigned char *npub, const unsigned char *k ) //Generates nonce out of plaintext and AD and put it into npub { Init();//Initializing GF(256) multiplication table for AES if(clen==NULL) return -1; if((mlen==0) && (adlen==0)) { *clen=0; return 0; } //Assume that we do encryption and/or authentication so we need a key and a ciphertext pointer valid if( (k==NULL) || (c==NULL) ) return -2; GenerateNonce(npub,m,mlen,ad,adlen,k); //Initializing constants unsigned char D0[2]; D0[0] = CRYPTO_NPUBBYTES*8; //nonce length in bits, zero for 256-bit nonce D0[1] = CRYPTO_KEYBYTES*8; //key length in bits (*clen)=0; //Block variables unsigned char BlockInput[64]; //V1 - input to the first layer call of F unsigned char BlockMiddle[64]; //W1 - output of the first layer call of F unsigned char BlockOutput[64]; //Y1 - output of the second layer call of F unsigned char BlockLastInput[64]; //Z1 - input to the last call of F memset(BlockLastInput,0,64); unsigned char Tag[64]; //Tag output unsigned long long encrypted_bytes=0;//Encrypted bytes counter //Encryption part if(mlen!=0) { if(m==NULL) { //Clearing variables for(unsigned i=0; i<64; ++i) BlockInput[i] = BlockMiddle[i] = BlockOutput[i] = BlockLastInput[i] = 0; return -3; } unsigned long long mblock_counter=1; //Message block counter while((mlen>0)) { /* I. First layer */ //1. Domain-separation constant BlockInput[1] = D0[1]; if(mlen>= CRYPTO_MBLOCK) BlockInput[0] = D0[0]; else //Last incomplete block BlockInput[0] = D0[0]+1; //2. Counter for(unsigned i=0; i<CRYPTO_COUNTERBYTES; ++i) { BlockInput[i+2] = (i<sizeof(mblock_counter))?(mblock_counter>>(8*i))&0xff :0;//copying counter bytewise } //3. Nonce for(unsigned i=0; i<CRYPTO_NPUBBYTES; ++i) { BlockInput[i+2+CRYPTO_COUNTERBYTES] = npub[i]; } //4. Key for(unsigned i=0; i<CRYPTO_KEYBYTES; ++i) { BlockInput[i+2+CRYPTO_COUNTERBYTES+CRYPTO_NPUBBYTES] = k[i]; } //5. Permutation call FPerm(BlockInput, BlockMiddle); //First layer call to F /* II. Encryption*/ if(mlen>=CRYPTO_MBLOCK)//Full block encryption { for(unsigned i=0; i<CRYPTO_MBLOCK; ++i) { BlockMiddle[i+2] ^= m[encrypted_bytes+i]; c[encrypted_bytes+i] = BlockMiddle[i+2]; } BlockMiddle[1] = D0[1]; BlockMiddle[0] = D0[0]+2; //New Di constant } else //Last incomplete block { for(unsigned i=0; i<(unsigned)mlen; ++i)//Incomplete block Encryption { BlockMiddle[i+2] ^= m[encrypted_bytes+i]; c[encrypted_bytes+i] = BlockMiddle[i+2]; } for(unsigned i=(unsigned)mlen; i<CRYPTO_MBLOCK; ++i) { BlockMiddle[i+2] ^= (unsigned char)mlen; //Extra Padding: extra bytes filled with the last block length in bytes } BlockMiddle[1] = D0[1]; BlockMiddle[0] = D0[0]+3; //New Di constant } //III. Second permutation call //1. Call FPerm(BlockMiddle, BlockOutput); //Second layer call to F //2. Buffer update for(unsigned i=0; i<64-2-CRYPTO_KEYBYTES; ++i)//Adding the output to tag preparation buffer { BlockLastInput[i+2] ^= BlockOutput[i+2]; } //Counters increment mblock_counter++; if(mlen>=CRYPTO_MBLOCK) { encrypted_bytes += CRYPTO_MBLOCK; mlen-=CRYPTO_MBLOCK; } else { encrypted_bytes += mlen; mlen=0; } (*clen) = encrypted_bytes; } } //Associated data part if(adlen!=0) { if(ad==NULL) { //Clearing variables for(unsigned i=0; i<64; ++i) BlockInput[i] = BlockMiddle[i] = BlockOutput[i] = BlockLastInput[i] = 0; return -4; } unsigned long long adblock_counter=1; //AD block counter unsigned long long auth_bytes=0; while(adlen>0) { //1. Constant BlockInput[1] = D0[1]; if(adlen>= CRYPTO_ADBLOCK) BlockInput[0] = D0[0]+4; else //Last incomplete block BlockInput[0] = D0[0]+5; //2. Counter for(unsigned i=0; i<CRYPTO_KEYBYTES; ++i) BlockInput[i+2] = (i<sizeof(adblock_counter))? (adblock_counter>>(8*i))&0xff:0;//copying counter bytewise //3. AD block if(adlen >= CRYPTO_ADBLOCK) //Filling AD block { for(unsigned i=0; i<CRYPTO_ADBLOCK; ++i) BlockInput[i+2+CRYPTO_KEYBYTES] = ad[auth_bytes+i]; } else //Last incomplete block { for(unsigned i=0; i<adlen; ++i) BlockInput[i+2+CRYPTO_KEYBYTES] = ad[auth_bytes+i]; for(unsigned i=(unsigned)adlen; i<CRYPTO_ADBLOCK; ++i) BlockInput[i+2+CRYPTO_KEYBYTES] = (unsigned char)adlen; } //4. Key for(unsigned i=0; i<CRYPTO_KEYBYTES; ++i) { BlockInput[i+CRYPTO_ADBLOCK+CRYPTO_KEYBYTES+2] = k[i]; } //5.Call to the F permutation FPerm(BlockInput,BlockOutput);//Call to the F permutation for(unsigned i=0; i<64-2-CRYPTO_KEYBYTES; ++i)//Adding the output to Z { BlockLastInput[i+2] ^= BlockOutput[i]; } //Counters increment adblock_counter++; if(adlen>=CRYPTO_ADBLOCK) { auth_bytes += CRYPTO_ADBLOCK; adlen-=CRYPTO_ADBLOCK; } else { auth_bytes += adlen; adlen=0; } } } // Tag production for(unsigned i=0; i<CRYPTO_KEYBYTES; ++i) //Key to the Z input BlockLastInput[64-CRYPTO_KEYBYTES+i] = k[i]; BlockLastInput[0] = D0[0]+6; BlockLastInput[1] = D0[1]; //1. Permutation call FPerm(BlockLastInput,Tag); //2. Key injection for(unsigned i=0; i<CRYPTO_KEYBYTES; ++i) { Tag[64-CRYPTO_KEYBYTES+i] ^= k[i]; } //3. Truncation for(unsigned i=0; i<CRYPTO_ABYTES; ++i) c[(*clen)+i] = Tag[i]; *clen += CRYPTO_ABYTES; //Clearing variables for(unsigned i=0; i<64; ++i) BlockInput[i] = BlockMiddle[i] = BlockOutput[i] = BlockLastInput[i] = 0; return 0; }
//-------------------------------------------------------------------------------------------------- void OAuthSignRequest ( const Credentials_t& keys, ///< [IN] The application's keys. Request_t type, ///< [IN] The type of request to be performed. const std::string& url, ///< [IN] The address and path of the request. ParamMap_t& params, ///< [IN/OUT] The parameter list will be updated with the required ///< OAuth additions. bool excludeConsumer ///< [IN] Should the consumer key be excluded from the params? ) //-------------------------------------------------------------------------------------------------- { std::string timeStamp = GenerateTimestamp(); params.insert({ "oauth_nonce", GenerateNonce(timeStamp) }); params.insert({ "oauth_signature_method", "HMAC-SHA1" }); params.insert({ "oauth_timestamp", timeStamp }); params.insert({ "oauth_version", "1.0" }); if (excludeConsumer == false) { params.insert({ "oauth_consumer_key", keys.consumer.publicKey }); } if (keys.oAuthAccess.publicKey.size() > 0) { params.insert({ "oauth_token", keys.oAuthAccess.publicKey }); } std::stringstream requestString; std::stringstream paramString; switch (type) { case Request_t::Get: requestString << "GET&"; break; case Request_t::Post: requestString << "POST&"; break; default: throw std::runtime_error("Unexpected HTTP request type."); } requestString << UrlEncode(url) << "&"; bool first = true; for (auto iter : params) { if (first) { first = false; } else { paramString << "&"; } paramString << UrlEncode(iter.first) << "=" << UrlEncode(iter.second); } requestString << UrlEncode(paramString.str()); for (size_t i = 0; i < requestString.str().size(); i += 20) { std::string section = requestString.str().substr(i, 20); } CHMAC_SHA1 sha1; std::string signingKey = UrlEncode(keys.consumer.secretKey) + "&"; if (keys.oAuthAccess.secretKey.size() > 0) { signingKey += UrlEncode(keys.oAuthAccess.secretKey); } BYTE digest[CHMAC_SHA1::SHA1_DIGEST_LENGTH] = ""; sha1.HMAC_SHA1((unsigned char*)requestString.str().c_str(), requestString.str().size(), (unsigned char*)signingKey.c_str(), signingKey.size(), digest); params.insert({ "oauth_signature", base64_encode(digest, sizeof(digest)) }); }
ThreadError Mac::ProcessReceiveSecurity(const Address &aSrcAddr, Neighbor *aNeighbor) { ThreadError error = kThreadError_None; uint8_t securityLevel; uint32_t frameCounter; uint8_t nonce[kNonceSize]; uint8_t tag[Frame::kMaxMicSize]; uint8_t tagLength; uint8_t keyid; uint32_t keySequence; const uint8_t *macKey; Crypto::AesCcm aesCcm; mReceiveFrame.SetSecurityValid(false); if (mReceiveFrame.GetSecurityEnabled() == false) { ExitNow(); } VerifyOrExit(aNeighbor != NULL, error = kThreadError_Security); mReceiveFrame.GetSecurityLevel(securityLevel); mReceiveFrame.GetFrameCounter(frameCounter); GenerateNonce(aSrcAddr.mExtAddress, frameCounter, securityLevel, nonce); tagLength = mReceiveFrame.GetFooterLength() - Frame::kFcsSize; mReceiveFrame.GetKeyId(keyid); keyid--; if (keyid == (mKeyManager.GetCurrentKeySequence() & 0x7f)) { // same key index keySequence = mKeyManager.GetCurrentKeySequence(); macKey = mKeyManager.GetCurrentMacKey(); VerifyOrExit(aNeighbor->mPreviousKey == true || frameCounter >= aNeighbor->mValid.mLinkFrameCounter, error = kThreadError_Security); } else if (aNeighbor->mPreviousKey && mKeyManager.IsPreviousKeyValid() && keyid == (mKeyManager.GetPreviousKeySequence() & 0x7f)) { // previous key index keySequence = mKeyManager.GetPreviousKeySequence(); macKey = mKeyManager.GetPreviousMacKey(); VerifyOrExit(frameCounter >= aNeighbor->mValid.mLinkFrameCounter, error = kThreadError_Security); } else if (keyid == ((mKeyManager.GetCurrentKeySequence() + 1) & 0x7f)) { // next key index keySequence = mKeyManager.GetCurrentKeySequence() + 1; macKey = mKeyManager.GetTemporaryMacKey(keySequence); } else { for (Receiver *receiver = mReceiveHead; receiver; receiver = receiver->mNext) { receiver->HandleReceivedFrame(mReceiveFrame, kThreadError_Security); } ExitNow(error = kThreadError_Security); } aesCcm.SetKey(macKey, 16); aesCcm.Init(mReceiveFrame.GetHeaderLength(), mReceiveFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce)); aesCcm.Header(mReceiveFrame.GetHeader(), mReceiveFrame.GetHeaderLength()); aesCcm.Payload(mReceiveFrame.GetPayload(), mReceiveFrame.GetPayload(), mReceiveFrame.GetPayloadLength(), false); aesCcm.Finalize(tag, &tagLength); VerifyOrExit(memcmp(tag, mReceiveFrame.GetFooter(), tagLength) == 0, error = kThreadError_Security); if (keySequence > mKeyManager.GetCurrentKeySequence()) { mKeyManager.SetCurrentKeySequence(keySequence); } if (keySequence == mKeyManager.GetCurrentKeySequence()) { aNeighbor->mPreviousKey = false; } aNeighbor->mValid.mLinkFrameCounter = frameCounter + 1; mReceiveFrame.SetSecurityValid(true); exit: return error; }