行业知识
SM4加解密算法的电路设计
一、SM4介绍
SM4���法是我国的一个商用加解密算法,主要用于数据的加解密,与DES和AES类似,属于分组密码算法。该算法输入明文、密钥,输出密文,或者输入密文、密钥,输出明文。明文是指待加密的信息,在SM4中为128位的二进制数,密钥是指参与运算的特殊数据参数,也是128位的二进制数。进行加密运算时得到的是128位的二进制密文,进行解密运算时得到的是128位二进制明文。
例如:
明文OText=128'h01234567_89abcdef_fedcba98_76543210,
密钥MKey=128'h01234567_89abcdef_fedcba98_76543210,
经过加密后的密文PCText=128'h681edf34_d206965e_86b3e94f_536e4246。
加密运算可以分为三步:1.生成32个轮密钥,2.对明文进行32次轮操作迭代运算,3.对步骤2结束后的数据分成4个32位字将4个字逆序得到最终的密文。
解密运算时如果已经生成了轮密钥就可以不再重复轮密钥的生成步骤直接进行32次文的轮操作,得到数据后也是像加密运算最后一步一样逆序输出,不过此时参与32次轮操作的轮密钥也是逆序的,比如32个轮密钥中加密时第5轮使用的是第5个轮密钥,解密时第5轮使用的是第28个轮密钥。
本设计同时设计了两个轮函数,分别是生成轮密钥的轮函数和明文加密或密文解密的轮函数,在数据通路里将两个轮函数通过一定的逻辑连接,使得在加密时每生成一个轮密钥后即刻与明文进行轮操作迭代一次,于是数据通路总共的轮函数执行时钟周期为32次,加上控制通路里的状态机的额外状态的时钟消耗,得到加解密一次的总共时间为35个时钟上升沿。但是对于一组密钥在第一次解密之前必须要加密一次来生成32个轮密钥(存储在电路内部的触发器里),否则不能解密。
二、电路结构
(一)总接口
设计的顶层模块接口如下图所示。
接口信号描述表如下表所示。
| 信号 | 位宽 | 方向 | 描述 |
| clk | 1 | input | 时钟 |
| rst_n | 1 | input | 全局异步清零 |
| en_or_de | 1 | input | 加解密标志,0为加密1为解密 |
| start | 1 | input | 加解密开始标志,1有效 |
| K_valid | 1 | input | 输入的密钥数据MKey有效标志,1有效 |
| X_valid | 1 | input | 输入的明密文数据OText有效标志,1有效 |
| MKey | 128 | input | 密钥 |
| OText | 128 | input | 输入的明密文 |
| rkey_q | 1024 | output | 32个32位的轮密钥数据 |
| PCText | 128 | output | 输出的加解密后的密明文 |
| finish | 1 | output | 加解密运算完成标志,1有效 |
顶层模块的Verilog代码如下。
/* Module:SM4 * top*/module SM4( //global input clk, input rst_n, //start,high active input start, //de-encryption mode select input en_or_de, //input data valid,active high input K_valid, input X_valid, //Key input input [127:0] MKey, //Text input input [127:0] OText, //roundkey output output [1023:0] rkey_q, //text output after de-encryption output [127:0] PCText, //finish output finish); //internal signals wire loadK,loadX; wire flopK_en,flopX_en; wire write_rk_en; wire [4:0] cntK,cntX; //CtrlPath Controller CtrlPath_x( .clk (clk), .rst_n (rst_n), .start (start), .en_or_de (en_or_de), .K_valid (K_valid), .X_valid (X_valid), .loadK (loadK), .loadX (loadX), .flopK_en (flopK_en), .flopX_en (flopX_en), .write_rk_en (write_rk_en), .cntK (cntK), .cntX (cntX), .finish (finish) ); //DataPath DataPath DataPath_x( .clk (clk), .rst_n (rst_n), .en_or_de (en_or_de), .MKey (MKey), .OText (OText), .rkey_q (rkey_q), .PCText (PCText), .loadK (loadK), .loadX (loadX), .flopK_en (flopK_en), .flopX_en (flopX_en), .write_rk_en (write_rk_en), .cntK (cntK), .cntX (cntX) );endmodule
(二)控制通路
1、接口
总的控制通路接口图如下图所示。
该接口信号描述表如下表所示。
| 信号 | 位宽 | 方向 | 描述 |
| clk | 1 | input | 时钟 |
| rst_n | 1 | input | 全局异步清零 |
| start | 1 | input | 加解密开始标志,1有效 |
| en_or_de | 1 | input | 加解密标志,0为加密1为解密 |
| K_valid | 1 | input | 输入的密钥数据MKey有效标志,1有效 |
| X_valid | 1 | input | 输入的明密文数据OText有效标志,1有效 |
| loadK | 1 | output | 在第一个轮操作时置数MKey到内部,1有效 |
| loadX | 1 | output | 在第一个轮操作时置数OText到内部,1有效 |
| flopK_en | 1 | output | 存储轮函数RoundFunc1输出信号KeyNew的触发器的使能信号,1有效 |
| flopX_en | 1 | output | 存储轮函数RoundFunc2输出信号XNew的触发器的使能信号,1有效 |
| write_rk_en | 1 | output | 存储32个轮密钥的触发器的使能信号,1有效 |
| cntK | 5 | output | 计数器counterK的计数输出 |
| cntX | 5 | output | 计数器counterX的计数输出 |
| finish | 1 | output | 加解密运算完成标志,1有效 |
2、状态机
状态转换图和两个计数器的信号如下所示。
状态输出信号描述表如下表所示。
| 状态名 | 描述 |
| IDLE | 空闲 |
| WAIT | 等待MKey和OText有效 |
| LOAD | 将MKey和OText置入内部,进行第一次轮操作 |
| DEALK | 处理key,在加密阶段counterK的进位co_cntK拉高后跳出,在解密阶段只消耗一个时钟周期用来写入第一个RoundFunc2结果到触发器 |
| DEALX | 处理text,counterX的进位co_cntX拉高后跳出 |
| FINISH | 完成状态,拉高finish信号表示完成加密或解密 |
| 状态名 | loadK | loadX | flopK_en | flopX_en |
| IDLE | 0 | 0 | 0 | 0 |
| WAIT | K_valid | X_valid | 0 | 0 |
| LOAD | 1 | 1 | !en_or_de | 0 |
| DEALK | 0 | cntX==0 | !en_or_de | 1 |
| DEALX | 0 | 0 | 0 | 1 |
| FINISH | 0 | 0 | 0 | 0 |
| 状态名 | cntK_en | cntX_en | write_rk_en | finish |
| IDLE | 0 | 0 | 0 | 0 |
| WAIT | 0 | 0 | 0 | 0 |
| LOAD | !en_or_de | 0 | 0 | 0 |
| DEALK | !en_or_de | 1 | !en_or_de | 0 |
| DEALX | 0 | 1 | !en_or_de | 0 |
| FINISH | 0 | 0 | 0 | 1 |
控制通路包括一个有限状态机和两个计数器,co_cntK为计数器counterK的进位输出,co_cntX为计数器counterX的进位输出,两个计数器的计数上限均为31,所以是32进制计数器。在之后的第(三)部分的总数据通路部分里可以看到控制通路给数据通路的各个信号的作用。
控制通路的Verilog代码如下。
/* Module:Controller * */module Controller( //global input clk, input rst_n, input start,//wait for high to start de-encryption input en_or_de,//0 is encryption,1 is decryption input K_valid,//input MKey valid input X_valid,//input Text valid //to DataPath output reg loadK,//load MKey in first make-rkey round output reg loadX,//load Text in first de-encryption round output reg flopK_en,//en for flop stores Key every round output reg flopX_en,//en for flop stores Text every round output reg write_rk_en,//en for flop stores rk every round output reg [4:0] cntK,//counterK output output reg [4:0] cntX,//counterX output //finish signal output reg finish//pull high when whole procedure finished); //parameters localparam IDLE = 6'b000001;//nothing to do localparam WAIT = 6'b000010;//wait for the Key and Text valid localparam LOAD = 6'b000100;//load Key and Text localparam DEALK = 6'b001000;//deal with Key localparam DEALX = 6'b010000;//deal with Text localparam FINISH = 6'b100000;//finish //internal signals reg [5:0] cur_state,nxt_state; wire co_cntK; wire co_cntX; reg cntK_en; reg cntX_en; //counterK assign co_cntK = &cntK; always @(posedge clk,negedge rst_n) begin if(!rst_n) cntK
上一篇:为什么应用安装失败?
下一篇:前端如何调后端服务器?