# AESFile Module

The AESFile module implements the AESF file format and uses the XTS-AES standard with 256-bit encryption.

## Syntax

```text
IPWorksEncrypt.AESFile
```

## Remarks

The AESFile component provides robust encryption capabilities to securely store and retrieve data using XTS-AES 256-bit encryption. This component implements the AESF file format, enabling developers to encrypt arbitrary data and serialize it in a standardized manner.

The first step in using the component is to set [Password](#AESFile_p_Password) property. Specify the input data using [InputFile](#AESFile_p_InputFile) or [InputMessage](#AESFile_p_InputMessage). Next, call [Encrypt](#AESFile_m_Encrypt) and the component will encrypt the input data and populate [OutputMessage](#AESFile_p_OutputMessage), or write to the file specified by [OutputFile](#AESFile_p_OutputFile) with the result.

To change the password of existing file encrypted in AESF format, or to encrypt a file under a different password call [ChangePassword](#AESFile_m_ChangePassword). To decrypt data, first set [Password](#AESFile_p_Password) property. Specify the input data using [InputFile](#AESFile_p_InputFile) or [InputMessage](#AESFile_p_InputMessage). Next, call [Decrypt](#AESFile_m_Decrypt) and the component will compute the plaintext and populate [OutputMessage](#AESFile_p_OutputMessage) or write to [OutputFile](#AESFile_p_OutputFile) with the result.

## AES File Format

The AES file format used by AES Drive is documented below in detail. All algorithms used by AES Drive are standards and publicly documented.

Each encrypted file consists of a header and the encrypted contents. The header is 144 bytes in length and contains the AES file format version, a checksum of the header bytes, and the encrypted file-specific key and padding length. The original file data is encrypted using XTS-AES with file-specific keys that are derived from a master key for the drive.

Encrypted files are slightly longer than their unencrypted equivalents due to presence of encryption information (from 145 to 656 bytes each, or less than 0.5% on average). This information is stored at both beginning and end of the file, and is composed of the following elements:

| Field | Data Offset | Length | Description |
| --- | --- | --- | --- |
| Magic string | 0-3 | 4 bytes | The signature value which indicates the file is formatted according to this specification. The value is always AESF. |
| Version | 4 | 1 byte | The file format version. This documentation defines the format for version 1 (0x01). |
| Reserved | 5-11 | 7 bytes | Reserved. These bytes are unused and should be 0x00. |
| Checksum | 12-15 | 4 bytes | The CRC32 checksum of the 144-byte header. Used to quickly confirm that the file is a well-formed AESF file. See the Additional Details section below for details on how this value is calculated. |
| Drive Level Salt | 16-31 | 16 bytes | The global salt value shared by all files created within the drive. It is a random value created when the drive is created and used when encrypting newly created files within the drive. |
| File Level Salt | 32-47 | 16 bytes | The file-specific salt value. It is a random value created when the file is created. |
| Encryption Key Safe | 48-127 | 80 bytes | An AES-GCM encrypted container which secures the file encryption key. The container can only be unlocked with the correct drive password. The container protection relies on a combination of modern cryptographic techniques to provide the highest level of protection including: Strong one-way hash function (keyed and salted SHA512) Secure password hashing with PBKDF2 Authenticated AES256 encryption See the Additional Details section below for step-by-step instructions on how the encryption key safe can be accessed. |
| Encryption Auth Tag | 128-143 | 16 bytes | AES-GCM auth tag. Used when decrypting the encryption key safe. |
| Encrypted File Data | 144-... | 512 x N bytes | Encrypted file content. Industry-standard double-key XTS-AES algorithm is used, which provides high efficiency and security. File content blocks are always 512 bytes in length. |
| Padding + Random | Last 512 | 512 bytes | Special padding and random bytes. The encrypted file is padded with up to 512 random bytes so the overall length is the length of unencrypted file, plus the length of the header (144), plus 512. This way, the length of the decrypted file can quickly be determined from the length of the encrypted file. See the Additional Details for an example and a detailed explanation. |

### Additional Details

```text
byte[] CRC32Bytes = new byte[4];
for (int i = 0; i < 4; i++)
  CRC32Bytes[i] = (byte)((CRC32uint >> (24 - 8 * i)) & 0xff);

```

```text
PaddingLen = (decryptedHeaderBytes[0] << 8) + decryptedHeaderBytes[1];
```

|  |  |  |
| --- | --- | --- |
|  | Checksum Details The CRC32 checksum is calculated by replacing the 4 bytes holding the checksum (12-15) with 0x00 and then computing the checksum over the 144 byte header. The resulting numeric value is converted into 4 bytes using the operation: |  |
|  | Encryption Key Safe Details The steps to derive the key to decrypt the encryption key safe are as follows: First use PBKDF2 with the following settings: Algorithm: HMACSHA512 Iterations: 50,000 Salt: 16-byte drive level salt value read from the header Password: Original encryption password Derived key length: 32 bytes Concatenate the 16-byte file level salt from the header with the 32-byte derived key from the PBKDF2 process above to obtain a byte array of length 48. The first 16 bytes are the salt, and the last 32 bytes are the derived key. Compute the SHA512 hash over the 48-byte value from the above step. The first 32 bytes (0-31) of the hash from the above step are the AES-GCM key. The next 12 bytes (32-43) are the AES-GCM IV. The remaining 20 bytes are unused. The derived Key and IV are used together with the AES-GCM Auth Tag (the last 16 bytes of the 144-byte header) to AES-GCM decrypt the 80-byte key safe. The decrypted value contains: |  |
| 2 bytes | 0-1 | Padding length. The padding length is represented in Big Endian and may be converted from bytes to an integer using the following operation: |
| 14 bytes | 2-15 | Reserved. These bytes are unused and should be 0x00. |
| 64 bytes | 16-79 | File-specific XTS-AES 256 encryption keys. The first 32 bytes (16-47) are the first key, and the last 32 bytes (48-79) are the second key. |

**Last 512 Bytes Details**

 When encrypting, the last plaintext block of data may be padded with random bytes as needed to reach 512 bytes in length (the data unit size), as the encryption algorithm works with 512-byte blocks ("pages") and otherwise would not work with files that do not end strictly at a 512-byte boundary.

 The padding length is encrypted and stored in the encrypted key safe. Once the data is encrypted, an additional (512 - padding_length) random bytes are appended to the end of the encrypted file so that the padding bytes plus additional random bytes together are 512 bytes in length. This scheme allows applications to easily determine the length of the decrypted file without having to first decrypt the encrypted key safe to obtain the padding length.

 The decrypted file length can be computed like so:

```text
long decryptedFileLength = encryptedFileLength - 144 - 512.
//Subtract 144 for header length
//Subtract 512 for padding bytes plus additional random bytes

```

 When decrypting, the padding length is determined from data in the encrypted key safe. The number of additional random bytes is 512 minus the padding length. The additional random bytes are discarded before using XTS-AES to decrypt the file content. After decrypting the file content, the padding bytes in the decrypted content are discarded.

```text
                  --------------------[512 bytes]--------------------
                  |                                                 |
encrypted_content | encrypted_padding_bytes | additional_random_bytes

```
