silk.crypto.aes_ocb.
Encrypt and authenticate data with AES-OCB3 (RFC 7253), for a message in parts.
When to use#
Use AesOcbEncryptor and AesOcbDecryptor where a protocol names OCB, or for Node's
aes-128-ocb. For new designs, silk.crypto.aes_gcm is the common choice.
Details#
The key is 16, 24, or 32 bytes, the nonce 1 to 15 bytes, and the tag 1 to 16 bytes. The tag
length is fixed when the value is made, because OCB mixes it into the nonce. The associated
data (aad) is authenticated but not encrypted. update writes the ciphertext of every
complete 16-byte block and keeps a partial block, so AesOcbEncryptor.updateLength says how
many bytes a call writes. finish writes the rest. Nothing allocates.
Errors#
The functions return an AesOcbError. All checks come before the first write, and on any
error the output buffers do not change.
Gotchas#
The same key and nonce must never encrypt two messages. AesOcbDecryptor.update writes
plaintext before the tag is checked: do not use it until AesOcbDecryptor.finish succeeds. A
message is at most 2^32 blocks. The values do not erase their copies of the key.
Examples#
Encrypt and decrypt#
import silk.crypto.aes_ocb { AesOcbDecryptor, AesOcbEncryptor, AesOcbError }
import silk.core.result { Result }
pub fn main() -> i32 {
let key: [u8; 16] = [4; 16]
let nonce: [u8; 12] = [8; 12]
let mut encryptor = match AesOcbEncryptor.make(&key, &nonce, b"v1", 16) {
Result<AesOcbEncryptor, AesOcbError>.Success { value } => move value
Result<AesOcbEncryptor, AesOcbError>.Failure { error: _ } => { return 1 }
}
let mut ciphertext: [u8; 5] = [0; 5]
let mut tag: [u8; 16] = [0; 16]
// Five bytes are less than a block, so update writes nothing and finish writes them.
if let Result.Failure { error: _ } = encryptor.update(b"hello", &mut ciphertext) { return 1 }
if let Result.Failure { error: _ } = encryptor.finish(&mut ciphertext, &mut tag) { return 1 }
let mut decryptor = match AesOcbDecryptor.make(&key, &nonce, b"v1", 16) {
Result<AesOcbDecryptor, AesOcbError>.Success { value } => move value
Result<AesOcbDecryptor, AesOcbError>.Failure { error: _ } => { return 1 }
}
let mut plaintext: [u8; 5] = [0; 5]
if let Result.Failure { error: _ } = decryptor.update(&ciphertext, &mut plaintext) { return 1 }
return match decryptor.finish(&mut plaintext, &tag) {
Result<usize, AesOcbError>.Success { value } => if value == 5 && plaintext[0] == 104 { 0 } else { 1 }
Result<usize, AesOcbError>.Failure { error: _ } => 1
}
}Import as AesOcbEncryptor with import silk.crypto.aes_ocb { AesOcbEncryptor }.
Public declarations: 3.
AesOcbError#
pub enum AesOcbErrorThe reason that an OCB call was rejected. The checks run in the order of the variants, and the first failure is returned.
InvalidKeyLength#
InvalidKeyLengthThe key is not 16, 24, or 32 bytes.
InvalidNonceLength#
InvalidNonceLengthThe nonce is not 1 to 15 bytes.
InvalidTagLength#
InvalidTagLengthThe tag length is not 1 to 16 bytes, or a tag buffer does not have that length.
OutputTooSmall#
OutputTooSmallThe output is shorter than the bytes the call writes.
LimitExceeded#
LimitExceededThe message is longer than 2^32 blocks.
AuthenticationFailed#
AuthenticationFailedThe tag is not correct for the key, nonce, associated data, and ciphertext.
Implementation Debug for AesOcbError#
impl Debug for AesOcbErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as InvalidKeyLength.
AesOcbEncryptor#
pub struct AesOcbEncryptorA streaming AES-OCB3 encryptor (RFC 7253).
Details#
Make one with AesOcbEncryptor.make, give the message with AesOcbEncryptor.update, then
call AesOcbEncryptor.finish for the last partial block and the tag. Any split of the
message gives the same result. Nothing allocates.
Gotchas#
The same key and nonce must never encrypt two messages. The value holds key material and is not erased when it is dropped.
Implementation AesOcbEncryptor#
impl AesOcbEncryptorAssociated function make#
pub fn make(key: &[u8], nonce: &[u8], aad: &[u8], tagLength: usize) -> Result<AesOcbEncryptor, AesOcbError>Returns an encryptor for key and nonce that authenticates aad and makes a tag of
tagLength bytes.
Errors#
InvalidKeyLengthifkeyis not 16, 24, or 32 bytes.InvalidNonceLengthifnonceis not 1 to 15 bytes.InvalidTagLengthiftagLengthis not 1 to 16.
Method updateLength#
pub fn updateLength(self: &Self, length: usize) -> usizeReturns how many bytes AesOcbEncryptor.update writes for length more input bytes: every
complete 16-byte block.
Method update#
pub fn update(self: &mut Self, plaintext: &[u8], ciphertext: &mut [u8]) -> Result<usize, AesOcbError>Encrypts the complete blocks of the buffered bytes and plaintext into ciphertext and
returns how many bytes it wrote. A partial block stays buffered.
Errors#
On an error the state and ciphertext do not change.
OutputTooSmallifciphertextis shorter thanAesOcbEncryptor.updateLength.LimitExceededif the message grows past 2^32 blocks.
Method finish#
pub fn finish(self: Self, ciphertext: &mut [u8], tag: &mut [u8]) -> Result<usize, AesOcbError>Encrypts the buffered partial block into ciphertext, writes the tag to tag, and returns
how many ciphertext bytes it wrote (0 to 15).
Errors#
InvalidTagLengthiftagis not the tag length given toAesOcbEncryptor.make.OutputTooSmallifciphertextis shorter than the buffered bytes.
AesOcbDecryptor#
pub struct AesOcbDecryptorA streaming AES-OCB3 decryptor (RFC 7253).
Details#
Make one with AesOcbDecryptor.make, give the ciphertext with AesOcbDecryptor.update,
then call AesOcbDecryptor.finish with the received tag. Nothing allocates.
Gotchas#
AesOcbDecryptor.update writes plaintext before the tag is checked. Do not use or release it
until AesOcbDecryptor.finish succeeds. The value holds key material and is not erased when it
is dropped.
Implementation AesOcbDecryptor#
impl AesOcbDecryptorAssociated function make#
pub fn make(key: &[u8], nonce: &[u8], aad: &[u8], tagLength: usize) -> Result<AesOcbDecryptor, AesOcbError>Returns a decryptor for key and nonce that authenticates aad and checks a tag of
tagLength bytes.
Errors#
InvalidKeyLengthifkeyis not 16, 24, or 32 bytes.InvalidNonceLengthifnonceis not 1 to 15 bytes.InvalidTagLengthiftagLengthis not 1 to 16.
Method updateLength#
pub fn updateLength(self: &Self, length: usize) -> usizeReturns how many bytes AesOcbDecryptor.update writes for length more input bytes: every
complete 16-byte block.
Method update#
pub fn update(self: &mut Self, ciphertext: &[u8], plaintext: &mut [u8]) -> Result<usize, AesOcbError>Decrypts the complete blocks of the buffered bytes and ciphertext into plaintext and
returns how many bytes it wrote. The plaintext is not authenticated until
AesOcbDecryptor.finish succeeds.
Errors#
On an error the state and plaintext do not change.
OutputTooSmallifplaintextis shorter thanAesOcbDecryptor.updateLength.LimitExceededif the ciphertext grows past 2^32 blocks.
Method finish#
pub fn finish(self: Self, plaintext: &mut [u8], tag: &[u8]) -> Result<usize, AesOcbError>Decrypts the buffered partial block into plaintext, checks tag, and returns how many
plaintext bytes it wrote (0 to 15).
Errors#
InvalidTagLengthiftagis not the tag length given toAesOcbDecryptor.make.OutputTooSmallifplaintextis shorter than the buffered bytes.AuthenticationFailedif the tag is not correct. Discard all plaintext this value wrote.
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.