Esempio n. 1
0
        public static void XTSEncrypt(SymmetricAlgorithm algorithm, byte[] key1, byte[] key2, ulong dataUnitIndex, byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
        {
            byte[]             initializationVector = new byte[16];
            ICryptoTransform   encryptor1           = algorithm.CreateEncryptor(key1, initializationVector);
            ICryptoTransform   encryptor2           = algorithm.CreateEncryptor(key2, initializationVector);
            XtsCryptoTransform transform            = new XtsCryptoTransform(encryptor1, encryptor2, false);

            transform.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset, dataUnitIndex);
        }
Esempio n. 2
0
            public override void Write(byte[] buffer, int offset, int count)
            {
                ValidateSize(count);
                if (count == 0)
                {
                    return;
                }
                var currentSector = CurrentSector;

                if (_encryptor == null)
                {
                    _encryptor = _xts.CreateEncryptor();
                }
                int transformedCount = _encryptor.TransformBlock(buffer, offset, count, _tempBuffer, 0, currentSector);

                base.Write(_tempBuffer, 0, transformedCount);
            }
Esempio n. 3
0
            public override int Read(byte[] buffer, int offset, int count)
            {
                ValidateSize(count);
                var currentSector = CurrentSector;
                var ret           = base.Read(_tempBuffer, 0, count);

                if (ret == 0)
                {
                    return(0);
                }
                if (_decryptor == null)
                {
                    _decryptor = _xts.CreateDecryptor();
                }
                var retV = _decryptor.TransformBlock(_tempBuffer, 0, ret, buffer, offset, currentSector);

                return(retV);
            }
Esempio n. 4
0
        protected override void TransformSectorImpl(Memory <byte> dest, ReadOnlyMemory <byte> src, long sectorNumber, bool logicalToPhysical)
        {
            checked
            {
                if (dest.Length != src.Length)
                {
                    throw new ArgumentOutOfRangeException("dest.Length != src.Length");
                }
                if (dest.Length != SectorSize)
                {
                    throw new ArgumentOutOfRangeException("dest.Length != SectorSize");
                }

                var destSeg = dest._AsSegment();
                var srcSeg  = src._AsSegment();

                XtsCryptoTransform transform = logicalToPhysical ? this.CurrentDescrypter : this.CurrentEncrypter;

                transform.TransformBlock(srcSeg.Array !, srcSeg.Offset, srcSeg.Count, destSeg.Array !, destSeg.Offset, (ulong)sectorNumber);
            }
        }
Esempio n. 5
0
        protected override async Task InitMetadataImplAsync(CancellationToken cancel = default)
        {
            Memory <byte> firstSectorData = new byte[XtsAesMetaDataSize];

            // ヘッダの読み込みを試行する
            int readSize = await this.PhysicalReadAsync(0, firstSectorData, cancel);

            if (readSize == XtsAesMetaDataSize)
            {
                var metaDataParseResult = TryParseMetaData(firstSectorData);

                metaDataParseResult.ThrowIfException();

                var metaData = metaDataParseResult.Value !;

                // パスワード検査
                if (Secure.VeritySaltedPassword(metaData.SaltedPassword, this.CurrentPassword) == false)
                {
                    throw new CoresException("XtsAesRandomAccess: Incorrect password.");
                }

                // 秘密鍵解読
                var decrypted = ChaChaPoly.EasyDecryptWithPassword(metaData.MasterKeyEncryptedByPassword._GetHexBytes(), this.CurrentPassword);
                decrypted.ThrowIfException();

                // 秘密鍵サイズ検査
                if (decrypted.Value.Length != XtsAesKeySize)
                {
                    throw new CoresException("XtsAesRandomAccess: decrypted.Value.Length != XtsAesKeySize");
                }

                this.CurrentMasterKey = decrypted.Value;

                this.CurrentMetaData = metaData;
            }
            else if (readSize == 0)
            {
                // ファイルの内容が存在しない

                // マスターキーを新規作成する
                this.CurrentMasterKey = Secure.Rand(XtsAesKeySize);

                // メタデータを新規作成する
                var metaData = new XtsAesRandomAccessMetaData
                {
                    Version        = 1,
                    VirtualSize    = 0,
                    SaltedPassword = Secure.SaltPassword(this.CurrentPassword),
                    MasterKeyEncryptedByPassword = ChaChaPoly.EasyEncryptWithPassword(this.CurrentMasterKey, this.CurrentPassword)._GetHexString(),
                };

                this.CurrentMetaData = metaData;

                // メタデータを書き込みする
                await WriteMetaDataAsync(cancel);
            }
            else
            {
                // 不正 ここには来ないはず
                throw new CoresException($"XtsAesRandomAccess: Invalid readSize: {readSize}");
            }

            // XTS を作成
            this.CurrentXts        = XtsAes256.Create(this.CurrentMasterKey.ToArray());
            this.CurrentEncrypter  = this.CurrentXts.CreateEncryptor();
            this.CurrentDescrypter = this.CurrentXts.CreateDecryptor();
        }