silk.crypto.aes_ccm.
Encrypt and authenticate data with AES-CCM (NIST SP 800-38C, RFC 3610).
When to use#
Use AesCcm where a protocol names CCM, such as Bluetooth, Zigbee, some TLS 1.2 suites, or
Node's aes-128-ccm. For new designs, silk.crypto.aes_gcm is faster and more common.
Details#
The key is 16, 24, or 32 bytes. The nonce is 7 to 13 bytes, and a shorter nonce leaves more room
for the message length: a message is at most 2^(8 * (15 - nonce length)) - 1 bytes. The tag is
4, 6, 8, 10, 12, 14, or 16 bytes and is separate from the ciphertext. The associated data
(aad) is authenticated but not encrypted. CCM needs the whole message to start, so there is no
streaming form. Nothing allocates.
Errors#
The functions return an AesCcmError. All checks come before the first write, and on any
error the output buffers do not change. AesCcm.open writes no plaintext unless the tag is
correct.
Gotchas#
The same key and nonce must never encrypt two messages. Authentication does not stop replay. The functions do not erase their copies of the key.
Examples#
Encrypt and decrypt#
import silk.crypto.aes_ccm { AesCcm, AesCcmError }
import silk.core.result { Result }
pub fn main() -> i32 {
let key: [u8; 16] = [3; 16]
let nonce: [u8; 12] = [9; 12]
let mut ciphertext: [u8; 5] = [0; 5]
let mut tag: [u8; 16] = [0; 16]
if let Result.Failure { error: _ } = AesCcm.seal(&key, &nonce, b"v1", b"hello", &mut ciphertext, &mut tag) {
return 1
}
let mut plaintext: [u8; 5] = [0; 5]
if let Result.Failure { error: _ } = AesCcm.open(&key, &nonce, b"v1", &ciphertext, &tag, &mut plaintext) {
return 1
}
if plaintext[0] != 104 {
return 1
}
return match AesCcm.open(&key, &nonce, b"v2", &ciphertext, &tag, &mut plaintext) {
Result<(), AesCcmError>.Failure { error: AesCcmError.AuthenticationFailed } => 0
_ => 1
}
}Import as AesCcm with import silk.crypto.aes_ccm { AesCcm }.
Public declarations: 2.
AesCcmError#
pub enum AesCcmErrorThe reason that AesCcm.seal or AesCcm.open rejected a call. 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 7 to 13 bytes.
InvalidTagLength#
InvalidTagLengthThe tag is not 4, 6, 8, 10, 12, 14, or 16 bytes.
OutputTooSmall#
OutputTooSmallThe output is shorter than the input message.
LimitExceeded#
LimitExceededThe message is too long for the length field that the nonce length leaves.
AuthenticationFailed#
AuthenticationFailedThe tag is not correct for the key, nonce, associated data, and ciphertext.
Implementation Debug for AesCcmError#
impl Debug for AesCcmErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as InvalidKeyLength.
AesCcm#
pub struct AesCcmFunctions that encrypt and authenticate with AES-CCM (NIST SP 800-38C).
Details#
The key is 16, 24, or 32 bytes, the nonce 7 to 13 bytes, and the tag 4 to 16 bytes in steps of two. The ciphertext has the same length as the plaintext. Nothing allocates. All checks come before the first write.
Gotchas#
The same key and nonce must never encrypt two messages.
Implementation AesCcm#
impl AesCcmAssociated function seal#
pub fn seal(key: &[u8], nonce: &[u8], aad: &[u8], plaintext: &[u8], ciphertext: &mut [u8], tag: &mut [u8]) -> Result<(), AesCcmError>Encrypts plaintext into ciphertext and writes the tag to tag, whose length picks the tag
length.
Errors#
InvalidKeyLengthifkeyis not 16, 24, or 32 bytes.InvalidNonceLengthifnonceis not 7 to 13 bytes.InvalidTagLengthiftagis not 4, 6, 8, 10, 12, 14, or 16 bytes.OutputTooSmallifciphertextis shorter thanplaintext.LimitExceededifplaintextdoes not fit the length field.
Associated function open#
pub fn open(key: &[u8], nonce: &[u8], aad: &[u8], ciphertext: &[u8], tag: &[u8], plaintext: &mut [u8]) -> Result<(), AesCcmError>Checks tag, and if it is correct, decrypts ciphertext into plaintext.
The function checks the tag before it writes plaintext, so it runs the key stream twice.
Errors#
InvalidKeyLengthifkeyis not 16, 24, or 32 bytes.InvalidNonceLengthifnonceis not 7 to 13 bytes.InvalidTagLengthiftagis not 4, 6, 8, 10, 12, 14, or 16 bytes.OutputTooSmallifplaintextis shorter thanciphertext.LimitExceededifciphertextdoes not fit the length field.AuthenticationFailedif the tag is not correct.plaintextdoes not change.
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.