Пример #1
0
McNackFrame::McNackFrame(unsigned char* buffer)
{

    unsigned char* buffer_start = buffer;
    buffer_str_len_ = 0;

    /*ETHERNET HEADER*/
    eh_header* eh = (struct eh_header *) buffer;
    buffer += sizeof (eh_header);
    buffer_str_len_ += sizeof (eh_header);

    /*FRAME HEADER*/
    mc_nack_header* rfh = (struct mc_nack_header *) buffer;
    buffer += sizeof (mc_nack_header);
    buffer_str_len_ += sizeof (mc_nack_header);

    /*SOURCE HOST*/
    hostname_source_ = "";
    hostname_source_.append((const char*) buffer, rfh->hostname_source_len);
    buffer += rfh->hostname_source_len;
    buffer_str_len_ += hostname_source_.length();

    /*MC GROUP */
    mc_group_ = "";
    if (rfh->mc_group_len > 0)
    {
        mc_group_.append((const char*) buffer, rfh->mc_group_len);
        buffer += rfh->mc_group_len;
    }
    buffer_str_len_ += mc_group_.length();


    /* req frame list */
    for(uint32_t i = 0; i < rfh->frame_seq_num_size; i++)
    {
        uint32_t n;
        memcpy(&n, buffer, sizeof(uint32_t));
        buffer += sizeof(uint32_t);
        req_seq_nums_.push_back(n);
    }


    /*CRC */
    uint32_t crc = 0;
    memcpy((unsigned char*) &crc, (unsigned char*) buffer, 4); // get CRC

    std::string crc_data_string = "";
    crc_data_string.append((const char*) buffer_start, this->HEADER_FIXED_LEN + rfh->hostname_source_len + rfh->mc_group_len + rfh->frame_seq_num_size * sizeof(uint32_t));
    correct_crc_ = (crc == (uint32_t) GetCrc32(crc_data_string));
    buffer_str_len_++;



    /* COPY HEADER FIELDS */
    memcpy(&this->eh_h_, &(*eh), sizeof (eh_header));
    memcpy(&this->header_, &(*rfh), sizeof (mc_nack_header));



}
Пример #2
0
// Verifies the CRC-32 of the whole self-extracting package (except the digital signature areas, if present)
BOOL VerifyPackageIntegrity (void)
{
	int fileDataEndPos = 0;
	int fileDataStartPos = 0;
	unsigned __int32 crc = 0;
	unsigned char *tmpBuffer;
	int tmpFileSize;
	char path [TC_MAX_PATH];

	GetModuleFileName (NULL, path, sizeof (path));

	fileDataEndPos = (int) FindStringInFile (path, MagEndMarker, strlen (MagEndMarker));
	if (fileDataEndPos < 0)
	{
		Error ("DIST_PACKAGE_CORRUPTED");
		return FALSE;
	}
	fileDataEndPos--;

	fileDataStartPos = (int) FindStringInFile (path, MAG_START_MARKER, strlen (MAG_START_MARKER));
	if (fileDataStartPos < 0)
	{
		Error ("DIST_PACKAGE_CORRUPTED");
		return FALSE;
	}
	fileDataStartPos += strlen (MAG_START_MARKER);


	if (!LoadInt32 (path, &crc, fileDataEndPos + strlen (MagEndMarker) + 1))
	{
		Error ("CANT_VERIFY_PACKAGE_INTEGRITY");
		return FALSE;
	}

	// Compute the CRC-32 hash of the whole file (except the digital signature area, if present)
	tmpBuffer = LoadFile (path, &tmpFileSize);

	if (tmpBuffer == NULL)
	{
		Error ("CANT_VERIFY_PACKAGE_INTEGRITY");
		return FALSE;
	}

	// Zero all bytes that change when an exe is digitally signed (except appended blocks).
	WipeSignatureAreas (tmpBuffer);

	if (crc != GetCrc32 (tmpBuffer, fileDataEndPos + 1 + strlen (MagEndMarker)))
	{
		free (tmpBuffer);
		Error ("DIST_PACKAGE_CORRUPTED");
		return FALSE;
	}

	free (tmpBuffer);

	return TRUE;
}
Пример #3
0
std::string McNackFrame::getFrameAsNetworkString()
{




    /*LEN FIELDS */
    this->header_.hostname_source_len = hostname_source_.length();
    this->header_.mc_group_len = mc_group_.length();


    unsigned char f_buffer[ETHER_MAX_LEN]; // = unsigned char[ETHER_MAX_LEN];
    unsigned char* buffer = f_buffer;
    unsigned char* buffer_start = f_buffer;

    /*ETHERNET FIELDS*/
    //eh_header* eh = (struct eh_header *) buffer;
    memcpy(buffer, &this->eh_h_, sizeof (eh_header));
    buffer += sizeof (eh_header);

    /*FIXED RF HEADER FIELDS*/
    memcpy(buffer, &this->header_, sizeof (mc_nack_header));
    buffer += sizeof (mc_nack_header);

    /*SOURCE HOST */
    memcpy(buffer, this->hostname_source_.data(),
           this->hostname_source_.length());
    buffer += this->hostname_source_.length();

    /*MC GROUP */
    memcpy(buffer, this->mc_group_.data(), this->mc_group_.length());
    buffer += mc_group_.length();

    /*req_seq_nums_*/
    for (std::vector<uint32_t>::iterator i = req_seq_nums_.begin(); i != req_seq_nums_.end(); i++)
    {
        memcpy(buffer, &(*i), sizeof(uint32_t));
        buffer += sizeof(uint32_t);
    }



    /*CRC*/
    int dynamic_field_len = this->hostname_source_.length() + this->mc_group_.length() + req_seq_nums_.size() * sizeof(uint32_t);
    std::string crc_string = std::string((const char*) buffer_start, this->HEADER_FIXED_LEN + dynamic_field_len);
    uint32_t crc = GetCrc32(crc_string);
    memcpy(buffer, &crc, sizeof (uint32_t));
    buffer += sizeof (uint32_t);



    return string((const char*) buffer_start, this->HEADER_FIXED_LEN + dynamic_field_len + sizeof (crc));


}
Пример #4
0
  bool Producer::DoSend(BrokerChannel *channel, const string& topic_name,
                        int partition_id, const vector<string>& msgs)
  {
    assert(writer_);
    writer_->Reset();
    WriteProduceRequestHeader();

    uint32_t topics_count = 1;
    writer_->WriteInt32(topics_count);

    for (int i = 0; i < topics_count; ++i) {
      //string topic1("tempdel1");
      //string topic1("cltest2p2r");
      writer_->WriteShortString(topic_name);

      uint32_t partition_count = 1;
      writer_->WriteInt32(partition_count);

      // @TODO: delete this message variable later.
      const char *message = msgs.front().c_str();
      int msgs_total_size = 0;

      for(vector<string>::const_iterator it = msgs.begin();
          it != msgs.end(); ++it) {
        msgs_total_size += (*it).size() + 6 + 4;
      }


      for (int k = 0; k < partition_count; ++k) {
        uint32_t partition_id = 0;
        writer_->WriteInt32(partition_id);
        //uint32_t message_size = strlen(message) + 6;  // 6 is the magic.
        writer_->WriteInt32(msgs_total_size);
        for (vector<string>::const_iterator it2 = msgs.begin();
            it2 != msgs.end(); ++it2) {
          //char data[100] = message;
          int msg_size = (*it2).size() + 6;
          writer_->WriteInt32(msg_size);
          writer_->WriteInt8(1);
          writer_->WriteInt8(0);
          //std::string temp(*it2);
          int32_t crc32 = GetCrc32(*it2);
          // writer_->WriteInt32(0xb61f1169);
          writer_->WriteInt32(crc32);
          // cout << "wrote CRC" << endl;
          writer_->WriteCharN((*it2).c_str(), strlen((*it2).c_str()));
        }
      }
    }
    writer_->WriteLengthAtIndex(0);
    return channel->SendDataBlocking(writer_->GetRawBuffer(),
                                     writer_->GetRawBufferLength());
  }
Пример #5
0
uint32 CRdbHashIndex::AttachRecord(CRecord* pRecord)
{
	uint32 nHashValue;
	uint32 i, nIdxFieldCount = m_pIdxDef->m_nFieldCount;
	m_oFilter.Clear();
	if(nIdxFieldCount == 1)
	{
		uint32 nFieldNo = m_pIdxDef->m_pFields[0];
		m_oFilter.SetField(nFieldNo);
		nHashValue = pRecord->GetField(nFieldNo)->GetHashValue();
	}
	else
	{
		uint32 * pHashValue = new uint32[nIdxFieldCount];
		if(!pHashValue)
		{
			FocpLogEx(GetLogName(), FOCP_LOG_ERROR, ("CRdbHashIndex::AttachRecord(%s): RDB_LACK_MEMORY", m_pTabDef->m_pBaseAttr->sTableName));
			return RDB_LACK_MEMORY;
		}
		for(i=0; i<nIdxFieldCount; ++i)
		{
			uint32 nFieldNo = m_pIdxDef->m_pFields[i];
			m_oFilter.SetField(nFieldNo);	
			pHashValue[i] = pRecord->GetField(nFieldNo)->GetHashValue();
		}
		nHashValue = GetCrc32((const uint8*)pHashValue, nIdxFieldCount<<2, 1);
		delete[] pHashValue;
	}
	if(m_pPrimaryIndex && !ExistInPrimaryTable(&m_oFilter, pRecord))
		return RDB_RECORD_NOTEXIST_IN_PRIMARY_TABLE;
	bool bConflict;
	int32 bMemory = 1;
	if(m_pTabDef->m_pBaseAttr->nStorage == RDB_FILE_TABLE)
		bMemory = 0;

	uint32 nSub;
	CRecordIsEqualContext oContext = {this, pRecord, &m_oFilter};
	uint64 nRowId = pRecord->m_nRowId, nBlock;
	THashBlock* pBlock = m_oHash.InsertNode(nHashValue, nRowId, FOCP_NAME::RecordIsEqual, &oContext, bMemory, nBlock, nSub, bConflict);
	if(!pBlock)
	{
		if(bConflict)
			return RDB_UNIQUE_INDEX_CONFLICT;
		return RDB_LACK_STORAGE;
	}
	m_oHash.ReleaseBlock(nBlock, pBlock);
	CVmmHashInfo& oHashInfo = m_oHash.GetHashInfo();
	CRdbHashInfo oInfo = {{m_oAllocator.GetThis(), m_oHash.GetThis()}, {oHashInfo.i, oHashInfo.n, oHashInfo.r, oHashInfo.d}};
	vcommit(m_nThis, (char*)&oInfo, sizeof(oInfo));
	return RDB_SUCCESS;
}
Пример #6
0
RouteRequest::RouteRequest(unsigned char* buffer) {

    unsigned char* buffer_start = buffer;

    eh_header* eh = (struct eh_header *) buffer;
    buffer += sizeof (eh_header);
    rreq_header* rfh = (struct rreq_header *) buffer;
    buffer += sizeof (rreq_header);
    


    /*Source Host*/
    hostname_source_ = "";
    hostname_source_.append((const char*) buffer, rfh->hostname_source_len);
    buffer += rfh->hostname_source_len;

    /*Dest Host*/
    hostname_destination_ = "";
    hostname_destination_.append((const char*) buffer, rfh->hostname_destination_len);
    buffer += rfh->hostname_destination_len;


    /*PATH*/
    for (uint32_t i = 0; i < rfh->hop_count; i++) {
        mac current_mac;
        memcpy((unsigned char*) current_mac.mac_adr, (unsigned char*) buffer, 6);
        path_l_.push_back(current_mac);

        buffer += 6;
    }
    
        /*INIT FLAGS*/
	mc_flag_ = (rfh->flag_field / 128) % 2 == 1;
        

	/*CRC */
	uint32_t crc = 0;
	memcpy((unsigned char*) &crc, (unsigned char*) buffer, 4); // get CRC
        uint16_t dynamic_field_len = + rfh->hostname_source_len + rfh->hostname_destination_len+ path_l_.size() * 6;
	std::string crc_data_string = "";
	crc_data_string.append((const char*) buffer_start,
			this->HEADER_FIXED_LEN + dynamic_field_len) ;
	correct_crc_ = (crc == (uint32_t) GetCrc32(crc_data_string));


        buffer_str_len_ = this->HEADER_FIXED_LEN +dynamic_field_len;
                
	/* COPY HEADER FIELDS */
	memcpy(&this->eh_h_, &(*eh), sizeof(eh_header));
	memcpy(&this->header_, &(*rfh), sizeof(rreq_header));
}
Пример #7
0
static bool OpenVolume (byte drive, Password &password, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32, bool skipNormal, bool skipHidden)
{
	int volumeType;
	bool hiddenVolume;
	uint64 headerSec;
	
	AcquireSectorBuffer();

	for (volumeType = 1; volumeType <= 2; ++volumeType)
	{
		hiddenVolume = (volumeType == 2);

		if (hiddenVolume)
		{
			if (skipHidden || PartitionFollowingActive.Drive != drive || PartitionFollowingActive.SectorCount <= ActivePartition.SectorCount)
				continue;

			headerSec = PartitionFollowingActive.StartSector + TC_HIDDEN_VOLUME_HEADER_OFFSET / TC_LB_SIZE;
		}
		else
		{
			if (skipNormal)
				continue;

			headerSec.HighPart = 0;
			headerSec.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR;
		}

		if (ReadSectors (SectorBuffer, drive, headerSec, 1) != BiosResultSuccess)
			continue;

		if (ReadVolumeHeader (!hiddenVolume, (char *) SectorBuffer, &password, cryptoInfo, nullptr) == ERR_SUCCESS)
		{
			// Prevent opening a non-system hidden volume
			if (hiddenVolume && !((*cryptoInfo)->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM))
			{
				crypto_close (*cryptoInfo);
				continue;
			}

			if (headerSaltCrc32)
				*headerSaltCrc32 = GetCrc32 (SectorBuffer, PKCS5_SALT_SIZE);

			break;
		}
	}

	ReleaseSectorBuffer();
	return volumeType != 3;
}
Пример #8
0
/* Capture the keyboard, as long as the event is not the same as the last two
   events, add the crc of the event to the pool along with the crc of the time
   difference between this event and the last. The role of CRC-32 is merely to
   perform diffusion. Note that the output of CRC-32 is subsequently processed
   using a cryptographically secure hash algorithm.  */
LRESULT CALLBACK KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam)
{
	static int lLastKey, lLastKey2;
	static DWORD dwLastTimer;
	int nKey = (lParam & 0x00ff0000) >> 16;
	int nCapture = 0;

	if (nCode < 0)
		return CallNextHookEx (hMouse, nCode, wParam, lParam);

	if ((lParam & 0x0000ffff) == 1 && !(lParam & 0x20000000) &&
	    (lParam & 0x80000000))
	{
		if (nKey != lLastKey)
			nCapture = 1;	/* Capture this key */
		else if (nKey != lLastKey2)
			nCapture = 1;	/* Allow for one repeat */
	}
	if (nCapture)
	{
		DWORD dwTimer = GetTickCount ();
		DWORD j = dwLastTimer - dwTimer;
		unsigned __int32 timeCrc = 0L;
		int i;

		dwLastTimer = dwTimer;
		lLastKey2 = lLastKey;
		lLastKey = nKey;

		for (i = 0; i < 4; i++)
		{
			timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
		}

		for (i = 0; i < 4; i++)
		{
			timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
		}

		EnterCriticalSection (&critRandProt);
		RandaddInt32 ((unsigned __int32) (GetCrc32((unsigned char*) &lParam, sizeof(lParam)) + timeCrc));
		LeaveCriticalSection (&critRandProt);
	}

	return CallNextHookEx (hMouse, nCode, wParam, lParam);
}
Пример #9
0
uint32 CRdbHashIndex::DetachRecord(CRecord* pRecord)
{
    uint32 nHashValue;
	uint32 i, nIdxFieldCount = m_pIdxDef->m_nFieldCount;
	if(nIdxFieldCount == 1)
	{
		uint32 nFieldNo = m_pIdxDef->m_pFields[0];
		nHashValue = pRecord->GetField(nFieldNo)->GetHashValue();
	}
	else
	{
		uint32 * pHashValue = new uint32[nIdxFieldCount];
		if(!pHashValue)
		{
			FocpLogEx(GetLogName(), FOCP_LOG_ERROR, ("CRdbHashIndex::DetachRecord(%s): RDB_LACK_MEMORY", m_pTabDef->m_pBaseAttr->sTableName));
			return RDB_LACK_MEMORY;
		}
		for(i=0; i<nIdxFieldCount; ++i)
		{
			uint32 nFieldNo = m_pIdxDef->m_pFields[i];
			pHashValue[i] = pRecord->GetField(nFieldNo)->GetHashValue();
		}
		nHashValue = GetCrc32((const uint8*)pHashValue, nIdxFieldCount<<2, 1);
		delete[] pHashValue;
	}

	uint64 nRowId = pRecord->m_nRowId;
	if(m_oHash.RemoveNode(nHashValue, FOCP_NAME::IsEqualRowId, &nRowId))
	{
		CVmmHashInfo& oHashInfo = m_oHash.GetHashInfo();
		CRdbHashInfo oInfo = {{m_oAllocator.GetThis(), m_oHash.GetThis()}, {oHashInfo.i, oHashInfo.n, oHashInfo.r, oHashInfo.d}};
		vcommit(m_nThis, (char*)&oInfo, sizeof(oInfo));
		return RDB_SUCCESS;
	}
	return RDB_RECORD_NOT_EXIST;
}
Пример #10
0
RouteResponse::RouteResponse(unsigned char *buffer)
{

    unsigned char *buffer_start = buffer;
    /*ETHERNET HEADER*/
    unsigned char *mac_list_pos =
        buffer + 29; // points to the first mac in path_l_;
    ethhdr *eh = (struct ethhdr *)buffer;
    buffer += 15; // 14 eth_head + 1 frame_Type

    memcpy(&this->eh_, &(*eh), sizeof(ethhdr));

    /*REQUEST ID*/
    uint32_t num_from_network; // help var to convert the integers from bigE to
    // littleE
    memcpy((unsigned char *)&num_from_network, (unsigned char *)buffer, 4);
    request_id_ = ntohl(num_from_network);
    buffer += 4;

    /*MC FLAG*/
    memcpy((unsigned char *)&mc_flag_, (unsigned char *)buffer, 1);
    buffer += 1;

    /*ROOT DISTANCE*/
    memcpy((unsigned char *)&root_distance, (unsigned char *)buffer, 1);
    buffer += 1;

    /*HOP COUNT*/
    memcpy((unsigned char *)&num_from_network, (unsigned char *)buffer, 4);
    hop_count_ = ntohl(num_from_network);
    buffer += 4;

    /*CURRENT HOP*/
    memcpy((unsigned char *)&num_from_network, (unsigned char *)buffer, 4);
    current_hop_ = ntohl(num_from_network);
    current_hop_++;
    buffer += 4;

    /*PATH*/
    for (uint32_t i = 0; i < hop_count_; i++)
    {
        mac currentMac;
        memcpy((unsigned char *)currentMac.mac_adr, (unsigned char *)buffer, 6);
        path_l_.push_back(currentMac);
        buffer += 6;
    }

    /*SRC HOST LEN*/
    memcpy((unsigned char *)&num_from_network, (unsigned char *)buffer,
           4); // get frameId
    uint32_t hostname_source_Len = ntohl(num_from_network);
    buffer += 4;

    /*SRC HOST*/
    hostname_source_ = "";
    for (uint32_t i = 0; i < hostname_source_Len; i++)
    {
        hostname_source_.append((const char *)buffer, 1);
        buffer++;
    }

    /*CRC */
    uint32_t crc = 0;
    memcpy((unsigned char *)&num_from_network, (unsigned char *)buffer,
           4); // get CRC
    crc = ntohl(num_from_network);

    std::string crc_data_string = "";
    crc_data_string.append((const char *)buffer_start,
                           RouteResponse::HEADER_FIXED_LEN - 4 +
                           hostname_source_.length() + 6 * hop_count_);

    if (crc == (uint32_t)GetCrc32(crc_data_string))
        correct_crc_ = true;
    else
        correct_crc_ = false;

    /*INIT mac_current_hop_ */
    unsigned char *mac_current_hop_Pos = mac_list_pos;
    uint32_t relativeMacPostion;
    if (hop_count_ >= current_hop_)
        relativeMacPostion = hop_count_ - current_hop_;
    else
        relativeMacPostion = 0;

    mac_current_hop_Pos += (relativeMacPostion * 6);

    memcpy((void *)mac_current_hop_, (unsigned char *)mac_current_hop_Pos, 6);

    /*INIT mac_previous_hop_ */
    mac_current_hop_Pos = mac_list_pos;
    if (hop_count_ - 1 >= current_hop_)
        relativeMacPostion = hop_count_ - 1 - current_hop_;
    else
        relativeMacPostion = 0;

    mac_current_hop_Pos += (relativeMacPostion * 6);

    memcpy((void *)mac_previous_hop_, (unsigned char *)mac_current_hop_Pos, 6);

    /*INIT mac_next_hop_ */
    mac_current_hop_Pos = mac_list_pos;
    if (hop_count_ + 1 >= current_hop_)
        relativeMacPostion = hop_count_ + 1 - current_hop_;
    else
        relativeMacPostion = 0;

    mac_current_hop_Pos += (relativeMacPostion * 6);

    memcpy((void *)mac_next_hop_, (unsigned char *)mac_current_hop_Pos, 6);
}
Пример #11
0
std::string
RouteResponse::getResponseAsNetworkString(unsigned char source_mac[6])
{

    unsigned char *buffer = new unsigned char[ETHER_MAX_LEN];
    unsigned char *eth_head = buffer;
    unsigned char *eth_data = buffer + 14;
    uint32_t int_htonl;
    uint32_t buffer_offset = 0;

    /* Build Ethernet header*/
    memcpy(buffer, bcast_mac, ETH_ALEN);

    memcpy(buffer + 6, source_mac, ETH_ALEN);

    uint16_t tf = htons(ETH_TYPE);
    memcpy(eth_head + 12, &tf, 2);
    buffer_offset += 14;

    /*PACKET TYPE*/
    uint8_t ff = FRAME_TYPE_REPLY;
    memcpy(eth_data, &ff, 1);
    eth_data++;
    buffer_offset += 1;

    /*REQ ID*/
    int_htonl = htonl(request_id_);
    memcpy(eth_data, &int_htonl, sizeof(uint32_t));
    eth_data += sizeof(uint32_t);
    buffer_offset += sizeof(uint32_t);

    /*MC FLAG*/
    memcpy(eth_data, &mc_flag_, 1);
    eth_data++;
    buffer_offset += 1;

    /*ROOT DISTANCE*/
    memcpy(eth_data, &root_distance, 1);
    eth_data++;
    buffer_offset += 1;

    /*HOP COUNT*/
    int_htonl = htonl(this->hop_count_);
    memcpy(eth_data, &int_htonl, sizeof(uint32_t));
    eth_data += sizeof(uint32_t);
    buffer_offset += sizeof(uint32_t);

    /*CURRENT HOP*/
    int_htonl = htonl(current_hop_);
    memcpy(eth_data, &int_htonl, sizeof(uint32_t));
    eth_data += sizeof(uint32_t);
    buffer_offset += sizeof(uint32_t);
    /*MAC LIST*/

    for (std::list<mac>::iterator it = this->path_l_.begin();
            it != path_l_.end(); ++it)
    {
        mac &tmp(*it);
        memcpy(eth_data, (unsigned char *)tmp.mac_adr, ETH_ALEN);
        eth_data += ETH_ALEN;
        buffer_offset += ETH_ALEN;
    }

    /*SOURCE HOST LENGTH*/
    int_htonl = htonl(hostname_source_.length());
    memcpy(eth_data, &int_htonl, sizeof(uint32_t));
    eth_data += sizeof(uint32_t);
    buffer_offset += sizeof(uint32_t);

    /*SOURCE HOST*/
    memcpy(eth_data, hostname_source_.data(), hostname_source_.length());
    eth_data += hostname_source_.length();
    buffer_offset += hostname_source_.length();

    /*CRC*/
    std::string crc_string = std::string((const char *)buffer, buffer_offset);
    uint32_t crc = GetCrc32(crc_string);
    int_htonl = htonl(crc);
    memcpy(eth_data, &int_htonl, sizeof(uint32_t));
    eth_data += sizeof(uint32_t);
    buffer_offset += sizeof(uint32_t);

    std::string res = std::string((const char *)buffer, buffer_offset);
    delete[] buffer;
    return res;
}
Пример #12
0
    PluginMetadata& PluginMetadata::EvalAllConditions(Game& game, const unsigned int language) {
        for (auto it = loadAfter.begin(); it != loadAfter.end();) {
            if (!it->EvalCondition(game))
                loadAfter.erase(it++);
            else
                ++it;
        }

        for (auto it = requirements.begin(); it != requirements.end();) {
            if (!it->EvalCondition(game))
                requirements.erase(it++);
            else
                ++it;
        }

        for (auto it = incompatibilities.begin(); it != incompatibilities.end();) {
            if (!it->EvalCondition(game))
                incompatibilities.erase(it++);
            else
                ++it;
        }

        for (auto it = messages.begin(); it != messages.end();) {
            if (!it->EvalCondition(game, language))
                it = messages.erase(it);
            else
                ++it;
        }

        for (auto it = tags.begin(); it != tags.end();) {
            if (!it->EvalCondition(game))
                tags.erase(it++);
            else
                ++it;
        }

        //First need to get plugin's CRC, if it is an exact plugin and it does not have its CRC set.
        if (!IsRegexPlugin()) {
            uint32_t crc = 0;
            unordered_map<std::string, uint32_t>::iterator it = game.crcCache.find(boost::locale::to_lower(name));
            if (it != game.crcCache.end())
                crc = it->second;
            else if (boost::filesystem::exists(game.DataPath() / name)) {
                crc = GetCrc32(game.DataPath() / name);
            }
            else if (boost::filesystem::exists(game.DataPath() / (name + ".ghost"))) {
                crc = GetCrc32(game.DataPath() / (name + ".ghost"));
            }
            else {
                // The plugin isn't installed, discard the dirty info.
                _dirtyInfo.clear();
            }

            // Store the CRC in the cache in case it's not already in there.
            game.crcCache.insert(pair<string, uint32_t>(boost::locale::to_lower(name), crc));

            // Now use the CRC to evaluate the dirty info.
            for (auto it = _dirtyInfo.begin(); it != _dirtyInfo.end();) {
                if (it->CRC() != crc)
                    _dirtyInfo.erase(it++);
                else
                    ++it;
            }
        }
        else {
            // Regex plugins shouldn't have dirty info, but just clear in case.
            _dirtyInfo.clear();
        }

        return *this;
    }
Пример #13
0
void ZipArchiveEntry::SerializeLocalFileHeader(std::ostream& stream)
{
  // ensure opening the stream
  std::istream* compressedDataStream = nullptr;

  if (!this->IsDirectory())
  {
    if (_inputStream == nullptr)
    {
      if (!_isNewOrChanged)
      {
        // the file was either compressed in immediate mode,
        // or was in previous archive
        compressedDataStream = this->GetRawStream();
      }

      // if file is new and empty or stream has been set to nullptr,
      // just do not set any compressed data stream
    }
    else
    {
      assert(_isNewOrChanged);
      compressedDataStream = _inputStream;
    }
  }

  if (!_hasLocalFileHeader)
  {
    this->FetchLocalFileHeader();
  }

  // save offset of stream here
  _offsetOfSerializedLocalFileHeader = stream.tellp();      

  if (this->IsUsingDataDescriptor())
  {
    _localFileHeader.CompressedSize = 0;
    _localFileHeader.UncompressedSize = 0;
    _localFileHeader.Crc32 = 0;
  }

  _localFileHeader.Serialize(stream);

  // if this entry is a directory, it should not contain any data
  // nor crc.
  assert(
    this->IsDirectory()
    ? !GetCrc32() && !GetSize() && !GetCompressedSize() && !_inputStream
    : true
  );

  if (!this->IsDirectory() && compressedDataStream != nullptr)
  {
    if (_isNewOrChanged)
    {
      this->InternalCompressStream(*compressedDataStream, stream);

      if (this->IsUsingDataDescriptor())
      {
        _localFileHeader.SerializeAsDataDescriptor(stream);
      }
      else
      {
        // actualize local file header
        // make non-seekable version?
        stream.seekp(_offsetOfSerializedLocalFileHeader);
        _localFileHeader.Serialize(stream);
        stream.seekp(this->GetCompressedSize(), std::ios::cur);
      }
    }
    else
    {
      utils::stream::copy(*compressedDataStream, stream);
    }
  }
}
Пример #14
0
 inline static uint32 GetHashValue(const CString* pKey)
 {
     return GetCrc32((const uint8*)pKey->GetStr(), pKey->GetSize(), 0);
 }
void ChannelLogonManager::OnHandleLogonInfo(ServerClientData* pClient, LO_Cmd_ChannelLogon* pMsg)
{
	if (!pMsg || !pClient)
	{
		ASSERT(false);
		return;
	}
	//处理客户端发送来的变长命令
	LO_Cmd_ChannelLogon* pNewChannelInfo = (LO_Cmd_ChannelLogon*)malloc(pMsg->CmdSize);
	memcpy_s(pNewChannelInfo, pMsg->CmdSize, pMsg, pMsg->CmdSize);

	std::vector<TCHAR*> pVec;
	GetStringArrayVecByData(pVec, &pMsg->channelInfo);
	if (pVec.size() != pMsg->channelInfo.HandleSum)
	{
		free(pNewChannelInfo);
		ASSERT(false);
		return;
	}
	
	TCHAR PostUrl[1024];
	swprintf_s(PostUrl, CountArray(PostUrl), TEXT("game_agent/checkLogin?userId=%s&channel=%s&token=%s&productCode=%s"), pVec[0], pVec[4], pVec[6], pVec[3]);
	UINT Count = 0;
	char* pPostUrl = WCharToChar(PostUrl, Count);
	//URL 产生后 我们异步 处理
	AE_CRC_PAIRS pThree;
	AECrc32(pThree, pVec[0], CountArray(pVec[0])*sizeof(TCHAR), 0, 0x73573);
	//订单转化的CRC 数据
	DWORD Crc1 = pThree.Crc1;
	DWORD Crc2 = pThree.Crc2;
	unsigned __int64 i64Value = Crc1;
	i64Value = (i64Value << 32);
	i64Value += Crc2;//唯一的订单号
	
	WORD RequestID = g_FishServer.GetChannelLogonID();
	UINT64* pID = new UINT64(i64Value);
	
	HashMap < unsigned __int64, LogonTempInfo>::iterator Iter = m_RoleLogonMap.find(i64Value);
	if (Iter != m_RoleLogonMap.end())
	{
		free(Iter->second.pMsg);
		m_RoleLogonMap.erase(Iter);
		LogInfoToFile("LogonError.txt", TEXT("客户端渠道登陆 顶掉以前的渠道数据"));
	}
	LogonTempInfo pInfo;
	pInfo.pMsg = pNewChannelInfo;
	pInfo.ClientID = static_cast<BYTE>(pClient->OutsideExtraData);
	pInfo.ChannelID = GetCrc32(pVec[0]);
	TCHARCopy(pInfo.MacAddress, CountArray(pInfo.MacAddress), pMsg->MacAddress, _tcslen(pMsg->MacAddress));
	m_RoleLogonMap.insert(HashMap<unsigned __int64, LogonTempInfo>::value_type(i64Value, pInfo));
	vector<TCHAR*>::iterator IterVec = pVec.begin();
	for (; IterVec != pVec.end(); ++IterVec)
	{
		free(*IterVec);
	}
	if (g_FishServerConfig.GetIsOperateTest())
	{
		OnHandleLogonResult(i64Value, "true", strlen("true"));
		delete pID;
	}
	else
	{
		if (!g_FishServer.GetHttpClient().AddRequest((UINT_PTR)pID, RequestID, pPostUrl))
		{
			delete(pID);
			free(pNewChannelInfo);
			free(pPostUrl);
			return;
		}
		free(pPostUrl);
	}
}
Пример #16
0
int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
{
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
	char dk[32 * 2];			// 2 * 256-bit key
	char masterKey[32 * 2];
#else
	char dk[32 * 2 * 3];		// 6 * 256-bit key
	char masterKey[32 * 2 * 3];
#endif

	PCRYPTO_INFO cryptoInfo;
	int status;

	if (retHeaderCryptoInfo != NULL)
		cryptoInfo = retHeaderCryptoInfo;
	else
		cryptoInfo = *retInfo = crypto_open ();

	// PKCS5 PRF
	derive_key_ripemd160 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
		PKCS5_SALT_SIZE, bBoot ? 1000 : 2000, dk, sizeof (dk));

	// Mode of operation
	cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;

	// Test all available encryption algorithms
	for (cryptoInfo->ea = EAGetFirst (); cryptoInfo->ea != 0; cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
	{
		status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
		if (status == ERR_CIPHER_INIT_FAILURE)
			goto err;

		// Secondary key schedule
		EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);

		// Try to decrypt header 
		DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
		
		// Check magic 'TRUE' and CRC-32 of header fields and master keydata
		if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545
			|| (GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION) >= 4 && GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
			|| GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
		{
			EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
			continue;
		}

		// Header decrypted
		status = 0;

		// Hidden volume status
		cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE);
		cryptoInfo->hiddenVolume = (cryptoInfo->VolumeSize.LowPart != 0 || cryptoInfo->VolumeSize.HighPart != 0);

		// Volume size
		cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);

		// Encrypted area size and length
		cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
		cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);

		// Flags
		cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);

		memcpy (masterKey, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (masterKey));
		EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

		if (retHeaderCryptoInfo)
			goto ret;

		// Init the encryption algorithm with the decrypted master key
		status = EAInit (cryptoInfo->ea, masterKey, cryptoInfo->ks);
		if (status == ERR_CIPHER_INIT_FAILURE)
			goto err;

		// The secondary master key (if cascade, multiple concatenated)
		EAInit (cryptoInfo->ea, masterKey + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
		goto ret;
	}

	status = ERR_PASSWORD_WRONG;

err:
	if (cryptoInfo != retHeaderCryptoInfo)
	{
		crypto_close(cryptoInfo);
		*retInfo = NULL; 
	}

ret:
	burn (dk, sizeof(dk));
	burn (masterKey, sizeof(masterKey));
	return status;
}
Пример #17
0
// Creates a volume header in memory
int CreateVolumeHeaderInMemory (BOOL bBoot, char *header, int ea, int mode, Password *password,
		   int pkcs5_prf, char *masterKeydata, PCRYPTO_INFO *retInfo,
		   unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize,
		   unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode)
{
	unsigned char *p = (unsigned char *) header;
	static KEY_INFO keyInfo;

	int nUserKeyLen = password->Length;
	PCRYPTO_INFO cryptoInfo = crypto_open ();
	static char dk[MASTER_KEYDATA_SIZE];
	int x;
	int retVal = 0;
	int primaryKeyOffset;

	if (cryptoInfo == NULL)
		return ERR_OUTOFMEMORY;

	memset (header, 0, TC_VOLUME_HEADER_EFFECTIVE_SIZE);

	VirtualLock (&keyInfo, sizeof (keyInfo));
	VirtualLock (&dk, sizeof (dk));

	/* Encryption setup */

	if (masterKeydata == NULL)
	{
		// We have no master key data (creating a new volume) so we'll use the TrueCrypt RNG to generate them

		int bytesNeeded;

		switch (mode)
		{
		case LRW:
		case CBC:
		case INNER_CBC:
		case OUTER_CBC:

			// Deprecated/legacy modes of operation
			bytesNeeded = LEGACY_VOL_IV_SIZE + EAGetKeySize (ea);

			// In fact, this should never be the case since volumes being newly created are not
			// supposed to use any deprecated mode of operation.
			TC_THROW_FATAL_EXCEPTION;
			break;

		default:
			bytesNeeded = EAGetKeySize (ea) * 2;	// Size of primary + secondary key(s)
		}

		if (!RandgetBytes (keyInfo.master_keydata, bytesNeeded, TRUE))
			return ERR_CIPHER_INIT_WEAK_KEY;
	}
	else
	{
		// We already have existing master key data (the header is being re-encrypted)
		memcpy (keyInfo.master_keydata, masterKeydata, MASTER_KEYDATA_SIZE);
	}

	// User key 
	memcpy (keyInfo.userKey, password->Text, nUserKeyLen);
	keyInfo.keyLength = nUserKeyLen;
	keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot);

	// User selected encryption algorithm
	cryptoInfo->ea = ea;

	// Mode of operation
	cryptoInfo->mode = mode;

	// Salt for header key derivation
	if (!RandgetBytes (keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode))
		return ERR_CIPHER_INIT_WEAK_KEY; 

	// PBKDF2 (PKCS5) is used to derive primary header key(s) and secondary header key(s) (XTS) from the password/keyfiles
	switch (pkcs5_prf)
	{
	case SHA512:
		derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
			PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
		break;

	case SHA1:
		// Deprecated/legacy
		derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
			PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
		break;

	case RIPEMD160:
		derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
			PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
		break;

	case WHIRLPOOL:
		derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
			PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
		break;

	default:		
		// Unknown/wrong ID
		TC_THROW_FATAL_EXCEPTION;
	} 

	/* Header setup */

	// Salt
	mputBytes (p, keyInfo.salt, PKCS5_SALT_SIZE);	

	// Magic
	mputLong (p, 0x54525545);

	// Header version
	mputWord (p, VOLUME_HEADER_VERSION);
	cryptoInfo->HeaderVersion = VOLUME_HEADER_VERSION;

	// Required program version to handle this volume
	switch (mode)
	{
	case LRW:
		// Deprecated/legacy
		mputWord (p, 0x0410);
		break;
	case OUTER_CBC:
	case INNER_CBC:
		// Deprecated/legacy
		mputWord (p, 0x0300);
		break;
	case CBC:
		// Deprecated/legacy
		mputWord (p, hiddenVolumeSize > 0 ? 0x0300 : 0x0100);
		break;
	default:
		mputWord (p, requiredProgramVersion != 0 ? requiredProgramVersion : TC_VOLUME_MIN_REQUIRED_PROGRAM_VERSION);
	}

	// CRC of the master key data
	x = GetCrc32(keyInfo.master_keydata, MASTER_KEYDATA_SIZE);
	mputLong (p, x);

	// Reserved fields
	p += 2 * 8;

	// Size of hidden volume (if any)
	cryptoInfo->hiddenVolumeSize = hiddenVolumeSize;
	mputInt64 (p, cryptoInfo->hiddenVolumeSize);

	cryptoInfo->hiddenVolume = cryptoInfo->hiddenVolumeSize != 0;

	// Volume size
	cryptoInfo->VolumeSize.Value = volumeSize;
	mputInt64 (p, volumeSize);

	// Encrypted area start
	cryptoInfo->EncryptedAreaStart.Value = encryptedAreaStart;
	mputInt64 (p, encryptedAreaStart);

	// Encrypted area size
	cryptoInfo->EncryptedAreaLength.Value = encryptedAreaLength;
	mputInt64 (p, encryptedAreaLength);

	// Flags
	cryptoInfo->HeaderFlags = headerFlags;
	mputLong (p, headerFlags);

	// Sector size
	if (sectorSize < TC_MIN_VOLUME_SECTOR_SIZE
		|| sectorSize > TC_MAX_VOLUME_SECTOR_SIZE
		|| sectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
	{
		TC_THROW_FATAL_EXCEPTION;
	}

	cryptoInfo->SectorSize = sectorSize;
	mputLong (p, sectorSize);

	// CRC of the header fields
	x = GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
	p = header + TC_HEADER_OFFSET_HEADER_CRC;
	mputLong (p, x);

	// The master key data
	memcpy (header + HEADER_MASTER_KEYDATA_OFFSET, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);


	/* Header encryption */

	switch (mode)
	{
	case LRW:
	case CBC:
	case INNER_CBC:
	case OUTER_CBC:

		// For LRW (deprecated/legacy), the tweak key
		// For CBC (deprecated/legacy), the IV/whitening seed
		memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
		primaryKeyOffset = LEGACY_VOL_IV_SIZE;
		break;

	default:
		// The secondary key (if cascade, multiple concatenated)
		memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
		primaryKeyOffset = 0;
	}

	retVal = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
	if (retVal != ERR_SUCCESS)
		return retVal;

	// Mode of operation
	if (!EAInitMode (cryptoInfo))
		return ERR_OUTOFMEMORY;


	// Encrypt the entire header (except the salt)
	EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET,
		HEADER_ENCRYPTED_DATA_SIZE,
		cryptoInfo);


	/* cryptoInfo setup for further use (disk format) */

	// Init with the master key(s) 
	retVal = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
	if (retVal != ERR_SUCCESS)
		return retVal;

	memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);

	switch (cryptoInfo->mode)
	{
	case LRW:
	case CBC:
	case INNER_CBC:
	case OUTER_CBC:

		// For LRW (deprecated/legacy), the tweak key
		// For CBC (deprecated/legacy), the IV/whitening seed
		memcpy (cryptoInfo->k2, keyInfo.master_keydata, LEGACY_VOL_IV_SIZE);
		break;

	default:
		// The secondary master key (if cascade, multiple concatenated)
		memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
	}

	// Mode of operation
	if (!EAInitMode (cryptoInfo))
		return ERR_OUTOFMEMORY;


#ifdef VOLFORMAT
	if (showKeys && !bInPlaceEncNonSys)
	{
		BOOL dots3 = FALSE;
		int i, j;

		j = EAGetKeySize (ea);

		if (j > NBR_KEY_BYTES_TO_DISPLAY)
		{
			dots3 = TRUE;
			j = NBR_KEY_BYTES_TO_DISPLAY;
		}

		MasterKeyGUIView[0] = 0;
		for (i = 0; i < j; i++)
		{
			char tmp2[8] = {0};
			sprintf (tmp2, "%02X", (int) (unsigned char) keyInfo.master_keydata[i + primaryKeyOffset]);
			strcat (MasterKeyGUIView, tmp2);
		}

		HeaderKeyGUIView[0] = 0;
		for (i = 0; i < NBR_KEY_BYTES_TO_DISPLAY; i++)
		{
			char tmp2[8];
			sprintf (tmp2, "%02X", (int) (unsigned char) dk[primaryKeyOffset + i]);
			strcat (HeaderKeyGUIView, tmp2);
		}

		if (dots3)
		{
			DisplayPortionsOfKeys (hHeaderKey, hMasterKey, HeaderKeyGUIView, MasterKeyGUIView, !showKeys);
		}
		else
		{
			SendMessage (hMasterKey, WM_SETTEXT, 0, (LPARAM) MasterKeyGUIView);
			SendMessage (hHeaderKey, WM_SETTEXT, 0, (LPARAM) HeaderKeyGUIView);
		}
	}
#endif	// #ifdef VOLFORMAT

	burn (dk, sizeof(dk));
	burn (&keyInfo, sizeof (keyInfo));

	*retInfo = cryptoInfo;
	return 0;
}
Пример #18
0
 inline static uint32 GetHashValue(const CBinary* pKey)
 {
     return GetCrc32((const uint8*)pKey->GetData(), pKey->GetSize(), 0);
 }
Пример #19
0
int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
{
	char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
	KEY_INFO keyInfo;
	PCRYPTO_INFO cryptoInfo;
	char dk[MASTER_KEYDATA_SIZE];
	int enqPkcs5Prf, pkcs5_prf;
	uint16 headerVersion;
	int status = ERR_PARAMETER_INCORRECT;
	int primaryKeyOffset;

	TC_EVENT keyDerivationCompletedEvent;
	TC_EVENT noOutstandingWorkItemEvent;
	KeyDerivationWorkItem *keyDerivationWorkItems;
	KeyDerivationWorkItem *item;
	int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1;
	size_t encryptionThreadCount = GetEncryptionThreadCount();
	size_t queuedWorkItems = 0;
	LONG outstandingWorkItemCount = 0;
	int i;

	if (retHeaderCryptoInfo != NULL)
	{
		cryptoInfo = retHeaderCryptoInfo;
	}
	else
	{
		cryptoInfo = *retInfo = crypto_open ();
		if (cryptoInfo == NULL)
			return ERR_OUTOFMEMORY;
	}

	if (encryptionThreadCount > 1)
	{
		keyDerivationWorkItems = TCalloc (sizeof (KeyDerivationWorkItem) * pkcs5PrfCount);
		if (!keyDerivationWorkItems)
			return ERR_OUTOFMEMORY;

		for (i = 0; i < pkcs5PrfCount; ++i)
			keyDerivationWorkItems[i].Free = TRUE;

#ifdef DEVICE_DRIVER
		KeInitializeEvent (&keyDerivationCompletedEvent, SynchronizationEvent, FALSE);
		KeInitializeEvent (&noOutstandingWorkItemEvent, SynchronizationEvent, TRUE);
#else
		keyDerivationCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
		if (!keyDerivationCompletedEvent)
		{
			TCfree (keyDerivationWorkItems);
			return ERR_OUTOFMEMORY;
		}

		noOutstandingWorkItemEvent = CreateEvent (NULL, FALSE, TRUE, NULL);
		if (!noOutstandingWorkItemEvent)
		{
			CloseHandle (keyDerivationCompletedEvent);
			TCfree (keyDerivationWorkItems);
			return ERR_OUTOFMEMORY;
		}
#endif
	}
		
#ifndef DEVICE_DRIVER
	VirtualLock (&keyInfo, sizeof (keyInfo));
	VirtualLock (&dk, sizeof (dk));
#endif

	crypto_loadkey (&keyInfo, password->Text, (int) password->Length);

	// PKCS5 is used to derive the primary header key(s) and secondary header key(s) (XTS mode) from the password
	memcpy (keyInfo.salt, encryptedHeader + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE);

	// Test all available PKCS5 PRFs
	for (enqPkcs5Prf = FIRST_PRF_ID; enqPkcs5Prf <= LAST_PRF_ID || queuedWorkItems > 0; ++enqPkcs5Prf)
	{
		BOOL lrw64InitDone = FALSE;		// Deprecated/legacy
		BOOL lrw128InitDone = FALSE;	// Deprecated/legacy

		if (encryptionThreadCount > 1)
		{
			// Enqueue key derivation on thread pool
			if (queuedWorkItems < encryptionThreadCount && enqPkcs5Prf <= LAST_PRF_ID)
			{
				for (i = 0; i < pkcs5PrfCount; ++i)
				{
					item = &keyDerivationWorkItems[i];
					if (item->Free)
					{
						item->Free = FALSE;
						item->KeyReady = FALSE;
						item->Pkcs5Prf = enqPkcs5Prf;

						EncryptionThreadPoolBeginKeyDerivation (&keyDerivationCompletedEvent, &noOutstandingWorkItemEvent,
							&item->KeyReady, &outstandingWorkItemCount, enqPkcs5Prf, keyInfo.userKey,
							keyInfo.keyLength, keyInfo.salt, get_pkcs5_iteration_count (enqPkcs5Prf, bBoot), item->DerivedKey);
						
						++queuedWorkItems;
						break;
					}
				}

				if (enqPkcs5Prf < LAST_PRF_ID)
					continue;
			}
			else
				--enqPkcs5Prf;

			// Wait for completion of a key derivation
			while (queuedWorkItems > 0)
			{
				for (i = 0; i < pkcs5PrfCount; ++i)
				{
					item = &keyDerivationWorkItems[i];
					if (!item->Free && InterlockedExchangeAdd (&item->KeyReady, 0) == TRUE)
					{
						pkcs5_prf = item->Pkcs5Prf;
						keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot);
						memcpy (dk, item->DerivedKey, sizeof (dk));

						item->Free = TRUE;
						--queuedWorkItems;
						goto KeyReady;
					}
				}

				if (queuedWorkItems > 0)
					TC_WAIT_EVENT (keyDerivationCompletedEvent);
			}
			continue;
KeyReady:	;
		}
		else
		{
			pkcs5_prf = enqPkcs5Prf;
			keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, bBoot);

			switch (pkcs5_prf)
			{
			case RIPEMD160:
				derive_key_ripemd160 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
					PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
				break;

			case SHA512:
				derive_key_sha512 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
					PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
				break;

			case SHA1:
				// Deprecated/legacy
				derive_key_sha1 (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
					PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
				break;

			case WHIRLPOOL:
				derive_key_whirlpool (keyInfo.userKey, keyInfo.keyLength, keyInfo.salt,
					PKCS5_SALT_SIZE, keyInfo.noIterations, dk, GetMaxPkcs5OutSize());
				break;

			default:		
				// Unknown/wrong ID
				TC_THROW_FATAL_EXCEPTION;
			} 
		}

		// Test all available modes of operation
		for (cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
			cryptoInfo->mode <= LAST_MODE_OF_OPERATION;
			cryptoInfo->mode++)
		{
			switch (cryptoInfo->mode)
			{
			case LRW:
			case CBC:
			case INNER_CBC:
			case OUTER_CBC:

				// For LRW (deprecated/legacy), copy the tweak key 
				// For CBC (deprecated/legacy), copy the IV/whitening seed 
				memcpy (cryptoInfo->k2, dk, LEGACY_VOL_IV_SIZE);
				primaryKeyOffset = LEGACY_VOL_IV_SIZE;
				break;

			default:
				primaryKeyOffset = 0;
			}

			// Test all available encryption algorithms
			for (cryptoInfo->ea = EAGetFirst ();
				cryptoInfo->ea != 0;
				cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
			{
				int blockSize;

				if (!EAIsModeSupported (cryptoInfo->ea, cryptoInfo->mode))
					continue;	// This encryption algorithm has never been available with this mode of operation

				blockSize = CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea));

				status = EAInit (cryptoInfo->ea, dk + primaryKeyOffset, cryptoInfo->ks);
				if (status == ERR_CIPHER_INIT_FAILURE)
					goto err;

				// Init objects related to the mode of operation

				if (cryptoInfo->mode == XTS)
				{
					// Copy the secondary key (if cascade, multiple concatenated)
					memcpy (cryptoInfo->k2, dk + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));

					// Secondary key schedule
					if (!EAInitMode (cryptoInfo))
					{
						status = ERR_MODE_INIT_FAILED;
						goto err;
					}
				}
				else if (cryptoInfo->mode == LRW
					&& (blockSize == 8 && !lrw64InitDone || blockSize == 16 && !lrw128InitDone))
				{
					// Deprecated/legacy

					if (!EAInitMode (cryptoInfo))
					{
						status = ERR_MODE_INIT_FAILED;
						goto err;
					}

					if (blockSize == 8)
						lrw64InitDone = TRUE;
					else if (blockSize == 16)
						lrw128InitDone = TRUE;
				}

				// Copy the header for decryption
				memcpy (header, encryptedHeader, sizeof (header));

				// Try to decrypt header 

				DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

				// Magic 'TRUE'
				if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
					continue;

				// Header version
				headerVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION);
				
				if (headerVersion > VOLUME_HEADER_VERSION)
				{
					status = ERR_NEW_VERSION_REQUIRED;
					goto err;
				}

				// Check CRC of the header fields
				if (!ReadVolumeHeaderRecoveryMode
					&& headerVersion >= 4
					&& GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
					continue;

				// Required program version
				cryptoInfo->RequiredProgramVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_REQUIRED_VERSION);
				cryptoInfo->LegacyVolume = cryptoInfo->RequiredProgramVersion < 0x600;

				// Check CRC of the key set
				if (!ReadVolumeHeaderRecoveryMode
					&& GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
					continue;

				// Now we have the correct password, cipher, hash algorithm, and volume type

				// Check the version required to handle this volume
				if (cryptoInfo->RequiredProgramVersion > VERSION_NUM)
				{
					status = ERR_NEW_VERSION_REQUIRED;
					goto err;
				}

				// Header version
				cryptoInfo->HeaderVersion = headerVersion;

				// Volume creation time (legacy)
				cryptoInfo->volume_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_CREATION_TIME).Value;

				// Header creation time (legacy)
				cryptoInfo->header_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_MODIFICATION_TIME).Value;

				// Hidden volume size (if any)
				cryptoInfo->hiddenVolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE).Value;

				// Hidden volume status
				cryptoInfo->hiddenVolume = (cryptoInfo->hiddenVolumeSize != 0);

				// Volume size
				cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);
				
				// Encrypted area size and length
				cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
				cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);

				// Flags
				cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);

				// Sector size
				if (headerVersion >= 5)
					cryptoInfo->SectorSize = GetHeaderField32 (header, TC_HEADER_OFFSET_SECTOR_SIZE);
				else
					cryptoInfo->SectorSize = TC_SECTOR_SIZE_LEGACY;

				if (cryptoInfo->SectorSize < TC_MIN_VOLUME_SECTOR_SIZE
					|| cryptoInfo->SectorSize > TC_MAX_VOLUME_SECTOR_SIZE
					|| cryptoInfo->SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
				{
					status = ERR_PARAMETER_INCORRECT;
					goto err;
				}

				// Preserve scheduled header keys if requested			
				if (retHeaderCryptoInfo)
				{
					if (retInfo == NULL)
					{
						cryptoInfo->pkcs5 = pkcs5_prf;
						cryptoInfo->noIterations = keyInfo.noIterations;
						goto ret;
					}

					cryptoInfo = *retInfo = crypto_open ();
					if (cryptoInfo == NULL)
					{
						status = ERR_OUTOFMEMORY;
						goto err;
					}

					memcpy (cryptoInfo, retHeaderCryptoInfo, sizeof (*cryptoInfo));
				}

				// Master key data
				memcpy (keyInfo.master_keydata, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE);
				memcpy (cryptoInfo->master_keydata, keyInfo.master_keydata, MASTER_KEYDATA_SIZE);

				// PKCS #5
				memcpy (cryptoInfo->salt, keyInfo.salt, PKCS5_SALT_SIZE);
				cryptoInfo->pkcs5 = pkcs5_prf;
				cryptoInfo->noIterations = keyInfo.noIterations;

				// Init the cipher with the decrypted master key
				status = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks);
				if (status == ERR_CIPHER_INIT_FAILURE)
					goto err;

				switch (cryptoInfo->mode)
				{
				case LRW:
				case CBC:
				case INNER_CBC:
				case OUTER_CBC:

					// For LRW (deprecated/legacy), the tweak key
					// For CBC (deprecated/legacy), the IV/whitening seed
					memcpy (cryptoInfo->k2, keyInfo.master_keydata, LEGACY_VOL_IV_SIZE);
					break;

				default:
					// The secondary master key (if cascade, multiple concatenated)
					memcpy (cryptoInfo->k2, keyInfo.master_keydata + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));

				}

				if (!EAInitMode (cryptoInfo))
				{
					status = ERR_MODE_INIT_FAILED;
					goto err;
				}

				status = ERR_SUCCESS;
				goto ret;
			}
		}
	}
	status = ERR_PASSWORD_WRONG;

err:
	if (cryptoInfo != retHeaderCryptoInfo)
	{
		crypto_close(cryptoInfo);
		*retInfo = NULL; 
	}

ret:
	burn (&keyInfo, sizeof (keyInfo));
	burn (dk, sizeof(dk));

#ifndef DEVICE_DRIVER
	VirtualUnlock (&keyInfo, sizeof (keyInfo));
	VirtualUnlock (&dk, sizeof (dk));
#endif

	if (encryptionThreadCount > 1)
	{
		TC_WAIT_EVENT (noOutstandingWorkItemEvent);

		burn (keyDerivationWorkItems, sizeof (KeyDerivationWorkItem) * pkcs5PrfCount);
		TCfree (keyDerivationWorkItems);

#ifndef DEVICE_DRIVER
		CloseHandle (keyDerivationCompletedEvent);
		CloseHandle (noOutstandingWorkItemEvent);
#endif
	}

	return status;
}
Пример #20
0
Plugin::Plugin(const Game& game, const std::string& name, const bool headerOnly) :
  PluginMetadata(name),
  libespm::Plugin(game.LibespmId()),
  isEmpty_(true),
  isActive_(false),
  loadsArchive_(false),
  crc_(0),
  numOverrideRecords_(0) {
  try {
    boost::filesystem::path filepath = game.DataPath() / Name();

    // In case the plugin is ghosted.
    if (!boost::filesystem::exists(filepath) && boost::filesystem::exists(filepath.string() + ".ghost"))
      filepath += ".ghost";

    load(filepath, headerOnly);

    isEmpty_ = getRecordAndGroupCount() == 0;

    if (!headerOnly) {
      BOOST_LOG_TRIVIAL(trace) << Name() << ": Caching CRC value.";
      crc_ = GetCrc32(filepath);
    }

    BOOST_LOG_TRIVIAL(trace) << Name() << ": Counting override FormIDs.";
    for (const auto& formID : getFormIds()) {
      if (!boost::iequals(formID.getPluginName(), Name()))
        ++numOverrideRecords_;
    }

    //Also read Bash Tags applied and version string in description.
    string text = getDescription();
    BOOST_LOG_TRIVIAL(trace) << Name() << ": " << "Attempting to extract Bash Tags from the description.";
    size_t pos1 = text.find("{{BASH:");
    if (pos1 != string::npos && pos1 + 7 != text.length()) {
      pos1 += 7;

      size_t pos2 = text.find("}}", pos1);
      if (pos2 != string::npos && pos1 != pos2) {
        text = text.substr(pos1, pos2 - pos1);

        std::vector<string> bashTags;
        boost::split(bashTags, text, [](char c) { return c == ','; });

        for (auto &tag : bashTags) {
          boost::trim(tag);
          BOOST_LOG_TRIVIAL(trace) << Name() << ": " << "Extracted Bash Tag: " << tag;
          tags_.insert(Tag(tag));
        }
      }
    }
    // Get whether the plugin is active or not.
    isActive_ = game.LoadOrderHandler::IsPluginActive(Name());

    // Get whether the plugin loads an archive (BSA/BA2) or not.
    const string archiveExtension = game.GetArchiveFileExtension();

    if (game.Type() == GameType::tes5) {
        // Skyrim plugins only load BSAs that exactly match their basename.
      loadsArchive_ = boost::filesystem::exists(game.DataPath() / (Name().substr(0, Name().length() - 4) + archiveExtension));
    } else if (game.Type() != GameType::tes4 || boost::iends_with(Name(), ".esp")) {
        //Oblivion .esp files and FO3, FNV, FO4 plugins can load archives which begin with the plugin basename.
      string basename = Name().substr(0, Name().length() - 4);
      for (boost::filesystem::directory_iterator it(game.DataPath()); it != boost::filesystem::directory_iterator(); ++it) {
        if (boost::iequals(it->path().extension().string(), archiveExtension) && boost::istarts_with(it->path().filename().string(), basename)) {
          loadsArchive_ = true;
          break;
        }
      }
    }
  } catch (std::exception& e) {
    BOOST_LOG_TRIVIAL(error) << "Cannot read plugin file \"" << name << "\". Details: " << e.what();
    messages_.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("Cannot read \"%1%\". Details: %2%")) % name % e.what()).str()));
  }

  BOOST_LOG_TRIVIAL(trace) << Name() << ": " << "Plugin loading complete.";
}
Пример #21
0
std::string RouteRequest::getRequestAsNetworkString(unsigned char source_mac[6]) {


    /*Add the current hop mac to the routing path_l_*/
    mac currentHopMac;
    memcpy(currentHopMac.mac_adr,  source_mac, 6);
    memcpy( eh_h_.eh_source,  source_mac, 6);
    memcpy(eh_h_.eh_dest,  bcast_mac, 6);
    path_l_.push_back(currentHopMac);
    header_.hop_count++;
    
    this->header_.hop_count = this->path_l_.size();


    /*FLAG FIELD*/
    this->header_.flag_field = 0;
    if (mc_flag_)
        this->header_.flag_field += 128;


    /*LEN FIELDS */
    this->header_.hostname_source_len = hostname_source_.length();
    this->header_.hostname_destination_len = hostname_destination_.length();

    unsigned char a_buffer[ETHER_MAX_LEN];
    unsigned char* buffer_start = a_buffer;
    unsigned char* buffer = a_buffer;




    /*ETHERNET FIELDS*/
    //eh_header* eh = (struct eh_header *) buffer;
    memcpy(buffer, &this->eh_h_, sizeof (eh_header));
    buffer += sizeof (eh_header);

    /*FIXED RF HEADER FIELDS*/
    memcpy(buffer, &this->header_, sizeof (rreq_header));
    buffer += sizeof (rreq_header);

    /*SOURCE HOST */
    memcpy(buffer, this->hostname_source_.data(),
            this->hostname_source_.length());
    buffer += this->hostname_source_.length();

    /*DEST HOST */
    memcpy((unsigned char*)buffer, (unsigned char*) this->hostname_destination_.data(), this->hostname_destination_.length());
    buffer += hostname_destination_.length();


    /*PATH (list of macs from the src to dest)*/
    for (std::list<mac>::iterator it = this->path_l_.begin(); it != path_l_.end(); ++it) {
        memcpy(buffer, (unsigned char*) (*it).mac_adr, ETH_ALEN);

        buffer += ETH_ALEN;
    }


    /*CRC*/
    int dynamic_field_len = this->hostname_source_.length() + this->hostname_destination_.length() + 6 * path_l_.size();
    std::string crc_string = std::string((const char*) buffer_start, this->HEADER_FIXED_LEN + dynamic_field_len);
    uint32_t crc = GetCrc32(crc_string);
    memcpy(buffer, &crc, sizeof (uint32_t));
    buffer += sizeof (uint32_t);

    

   return std::string((const char*) buffer_start, this->HEADER_FIXED_LEN + dynamic_field_len + sizeof (crc));




}
Пример #22
0
// Assumes that VerifyPackageIntegrity() has been used. Returns TRUE, if successful (otherwise FALSE).
// Creates a table of pointers to buffers containing the following objects for each file:
// filename size, filename (not null-terminated!), file size, file CRC-32, uncompressed file contents.
// For details, see the definition of the DECOMPRESSED_FILE structure.
BOOL SelfExtractInMemory (char *path)
{
	int filePos = 0, fileNo = 0;
	int fileDataEndPos = 0;
	int fileDataStartPos = 0;
	unsigned int uncompressedLen = 0;
	unsigned int compressedLen = 0;
	unsigned char *compressedData = NULL;
	unsigned char *bufPos = NULL, *bufEndPos = NULL;

	FreeAllFileBuffers();

	fileDataEndPos = (int) FindStringInFile (path, MagEndMarker, strlen (MagEndMarker));
	if (fileDataEndPos < 0)
	{
		Error ("CANNOT_READ_FROM_PACKAGE");
		return FALSE;
	}

	fileDataEndPos--;

	fileDataStartPos = (int) FindStringInFile (path, MAG_START_MARKER, strlen (MAG_START_MARKER));
	if (fileDataStartPos < 0)
	{
		Error ("CANNOT_READ_FROM_PACKAGE");
		return FALSE;
	}

	fileDataStartPos += strlen (MAG_START_MARKER);

	filePos = fileDataStartPos;

	// Read the stored total size of the uncompressed data
	if (!LoadInt32 (path, &uncompressedLen, filePos))
	{
		Error ("CANNOT_READ_FROM_PACKAGE");
		return FALSE;
	}

	filePos += 4;

	// Read the stored total size of the compressed data
	if (!LoadInt32 (path, &compressedLen, filePos))
	{
		Error ("CANNOT_READ_FROM_PACKAGE");
		return FALSE;
	}

	filePos += 4;

	if (compressedLen != fileDataEndPos - fileDataStartPos - 8 + 1)
	{
		Error ("DIST_PACKAGE_CORRUPTED");
	}

	DecompressedData = malloc (uncompressedLen + 524288);	// + 512K reserve 
	if (DecompressedData == NULL)
	{
		Error ("ERR_MEM_ALLOC");
		return FALSE;
	}

	bufPos = DecompressedData;
	bufEndPos = bufPos + uncompressedLen - 1;

	compressedData = LoadFileBlock (path, filePos, compressedLen);

	if (compressedData == NULL)
	{
		free (DecompressedData);
		DecompressedData = NULL;

		Error ("CANNOT_READ_FROM_PACKAGE");
		return FALSE;
	}

	// Decompress the data
	if (DecompressBuffer (DecompressedData, compressedData, compressedLen) != uncompressedLen)
	{
		Error ("DIST_PACKAGE_CORRUPTED");
		goto sem_end;
	}

	while (bufPos <= bufEndPos && fileNo < NBR_COMPRESSED_FILES)
	{
		// Filename length
		Decompressed_Files[fileNo].fileNameLength = mgetWord (bufPos);

		// Filename
		Decompressed_Files[fileNo].fileName = bufPos;
		bufPos += Decompressed_Files[fileNo].fileNameLength;

		// CRC-32 of the file
		Decompressed_Files[fileNo].crc = mgetLong (bufPos);

		// File length
		Decompressed_Files[fileNo].fileLength = mgetLong (bufPos);

		// File content
		Decompressed_Files[fileNo].fileContent = bufPos;
		bufPos += Decompressed_Files[fileNo].fileLength;

		// Verify CRC-32 of the file (to verify that it didn't get corrupted while creating the solid archive).
		if (Decompressed_Files[fileNo].crc 
			!= GetCrc32 (Decompressed_Files[fileNo].fileContent, Decompressed_Files[fileNo].fileLength))
		{
			Error ("DIST_PACKAGE_CORRUPTED");
			goto sem_end;
		}

		fileNo++;
	}

	if (fileNo < NBR_COMPRESSED_FILES)
	{
		Error ("DIST_PACKAGE_CORRUPTED");
		goto sem_end;
	}

	free (compressedData);
	return TRUE;

sem_end:
	FreeAllFileBuffers();
	free (compressedData);
	return FALSE;
}
Пример #23
0
int cpu_Xts(int encryptionAlgorithm, char *encryptedHeader, char *headerKey, int headerKey_length, char *masterKey, int *masterKey_length) {
	BOOL ReadVolumeHeaderRecoveryMode = FALSE;
	char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
	PCRYPTO_INFO cryptoInfo;
	uint16 headerVersion;
	int status = ERR_PARAMETER_INCORRECT;
	int primaryKeyOffset=0;
	CRYPTO_INFO cryptoInfo_struct;

	//int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1;
	int i,j;

	cryptoInfo=&cryptoInfo_struct;
	memset (cryptoInfo, 0, sizeof (CRYPTO_INFO));
	if (cryptoInfo == NULL)
		return ERR_OUT_OF_MEMORY;


	// Support only XTS
	cryptoInfo->mode= XTS ;
	if(encryptionAlgorithm!=AES && encryptionAlgorithm!=SERPENT && encryptionAlgorithm!=TWOFISH)
		return ERR_CIPHER_INIT;
	cryptoInfo->ea=encryptionAlgorithm;

	status = cpu_EAInit (cryptoInfo->ea, headerKey + primaryKeyOffset, cryptoInfo->ks);
	if (status == ERR_CIPHER_INIT_FAILURE)
		return ERR_CIPHER_INIT;
	// Init objects related to the mode of operation

	// Copy the secondary key (if cascade, multiple concatenated)
	//memcpy (cryptoInfo->km2, headerKey + EAGetKeySize (cryptoInfo->ea), EAGetKeySize (cryptoInfo->ea));
	memcpy (cryptoInfo->km2, headerKey + 32, 32);
	// Secondary key schedule
	if (!cpu_EAInitMode (cryptoInfo)) {
		return ERR_MODE_INIT;
	}

	// Copy the header for decryption
	memcpy (header, encryptedHeader, 512*sizeof(unsigned char));

	// Try to decrypt header
	cpu_DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

	// Magic 'TRUE'
	if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
		return ERR_MAGIC_TRUE;

	// Header version
	headerVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION);
	if (headerVersion > VOLUME_HEADER_VERSION) {
		return ERR_VERSION_REQUIRED;
	}
	// Check CRC of the header fields
	if (!ReadVolumeHeaderRecoveryMode
			&& headerVersion >= 4
			&& GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
		return ERR_CRC_HEADER_FIELDS;

	// Required program version
	//cryptoInfo->RequiredProgramVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_REQUIRED_VERSION);
	//cryptoInfo->LegacyVolume = cryptoInfo->RequiredProgramVersion < 0x600;

	// Check CRC of the key set
	if (!ReadVolumeHeaderRecoveryMode
			&& GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
		return ERR_CRC_KEY_SET;

	/*
	// Now we have the correct password, cipher, hash algorithm, and volume type
	// Check the version required to handle this volume
	if (cryptoInfo->RequiredProgramVersion > VERSION_NUM){
	return ERR_NEW_VERSION_REQUIRED;
	}

	// Header version
	cryptoInfo->HeaderVersion = headerVersion;

	// Volume creation time (legacy)
	cryptoInfo->volume_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_CREATION_TIME).Value;

	// Header creation time (legacy)
	cryptoInfo->header_creation_time = GetHeaderField64 (header, TC_HEADER_OFFSET_MODIFICATION_TIME).Value;

	// Hidden volume size (if any)
	cryptoInfo->hiddenVolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE).Value;

	// Hidden volume status
	cryptoInfo->hiddenVolume = (cryptoInfo->hiddenVolumeSize != 0);

	// Volume size
	cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);

	// Encrypted area size and length
	cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
	cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);

	// Flags
	cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);

	// Sector size
	if (headerVersion >= 5)
	cryptoInfo->SectorSize = GetHeaderField32 (header, TC_HEADER_OFFSET_SECTOR_SIZE);
	else
	cryptoInfo->SectorSize = TC_SECTOR_SIZE_LEGACY;

	if (cryptoInfo->SectorSize < TC_MIN_VOLUME_SECTOR_SIZE
	|| cryptoInfo->SectorSize > TC_MAX_VOLUME_SECTOR_SIZE
	|| cryptoInfo->SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0){
	return ERR_PARAMETER_INCORRECT;
	}
	 */
	// Master key data
	if (masterKey!=NULL && masterKey_length!=NULL) {
		memcpy (masterKey, header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE);
		*masterKey_length= 64;
	}

	return SUCCESS;
}
Пример #24
0
BOOL MakeSelfExtractingPackage (HWND hwndDlg, char *szDestDir)
{
	int i, x;
	unsigned char inputFile [TC_MAX_PATH];
	unsigned char outputFile [TC_MAX_PATH];
	unsigned char szTmpFilePath [TC_MAX_PATH];
	unsigned char szTmp32bit [4] = {0};
	unsigned char *szTmp32bitPtr = szTmp32bit;
	unsigned char *buffer = NULL, *compressedBuffer = NULL;
	unsigned char *bufIndex = NULL;
	char tmpStr [2048];
	int bufLen = 0, compressedDataLen = 0, uncompressedDataLen = 0;

	x = strlen (szDestDir);
	if (x < 2)
		return FALSE;

	if (szDestDir[x - 1] != '\\')
		strcat (szDestDir, "\\");

	GetModuleFileName (NULL, inputFile, sizeof (inputFile));

	strcpy (outputFile, szDestDir);
	strncat (outputFile, OutputPackageFile, sizeof (outputFile) - strlen (outputFile) - 1);

	// Clone 'TrueCrypt Setup.exe' to create the base of the new self-extracting archive

	if (!TCCopyFile (inputFile, outputFile))
	{
		handleWin32Error (hwndDlg);
		PkgError ("Cannot copy 'TrueCrypt Setup.exe' to the package");
		return FALSE;
	}

	// Determine the buffer size needed for all the files and meta data and check if all required files exist

	bufLen = 0;

	for (i = 0; i < sizeof (szCompressedFiles) / sizeof (szCompressedFiles[0]); i++)
	{
		_snprintf (szTmpFilePath, sizeof(szTmpFilePath), "%s%s", szDestDir, szCompressedFiles[i]);

		if (!FileExists (szTmpFilePath))
		{
			char tmpstr [1000];

			_snprintf (tmpstr, sizeof(tmpstr), "File not found:\n\n'%s'", szTmpFilePath);
			remove (outputFile);
			PkgError (tmpstr);
			return FALSE;
		}

		bufLen += (int) GetFileSize64 (szTmpFilePath);

		bufLen += 2;					// 16-bit filename length
		bufLen += strlen(szCompressedFiles[i]);	// Filename
		bufLen += 4;					// CRC-32
		bufLen += 4;					// 32-bit file length
	}

	buffer = malloc (bufLen + 524288);	// + 512K reserve 
	if (buffer == NULL)
	{
		PkgError ("Cannot allocate memory for uncompressed data");
		remove (outputFile);
		return FALSE;
	}


	// Write the start marker
	if (!SaveBufferToFile (MAG_START_MARKER, outputFile, strlen (MAG_START_MARKER), TRUE))
	{
		PkgError ("Cannot write the start marker");
		remove (outputFile);
		return FALSE;
	}


	bufIndex = buffer;

	// Copy all required files and their meta data to the buffer
	for (i = 0; i < sizeof (szCompressedFiles) / sizeof (szCompressedFiles[0]); i++)
	{
		DWORD tmpFileSize;
		unsigned char *tmpBuffer;

		_snprintf (szTmpFilePath, sizeof(szTmpFilePath), "%s%s", szDestDir, szCompressedFiles[i]);

		tmpBuffer = LoadFile (szTmpFilePath, &tmpFileSize);

		if (tmpBuffer == NULL)
		{
			char tmpstr [1000];

			free (tmpBuffer);
			_snprintf (tmpstr, sizeof(tmpstr), "Cannot load file \n'%s'", szTmpFilePath);
			remove (outputFile);
			PkgError (tmpstr);
			goto msep_err;
		}

		// Copy the filename length to the main buffer
		mputWord (bufIndex, (WORD) strlen(szCompressedFiles[i]));

		// Copy the filename to the main buffer
		memcpy (bufIndex, szCompressedFiles[i], strlen(szCompressedFiles[i]));
		bufIndex += strlen(szCompressedFiles[i]);

		// Compute CRC-32 hash of the uncompressed file and copy it to the main buffer
		mputLong (bufIndex, GetCrc32 (tmpBuffer, tmpFileSize));

		// Copy the file length to the main buffer
		mputLong (bufIndex, (unsigned __int32) tmpFileSize);

		// Copy the file contents to the main buffer
		memcpy (bufIndex, tmpBuffer, tmpFileSize);
		bufIndex += tmpFileSize;

		free (tmpBuffer);
	}

	// Calculate the total size of the uncompressed data
	uncompressedDataLen = (int) (bufIndex - buffer);

	// Write total size of the uncompressed data
	szTmp32bitPtr = szTmp32bit;
	mputLong (szTmp32bitPtr, (unsigned __int32) uncompressedDataLen);
	if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE))
	{
		remove (outputFile);
		PkgError ("Cannot write the total size of the uncompressed data");
		return FALSE;
	}

	// Compress all the files and meta data in the buffer to create a solid archive

	compressedBuffer = malloc (uncompressedDataLen + 524288);	// + 512K reserve
	if (compressedBuffer == NULL)
	{
		remove (outputFile);
		PkgError ("Cannot allocate memory for compressed data");
		return FALSE;
	}

	compressedDataLen = CompressBuffer (compressedBuffer, buffer, uncompressedDataLen);
	if (compressedDataLen <= 0)
	{
		remove (outputFile);
		PkgError ("Failed to compress the data");
		return FALSE;
	}

	free (buffer);

	// Write the total size of the compressed data
	szTmp32bitPtr = szTmp32bit;
	mputLong (szTmp32bitPtr, (unsigned __int32) compressedDataLen);
	if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE))
	{
		remove (outputFile);
		PkgError ("Cannot write the total size of the compressed data");
		return FALSE;
	}

	// Write the compressed data
	if (!SaveBufferToFile (compressedBuffer, outputFile, compressedDataLen, TRUE))
	{
		remove (outputFile);
		PkgError ("Cannot write compressed data to the package");
		return FALSE;
	}

	// Write the end marker
	if (!SaveBufferToFile (MagEndMarker, outputFile, strlen (MagEndMarker), TRUE))
	{
		remove (outputFile);
		PkgError ("Cannot write the end marker");
		return FALSE;
	}

	free (compressedBuffer);

	// Compute and write CRC-32 hash of the entire package
	{
		DWORD tmpFileSize;
		char *tmpBuffer;

		tmpBuffer = LoadFile (outputFile, &tmpFileSize);

		if (tmpBuffer == NULL)
		{
			handleWin32Error (hwndDlg);
			remove (outputFile);
			PkgError ("Cannot load the package to compute CRC");
			return FALSE;
		}

		// Zero all bytes that change when the exe is digitally signed (except appended blocks).
		WipeSignatureAreas (tmpBuffer);

		szTmp32bitPtr = szTmp32bit;
		mputLong (szTmp32bitPtr, GetCrc32 (tmpBuffer, tmpFileSize));
		if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE))
		{
			remove (outputFile);
			PkgError ("Cannot write the total size of the compressed data");
			return FALSE;
		}

		free (tmpBuffer);
	}

	sprintf (tmpStr, "Self-extracting package successfully created (%s)", outputFile);
	PkgInfo (tmpStr);
	return TRUE;

msep_err:
	free (buffer);
	free (compressedBuffer);
	return FALSE;
}
Пример #25
0
int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo)
{
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
    char dk[32 * 2];			// 2 * 256-bit key
#else
    char dk[32 * 2 * 3];		// 6 * 256-bit key
#endif

    PCRYPTO_INFO cryptoInfo;
    int status = ERR_SUCCESS;
    uint32 iterations = pim;
    iterations <<= 16;
    iterations |= bBoot;

    if (retHeaderCryptoInfo != NULL)
        cryptoInfo = retHeaderCryptoInfo;
    else
        cryptoInfo = *retInfo = crypto_open ();

    // PKCS5 PRF
#ifdef TC_WINDOWS_BOOT_SHA2
    derive_key_sha256 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
                       PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
#else
    derive_key_ripemd160 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
                          PKCS5_SALT_SIZE, iterations, dk, sizeof (dk));
#endif

    // Mode of operation
    cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;

#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
    cryptoInfo->ea = 1;
#else
    // Test all available encryption algorithms
    for (cryptoInfo->ea = EAGetFirst (); cryptoInfo->ea != 0; cryptoInfo->ea = EAGetNext (cryptoInfo->ea))
#endif
    {
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
#if defined (TC_WINDOWS_BOOT_SERPENT)
        serpent_set_key (dk, cryptoInfo->ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
        twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
        camellia_set_key (dk, cryptoInfo->ks);
#else
        status = EAInit (dk, cryptoInfo->ks);
        if (status == ERR_CIPHER_INIT_FAILURE)
            goto err;
#endif
#else
        status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
        if (status == ERR_CIPHER_INIT_FAILURE)
            goto err;
#endif
        // Secondary key schedule
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
#if defined (TC_WINDOWS_BOOT_SERPENT)
        serpent_set_key (dk + 32, cryptoInfo->ks2);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
        twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
        camellia_set_key (dk + 32, cryptoInfo->ks2);
#else
        EAInit (dk + 32, cryptoInfo->ks2);
#endif
#else
        EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
#endif

        // Try to decrypt header
        DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

        // Check magic 'VERA' and CRC-32 of header fields and master keydata
        if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241
                || (GetHeaderField16 (header, TC_HEADER_OFFSET_VERSION) >= 4 && GetHeaderField32 (header, TC_HEADER_OFFSET_HEADER_CRC) != GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC))
                || GetHeaderField32 (header, TC_HEADER_OFFSET_KEY_AREA_CRC) != GetCrc32 (header + HEADER_MASTER_KEYDATA_OFFSET, MASTER_KEYDATA_SIZE))
        {
            EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
            status = ERR_PASSWORD_WRONG;
            goto err;
#else
            continue;
#endif
        }

        // Header decrypted
        status = 0;

        // Hidden volume status
        cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE);
        cryptoInfo->hiddenVolume = (cryptoInfo->VolumeSize.LowPart != 0 || cryptoInfo->VolumeSize.HighPart != 0);

        // Volume size
        cryptoInfo->VolumeSize = GetHeaderField64 (header, TC_HEADER_OFFSET_VOLUME_SIZE);

        // Encrypted area size and length
        cryptoInfo->EncryptedAreaStart = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_START);
        cryptoInfo->EncryptedAreaLength = GetHeaderField64 (header, TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH);

        // Flags
        cryptoInfo->HeaderFlags = GetHeaderField32 (header, TC_HEADER_OFFSET_FLAGS);

#ifdef TC_WINDOWS_BOOT_SHA2
        cryptoInfo->pkcs5 = SHA256;
#else
        cryptoInfo->pkcs5 = RIPEMD160;
#endif

        memcpy (dk, header + HEADER_MASTER_KEYDATA_OFFSET, sizeof (dk));
        EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

        if (retHeaderCryptoInfo)
            goto ret;

        // Init the encryption algorithm with the decrypted master key
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
#if defined (TC_WINDOWS_BOOT_SERPENT)
        serpent_set_key (dk, cryptoInfo->ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
        twofish_set_key ((TwofishInstance *) cryptoInfo->ks, (const u4byte *) dk);
#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
        camellia_set_key (dk, cryptoInfo->ks);
#else
        status = EAInit (dk, cryptoInfo->ks);
        if (status == ERR_CIPHER_INIT_FAILURE)
            goto err;
#endif
#else
        status = EAInit (cryptoInfo->ea, dk, cryptoInfo->ks);
        if (status == ERR_CIPHER_INIT_FAILURE)
            goto err;
#endif

        // The secondary master key (if cascade, multiple concatenated)
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
#if defined (TC_WINDOWS_BOOT_SERPENT)
        serpent_set_key (dk + 32, cryptoInfo->ks2);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
        twofish_set_key ((TwofishInstance *)cryptoInfo->ks2, (const u4byte *) (dk + 32));
#elif defined (TC_WINDOWS_BOOT_CAMELLIA)
        camellia_set_key (dk + 32, cryptoInfo->ks2);
#else
        EAInit (dk + 32, cryptoInfo->ks2);
#endif
#else
        EAInit (cryptoInfo->ea, dk + EAGetKeySize (cryptoInfo->ea), cryptoInfo->ks2);
#endif
        goto ret;
    }

    status = ERR_PASSWORD_WRONG;

err:
    if (cryptoInfo != retHeaderCryptoInfo)
    {
        crypto_close(cryptoInfo);
        *retInfo = NULL;
    }

ret:
    burn (dk, sizeof(dk));
    return status;
}
Пример #26
0
uint32 CRdbHashIndex::QueryHelp(CSqlParameterSet* pCondition, CSqlFilter& oFilter, CRecordSet *pResult, uint32* pSkipCount, uint32* pCount, uint32* pMaxCount, bool bUpdate, FOnTravelIndex OnTravel, void* pPara)
{
    uint32 nHashValue;
	uint32 nIdxFieldCount = m_pIdxDef->m_nFieldCount;
	if(nIdxFieldCount == 1)
	{
		uint32 nHashCount = 0;
		uint32 nFieldNo = m_pIdxDef->m_pFields[0];
		pCondition->GetHashValue(nFieldNo, nHashValue, nHashCount);
		if(nHashCount != 1)
			return RDB_INVALID_COND;
		nHashValue = nHashValue;
	}
	else
	{
		uint32 * pHashValue = new uint32[nIdxFieldCount];
		if(!pHashValue)
		{
			FocpLogEx(GetLogName(), FOCP_LOG_ERROR, ("CRdbHashIndex::QueryHelp(%s): RDB_LACK_MEMORY", m_pTabDef->m_pBaseAttr->sTableName));
			return RDB_LACK_MEMORY;
		}
		for(uint32 i=0; i<nIdxFieldCount; ++i)
		{
			uint32 nHashCount = 0;
			uint32 nFieldNo = m_pIdxDef->m_pFields[i];
			pCondition->GetHashValue(nFieldNo, nHashValue, nHashCount);
			if(nHashCount != 1)
				return RDB_INVALID_COND;
			pHashValue[i] = nHashValue;
		}
		nHashValue = GetCrc32((const uint8*)pHashValue, nIdxFieldCount<<2, 1);
		delete[] pHashValue;
	}

	uint64 nList;
	THashBlock * idx = m_oHash.GetNode(nHashValue, nList);
	if(idx == NULL)
		return RDB_SUCCESS;

	uint64 nNext;
	THashBlock oBlock = *idx;
	THashBlock* pNext = m_oHash.GetNextNode(idx, nNext);
	m_oHash.ReleaseBlock(nList, idx);
	CRecord* pRecord = NULL;
	uint32 nRet = AllocRecord(pResult, pRecord);
	if(nRet)
	{
		if(pNext)
			m_oHash.ReleaseBlock(nNext, pNext);
		return nRet;
	}

	uint32 nFull;
	while(true)
	{
		bool Done = false;
		uint32 nCount = 0;
		for(uint32 i=0; nCount<oBlock.nSize; ++i)
		{
			uint64 nRowId = oBlock.oNode[i].oObject;
			if(nRowId)
			{
				++nCount;
				if(oBlock.oNode[i].nHashValue == nHashValue)
				{
					nRet = IsCoincident(pRecord, nRowId, pCondition, 
						oFilter, pResult, pSkipCount, pCount, 
						pMaxCount, nFull, bUpdate, OnTravel, pPara);
					if(nRet)
					{
						if(pNext)
							m_oHash.ReleaseBlock(nNext, pNext);
						return nRet;
					}
					Done = true;
					if(nFull || m_oHash.IsUnique())
						break;
				}
			}
		}

		if(Done && (nFull || m_oHash.IsUnique()))
			break;

		if(!pNext)
			break;

		nList = nNext;
		idx = pNext;
		oBlock = *idx;

		pNext = m_oHash.GetNextNode(idx, nNext);
		m_oHash.ReleaseBlock(nList, idx);
	}

	if(pRecord)
	{
		if(pResult)
			pResult->PopRecord();
		else
			delete pRecord;
	}
	return RDB_SUCCESS;
}