Hi, I need some fresh eyes on this code as I can't seem to figure out the 
issue. (reason for such an old version: NuGet. katkevich and smasherprog 
have yet to update since that version)

Using this line of code, I get an 
exception:CryptoPP::HashVerificationFilter::HashVerificationFailed at 
memory location 0x0000006907DFBD90.
AuthenticatedDecryptionFilter ss(decr, new StringSink(decoded));

StringSource xx(encUser.Data.cryptoBuffer, ENCRYPTION_DECRYPTION_BUFFER_SIZE
, true, new Redirector(ss));



Using these lines of code
AuthenticatedDecryptionFilter ss(decr, new StringSink(decoded), CryptoPP::
SignatureVerificationFilter::Flags::DEFAULT_FLAGS, TAG_SIZE, CryptoPP::
BlockPaddingSchemeDef::ZEROS_PADDING);
StringSource xx(encUser.Data.cryptoBuffer, ENCRYPTION_DECRYPTION_BUFFER_SIZE
, true, new Redirector(ss));

ss.GetLastResult() returns fals, data failed authenication process


Any and all input would be helpful.



Full related code snippets below:

#define ENCRYPTION_DECRYPTION_BUFFER_SIZE 384
#define ENCRYPTION_DECRYPTION_KEYIV_BUMPER 24 




const int TAG_SIZE = 16;
const int iterations = 100000;




typedef struct USER_DATA
{
        int SecurityLevel;
        int MinutesAllowed;
        int MinutesUsed;
        time_t FirstOn;
        time_t LastOn;

        // user conditional status
        bool Probationary;
        bool Active;
        bool Deleted;

        unsigned char iv[16];

        // general privileges
        bool CanPostPMs;
        bool CanPostMsgs;
        bool CanUpload;
        bool CanDownload;
        bool CanUseDoors;
        bool CanIMUsers;
        bool CanIMSysop;

        // special privileges
        bool SysOp;
        bool CoSysOp;

        bool ManageMessages;
        bool ManageFiles;
        bool ManageDoors;
        bool ManageUsers;
        bool ManageMenus;
        bool ManageConfig;

        // Misc flags
        unsigned short MiscPermissions1;        // 2 bytes - SysOp defined
        unsigned short MiscPermissions2;        // 2 bytes - SysOp defined

        unsigned char iv[16];
        unsigned char key[16];

    union
    {
        struct USER_DATA_DETAILS
        {
            // username
            char username[(USERNAME_MAX_LENGTH + 1)];

            // Password Salt & HASH 
            char password[PASSWORD_STORAGE_SIZE];

            // contact info
            char firstName[(REAL_FIRST_NAME_MAX_LENGTH + 1)];
            char lastName[(REAL_LAST_NAME_MAX_LENGTH + 1)];
            char email[(EMAIL_MAX_LENGTH + 1)];

            // demographics
            char city[(CITY_MAX_LENGTH + 1)];
            char state[(STATE_MAX_LENGTH + 1)];
            char country[(COUNTRY_MAX_LENGTH + 1)];
        } Info;
        unsigned char cryptoBuffer[(ENCRYPTION_DECRYPTION_BUFFER_SIZE + 
ENCRYPTION_DECRYPTION_KEYIV_BUMPER)];
    } Data;
} USERDATA, *PUSERDATA;




bool Encrypt(USERDATA decUser, PUSERDATA encUser)
{
    bool success = true;
    string cipher;

    AutoSeededRandomPool prng;
    GCM<Serpent>::Encryption enc;

    try
    {
        // generate key and iv
        prng.GenerateBlock(encUser->key, ENCRYPTION_DECRYPTION_KEYIV_BUMPER
);
        prng.GenerateBlock(encUser->iv, ENCRYPTION_DECRYPTION_KEYIV_BUMPER);

        // set keys
        enc.SetKeyWithIV(encUser->key, Serpent::DEFAULT_KEYLENGTH, encUser->
iv, Serpent::BLOCKSIZE);

        // ENCRYPT it!
        //AuthenticatedEncryptionFilter ss(enc, new StringSink(cipher));
        AuthenticatedEncryptionFilter ss(enc, new StringSink(cipher), false, 
TAG_SIZE, CryptoPP::DEFAULT_CHANNEL, CryptoPP::BlockPaddingSchemeDef::
ZEROS_PADDING);
        StringSource xx(decUser.Data.cryptoBuffer, 
ENCRYPTION_DECRYPTION_BUFFER_SIZE, true, new Redirector(ss));

        //cout << endl<< "      data size: " << sizeof(USERDATA::Data.Info)
        //     << endl << "    cipher size: " << cipher.size()
        //     << endl << "    buffer size: " << 
sizeof(USERDATA::Data.cryptoBuffer)
        //     << endl << "pri struct size: " << sizeof(USERDATA)
        //     << endl << endl;

        memcpy(encUser->Data.cryptoBuffer, cipher.data(), cipher.size());
    }
    catch (const CryptoPP::Exception& e)
    {
        cerr << "ENCRYPT: " << e.what() << endl;
        success = false;
    }

    return (success);
}


bool Decrypt(USERDATA encUser, PUSERDATA decUser)
{
    bool success = true;
    string decoded;

    GCM<Serpent>::Decryption decr;

    try
    {
        decr.SetKeyWithIV(encUser.key, Serpent::DEFAULT_KEYLENGTH, encUser.
iv, Serpent::BLOCKSIZE);

        // DECRYPT it!
        //AuthenticatedDecryptionFilter ss(decr, new StringSink(decoded));
        AuthenticatedDecryptionFilter ss(decr, new StringSink(decoded), 
CryptoPP::SignatureVerificationFilter::Flags::DEFAULT_FLAGS, TAG_SIZE, 
CryptoPP::BlockPaddingSchemeDef::ZEROS_PADDING);
        StringSource xx(encUser.Data.cryptoBuffer, 
ENCRYPTION_DECRYPTION_BUFFER_SIZE, true, new Redirector(ss));

        if ((success = ss.GetLastResult()) == true)
        {
            memcpy(decUser->Data.cryptoBuffer, decoded.data(), sizeof(
USERDATA::Data.cryptoBuffer));
        }
        else
        {
            cerr << endl << "DECRYPT Problem: data failed authenication 
process"<< endl << endl;
        }
    }
    catch (const CryptoPP::Exception& e)
    {
        cerr << "DECRYPT: " << e.what() << endl;
        success = false;
    }
    return (success);
}





Now, the test code, as provided by the CryptoPP website for this GCM 
<Serpent> based encryption, works as intended.

void Test()
{
    AutoSeededRandomPool prng;

    SecByteBlock key(Serpent::DEFAULT_KEYLENGTH);


    prng.GenerateBlock(key, key.size());

    SecByteBlock iv(Serpent::BLOCKSIZE);
    prng.GenerateBlock(iv, iv.size());

    cout << "key length: " << Serpent::DEFAULT_KEYLENGTH << endl;
    cout << "key length (min): " << Serpent::MIN_KEYLENGTH << endl;
    cout << "key length (max): " << Serpent::MAX_KEYLENGTH << endl;
    cout << "block size: " << Serpent::BLOCKSIZE << endl;

    string plain = "GCM Mode Test Will this work right?" + string(12, '\0') 
+ "This is a test of the Emergency Broadcasting System";
    string cipher, encoded, recovered;

    /*********************************\
    \*********************************/

    // Pretty print key
    encoded.clear();
    StringSource ss1(key, key.size(), true,
        new HexEncoder(
            new StringSink(encoded)
        ) // HexEncoder
    ); // StringSource
    cout << "key: " << encoded << "\t" << encoded.size() << endl;

    // Pretty print iv
    encoded.clear();
    StringSource ss2(iv, iv.size(), true,
        new HexEncoder(
            new StringSink(encoded)
        ) // HexEncoder
    ); // StringSource
    cout << "iv: " << encoded << "\t" << encoded.size() << endl;

    /*********************************\
    \*********************************/

    try
    {
        cout << "plain text: " << plain << endl;

        GCM< Serpent >::Encryption e;
        e.SetKeyWithIV(key, Serpent::DEFAULT_KEYLENGTH, iv, Serpent::
BLOCKSIZE);

        // The StreamTransformationFilter adds padding
        //  as required. GCM and CBC Mode must be padded
        //  to the block size of the cipher.
        StringSource ss3(plain, true,
            new AuthenticatedEncryptionFilter(e,
                new StringSink(cipher)
            ) // StreamTransformationFilter      
        ); // StringSource
    }
    catch (const CryptoPP::Exception& e)
    {
        cerr << e.what() << endl;
        exit(1);
    }

    /*********************************\
    \*********************************/

    // Pretty print
    encoded.clear();
    StringSource ss4(cipher, true,
        new HexEncoder(
            new StringSink(encoded)
        ) // HexEncoder
    ); // StringSource
    cout << "cipher text: " << encoded << "\t" << encoded.size() << endl;

    /*********************************\
    \*********************************/

    try
    {
        GCM< Serpent >::Decryption d;
        d.SetKeyWithIV(key, key.size(), iv, iv.size());

        // The StreamTransformationFilter removes
        //  padding as required.
        StringSource ss5(cipher, true,
            new AuthenticatedDecryptionFilter(d,
                new StringSink(recovered)
            ) // StreamTransformationFilter
        ); // StringSource

        cout << "recovered text: " << recovered << endl;
    }
    catch (const CryptoPP::Exception& e)
    {
        cerr << e.what() << endl;
        exit(1);
    }

    cout << endl << endl
        << "length of cipher text: " << plain.length() << "\t size: " << 
plain.size() << endl
        << "     length of cipher: " << cipher.length() << "\t size: " << 
cipher.size() << endl
        << "  length of recovered: " << recovered.length() << "\t size: " << 
recovered.size() << endl
        << endl;
}



-- 
You received this message because you are subscribed to "Crypto++ Users". More 
information about Crypto++ and this group is available at 
http://www.cryptopp.com and 
http://groups.google.com/forum/#!forum/cryptopp-users.
--- 
You received this message because you are subscribed to the Google Groups 
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to