Beispiel #1
0
void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(RandomNumberGenerator &rng, 
	const byte *recoverableMessage, unsigned int recoverableMessageLength,
	HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
	byte *representative, unsigned int representativeBitLength) const
{
	unsigned int digestSize = hash.DigestSize();
	if (digestSize + hashIdentifier.second + 10 > representativeBitLength/8)
		throw PK_Signer::KeyTooShort();

	unsigned int pkcsBlockLen = representativeBitLength;
	// convert from bit length to byte length
	if (pkcsBlockLen % 8 != 0)
	{
		representative[0] = 0;
		representative++;
	}
	pkcsBlockLen /= 8;

	representative[0] = 1;   // block type 1

	byte *pPadding = representative + 1;
	byte *pDigest = representative + pkcsBlockLen - digestSize;
	byte *pHashId = pDigest - hashIdentifier.second;
	byte *pSeparator = pHashId - 1;

	// pad with 0xff
	memset(pPadding, 0xff, pSeparator-pPadding);
	*pSeparator = 0;
	memcpy(pHashId, hashIdentifier.first, hashIdentifier.second);
	hash.Final(pDigest);
}
Beispiel #2
0
bool HashModuleTest(HashTransformation &md, const HashTestTuple *testSet, unsigned int testSetSize)
{
	bool pass=true, fail;
	SecByteBlock digest(md.DigestSize());

	for (unsigned int i=0; i<testSetSize; i++)
	{
		unsigned j;

		for (j=0; j<testSet[i].repeatTimes; j++)
			md.Update(testSet[i].input, testSet[i].inputLen);
		md.Final(digest);
		fail = memcmp(digest, testSet[i].output, md.DigestSize()) != 0;
		pass = pass && !fail;

		cout << (fail ? "FAILED   " : "passed   ");
		for (j=0; j<md.DigestSize(); j++)
			cout << setw(2) << setfill('0') << hex << (int)digest[j];
		cout << "   \"" << (char *)testSet[i].input << '\"';
		if (testSet[i].repeatTimes != 1)
			cout << " repeated " << dec << testSet[i].repeatTimes << " times";
		cout  << endl;
	}

	return pass;
}
Beispiel #3
0
void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(RandomNumberGenerator &rng,
	const byte *recoverableMessage, size_t recoverableMessageLength,
	HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
	byte *representative, size_t representativeBitLength) const
{
	CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
	CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
	CRYPTOPP_ASSERT(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize()));

	size_t pkcsBlockLen = representativeBitLength;
	// convert from bit length to byte length
	if (pkcsBlockLen % 8 != 0)
	{
		representative[0] = 0;
		representative++;
	}
	pkcsBlockLen /= 8;

	representative[0] = 1;   // block type 1

	unsigned int digestSize = hash.DigestSize();
	byte *pPadding = representative + 1;
	byte *pDigest = representative + pkcsBlockLen - digestSize;
	byte *pHashId = pDigest - hashIdentifier.second;
	byte *pSeparator = pHashId - 1;

	// pad with 0xff
	memset(pPadding, 0xff, pSeparator-pPadding);
	*pSeparator = 0;
	memcpy(pHashId, hashIdentifier.first, hashIdentifier.second);
	hash.Final(pDigest);
}
Beispiel #4
0
bool HashModuleTest(HashTransformation &md, const HashTestTuple *testSet, unsigned int testSetSize)
{
	bool pass=true, fail;
	SecByteBlock digest(md.DigestSize());

	// Coverity finding (http://stackoverflow.com/a/30968371 does not squash the finding)
	std::ostringstream out;
	out.copyfmt(cout);

	for (unsigned int i=0; i<testSetSize; i++)
	{
		unsigned j;

		for (j=0; j<testSet[i].repeatTimes; j++)
			md.Update(testSet[i].input, testSet[i].inputLen);
		md.Final(digest);
		fail = memcmp(digest, testSet[i].output, md.DigestSize()) != 0;
		pass = pass && !fail;

		out << (fail ? "FAILED   " : "passed   ");
		for (j=0; j<md.DigestSize(); j++)
			out << setw(2) << setfill('0') << hex << (int)digest[j];
		out << "   \"" << (char *)testSet[i].input << '\"';
		if (testSet[i].repeatTimes != 1)
			out << " repeated " << dec << testSet[i].repeatTimes << " times";
		out  << endl;
	}

	cout << out.str();
	return pass;
}
DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative(
	HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
	byte *representative, size_t representativeBitLength,
	byte *recoverableMessage) const
{
	assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize()));

	const size_t u = hashIdentifier.second + 1;
	const size_t representativeByteLength = BitsToBytes(representativeBitLength);
	const size_t digestSize = hash.DigestSize();
	const size_t saltSize = SaltLen(digestSize);
	const byte *const h = representative + representativeByteLength - u - digestSize;

	SecByteBlock digest(digestSize);
	hash.Final(digest);

	DecodingResult result(0);
	bool &valid = result.isValidCoding;
	size_t &recoverableMessageLength = result.messageLength;

	valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid;
	valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid;

	GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize);
	if (representativeBitLength % 8 != 0)
		representative[0] = (byte)Crop(representative[0], representativeBitLength % 8);

	// extract salt and recoverableMessage from DB = 00 ... || 01 || M || salt
	byte *salt = representative + representativeByteLength - u - digestSize - saltSize;
	byte *M = std::find_if(representative, salt-1, std::bind2nd(std::not_equal_to<byte>(), 0));
	recoverableMessageLength = salt-M-1;
	if (*M == 0x01 
		&& (size_t)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize)
		&& recoverableMessageLength <= MaxRecoverableLength(representativeBitLength, hashIdentifier.second, digestSize))
	{
		memcpy(recoverableMessage, M+1, recoverableMessageLength);
	}
	else
	{
		recoverableMessageLength = 0;
		valid = false;
	}

	// verify H = hash of M'
	byte c[8];
	PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength));
	PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3));
	hash.Update(c, 8);
	hash.Update(recoverableMessage, recoverableMessageLength);
	hash.Update(digest, digestSize);
	hash.Update(salt, saltSize);
	valid = hash.Verify(h) && valid;

	if (!AllowRecovery() && valid && recoverableMessageLength != 0)
		{throw NotImplemented("PSSR_MEM: message recovery disabled");}
	
	return result;
}
void PSSR_MEM_Base::ComputeMessageRepresentative(RandomNumberGenerator &rng, 
	const byte *recoverableMessage, size_t recoverableMessageLength,
	HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
	byte *representative, size_t representativeBitLength) const
{
	assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize()));

	const size_t u = hashIdentifier.second + 1;
	const size_t representativeByteLength = BitsToBytes(representativeBitLength);
	const size_t digestSize = hash.DigestSize();
	const size_t saltSize = SaltLen(digestSize);
	byte *const h = representative + representativeByteLength - u - digestSize;

	SecByteBlock digest(digestSize), salt(saltSize);
	hash.Final(digest);
	rng.GenerateBlock(salt, saltSize);

	// compute H = hash of M'
	byte c[8];
	PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength));
	PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3));
	hash.Update(c, 8);
	hash.Update(recoverableMessage, recoverableMessageLength);
	hash.Update(digest, digestSize);
	hash.Update(salt, saltSize);
	hash.Final(h);

	// compute representative
	GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize, false);
	byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1;
	xorStart[0] ^= 1;
	xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength);
	xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size());
	memcpy(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second);
	representative[representativeByteLength - 1] = hashIdentifier.second ? 0xcc : 0xbc;
	if (representativeBitLength % 8 != 0)
		representative[0] = (byte)Crop(representative[0], representativeBitLength % 8);
}
/* function finalHash : This function completes the hash computation
 * param hashPtr	   : The actual hash object pointer 
 * param input		   : the byte array to put the result in
 * param size		   : the length of the byte array. This will be different for different hash functions
 */
JNIEXPORT void JNICALL Java_edu_biu_scapi_primitives_hash_cryptopp_CryptoPpHash_finalHash
(JNIEnv *env, jobject, jlong hashPtr, jbyteArray output){

	HashTransformation *localHashPtr = (HashTransformation *)hashPtr;

	//allocate a new byte array with the size of the specific hash algorithm.
	byte *ret = new byte[localHashPtr->DigestSize()]; 

	//perform the final function
	localHashPtr->Final(ret);

	//put the result of the final computation in the output array passed from java
	env->SetByteArrayRegion(output, 0, localHashPtr->DigestSize(), (jbyte*)ret); 

	//make sure to release the dynamically allocated memory. Will not be deleted by the JVM.
	delete ret;


}
Beispiel #8
0
void EMSA2Pad::ComputeMessageRepresentative(RandomNumberGenerator &rng, 
	const byte *recoverableMessage, size_t recoverableMessageLength,
	HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
	byte *representative, size_t representativeBitLength) const
{
	assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize()));

	if (representativeBitLength % 8 != 7)
		throw PK_SignatureScheme::InvalidKeyLength("EMSA2: EMSA2 requires a key length that is a multiple of 8");

	size_t digestSize = hash.DigestSize();
	size_t representativeByteLength = BitsToBytes(representativeBitLength);

	representative[0] = messageEmpty ? 0x4b : 0x6b;
	memset(representative+1, 0xbb, representativeByteLength-digestSize-4);	// pad with 0xbb
	byte *afterP2 = representative+representativeByteLength-digestSize-3;
	afterP2[0] = 0xba;
	hash.Final(afterP2+1);
	representative[representativeByteLength-2] = *hashIdentifier.first;
	representative[representativeByteLength-1] = 0xcc;
}