Beispiel #1
0
        public LoadModule(AisSecureType secureType, SecureLoadMagic magic, String encKey, String rsaKeyFileName) : this()
        {
            String currHashAlgorithmString = "SHA1"; // Default hash algorithm

            SecureType = secureType;
            MagicNum   = magic;

            // Get the encryption key
            customerEncryptionKey = new Byte[16];
            CEKInitialValue       = new Byte[16];

            if (encKey.Length != 32)
            {
                throw new ArgumentException("AES Encryption Key is wrong length!");
            }
            for (int j = 0; j < encKey.Length; j += 2)
            {
                customerEncryptionKey[(j >> 1)] = Convert.ToByte(encKey.Substring(j, 2), 16);
            }

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

            // Get RSA key
            rsaObject = RSAKey.LoadFromFile(rsaKeyFileName);
            if (rsaObject == null)
            {
                throw new ArgumentException("RSA key loading failed!");
            }

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

            try
            {
                currHashAlgorithm = HashAlgorithm.Create(currHashAlgorithmString);
            }
            catch (Exception e)
            {
                Console.WriteLine("Invalid Hash Algorithm Selected. Exception message: {0}.", e.Message);
                throw e;
            }
        }
Beispiel #2
0
        public static Byte[] GenerateCertData(LoadModule loadMod)
        {
            Byte[] delegateKeyData = null;

            if (loadMod.SecureType == AisSecureType.CUSTOM)
            {
                // Create Delegate Key Certificate Format
                //Key cert: 32 + (128 or 256) bytes
                //  decryptionKey: 16 byte (128 bits) AES key

                //  rsaPublicKey: 8 bytes + 128/256 for modulus data (actual modulus data may only be 128 bytes for RSA1024)
                //    keyExponent: 4 bytes
                //    keyPad: 2 bytes
                //    modLength: 2 bytes
                //    modData: 128 or 256 bytes
                //  keyFlags: 8 bytes

                delegateKeyData = new Byte[32 + (loadMod.rsaObject.KeySize >> 3)];

                // Fill with random data
                (new Random()).NextBytes(delegateKeyData);

                // Insert decryptionKey at offset 0
                loadMod.certEncryptionKey.CopyTo(delegateKeyData, 0);

                // Insert rsaPublicKey at offset 16
                RSAKey.CreateCustomSecureKeyVerifyStruct(loadMod.certRsaObject).CopyTo(delegateKeyData, 16);

                // Insert flags data
                BitConverter.GetBytes((UInt32)0x00000000).CopyTo(delegateKeyData, 24 + (loadMod.rsaObject.KeySize >> 3));
                BitConverter.GetBytes((UInt32)0x00000000).CopyTo(delegateKeyData, 28 + (loadMod.rsaObject.KeySize >> 3));
            }
            else if (loadMod.SecureType == AisSecureType.GENERIC)
            {
                delegateKeyData = new Byte[32];

                // Fill with random data
                (new Random()).NextBytes(delegateKeyData);

                // Insert decryptionKey at offset 0
                loadMod.certEncryptionKey.CopyTo(delegateKeyData, 0);

                // Insert flags data
                BitConverter.GetBytes((UInt32)0x00000000).CopyTo(delegateKeyData, 16);
                BitConverter.GetBytes((UInt32)0x00000000).CopyTo(delegateKeyData, 20);
                BitConverter.GetBytes((UInt32)0x00000000).CopyTo(delegateKeyData, 24);
                BitConverter.GetBytes((UInt32)0x00000000).CopyTo(delegateKeyData, 28);
            }

            return(delegateKeyData);
        }
Beispiel #3
0
        private static retType SecurityIniSectionParse(LoadModule loadMod, 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))
                    {
                        loadMod.SecureType = (AisSecureType)Enum.Parse(typeof(AisSecureType), (String)sec.sectionValues["SECURITYTYPE"], true);
                    }

                    if (((String)de.Key).Equals("ENCRYPT", StringComparison.OrdinalIgnoreCase))
                    {
                        if (((String)sec.sectionValues["ENCRYPT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
                        {
                            loadMod.encryptData = true;
                        }
                        if (((String)sec.sectionValues["ENCRYPT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                        {
                            loadMod.encryptData = true;
                        }
                    }

                    // AES Encryption Key (CEK)
                    if (((String)de.Key).Equals("MAGICNUM", StringComparison.OrdinalIgnoreCase))
                    {
                        loadMod.MagicNum = (SecureLoadMagic)Enum.Parse(typeof(SecureLoadMagic), (String)sec.sectionValues["MAGICNUM"], true);
                    }

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

                        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)
                        {
                            loadMod.customerEncryptionKey[(j >> 1)] = Convert.ToByte(keyString.Substring(j, 2), 16);
                        }

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

                    // Key Encryption Key (not normally known, here for debug/testing purposes)
                    if (((String)de.Key).Equals("KEYENCRYPTIONKEY", StringComparison.OrdinalIgnoreCase))
                    {
                        loadMod.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)
                        {
                            loadMod.keyEncryptionKey[(j >> 1)] = Convert.ToByte(keyString.Substring(j, 2), 16);
                        }
                    }

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

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

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

                    // Custom Secure RSA Key File
                    if (((String)de.Key).Equals("CERTRSAKEYFILENAME", StringComparison.OrdinalIgnoreCase))
                    {
                        String rsaKeyFileName = (String)sec.sectionValues["CERTRSAKEYFILENAME"];
                        loadMod.certRsaObject = RSAKey.LoadFromFile(rsaKeyFileName);

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

                    // AES Encryption Key (CEK)
                    if (((String)de.Key).Equals("CERTENCRYPTIONKEY", StringComparison.OrdinalIgnoreCase))
                    {
                        loadMod.certEncryptionKey = new Byte[16];

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

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

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

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

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

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

            // 7) If custom CERT_MAGIC module, verify certRsaObject and certEncryptionKey are set
            if ((loadMod.MagicNum == SecureLoadMagic.CERT_MAGIC) && (loadMod.SecureType == AisSecureType.CUSTOM))
            {
                if (loadMod.certRsaObject == null)
                {
                    Console.WriteLine("ERROR: Delegate Key Certificate load module for custom devices requires CERTRSAKEYFILENAME value.");
                    return(retType.FAIL);
                }
                if (loadMod.certEncryptionKey == null)
                {
                    Console.WriteLine("ERROR:Delegate Key Certificate load module for custom devices requires CERTENCRYPTIONKEY value.");
                    return(retType.FAIL);
                }

                // 9) Make sure RSA key sizes match
                if (loadMod.certRsaObject.KeySize != loadMod.rsaObject.KeySize)
                {
                    Console.WriteLine("ERROR: Certificate RSA key size does not match current RSA key size.");
                    return(retType.FAIL);
                }
            }

            // 8) If custom CERT_MAGIC module, verify certRsaObject and certEncryptionKey are set
            if ((loadMod.MagicNum == SecureLoadMagic.CERT_MAGIC) && (loadMod.SecureType == AisSecureType.GENERIC))
            {
                if (loadMod.certEncryptionKey == null)
                {
                    Console.WriteLine("ERROR: Delegate Key Certificate load module for generic devices requires CERTENCRYPTIONKEY value.");
                    return(retType.FAIL);
                }
            }

            if ((loadMod.MagicNum == SecureLoadMagic.CERT_MAGIC) && (!loadMod.encryptData))
            {
                Console.WriteLine("INFO: For CERT_MAGIC, encryption is required - forcing load module payload to be encrypted.");
                loadMod.encryptData = true;
            }

            #endregion
            return(retType.SUCCESS);
        }