// 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; }
// 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); }
// 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; }
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]); }
// 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; }
// 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; }
//!!!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:-) }