7个版本 (4个重大更新)
0.5.0 | 2020年6月13日 |
---|---|
0.4.1 | 2020年3月17日 |
0.4.0 | 2019年12月1日 |
0.3.0 | 2019年9月9日 |
0.1.0 | 2019年8月19日 |
2613 在 密码学 中
每月下载量 202
47KB
789 行
aes-ccm
一个纯Rust,#![no_std]
,零分配AES-CCM实现,从TinyCrypt移植而来,使用RustCrypto的AES(支持可选的硬件实现)。
它实现了aead::AeadInPlace
特质,因此可以与其他实现无缝配合使用。
概述
CCM("带有CBC-MAC的计数器")模式是NIST批准的操作模式,定义在SP 800-38C中。
此实现接受
- 非空有效载荷和关联数据(它加密和验证有效载荷,并验证关联数据)。
- 非空有效载荷和空关联数据(它加密和验证有效载荷)。
- 非空关联数据和空有效载荷(它退化到关联数据的验证模式)。
实现接受0到2^16字节之间的任何长度的有效载荷和0到(2^16 - 2^8)字节之间的任何长度的关联数据。
用法
use aes_ccm::{
aead::{consts::U8, Aead, NewAead, Payload},
Aes128Ccm,
};
let key = [
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
];
// `U8` represents the tag size as a `typenum` unsigned (8-bytes here)
let ccm = Aes128Ccm::<U8>::new(&key.into());
let nonce = [
0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 0xA1, 0xA2, 0xA3,
0xA4, 0xA5,
];
let msg = [
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
0x1E,
];
let associated_data = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
let ciphertext = ccm
.encrypt(
&nonce.into(),
Payload {
aad: &associated_data,
msg: &msg,
},
)
.unwrap();
let plaintext = ccm
.decrypt(
&nonce.into(),
Payload {
aad: &associated_data,
msg: &ciphertext,
},
)
.unwrap();
assert_eq!(&msg[..], plaintext.as_slice());
原地使用(消除alloc
要求)
此crate有一个可选的alloc
功能,可以在例如没有堆的微控制器环境中禁用。
方法 AeadInPlace::encrypt_in_place
和 AeadInPlace::decrypt_in_place
可以接受实现了 aead::Buffer
特性的任何类型,该特性包含用于加密的明文或用于解密的密文。
注意,如果您启用此crate的 heapless
功能,您将获得 aead::Buffer
的实现,适用于 heapless::Vec
(由 aead
crate作为 aead::heapless::Vec
重导出),然后可以将它作为 buffer
参数传递给就地加密和解密方法
use aes_ccm::{
aead::{
consts::{U128, U8},
heapless::Vec,
AeadInPlace, NewAead,
},
Aes128Ccm,
};
let key = [
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
];
// `U8` represents the tag size as a `typenum` unsigned (8-bytes here)
let ccm = Aes128Ccm::<U8>::new(&key.into());
let nonce = [
0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 0xA1, 0xA2, 0xA3,
0xA4, 0xA5,
];
let associated_data = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
let plaintext = [
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
0x1E,
];
let mut buffer: Vec<u8, U128> = Vec::new();
buffer.extend_from_slice(&plaintext).unwrap();
// Encrypt `buffer` in-place, replacing the plaintext contents with
// ciphertext
ccm.encrypt_in_place(&nonce.into(), &associated_data, &mut buffer)
.unwrap();
// `buffer` now contains the message ciphertext
assert_ne!(&buffer, &plaintext);
// Decrypt `buffer` in-place, replacing its ciphertext contents with the
// original plaintext
ccm.decrypt_in_place(&nonce.into(), &associated_data, &mut buffer)
.unwrap();
assert_eq!(&buffer, &plaintext);
安全性
我不是密码学家,这个文档没有经过任何审核。然而,它是TinyCrypt的谨慎移植,所以如果它是可靠的,那么这个也应该是。
MAC长度参数是一个重要参数,用于估计对碰撞攻击(旨在找到产生相同认证标签的不同消息)的安全性。实现接受任何介于4和16之间的偶数,如SP 800-38C中建议的那样。
RFC 3610,它还指定了CCM,提出了一些相关的安全建议,例如
- 建议大多数应用程序使用大于8的MAC长度。
- 使用相同的nonce对使用相同密钥加密的两个不同消息会破坏CCM模式的安全性。
许可证
根据您的选择,许可如下
。
这是TinyCrypt的CCM模式的移植,其许可证文件在LICENSE-3RD-PARTY中。
贡献
除非您明确表示,否则您有意提交的任何贡献,根据Apache-2.0许可证定义,将按上述方式双许可,不附加任何额外条款或条件。
依赖关系
约600KB
约14K SLoC