Пример #1
0
uint32* blowfish_init(int8 key[], int16 keybytes, uint32* P, uint32* S)
{
	int16          i;
	int16          j;
	int16          k;
	uint32		 data;
	uint32		 datal;
	uint32		 datar;

	const uint32 N = 16;
	memcpy(P, subkey, 72);
	memcpy(S, subkey+72, 4096);

	j = 0;

    for (i = 0; i < N + 2; ++i)
	{
		data = 0;
		for (k = 0; k < 4; ++k)
		{
			data = (data << 8) | key[j];
			j = j + 1;
			if (j >= keybytes) {
				j = 0;
			}
		}
		P[i] = P[i] ^ data;
	}

	datal = 0;
	datar = 0;

	for (i = 0; i < N + 2; i += 2)
	{
		blowfish_encipher(&datal, &datar, P, S);
		
		P[i] = datal;
		P[i + 1] = datar;
	}

	for (i = 0; i < 4; ++i)
	{
		for (j = 0; j < 256; j += 2) 
		{
			blowfish_encipher(&datal, &datar, P, S);
   
			S[i*256+j] = datal;
			S[i*256+j + 1] = datar;
		}
	}

	return P;
}
Пример #2
0
int32 CTCPRequestPacket::SendToSocket(uint8* data, uint32 length)
{
    int32 iResult;

    WBUFW(data,(0x00)) = length;          // packet size
    WBUFL(data,(0x04)) = 0x46465849;      // "XIFF"

    md5((uint8*)(key), blowfish.hash, 24);

	blowfish_init((int8*)blowfish.hash,16, blowfish.P, blowfish.S[0]);

	md5(data+8, data+length-0x18+0x04, length-0x18-0x04);

	uint8 tmp = (length-12)/4;
	tmp -= tmp%2;

	for(uint8 i = 0; i < tmp; i += 2) 
    {
		blowfish_encipher((uint32*)data+i+2, (uint32*)data+i+3, blowfish.P, blowfish.S[0]);
	}

	memcpy(&data[length]-0x04, key+16, 4);

    iResult = send(*m_socket, (const int8*)data, length, 0);
    if (iResult == SOCKET_ERROR) 
    {
#ifdef WIN32
        ShowError("send failed with error: %d\n", WSAGetLastError());
#else
        ShowError("send failed with error: %d\n", errno);
#endif
        return 0;
    }
    return ReceiveFromSocket();
}
Пример #3
0
int32 send_parse(int8 *buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* map_session_data)
{
	// Модификация заголовка исходящего пакета
	// Суть преобразований:
	//  - отправить клиенту номер последнего полученного от него пакета
	//  - присвоить исходящему пакету номер последнего отправленного клиенту пакета +1
	//  - записать текущее время отправки пакета

	WBUFW(buff,0) = map_session_data->server_packet_id;
	WBUFW(buff,2) = map_session_data->client_packet_id;

	// сохранение текущего времени (32 BIT!)
	WBUFL(buff,8) = (uint32)time(NULL);

	//Сжимаем данные без учета заголовка
	//Возвращаемый размер в 8 раз больше реальных данных
	uint32 PacketSize = zlib_compress(buff+FFXI_HEADER_SIZE, *buffsize-FFXI_HEADER_SIZE, PTempBuff, *buffsize, zlib_compress_table);

	//Запись размера данных без учета заголовка
	WBUFL(PTempBuff,(PacketSize+7)/8) = PacketSize;

	//Расчет hash'a также без учета заголовка, но с учетом записанного выше размера данных
	PacketSize = (PacketSize+7)/8+4;
	uint8 hash[16];
	md5((uint8*)PTempBuff, hash, PacketSize);
	memcpy(PTempBuff+PacketSize, hash, 16);
	PacketSize += 16;

    if (PacketSize > map_config.buffer_size + 20)
    {
        ShowFatalError(CL_RED"%Memory manager: PTempBuff is overflowed (%u)\n" CL_RESET, PacketSize);
    }

	//making total packet
	memcpy(buff+FFXI_HEADER_SIZE, PTempBuff, PacketSize);

	uint32 CypherSize = (PacketSize/4)&-2;

	blowfish_t* pbfkey = &map_session_data->blowfish;

	for(uint32 j = 0; j < CypherSize; j += 2)
	{
		blowfish_encipher((uint32*)(buff)+j+7, (uint32*)(buff)+j+8, pbfkey->P, pbfkey->S[0]);
	}

	// контролируем размер отправляемого пакета. в случае,
	// если его размер превышает 1400 байт (размер данных + 42 байта IP заголовок),
	// то клиент игнорирует пакет и возвращает сообщение о его потере

	// в случае возникновения подобной ситуации выводим предупреждующее сообщение и
	// уменьшаем размер BuffMaxSize с шагом в 4 байта до ее устранения (вручную)

	*buffsize = PacketSize+FFXI_HEADER_SIZE;

	if (*buffsize > 1350)
	{
		ShowWarning(CL_YELLOW"send_parse: packet is very big <%u>\n" CL_RESET,*buffsize);
	}
	return 0;
}
Пример #4
0
int32 send_parse(int8 *buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* map_session_data)
{
    // Модификация заголовка исходящего пакета
    // Суть преобразований:
    //  - отправить клиенту номер последнего полученного от него пакета
    //  - присвоить исходящему пакету номер последнего отправленного клиенту пакета +1
    //  - записать текущее время отправки пакета

    WBUFW(buff, 0) = map_session_data->server_packet_id;
    WBUFW(buff, 2) = map_session_data->client_packet_id;

    // сохранение текущего времени (32 BIT!)
    WBUFL(buff, 8) = (uint32)time(nullptr);

    // собираем большой пакет, состоящий из нескольких маленьких
    CCharEntity *PChar = map_session_data->PChar;
    CBasicPacket* PSmallPacket;
    uint32 PacketSize = UINT32_MAX;
    uint32 PacketCount = PChar->getPacketCount();
    uint8 packets = 0;

    while (PacketSize > 1300 - FFXI_HEADER_SIZE - 16) //max size for client to accept
    {
        *buffsize = FFXI_HEADER_SIZE;
        PacketList_t packetList = PChar->getPacketList();
        packets = 0;

        while (!packetList.empty() && *buffsize + packetList.front()->length() < map_config.buffer_size &&
            packets < PacketCount)
        {
            PSmallPacket = packetList.front();

            PSmallPacket->sequence(map_session_data->server_packet_id);
            memcpy(buff + *buffsize, *PSmallPacket, PSmallPacket->length());

            *buffsize += PSmallPacket->length();
            packetList.pop_front();
            packets++;
        }
        //Сжимаем данные без учета заголовка
        //Возвращаемый размер в 8 раз больше реальных данных
        PacketSize = zlib_compress(buff + FFXI_HEADER_SIZE, *buffsize - FFXI_HEADER_SIZE, PTempBuff, *buffsize, zlib_compress_table);
        WBUFL(PTempBuff, (PacketSize + 7) / 8) = PacketSize;

        PacketSize = (PacketSize + 7) / 8 + 4;

        PacketCount /= 2;
    }
    PChar->erasePackets(packets);

    //Запись размера данных без учета заголовка
    uint8 hash[16];
    md5((uint8*)PTempBuff, hash, PacketSize);
    memcpy(PTempBuff + PacketSize, hash, 16);
    PacketSize += 16;

    if (PacketSize > map_config.buffer_size + 20)
    {
        ShowFatalError(CL_RED"%Memory manager: PTempBuff is overflowed (%u)\n" CL_RESET, PacketSize);
    }

    //making total packet
    memcpy(buff + FFXI_HEADER_SIZE, PTempBuff, PacketSize);

    uint32 CypherSize = (PacketSize / 4)&-2;

    blowfish_t* pbfkey = &map_session_data->blowfish;

    for (uint32 j = 0; j < CypherSize; j += 2)
    {
        blowfish_encipher((uint32*)(buff)+j + 7, (uint32*)(buff)+j + 8, pbfkey->P, pbfkey->S[0]);
    }

    // контролируем размер отправляемого пакета. в случае,
    // если его размер превышает 1400 байт (размер данных + 42 байта IP заголовок),
    // то клиент игнорирует пакет и возвращает сообщение о его потере

    // в случае возникновения подобной ситуации выводим предупреждующее сообщение и
    // уменьшаем размер BuffMaxSize с шагом в 4 байта до ее устранения (вручную)

    *buffsize = PacketSize + FFXI_HEADER_SIZE;

    return 0;
}
Пример #5
0
static void blowfish_init(u_8bit_t * key, int keybytes)
{
  int i, j, bx;
  time_t lowest;
  u_32bit_t data;
  u_32bit_t datal;
  u_32bit_t datar;
  union aword temp;

  /* drummer: Fixes crash if key is longer than 80 char. This may cause the key
   *          to not end with \00 but that's no problem.
   */
  if (keybytes > 80)
    keybytes = 80;

  /* Is buffer already allocated for this? */
  for (i = 0; i < BOXES; i++)
    if (box[i].P != NULL) {
      if ((box[i].keybytes == keybytes) &&
	  (!strncmp((char *) (box[i].key), (char *) key, keybytes))) {
	/* Match! */
	box[i].lastuse = now;
	bf_P = box[i].P;
	bf_S = box[i].S;
	return;
      }
    }
  /* No pre-allocated buffer: make new one */
  /* Set 'bx' to empty buffer */
  bx = (-1);
  for (i = 0; i < BOXES; i++) {
    if (box[i].P == NULL) {
      bx = i;
      i = BOXES + 1;
    }
  }
  if (bx < 0) {
    /* Find oldest */
    lowest = now;
    for (i = 0; i < BOXES; i++)
      if (box[i].lastuse <= lowest) {
	lowest = box[i].lastuse;
	bx = i;
      }
    nfree(box[bx].P);
    for (i = 0; i < 4; i++)
      nfree(box[bx].S[i]);
    nfree(box[bx].S);
  }
  /* Initialize new buffer */
  /* uh... this is over 4k */
  box[bx].P = (u_32bit_t *) nmalloc((bf_N + 2) * sizeof(u_32bit_t));
  box[bx].S = (u_32bit_t **) nmalloc(4 * sizeof(u_32bit_t *));
  for (i = 0; i < 4; i++)
    box[bx].S[i] = (u_32bit_t *) nmalloc(256 * sizeof(u_32bit_t));
  bf_P = box[bx].P;
  bf_S = box[bx].S;
  box[bx].keybytes = keybytes;
  strncpy(box[bx].key, key, keybytes);
  box[bx].key[keybytes] = 0;
  box[bx].lastuse = now;
  /* Robey: Reset blowfish boxes to initial state
   * (I guess normally it just keeps scrambling them, but here it's
   * important to get the same encrypted result each time)
   */
  for (i = 0; i < bf_N + 2; i++)
    bf_P[i] = initbf_P[i];
  for (i = 0; i < 4; i++)
    for (j = 0; j < 256; j++)
      bf_S[i][j] = initbf_S[i][j];

  j = 0;
  if (keybytes > 0) { /* drummer: fixes crash if key=="" */
    for (i = 0; i < bf_N + 2; ++i) {
      temp.word = 0;
      temp.w.byte0 = key[j];
      temp.w.byte1 = key[(j + 1) % keybytes];
      temp.w.byte2 = key[(j + 2) % keybytes];
      temp.w.byte3 = key[(j + 3) % keybytes];
      data = temp.word;
      bf_P[i] = bf_P[i] ^ data;
      j = (j + 4) % keybytes;
    }
  }
  datal = 0x00000000;
  datar = 0x00000000;
  for (i = 0; i < bf_N + 2; i += 2) {
    blowfish_encipher(&datal, &datar);
    bf_P[i] = datal;
    bf_P[i + 1] = datar;
  }
  for (i = 0; i < 4; ++i) {
    for (j = 0; j < 256; j += 2) {
      blowfish_encipher(&datal, &datar);
      bf_S[i][j] = datal;
      bf_S[i][j + 1] = datar;
    }
  }
}
Пример #6
0
void blowfish_init(UBYTE_08bits *key, short keybytes)
{
	int i, j, bx;
	time_t lowest;
	UWORD_32bits data;
	UWORD_32bits datal;
	UWORD_32bits datar;
	union aword temp;

	/* is buffer already allocated for this? */
	for(i=0; i<BOXES; i++)
	{
		if(box[i].P != NULL)
		{
			if((box[i].keybytes == keybytes) && (strncmp(box[i].key,key,keybytes) == 0))
			{
				/* match! */
				box[i].lastuse = time(NULL);
				bf_P = box[i].P;
				bf_S = box[i].S;
				return;
			}
		}
	}

	/* no pre-allocated buffer: make new one */
	/* set 'bx' to empty buffer */
	bx = (-1);
	for(i=0; i<BOXES; i++)
	{
		if(box[i].P == NULL)
		{
			bx = i;
			i = BOXES + 1;
		}
	}
	if(bx < 0)
	{
		/* find oldest */
		lowest = time(NULL);
		for(i=0; i<BOXES; i++)
		{
			if(box[i].lastuse <= lowest)
			{
				lowest = box[i].lastuse;
				bx = i;
			}
		}
		mfree(box[bx].P);
		for(i=0; i<4; i++)
			mfree(box[bx].S[i]);
		mfree(box[bx].S);
	}

	/* initialize new buffer */
	/* uh... this is over 4k */
	box[bx].P = (UWORD_32bits *)nmalloc((bf_N+2)*sizeof(UWORD_32bits));
	box[bx].S = (UWORD_32bits **)nmalloc(4*sizeof(UWORD_32bits *));
	for(i=0; i<4; i++)
		box[bx].S[i] = (UWORD_32bits *)nmalloc(256*sizeof(UWORD_32bits));
	bf_P = box[bx].P;
	bf_S = box[bx].S;
	box[bx].keybytes = keybytes;
	strncpy(box[bx].key,key,keybytes);
	box[bx].lastuse = time(NULL);

	/* robey: reset blowfish boxes to initial state */
	/* (i guess normally it just keeps scrambling them, but here it's */
	/* important to get the same encrypted result each time) */
	for(i=0; i<bf_N+2; i++)
		bf_P[i] = initbf_P[i];
	for(i=0; i<4; i++)
		for(j=0; j<256; j++)
			bf_S[i][j] = initbf_S[i][j];

	j = 0;
	for(i=0; i<bf_N+2; ++i)
	{
		temp.word = 0;
		temp.w.byte0 = key[j];
		temp.w.byte1 = key[(j+1) % keybytes];
		temp.w.byte2 = key[(j+2) % keybytes];
		temp.w.byte3 = key[(j+3) % keybytes];
		data = temp.word;
		bf_P[i] = bf_P[i] ^ data;
		j = (j+4) % keybytes;
	}

	datal = 0x00000000;
	datar = 0x00000000;

	for(i=0; i<bf_N+2; i+=2)
	{
		blowfish_encipher(&datal,&datar);

		bf_P[i] = datal;
		bf_P[i+1] = datar;
	}

	for(i=0; i<4; ++i)
	{
		for(j=0; j<256; j+=2)
		{

			blowfish_encipher(&datal, &datar);

			bf_S[i][j] = datal;
			bf_S[i][j+1] = datar;
		}
	}
}
Пример #7
0
static void blowfish_init(UBYTE_08bits * key, short keybytes)
{
  int i, j;
  UWORD_32bits data;
  UWORD_32bits datal;
  UWORD_32bits datar;
  union aword temp;

  /* is buffer already allocated for this? */
  if (box.P != NULL) {
      if ((box.keybytes == keybytes) &&
	  (!strncmp((char *) (box.key), (char *) key, keybytes))) {
	/* match! */
	bf_P = box.P;
	bf_S = box.S;
	return;
      }
        free(box.P);
        for (i = 0; i < 4; i++)
          free(box.S[i]);
        free(box.S);
  }
  /* initialize new buffer */
  /* uh... this is over 4k */
  box.P = (UWORD_32bits *) malloc((bf_N + 2) * sizeof(UWORD_32bits));
  box.S = (UWORD_32bits **) malloc(4 * sizeof(UWORD_32bits *));
  for (i = 0; i < 4; i++)
    box.S[i] = (UWORD_32bits *) malloc(256 * sizeof(UWORD_32bits));
  bf_P = box.P;
  bf_S = box.S;
  box.keybytes = keybytes;
  strncpy(box.key, key, keybytes);
  /* robey: reset blowfish boxes to initial state */
  /* (i guess normally it just keeps scrambling them, but here it's
   * important to get the same encrypted result each time) */
  for (i = 0; i < bf_N + 2; i++)
    bf_P[i] = initbf_P[i];
  for (i = 0; i < 4; i++)
    for (j = 0; j < 256; j++)
      bf_S[i][j] = initbf_S[i][j];

  j = 0;
  for (i = 0; i < bf_N + 2; ++i) {
    temp.word = 0;
    temp.w.byte0 = key[j];
    temp.w.byte1 = key[(j + 1) % keybytes];
    temp.w.byte2 = key[(j + 2) % keybytes];
    temp.w.byte3 = key[(j + 3) % keybytes];
    data = temp.word;
    bf_P[i] = bf_P[i] ^ data;
    j = (j + 4) % keybytes;
  }
  datal = 0x00000000;
  datar = 0x00000000;
  for (i = 0; i < bf_N + 2; i += 2) {
    blowfish_encipher(&datal, &datar);
    bf_P[i] = datal;
    bf_P[i + 1] = datar;
  }
  for (i = 0; i < 4; ++i) {
    for (j = 0; j < 256; j += 2) {
      blowfish_encipher(&datal, &datar);
      bf_S[i][j] = datal;
      bf_S[i][j + 1] = datar;
    }
  }
}