Пример #1
0
 /// <summary>
 /// Secondary genAIS that calls the first
 /// </summary>
 /// <param name="mainObjectFileName">File name of .out file</param>
 /// <param name="bootmode">String containing desired boot mode</param>
 /// <returns>an Array of bytes to write to create an AIS file</returns>
 public static Byte[] GenAIS( AISGen devAISGen,
                          List<String> inputFileNames,
                          String bootmode,
                          String iniData )
 {
     devAISGen.bootMode = (AisBootModes)Enum.Parse(typeof(AisBootModes), bootmode, true);
       Console.WriteLine("Chosen bootmode is {0}.", devAISGen.bootMode.ToString());
       return GenAIS(devAISGen, inputFileNames, iniData);
 }
Пример #2
0
        /// <summary>
        /// genAIS command.  Always use section-by-section CRC checks
        /// </summary>
        /// <param name="mainObjectFileName"></param>
        /// <param name="bootMode"></param>
        /// <returns>Bytes of the binary or text AIS command</returns>
        public static Byte[] GenAIS( AISGen devAISGen, 
                                 List<String> inputFileNames,
                                 IniFile iniFile )
        {
            UInt32 numWords;

              // Setup the binary writer to generate the temp AIS file
              devAISGen.devAISStream = new MemoryStream();
              using ( devAISGen.writer = new EndianBinaryWriter( devAISGen.devAISStream, devAISGen.devEndian) )
              {
            // List to keep track of loadable sections and their occupied memory ranges
            devAISGen.sectionMemory = new List<MemoryRange>();
            // Initiate list to keep track of the input files
            devAISGen.objectFiles   = new List<ObjectFile>();

            // Get data from the GENERAL INI Section
            GeneralIniSectionParse(devAISGen, iniFile);

            #region Main AIS Generation
            // ---------------------------------------------------------
            // ****************** BEGIN AIS GENERATION *****************
            // ---------------------------------------------------------
            Console.WriteLine("Begining the AIS file generation.");

            // Diaplay currently selected boot mode
            Console.WriteLine("AIS file being generated for bootmode: {0}.",Enum.GetName(typeof(AisBootModes),devAISGen.bootMode));

            // Write the premilinary header and fields (everything before first AIS command)
            devAISGen.InsertAISPreamble();
            Debug.DebugMSG("Preamble Complete");

            // Parse the INI sections in order, inserting needed AIS commands
            if (iniFile != null)
            {
              foreach(IniSection sec in iniFile.Sections)
              {
            InsertAISCommandViaINI(devAISGen, sec);
              }
              Debug.DebugMSG("INI parsing complete");
            }

            // Insert the object file passed in on the top-level (if it exists)
            if (inputFileNames != null)
            {
              foreach (String fn in inputFileNames)
              {
            String[] nameAndAddr = fn.Split('@');

            Debug.DebugMSG("Inserting file " + nameAndAddr[0]);

            if (!File.Exists(nameAndAddr[0]))
            {
              Console.WriteLine("ERROR: {0} does not exist. Aborting...", nameAndAddr[0]);
              return null;
            }

            if (nameAndAddr.Length == 2)
            {
              UInt32 loadAddr;

              nameAndAddr[1] = nameAndAddr[1].ToLower();

              if (nameAndAddr[1].StartsWith("0x"))
              {
                if (!UInt32.TryParse(nameAndAddr[1].Replace("0x", ""), NumberStyles.HexNumber, null, out loadAddr))
                {
                  Console.WriteLine("WARNING: Invalid address format, {0}. Ignoring...", nameAndAddr[1]);
                }
                else
                {
                  devAISGen.InsertAISObjectFile(nameAndAddr[0], loadAddr);
                }
              }
              else if (UInt32.TryParse(nameAndAddr[1], out loadAddr))
              {
                devAISGen.InsertAISObjectFile(nameAndAddr[0], loadAddr);
              }
              else
              {
                Console.WriteLine("WARNING: Invalid address format, {0}. Ignoring...", nameAndAddr[1]);
              }
            }
            else if (nameAndAddr.Length == 1)
            {
              // If we still have not had a valid entry point set, then use entry point from
              // first encountered non-binary file in the inputFileNames list
              if (devAISGen.entryPoint == 0xFFFFFFFF)
              {
                devAISGen.InsertAISObjectFile(nameAndAddr[0], true);
              }
              else
              {
                devAISGen.InsertAISObjectFile(nameAndAddr[0], false);
              }
            }
            else
            {
              Console.WriteLine("WARNING: Invalid filename format, {0}. Ignoring...", fn);
            }
              }

              Debug.DebugMSG("Main input file insertion complete.");
            }

            // If CRC type is for single CRC, send Request CRC now
            if (devAISGen.aisCRCType == AisCRCCheckType.SINGLE_CRC)
            {
              devAISGen.InsertAISRequestCRC();
            }

            // Insert closing JumpClose AIS command (issue warning)
            if (devAISGen.entryPoint == 0xFFFFFFFF)
            {
              // No valid entry point was ever set (issue warning)
              Console.WriteLine("WARNING: Entry point set to null pointer!");
              devAISGen.InsertAISJumpClose(0x00000000);
            }
            else
            {
              devAISGen.InsertAISJumpClose(devAISGen.entryPoint);
            }

            // Flush the data and then return to start
            devAISGen.devAISStream.Flush();
            devAISGen.devAISStream.Seek(0,SeekOrigin.Begin);

            Console.WriteLine("AIS file generation was successful.");
            // ---------------------------------------------------------
            // ******************* END AIS GENERATION ******************
            // ---------------------------------------------------------

              #endregion

            // Now create return Byte array based on tempAIS file and the bootmode
            EndianBinaryReader tempAIS_br = new EndianBinaryReader(devAISGen.devAISStream, Endian.LittleEndian);

            // Setup the binary reader object
            numWords = ((UInt32)tempAIS_br.BaseStream.Length) >> 2;
            devAISGen.AISData = new Byte[numWords << 2];   //Each word converts to 4 binary bytes

            Debug.DebugMSG("Number of words in the AIS output is {0}", numWords);

            // Copy the data to the output Byte array
            for (UInt32 i = 0; i < numWords; i++)
            {
              BitConverter.GetBytes(tempAIS_br.ReadUInt32()).CopyTo(devAISGen.AISData, i * 4);
            }

            // Close the binary reader
            tempAIS_br.Close();
              }

              // Dispose of all object files
              foreach (ObjectFile file in devAISGen.objectFiles)
              {
            try
            {
              file.Dispose();
            }
            catch (Exception e)
            {
              Console.WriteLine(e.Message);
            }
              }

              // Clean up any embedded file resources that may have been extracted
              EmbeddedFileIO.CleanUpEmbeddedFiles();

              // Return Byte Array
              return devAISGen.AISData;
        }
Пример #3
0
 /// <summary>
 /// genAIS command.  Always use section-by-section CRC checks
 /// </summary>
 /// <param name="mainObjectFileName"></param>
 /// <param name="bootMode"></param>
 /// <returns>Bytes of the binary or text AIS command</returns>
 public static Byte[] GenAIS( AISGen devAISGen,
                          List<String> inputFileNames,
                          String iniData )
 {
     return GenAIS(devAISGen, inputFileNames, new IniFile(iniData));
 }
Пример #4
0
 public static ObjectFile FindObjectFile(AISGen devAISGen, String fileName)
 {
     foreach (ObjectFile file in devAISGen.objectFiles)
       {
     if (file.FileName.Equals(fileName))
     {
       return file;
     }
       }
       return null;
 }
Пример #5
0
 public static ObjectSymbol FindSymbol(AISGen devAISGen, String symbolName)
 {
     ObjectSymbol sym = null;
       foreach (ObjectFile file in devAISGen.objectFiles)
       {
     sym = file.symFind(symbolName);
     if (sym != null) break;
       }
       return sym;
 }
Пример #6
0
        /// <summary>
        /// AIS COFF file Load command generation (loads all sections)
        /// </summary>
        /// <param name="cf">The COFFfile object that the section comes from.</param>
        /// <param name="devAISGen">The specific device AIS generator object.</param>
        /// <returns>retType enumerator indicating success or failure.</returns>
        private static retType AISSecureObjectFileLoad( AISGen devAISGen, ObjectFile file )
        {
            UInt32 loadedSectionCount = 0;

              // Check if object file already loaded
              if (FindObjectFile(devAISGen,file.FileName) != null)
              {
            return retType.FAIL;
              }

              // Ii this is a new file, let's add it to our list
              devAISGen.objectFiles.Add(file);

              // Make sure we have an endianness match be
              // FIXME - Is this a good idea, what about binary files?
              if (!devAISGen.devEndian.ToString().Equals(file.Endianness))
              {
            Console.WriteLine("Endianness mismatch. Device is {0} endian, Object file is {1} endian",
            devAISGen.devEndian.ToString(),
            file.Endianness);
            return retType.FAIL;
              }

              // Make sure the .TIBoot section is first (if it exists)
              ObjectSection firstSection = file.LoadableSections[0];
              for (int i = 1; i < file.LoadableSectionCount; i++)
              {
            if ((file.LoadableSections[i].name).Equals(".TIBoot"))
            {
              file.LoadableSections[0] = file.LoadableSections[i];
              file.LoadableSections[i] = firstSection;
              break;
            }
              }

              // Do all SECTION_LOAD commands
              for (Int32 i = 0; i < file.LoadableSectionCount; i++)
              {
            Boolean encryptSection = false;

            // Determine section encryption status
            if (devAISGen.sectionsToEncrypt != null)
            {
              if ( (devAISGen.sectionsToEncrypt.Length == 1) && devAISGen.sectionsToEncrypt[0].Equals("ALL"))
              {
            encryptSection = true;
            Console.WriteLine("Encrypting section {0}, since ALL was specified for encryptSections in ini file.",file.LoadableSections[i].name);
              }
              else
              {
            if ( Array.IndexOf(devAISGen.sectionsToEncrypt,file.LoadableSections[i].name) >= 0 )
            {
              encryptSection = true;
              Console.WriteLine("Encrypting section {0}, since it was explicitly specified in encryptSections in ini file.",file.LoadableSections[i].name);
            }
              }
            }

            // Perform secure section load
            if (AISSecureSectionLoad(devAISGen, file, file.LoadableSections[i], encryptSection) != retType.SUCCESS)
            {
              return retType.FAIL;
            }

            // Check for need to do TIBoot initialization
            if ( (loadedSectionCount == 0) && ((file.LoadableSections[i].name).Equals(".TIBoot")) )
            {
              devAISGen.InsertAISJump("_TIBootSetup");
              InsertAISSecureSignature(devAISGen);
            }

            loadedSectionCount++;
              }
              // End of SECTION_LOAD commands

              // Now that we are done with file contents, we can close it
              file.Close();

              return retType.SUCCESS;
        }
Пример #7
0
 public static ObjectFile FindFileWithSymbol(AISGen devAISGen, String symbolName)
 {
     foreach (ObjectFile file in devAISGen.objectFiles)
       {
     if (file.symFind(symbolName) != null)
     {
       return file;
     }
       }
       return null;
 }
Пример #8
0
        private static retType AISObjectFileLoad( AISGen devAISGen, ObjectFile file )
        {
            UInt32 loadedSectionCount = 0;

              // Check if object file already loaded
              if (FindObjectFile(devAISGen,file.FileName) != null)
              {
            return retType.FAIL;
              }

              // If this is a new file, let's add it to our list
              devAISGen.objectFiles.Add(file);

              if (!devAISGen.devEndian.ToString().Equals(file.Endianness))
              {
            Console.WriteLine("Endianness mismatch. Device is {0} endian, Object file is {1} endian",
            devAISGen.devEndian.ToString(),
            file.Endianness);
            return retType.FAIL;
              }

              // Make sure the .TIBoot section is first (if it exists)
              ObjectSection firstSection = file.LoadableSections[0];
              for (Int32 i = 1; i < file.LoadableSectionCount; i++)
              {
            if ((file.LoadableSections[i].name).Equals(".TIBoot"))
            {
              file.LoadableSections[0] = file.LoadableSections[i];
              file.LoadableSections[i] = firstSection;
              break;
            }
              }

              // Enable CRC if needed
              devAISGen.InsertAISEnableCRC();

              // Do all SECTION_LOAD commands
              for (Int32 i = 0; i < file.LoadableSectionCount; i++)
              {
            if (AISSectionLoad(devAISGen, file, file.LoadableSections[i]) != retType.SUCCESS)
            {
              return retType.FAIL;
            }

            // Check for need to do TIBoot initialization
            if (loadedSectionCount == 0)
            {
              devAISGen.InsertAISJump("_TIBootSetup");
            }

            loadedSectionCount++;
              }
              // End of SECTION_LOAD commands

              // Now that we are done with file contents, we can close it
              file.Close();

              return retType.SUCCESS;
        }
Пример #9
0
        private static retType AISSectionLoad( AISGen devAISGen, ObjectFile file, ObjectSection section)
        {
            Byte[] secData = file.secRead(section);
              Byte[] srcCRCData = new Byte[section.size + 8];

              Debug.DebugMSG("AISSectionLoad for section " + section.name + " from file " + file.FileName + ".");

              // If we are doing section-by-section CRC, then zero out the CRC value
              if (devAISGen.aisCRCType == AisCRCCheckType.SECTION_CRC)
              {
            devAISGen.devCRC.ResetCRC();
              }

              // Add section load to the output
              devAISGen.InsertAISSectionLoad((UInt32) section.loadAddr, (UInt32) section.size, secData);

              // Copy bytes to CRC byte array for future CRC calculation
              if (devAISGen.aisCRCType != AisCRCCheckType.NO_CRC)
              {
            if (devAISGen.devEndian != devAISGen.devAISEndian)
            {
              Endian.swapEndian(BitConverter.GetBytes(section.loadAddr)).CopyTo(srcCRCData, 0);
              Endian.swapEndian(BitConverter.GetBytes(section.size)).CopyTo(srcCRCData, 4);
            }
            else
            {
              BitConverter.GetBytes(section.loadAddr).CopyTo(srcCRCData, 0);
              BitConverter.GetBytes(section.size).CopyTo(srcCRCData, 4);
            }

              }

              // Now write contents to CRC array
              for (UInt32 k = 0; k < section.size; k+=4)
              {
            // Copy bytes to array for future CRC calculation
            if (devAISGen.aisCRCType != AisCRCCheckType.NO_CRC)
            {
              Byte[] temp = new Byte[4];
              Array.Copy(secData,k,temp,0,4);
              if (devAISGen.devEndian != devAISGen.devAISEndian)
              {
            Endian.swapEndian(temp).CopyTo(srcCRCData, (8 + k));
              }
              else
              {
            temp.CopyTo(srcCRCData, (8 + k));
              }
            }
              }

              // Add this section's memory range, checking for overlap
              AddMemoryRange(devAISGen, (UInt32) section.loadAddr, (UInt32) (section.loadAddr+section.size-1));

              // Perform CRC calculation of the section's contents
              if (devAISGen.aisCRCType != AisCRCCheckType.NO_CRC)
              {
            devAISGen.devCRC.CalculateCRC(srcCRCData);
            if (devAISGen.aisCRCType == AisCRCCheckType.SECTION_CRC)
            {
              // Write CRC request command, value, and jump value to temp AIS file
              devAISGen.InsertAISRequestCRC(((Int32)(-1) * (Int32)(section.size + 12 + 12)));
            }
              }

              return retType.SUCCESS;
        }
Пример #10
0
        /// <summary>
        /// SecureGenAIS command.
        /// </summary>
        /// <param name="inputFileNames">File name of input .out file</param>
        /// <param name="bootMode">AISGen Object for the particular device</param>
        /// <returns>Bytes of the binary or AIS boot image</returns>
        public static Byte[] SecureGenAIS(AISGen devAISGen,
                                      List<String> inputFileNames,
                                      IniFile iniFile)
        {
            UInt32 numWords;

              // Set defaults
              devAISGen.bootLoaderExitType      = BootLoaderExitType.NONE;
              devAISGen.currHashAlgorithmValue  = SHA_Algorithm.SHA1;
              devAISGen.sectionsToEncrypt       = null;
              devAISGen.rsaObject               = null;
              devAISGen.customerEncryptionKey   = null;
              devAISGen.keyEncryptionKey        = null;
              devAISGen.genericKeyHeaderData    = null;
              devAISGen.currHashAlgorithm       = null;

              // Setup the binary writer to generate the temp AIS file
              devAISGen.sigStream       = new MemoryStream();
              devAISGen.devAISStream    = new MemoryStream();
              devAISGen.sigWriter       = new EndianBinaryWriter( devAISGen.sigStream, devAISGen.devEndian);
              using ( devAISGen.writer  = new EndianBinaryWriter( devAISGen.devAISStream, devAISGen.devEndian) )
              {
            // List to keep track of loadable sections and their occupied memory ranges
            devAISGen.sectionMemory = new List<MemoryRange>();
            // Initiate list to keep track of the input files
            devAISGen.objectFiles   = new List<ObjectFile>();

            // Get data from the GENERAL INI Section
            GeneralIniSectionParse(devAISGen, iniFile);

            // Get data from the SECURITY INI Section
            if (SecurityIniSectionParse(devAISGen, iniFile) != retType.SUCCESS)
            {
              Console.WriteLine("Aborting...");
              return null;
            }

              #region Handle the case of Legacy boot mode
            if (devAISGen.bootMode == AisBootModes.LEGACY)
            {
              UInt32 fileSize = 0, secureDataSize = 0, totalImgSize = 0, paddingSize = 0;
              UInt32 loadAddr = 0, fileCount = 0;
              Byte[] fileData;

              String fileName = null;
              Boolean encryptSections = false;
              UInt32 entryPointAddr = 0x00000000;

              // Check for legacy input file
              foreach( IniSection sec in iniFile.Sections)
              {
            if (sec.sectionName.Equals("LEGACYINPUTFILE", StringComparison.OrdinalIgnoreCase))
            {
              fileCount++;
              foreach (DictionaryEntry de in sec.sectionValues)
              {
                // File name for binary section data
                if (((String)de.Key).Equals("FILENAME", StringComparison.OrdinalIgnoreCase))
                {
                   fileName = (String) sec.sectionValues["FILENAME"];
                }

                // Binary section's load address in the memory map
                if (((String)de.Key).Equals("LOADADDRESS", StringComparison.OrdinalIgnoreCase))
                {
                  loadAddr = (UInt32) sec.sectionValues["LOADADDRESS"];
                }

                // Binary section's entry point address in the memory map
                if (((String)de.Key).Equals("ENTRYPOINTADDRESS", StringComparison.OrdinalIgnoreCase))
                {
                  entryPointAddr = (UInt32) sec.sectionValues["ENTRYPOINTADDRESS"];
                }

                // Binary section's entry point address in the memory map
                if (((String)de.Key).Equals("ENCRYPT", StringComparison.OrdinalIgnoreCase))
                {
                  if (((String)sec.sectionValues["ENCRYPT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
                    encryptSections = true;
                  if (((String)sec.sectionValues["ENCRYPT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                    encryptSections = true;
                }

              }

              if (fileName == null)
              {
                Console.WriteLine("ERROR: File name must be provided in INPUTFILE section.");
                return null;
              }

              // Insert the file into the AIS image
              if (( entryPointAddr == 0x00000000))
              {
                Console.WriteLine("Entrypoint Address = {0} is not valid.", entryPointAddr);
                return null;
              }
            }
              }

              // Validate an input binary file was given in the INI file
              if (fileCount == 0)
              {
            Console.WriteLine("ERROR: You did not supply a binary file section in the INI file!");
            return null;
              }
              if (fileCount > 1)
              {
            Console.WriteLine("WARNING: You supplied too many binary file sections in the INI file.");
            Console.WriteLine("         Only using the first one.");
              }

              // Figure out the size of the secure data region (signature + keystruct)
              if (devAISGen.SecureType == AisSecureType.CUSTOM)
              {
            // On custom secure we have rsa keySize bits for signature and modulus of key struct,
            // plus eight additional bytes from key struct
            secureDataSize = (UInt32) (8 + (devAISGen.rsaObject.KeySize >> 3) + (devAISGen.rsaObject.KeySize >> 3));
              }
              else if (devAISGen.SecureType == AisSecureType.GENERIC)
              {
            // On generic secure we have 32 for key and HashSize bits rounded up to nearst 16 bytes
            // for signature data.
            secureDataSize = (UInt32) (32 + ((((devAISGen.currHashAlgorithm.HashSize >> 3)+15)>>4)<<4));
              }

              // Verify legacy input binary file exists, and get data if it does
              if (File.Exists(fileName))
              {
            Byte[] tempFileData = FileIO.GetFileData(fileName);

            fileSize = (UInt32) tempFileData.Length;

            totalImgSize = 16 + fileSize + secureDataSize;

            if (totalImgSize > 16*1024)
            {
              Console.WriteLine("WARNING: The input image is too large for the ROM boot loader.");
              Console.WriteLine("Reduce its size by {0} bytes.", (totalImgSize - (16*1024)));
            }

            // Figure out how much to pad input file region to acheive complete image ending on 1K boundary
            paddingSize = (((totalImgSize+1023) >> 10) << 10) - totalImgSize;

            // Copy to final data array of fileSize
            fileSize = fileSize + paddingSize;
            fileData = new Byte[fileSize];
            tempFileData.CopyTo(fileData,0);

            // Adjust total image size to final amount
            totalImgSize = 16 + fileSize + secureDataSize;
              }
              else
              {
            Console.WriteLine("Error: Binary file was not found!");
            return null;
              }

              if ( ((entryPointAddr & 0x00FFFFFF) < loadAddr) ||
               ((entryPointAddr & 0x00FFFFFF) > (loadAddr+fileSize)) )
              {
            Console.WriteLine("ERROR: Entry point falls outside load image region.");
            return null;
              }

              // Place header
              // Config Word - indicates total image size, nor width (if applicable)
              if (devAISGen.busWidth == 16)
              {
            devAISGen.writer.Write   ((UInt32)(((((totalImgSize >> 10)-1) & 0xFFFF) << 8)|(0x1 << 0)|(0x0 << 4)));
            devAISGen.sigWriter.Write((UInt32)(((((totalImgSize >> 10)-1) & 0xFFFF) << 8)|(0x1 << 0)|(0x0 << 4)));
              }
              else
              {
            devAISGen.writer.Write   ((UInt32)(((((totalImgSize >> 10)-1) & 0xFFFF) << 8)|(0x0 << 0)|(0x0 << 4)));
            devAISGen.sigWriter.Write((UInt32)(((((totalImgSize >> 10)-1) & 0xFFFF) << 8)|(0x0 << 0)|(0x0 << 4)));
              }

              // Magic Number   - indicates signed or encrypted
              if (encryptSections)
              {
            devAISGen.writer.Write((UInt32)SecureLegacyMagic.ENCMOD_MAGIC);
            devAISGen.sigWriter.Write((UInt32)SecureLegacyMagic.ENCMOD_MAGIC);
              }
              else
              {
            devAISGen.writer.Write((UInt32)SecureLegacyMagic.SIGNMOD_MAGIC);
            devAISGen.sigWriter.Write((UInt32)SecureLegacyMagic.SIGNMOD_MAGIC);
              }

              // Entry Point - where to jump within the image upon load
              devAISGen.writer.Write( entryPointAddr );
              devAISGen.sigWriter.Write( entryPointAddr );

              // SecureDataSize - size of data following image for key struct & signature
              devAISGen.writer.Write( (UInt32)secureDataSize );
              devAISGen.sigWriter.Write( (UInt32)secureDataSize );

              // Now place padded binary contents
              if (!encryptSections)
              {
            // Non-encrypted section
            devAISGen.writer.Write(fileData);
            devAISGen.sigWriter.Write(fileData);
              }
              else
              {
            // Encrypted section
            // Write unencrypted data to the signature buffer
            devAISGen.sigWriter.Write(fileData);

            // Encrypt data using CBC algorithm
            try
            {
              Byte[] encData = AesManagedUtil.AesCTSEncrypt(fileData,devAISGen.customerEncryptionKey,devAISGen.CEKInitialValue);

              // Write encrypted section data out to AIS data stream
              devAISGen.writer.Write(encData);
            }
            catch(Exception e)
            {
              Console.WriteLine("Exception during encryption operation: {0}",e.Message);
            }
              }

              // Now place the key data
              devAISGen.writer.Write(devAISGen.secureKeyData);
              devAISGen.sigWriter.Write(devAISGen.secureKeyData);

              // Finally place the signature which covers the entire image
              InsertAISSecureSignature( devAISGen );

              // Flush the data and then return to start
              devAISGen.devAISStream.Flush();
              devAISGen.devAISStream.Seek(0,SeekOrigin.Begin);

              devAISGen.sigStream.Close();
            }
              #endregion

              #region AIS Generation
            else
            {
              // ---------------------------------------------------------
              // ****************** BEGIN AIS GENERATION *****************
              // ---------------------------------------------------------
              Console.WriteLine("Begining the Secure AIS file generation.");

              // Diaplay currently selected boot mode
              Console.WriteLine("AIS file being generated for bootmode: {0}.",Enum.GetName(typeof(AisBootModes),devAISGen.bootMode));

              // Write the premilinary header and fields (everything before first AIS command)
              devAISGen.InsertAISPreamble();
              Debug.DebugMSG("Preamble Complete");

              // Write the Secure Key command and key data
              devAISGen.InsertAISSecureKeyLoad(devAISGen.secureKeyData);
              Debug.DebugMSG("Secure Key Insertion Complete");

              // Insert Exit Mode type
              devAISGen.InsertAISSetExitMode(devAISGen.bootLoaderExitType);
              Debug.DebugMSG("Set Exit Mode complete");

              // Parse the INI sections in order, inserting needed AIS commands
              foreach(IniSection sec in iniFile.Sections)
              {
            InsertSecureAISCommandViaINI(devAISGen, sec);
              }
              Debug.DebugMSG("INI parsing complete");

              // Insert the object file(s) passed in on the top-level (if it exists)
              foreach (String fn in inputFileNames)
              {
            String[] nameAndAddr = fn.Split('@');

            Debug.DebugMSG("Inserting file " + nameAndAddr[0]);

            if (!File.Exists(nameAndAddr[0]))
            {
              Console.WriteLine("ERROR: {0} does not exist. Aborting...", nameAndAddr[0]);
              return null;
            }

            // Handle binary files provided with a load address
            if (nameAndAddr.Length == 2)
            {
              UInt32 loadAddr;

              nameAndAddr[1] = nameAndAddr[1].ToLower();

              if (nameAndAddr[1].StartsWith("0x"))
              {
                if (!UInt32.TryParse(nameAndAddr[1].Replace("0x", ""), NumberStyles.HexNumber, null, out loadAddr))
                {
                  Console.WriteLine("WARNING: Invalid address format, {0}. Ignoring...", nameAndAddr[1]);
                }
                else
                {
                  devAISGen.InsertAISSecureObjectFile(nameAndAddr[0], loadAddr, false);
                }
              }
              else if (UInt32.TryParse(nameAndAddr[1], out loadAddr))
              {
                devAISGen.InsertAISSecureObjectFile(nameAndAddr[0], loadAddr, false);
              }
              else
              {
                Console.WriteLine("WARNING: Invalid address format, {0}. Ignoring...", nameAndAddr[1]);
              }
            }

            // Handle Object files (ones provided without load address)
            else if (nameAndAddr.Length == 1)
            {
              // If we still have not had a valid entry point set, then use entry point from
              // first encountered non-binary file in the inputFileNames list
              if (devAISGen.entryPoint == 0xFFFFFFFF)
              {
                devAISGen.InsertAISSecureObjectFile(nameAndAddr[0], true, false);
              }
              else
              {
                devAISGen.InsertAISSecureObjectFile(nameAndAddr[0], false, false);
              }
            }
            else
            {
              Console.WriteLine("WARNING: Invalid filename format, {0}. Ignoring...", fn);
            }
              }

              Debug.DebugMSG("Main input file insertion complete.");

              // Insert closing JumpClose AIS command (issue warning)
              if (devAISGen.entryPoint == 0x00000000)
              {
            Console.WriteLine("WARNING: Entry point set to null pointer!");
              }
              devAISGen.InsertAISJumpClose(devAISGen.entryPoint);

              // Insert final Signature
              InsertAISSecureSignature(devAISGen);

              // Flush the data and then return to start
              devAISGen.devAISStream.Flush();
              devAISGen.devAISStream.Seek(0,SeekOrigin.Begin);

              Console.WriteLine("AIS file generation was successful.");
              // ---------------------------------------------------------
              // ******************* END AIS GENERATION ******************
              // ---------------------------------------------------------
            }
              #endregion

            // Now create return byte array based on AIS Stream data
            EndianBinaryReader tempAIS_br = new EndianBinaryReader(devAISGen.devAISStream,Endian.LittleEndian);

            numWords = ((UInt32)tempAIS_br.BaseStream.Length) >> 2;
            devAISGen.AISData = new Byte[numWords << 2];   //Each word converts to 4 binary bytes

            Debug.DebugMSG("Number of words in the stream is {0}", numWords);

            // Copy the data to the output Byte array
            for (UInt32 i = 0; i < numWords; i++)
            {
              BitConverter.GetBytes(tempAIS_br.ReadUInt32()).CopyTo(devAISGen.AISData, i * 4);
            }

            // Close the binary reader
            tempAIS_br.Close();
              }

              // Dispose of all object files
              foreach (ObjectFile file in devAISGen.objectFiles)
              {
            try
            {
              file.Dispose();
            }
            catch (Exception e)
            {
              Console.WriteLine(e.Message);
            }
              }

              // Clean up any embedded file resources that may have been extracted
              EmbeddedFileIO.CleanUpEmbeddedFiles();

              // Return Byte Array
              return devAISGen.AISData;
        }
Пример #11
0
        private static void AddMemoryRange(AISGen devAISGen, UInt32 startAddr, UInt32 endAddr)
        {
            // Cycle through entire list looking for overlaps
              foreach (MemoryRange m in devAISGen.sectionMemory)
              {
            // Three issues:
            //   1) Both fall in occupied memory
            //   2) Input startAddr falls in occuppied memory, input endAddr does not
            //   3) Input endAddr falls in occuppied memory
            if ( ( (startAddr >= m.startAddr) && (startAddr <= m.endAddr) ) && ( (endAddr >= m.startAddr) && (endAddr <= m.endAddr) ) )
            {
              Console.WriteLine("WARNING: Memory overlap from 0x{0:X8} to 0x{1:X8}.",startAddr, endAddr);
              continue;
            }

            if ( (startAddr >= m.startAddr) && (startAddr <= m.endAddr) && (endAddr > m.endAddr) )
            {
              Console.WriteLine("WARNING: Memory overlap from 0x{0:X8} to 0x{1:X8}.",startAddr, m.endAddr);
              continue;
            }

            if ( (startAddr < m.startAddr) && (endAddr >= m.startAddr) && (endAddr <= m.endAddr) )
            {
              Console.WriteLine("WARNING: Memory overlap from 0x{0:X8} to 0x{1:X8}.",m.startAddr, endAddr);
              continue;
            }
              }

              // Add the MemoryRange for this section to the list
              devAISGen.sectionMemory.Add(new MemoryRange(startAddr,endAddr));
        }
Пример #12
0
        private static retType SecurityIniSectionParse(AISGen devAISGen, IniFile iniFile)
        {
            String currHashAlgorithmString = "SHA1";  // Default hash algorithm

              // Get data from the GENERAL INI Section
              IniSection sec = iniFile.GetSectionByName("Security");

            #region INI Section parsing
              if (sec != null)
              {
            foreach (DictionaryEntry de in sec.sectionValues)
            {
              // Security Type
              if (((String)de.Key).Equals("SECURITYTYPE", StringComparison.OrdinalIgnoreCase))
              {
            devAISGen.SecureType = (AisSecureType) Enum.Parse(typeof(AisSecureType), (String)sec.sectionValues["SECURITYTYPE"], true);
              }

              // Boot exit type
              if (((String)de.Key).Equals("BOOTEXITTYPE", StringComparison.OrdinalIgnoreCase))
              {
            devAISGen.bootLoaderExitType = (BootLoaderExitType) Enum.Parse(typeof(BootLoaderExitType), (String)sec.sectionValues["BOOTEXITTYPE"], true);
              }

              // Encrypted section settings
              if (((String)de.Key).Equals("ENCRYPTSECTIONS", StringComparison.OrdinalIgnoreCase))
              {
            Char[] separators = new Char[]{','};
            String encryptSections = (String)sec.sectionValues["ENCRYPTSECTIONS"];
            devAISGen.sectionsToEncrypt = encryptSections.Split(separators,StringSplitOptions.RemoveEmptyEntries);
            for( int k = 0; k<devAISGen.sectionsToEncrypt.Length; k++)
            {
              devAISGen.sectionsToEncrypt[k] = devAISGen.sectionsToEncrypt[k].Trim();
            }
              }

              // AES Encryption Key (CEK)
              if (((String)de.Key).Equals("ENCRYPTIONKEY", StringComparison.OrdinalIgnoreCase))
              {
            devAISGen.customerEncryptionKey = new Byte[16];
            devAISGen.rootCustomerEncryptionKey = null;
            devAISGen.CEKInitialValue = new Byte[16];
            devAISGen.rootCEKInitialValue = null;

            String keyString = (String)sec.sectionValues["ENCRYPTIONKEY"];
            if (keyString.Length != 32)
            {
              Console.WriteLine("AES Encryption Key is wrong length!");
              return retType.FAIL;
            }
            for (int j=0; j<keyString.Length; j+=2)
            {
              devAISGen.customerEncryptionKey[(j>>1)] = Convert.ToByte(keyString.Substring(j,2),16);
            }

            // Save base CEK key for restoring after delegate key removal
            devAISGen.rootCustomerEncryptionKey = devAISGen.customerEncryptionKey;

            // Generate IV as encrypted version of AES Key
            using (MemoryStream ms = new MemoryStream(devAISGen.CEKInitialValue))
            {
              Aes myAES = new AesManaged();
              myAES.KeySize = 128;
              myAES.Mode = CipherMode.ECB;
              myAES.Padding = PaddingMode.None;
              ICryptoTransform encryptor = myAES.CreateEncryptor(devAISGen.customerEncryptionKey, new Byte[16]);
              CryptoStream cs = new CryptoStream(ms,encryptor,CryptoStreamMode.Write);
              cs.Write(devAISGen.customerEncryptionKey,0,devAISGen.customerEncryptionKey.Length);
            }
            devAISGen.rootCEKInitialValue = devAISGen.CEKInitialValue;
              }

              // Key Encryption Key (not normally known, here for debug/testing purposes)
              if (((String)de.Key).Equals("KEYENCRYPTIONKEY", StringComparison.OrdinalIgnoreCase))
              {
            devAISGen.keyEncryptionKey = new Byte[16];
            String keyString = (String)sec.sectionValues["KEYENCRYPTIONKEY"];
            if (keyString.Length != 32)
            {
              Console.WriteLine("Key Encryption Key is wrong length!");
              return retType.FAIL;
            }
            for (int j=0; j<keyString.Length; j+=2)
            {
              devAISGen.keyEncryptionKey[(j>>1)] = Convert.ToByte(keyString.Substring(j,2),16);
            }
              }

              // Generic Secure Option to force JTAG off as part of the key loading
              if (((String)de.Key).Equals("GENERICJTAGFORCEOFF", StringComparison.OrdinalIgnoreCase))
              {
            if (((String)sec.sectionValues["GENERICJTAGFORCEOFF"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
              devAISGen.genericJTAGForceOff = true;
            else
              devAISGen.genericJTAGForceOff = false;
              }

              // Generic Secure Option to select the hash algorithm for signatures
              if (((String)de.Key).Equals("GENERICSHASELECTION", StringComparison.OrdinalIgnoreCase))
              {
            currHashAlgorithmString = (String)sec.sectionValues["GENERICSHASELECTION"];
            devAISGen.currHashAlgorithmValue = (SHA_Algorithm) Enum.Parse(typeof(SHA_Algorithm), currHashAlgorithmString, true);
              }

              // Generic Key Header file
              if (((String)de.Key).Equals("GENKEYHEADERFILENAME", StringComparison.OrdinalIgnoreCase))
              {
            String genKeyHeaderFileName = (String)sec.sectionValues["GENKEYHEADERFILENAME"];
            devAISGen.genericKeyHeaderData = new Byte[32];
            // Open file, read contents, copy to our AIS array
            using (FileStream tempFS = new FileStream(genKeyHeaderFileName, FileMode.Open, FileAccess.Read))
            {
              tempFS.Read(devAISGen.genericKeyHeaderData,0,32);
            }
              }

              // Custom Secure RSA Key File
              if (((String)de.Key).Equals("RSAKEYFILENAME", StringComparison.OrdinalIgnoreCase))
              {
            String rsaKeyFileName = (String)sec.sectionValues["RSAKEYFILENAME"];
            devAISGen.rsaObject = RSAKey.LoadFromFile(rsaKeyFileName);
            devAISGen.rootRsaObject = null;

            if (devAISGen.rsaObject == null)
            {
              Console.WriteLine("RSA key loading failed!");
              return retType.FAIL;
            }

            // Update the hash algo string if RSA key size is 2048 bits
            if (devAISGen.rsaObject.KeySize == 2048)
            {
              currHashAlgorithmString = "SHA256";
              devAISGen.currHashAlgorithmValue = SHA_Algorithm.SHA256;
            }

            // Save root public key reference for use after delegate key removal
            devAISGen.rootRsaObject = devAISGen.rsaObject;
              }
            }
              }
              else
              {
            sec = iniFile.GetSectionByName("SecureLegacy");
            if (sec != null)
            {
              devAISGen.bootMode = AisBootModes.LEGACY;
            }
            else
            {
              Console.WriteLine("INI file is missing a SECURITY or SECURELEGACY section.");
              return retType.FAIL;
            }
              }
            #endregion

            #region Security INI Input Validation
              // 2) Make sure a secure type has been specified
              if (devAISGen.SecureType == AisSecureType.NONE)
              {
            Console.WriteLine("ERROR: The device's security type was not specified!");
            return retType.FAIL;
              }
              else
              {
            Console.WriteLine("Creating boot image for a {0} secure device.",devAISGen.SecureType.ToString().ToLower());
            // 3) Make sure we have a CEK and IV
            if (devAISGen.customerEncryptionKey == null)
            {
              Console.WriteLine("ERROR: No encryption key was specified!");
              return retType.FAIL;
            }

            // 4) If custom secure, make sure we have an rsaObject
            if ((devAISGen.SecureType == AisSecureType.CUSTOM) && (devAISGen.rsaObject == null))
            {
              Console.WriteLine("ERROR: No RSA key file was specified!");
              return retType.FAIL;
            }

            // 5) Make sure RSA key size is supported
            if ((devAISGen.SecureType == AisSecureType.CUSTOM) && (devAISGen.rsaObject != null))
            {
              if ( (devAISGen.rsaObject.KeySize != 1024) && (devAISGen.rsaObject.KeySize != 2048) )
              {
            Console.WriteLine("ERROR: No RSA key size is invalid!");
            return retType.FAIL;
              }
              else
              {
            Console.WriteLine("INFO: RSA key is {0} bits.",devAISGen.rsaObject.KeySize);
              }
            }

            // 6) Specify Boot Exit type (if not legacy boot)
            if (devAISGen.bootMode != AisBootModes.LEGACY)
            {
              if (devAISGen.bootLoaderExitType == BootLoaderExitType.NONE)
              {
            Console.WriteLine("ERROR: No boot loader exit type was specified!");
            return retType.FAIL;
              }
              else
              {
            Console.WriteLine("INFO: Boot exit type has been selected as {0}.",devAISGen.bootLoaderExitType);
              }
            }

            // 7) If generic secure, make sure we have the CEK header info (or KEK though that's not typical use-case)
            if ( (devAISGen.SecureType == AisSecureType.GENERIC) &&
             (devAISGen.genericKeyHeaderData == null) &&
             (devAISGen.keyEncryptionKey == null) )
            {
              Console.WriteLine("WARNING: Encrypted Key Header data is absent - generating plaintext version. ");
              Console.WriteLine("         The Customer Encryption Key will be transferred in plaintext!  ");
            }

            // 8) Give warning if generic device and no sections are specified for encryption
            if (devAISGen.bootMode != AisBootModes.LEGACY)
            {
              if ((devAISGen.SecureType == AisSecureType.GENERIC) && (devAISGen.sectionsToEncrypt == null))
              {
            Console.WriteLine("WARNING: Generic Secure device was specified, but no input sections were indicated for encryption.");
            Console.WriteLine("         Only boot image signing will take place.");
              }
            }
              }

              // 9) Make sure valid hash algorithm was selected
              try
              {
            devAISGen.currHashAlgorithm = HashAlgorithm.Create(currHashAlgorithmString);
            Console.WriteLine("INFO: Current SHA algorithm is {0}.",devAISGen.currHashAlgorithmValue);
              }
              catch (Exception e)
              {
            Console.WriteLine("Invalid Hash Algorithm Selected. Exception message: {0}.",e.Message);
            return retType.FAIL;
              }
            #endregion

            #region Secure data/structure creation
              if ( devAISGen.SecureType == AisSecureType.GENERIC )
              {
            // Create our own key header
            devAISGen.secureKeyData = new Byte[32];
            Byte[] tempHeaderData   = new Byte[32];

            // Init with Random Data
            (new Random()).NextBytes(tempHeaderData);

            // Copy in the magic word for the generic key header structure
            BitConverter.GetBytes((UInt32)SecureLoadMagic.GENKEY_MAGIC).CopyTo(tempHeaderData, 0);

            // Insert JTAGForceOff word
            BitConverter.GetBytes( (UInt32) (devAISGen.genericJTAGForceOff ? 0x00000001 : 0x00000000) ).CopyTo(tempHeaderData, 4);

            // Insert Hash algorithm selection word
            BitConverter.GetBytes( (UInt32)devAISGen.currHashAlgorithmValue ).CopyTo(tempHeaderData, 8);

            // Insert key Data (at offset 16)
            devAISGen.customerEncryptionKey.CopyTo(tempHeaderData, 16);

            // If KEK is provided, use it to generate the header for the boot image
            if (devAISGen.keyEncryptionKey != null)
            {
              Byte[] iv = new Byte[16];
              using (MemoryStream ms = new MemoryStream(iv))
              {
            Aes myAES = new AesManaged();
            myAES.KeySize = 128;
            myAES.Mode = CipherMode.ECB;
            myAES.Padding = PaddingMode.None;
            ICryptoTransform encryptor = myAES.CreateEncryptor(devAISGen.keyEncryptionKey, new Byte[16]);
            CryptoStream cs = new CryptoStream(ms,encryptor,CryptoStreamMode.Write);
            cs.Write(devAISGen.keyEncryptionKey,0,devAISGen.keyEncryptionKey.Length);
              }

              Byte[] encSecureKeyData = new Byte[32];
              using (MemoryStream ms = new MemoryStream(encSecureKeyData))
              {
            Aes myAES = new AesManaged();
            myAES.KeySize = 128;
            myAES.Mode = CipherMode.CBC;
            myAES.Padding = PaddingMode.None;
            ICryptoTransform encryptor = myAES.CreateEncryptor(devAISGen.keyEncryptionKey, iv);
            CryptoStream cs = new CryptoStream(ms,encryptor,CryptoStreamMode.Write);
            cs.Write(tempHeaderData,0,32);
              }
            //#if (DEBUG)
              // For debug write the data out to file
              FileIO.SetFileData("gen_keyhdr_unencrypted.bin",tempHeaderData,true);
              FileIO.SetFileData("gen_keyhdr_encrypted.bin",encSecureKeyData,true);
            //#endif

              Array.Copy(encSecureKeyData,0,devAISGen.secureKeyData,0,32);
            }

            // We have a file being provided - use first 32 bytes of it
            else if ((devAISGen.genericKeyHeaderData != null) && (devAISGen.genericKeyHeaderData.Length >= 32))
            {
              Array.Copy(devAISGen.genericKeyHeaderData,0,devAISGen.secureKeyData,0,32);
            }

            // There is no KEK to create an encrypted header and no file is provided with key data
            // so let's just use our own unencrypted data
            else
            {
              Array.Copy(tempHeaderData,0,devAISGen.secureKeyData,0,32);
            }
              }
              else if ( devAISGen.SecureType == AisSecureType.CUSTOM )
              {
            // Create RPK Verify Struct
            devAISGen.secureKeyData = RSAKey.CreateCustomSecureKeyVerifyStruct(devAISGen.rsaObject);
              #if (DEBUG)
            // For debug write the data out to file
            FileIO.SetFileData("rpk_struct.bin",devAISGen.secureKeyData,true);

            // Calculate the SHA hash of the Root Public Key
            Byte[] digest = devAISGen.currHashAlgorithm.ComputeHash(devAISGen.secureKeyData);

            // Write the full hash of the RPK struct
            // For debug write the data out to file
            FileIO.SetFileData("rpk_hash_full.bin",digest,true);

            for (int i=16;i<digest.Length;i++)
            {
              digest[i-16] ^= digest[i];
            }

            // Write the expected MPK (hash of RPK structure truncated to 128 bits) in binary format to file mpk.bin
            Byte[] mpk = new Byte[16];
            Array.Copy(digest,0,mpk,0,16);
            // For debug write the data out to file
            FileIO.SetFileData("mpk.bin",mpk,true);
              #endif
              }

            #endregion

              return retType.SUCCESS;
        }
Пример #13
0
        /// <summary>
        /// Signature insertion creation and insertion routine
        /// </summary>
        public static retType InsertAISSecureSignature( AISGen devAISGen )
        {
            EndianBinaryWriter ebw = new EndianBinaryWriter(
              devAISGen.devAISStream,
              devAISGen.devEndian);

              // Make sure all data is present for signature calculation
              devAISGen.sigStream.Flush();

              // Reset stream to start
              devAISGen.sigStream.Position = 0;

            #if (DEBUG)
              // For debug write the data out to file
              Byte[] sigData = null;
              sigData = ((MemoryStream) devAISGen.sigStream).ToArray();
              FileIO.SetFileData("sig_data.bin",sigData,true);
            #endif

              // Calculate hash of data
              Byte[] hash = devAISGen.currHashAlgorithm.ComputeHash(devAISGen.sigStream);
              Console.WriteLine("\tSignature Hash: {0}", BitConverter.ToString(hash));
              Console.WriteLine("\tSignature Byte Count = {0}", devAISGen.sigStream.Length);
              Byte[] signatureData = null;

              // Generate signature via encryption
              if ( devAISGen.SecureType == AisSecureType.GENERIC )
              {
            signatureData = new Byte[32];

            // Fill signature data buffer with random bytes
            (new Random()).NextBytes(signatureData);

            // Copy calculated SHA hash into signature data buffer
            hash.CopyTo(signatureData,0);

            using (MemoryStream ms = new MemoryStream())
            {
              Aes myAES = new AesManaged();
              myAES.KeySize = 128;
              myAES.Mode = CipherMode.CBC;
              myAES.Padding = PaddingMode.None;
              ICryptoTransform encryptor = myAES.CreateEncryptor(devAISGen.customerEncryptionKey, devAISGen.CEKInitialValue);
              CryptoStream cs = new CryptoStream(ms,encryptor,CryptoStreamMode.Write);
              cs.Write(signatureData,0,signatureData.Length);
              cs.FlushFinalBlock();
              ms.ToArray().CopyTo(signatureData,0);
            }
              }
              else if ( devAISGen.SecureType == AisSecureType.CUSTOM )
              {

            RSAPKCS1SignatureFormatter rsaFormatter = new RSAPKCS1SignatureFormatter(devAISGen.rsaObject);

            // Create a signature for HashValue and return it.
            signatureData = rsaFormatter.CreateSignature(devAISGen.currHashAlgorithm);

            // Signature info needs to be revered to work with RSA functionality in ROM
            Array.Reverse(signatureData);
              }

              // Write the signature data to the output AIS binary writer
              ebw.Write(signatureData);

              // Clear the signature stream now that we have used the data for signature generation
              devAISGen.sigStream.SetLength(0);
              devAISGen.sigStream.Position = 0;

              return retType.SUCCESS;
        }
Пример #14
0
        /// <summary>
        /// AIS Section Load command generation
        /// </summary>
        /// <param name="cf">The COFFfile object that the section comes from.</param>
        /// <param name="secHeader">The Hashtable object of the section header to load.</param>
        /// <param name="devAISGen">The specific device AIS generator object.</param>
        /// <returns>retType enumerator indicating success or failure.</returns>
        private static retType AISSecureSectionLoad( AISGen devAISGen, ObjectFile file, ObjectSection section, Boolean encryptSection)
        {
            Byte[] secData = file.secRead(section);

              // Write Section_Load AIS command, load address, and size
              if (encryptSection)
              {
            Byte[] encData = null;

            // Encrypt data using CTS algorithm
            try
            {
              encData = AesManagedUtil.AesCTSEncrypt(secData,devAISGen.customerEncryptionKey,devAISGen.CEKInitialValue);
            }
            catch(Exception e)
            {
              Console.WriteLine("Exception during encryption operation: {0}",e.Message);
              return retType.FAIL;
            }

            if (encData != null)
            {
              devAISGen.InsertAISEncSectionLoad((UInt32) section.loadAddr, (UInt32) section.size, secData, encData);
            }
            else
            {
              Console.WriteLine("Section encryption failed.");
              return retType.FAIL;
            }
              }
              else
              {
            devAISGen.InsertAISSectionLoad((UInt32) section.loadAddr, (UInt32) section.size, secData);
              }

              // Add this section's memory range, checking for overlap
              AddMemoryRange(devAISGen, (UInt32) section.loadAddr, (UInt32) (section.loadAddr+section.size-1));

              return retType.SUCCESS;
        }
Пример #15
0
 /// <summary>
 /// Secondary genAIS that calls the first
 /// </summary>
 /// <param name="mainObjectFileName">File name of .out file</param>
 /// <param name="bootmode">AISGen.AisBootModes Enum value containing desired boot mode</param>
 /// <returns>an Array of bytes to write to create an AIS file</returns>
 public static Byte[] GenAIS( AISGen devAISGen,
                          List<String> inputFileNames,
                          AisBootModes bootmode,
                          String iniData )
 {
     devAISGen.bootMode = bootmode;
       Console.WriteLine("Chosen bootmode is {0}.", devAISGen.bootMode.ToString());
       return GenAIS(devAISGen, inputFileNames, iniData);
 }
Пример #16
0
        private static void GeneralIniSectionParse(AISGen devAISGen, IniFile iniFile)
        {
            // Get data from the GENERAL INI Section
              IniSection genSec = iniFile.GetSectionByName("General");

              foreach (DictionaryEntry de in genSec.sectionValues)
              {
            // Read buswidth
            if (((String)de.Key).Equals("BUSWIDTH", StringComparison.OrdinalIgnoreCase))
              devAISGen.busWidth = (UInt32)genSec.sectionValues["BUSWIDTH"];

            // Read BootMode (unless already set)
            if ((((String)de.Key).Equals("BOOTMODE", StringComparison.OrdinalIgnoreCase)) && (devAISGen.bootMode == AisBootModes.NONE))
              devAISGen.bootMode = (AisBootModes) Enum.Parse(typeof(AisBootModes), (String)genSec.sectionValues["BOOTMODE"], true);

            // Read Addr width (for I2C/SPI)
            if (((String)de.Key).Equals("ADDRWIDTH", StringComparison.OrdinalIgnoreCase))
            {
              devAISGen.addrWidth = (UInt32)genSec.sectionValues["ADDRWIDTH"];
            }

            // CRC Type override
            if (((String)de.Key).Equals("CRCCheckType", StringComparison.OrdinalIgnoreCase))
            {
              devAISGen.AISCRCType = (AisCRCCheckType) Enum.Parse(typeof(AisCRCCheckType), (String)genSec.sectionValues["CRCCHECKTYPE"], true);
            }

            // Read global entry point
            if (((String)de.Key).Equals("ENTRYPOINT", StringComparison.OrdinalIgnoreCase))
            {
              devAISGen.entryPoint = (UInt32)genSec.sectionValues["ENTRYPOINT"];
            }
              }
        }
Пример #17
0
        public static retType InsertAISCommandViaINI(AISGen devAISGen, IniSection sec)
        {
            #region Handle Input Binary and Object Files
              if (sec.sectionName.Equals("INPUTFILE", StringComparison.OrdinalIgnoreCase))
              {
            String fileName = null;
            Boolean useEntryPoint = false;
            UInt32 loadAddr = 0xFFFFFFFF;
            UInt32 entryPointAddr = 0xFFFFFFFF;

            foreach (DictionaryEntry de in sec.sectionValues)
            {
              // File name for binary section data
              if (((String)de.Key).Equals("FILENAME", StringComparison.OrdinalIgnoreCase))
              {
            fileName = (String) sec.sectionValues["FILENAME"];
              }

              // Binary section's load address in the memory map
              if (((String)de.Key).Equals("LOADADDRESS", StringComparison.OrdinalIgnoreCase))
              {
            loadAddr = (UInt32) sec.sectionValues["LOADADDRESS"];
              }

              // Binary section's entry point address in the memory map
              if (((String)de.Key).Equals("ENTRYPOINTADDRESS", StringComparison.OrdinalIgnoreCase))
              {
            entryPointAddr = (UInt32) sec.sectionValues["ENTRYPOINTADDRESS"];
              }

              // Option to specify that this entry point should be used for AIS
              if (((String)de.Key).Equals("USEENTRYPOINT", StringComparison.OrdinalIgnoreCase))
              {
            if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
            {
              useEntryPoint = true;
            }
            else if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
            {
              useEntryPoint = true;
            }
              }
            }

            if (fileName == null)
            {
              Console.WriteLine("ERROR: File name must be provided in INPUTFILE section.");
              return retType.FAIL;
            }

            // Insert the file into the AIS image
            if ( loadAddr != 0xFFFFFFFF )
            {
              // binary image
              if ( entryPointAddr != 0xFFFFFFFF )
              {
            devAISGen.InsertAISObjectFile(fileName, loadAddr, entryPointAddr);
              }
              else
              {
            devAISGen.InsertAISObjectFile(fileName, loadAddr);
              }
            }
            else
            {
              if ( entryPointAddr != 0xFFFFFFFF )
              {
            devAISGen.InsertAISObjectFile(fileName,true);
              }
              else
              {
            devAISGen.InsertAISObjectFile(fileName,useEntryPoint);
              }
            }
            return retType.SUCCESS;
              }
              #endregion

              #region Handle ROM and AIS Extra Functions
              // Handle ROM functions
              if (devAISGen.ROMFunc != null)
              {
            for (UInt32 j = 0; j < devAISGen.ROMFunc.Length; j++)
            {
              if (sec.sectionName.Equals(devAISGen.ROMFunc[j].iniSectionName, StringComparison.OrdinalIgnoreCase))
              {
            UInt32 funcIndex = j;

            UInt32[] args = new UInt32[ (UInt32)devAISGen.ROMFunc[funcIndex].numParams ];

            for (Int32 k = 0; k < devAISGen.ROMFunc[funcIndex].numParams; k++)
            {
              Debug.DebugMSG("\tParam name: {0}, Param num: {1}, Value: {2}\n",
                devAISGen.ROMFunc[funcIndex].paramNames[k],
                k,
                sec.sectionValues[devAISGen.ROMFunc[funcIndex].paramNames[k].ToUpper()]);
              try
              {
                args[k] = (UInt32) sec.sectionValues[devAISGen.ROMFunc[funcIndex].paramNames[k].ToUpper()];
              }
              catch
              {
                Console.WriteLine("WARNING: INI Section {0} is malformed - {1} parameter not provided. Ignoring section contens.",sec.sectionName, devAISGen.ROMFunc[funcIndex].paramNames[k].ToUpper());
                return retType.SUCCESS;
              }
            }

            devAISGen.InsertAISFunctionExecute((UInt16) funcIndex, (UInt16) devAISGen.ROMFunc[funcIndex].numParams, args);

            return retType.SUCCESS;
              }
            }
              }

              // Handle AISExtras functions
              if (devAISGen.AISExtraFunc != null)
              {
            for (UInt32 j = 0; j < devAISGen.AISExtraFunc.Length; j++)
            {
              if (sec.sectionName.Equals(devAISGen.AISExtraFunc[j].iniSectionName, StringComparison.OrdinalIgnoreCase))
              {
            UInt32 funcIndex = j;

            UInt32[] args = new UInt32[ (UInt32)devAISGen.AISExtraFunc[j].numParams ];

            // Load the AIS extras file if needed
            {
              IniSection tempSec = new IniSection();
              tempSec.sectionName = "INPUTFILE";
              tempSec.sectionValues = new Hashtable();
              tempSec.sectionValues["FILENAME"] = devAISGen.AISExtraFunc[funcIndex].aisExtraFileName;

              EmbeddedFileIO.ExtractFile(Assembly.GetExecutingAssembly(), devAISGen.AISExtraFunc[funcIndex].aisExtraFileName, true);

              InsertAISCommandViaINI(devAISGen, tempSec);

              Debug.DebugMSG("AISExtras file loaded.\n");

              // Use symbols to get address for AISExtra functions and parameters
              for (Int32 k = 0; k < devAISGen.AISExtraFunc.Length; k++)
              {
                ObjectFile tempFile = FindFileWithSymbol(devAISGen, devAISGen.AISExtraFunc[funcIndex].funcName);
                if (tempFile == null)
                {
                  // Try looking for underscore version
                  tempFile = FindFileWithSymbol(devAISGen, "_" + devAISGen.AISExtraFunc[funcIndex].funcName);
                }

                if (tempFile != null)
                {
                  ObjectSymbol tempSym = tempFile.symFind(devAISGen.AISExtraFunc[funcIndex].funcName);
                  if (tempSym == null)
                  {
                    // Try looking for underscore version
                    tempSym = tempFile.symFind("_"+devAISGen.AISExtraFunc[funcIndex].funcName);
                  }

                  if (tempSym != null)
                  {
                    devAISGen.AISExtraFunc[funcIndex].funcAddr = (UInt32) tempSym.value;
                    ObjectSection tempObjSec = tempFile.secFind(".params");
                    if (tempObjSec == null)
                    {
                      Console.WriteLine(".params section not found in file {0}.",
                                        devAISGen.AISExtraFunc[funcIndex].aisExtraFileName);
                      return retType.FAIL;
                    }
                    else
                    {
                      devAISGen.AISExtraFunc[funcIndex].paramAddr = (UInt32) tempObjSec.runAddr;
                    }
                  }
                  else
                  {
                    Console.WriteLine("AIS extra function, {0}, not found in file {1}.",
                                      devAISGen.AISExtraFunc[funcIndex].funcName,
                                      devAISGen.AISExtraFunc[funcIndex].aisExtraFileName);
                    return retType.FAIL;
                  }
                }
                else
                {
                  // The function name was not found - that's a big problem with our
                  // device specific AISGen class.
                  Console.WriteLine("AIS extra function, {0}, not found in file {1}.",
                                    devAISGen.AISExtraFunc[funcIndex].funcName,
                                    devAISGen.AISExtraFunc[funcIndex].aisExtraFileName);
                  return retType.FAIL;
                }
              }
            }

            Debug.DebugMSG("Found required sections and symbols in AISExtras file.\n");

            // Validate input parameters
            for (Int32 k = 0; k < devAISGen.AISExtraFunc[funcIndex].numParams; k++)
            {
              try
              {
                args[k] = (UInt32) sec.sectionValues[devAISGen.AISExtraFunc[funcIndex].paramNames[k].ToUpper()];
              }
              catch
              {
                Console.WriteLine("WARNING: INI Section {0} is malformed - {1} parameter not provided. Ignoring section contens.",sec.sectionName, devAISGen.ROMFunc[funcIndex].paramNames[k].ToUpper());
                return retType.SUCCESS;
              }
            }

            Debug.DebugMSG("Input parameter validation for AISExtras function is complete.\n");

            // Write SET command for each input parameter
            for (Int32 k = 0; k < devAISGen.AISExtraFunc[funcIndex].numParams; k++)
            {
              devAISGen.InsertAISSet(
                (UInt32)AisSetType.INT,    // Write type field (32-bit only)
                (UInt32) (devAISGen.AISExtraFunc[funcIndex].paramAddr + (k * 4)),
                args[k],
                (UInt32)0x0 );  // Write Sleep value (should always be zero)
            }

            // Now that params are set, Jump to function
            devAISGen.InsertAISJump(devAISGen.AISExtraFunc[funcIndex].funcAddr);

            return retType.SUCCESS;
              }
            }
              }
              #endregion

              #region Handle AIS Command Sections

              if (sec.sectionName.Equals("AIS_EnableCRC", StringComparison.OrdinalIgnoreCase))
              {
            devAISGen.InsertAISEnableCRC();
              }

              else if (sec.sectionName.Equals("AIS_DisableCRC", StringComparison.OrdinalIgnoreCase))
              {
            devAISGen.InsertAISDisableCRC();
              }

              else if (sec.sectionName.Equals("AIS_RequestCRC", StringComparison.OrdinalIgnoreCase))
              {
            UInt32 crcValue = 0x00000000;
            Int32 seekValue = -12;

            foreach (DictionaryEntry de in sec.sectionValues)
            {
              if (((String)de.Key).Equals("CRCValue", StringComparison.OrdinalIgnoreCase))
              {
            crcValue = (UInt32)sec.sectionValues["CRCVALUE"];
              }
              if (((String)de.Key).Equals("SEEKValue", StringComparison.OrdinalIgnoreCase))
              {
            seekValue = (Int32)sec.sectionValues["SEEKVALUE"];
              }
            }
            if (devAISGen.InsertAISRequestCRC(crcValue, seekValue) != retType.SUCCESS)
            {
              Console.WriteLine("WARNING: Final function register AIS command failed.");
            }
              }

              else if (sec.sectionName.Equals("AIS_Jump", StringComparison.OrdinalIgnoreCase))
              {
            String symbolName = "";
            UInt32 address = 0x00000000;

            foreach (DictionaryEntry de in sec.sectionValues)
            {
              if (((String)de.Key).Equals("LOCATION", StringComparison.OrdinalIgnoreCase))
              {
            symbolName = sec.sectionValues["LOCATION"].ToString();
              }
            }
            // See if string is number (address)
            if (UInt32.TryParse(symbolName, out address))
            {
              if (devAISGen.InsertAISJump(address) != retType.SUCCESS)
              {
            Console.WriteLine("WARNING: AIS Jump to {0} was not inserted.",symbolName);
              }
            }
            else
            {
              if (devAISGen.InsertAISJump(symbolName) != retType.SUCCESS)
              {
            Console.WriteLine("WARNING: AIS Jump to {0} was not inserted.",symbolName);
              }
            }
              }

              else if (sec.sectionName.Equals("AIS_JumpClose", StringComparison.OrdinalIgnoreCase))
              {
            String symbolName = "";
            UInt32 address = 0x00000000;

            foreach (DictionaryEntry de in sec.sectionValues)
            {
              if (((String)de.Key).Equals("ENTRYPOINT", StringComparison.OrdinalIgnoreCase))
              {
            symbolName = (String)sec.sectionValues["ENTRYPOINT"];
              }
            }

            if (symbolName == "")
            {
              devAISGen.InsertAISJumpClose(devAISGen.entryPoint);
            }
            else
            {
              // See if string is number (address)
              if (UInt32.TryParse(symbolName, out address))
              {
            if (devAISGen.InsertAISJumpClose(address) != retType.SUCCESS)
            {
              Console.WriteLine("WARNING: AIS Jump to {0} was not inserted.",symbolName);
            }
              }
              else
              {
            if (devAISGen.InsertAISJumpClose(symbolName) != retType.SUCCESS)
            {
              Console.WriteLine("WARNING: AIS Jump to {0} was not inserted.",symbolName);
            }
              }
            }
              }

              else if (sec.sectionName.Equals("AIS_Set", StringComparison.OrdinalIgnoreCase))
              {
            UInt32 type     = 0x00000000;
            UInt32 address  = 0x00000000;
            UInt32 data     = 0x00000000;
            UInt32 sleep    = 0x00000000;

            foreach (DictionaryEntry de in sec.sectionValues)
            {
              if (sec.sectionValues["TYPE"].GetType() == typeof(String))
              {
            if (((String)de.Key).Equals("TYPE", StringComparison.OrdinalIgnoreCase))
            {
              if (! UInt32.TryParse((String)sec.sectionValues["TYPE"], out type))
              {
                try
                {
                  type = (UInt32)Enum.Parse(typeof(AisSetType),(String)sec.sectionValues["TYPE"]);
                }
                catch (ArgumentException e)
                {
                  Console.WriteLine((String)sec.sectionValues["TYPE"] + " is not allowed specifier for SET type.");
                  Console.WriteLine(e.Message);
                  return retType.FAIL;
                }
              }
            }
              }
              else
              {
            type = (UInt32)sec.sectionValues["TYPE"];
              }
              if (((String)de.Key).Equals("ADDRESS", StringComparison.OrdinalIgnoreCase))
              {
            address = (UInt32)sec.sectionValues["ADDRESS"];
              }
              if (((String)de.Key).Equals("DATA", StringComparison.OrdinalIgnoreCase))
              {
            data = (UInt32)sec.sectionValues["DATA"];
              }
              if (((String)de.Key).Equals("SLEEP", StringComparison.OrdinalIgnoreCase))
              {
            sleep = (UInt32)sec.sectionValues["SLEEP"];
              }

            }
            devAISGen.InsertAISSet(type, address, data, sleep);
              }

              else if (sec.sectionName.Equals("AIS_SectionFill", StringComparison.OrdinalIgnoreCase))
              {
            UInt32 address  = 0x00000000;
            UInt32 size     = 0x00000000;
            UInt32 type     = 0x00000000;
            UInt32 pattern  = 0x00000000;

            foreach (DictionaryEntry de in sec.sectionValues)
            {
              if (((String)de.Key).Equals("ADDRESS", StringComparison.OrdinalIgnoreCase))
              {
            address = (UInt32)sec.sectionValues["ADDRESS"];
              }
              if (((String)de.Key).Equals("SIZE", StringComparison.OrdinalIgnoreCase))
              {
            size = (UInt32)sec.sectionValues["SIZE"];
              }
              if (((String)de.Key).Equals("TYPE", StringComparison.OrdinalIgnoreCase))
              {
            type = (UInt32)sec.sectionValues["TYPE"];
              }
              if (((String)de.Key).Equals("PATTERN", StringComparison.OrdinalIgnoreCase))
              {
            pattern = (UInt32)sec.sectionValues["PATTERN"];
              }
            }
            devAISGen.InsertAISSectionFill( address, size, type, pattern);
              }

              else if (sec.sectionName.Equals("AIS_FastBoot", StringComparison.OrdinalIgnoreCase))
              {
            devAISGen.InsertAISFastBoot();
              }

              else if (sec.sectionName.Equals("AIS_ReadWait", StringComparison.OrdinalIgnoreCase))
              {
            UInt32 address  = 0x00000000;
            UInt32 mask     = 0xFFFFFFFF;
            UInt32 data     = 0xFFFFFFFF;

            foreach (DictionaryEntry de in sec.sectionValues)
            {
              if (((String)de.Key).Equals("ADDRESS", StringComparison.OrdinalIgnoreCase))
              {
            address = (UInt32)sec.sectionValues["ADDRESS"];
              }
              if (((String)de.Key).Equals("MASK", StringComparison.OrdinalIgnoreCase))
              {
            mask = (UInt32)sec.sectionValues["MASK"];
              }
              if (((String)de.Key).Equals("DATA", StringComparison.OrdinalIgnoreCase))
              {
            data = (UInt32)sec.sectionValues["DATA"];
              }
            }
            devAISGen.InsertAISReadWait(address, mask, data);
              }

              else if (sec.sectionName.Equals("AIS_SeqReadEnable", StringComparison.OrdinalIgnoreCase))
              {
            devAISGen.InsertAISSeqReadEnable();
              }

              else if (sec.sectionName.Equals("AIS_FinalFunctionReg", StringComparison.OrdinalIgnoreCase))
              {
            String finalFxnName = "";

            foreach (DictionaryEntry de in sec.sectionValues)
            {
              if (((String)de.Key).Equals("FINALFXNSYMBOLNAME", StringComparison.OrdinalIgnoreCase))
              {
            finalFxnName = (String)sec.sectionValues["FINALFXNSYMBOLNAME"];
              }
            }
            if (devAISGen.InsertAISFinalFxnReg(finalFxnName) != retType.SUCCESS)
            {
              Console.WriteLine("WARNING: Final function register AIS command failed.");
            }
              }

              else if ( (sec.sectionName.Equals("GENERAL", StringComparison.OrdinalIgnoreCase)) ||
                (sec.sectionName.Equals("SECURITY", StringComparison.OrdinalIgnoreCase)) )
              {
            // Ignore General/Security section here since it should have already been processed
              }

              else
              {
            // Any other sections names should be ignored with warning
            Console.WriteLine("WARNING: Unrecognized INI section, {0}. Ignoring...", sec.sectionName );
              }

              #endregion

              return retType.SUCCESS;
        }
Пример #18
0
 /// <summary>
 /// Secondary genAIS thats calls the first
 /// </summary>
 /// <param name="inputFileNames">File name of .out file</param>
 /// <param name="bootmode">AISGen.AisBootModes Enum value containing desired boot mode</param>
 /// <returns>an Array of bytes to write to create an AIS file</returns>
 public static Byte[] SecureGenAIS(AISGen devAISGen,
                               List<String> inputFileNames,
                               AisBootModes bootmode,
                               String iniData)
 {
     return SecureGenAIS(devAISGen, inputFileNames, bootmode, new IniFile(iniData));
 }