CCM加密學習


這幾天終於搞定了AES硬件加密工具的使用,幾種簡單的加密模式也都實驗通過了,比較麻煩的一種是CCM模式的加密,它是CTR加密模式和CMAC認證算法的混合使用。本文先介紹CCM模式的原理與基本實現,然后結合OpenSSL的加密庫,了解一下具體過程,最后,在AES硬件加密引擎上實現。

 

CCM介紹

CCM是CTR加密模式和CMAC認證算法的混合使用,常用在需要同時加密和認證的領域,比如WiFi安全中的WPE協議,它就使用了AES-CCM模式。

CCM首先使用CBC-MAC模式來認證傳輸幀,然后使用CTR模式來加密幀。在這里,用於加密的初始化向量IV構成結構如下:

image

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

image

Bit7設置為0,Adata為1的話,表示此幀有額外的認證數據,為0則表示沒有額外的認證數據。M為認證域長度經過轉換后的結果.L固定為1. 在不同的安全模式下,初始化向量中的Flags值不同。image從上表可以看出,只要有MIC的存在,那么Adata就必須為1.

 

 

首先引入兩個CCM模式下的兩個參數:

L : 長度域,取值為2~8, OpenSSL中缺省為8

M  :  tag的長度,可選范圍為4,6,8,10,12,14,16.OpenSSL中缺省為12

 

 

接下來,將詳細描述如何在硬件加密模塊上實現CCM模式的認證和加密。

 

在硬件AES加密引擎上面,沒有完整的實現CCM模式的加密,需要軟硬件一起配合,才能實現CCM模式。

在CCM模式下CBC-MAC

對於待加密數據中的前數據塊,采用CBC-MAC模式加密生成認證域,對於最后一個數據塊,需要改為使用CBC模式加密。當最后一個數據塊載入AES硬件加密引擎后,從AES讀出的就是消息的MAC校驗碼。

在CCM模式下CTR

以下是認證執行的步驟。

1. 載入加密密鑰

2. 載入全0的初始化向量

3. 構建一個16個字節的數組B,其第一個元素B[0]需要有如下的構造。

image

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

image

其他內容元素按規則來填充。

4. 按照16字節加密塊來划分,第一個塊填充初始化向量,第二個塊填充Adata相關內容,第三個塊(或者更多塊)填充明文內容

5. 先按照CBC_MAC模式加密前N-1個塊,最后一個數據塊使用CBC模式來加密.當認證域長度為16時,CBC_MAC加密后的內容是不變的,如果不為16,則高M字節內容保持不變,其余字節變為0.

6. 等待加密完成后,從結果中,讀出Mval個字節到Cstate就可以了。

函數頭說明:

 

void Test_SSP_CCM_Auth (uint8 Mval,     // 認證域字節長度 [0,4,8,16]

                                     uint8 *N,       // N 指向13字節的隨機數

                                     uint8 *M,   // M 指向明文的指針

                                     uint16 len_m, // len_m 明文長度

                                     uint8 *A,       // A 指向Adata的指針
                                          uint16 len_a,  // len_a 數據長度

                                     uint8 *AesKey,  //AesKey 指向密鑰的指針

                                     uint8 *Cstate)   //輸出Cstate 緩存

 

 

加密步驟:

CCM模式下的加密,需要使用前面生產的Cstate值,具體使用步驟如下:

加密也需要初始化向量,其構成如下:

image

當在OFB模式,將認證域加密生產U時,CTR的值必須為0,當在CTR模式,CTR的值必須不為0

1. 創建A塊,並按照規則來填充A[0],當做后的IV

2. 創建T塊,將Cstate的前Mval填充到T中。

3.分配緩存,用於填充輸入明文,不足16字節的補0.

4. 以OFB模式,將明文T加密輸出到Cstate[也叫做U]。當認證域長度為16時,上傳緩存內容保持不變,如果不為16,則上傳內容的高M位保持不變,其余字節變為0.結果為U.

5. 以CTR模式,將IV最高字節設置為1,重新載入IV,然后加密明文緩存塊

6. 最后的結果,是輸出的密文塊加上U,都是16字節對齊的。

void Test_SSP_CCM_Encrypt (uint8 Mval,   //認證域字節長度 [0,4,8,16]

                                         uint8 *N,     //指向13個字節的隨機數指針

                                         uint8 *M,    //指向待加密明文 (明文輸出也在這里,多加16個字節的空間)

                                         uint16 len_m,    //待加密明文長度
                                              uint8 *AesKey,  //AekKey密鑰指針

                                         uint8 *Cstate)   //明文的認證域內容

 

從目前淺顯的理解上來看,CCM的認證和加密好像是相互獨立設置的,從邏輯上,一段明文進來,先通過認證,產生一個tag,在后續加密時使用此Tag和IV生成一個新的校驗U.原負載明文填充滿后,通過CTR模式來加密數據,在密文的后面附上新的校驗碼U,這樣,就完成了校驗和加密的過程。

---------------今天就先介紹到這里,還有解密過程和代碼沒貼上來,周一來了再貼-----------------------

 

-------------------周一來了,整理剩下的代碼---------------------------------------------------

解密的過程和加密的相反,先解密,再解認證。

void Test_SSP_CCM_Decrypt (uint8 Mval,     //認證域長度

                uint8 *N,       //隨機數

                uint8 *C,      //待解密密文指針

                uint16 len_c,    //待解密密文長度
                                               uint8 *AesKey,        //解密密鑰

                uint8 *Cstate)         //認證域內容

解密流程:

1. 先利用隨機數,構造A向量

2.   從待解密密文中提取最后Mval字節(補全16個字節)到U向量中

3. 通過OFB模式,來將U解密成T

4.   通過CTR模式,將密文解密成明文

5. 最后,將T附加在明文后

 

鑒權的過程是利用上述解密出來的明文,全場為len_c,認證域長度位為Mval,位置在字節的尾端,鑒權就是把解密的明文,通過(len_c-Mval)長度鑒權計算,把得到的結果和解密輸出的結果進行對比,如果相同,則鑒權成功,否則,鑒權失敗。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

參考資料:openssl學習之ccm,gcm 模式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM