Remote Access Control


createrxhex.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 
00053 
00054 
00056 class ParameterParser
00057 {
00058 private:
00059         std::string m_filename; 
00060         size_t m_keySize; 
00061         size_t m_serialNoSize; 
00062         size_t m_counterSize; 
00063         std::vector< byte > m_sharedKey; 
00064         size_t m_maxTransmitters; 
00065 
00067         std::vector< byte > ParseHexString( const std::string & hexString ) const;
00069         std::string CreateHexString( const std::vector< byte > & byteVector ) const;
00070 
00071 public:
00073         ParameterParser( size_t argc, const char * * argv );
00074         ~ParameterParser() {}
00075 
00076         //
00077         // Query methods.
00078         //
00079         const std::string & GetFilename() const { return m_filename; }
00080         size_t GetKeySize() const { return m_keySize; }
00081         size_t GetSerialNoSize() const { return m_serialNoSize; }
00082         size_t GetCounterSize() const { return m_counterSize; }
00083         const std::vector< byte > & GetSharedKey() const { return m_sharedKey; }
00084         size_t GetMaxTransmitters() const { return m_maxTransmitters; }
00085 
00086         std::string GetSharedKeyString() const { return CreateHexString( GetSharedKey() ); }
00087 };
00088 
00089 
00090 
00091 std::vector< byte > ParameterParser::ParseHexString( const std::string & hexString ) const
00092 {
00093         // String must be even number of hex digits.
00094         if( hexString.size() % 2 != 0 ) {
00095                 throw std::runtime_error( "Hex string does not have even character count" );
00096         }
00097 
00098         //
00099         // Parse hex digit pairs and insert into byte vector.
00100         //
00101         std::vector< byte > bytes;
00102         for( size_t idx = 0; idx < hexString.size(); idx += 2 ) {
00103                 std::istringstream iss( hexString.substr( idx, 2 ) );
00104                 byte data;
00105                 iss >> std::hex >> data;
00106                 if( !iss ) {
00107                         throw std::runtime_error( "Error parsing hex string \"" + hexString + "\"" );
00108                 }
00109                 bytes.push_back( data );
00110         }
00111         return bytes;
00112 }
00113 
00114 
00115 
00116 std::string ParameterParser::CreateHexString( const std::vector< byte > & byteVector ) const
00117 {
00118         std::ostringstream oss;
00119         oss << std::setfill('0') << std::hex;
00120 
00121         // Add all byte last byte with spaces in between.
00122         for( size_t idx = 0; idx < byteVector.size() - 1; ++idx ) {
00123                 oss << std::setw(2) << byteVector.at( idx ) << ' ';
00124         }
00125 
00126         // Add last byte.
00127         if( byteVector.size() > 0 ) {
00128                 oss << std::setw(2) << byteVector.at( byteVector.size()-1 );
00129         }
00130 
00131         return oss.str();
00132 }
00133 
00134 
00135 
00136 ParameterParser::ParameterParser( size_t argc, const char * * argv )
00137 {
00138         // Check that argument count is valid.
00139         if( argc != 7 ) {
00140                 std::cout << "Parameters:\n"
00141                         "  filename        - Filename for resulting Intel HEX file\n"
00142                         "  keysize         - Size in bits of the AES secret and shared keys (128, 192 or 256)\n"
00143                         "  serialnosize    - Size in bytes of the serial number (1, 2 or 4)\n"
00144                         "  countersize     - Size in bytes of the sequential counter (1, 2 or 4)\n"
00145                         "  sharedkey       - Hex representation of the shared key (32, 48 or 64 digits)\n"
00146                         "  maxtransmitters - Maximum number of associated transmitters\n"
00147                         << std::endl;
00148                 throw std::runtime_error( "Not exactly 6 parameters" );
00149         }
00150 
00151         //
00152         // Create strings or string streams from argument character arrays.
00153         //
00154         std::string arg1( argv[1] ); // Filename
00155         std::istringstream arg2( argv[2] ); // Key size
00156         std::istringstream arg3( argv[3] ); // Serial no size
00157         std::istringstream arg4( argv[4] ); // Counter size
00158         std::string arg5( argv[5] ); // Shared key
00159         std::istringstream arg6( argv[6] ); // Max transmitters
00160 
00161         //
00162         // Copy string arguments and parse non-string arguments.
00163         //
00164         m_filename = arg1;
00165 
00166         arg2 >> m_keySize;
00167         if( !arg2 ) {
00168                 throw std::runtime_error( "Error parsing key size argument" );
00169         }
00170 
00171         arg3 >> m_serialNoSize;
00172         if( !arg3 ) {
00173                 throw std::runtime_error( "Error parsing serial no size argument" );
00174         }
00175 
00176         arg4 >> m_counterSize;
00177         if( !arg4 ) {
00178                 throw std::runtime_error( "Error parsing counter size argument" );
00179         }
00180 
00181         m_sharedKey = ParseHexString( arg5 );
00182 
00183         arg6 >> m_maxTransmitters;
00184         if( !arg6 ) {
00185                 throw std::runtime_error( "Error parsing max transmitters argument" );
00186         }
00187 
00188         //
00189         // Check argument validity.
00190         //
00191         if( m_keySize != 128 && m_keySize != 192 && m_keySize != 256 ) {
00192                 throw std::runtime_error( "Key size is not 128, 192 or 256 bits" );
00193         }
00194 
00195         if( m_serialNoSize != 1 && m_serialNoSize != 2 && m_serialNoSize != 4 ) {
00196                 throw std::runtime_error( "Serial no is not 1, 2 or 4 bytes" );
00197         }
00198 
00199         if( m_counterSize != 1 && m_counterSize != 2 && m_counterSize != 4 ) {
00200                 throw std::runtime_error( "Counter is not 1, 2 or 4 bytes" );
00201         }
00202 
00203         if( m_sharedKey.size() != m_keySize / 8 ) {
00204                 throw std::runtime_error( "Shared key has invalid length" );
00205         }
00206 }
00207 
00208 
00209 
00211 void CreateHEXFile( const ParameterParser & parser )
00212 {
00213         HEXFile hexData;
00214         std::ofstream outFile( parser.GetFilename().c_str() );
00215 
00216         // Prepare shared key bytes.
00217         HEXRecord sharedKey;
00218         sharedKey << parser.GetSharedKey();
00219 
00220         // Prepare transmitter count byte.
00221         HEXRecord transmitterCount;
00222         transmitterCount << ((byte) 0x00);
00223 
00224         // Prepare empty transmitter table entry.
00225         HEXRecord transmitterTableEntry;
00226         const size_t entrySize =
00227                 (parser.GetKeySize() / 8) +
00228                 parser.GetSerialNoSize() +
00229                 parser.GetCounterSize();
00230         for( size_t idx = 0; idx < entrySize; ++idx ) {
00231                 transmitterTableEntry << ((byte) 0xff); // Erased EEPROM cells.
00232         }
00233 
00234         // Add records to HEX file.
00235         hexData << sharedKey << transmitterCount;
00236         for( size_t idx = 0; idx < parser.GetMaxTransmitters(); ++idx ) {
00237                 hexData << transmitterTableEntry;
00238         }
00239 
00240         // Write to disk.
00241         outFile << hexData;
00242 }
00243 
00244 
00245 
00246 int main( size_t argc, const char * * argv )
00247 {
00248         try {
00249                 ParameterParser parser( argc, argv );
00250                 std::cout << "Filename        : " << parser.GetFilename() << std::endl
00251                         << "Key size        : " << parser.GetKeySize() << std::endl
00252                         << "Serial no size  : " << parser.GetSerialNoSize() << std::endl
00253                         << "Counter size    : " << parser.GetCounterSize() << std::endl
00254                         << "Shared key      : " << parser.GetSharedKeyString() << std::endl
00255                         << "Max transmitters: " << parser.GetMaxTransmitters() << std::endl;
00256 
00257                 CreateHEXFile( parser );
00258                 std::cout << std::endl << parser.GetFilename() << " created!" << std::endl;
00259 
00260         } catch( const std::exception & e ) {
00261                 std::cout << "Error: " << e.what() << std::endl;
00262         } catch(...) {
00263                 std::cout << "Unknown error" << std::endl;
00264         }
00265 }
00266 
@DOC_TITLE@
Generated on Fri Aug 8 11:02:21 2008 for AVR411 Secure Rolling Code Algorithm (PC Tools - createrxhex) by doxygen 1.4.7