void HmacImpl<HASH,DRBGINFO>::setSeedImpl(int seed)
    {
        ASSERT(DigestLength == m_v.size());
        ASSERT(DigestLength == m_k.size());

        // Has a catastrophic error been encountered previously? Forwarding facing gear is the gate keeper.
        ASSERT(!m_catastrophic);
        if(m_catastrophic)
            throw EncryptionException("A catastrophic error was previously encountered");

        try
        {
            setSeedImpl((const byte*)&seed, sizeof(seed));
        }
        catch(CryptoPP::Exception& ex)
        {
            m_catastrophic = true;
            throw EncryptionException(NarrowString("Internal error: ") + ex.what());
        } }
    void HashImpl<HASH, DRBGINFO>::HashReseed(const byte* seed, size_t ssize)
    {
        ASSERT(SeedLength == m_v.size());
        ASSERT(SeedLength == m_c.size());

        ASSERT(seed && ssize);
        if(!seed || !ssize)
            throw IllegalArgumentException("Unable to reseed hash drbg. The seed buffer or size is not valid");

        try
        {
            const size_t msize /*seed material size*/ = 1 + m_v.size() + SeedLength + ssize;
            size_t idx = 0;

            CryptoPP::SecByteBlock material(msize);
            material.data()[idx] = 0x01; idx++;

            ::memcpy(material.data()+idx, m_v.data(), m_v.size());
            idx += m_v.size();

            RandomPool::GetSharedInstance().GenerateBlock(material.data()+idx, SeedLength);
            idx += SeedLength;

            if(seed)
                ::memcpy(material.data()+idx, seed, ssize);

            HashDerivationFunction(material.data(), material.size(), m_v.data(), m_v.size());

            byte c[SeedLength+1];
            ByteArrayZeroizer z1(c, sizeof(c));

            HashInitBufferWithData(0x00, m_v.data(), m_v.size(), c, sizeof(c));
            HashDerivationFunction(c, sizeof(c), m_c.data(), m_c.size());

            m_rctr = 1;
        }
        catch(CryptoPP::Exception& ex)
        {
            m_catastrophic = true;
            throw EncryptionException(NarrowString("Internal error: ") + ex.what());
        }
    }
    void HashImpl<HASH, DRBGINFO>::HashDerivationFunction(const byte* data, size_t dsize, byte* hash, size_t hsize)
    {
        ASSERT(SeedLength == m_v.size());
        ASSERT(SeedLength == m_c.size());

        ASSERT(data && dsize);
        if(!data || !dsize)
            throw IllegalArgumentException("Unable to derive hash. The data buffer or size is not valid");

        ASSERT(hash && hsize);
        if(!hash || !hsize)
            throw IllegalArgumentException("Unable to derive hash. The hash buffer or size is not valid");

        static const unsigned int seedBits = SeedBits;
        byte counter = 1;

        try
        {
            size_t idx = 0, rem = hsize;
            while(rem)
            {
                m_hash.Update(&counter, 1);
                m_hash.Update((const byte*)&seedBits, sizeof(seedBits));
                m_hash.Update(data, dsize);

                // Though we call TruncatedFinal, full digest sizes are
                // retireved, except for possibly the last block. Note
                // that TruncatedFinal will reset the hash object.
                const size_t req = std::min(rem,(size_t)HASH::DIGESTSIZE);
                m_hash.TruncatedFinal(hash+idx, req);

                counter++;
                idx += req;
                rem -= req;
            }
        }
        catch(CryptoPP::Exception& ex)
        {
            m_catastrophic = true;
            throw EncryptionException(NarrowString("Internal error: ") + ex.what());
        }
    }
    void HmacImpl<HASH,DRBGINFO>::nextBytesImpl(byte bytes[], size_t size)
    {
        // Assert here. Parameters are validated in HmacGenerate()
        ASSERT(DigestLength == m_v.size());
        ASSERT(DigestLength == m_k.size());

        // Has a catastrophic error been encountered previously?
        ASSERT(!m_catastrophic);
        if(m_catastrophic)
            throw EncryptionException("A catastrophic error was previously encountered");

        ASSERT(bytes && size);
        if( !(bytes && size) )
            throw IllegalArgumentException("Unable to generate bytes from hash drbg. The buffer or size is not valid");

        ASSERT(m_rctr <= MaxReseed);
        if( !(m_rctr <= MaxReseed) )
            throw IllegalArgumentException("Unable to generate bytes from hash drbg. A reseed is required");

        ASSERT(size <= MaxRequest);
        if( !(size <= MaxRequest) )
            throw IllegalArgumentException("Unable to generate bytes from hash drbg. The requested size exceeds the maximum this DRBG can produce");

        try
        {
            // Set up a temporary so we don't leak bits on an exception
            CryptoPP::SecByteBlock temp(size);
            HmacGenerate(temp.data(), temp.size());

            ::memcpy(bytes, temp.data(), size);
        }
        catch(CryptoPP::Exception& ex)
        {
            m_catastrophic = true;
            throw EncryptionException(NarrowString("Internal error: ") + ex.what());
        }
    }
    void HashImpl<HASH, DRBGINFO>::HashGenerateHelper(byte* hash, size_t hsize)
    {
        ASSERT(SeedLength == m_v.size());

        ASSERT(hash && hsize);
        if( !hash || !hsize )
            throw IllegalArgumentException("Unable to reseed the hash drbg. The seed buffer or size is not valid");

        try
        {
            byte data[SeedLength];
            ByteArrayZeroizer z1(data, sizeof(data));

            ::memcpy(data, m_v.data(), m_v.size());
            size_t idx = 0, rem /*remaining*/ = hsize;

            // Write the string W directly into the provided buffer
            // (10.1.1.4 forms W = w_1 || w_2 || ... || w_i)
            while(rem)
            {
                const size_t req = std::min(rem, (size_t)HASH::DIGESTSIZE);
                m_hash.Update(data, sizeof(data));
                m_hash.TruncatedFinal(hash+idx, req);

                static const int one = 1;
                CascadingAddModPower2(data, sizeof(data), (const byte*)&one, sizeof(one));

                idx += req;
                rem -= req;
            }
        }
        catch(CryptoPP::Exception& ex)
        {
            m_catastrophic = true;
            throw EncryptionException(NarrowString("Internal error: ") + ex.what());
        }
    }
    void HmacImpl<HASH,DRBGINFO>::HmacInstantiate(const byte* seed, size_t ssize)
    {
        ASSERT(DigestLength == m_v.size());
        ASSERT(DigestLength == m_k.size());

        ASSERT(seed && ssize);
        if(!seed || !ssize)
            throw IllegalArgumentException("Unable to instatiate hmac drbg. The seed buffer or size is not valid");

        try
        {
            ::memset(m_k.data(), 0x00, m_k.size());
            ::memset(m_v.data(), 0x01, m_v.size());

            m_hmac.SetKey(m_k.data(), m_k.size());

            HmacUpdate(seed, ssize);
        }
        catch(CryptoPP::Exception& ex)
        {
            m_catastrophic = true;
            throw EncryptionException(NarrowString("Internal error: ") + ex.what());
        }
    }
    void HmacImpl<HASH,DRBGINFO>::setSeedImpl(const byte seed[], size_t size)
    {
        ASSERT(DigestLength == m_v.size());
        ASSERT(DigestLength == m_k.size());

        // Has a catastrophic error been encountered previously? Forwarding facing gear is the gate keeper.
        ASSERT(!m_catastrophic);
        if(m_catastrophic)
            throw EncryptionException("A catastrophic error was previously encountered");

        ASSERT(seed && size);
        if(!seed || !size)
            throw IllegalArgumentException("Unable to reseed the hmac drbg. The seed buffer or size is not valid");

        try
        {
            HmacReseed(seed, size);
        }
        catch(CryptoPP::Exception& ex)
        {
            m_catastrophic = true;
            throw EncryptionException(NarrowString("Internal error: ") + ex.what());
        }
    }
Esempio n. 8
0
// Called when the dll is loaded
extern "C" __declspec(dllexport) void OnLoad()
{
    srand(GetTickCount());
    g_PrintStream.reset(new halo::CHaloPrintStream());
    *g_PrintStream << L"44656469636174656420746f206d756d2e2049206d69737320796f752e" << endl;
    LocateDirectories();

    QueryPerformanceFrequency(&g_FrequencyMs);
    g_FrequencyMs.QuadPart /= 1000; // we want milliseconds

    // can't rename phasor log for startup errors via earlyinit
    CLoggingStream PhasorLog(g_LogsDirectory, L"PhasorLog", g_OldLogsDirectory);

    try
    {
        PhasorLog << L"Initializing Phasor ... " << endl;

        PhasorLog << L"Locating Halo addresses and structures" << endl;
        DWORD ticks = GetTickCount();
        Addresses::LocateAddresses();
        //PhasorLog << L"Finished in " << GetTickCount() - ticks << " ticks" << endl;

        PhasorLog << L"Installing crash handler..." << endl;
        CrashHandler::InstallCatchers();

        halo::server::maploader::Initialize(PhasorLog);
        PhasorLog << L"Building gametype list..." << endl;
        if (!halo::server::gametypes::BuildGametypeList())
            PhasorLog << L"    No gametypes were found!" << endl;

        halo::InstallHooks();

        if (!g_Thread.run()) {
            throw std::exception("cannot start the auxiliary thread.");
        }

        // Initialize the other logs
        g_PhasorLog.reset(new CThreadedLogging(PhasorLog, g_Thread, 0));
        g_ScriptsLog.reset(new CThreadedLogging(
            g_LogsDirectory, L"ScriptsLog", g_OldLogsDirectory, g_Thread, 0));
        //	g_ScriptsLog->EnableTimestamp(false);
        g_GameLog.reset(new CGameLog(g_LogsDirectory, L"GameLog", g_Thread));
        g_RconLog.reset(new CThreadedLogging(g_LogsDirectory, L"RconLog", g_OldLogsDirectory, g_Thread));
        scriptOutput.reset(new Forwarder(*g_PrintStream, Forwarder::end_point(*g_ScriptsLog)));

        // Initialize scripting system
        g_Scripts.reset(new scripting::ScriptHandler(NarrowString(g_ScriptsDirectory), *scriptOutput));

        // Load all scripts in scripts\\persistent
        PhasorLog << "Loading persistent scripts" << endl;
        g_Scripts->loadPersistentScripts();

        PhasorLog << L"Processing earlyinit.txt" << endl;
        LoadEarlyInit(PhasorLog);

        PhasorLog << L"Initializing admin system" << endl;
        Admin::initialize(&PhasorLog);

        PhasorLog << L"Initializing alias system" << endl;
        halo::alias::Initialize();

        PhasorLog << L"Phasor was successfully initialized." << endl;
    } catch (std::exception& e)
    {
        PhasorLog << "Phasor cannot be loaded because : " <<  e.what() << endl;
        *g_PrintStream << "Phasor cannot be loaded because : " <<  e.what() << endl;
        WAIT_AND_QUIT
    } catch (...)
    {
        static const std::wstring err = L"An unknown error occurred which prevented Phasor from loading";
        PhasorLog << err << endl;
        *g_PrintStream << err << endl;
        WAIT_AND_QUIT
    }
}
    void HmacImpl<HASH,DRBGINFO>::HmacGenerate(byte* hash, size_t hsize)
    {
        ASSERT(DigestLength == m_v.size());
        ASSERT(DigestLength == m_k.size());

        ASSERT(hash && hsize);
        ASSERT(m_rctr <= MaxReseed);
        ASSERT(hsize <= MaxRequest);

        ASSERT(hash && hsize);
        if( !hash || !hsize )
            throw IllegalArgumentException("Unable to generate bytes from hmac drbg. The hash buffer or size is not valid");

        /////////////////////////////////////////////////////////
        // Sanity check, Step 1
        /////////////////////////////////////////////////////////
        ASSERT(m_rctr <= MaxReseed);
        if( !(m_rctr <= MaxReseed) )
            throw IllegalArgumentException("Unable to generate bytes from hmac drbg. A reseed is required");

        /////////////////////////////////////////////////////////
        // Sanity check, Table 2
        /////////////////////////////////////////////////////////
        ASSERT(hsize <= MaxRequest);
        if( !(hsize <= MaxRequest) )
            throw IllegalArgumentException("Unable to generate bytes from hmac drbg. The requested size exceeds the maximum this DRBG can produce");

        /////////////////////////////////////////////////////////
        // We don't accept additional input, Steps 2 & 3 omitted
        /////////////////////////////////////////////////////////

        try
        {
            /////////////////////////////////////////////////////////
            // Generate bits, Step 4
            /////////////////////////////////////////////////////////
            size_t idx = 0, rem /*remaining*/ = hsize;
            while(rem)
            {
                /////////////////////////////////////////////////////////
                // Update V, Step 4.1
                /////////////////////////////////////////////////////////
                m_hmac.Update(m_v.data(), m_v.size());
                m_hmac.TruncatedFinal(m_v.data(), m_v.size());

                /////////////////////////////////////////////////////////
                // Copy out, Step 4.2 and 5
                /////////////////////////////////////////////////////////
                const size_t req = std::min(rem, (size_t)CryptoPP::HMAC<HASH>::DIGESTSIZE);
                ::memcpy(hash+idx, m_v.data(), req);

                idx += req;
                rem -= req;
            }

            /////////////////////////////////////////////////////////
            // Update V, Step 6
            /////////////////////////////////////////////////////////
            m_hmac.Update(m_v.data(), m_v.size());
            m_hmac.TruncatedFinal(m_v.data(), m_v.size());

            /////////////////////////////////////////////////////////
            // Update reseed counter, Step 7
            /////////////////////////////////////////////////////////
            m_rctr++;
        }
        catch(CryptoPP::Exception& ex)
        {
            m_catastrophic = true;
            throw EncryptionException(NarrowString("Internal error: ") + ex.what());
        }
    }
 NarrowString HTMLEntityCodec::REPLACEMENT_CHAR()
 {
   return NarrowString("\xFF\xDD");
 }
 /**
  * The default secure random number generator (RNG) algorithm. Currently returns
  * SHA-256. SHA-1 is approved for Random Number Generation. See SP 800-57, Table 2.
  */
 NarrowString SecureRandom::DefaultAlgorithm()
 {
     return NarrowString("SHA-256");
 }