這幾天終于搞定了AES硬件加密工具的使用,幾種簡(jiǎn)單的加密模式也都實(shí)驗通過(guò)了,比較麻煩的一種是CCM模式的加密,它是CTR加密模式和CMAC認證算法的混合使用。本文先介紹CCM模式的原理與基本實(shí)現,然后結合OpenSSL的加密庫,了解一下具體過(guò)程,最后,在A(yíng)ES硬件加密引擎上實(shí)現。
CCM是CTR加密模式和CMAC認證算法的混合使用,常用在需要同時(shí)加密和認證的領(lǐng)域,比如WiFi安全中的WPE協(xié)議,它就使用了AES-CCM模式。
CCM首先使用CBC-MAC模式來(lái)認證傳輸幀,然后使用CTR模式來(lái)加密幀。在這里,用于加密的初始化向量IV構成結構如下:

sequence counter表示在一個(gè)幀中16個(gè)字節塊的數目. Flags域結構如下:

Bit7設置為0,Adata為1的話(huà),表示此幀有額外的認證數據,為0則表示沒(méi)有額外的認證數據。M為認證域長(cháng)度經(jīng)過(guò)轉換后的結果.L固定為1. 在不同的安全模式下,初始化向量中的Flags值不同。

首先引入兩個(gè)CCM模式下的兩個(gè)參數:
L?。骸¢L(cháng)度域,取值為2~8, OpenSSL中缺省為8
M : tag的長(cháng)度,可選范圍為4,6,8,10,12,14,16.OpenSSL中缺省為12
接下來(lái),將詳細描述如何在硬件加密模塊上實(shí)現CCM模式的認證和加密。
在硬件AES加密引擎上面,沒(méi)有完整的實(shí)現CCM模式的加密,需要軟硬件一起配合,才能實(shí)現CCM模式。
對于待加密數據中的前數據塊,采用CBC-MAC模式加密生成認證域,對于最后一個(gè)數據塊,需要改為使用CBC模式加密。當最后一個(gè)數據塊載入AES硬件加密引擎后,從AES讀出的就是消息的MAC校驗碼。
以下是認證執行的步驟。
1. 載入加密密鑰
2. 載入全0的初始化向量
3. 構建一個(gè)16個(gè)字節的數組B,其第一個(gè)元素B[0]需要有如下的構造。

其中,Flag的值和安全級別有關(guān)系,具體關(guān)系間下表。

其他內容元素按規則來(lái)填充。
4. 按照16字節加密塊來(lái)劃分,第一個(gè)塊填充初始化向量,第二個(gè)塊填充Adata相關(guān)內容,第三個(gè)塊(或者更多塊)填充明文內容
5. 先按照CBC_MAC模式加密前N-1個(gè)塊,最后一個(gè)數據塊使用CBC模式來(lái)加密.當認證域長(cháng)度為16時(shí),CBC_MAC加密后的內容是不變的,如果不為16,則高M(jìn)字節內容保持不變,其余字節變?yōu)?.
6. 等待加密完成后,從結果中,讀出Mval個(gè)字節到Cstate就可以了。
函數頭說(shuō)明:
void Test_SSP_CCM_Auth (uint8 Mval, // 認證域字節長(cháng)度 [0,4,8,16]
uint8 *N, // N 指向13字節的隨機數
uint8 *M, // M 指向明文的指針
uint16 len_m, // len_m 明文長(cháng)度
uint8 *A, // A 指向Adata的指針
uint16 len_a, // len_a 數據長(cháng)度
uint8 *AesKey, //AesKey 指向密鑰的指針
uint8 *Cstate) //輸出Cstate 緩存
加密步驟:
CCM模式下的加密,需要使用前面生產(chǎn)的Cstate值,具體使用步驟如下:
加密也需要初始化向量,其構成如下:

當在OFB模式,將認證域加密生產(chǎn)U時(shí),CTR的值必須為0,當在CTR模式,CTR的值必須不為0
1. 創(chuàng )建A塊,并按照規則來(lái)填充A[0],當做后的IV
2. 創(chuàng )建T塊,將Cstate的前Mval填充到T中。
3.分配緩存,用于填充輸入明文,不足16字節的補0.
4. 以OFB模式,將明文T加密輸出到Cstate[也叫做U]。當認證域長(cháng)度為16時(shí),上傳緩存內容保持不變,如果不為16,則上傳內容的高M(jìn)位保持不變,其余字節變?yōu)?.結果為U.
5. 以CTR模式,將IV最高字節設置為1,重新載入IV,然后加密明文緩存塊
6. 最后的結果,是輸出的密文塊加上U,都是16字節對齊的。
void Test_SSP_CCM_Encrypt (uint8 Mval, //認證域字節長(cháng)度 [0,4,8,16]
uint8 *N, //指向13個(gè)字節的隨機數指針
uint8 *M, //指向待加密明文 (明文輸出也在這里,多加16個(gè)字節的空間)
uint16 len_m, //待加密明文長(cháng)度
uint8 *AesKey, //AekKey密鑰指針
uint8 *Cstate) //明文的認證域內容
從目前淺顯的理解上來(lái)看,CCM的認證和加密好像是相互獨立設置的,從邏輯上,一段明文進(jìn)來(lái),先通過(guò)認證,產(chǎn)生一個(gè)tag,在后續加密時(shí)使用此Tag和IV生成一個(gè)新的校驗U.原負載明文填充滿(mǎn)后,通過(guò)CTR模式來(lái)加密數據,在密文的后面附上新的校驗碼U,這樣,就完成了校驗和加密的過(guò)程。
---------------今天就先介紹到這里,還有解密過(guò)程和代碼沒(méi)貼上來(lái),周一來(lái)了再貼-----------------------
-------------------周一來(lái)了,整理剩下的代碼---------------------------------------------------
解密的過(guò)程和加密的相反,先解密,再解認證。
void Test_SSP_CCM_Decrypt (uint8 Mval, //認證域長(cháng)度
uint8 *N, //隨機數
uint8 *C, //待解密密文指針
uint16 len_c, //待解密密文長(cháng)度
uint8 *AesKey, //解密密鑰
uint8 *Cstate) //認證域內容
解密流程:
1. 先利用隨機數,構造A向量
2. 從待解密密文中提取最后Mval字節(補全16個(gè)字節)到U向量中
3. 通過(guò)OFB模式,來(lái)將U解密成T
4. 通過(guò)CTR模式,將密文解密成明文
5. 最后,將T附加在明文后
鑒權的過(guò)程是利用上述解密出來(lái)的明文,全場(chǎng)為len_c,認證域長(cháng)度位為Mval,位置在字節的尾端,鑒權就是把解密的明文,通過(guò)(len_c-Mval)長(cháng)度鑒權計算,把得到的結果和解密輸出的結果進(jìn)行對比,如果相同,則鑒權成功,否則,鑒權失敗。
聯(lián)系客服