Remote Access Control


createtxhex.cpp

Go to the documentation of this file.
00001 // This file has been prepared for Doxygen automatic documentation generation.
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         // Query methods.
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         // String must be even number of hex digits.
00102         if( hexString.size() % 2 != 0 ) {
00103                 throw std::runtime_error( "Hex string does not have even character count" );
00104         }
00105 
00106         //
00107         // Parse hex digit pairs and insert into byte vector.
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         // Add all byte last byte with spaces in between.
00130         for( size_t idx = 0; idx < byteVector.size() - 1; ++idx ) {
00131                 oss << std::setw(2) << byteVector.at( idx ) << ' ';
00132         }
00133 
00134         // Add last byte.
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         // Check that argument count is valid.
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         // Create strings or string streams from argument character arrays.
00163         // 
00164         std::string arg1( argv[1] ); // Filename
00165         std::istringstream arg2( argv[2] ); // Key size
00166         std::istringstream arg3( argv[3] ); // Serial no size
00167         std::istringstream arg4( argv[4] ); // Counter size
00168         std::string arg5( argv[5] ); // Shared key
00169         std::string arg6( argv[6] ); // Secret key
00170         std::string arg7( argv[7] ); // Serial number
00171         std::string arg8( argv[8] ); // Counter Value
00172 
00173         //
00174         // Copy string arguments and parse non-string arguments.
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         // Check argument validity.
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         // Prepare serial number bytes.
00239         HEXRecord serialNo;
00240         std::vector< byte > serialNoReversed = parser.GetSerialNo();
00241         std::reverse( serialNoReversed.begin(), serialNoReversed.end() );
00242         serialNo << serialNoReversed;
00243 
00244         // Prepare counter value bytes.
00245         HEXRecord counterValue;
00246         std::vector< byte > counterValueReversed = parser.GetCounterValue();
00247         std::reverse( counterValueReversed.begin(), counterValueReversed.end() );
00248         counterValue << counterValueReversed;
00249 
00250         // Prepare secret key bytes.
00251         HEXRecord secretKey;
00252         secretKey << parser.GetSecretKey();
00253 
00254         // Prepare shared key bytes.
00255         HEXRecord sharedKey;
00256         sharedKey << parser.GetSharedKey();
00257 
00258         // Add records to HEX file.
00259         hexData << serialNo << counterValue << secretKey << sharedKey;
00260 
00261         // Write to disk.
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 
@DOC_TITLE@
Generated on Fri Aug 8 11:02:38 2008 for AVR411 Secure Rolling Code Algorithm (PC Tools - createtxhex) by doxygen 1.4.7