(本文资料主要来自:RFC3610)
CCM是Cipher Block Chaining Message Authentication Code (CBC-MAC)和Counter模式(CTR)的组合。可以同时生存认证信息和对数据加密。CCM广泛用于互联网和物联网中对传输数据进行保护。而且很多MCU中都实现了对CCM的硬件支持,使用也比较方便。下面的介绍主要根据RFC3610整理。
在数据通信中,传输中的数据包由两部分构成:数据包头和用户数据(payload)。用户数据一般需要加密以防止窃听。但传输路上的设备(路由器、交换机等)往往需要参照数据包头以保证把数据包能正确地送到目的地,因此数据包头不能加密。网络通信中的风险除了窃听,还有恶意篡改、伪造等其他行为。因此为了保证收到的数据包没有被篡改,需要对整个数据、包括包头进行认证。
数据认证
认证采用CBC-MAC模式。需要指定两个参数:
- 认证域的长度M:可以是4、6、8、10、12、14、16。
- 长度域的长度(大小)L。
M、L均用3bit编码,编码方式如下:
M域:(M-2)/2;
L域:L-1。
为了认证处理,需要的信息如下:
- 密钥K
- Nonce N,长度为:15-L。Nonce在一个密钥的使用周期内必须确保唯一。
- 明文信息m,其长度l(m)的范围为0≤l(m)<2^(8L),目的是其长度确保可以由L字节的长度域保存。
- 额外认证数据a(一般为数据包的报头),其长度为l(a),大小范围为:0≤l(a)<2^(64)。这部分数据只认证(Authenticate),不加密。因此也不包含在该模式的输出中。主要是用于认证明文的报头、或影响消息解析的上下文信息。
CBC-MAC的操作流程如下:
为了利用上述算法,需要构建各个块mi,也叫B_i。每块的大小是16bytes。
B_0由Nonce和一下特殊规则构成:
Octet Number | Contents |
---|---|
0 | Flags |
1 … 15-L | Nonce N |
16-L … 15 | l(m) |
第一个字节的Flags域由以下bit构成:
Bit Number | Contents |
---|---|
7 | Reserved (always zero) |
6 | Adata,=0 IF l(a) = 0;=1 IF l(a)>0 |
5…3 | 根据认证域长度编码(M-2)/2 |
2…0 | 根据长度域长度编码(L-1),(L=1为保留值,禁止使用) |
如果l(a)>0,在B_0之后,会添加一个或多个认证数据块(Authentication Data Block)。认证数据块由以下方式构建:将l(a)按以下方式编码,并添加到额外认证数据a之前,然后分割为16字节的数据块。如果不足,则在最后一个数据块中补0。
l(a)的编码方式如下,并且most-significant-byte first order。
First two octets | Followed by | Comment |
---|---|---|
0x0000 | Nothing | Reserved |
0x0001 … 0xFEFF | Nothing | For 0 < l(a) < (2^16 - 2^8) |
0xFF00 … 0xFFFD | Nothing | Reserved |
0xFFFE | 4 octets of l(a) | For (2^16 - 2^8) <= l(a) < 2^32 |
0xFFFF | 8 octets of l(a) | For 2^32 <= l(a) < 2^64 |
在上述块之后,增进消息块:分割消息m为16字节的块,并在最后一块根据需要补0为一个完整的16字节块。
对上述生存的数据块B_i,基本的计算公式如下:
X_1 := E( K, B_0 )
X_i+1 := E( K, X_i XOR B_i ) for i=1, …, n
T := first-M-bytes( X_n+1 )
其中:
E()—block cipher encryption function
T—MAC value.
数据加密
采用Counter(CTR)模式,其操作流程如下:
需要进行加密计算的Counter域A_i根据以下方式生成:
Octet Number | Contents |
---|---|
0 | Flags |
1 … 15-L | Nonce N |
16-L … 15 | Counter i |
其中的Counter i域以most-significant-byte first order形式编码。第一个字节的Flags域由以下bit构成:
Bit Number | Contents |
---|---|
7 | Reserved (always zero) |
6 | Reserved (always zero) |
5…3 | Zero |
2…0 | L’=L-1,(L:长度域长度,L=1为保留值,禁止使用) |
加密计算后的结果表示为S_i:\
S_i := E( K, A_i ) for i=0, 1, 2, …
将上述加密后的结果S_1, S_2, S_3 … .组合成数据串,并取前l(m)个字节与明文数据m进行XOR操作,得到密文。注意:S_0不用于XOR操作。
最终的认证串的值U则利用S_0计算得到,如下所示:
U := T XOR first-M-bytes( S_0 )