dear all
i have run a test case of AES-GCM mode but the result was not the same as
the specified in the GCM spec. i have attached the code that i have done
the expected result for the cipher text from the spec book should be
42831ec2217774244b7221b784d0d49c
e3aa212f2c02a4e035c17e2329aca12e
21d514b25466931c7d8f6a5aac84aa05
1ba30b396a0aac973d58e091473f5985
but the result that i got from the code was
key: FEFFE9928665731C6D6A8F9467308308
iv: CAFEBABEFACEDBADDECAF888
plain text:
d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
Decrypted and Verified data. Ready for use.
adata length: 40
pdata length: 120
adata: feedfacedeadbeeffeedfacedeadbeefabaddad2
pdata:
d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
cipher text:
CAFEBABEFACEDBADDECAF888FF8B1FD6EAC140F4 881310461B139733 0438BD45090F300F
7AEB282B91AB123D 05DF7910A037AF7C 6375574A83157B41 98ACD2AFF33779A4
BF5AA89965F1BCE2 ECCB54A7FE9188C4 819CC971FA19BE52 24BE9797F3AC150B
17EE392AA146D654 922F6ADEC04B26C7 316D37A07A014446 A3DCC2865704B049
D21A9D27DBAE4E5E E0FD01448DB5A10F
recovered adata length: 40
recovered pdata length: 120
recovered adata: feedfacedeadbeeffeedfacedeadbeefabaddad2
recovered pdata:
d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
any one help me tell me what i did wrong
thx allot for help
--
--
You received this message because you are subscribed to the "Crypto++ Users"
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at
http://www.cryptopp.com.
---
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/groups/opt_out.
/*
* GCM1.cc
*
* Created on: Feb 4, 2014
* Author: amirale32
*/
#include <iostream>
#include <string>
#include "cryptopp/hex.h"
#include "cryptopp/aes.h"
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
#include "cryptopp/cryptlib.h"
using CryptoPP::BufferedTransformation;
using CryptoPP::AuthenticatedSymmetricCipher;
#include "cryptopp/filters.h"
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
using CryptoPP::AES;
#include "cryptopp/gcm.h"
using CryptoPP::GCM;
using CryptoPP::GCM_TablesOption;
#include "assert.h"
using namespace std;
int main(int argc, char* argv[])
{
//KEY 0000000000000000000000000000000000000000000000000000000000000000
//IV 000000000000000000000000
//HDR 00000000000000000000000000000000
//PTX 00000000000000000000000000000000
//CTX cea7403d4d606b6e074ec5d3baf39d18
//TAG ae9b1771dba9cf62b39be017940330b4
// Test Vector 003
byte startkey[16] = {0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08};
byte key[16];
memcpy( key, startkey, sizeof(key) );
byte startiv[12] = {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88};
byte iv[12];
memcpy( iv, startiv, sizeof(iv) );
//
// byte key[32];
// memset( key, 0x0, sizeof(key));
// feffe9928665731c6d6a8f9467308308
// byte iv[12];
// memset( iv, 0x0, sizeof(iv));
string adata( 16, (char)0x00);
adata = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
string pdata( 16, (char)0x00);
pdata = "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39";
const int TAG_SIZE = 16;
// Encrypted, with Tag
string cipher, encoded;
// Recovered
string radata, rpdata;
// Pretty print
encoded.clear();
StringSource( key, sizeof(key), true,
new HexEncoder(
new StringSink( encoded )
) // HexEncoder
); // StringSource
cout << "key: " << encoded << endl;
// Pretty print
encoded.clear();
StringSource( iv, sizeof(iv), true,
new HexEncoder(
new StringSink( encoded )
) // HexEncoder
); // StringSource
cout << " iv: " << encoded << endl;
cout << endl;
/*********************************\
\*********************************/
try
{
cout << "plain text: " << pdata << endl;
GCM< AES >::Encryption e;
e.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
// Not required for GCM mode (but required for CCM mode)
// e.SpecifyDataLengths( adata.size(), pdata.size(), 0 );
AuthenticatedEncryptionFilter ef( e,
new StringSink( cipher ), false, TAG_SIZE
); // AuthenticatedEncryptionFilter
// AuthenticatedEncryptionFilter::ChannelPut
// defines two channels: "" (empty) and "AAD"
// channel "" is encrypted and authenticated
// channel "AAD" is authenticated
ef.ChannelPut( "AAD", (const byte*)adata.data(), adata.size() );
ef.ChannelMessageEnd("AAD");
// Authenticated data *must* be pushed before
// Confidential/Authenticated data. Otherwise
// we must catch the BadState exception
ef.ChannelPut( "", (const byte*)pdata.data(), pdata.size() );
ef.ChannelMessageEnd("");
// Pretty print
StringSource( cipher, true,
new HexEncoder( new StringSink( encoded ), true, 16, " " ) );
}
catch( CryptoPP::BufferedTransformation::NoChannelSupport& e )
{
// The tag must go in to the default channel:
// "unknown: this object doesn't support multiple channels"
cerr << "Caught NoChannelSupport..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::AuthenticatedSymmetricCipher::BadState& e )
{
// Pushing PDATA before ADATA results in:
// "GMC/AES: Update was called before State_IVSet"
cerr << "Caught BadState..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::InvalidArgument& e )
{
cerr << "Caught InvalidArgument..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
/*********************************\
\*********************************/
// Attack the first and last byte
//if( cipher.size() > 1 )
//{
// cipher[ 0 ] |= 0x0F;
// cipher[ cipher.size()-1 ] |= 0x0F;
//}
/*********************************\
\*********************************/
try
{
GCM< AES >::Decryption d;
d.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
// Break the cipher text out into it's
// components: Encrypted Data and MAC Value
string enc = cipher.substr( 0, cipher.length()-TAG_SIZE );
string mac = cipher.substr( cipher.length()-TAG_SIZE );
// Sanity checks
assert( cipher.size() == enc.size() + mac.size() );
assert( enc.size() == pdata.size() );
assert( TAG_SIZE == mac.size() );
// Not recovered - sent via clear channel
radata = adata;
// Object will not throw an exception
// during decryption\verification _if_
// verification fails.
//AuthenticatedDecryptionFilter df( d, NULL,
// AuthenticatedDecryptionFilter::MAC_AT_BEGIN );
AuthenticatedDecryptionFilter df( d, NULL,
AuthenticatedDecryptionFilter::MAC_AT_BEGIN |
AuthenticatedDecryptionFilter::THROW_EXCEPTION, TAG_SIZE );
// The order of the following calls are important
df.ChannelPut( "", (const byte*)mac.data(), mac.size() );
df.ChannelPut( "AAD", (const byte*)adata.data(), adata.size() );
df.ChannelPut( "", (const byte*)enc.data(), enc.size() );
// If the object throws, it will most likely occur
// during ChannelMessageEnd()
df.ChannelMessageEnd( "AAD" );
df.ChannelMessageEnd( "" );
// If the object does not throw, here's the only
// opportunity to check the data's integrity
bool b = false;
b = df.GetLastResult();
assert( true == b );
// Remove data from channel
string retrieved;
size_t n = (size_t)-1;
// Plain text recovered from enc.data()
df.SetRetrievalChannel( "" );
n = (size_t)df.MaxRetrievable();
retrieved.resize( n );
if( n > 0 ) { df.Get( (byte*)retrieved.data(), n ); }
rpdata = retrieved;
assert( rpdata == pdata );
// Hmmm... No way to get the calculated MAC
// mac out of the Decryptor/Verifier. At
// least it is purported to be good.
//df.SetRetrievalChannel( "AAD" );
//n = (size_t)df.MaxRetrievable();
//retrieved.resize( n );
//if( n > 0 ) { df.Get( (byte*)retrieved.data(), n ); }
//assert( retrieved == mac );
// All is well - work with data
//for (int i = 0 ; i<=)
cout << "Decrypted and Verified data. Ready for use." << endl;
cout << endl;
cout << "adata length: " << adata.size() << endl;
cout << "pdata length: " << pdata.size() << endl;
cout << endl;
cout << "adata: " << adata << endl;
cout << "pdata: " << pdata << endl;
cout << endl;
cout << "cipher text: " << endl << " " << encoded << endl;
cout << endl;
cout << "recovered adata length: " << radata.size() << endl;
cout << "recovered pdata length: " << rpdata.size() << endl;
cout << endl;
cout << "recovered adata: " << radata << endl;
cout << "recovered pdata: " << rpdata << endl;
cout << endl;
}
catch( CryptoPP::InvalidArgument& e )
{
cerr << "Caught InvalidArgument..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::AuthenticatedSymmetricCipher::BadState& e )
{
// Pushing PDATA before ADATA results in:
// "GMC/AES: Update was called before State_IVSet"
cerr << "Caught BadState..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::HashVerificationFilter::HashVerificationFailed& e )
{
cerr << "Caught HashVerificationFailed..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
/*********************************\
\*********************************/
return 0;
}