/// <summary> /// Gets the file encryption transform. /// </summary> /// <param name="initializationVector">The initialization vector.</param> /// <param name="fileOffset">The file offset.</param> /// <returns>The transform.</returns> public FileEncryptionTransform GetTransform(ulong initializationVector, long fileOffset) { ICryptoTransform transform = null; using (CriticalSection.Enter(this._lockObject)) { // Note that ECB encrypt is always used for AES-CTR whether doing encryption or decryption. transform = this._key.CreateEncryptor(); } return(new FileEncryptionTransform(transform, initializationVector, fileOffset)); }
/// <summary> /// Gets the initialization vector for file. /// </summary> /// <param name="fileName">Name of the file.</param> /// <returns>The initialization vector.</returns> public ulong GetInitializationVectorForFile(string fileName) { ulong returnValue = 0; if (string.IsNullOrEmpty(fileName)) { throw new ArgumentException("Cannot be null or empty", "fileName"); } using (CriticalSection.Enter(this._lockObject)) { returnValue = this._initializationVectorListByFileName[fileName]; } return(returnValue); }
/// <summary> /// Determines whether [is initialization vector present] [the specified file name]. /// </summary> /// <param name="fileName">Name of the file.</param> /// <returns> /// <c>true</c> if [is initialization vector present] [the specified file name]; otherwise, <c>false</c>. /// </returns> public bool IsInitializationVectorPresent(string fileName) { bool returnValue = false; if (string.IsNullOrEmpty(fileName)) { throw new ArgumentException("Cannot be null or empty", "fileName"); } using (CriticalSection.Enter(this._lockObject)) { returnValue = this._initializationVectorListByFileName.ContainsKey(fileName); } return(returnValue); }
/// <summary> /// Sets the initialization vector for file. /// </summary> /// <param name="fileName">Name of the file.</param> /// <param name="initializationVectorToSet">The initialization vector to set.</param> public void SetInitializationVectorForFile(string fileName, ulong initializationVectorToSet) { ulong temp = 0; if (string.IsNullOrEmpty(fileName)) { throw new ArgumentException("Cannot be null or empty", "fileName"); } using (CriticalSection.Enter(this._lockObject)) { if (!this._initializationVectorListByFileName.TryGetValue(fileName, out temp)) { this._initializationVectorListByFileName.Add(fileName, initializationVectorToSet); } else if (this._initializationVectorListByFileName[fileName] != initializationVectorToSet) { string message = string.Format(CultureInfo.CurrentCulture, "An initialization vector is already set for {0}.", fileName); throw new InvalidOperationException(message); } } }
/// <summary> /// Creates the initialization vector for file. /// </summary> /// <param name="fileName">Name of the file.</param> /// <returns>The initialization vector.</returns> public ulong CreateInitializationVectorForFile(string fileName) { ulong iv = 0; bool duplicateIv = false; if (string.IsNullOrEmpty(fileName)) { throw new ArgumentException("Cannot be null or empty", "fileName"); } using (CriticalSection.Enter(this._lockObject)) { if (this._rng == null) { this._rng = new RNGCryptoServiceProvider(); } byte[] initializationVectorAsBytes = new byte[sizeof(ulong)]; do { this._rng.GetBytes(initializationVectorAsBytes); iv = BitConverter.ToUInt64(initializationVectorAsBytes, 0); // Each file protected by a given key must have a unique iv value. // One of the issues with using CTR mode is that reusing counter // values can lead to an attack on the encryption. To prevent that, // we use a unique 64-bit IV value per file. The remaining 64 bits // of the counter value are a block counter ensuring that each block // in the file has a unique counter value IF each file has a unique // 64-bit IV value. duplicateIv = this._initializationVectorListByFileName.ContainsValue(iv); }while (duplicateIv); this._initializationVectorListByFileName.Add(fileName, iv); } return(iv); }