00001
00045 #include "hexfile.h"
00046 #include <sstream>
00047 #include <iomanip>
00048 #include <string>
00049 #include <stdexcept>
00050 #include <vector>
00051 #include <fstream>
00052 #include <algorithm>
00053
00054
00055
00057 class ParameterParser
00058 {
00059 private:
00060 std::string m_filename;
00061 size_t m_keySize;
00062 size_t m_serialNoSize;
00063 size_t m_counterSize;
00064 std::vector< byte > m_sharedKey;
00065 std::vector< byte > m_secretKey;
00066 std::vector< byte > m_serialNo;
00067 std::vector< byte > m_counterValue;
00068
00070 std::vector< byte > ParseHexString( const std::string & hexString ) const;
00072 std::string CreateHexString( const std::vector< byte > & byteVector ) const;
00073
00074 public:
00076 ParameterParser( size_t argc, const char * * argv );
00077 ~ParameterParser() {}
00078
00079
00080
00081
00082 const std::string & GetFilename() const { return m_filename; }
00083 size_t GetKeySize() const { return m_keySize; }
00084 size_t GetSerialNoSize() const { return m_serialNoSize; }
00085 size_t GetCounterSize() const { return m_counterSize; }
00086 const std::vector< byte > & GetSharedKey() const { return m_sharedKey; }
00087 const std::vector< byte > & GetSecretKey() const { return m_secretKey; }
00088 const std::vector< byte > & GetSerialNo() const { return m_serialNo; }
00089 const std::vector< byte > & GetCounterValue() const { return m_counterValue; }
00090
00091 std::string GetSharedKeyString() const { return CreateHexString( GetSharedKey() ); }
00092 std::string GetSecretKeyString() const { return CreateHexString( GetSecretKey() ); }
00093 std::string GetSerialNoString() const { return CreateHexString( GetSerialNo() ); }
00094 std::string GetCounterValueString() const { return CreateHexString( GetCounterValue() ); }
00095 };
00096
00097
00098
00099 std::vector< byte > ParameterParser::ParseHexString( const std::string & hexString ) const
00100 {
00101
00102 if( hexString.size() % 2 != 0 ) {
00103 throw std::runtime_error( "Hex string does not have even character count" );
00104 }
00105
00106
00107
00108
00109 std::vector< byte > bytes;
00110 for( size_t idx = 0; idx < hexString.size(); idx += 2 ) {
00111 std::istringstream iss( hexString.substr( idx, 2 ) );
00112 byte data;
00113 iss >> std::hex >> data;
00114 if( !iss ) {
00115 throw std::runtime_error( "Error parsing hex string \"" + hexString + "\"" );
00116 }
00117 bytes.push_back( data );
00118 }
00119 return bytes;
00120 }
00121
00122
00123
00124 std::string ParameterParser::CreateHexString( const std::vector< byte > & byteVector ) const
00125 {
00126 std::ostringstream oss;
00127 oss << std::setfill('0') << std::hex;
00128
00129
00130 for( size_t idx = 0; idx < byteVector.size() - 1; ++idx ) {
00131 oss << std::setw(2) << byteVector.at( idx ) << ' ';
00132 }
00133
00134
00135 if( byteVector.size() > 0 ) {
00136 oss << std::setw(2) << byteVector.at( byteVector.size()-1 );
00137 }
00138
00139 return oss.str();
00140 }
00141
00142
00143
00144 ParameterParser::ParameterParser( size_t argc, const char * * argv )
00145 {
00146
00147 if( argc != 9 ) {
00148 std::cout << "Parameters:\n"
00149 " filename - Filename for resulting Intel HEX file\n"
00150 " keysize - Size in bits of the AES secret and shared keys (128, 192 or 256)\n"
00151 " serialnosize - Size in bytes of the serial number (1, 2 or 4)\n"
00152 " countersize - Size in bytes of the sequential counter (1, 2 or 4)\n"
00153 " sharedkey - Hex representation of the shared key (32, 48 or 64 digits)\n"
00154 " secretkey - Hex representation of the secret key (32, 48 or 64 digits)\n"
00155 " serialno - Hex representation of the serial number (2, 4 or 8 digits)\n"
00156 " countervalue - Hex representation of the current counter value (2, 4 or 8 digits)\n"
00157 << std::endl;
00158 throw std::runtime_error( "Not exactly 8 parameters" );
00159 }
00160
00161
00162
00163
00164 std::string arg1( argv[1] );
00165 std::istringstream arg2( argv[2] );
00166 std::istringstream arg3( argv[3] );
00167 std::istringstream arg4( argv[4] );
00168 std::string arg5( argv[5] );
00169 std::string arg6( argv[6] );
00170 std::string arg7( argv[7] );
00171 std::string arg8( argv[8] );
00172
00173
00174
00175
00176 m_filename = arg1;
00177
00178 arg2 >> m_keySize;
00179 if( !arg2 ) {
00180 throw std::runtime_error( "Error parsing key size argument" );
00181 }
00182
00183 arg3 >> m_serialNoSize;
00184 if( !arg3 ) {
00185 throw std::runtime_error( "Error parsing serial no size argument" );
00186 }
00187
00188 arg4 >> m_counterSize;
00189 if( !arg4 ) {
00190 throw std::runtime_error( "Error parsing counter size argument" );
00191 }
00192
00193 m_sharedKey = ParseHexString( arg5 );
00194 m_secretKey = ParseHexString( arg6 );
00195 m_serialNo = ParseHexString( arg7 );
00196 m_counterValue = ParseHexString( arg8 );
00197
00198
00199
00200
00201 if( m_keySize != 128 && m_keySize != 192 && m_keySize != 256 ) {
00202 throw std::runtime_error( "Key size is not 128, 192 or 256 bits" );
00203 }
00204
00205 if( m_serialNoSize != 1 && m_serialNoSize != 2 && m_serialNoSize != 4 ) {
00206 throw std::runtime_error( "Serial no is not 1, 2 or 4 bytes" );
00207 }
00208
00209 if( m_counterSize != 1 && m_counterSize != 2 && m_counterSize != 4 ) {
00210 throw std::runtime_error( "Counter is not 1, 2 or 4 bytes" );
00211 }
00212
00213 if( m_sharedKey.size() != m_keySize / 8 ) {
00214 throw std::runtime_error( "Shared key has invalid length" );
00215 }
00216
00217 if( m_secretKey.size() != m_keySize / 8 ) {
00218 throw std::runtime_error( "Secret key has invalid length" );
00219 }
00220
00221 if( m_serialNo.size() != m_serialNoSize ) {
00222 throw std::runtime_error( "Serial number has invalid length" );
00223 }
00224
00225 if( m_counterValue.size() != m_counterSize ) {
00226 throw std::runtime_error( "Counter value has invalid length" );
00227 }
00228 }
00229
00230
00231
00233 void CreateHEXFile( const ParameterParser & parser )
00234 {
00235 HEXFile hexData;
00236 std::ofstream outFile( parser.GetFilename().c_str() );
00237
00238
00239 HEXRecord serialNo;
00240 std::vector< byte > serialNoReversed = parser.GetSerialNo();
00241 std::reverse( serialNoReversed.begin(), serialNoReversed.end() );
00242 serialNo << serialNoReversed;
00243
00244
00245 HEXRecord counterValue;
00246 std::vector< byte > counterValueReversed = parser.GetCounterValue();
00247 std::reverse( counterValueReversed.begin(), counterValueReversed.end() );
00248 counterValue << counterValueReversed;
00249
00250
00251 HEXRecord secretKey;
00252 secretKey << parser.GetSecretKey();
00253
00254
00255 HEXRecord sharedKey;
00256 sharedKey << parser.GetSharedKey();
00257
00258
00259 hexData << serialNo << counterValue << secretKey << sharedKey;
00260
00261
00262 outFile << hexData;
00263 }
00264
00265
00266
00267 int main( size_t argc, const char * * argv )
00268 {
00269 try {
00270 const std::string endian( " (Byte order reversed in HEX file)" );
00271 ParameterParser parser( argc, argv );
00272 std::cout << "Filename : " << parser.GetFilename() << std::endl
00273 << "Key size : " << parser.GetKeySize() << std::endl
00274 << "Serial no size: " << parser.GetSerialNoSize() << std::endl
00275 << "Counter size : " << parser.GetCounterSize() << std::endl
00276 << "Shared key : " << parser.GetSharedKeyString() << std::endl
00277 << "Secret key : " << parser.GetSecretKeyString() << std::endl
00278 << "Serial no : " << parser.GetSerialNoString() << endian << std::endl
00279 << "Counter value : " << parser.GetCounterValueString() << endian << std::endl;
00280
00281 CreateHEXFile( parser );
00282 std::cout << std::endl << parser.GetFilename() << " created!" << std::endl;
00283
00284 } catch( const std::exception & e ) {
00285 std::cout << "Error: " << e.what() << std::endl;
00286 } catch(...) {
00287 std::cout << "Unknown error" << std::endl;
00288 }
00289 }
00290