示例#1
0
        byte[] ComputeAESWithRounds(AESDir aesDir, IV16 iv, byte[] dataBytes, byte[] keyBytes, byte roundsExp, IVCache ivCache, LongRunningOperationContext context)
        {
            Guard.NotNull(new object[] { aesDir, iv, dataBytes, keyBytes, roundsExp, ivCache, context });
            var rounds     = 1u << roundsExp;
            var roundsToGo = rounds;

            byte[] inputData = dataBytes;
            byte[] aesResult = null;
            while (roundsToGo > 0)
            {
                byte[] currentIV =
                    aesDir == AESDir.Encrypt
                       ? ivCache.IVTable.Item2[roundsToGo - 1]
                       : ivCache.IVTable.Item2[ivCache.IVTable.Item2.Length - roundsToGo];

                aesResult = this._platform.ComputeAESRound(aesDir, currentIV, inputData, keyBytes);
                inputData = aesResult;

                roundsToGo--;                 // decrement before calculating the percentage or we'll be stuck at 99%

                // START encryptionProgress / Cancellation
                context.CancellationToken.ThrowIfCancellationRequested();
                decimal progressValue = (rounds - roundsToGo) / (decimal)(rounds);

                context.EncryptionProgress.Percent = (int)(progressValue * 100m);
                context.EncryptionProgress.Report(context.EncryptionProgress);
                // END encryptionProgress
            }
            return(aesResult);
        }
示例#2
0
        InputDerivedKey32 CreateDerivedKeyWithSHA256(IV16 iv, KeyMaterial64 keyMaterial64)
        {
            var keyMaterial = ByteArrays.Concatenate(iv.GetBytes(), keyMaterial64.GetBytes());
            var derivedKey  = this._platform.ComputeSHA256(keyMaterial);

            return(new InputDerivedKey32(derivedKey));
        }
示例#3
0
        InputDerivedKey32 CreatePasswordDerivedKeyWithBCrypt(IV16 iv, KeyMaterial64 keyMaterial64, RoundsExponent roundsExponent,
                                                             LongRunningOperationContext context)
        {
            var leftSHA512  = new byte[32];
            var rightSHA512 = new byte[32];

            Buffer.BlockCopy(keyMaterial64.GetBytes(), 0, leftSHA512, 0, 32);
            Buffer.BlockCopy(keyMaterial64.GetBytes(), 32, rightSHA512, 0, 32);

            context.EncryptionProgress.Message = LocalizableStrings.MsgProcessingKey;

            // Compute the left side on a ThreadPool thread
            var task = Task.Run(() => BCrypt.CreateHash(iv, leftSHA512, roundsExponent.Value, context));

            // Compute the right side after dispatching the work for the right side
            BCrypt24 rightBCrypt = BCrypt.CreateHash(iv, rightSHA512, roundsExponent.Value, context);

            // Wait for the left side result
            task.Wait(context.CancellationToken);

            // Use the results
            var combinedHashes = ByteArrays.Concatenate(keyMaterial64.GetBytes(), task.Result.GetBytes(), rightBCrypt.GetBytes());

            Debug.Assert(combinedHashes.Length == 64 + 24 + 24);

            var condensedHash = this._platform.ComputeSHA256(combinedHashes);

            return(new InputDerivedKey32(condensedHash));
        }
示例#4
0
        /// <summary>'Hash a password using the OpenBSD bcrypt scheme'. Adapted for XDSSec.</summary>
        /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or
        /// illegal values.</exception>
        /// <param name="data">The data to hash.</param>
        /// <param name="iv16">The salt to hash with.</param>
        /// <param name="logRounds">Between [4..31].</param>
        /// <param name="context">Object for encryptionProgress indicator and cancelation</param>
        /// <returns>The hash.</returns>
        public static BCrypt24 CreateHash(IV16 iv16, byte[] data, byte logRounds, LongRunningOperationContext context)
        {
            Guard.NotNull(new object[] { iv16, data, context });

            if (logRounds < 4 || logRounds > 31)
            {
                throw new ArgumentOutOfRangeException(nameof(logRounds), logRounds, "logRounds must be between 4 and 31 (inclusive)");
            }

            var hash = new BCrypt(context).CryptRaw(data, iv16.GetBytes(), logRounds);

            return(new BCrypt24(hash));
        }
示例#5
0
        public PaddedData AESDecryptMessage(CipherV2 cipherV2, IV16 iv16, RandomKey32 randomKey, IVCache ivCache, LongRunningOperationContext context)
        {
            Guard.NotNull(new object[] { cipherV2, iv16, randomKey, context });

            byte[] paddedDataBytes;
            if (cipherV2.RoundsExponent.Value == RoundsExponent.DontMakeRounds)
            {
                paddedDataBytes = this._platform.ComputeAESRound(AESDir.Decrpyt, cipherV2.IV16.GetBytes(), cipherV2.MessageCipher.GetBytes(), randomKey.GetBytes());
            }
            else
            {
                context.EncryptionProgress.Message = LocalizableStrings.MsgDecryptingMessage;
                paddedDataBytes = ComputeAESWithRounds(AESDir.Decrpyt, cipherV2.IV16, cipherV2.MessageCipher.GetBytes(), randomKey.GetBytes(), cipherV2.RoundsExponent.Value, ivCache, context);
            }
            return(new PaddedData(paddedDataBytes, cipherV2.PlaintextPadding));
        }
示例#6
0
        /// <summary>
        /// Purpose:
        /// </summary>
        /// <param name="iv"></param>
        /// <param name="roundsExp"></param>
        /// <returns></returns>
        public IVCache CreateIVTable(IV16 iv, byte roundsExp)
        {
            Guard.NotNull(new object[] { iv });

            var ivCache  = new IVCache();
            var rounds   = 1u << roundsExp;
            var ivRounds = rounds;
            var ivTable  = new byte[rounds][];

            byte[] ivInput = iv.GetBytes();
            while (ivRounds > 0)
            {
                ivTable[ivTable.Length - ivRounds] = ivInput;

                ivInput = this._platform.ComputeSHA256(ivInput).Take(16).ToArray();

                ivRounds = ivRounds - 1;
            }
            ivCache.IVTable = new Tuple <byte[], byte[][]>(iv.GetBytes(), ivTable);
            return(ivCache);
        }
示例#7
0
        CipherV2 EncryptCommon(KeyMaterial64 keyMaterial64, RoundsExponent roundsExponent, LongRunningOperationContext context,
                               Compressed compressed)
        {
            if (context == null)
            {
                context = new LongRunningOperation(progress => { }, () => { }).Context;
            }

            if (this._log)
            {
                Debug.WriteLine("KeyMaterial64:");
                Debug.WriteLine(keyMaterial64.GetBytes().ToHexView(false));
            }

            if (this._log)
            {
                Debug.WriteLine("Compressed:");
                Debug.WriteLine(compressed.GetBytes().ToHexView(false));
            }

            PaddedData paddedData = this._internal.ApplyRandomPadding(compressed);

            if (this._log)
            {
                Debug.WriteLine("PaddedData:");
                Debug.WriteLine(paddedData.GetBytes().ToHexView(false));

                Debug.WriteLine("PlainTextPadding:");
                Debug.WriteLine(paddedData.PlaintextPadding);
            }

            IV16 iv = new IV16(this._platform.GenerateRandomBytes(16));

            if (this._log)
            {
                Debug.WriteLine("IV16:");
                Debug.WriteLine(iv.GetBytes().ToHexView(false));
            }

            InputDerivedKey32 inputDerivedKey = roundsExponent.Value == RoundsExponent.DontMakeRounds
                ? CreateDerivedKeyWithSHA256(iv, keyMaterial64)
                : CreatePasswordDerivedKeyWithBCrypt(iv, keyMaterial64, roundsExponent, context);

            if (this._log)
            {
                Debug.WriteLine("InputDerivedKey32:");
                Debug.WriteLine(inputDerivedKey.GetBytes().ToHexView(false));
            }

            RandomKey32 randomKey = new RandomKey32(this._platform.GenerateRandomBytes(32));

            if (this._log)
            {
                Debug.WriteLine("RandomKey32:");
                Debug.WriteLine(randomKey.GetBytes().ToHexView(false));
            }

            XDSSecAPIInternal.IVCache ivCache = roundsExponent.Value == RoundsExponent.DontMakeRounds
                ? null
                : this._internal.CreateIVTable(iv, roundsExponent.Value);

            var cipherV2 = new CipherV2 {
                RoundsExponent = roundsExponent, IV16 = iv
            };

            this._internal.AESEncryptRandomKeyWithInputDerivedKey(inputDerivedKey, randomKey, cipherV2, ivCache, context);
            if (this._log)
            {
                Debug.WriteLine("RandomKeyCipher32:");
                Debug.WriteLine(cipherV2.RandomKeyCipher32.GetBytes().ToHexView(false));
            }

            this._internal.AESEncryptMessageWithRandomKey(paddedData, randomKey, cipherV2, ivCache, context);
            if (this._log)
            {
                Debug.WriteLine("MessageCipher:");
                Debug.WriteLine(cipherV2.MessageCipher.GetBytes().ToHexView(false));
            }

            MAC16 mac = CreateMAC(cipherV2, context);

            if (this._log)
            {
                Debug.WriteLine("MAC16:");
                Debug.WriteLine(mac.GetBytes().ToHexView(false));
            }

            this._internal.AESEncryptMACWithRandomKey(cipherV2, mac, randomKey, ivCache, context);
            if (this._log)
            {
                Debug.WriteLine("MACCipher16:");
                Debug.WriteLine(cipherV2.MACCipher16.GetBytes().ToHexView(false));
            }
            return(cipherV2);
        }