silk.crypto.aes_xts.
Encrypt storage sectors with AES-XTS (IEEE 1619, NIST SP 800-38E).
When to use#
Use AesXts where a disk or file format names XTS, or for Node's aes-128-xts and
aes-256-xts. XTS is made for storage: it does not detect changes, and it does not hide when a
sector is written again with the same data. Use silk.crypto.aes_gcm for messages.
Details#
The key is two AES keys side by side: 32 bytes for AES-128-XTS or 64 bytes for AES-256-XTS. The 16-byte tweak names the data unit, usually the sector number. Each call encrypts or decrypts one whole data unit of at least 16 bytes. A length that is not a multiple of 16 uses ciphertext stealing, so the ciphertext has the same length as the plaintext. Nothing allocates.
Errors#
The functions return an AesXtsError. Every check comes before the first write, and on an
error the output does not change.
Gotchas#
Encryption rejects a key whose two halves are equal, as OpenSSL does. A data unit is at most 2^20 blocks, OpenSSL's limit. Each call is one data unit: splitting a sector across calls gives a different result.
Examples#
Encrypt and decrypt a sector#
import silk.crypto.aes_xts { AesXts, AesXtsError }
import silk.core.result { Result }
pub fn main() -> i32 {
let mut key: [u8; 32] = [0; 32]
key[16] = 1
let tweak: [u8; 16] = [0; 16]
let sector: [u8; 20] = [7; 20]
let mut ciphertext: [u8; 20] = [0; 20]
if let Result.Failure { error: _ } = AesXts.encrypt(&key, &tweak, §or, &mut ciphertext) {
return 1
}
let mut plaintext: [u8; 20] = [0; 20]
if let Result.Failure { error: _ } = AesXts.decrypt(&key, &tweak, &ciphertext, &mut plaintext) {
return 1
}
if plaintext[0] != 7 || plaintext[19] != 7 {
return 1
}
return 0
}Import as AesXts with import silk.crypto.aes_xts { AesXts }.
Public declarations: 2.
AesXtsError#
pub enum AesXtsErrorThe reason that AesXts.encrypt or AesXts.decrypt rejected a call. The output does not
change.
InvalidKeyLength#
InvalidKeyLengthThe key is not 32 or 64 bytes.
DuplicateKeyHalves#
DuplicateKeyHalvesThe two halves of the key are equal, which XTS encryption does not allow.
InvalidIvLength#
InvalidIvLengthThe tweak is not 16 bytes.
InvalidInputLength#
InvalidInputLengthThe data unit is shorter than 16 bytes or longer than 2^20 blocks.
OutputTooSmall#
OutputTooSmallThe output is shorter than the input.
Implementation Debug for AesXtsError#
impl Debug for AesXtsErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as InvalidKeyLength.
AesXts#
pub struct AesXtsFunctions that encrypt and decrypt one data unit with AES-XTS (IEEE 1619).
Details#
The key is 32 bytes (AES-128-XTS) or 64 bytes (AES-256-XTS): the first half encrypts the data and the second half encrypts the tweak. Each call handles one data unit of 16 bytes to 2^20 blocks, with ciphertext stealing for a partial last block. Nothing allocates.
Gotchas#
XTS does not detect changes to the ciphertext. Encryption rejects a key whose halves are equal.
Implementation AesXts#
impl AesXtsAssociated function encrypt#
pub fn encrypt(key: &[u8], tweak: &[u8], plaintext: &[u8], ciphertext: &mut [u8]) -> Result<(), AesXtsError>Encrypts the data unit plaintext with key and tweak into the first plaintext.length
bytes of ciphertext.
Errors#
InvalidKeyLengthifkeyis not 32 or 64 bytes.DuplicateKeyHalvesif the two halves ofkeyare equal.InvalidIvLengthiftweakis not 16 bytes.InvalidInputLengthifplaintextis shorter than 16 bytes or longer than 2^20 blocks.OutputTooSmallifciphertextis shorter thanplaintext.
Associated function decrypt#
pub fn decrypt(key: &[u8], tweak: &[u8], ciphertext: &[u8], plaintext: &mut [u8]) -> Result<(), AesXtsError>Decrypts the data unit ciphertext with key and tweak into the first
ciphertext.length bytes of plaintext.
Errors#
InvalidKeyLengthifkeyis not 32 or 64 bytes.InvalidIvLengthiftweakis not 16 bytes.InvalidInputLengthifciphertextis shorter than 16 bytes or longer than 2^20 blocks.OutputTooSmallifplaintextis shorter thanciphertext.
Category: Cryptography.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.