CRYP簡介
MCU加/解密可分為對稱加/解密、非對稱加/解密、以及HASH算法,以上加/解密算法均可通過CAVP FIPS認證,用于各類安全相關應用。其中,包含DES、三重DES(TDES)或AES(128、192或256)等算法的加密處理器(CRYP)即為對稱加/解密算法。通過CRYP,可實現對數據進行加密或解密,且該加密處理器完全兼容下列標準:
·聯邦信息處理標準出版物“FIPS PUB 46-3,1999年10月25日”規定的數據加密標準(DES和TDES)。它遵循美國國家標準協會(ANSI)X9.52標準。
·聯邦信息處理標準出版物(FIPS PUB 197,2001年11月26日)規定的高級加密標準(AES)。
CRYP處理器可在電子密碼本(ECB)模式或加密分組鏈接(CBC)模式下使用DES和TDES算法執行數據加密和解密。
CRYP外設為32位AHB2外設。它支持傳入數據和已處理數據的DMA傳輸,并具有輸入和輸出FIFO(分別為8個字深),本次例程采用DES128 ECB算法進行驗證,文章將著重講解該部分,其余算法詳見參考手冊。
CRYP 主要特性
·適用于AES、DES和TDES加密和解密操作
·DES
-直接執行簡單DES算法(使用單一密鑰K1)
-支持ECB和CBC鏈接算法
-支持64位、128位和192位密鑰(包括奇偶校驗)
-支持在CBC模式下使用的2×32位初始化向量(IV)
-使用DES處理一個64位塊需要16個HCLK周期
CRYP功能說明
加密處理器可實現TDES(同樣支持DES)內核和AES加密內核。
由于TDES和AES算法使用塊密碼,因此,加密前需對不完整的輸入數據塊進行填充(應將額外的位附加到數據串的尾端),解密后需要丟棄填充項。硬件不處理填充操作,需要通過軟件進行處理。圖1顯示了加密處理器的框圖。
圖1加密處理器框圖
1.DES加密內核
--DES加密內核由三部分組成
·DES算法(DEA)
·初始化向量(在CBC模式中使用)
·DES模式:密鑰=[K1]
--DES和TDES電子密碼本(DES/TDES-ECB)模式
·DES-ECB模式加密
DES電子密碼本(DES/TDES-ECB)模式中的加密是通過64位明文數據塊(P)經過位/字節/半字交換(請參見1.3.2節:數據類型的表1)后作為輸入塊(I)。輸入塊通過DEA在加密狀態下使用K1進行加密處理。
若是TDES,則會將上述處理過程的輸出會直接反饋到DEA的輸入,在解密狀態下使用K2執行DES,然后重復將上一步處理的輸出反饋到DEA的輸入,在加密狀態下使用K3執行DES,最后生成的64位輸出塊(O)在執行位/字節/半字交換之后,以密文(C)形式推入OUT FIFO,加密流程如圖2所示。
圖2DES-ECB模式加密
①K:密鑰;C:密文;I:輸入塊;O:輸出塊;P:明文。
·DES/TDES-ECB模式解密
圖3介紹了DES-ECB解密流程,64位密文(C)經過位/字節/半字交換后,作為輸入塊(I),而該密鑰序列將使用與加密過程相反的密鑰序列來實現。輸入塊通過DEA在解密狀態下使用K3進行解密處理,然后,將上述處理過程的輸出會直接反饋到DEA的輸入,在加密狀態下使用K2執行DES,使得新結果會直接反饋到DEA的輸入,在解密狀態下使用K1執行DES,最后,將生成的64位輸出塊(O)再進行位/字節/半字交換后,產生明文(P),以上便是解密過程。
圖3DES-ECB 模式解密
①K:密鑰;C:密文;I:輸入塊;O:輸出塊;P:明文
2.數據類型
將數據寫入CRYP_DIN寄存器時,會一次性向CRYP處理器輸入32位(字)數據。由于DES的原則是每隔64位對數據流進行處理,因此,針對每個64位塊,DES都會對其進行M1到M64的對位編號,其中M1為塊最左側的位,M64為塊最右側的位。
系統存儲器結構采用小端模式:即無論使用何種數據類型(位、字節、16位半字、32位字),最低有效數據均占用最低地址位置。因此,對于從IN FIFO中讀取的數據,在其進入CRYP處理器之前,必須對這些數據執行位、字節或半字交換操作(取決于要加密的數據類型)。在CRYP數據寫入OUT FIFO之前,需要對其執行同樣的交換操作。例如,對ASCII文本流執行字節交換操作。要處理的數據類型通過CRYP控制寄存器(CRYP_CR)中的DATATYPE位字段進行配置。
表1數據類型
圖4展示了根據不同的DATATYPE值,CRYP處理器是如何將IN FIFO中彈出的兩個連續32位字構建成64位數據塊M1...64的過程。同理,也可用該方法擴展構建用于AES加密算法的128位數據塊(對于AES,塊長度為四個32位字,但由于交換僅發生在字級別,因此它與此處描述的TDES的交換過程相同),本文不再贅述。
注意:IN FIFO和CRYP數據塊之間,以及CRYP數據塊和OUT FIFO之間執行相同的交換操作。
圖4根據DATATYPE構建64位塊
3.初始化向量——CRYP_IV0...1(L/R)
初始化向量可視為兩個64位數據項,因此,初始化向量在系統存儲器中的數據格式和表示形式均不同于明文或密碼數據,而且它們不受DATATYPE值的影響。初始化向量采用兩個連續的32位字進行定義,即CRYP_IVL(左部分,記為位IV1...32)和CRYP_IVR(右部分,記為位IV33...64)。
以DES CBC算法為例,加密期間,CRYP_IV0(L/R)位會與一個64位數據塊(即,數據塊的M1...64位)進行異或運算,這里的64位數據塊是根據DATATYPE值交換后從IN FIFO彈出的。當DEA3塊的輸出可用時,該輸出值會復制到CRYP_IV0(L/R)向量,之后,這個新值與IN FIFO彈出的下一個64位數據塊進行異或運算,以此類推。
在DES CBC解密期間,CRYP_IV0(L/R)位首先會與TDEA1塊輸出的64位數據塊(即,M1...64位)進行異或運算,然后異或運算后的結果根據DATATYPE值進行交換并壓入OUT FIFO。異或運算后的結果進行交換并壓入OUT FIFO后,IN FIFO的輸出會取代CRYP_IV0(L/R)值,然后IN FIFO執行彈出操作,隨后可對新的64位數據塊進行處理。
當CRYP_SR寄存器的BUSY位=1b時,針對CRYP_IV0...1(L/R)寄存器的任何寫操作都會被忽略(CRYP_IV0...1(L/R)寄存器內容不會被修改),因此,在修改初始化向量之前,必須檢查BUSY位是否等于0b。
4.CRYP忙碌狀態
當輸入FIFO中有充足的數據(至少有2個字可用于DES算法模式時)、輸出FIFO中有充足的自由空間(至少有2個(DES/TDES)字位置),以及CRYP_CR寄存器中的位CRYPEN=1時,加密處理器會自動開始加密或解密過程(根據CRYP_CR寄存器中ALGODIR位的值)。
在此過程中,執行簡易DES算法需16個AHB2時鐘周期。在整個過程中,CRYP_SR寄存器的BUSY位始終置“1”。完成此過程后,CRYP內核會將兩個(DES)字寫入輸出FIFO,并將BUSY位清零。在CBC、CTR模式下,還會更新初始化向量CRYP_IVx(L/R)R(x=0..3)。
當加密處理器繁忙時(CRYP_SR寄存器中的位BUSY=1b),會忽略針對密鑰寄存器(CRYP_Kx(L/R)R,x=0..3)、初始化寄存器(CRYP_IVx(L/R)R,x=0..3)或CRYP_CR寄存器的位[9:2]的寫操作,且不會修改這些寄存器,因此,不能在加密處理器處理數據塊時修改其配置。不過,可以在BUSY=1時將CRYPEN位清零,這種情況下,只有完成正在進行的DES處理過程并將兩個字的結果寫入輸出FIFO后才能將BUSY位清零。
注意:在DES模式下處理某個塊時,如果輸出FIFO已滿并且輸入FIFO至少含一個新塊,則輸入FIFO會彈出新塊且BUSY位保持置1,直到有足夠的空間可將這個新塊存儲到輸出FIFO。
5.加密或解密執行步驟
--初始化
1)初始化外設(在準備密鑰之前必須輸入密鑰大小和密鑰值,準備好密鑰后,必須立即配置相應算法):
①將對稱密鑰寫入CRYP_KxL/R寄存器(需寫入2到8個寄存器,具體取決于算法);
②使用CRYP_CR寄存器中的DATATYPE位配置數據類型(1位、8位、16位或32位);
③使用CRYP_CR寄存器中的ALGOMODE位配置算法和鏈接(在ECB/CBC中為DES);
④使用CRYP_CR寄存器中的ALGODIR位配置方向(加密/解密);
2)向CRYP_CR寄存器中的FFLUSH位寫入1,刷新IN和OUT FIFO。
--DMA用于存儲器數據傳入和傳出時的處理過程
1)將DMA控制器配置為傳輸存儲器中的輸入數據,傳輸長度為消息的長度。當消息填充并非由外設進行管理時,消息長度必須為整個數量的數據塊,數據傳輸均在突發模式下進行。DES中的突發長度為2個字,應將DMA配置為在完成輸出數據傳輸時設置一個中斷,以指示處理過程已結束;
2)通過向CRYPEN位寫入1來使能加密處理器,將CRYP_DMACR寄存器中的DIEN和DOEN位置1,以使能DMA請求;
3)所有傳輸和處理過程均由DMA和加密處理器管理,DMA中斷表示處理過程已完成,兩個FIFO通常均為空,且BUSY=0;
--在中斷期間通過CPU傳輸數據的處理過程
1)將CRYP_IMSCR寄存器中的INIM和OUTIM位置1,以使能中斷;
2)將CRYP_CR寄存器中的CRYPEN位置1,以使能加密處理器;
3)在中斷中管理輸入數據:將輸入消息加載到IN FIFO,一次性可加載2個字或4個字,或者加載數據直到FIFO已滿。當消息的最后一個字進入FIFO時,可通過將INIM位清零來禁止中斷;
4)在中斷中管理輸出數據:讀取OUT FIFO中的輸出消息。一次可讀取1個塊(2個字或4個字),或者讀取數據直到FIFO為空。讀取最后一個字后,INIM=0、BUSY=0且兩個FIFO均為空(IFEM=1且OFNE=0)。將OUTIM位清零可禁止中斷,而將CRYPEN位清零可禁止外設。
--不使用DMA也不使用中斷時的處理過程
1)將CRYP_CR寄存器中的CRYPEN位置1,以使能加密處理器;
2)將首個塊寫入輸入FIFO(2到8個字);
3)重復以下步驟,直到處理完整個信息:
①等待OFNE=1,然后讀取輸出FIFO(讀取1個塊,或FIFO為空為止);
②等待IFNF=1,然后寫入INFIFO(寫入1個塊,或FIFO已滿為止;
處理過程結束時,BUSY=0且兩個FIFO均為空(IFEM=1且OFNE=0),將CRYPEN位清零可禁止外設。
CRYP中斷
CRYP可產生兩個可單獨屏蔽的中斷源。這兩個中斷源共用同一個中斷信號,且該中斷信號是CRYP發出的唯一中斷信號,用于驅動NVIC(嵌套向量中斷控制器)。這一組合中斷是兩個單獨屏蔽的中斷源的或運算結果,如果下面列出的各個中斷中的任何一個中斷產生,則此組合中斷即會產生。
通過更改CRYP_IMSCR寄存器中的屏蔽位,可單獨使能或禁止各個中斷源,將相應的屏蔽位置“1”以使能中斷。
關于各個中斷源的狀態,通過CRYP_RISR寄存器可以讀取原始中斷狀態,通過CRYP_MISR寄存器可以讀取屏蔽中斷狀態。
--輸出FIFO服務中斷–OUTMIS
當輸出FIFO中存在一個或多個(32位字)數據項時,即會產生輸出FIFO服務中斷。通過讀取輸出FIFO的數據,直到讀完所有有效(32位)字,即可將此中斷清除(即該中斷的狀態與OFNE(輸出FIFO非空)標志一致)。
輸出FIFO服務中斷OUTMIS不是通過CRYP使能位使能,因此,如果輸出FIFO非空,即使禁止CRYP之后也不會強制OUTMIS信號為低電平。
--輸入FIFO服務中斷–INMIS
當輸入FIFO中少于四個字時,會產生輸入FIFO服務中斷,對輸入FIFO執行寫操作直到其中所含字不小于四字,這樣即可將此中斷清除。
輸入FIFO服務中斷INMIS通過CRYP使能位使能,因此,禁止CRYP之后,即使輸入FIFO為空,INMIS信號也為低(無效)。
圖5CRYP中斷映射圖表
CRYP DMA接口
加密處理器可使用一個接口連接DMA控制器。DMA操作通過CRYP DMA控制寄存器CRYP_DMACR進行控制。
突發傳輸請求信號和單次傳輸請求信號并不相互排斥。這兩種信號可同時產生。例如,當OUTFIFO中存在6個字時,會產生突發傳輸請求和單次傳輸請求。突發傳輸4個字之后,將只產生單次傳輸請求來傳輸余下的2個字。當數據流中待接收的剩余字數少于突發傳輸字數時,這一特性就非常有用。
在產生相關的DMA清除信號之前,仍會產生各個請求信號。禁止請求信號清除之后,可再次激活某個請求信號,具體取決于上述條件。如果已禁止CRYP外設并且已將DMA使能位清零(CRYP_DMACR寄存器中的DIEN位用于IN FIFO,DOEN位用于OUT FIFO),則會禁止所有請求信號。
注意:DMA控制器必須配置為執行不多余4字的突發傳輸。否則可能會丟失一些數據。為了在裝滿IN FIFO之前讓DMA控制器清空OUT FIFO,OUT DMA通道的優先級應高于INDMA通道。
CRYP原理部分介紹到此,下面介紹具體使用情況。
CRYP應用實例
本節,我們將針對CRYP部分與DMA部分共同完成一個實驗,首先需要在工程目錄下新建一個CRYP文件夾。CRYP為加密處理器,本節例程通過DES128EBC算法進行驗證,再使用軟件Debug的方式查看加密與解密數據的正確與否。
打開本節實驗工程可發現,相較其他工程,新增了幾項相關文件:
①cks32f4xx_cryp.c
②cks32f4xx_cryp.h
③cks32f4xx_cryp_des.c
④cks32f4xx_cryp_tdes.c
⑤cks32f4xx_cryp_aes.c
由于例程是通過CRYP加密處理器中的DES算法對數據進行加密/解密,且選用電子密碼本(ECB)模式執行,因此,在例程中僅添加上述①②③三項即可,加密/解密流程詳解見1.3.1小節,接下來介紹軟件層面的應用。
代碼中將實現數據加密/解密功能,取下列功能為例:
1)軟件復位
2)DES128 ECB
為縮短篇幅,不一一贅述所有算法形式,其余算法的使用方式可查閱相關參考手冊與庫文件,下面正式進入軟件代碼部分講解。
1)軟件復位功能
首先設置CRYP各個寄存器的軟件復位值與偏移地址,如下所示,具體寄存器功能如手冊所述。
uint32_t TABLE_RESETREG[][2] = { {0x0000, 0x00000000}, {0x0004, 0x00000003}, {0x0008, 0x00000000}, {0x000C, 0x00000000}, {0x0010, 0x00000000}, {0x0014, 0x00000000}, {0x0018, 0x00000001}, {0x001C, 0x00000000}, {0x0020, 0x00000000}, {0x0024, 0x00000000}, {0x0028, 0x00000000}, {0x002C, 0x00000000}, {0x0030, 0x00000000}, {0x0034, 0x00000000}, {0x0038, 0x00000000}, {0x003C, 0x00000000}, {0x0040, 0x00000000}, {0x0048, 0x00000000}, {0x004C, 0x00000000}, }; TestStatus Test1() { int i; for (i=0; i{ if(readl((uint8_t *)CRYP + TABLE_RESETREG[i][0]) != TABLE_RESETREG[i][1]) { return FAILED; } } return PASSED; }
通過代碼判定基地址+偏移地址是否為CRYP相應地址,一致則正確,不一致則錯誤。
1)DES128 ECB
根據手冊,首先設置以下向量組
①設置密鑰;
②設置初始向量組;
③設置明文文本;
④設置密文文本;
下面進行代碼講解:
由上可知,實驗開始前需要先設定DES-KEY密鑰、初始向量IV_1、明文Plaintext等一系列數組。
由于我們添加了cks32f4xx_cryp_des.c,因此可直接調用明文加密函數,并發送加密后的密文。
uart2_fputc(3, DESkey, 8); uart2_fputc(3, IV_1, 16); uart2_fputc(3, Plaintext, AES_TEXT_SIZE); for (j=0; j<4; j++) { DataType = 0x40 * j; /* Encrypt the plaintext message*/ if(MYCRYP_DES_ECB(MODE_ENCRYPT, DESkey, Plaintext, AES_TEXT_SIZE, Encryptedtext, DataType) != SUCCESS) { return FAILED; } uart2_fputc(3, Encryptedtext, AES_TEXT_SIZE); /* Decrypt the plaintext message */ if(MYCRYP_DES_ECB(MODE_DECRYPT,DESkey, Encryptedtext,AES_TEXT_SIZE,Decryptedtext, DataType) != SUCCESS) { return FAILED; } for (i=0; i{ if (Decryptedtext[i] != Plaintext[i]) { return FAILED; } }
上述代碼中的MYCRYP_DES_ECB()不僅可作為加密入口函數,同樣可作為解密算法的入口函數,參數如下所示:
ErrorStatus MYCRYP_DES_ECB (uint8_t Mode, uint8_t Key[8], uint8_t *Input, uint32_t Ilength, uint8_t *Output, uint16_t DataType)
對于各個參數,可根據需求配置:
① Mode:根據需求選擇加密(MODE_ENCRYPT)、解密(MODE_DECRYPT)
② Key[8]:本例成為DES128 ECB算法,所以選擇DESkey
③*Input:輸入,根據功能設定,當功能為加密時,輸入為明文;當輸入為解密時,輸入為密文
④ Ilength:輸入的buffer長度,規定必須為8的倍數
⑤*Output:輸出,與第③條相反
⑥ DataType:默認值
由于加密后的數據可通過DMA的突發模式進行傳輸,因此也對DMA功能作簡要介紹,如下所示,DMA配置與常規無異,僅在一句函數上需注意,入口函數如下所示:
void DES_Encrypt_DMA (uint32_t AlgoMode, uint8_t InitVectors[16], uint8_t *Key, uint8_t *Input, uint32_t Ilength, uint8_t *Output, uint16_t DataType, DMA_InitTypeDef *DMA_In_InitStructure, DMA_InitTypeDef *DMA_Out_InitStructure)
該函數用于CRYP加密處理器加密/解密的DMA傳輸,函數的各個參數根據使用需求決定:
① AlgoMode:根據選定的模式設置,由于例程是DES128 ECB算法,因此,該參數設定為CRYP_AlgoMode_DES_ECB
② InitVectors[16]:初始向量設定
③*Key:秘鑰方式,上文中已講解,本次例程為DESkey
④*Input:輸入,上文已講解
⑤ Ilength:輸入的buffer長度
⑥*Output:輸出
⑦ DataType:默認值
與加密函數類似,本節的DMA函數同樣分為加密和解密兩個過程,函數相應更改*Input和*Output參數即可。
接下來講解main.c函數,該函數相對不難。
在main.c中設定以下數組(具體數據如工程文件所示)
① DES密鑰;
②初始向量;
③明文/解密后的明文;
④加密計算后的密文;
Main.c函數如下所示:
int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); uart_init(115200); NVIC_Config(); while(1) { CRYP_DeInit(); RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, DISABLE); RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); if(func[(0)]() == PASSED) { uart2_fputc(0, 0, 0); } else { uart2_fputc(0, 0, 0); } RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); if(func[(1)]() == PASSED) { uart2_fputc(0, 0, 0); } else { CKS_EVAL_LEDToggle(LED1); CKS_EVAL_LEDToggle(LED2); } RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); if(func[(2)]() == PASSED) { uart2_fputc(0, 0, 0); } else { CKS_EVAL_LEDToggle(LED1); CKS_EVAL_LEDToggle(LED2); }
需注意的是,在驗證CRYP功能時,需要開啟相應的總線時鐘。具體的代碼可詳見工程。
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE);
以上即為CRYP加密處理器模塊代碼的大致講解,具體代碼詳見相關工程。將代碼下載到相應電路板后,通過軟件Debug的方式進行驗證,驗證成功則跳轉到相關的功能PASS位置。最后可得到明文數據(Plaintext),并將其與解密后的數據(Decrytedtext)相比對,比對正確則成功,實驗結果如下圖所示:
(a)明文數據
(b)解密后的數據
到此,CRYP加密處理器講解完成,其他算法的使用詳見參考手冊與庫文件。
審核編輯:湯梓紅
-
處理器
+關注
關注
68文章
19259瀏覽量
229651 -
mcu
+關注
關注
146文章
17123瀏覽量
350982 -
fifo
+關注
關注
3文章
387瀏覽量
43647 -
CRYP
+關注
關注
0文章
5瀏覽量
2480
原文標題:MCU微課堂|CRYP加密處理器
文章出處:【微信號:中科芯MCU,微信公眾號:中科芯MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論