bool decode(const char *data, uint32_t dataSize, const String& outFile, const std::string& pass, std::string& secretKey, bool doView, int *pSpinCount = 0) { ms::cfb::CompoundFile cfb(data, dataSize); cfb.put(); const std::string& encryptedPackage = GetContensByName(cfb, "EncryptedPackage"); // data const EncryptionInfo info(GetContensByName(cfb, "EncryptionInfo")); // xml if (pSpinCount) { *pSpinCount = info.spinCount; } info.put(); std::string decData; if (info.isStandardEncryption) { if (!decodeStandardEncryption(decData, encryptedPackage, info, pass, secretKey)) return false; } else { if (!decodeAgile(decData, encryptedPackage, info, pass, secretKey)) return false; } if (!doView) { DetectFormat(decData.c_str(), decData.size()); cybozu::File out; out.openW(outFile); out.write(decData.c_str(), decData.size()); } return true; }
void RandomPool::Stir() { for (int i=0; i<2; i++) { RandomPoolCipher cipher(key); CFBEncryption cfb(cipher, pool+pool.size-cipher.BlockSize()); cfb.ProcessString(pool, pool.size); memcpy(key, pool, key.size); } addPos = 0; getPos = key.size; }
void RandomPool::Stir() { // add these lines to be compatible with PGP's randpool.c // byteReverse((word32 *)pool.ptr, (word32 *)pool.ptr, pool.size); for (int i=0; i<2; i++) { RandomPoolCipher cipher(key); CFBEncryption cfb(cipher, pool+pool.size-cipher.BlockSize()); cfb.ProcessString(pool, pool.size); memcpy(key, pool, key.size); } // byteReverse((word32 *)pool.ptr, (word32 *)pool.ptr, pool.size); addPos = 0; getPos = key.size; }
void SHARKBase::InitEncryptionRoundKeys(const byte *key, unsigned int keyLen, unsigned int rounds, word64 *roundkeys) { // concatenate key enought times to fill a for (unsigned int i=0; i<(rounds+1)*8; i++) ((byte *)roundkeys)[i] = key[i%keyLen]; SHARKEncryption e; byte IV[8] = {0,0,0,0,0,0,0,0}; CFBEncryption cfb(e, IV); cfb.ProcessString((byte *)roundkeys, (rounds+1)*8); #ifdef IS_LITTLE_ENDIAN byteReverse(roundkeys, roundkeys, (rounds+1)*8); #endif roundkeys[rounds] = SHARKTransform(roundkeys[rounds]); }
inline std::string getSecretKey(const std::string& keyFile, const std::string& pass) { cybozu::Mmap m(keyFile); const char *data = m.get(); if (m.size() > 0xffffffff) { throw cybozu::Exception("getSecretKey:m.size") << m.size(); } const uint32_t dataSize = static_cast<uint32_t>(m.size()); const ms::Format format = ms::DetectFormat(data, dataSize); if (format != ms::fCfb) { throw cybozu::Exception("getSecretKey:bad format") << keyFile; } ms::cfb::CompoundFile cfb(data, dataSize); const EncryptionInfo info(GetContensByName(cfb, "EncryptionInfo")); // xml info.put(); if (info.isStandardEncryption) throw cybozu::Exception("getSecretKey:not support") << keyFile; std::string secretKey; if (!getAgileSecretKey(secretKey, info, pass)) throw cybozu::Exception("getSecretKey:can't get") << keyFile; return secretKey; }
void SHARK::Base::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int keyLen, unsigned int rounds) { AssertValidKeyLength(keyLen); AssertValidRounds(rounds); m_rounds = rounds; m_roundKeys.New(m_rounds+1); // concatenate key enought times to fill a for (unsigned int i=0; i<(m_rounds+1)*8; i++) ((byte *)m_roundKeys.begin())[i] = key[i%keyLen]; SHARK::Encryption e; e.InitForKeySetup(); byte IV[8] = {0,0,0,0,0,0,0,0}; CFB_Mode_ExternalCipher::Encryption cfb(e, IV); cfb.ProcessString((byte *)m_roundKeys.begin(), (m_rounds+1)*8); ConditionalByteReverse(BIG_ENDIAN_ORDER, m_roundKeys.begin(), m_roundKeys.begin(), (m_rounds+1)*8); m_roundKeys[m_rounds] = SHARKTransform(m_roundKeys[m_rounds]); if (dir == DECRYPTION) { unsigned int i; // transform encryption round keys into decryption round keys for (i=0; i<m_rounds/2; i++) std::swap(m_roundKeys[i], m_roundKeys[m_rounds-i]); for (i=1; i<m_rounds; i++) m_roundKeys[i] = SHARKTransform(m_roundKeys[i]); } #ifdef IS_LITTLE_ENDIAN m_roundKeys[0] = ByteReverse(m_roundKeys[0]); m_roundKeys[m_rounds] = ByteReverse(m_roundKeys[m_rounds]); #endif }