Example #1
0
int main(int argc, register char **argv)
{
	register char *curchar;
	char cKeyChar;
	int nKeyLen;

	// initialize
//	memset(freqtab, '\0', 256 * sizeof(int));
//	memset(&header, '\0', sizeof(header));
	for (i = 0; (i < 256); i++)
		freqtab[i] = '\0';

	// set default encryption key
	for (i = 0, cKeyChar = ' '; i < BC_MAX_USER_KEY; i++) {
		cKeyChar += (int)szDefKeyOffsets[i];
		cEncKey[i] = cKeyChar;
	}

	header.usSignature = 0xEBBE;	// set compression signature
	szInputName[0] = szOutputName[0] = '\0';

	// check for too few args or "batcomp /?"
	if ((argc == 1) || (stricmp(argv[1],"/?") == 0))
		usage();

	// parse command line
	for (argv++ ; argc > 1; argv++, argc--) {

		if (**argv == '/') {

			switch (toupper((*argv)[1])) {
	
				case 'O':
					fOverwrite = 1;
					continue;

				case 'Q':
					fQuiet = 1;
					continue;

				case 'K':
					fKillComments = 1;
					continue;
	
				case 'E':
					// Set encryption flag, copy key (or as much of it as we need)
					fEncrypt = 1;
					if ((nKeyLen = (int)strlen(&((*argv)[2]))) > 0)
						memcpy(cEncKey, &((*argv)[2]), (nKeyLen > BC_MAX_USER_KEY) ? BC_MAX_USER_KEY : nKeyLen);
					continue;

				default:
					usage();
			}
		}

		if (szInputName[0] == '\0')
			strcpy(szInputName, *argv);
		else if (szOutputName[0] == '\0')
			strcpy(szOutputName, *argv);
		else
			usage();
	}

	if (szInputName[0] == 0)
		usage();

	if (fQuiet == 0)	
		printf(COPYRIGHT, PROGNAME);

	if (szOutputName[0] == 0) {
		strcpy(szOutputName, szInputName);

		// check if it gets too long?
		if ((out_ext = strrchr(szOutputName, '.')) == NULL)
			out_ext = szOutputName + strlen(szOutputName);
		strcpy(out_ext, ".btm");
	}

	if (fQuiet == 0)	
		printf(COMPMSG, szInputName, szOutputName);

	// need full filename expansion here??
	if (stricmp(szInputName, szOutputName) == 0)
		error(ERR_SAMENAME);

	// holler if no overwrite and output exists
	if ((fOverwrite == 0) && (sopen(szOutputName, (O_RDONLY | O_BINARY), SH_DENYNO) != -1))
		error(ERR_OVERWRITE);

	// open input, deny read-write mode in case we get fooled and this is output as well!
	if ((in = sopen(szInputName, (O_RDONLY | O_BINARY), SH_DENYRW)) == -1)
		error(ERR_INPUT_OPEN);

	// rewind & read the file header
	read(in,(void *)&lCompressed,4);

	// check for input file already compressed
	if ((lCompressed & 0xFFFF) == 0xBEEB)
		error(ERR_ALREADY_COMPRESSED);

	// rewind input file
	lseek(in,0L,0);

	// open output
	if ((out = sopen(szOutputName, (O_CREAT | O_TRUNC | O_RDWR | O_BINARY), SH_DENYRW, (S_IREAD | S_IWRITE))) == -1)
		error(ERR_OUTPUT_OPEN);

	// loop for two passes
	for (pass = 1; (pass <= 2); pass++) {

		uLines = 0;									// clear line count

		if (pass == 2) {

			// output (unfinished) header
			if (fEncrypt) {
				// set up encryption key, encrypt common character table
				TripleKey(cEncKey);
				EncryptDecrypt(NULL, (char _far *)cEncKey, (char _far *)header.cCommon, BC_COM_SIZE);
			}

			data_out((char *)(&header), sizeof(header), 0, 0);

			if (fEncrypt) {
				// put common character table back like it was, also
				// leaves encryption system in its post-table state
				// for use in encrypting text stream
				EncryptDecrypt(NULL, (char _far *)cEncKey, (char _far *)header.cCommon, BC_COM_SIZE);

				// output dummy (gibberish) data for encryption key
				data_out((char *)(&freqtab), BC_MAX_USER_KEY, 0, 0);
			}

			// set buffer address
			dataptr = szOutputBuffer;
		}

		// back up to start
		if (lseek(in, 0L, SEEK_SET) == -1L)
			error(ERR_INPUT_SEEK);

		while (getline(szInputBuffer) > 0) {

			// scan or translate line

			// strip trailing whitespace
			strip_trailing(szInputBuffer);

			// skip blank lines and comments
			if (fKillComments && ((szInputBuffer[0] == '\0') || (strnicmp(szInputBuffer,"::",2) == 0)))
				continue;

			// check for REM
			if (fKillComments && ((strnicmp(szInputBuffer, "rem ", 4) == 0) && (strnicmp(szInputBuffer, "rem >", 5) != 0)))
				continue;

			if (fQuiet == 0)	
				printf(COMPLINE, ++uLines);

			curchar = szInputBuffer;
			if (pass == 1) {

				// pass 1, scan the line

				// accum. char counts
				for ( ; (*curchar != '\0'); curchar++)
					freqtab[(int)*curchar]++;

			} else {

				// pass 2, translate the line

				// count line length including CR
				i = (int)strlen(szInputBuffer);
				nTotalBytes += i;
				if ((lTotalInput += (i + 1)) >= 0xFFE0L)
					error(ERR_TOO_BIG);

				// compress & output each character
				for ( ; *curchar; curchar++) {

					char *comptr;

					if ((comptr = memchr(header.cCommon, *curchar, BC_COM_SIZE)) == NULL) {
						// not in table, 3 nibbles
						nibble_out(0);
						nibble_out((char)(*curchar & 0xF));
						nibble_out((char)(*curchar >> 4));
					} else if (comptr >= max_one_nib) {
						// last part of table, 2 nibbles
						nibble_out(1);
						nibble_out((char)(comptr - max_one_nib));
					} else {
						// beginning of table, just one nibble
						nibble_out((char)(comptr - header.cCommon + 2));
					}
				}
			}
		}
void WHartNetworkData::TransmitIndicate(const WHartLocalStatus& localStatus, WHartPriority priority,
		const WHartDllAddress& dllSrc, WHartPayload& npdu)
{
//	LOG_DEBUG("TransmitIndicate: localStatus=" << localStatus.status << ", priority=" << priority << ", dllSrc="
//			<< dllSrc << ", NPDU=" << npdu);

	BinaryStream stream;
	STREAM_INIT(&stream, npdu.data, npdu.dataLen);

	//parse network header
	uint8_t controlByte;
	STREAM_READ_UINT8(&stream, &controlByte);
	uint8_t ttl;
	STREAM_READ_UINT8(&stream, &ttl);
	uint16_t asn;
	STREAM_READ_UINT16(&stream, &asn);

	//HACK:[andrei.petrut] - write ASN to common data so it can be used in the next packet...
	commonData.lastReadASN = asn;

	uint16_t graphID;
	STREAM_READ_UINT16(&stream, &graphID);
	WHartAddress dest;
	StreamReadNetAddress(&stream, dest, (controlByte & CONTROLTYPE_DESTADDRESS_MASK) == 0);
	WHartAddress src;
	StreamReadNetAddress(&stream, src, (controlByte & CONTROLTYPE_SRCADDRESS_MASK) == 0);

	//TODO:[andy] - implement isBroadcast
	bool isForMe = (dest == commonData.myNickname || dest == commonData.myUniqueID);
	bool isBroadcast = false;
	bool isSourceRoute = ((controlByte & CONTROLTYPE_1STSOURCEROUTE_MASK) != 0);

	WHartShortAddress proxy = 0;
	if (controlByte & CONTROLTYPE_PROXYROUTE_MASK)
	{
		STREAM_READ_UINT16(&stream, &proxy);
	}

	Route tempRoute;
	if (isSourceRoute)
	{
		tempRoute.destinationType = Route::dtSourceRoute;
		tempRoute.graphID = graphID;
		for (int i = 0; i < 4; i++)
		{
			WHartShortAddress addr;
			STREAM_READ_UINT16(&stream, &addr);
			if (addr != 0xFFFF)
			{
				tempRoute.sourceRoutePath.push_back(addr);
			}
		}
		if (controlByte & CONTROLTYPE_2NDSOURCEROUTE_MASK)
		{
			for (int i = 0; i < 4; i++)
			{
				WHartShortAddress addr;
				STREAM_READ_UINT16(&stream, &addr);
				if (addr != 0xFFFF)
				{
					tempRoute.sourceRoutePath.push_back(addr);
				}
			}
		}
	}

//	LOG_DEBUG("TransmitIndicate: isForMe=" << (int) isForMe << ", isBroadcast=" << (int) isBroadcast << ", isSourceRoute=" << (int)isSourceRoute << ", destAddress="
//			<< dest << ", TTL=" << ToStringHexa(ttl) << ", ASN=" << ToStringHexa(asn) << ", graphID="
//			<< ToStringHexa(graphID));

	if (isForMe || isBroadcast)
	{
		uint8_t securityControl; //contain session
		STREAM_READ_UINT8(&stream, &securityControl);

		WHartSessionKey::SessionKeyCode sessionKey = (WHartSessionKey::SessionKeyCode) (securityControl & 0x0F);
        uint8_t sessionType = securityControl & SECURITYCONTROL_SECURITYTYPE_MASK;

        //if join flow detected OnJoinCalback is called, in order to create session with the new device/ap if it is
        //provisioned correctly
        if ((sessionType == WHartSessionKey::joinKeyed) && (OnJoinCallback))
        {
            OnJoinCallback(src);
        }

		SessionTable::iterator session = FindSession(src, sessionKey);
		if (session == sessionTable.end())
		{
			LOG_WARN("Session for Dest=" << src << "with type=" << (int) sessionKey
					<< " not found! packet droped.");
			return;//invalid session
		}
		else
		{
//			LOG_DEBUG("Session used for packet is=" << sessionKey << " and dest=" << src << " and sessionID=" << (int)session->sessionID);
		}



		uint32_t counter;
		if (sessionType == WHartSessionKey::sessionKeyed)
		{
			uint8_t lsbNonce;
			STREAM_READ_UINT8(&stream, &lsbNonce);
//			LOG_DEBUG("Read small nonce counter = " << (int)lsbNonce << " . Need to reconstruct nonce counter...");
//			LOG_DEBUG("Session counter = " << session->receiveNonceCounter <<
//					" Session history size = " << sizeof(session->nonceCounterHistory)<<
//					" and compare value=" << ((1 + ((int)session->receiveNonceCounter & 0xFF) - (int)sizeof(session->nonceCounterHistory) * 8)));
			counter = ReconstructNonceCounter(*session, lsbNonce);
//			LOG_DEBUG("Reconstructed nonce counter=" << counter);
		} else
		{
			STREAM_READ_UINT32(&stream, &counter);
//			LOG_DEBUG("Read entire nonce counter=" << counter);
		}


		// reconstruct nonce counter end

		WHartPayload spdu(stream.nextByte, stream.remainingBytes);

		uint8_t dataTPDU[CommonData::MAX_PAYLOAD];
		WHartPayload tpdu(dataTPDU, sizeof(dataTPDU));

//		LOG_DEBUG("Creating PDU with size=" << stream.nextByte - npdu.data << " with stream next byte="
//				<< nlib::detail::BytesToString(stream.nextByte, stream.nextByte - npdu.data));
		CryptoStatus decryptStatus = EncryptDecrypt(*session, counter, WHartPayload(npdu.data, stream.nextByte - npdu.data), spdu,
				tpdu, src, dest, false);

		if (decryptStatus != whartcsSuccess)
		{
			LOG_WARN("transmitIndicate failed to decrypt Error=" << CryptoStatusToString(decryptStatus));
			return;
		}

		//reconstruct nonce counter
		if (sessionType == WHartSessionKey::joinKeyed) // join flow
		{
			LOG_DEBUG("Join flow detected.");
			session->receiveNonceCounter = counter;

		} else
		{
			int noncePosition = session->receiveNonceCounter - counter;
			if (noncePosition > (int) (NONCECOUNTERHISTORY_BIT_LENGTH))
			{
				//discard packet
				LOG_INFO("Received packet with nonce counter outside of the sliding window (nonce=" << counter
						<< ", windowStart=" << session->receiveNonceCounter << ", windowSize="
						<< (int) NONCECOUNTERHISTORY_BIT_LENGTH << "). Discarding packet...");
				return;
			}

			if (noncePosition < 0)
			{
//				LOG_DEBUG("New nonce received (old=" << session->receiveNonceCounter << ", new=" << counter << ". Sliding window to accommodate new nonce (with steps=" << -noncePosition << ")...");
				if (noncePosition <= -32)
				{
					session->nonceCounterHistory = 0;
				}
				else
				{
					session->nonceCounterHistory = session->nonceCounterHistory >> (-noncePosition);
				}

				noncePosition = 0;
				session->receiveNonceCounter = counter;
			}

			uint32_t mask = 0x01 << (NONCECOUNTERHISTORY_BIT_LENGTH - noncePosition - 1);
			if (session->nonceCounterHistory & mask)
			{
				// already received packet with this nonce, discard
				LOG_WARN("Already received packet with nonce=" << counter << " from src=" << src << ". Discarding...");
				return;
			}

			// mark nonce in history
			session->nonceCounterHistory = session->nonceCounterHistory | mask;
		}


		//forward to upper
		++nextRoutedHandler;
		WHartHandle handle = MAKE_WHARTHANDLE(1, nextRoutedHandler);

//		LOG_DEBUG("transmitIndicate forward to TL" << " handle=" << handle << ", src=" << src << ", priority="
//				<< priority << ", TPDU=" << tpdu);
		upper->TransmitIndicate(handle, src, priority, tpdu, (WHartSessionKey::SessionKeyCode) (securityControl & 0x0F));
	} else
Example #3
0
int main(int argc, char **argv) {
	unsigned char szLine[LINE_MAX + 1], szKey[KEY_LEN + 1];
	char szVarName[32], szVarVal[LINE_MAX + 1];
	char szInName[256], szOutName[256], szOutBuf[LINE_MAX + 1];
	char *pExt, *pNewLine;
	int fhIn, fhOut, i, nLen;

	if (argc < 3)
		error("Too few parameters");

	// Copy the key
	if (strnicmp(argv[1], "/p", 2) == 0) {
		// /P means we have a product name
		for (i = 0; i < NUM_PRODUCTS; i++) {
			if (stricmp(argv[1] + 2, pszProdList[i]) == 0) {
				memcpy(szKey, acProdKeys[i], KEY_LEN);
				szKey[KEY_LEN] = '\0';
				break;
			}
			if (i == (NUM_PRODUCTS - 1))
				error("Invalid product name");
		}
	} else {
		// Not a product name, must be the real key
		strcpy(szKey, argv[1]);
		if (strlen(szKey) != KEY_LEN)
			error("Key length error");
	}

	// Get input name
	strcpy(szInName, argv[2]);

	// Get or set output name
	if (argc > 3)
		strcpy(szOutName, argv[3]);
	else {
		strcpy(szOutName, szInName);
		if ((pExt = strrchr(szOutName, '.')) != NULL)
			*pExt = '\0';
		strcat(szOutName, ".h");
	}

	// Open files
	if ((fhIn = _open(szInName, _O_RDONLY | _O_BINARY)) == -1)
		error("Cannot open input file");
	if ((fhOut = _open(szOutName, (_O_CREAT | _O_TRUNC | _O_RDWR | _O_TEXT),
			(_S_IREAD | _S_IWRITE))) == -1)
		error("Cannot open output file");

	// Process each line
	while (ReadLine(fhIn, szLine)) {

		// If it starts with #enc, encrypt it and output original text
		// as a comment and encrypted text as an array
		if (strnicmp(szLine, "#enc ", 5) == 0) {

			// Parse name and value
			if (sscanf(szLine, "%*s %32s \"%255[^\"]\"", szVarName, szVarVal) != 2)
				error("Invalid input data");
	  		nLen = strlen(szVarVal);

			// Output original name and text as comment
			sprintf(szOutBuf, "//    %s = \"%s\"\n", szVarName, szVarVal);

			// Replace ASCII 04s with CR/LF
			for (pNewLine = szVarVal; ((pNewLine = strchr(pNewLine, '\x04')) != NULL); pNewLine += 2 ) {
*pNewLine = '\n';
//				strcpy( pNewLine, pNewLine + 1 );
//				strins( pNewLine, "\r\n" );
			}

			// Encrypt it
	  		EncryptDecrypt(NULL, szKey, szVarVal, nLen);

			// Dump to output, max 64 charactes per line
			WriteText(fhOut, szOutBuf);
			sprintf(szOutBuf, "unsigned char %s[] = {%d, ", szVarName, nLen);
			WriteText(fhOut, szOutBuf);
	  		for (i = 0; i < nLen; i++) {
	  			if ((i > 0) && ((i % 64) == 0))
	  				WriteText(fhOut, "\\\n   ");
	  			sprintf(szOutBuf, "0x%.02X", (unsigned int)szVarVal[i]);
				WriteText(fhOut, szOutBuf);
				if (i != (nLen - 1))
					WriteText(fhOut, ", ");
	  		}
	  		WriteText(fhOut, "};\n");

		} else {
			// Not an encryption line, just copy it to output
			strcat(szLine, "\n");
			WriteText(fhOut, szLine);
		}
	}
	return 0;
}