示例#1
0
void BlockOrientedCipherModeBase::ProcessData(byte *outString, const byte *inString, size_t length)
{
	unsigned int s = BlockSize();
	assert(length % s == 0);
	unsigned int alignment = m_cipher->BlockAlignment();
	bool inputAlignmentOk = !RequireAlignedInput() || IsAlignedOn(inString, alignment);

	if (IsAlignedOn(outString, alignment))
	{
		if (inputAlignmentOk)
			ProcessBlocks(outString, inString, length / s);
		else
		{
			memcpy(outString, inString, length);
			ProcessBlocks(outString, outString, length / s);
		}
	}
	else
	{
		while (length)
		{
			if (inputAlignmentOk)
				ProcessBlocks(m_buffer, inString, 1);
			else
			{
				memcpy(m_buffer, inString, s);
				ProcessBlocks(m_buffer, m_buffer, 1);
			}
			memcpy(outString, m_buffer, s);
			inString += s;
			outString += s;
			length -= s;
		}
	}
}
示例#2
0
文件: shark.cpp 项目: xyliuke/plan9
inline SharkProcessAndXorBlock(const word64 *roundKeys, unsigned int rounds, const byte *inBlock, const byte *xorBlock, byte *outBlock)
{
	CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf<word64>()));
	word64 tmp = *(word64 *)(void *)inBlock ^ roundKeys[0];

	ByteOrder order = GetNativeByteOrder();
	tmp = cbox[0][GetByte(order, tmp, 0)] ^ cbox[1][GetByte(order, tmp, 1)]
		^ cbox[2][GetByte(order, tmp, 2)] ^ cbox[3][GetByte(order, tmp, 3)]
		^ cbox[4][GetByte(order, tmp, 4)] ^ cbox[5][GetByte(order, tmp, 5)]
		^ cbox[6][GetByte(order, tmp, 6)] ^ cbox[7][GetByte(order, tmp, 7)]
		^ roundKeys[1];

	for(unsigned int i=2; i<rounds; i++)
	{
		tmp = cbox[0][GETBYTE(tmp, 7)] ^ cbox[1][GETBYTE(tmp, 6)]
			^ cbox[2][GETBYTE(tmp, 5)] ^ cbox[3][GETBYTE(tmp, 4)]
			^ cbox[4][GETBYTE(tmp, 3)] ^ cbox[5][GETBYTE(tmp, 2)]
			^ cbox[6][GETBYTE(tmp, 1)] ^ cbox[7][GETBYTE(tmp, 0)]
			^ roundKeys[i];
	}

	PutBlock<byte, BigEndian>(xorBlock, outBlock)
		(sbox[GETBYTE(tmp, 7)])
		(sbox[GETBYTE(tmp, 6)])
		(sbox[GETBYTE(tmp, 5)])
		(sbox[GETBYTE(tmp, 4)])
		(sbox[GETBYTE(tmp, 3)])
		(sbox[GETBYTE(tmp, 2)])
		(sbox[GETBYTE(tmp, 1)])
		(sbox[GETBYTE(tmp, 0)]);

	CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf<word64>()));
	*(word64 *)(void *)outBlock ^= roundKeys[rounds];
}};
示例#3
0
inline void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, unsigned int length)
{
	if (m_leftOver > 0)
	{
		unsigned int len = STDMIN(m_leftOver, length);
		xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
		length -= len;
		m_leftOver -= len;
		inString += len;
		outString += len;
	}

	if (!length)
		return;

	assert(m_leftOver == 0);

	PolicyInterface &policy = this->AccessPolicy();
	unsigned int bytesPerIteration = policy.GetBytesPerIteration();
	unsigned int alignment = policy.GetAlignment();

	if (policy.CanOperateKeystream() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
	{
		if (IsAlignedOn(inString, alignment))
			policy.OperateKeystream(XOR_KEYSTREAM, outString, inString, length / bytesPerIteration);
		else
		{
			memcpy(outString, inString, length);
			policy.OperateKeystream(XOR_KEYSTREAM_INPLACE, outString, outString, length / bytesPerIteration);
		}
		inString += length - length % bytesPerIteration;
		outString += length - length % bytesPerIteration;
		length %= bytesPerIteration;

		if (!length)
			return;
	}

	unsigned int bufferByteSize = GetBufferByteSize(policy);
	unsigned int bufferIterations = policy.GetIterationsToBuffer();

	while (length >= bufferByteSize)
	{
		policy.WriteKeystream(m_buffer, bufferIterations);
		xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
		length -= bufferByteSize;
		inString += bufferByteSize;
		outString += bufferByteSize;
	}

	if (length > 0)
	{
		policy.WriteKeystream(m_buffer, bufferIterations);
		xorbuf(outString, inString, KeystreamBufferBegin(), length);
		m_leftOver = bytesPerIteration - length;
	}
}
示例#4
0
void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, unsigned int length)
{
	assert(length % this->MandatoryBlockSize() == 0);

	PolicyInterface &policy = this->AccessPolicy();
	unsigned int bytesPerIteration = policy.GetBytesPerIteration();
	unsigned int alignment = policy.GetAlignment();
	byte *reg = policy.GetRegisterBegin();

	if (m_leftOver)
	{
		unsigned int len = STDMIN(m_leftOver, length);
		CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
		m_leftOver -= len;
		length -= len;
		inString += len;
		outString += len;
	}

	if (!length)
		return;

	assert(m_leftOver == 0);

	if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
	{
		if (IsAlignedOn(inString, alignment))
			policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
		else
		{
			memcpy(outString, inString, length);
			policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
		}
		inString += length - length % bytesPerIteration;
		outString += length - length % bytesPerIteration;
		length %= bytesPerIteration;
	}

	while (length >= bytesPerIteration)
	{
		policy.TransformRegister();
		CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
		length -= bytesPerIteration;
		inString += bytesPerIteration;
		outString += bytesPerIteration;
	}

	if (length > 0)
	{
		policy.TransformRegister();
		CombineMessageAndShiftRegister(outString, reg, inString, length);
		m_leftOver = bytesPerIteration - length;
	}
}
示例#5
0
bool Socket::Connect(const char *addr, unsigned int port)
{
	assert(addr != NULL);

	sockaddr_in sa;
	memset(&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = inet_addr(addr);

	if (sa.sin_addr.s_addr == INADDR_NONE)
	{
		hostent *lphost = gethostbyname(addr);
		if (lphost == NULL)
		{
			SetLastError(SOCKET_EINVAL);
			CheckAndHandleError_int("gethostbyname", SOCKET_ERROR);
		}
		else
		{
			assert(IsAlignedOn(lphost->h_addr,GetAlignmentOf<in_addr>()));
			sa.sin_addr.s_addr = ((in_addr *)(void *)lphost->h_addr)->s_addr;
		}
	}

	sa.sin_port = htons((u_short)port);

	return Connect((const sockaddr *)&sa, sizeof(sa));
}
示例#6
0
void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length)
{
	if (m_leftOver > 0)
	{
		size_t len = STDMIN(m_leftOver, length);
		xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
		length -= len;
		m_leftOver -= len;
		inString += len;
		outString += len;

		if (!length)
			return;
	}
	CRYPTOPP_ASSERT(m_leftOver == 0);

	PolicyInterface &policy = this->AccessPolicy();
	unsigned int bytesPerIteration = policy.GetBytesPerIteration();

	if (policy.CanOperateKeystream() && length >= bytesPerIteration)
	{
		size_t iterations = length / bytesPerIteration;
		unsigned int alignment = policy.GetAlignment();
		KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));

		policy.OperateKeystream(operation, outString, inString, iterations);

		inString += iterations * bytesPerIteration;
		outString += iterations * bytesPerIteration;
		length -= iterations * bytesPerIteration;

		if (!length)
			return;
	}

	size_t bufferByteSize = m_buffer.size();
	size_t bufferIterations = bufferByteSize / bytesPerIteration;

	while (length >= bufferByteSize)
	{
		policy.WriteKeystream(m_buffer, bufferIterations);
		xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
		length -= bufferByteSize;
		inString += bufferByteSize;
		outString += bufferByteSize;
	}

	if (length > 0)
	{
		bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration);
		bufferIterations = bufferByteSize / bytesPerIteration;

		policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations);
		xorbuf(outString, inString, KeystreamBufferEnd()-bufferByteSize, length);
		m_leftOver = bufferByteSize - length;
	}
}
示例#7
0
void Camellia::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
#define KS(i, j) ks[i*4 + EFI(j/2)*2 + EFI(j%2)]

#define FL(klh, kll, krh, krl)		\
	ll ^= rotlFixed(lh & klh, 1);	\
	lh ^= (ll | kll);				\
	rh ^= (rl | krl);				\
	rl ^= rotlFixed(rh & krh, 1);

	word32 lh, ll, rh, rl;
	typedef BlockGetAndPut<word32, BigEndian> Block;
	Block::Get(inBlock)(lh)(ll)(rh)(rl);
	const word32 *ks = m_key.data();
	lh ^= KS(0,0);
	ll ^= KS(0,1);
	rh ^= KS(0,2);
	rl ^= KS(0,3);

	// timing attack countermeasure. see comments at top for more details
	const int cacheLineSize = GetCacheLineSize();
	unsigned int i;
	volatile word32 _u = 0;
	word32 u = _u;

	assert(IsAlignedOn(s1,GetAlignmentOf<word32>()));
	for (i=0; i<256; i+=cacheLineSize)
		u &= *(const word32 *)(void*)(s1+i);
	u &= *(const word32 *)(void*)(s1+252);
	lh |= u; ll |= u;

	SLOW_ROUND(lh, ll, rh, rl, KS(1,0), KS(1,1))
	SLOW_ROUND(rh, rl, lh, ll, KS(1,2), KS(1,3))
	for (i = m_rounds-1; i > 0; --i)
	{
		DOUBLE_ROUND(lh, ll, rh, rl, KS(2,0), KS(2,1), KS(2,2), KS(2,3))
		DOUBLE_ROUND(lh, ll, rh, rl, KS(3,0), KS(3,1), KS(3,2), KS(3,3))
		FL(KS(4,0), KS(4,1), KS(4,2), KS(4,3));
		DOUBLE_ROUND(lh, ll, rh, rl, KS(5,0), KS(5,1), KS(5,2), KS(5,3))
		ks += 16;
	}
	DOUBLE_ROUND(lh, ll, rh, rl, KS(2,0), KS(2,1), KS(2,2), KS(2,3))
	ROUND(lh, ll, rh, rl, KS(3,0), KS(3,1))
	SLOW_ROUND(rh, rl, lh, ll, KS(3,2), KS(3,3))
	lh ^= KS(4,0);
	ll ^= KS(4,1);
	rh ^= KS(4,2);
	rl ^= KS(4,3);
	Block::Put(xorBlock, outBlock)(rh)(rl)(lh)(ll);
}
示例#8
0
void BlockOrientedCipherModeBase::ProcessData(byte *outString, const byte *inString, size_t length)
{
	if (!length)
		return;

	unsigned int s = BlockSize();
	assert(length % s == 0);

	if (!RequireAlignedInput() || IsAlignedOn(inString, m_cipher->BlockAlignment()))
		ProcessBlocks(outString, inString, length / s);
	else
	{
		do
		{
			memcpy(m_buffer, inString, s);
			ProcessBlocks(outString, m_buffer, 1);
			inString += s;
			outString += s;
			length -= s;
		} while (length > 0);
	}
}
示例#9
0
文件: Crc.cpp 项目: lcs2/carpg
inline bool IsAligned(const void *p, T *dummy=NULL)	// VC60 workaround
{
	return IsAlignedOn(p, GetAlignmentOf<T>());
}
示例#10
0
void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length)
{
	CRYPTOPP_ASSERT(outString); CRYPTOPP_ASSERT(inString);
	CRYPTOPP_ASSERT(length % this->MandatoryBlockSize() == 0);

	PolicyInterface &policy = this->AccessPolicy();
	word32 bytesPerIteration = policy.GetBytesPerIteration();
	byte *reg = policy.GetRegisterBegin();

	if (m_leftOver)
	{
		const size_t len = STDMIN(m_leftOver, length);
		CombineMessageAndShiftRegister(outString, PtrAdd(reg, bytesPerIteration - m_leftOver), inString, len);

		m_leftOver -= len; length -= len;
		inString = PtrAdd(inString, len);
		outString = PtrAdd(outString, len);
	}

	// TODO: Figure out what is happening on ARM A-32. x86, Aarch64 and PowerPC are OK.
	//       The issue surfaced for CFB mode when we cut-in Cryptogams AES ARMv7 asm.
	//       Using 'outString' for both input and output leads to incorrect results.
	//
	//       Benchmarking on Cortex-A7 and Cortex-A9 indicates removing the block
	//       below costs about 9 cpb for CFB mode on ARM.
	//
	//       Also see https://github.com/weidai11/cryptopp/issues/683.
	//
	// UPDATE: It appears the issue is related to alignment checks. When we made
	//       the alignment check result volatile GCC and Clang stopped short-
	//       circuiting the transform, which is what we wanted. I suspect
	//       there's a little more to the issue, but we can enable the block again.

	const unsigned int alignment = policy.GetAlignment();
	volatile bool isAligned = IsAlignedOn(outString, alignment);
	if (policy.CanIterate() && length >= bytesPerIteration && isAligned)
	{
		isAligned &= IsAlignedOn(inString, alignment);
		const CipherDir cipherDir = GetCipherDir(*this);
		if (isAligned)
			policy.Iterate(outString, inString, cipherDir, length / bytesPerIteration);
		else
		{
			// GCC and Clang does not like this on ARM. The incorrect result is a string
			// of 0's instead of ciphertext (or plaintext if decrypting). The 0's trace
			// back to the allocation for the std::string in datatest.cpp. Elements in the
			// string are initialized to their default value, which is 0.
			//
			// It almost feels as if the compiler does not see the string is transformed
			// in-place so it short-circuits the transform. However, if we use a stand-alone
			// reproducer with the same data then the issue is _not_ present.
			//
			// When working on this issue we introduced PtrAdd and PtrSub to ensure we were
			// not running afoul of pointer arithmetic rules of the language. Namely we need
			// to use ptrdiff_t when subtracting pointers. We believe the relevant code paths
			// are clean.
			//
			// One workaround is a distinct and aligned temporary buffer. It [mostly] works
			// as expected but requires an extra allocation (casts not shown):
			//
			//   std::string temp(inString, length);
			//   policy.Iterate(outString, &temp[0], cipherDir, length / bytesPerIteration);
			//
			memcpy(outString, inString, length);
			policy.Iterate(outString, outString, cipherDir, length / bytesPerIteration);
		}
		const size_t remainder = length % bytesPerIteration;
		inString = PtrAdd(inString, length - remainder);
		outString = PtrAdd(outString, length - remainder);
		length = remainder;
	}

	while (length >= bytesPerIteration)
	{
		policy.TransformRegister();
		CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
		length -= bytesPerIteration;
		inString = PtrAdd(inString, bytesPerIteration);
		outString = PtrAdd(outString, bytesPerIteration);
	}

	if (length > 0)
	{
		policy.TransformRegister();
		CombineMessageAndShiftRegister(outString, reg, inString, length);
		m_leftOver = bytesPerIteration - length;
	}
}