예제 #1
0
// Generic login function
bool SecureDataManager::login(const ByteString& passphrase, const ByteString& encryptedKey)
{
	// Log out first
	this->logout();

	// First, take the salt from the encrypted key
	ByteString salt = encryptedKey.substr(0,8);

	// Then, take the IV from the encrypted key
	ByteString IV = encryptedKey.substr(8, aes->getBlockSize());

	// Now, take the encrypted data from the encrypted key
	ByteString encryptedKeyData = encryptedKey.substr(8 + aes->getBlockSize());

	// Derive the PBE key
	AESKey* pbeKey = NULL;

	if (!RFC4880::PBEDeriveKey(passphrase, salt, &pbeKey))
	{
		return false;
	}

	// Decrypt the key data
	ByteString decryptedKeyData;
	ByteString finalBlock;

	// NOTE: The login will fail here if incorrect passphrase is supplied
	if (!aes->decryptInit(pbeKey, SymMode::CBC, IV) ||
	    !aes->decryptUpdate(encryptedKeyData, decryptedKeyData) ||
	    !aes->decryptFinal(finalBlock))
	{
		delete pbeKey;

		return false;
	}

	delete pbeKey;

	decryptedKeyData += finalBlock;

	// Check the magic
	if (decryptedKeyData.substr(0, 3) != magic)
	{
		// The passphrase was incorrect
		DEBUG_MSG("Incorrect passphrase supplied");

		return false;
	}

	// Strip off the magic
	ByteString key = decryptedKeyData.substr(3);

	// And mask the key
	decryptedKeyData.wipe();

	MutexLocker lock(dataMgrMutex);
	remask(key);

	return true;
}
예제 #2
0
// Set the SO PIN (requires either a blank SecureDataManager or the
// SO to have logged in previously)
bool SecureDataManager::setSOPIN(const ByteString& soPIN)
{
	// Check the new PIN
	if (soPIN.size() == 0)
	{
		DEBUG_MSG("Zero length PIN specified");

		return false;
	}

	// Check if the SO needs to be logged in
	if ((soEncryptedKey.size() > 0) && !soLoggedIn)
	{
		DEBUG_MSG("SO must be logged in to change the SO PIN");

		return false;
	}

	// If no SO PIN was set, then this is a SecureDataManager for a blank token. This
	// means a new key has to be generated
	if (soEncryptedKey.size() == 0)
	{
		ByteString key;

		rng->generateRandom(key, 32);

		remask(key);
	}

	return pbeEncryptKey(soPIN, soEncryptedKey);
}
예제 #3
0
// Decrypt the supplied data
bool SecureDataManager::decrypt(const ByteString& encrypted, ByteString& plaintext)
{
	// Check the object logged in state
	if ((!userLoggedIn && !soLoggedIn) || (maskedKey.size() != 32))
	{
		return false;
	}

	// Do not attempt decryption of empty byte strings
	if (encrypted.size() == 0)
	{
		plaintext = ByteString("");
		return true;
	}

	AESKey theKey(256);
	ByteString unmaskedKey;

	{
		MutexLocker lock(dataMgrMutex);

		unmask(unmaskedKey);

		theKey.setKeyBits(unmaskedKey);

		remask(unmaskedKey);
	}

	// Take the IV from the input data
	ByteString IV = encrypted.substr(0, aes->getBlockSize());

	if (IV.size() != aes->getBlockSize())
	{
		ERROR_MSG("Invalid IV in encrypted data");

		return false;
	}

	ByteString finalBlock;

	if (!aes->decryptInit(&theKey, SymMode::CBC, IV) ||
	    !aes->decryptUpdate(encrypted.substr(aes->getBlockSize()), plaintext) ||
	    !aes->decryptFinal(finalBlock))
	{
		return false;
	}

	plaintext += finalBlock;

	return true;
}
예제 #4
0
void init_masked_round_keys(){
	//Mask[0] = m1
	//Mask[1] = m2
	//Mask[2] = m3
	//Mask[3] = m4
	//Mask[4] = m
	//Mask[5] = m'
	//Mask[6] = m1' = m5
	//Mask[7] = m2' = m6
	//Mask[8] = m3' = m7
	//Mask[9] = m4' = m8
	
	//	10th RK Mask m1'-m4' to Mask m
	remask(RoundKey_masked[10],Mask[6],Mask[7],Mask[8],Mask[9],Mask[4],Mask[4],Mask[4],Mask[4]);

	//	2nd-9th RK Mask m' to Mask m1-m4
	for(int i = 1; i<10;i++){
		remask(RoundKey_masked[i],Mask[0],Mask[1],Mask[2],Mask[3],Mask[5],Mask[5],Mask[5],Mask[5]); 
	}
	
	//1st RK Mask m' to 0
	remask(RoundKey_masked[0],0,0,0,0,Mask[5],Mask[5],Mask[5],Mask[5]); 
}
예제 #5
0
// Encrypt the supplied data
bool SecureDataManager::encrypt(const ByteString& plaintext, ByteString& encrypted)
{
	// Check the object logged in state
	if ((!userLoggedIn && !soLoggedIn) || (maskedKey.size() != 32))
	{
		return false;
	}

	AESKey theKey(256);
	ByteString unmaskedKey;

	{
		MutexLocker lock(dataMgrMutex);

		unmask(unmaskedKey);

		theKey.setKeyBits(unmaskedKey);

		remask(unmaskedKey);
	}

	// Wipe encrypted data block
	encrypted.wipe();

	// Generate random IV
	ByteString IV;

	if (!rng->generateRandom(IV, aes->getBlockSize())) return false;

	ByteString finalBlock;

	if (!aes->encryptInit(&theKey, SymMode::CBC, IV) ||
	    !aes->encryptUpdate(plaintext, encrypted) ||
	    !aes->encryptFinal(finalBlock))
	{
		return false;
	}

	encrypted += finalBlock;

	// Add IV to output data
	encrypted = IV + encrypted;

	return true;
}
예제 #6
0
// Generic function for creating an encrypted version of the key from the specified passphrase
bool SecureDataManager::pbeEncryptKey(const ByteString& passphrase, ByteString& encryptedKey)
{
	// Generate salt
	ByteString salt;

	if (!rng->generateRandom(salt, 8)) return false;

	// Derive the key using RFC4880 PBE
	AESKey* pbeKey = NULL;

	if (!RFC4880::PBEDeriveKey(passphrase, salt, &pbeKey))
	{
		return false;
	}

	// Add the salt
	encryptedKey.wipe();
	encryptedKey += salt;

	// Generate random IV
	ByteString IV;

	if (!rng->generateRandom(IV, aes->getBlockSize())) return false;

	// Add the IV
	encryptedKey += IV;

	// Encrypt the data
	ByteString block;

	if (!aes->encryptInit(pbeKey, SymMode::CBC, IV))
	{
		delete pbeKey;

		return false;
	}

	// First, add the magic
	if (!aes->encryptUpdate(magic, block))
	{
		delete pbeKey;

		return false;
	}

	encryptedKey += block;

	// Then, add the key itself
	ByteString key;

	{
		MutexLocker lock(dataMgrMutex);

		unmask(key);

		bool rv = aes->encryptUpdate(key, block);

		remask(key);

		if (!rv)
		{
			delete pbeKey;

			return false;
		}
	}

	encryptedKey += block;

	// And finalise encryption
	if (!aes->encryptFinal(block))
	{
		delete pbeKey;

		return false;
	}

	encryptedKey += block;

	delete pbeKey;

	return true;
}
예제 #7
0
//!!!MAIN FUNKTION!!!//
void inv_aes128(uint8_t state[16])
{	
	
	//Damn English - German Mix...
	//Firste define all Masks[1-10] 
	//then precalculate Sbox_masked and also the correct roundKeys
	
	//Try generating random sequence for Subbytes:
	uint8_t hiding_sequence[16];
	gen_random_sequence(hiding_sequence);
	
	init_masking();
	
	
	// 1.: Maskiert State mit m1'-m4'
	remask(state,Mask[6],Mask[7],Mask[8],Mask[9],0,0,0,0);
	
	//2.: Rundenschlüssel 11 (beinhalltet schon m1'-m4' und m
	// Maske m1'-m4' => m
    addRoundKey_masked(state, 10);  
	
	//3.: Maskierte Subbyte Operation
	// Maske M => m'
	//inv_subBytes_masked(state); // m => m'
	//inv_subBytes_masked_rand(state,hiding_sequence);
	//4.: Shiftrows
	// Maske m' => m' (bleibt natürlich gleich)
	//inv_shiftRows(state); // m' bleibt m'
	
	if(rand()%2 == 1){
		inv_subBytes_masked_rand(state,hiding_sequence);
		inv_shiftRows(state);
	}
	else{
		inv_shiftRows(state);
		inv_subBytes_masked_rand(state,hiding_sequence);
	}
	
	
	
	//Loop für Rundenschlüssel 10->2
    for (uint8_t i = 9; i > 0; i--) {
		
		//5.	Maske m' => m1-m4 
        addRoundKey_masked(state, i);	
		
		//6.	Maske m1-m4 -> m1'-m4'
		inv_mixColumns(state);			
		
		//7.	Maske m1'-m4' -> m
		remask(state,Mask[6],Mask[7],Mask[8],Mask[9],Mask[4],Mask[4],Mask[4],Mask[4]); 
		
		/*with Shuffling:*/
		//8.	Maske m => m'
		//inv_subBytes_masked(state);
		//9.	Maske m' bleibt m'
		//inv_shiftRows(state);
		//gen_random_sequence(hiding_sequence);
		if(rand()%2 == 1){
			inv_subBytes_masked_rand(state,hiding_sequence);
			inv_shiftRows(state);
		}
		else{
			inv_shiftRows(state);
			inv_subBytes_masked_rand(state,hiding_sequence);
		}
		/**/
		
    }
	
	//10. Addiert Rundenschlüssel 1:
	//Maske m' => 0
    addRoundKey_masked(state, 0);

	//Fertig:-)
}