Files
kunlun/dtest/dtest3/kl3_sm4_test/kl3_sm4_test.c
2024-09-28 14:24:04 +08:00

260 lines
7.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "os_types.h"
#include "iot_config.h"
#include "dbg_io.h"
#include "iot_diag.h"
#include "iot_io.h"
#include "gp_timer.h"
#include "iot_string.h"
#include "sec_sys_rf.h"
#include "chip_reg_base.h"
#include "hw_reg_api.h"
#include "os_mem.h"
#include "sec_sys.h"
#include "dtest_printf.h"
#include "ahb.h"
void p_buf(unsigned char *b, uint32_t l)
{
uint32_t i;
for (i = 0; i < l; i++) {
if (i % 32 == 0) {
iot_printf("\n");
}
iot_printf("%02x", b[i]);
};
iot_printf("\n");
}
#define SM4_1_BASE (0x58070000)
#define SM4_1_BASE_CFG (SM4_1_BASE)
#define SM4_1_MODE_REG (SM4_1_BASE + 0x4)
#define SM4_1_KEY0_REG (SM4_1_BASE + 0x10)
#define SM4_1_KEY1_REG
#define SM4_1_KEY2_REG
#define SM4_1_KEY3_REG
#define SM4_1_IV0_REG (SM4_1_BASE + 0x20)
#define SM4_1_IV1_REG
#define SM4_1_IV2_REG
#define SM4_1_IV3_REG
#define SM4_1_DATA0_REG (SM4_1_BASE + 0x30)
#define SM4_1_DATA1_REG
#define SM4_1_DATA2_REG
#define SM4_1_DATA3_REG
#define SM4_1_FAKE_REG (SM4_1_BASE + 0x40)
#define SM4_1_MASK0_REG (SM4_1_BASE + 0x44)
#define SM4_1_MASK1_REG
#define SM4_1_MASK2_REG
#define SM4_1_MASK3_REG
#define SM4_1_MASK4_REG
#define SM4_1_MASK5_REG
#define SM4_1_MASK6_REG
#define SM4_1_MASK7_REG
#define SM4_1_KEYMASK_REG (SM4_1_BASE + 0x64)
void sm4_test(uint8_t *input, uint8_t *output, uint32_t len, uint8_t *key,
uint8_t *iv, SEC_SYS_SM4_MODE mode, SEC_SYS_SM4_OPT_MODE opt_mode)
{
uint32_t tmp, remain;
uint8_t *input_p = input;
uint8_t *output_p = output;
remain = len & (~0xf);
/* 1.不启动 */
tmp = SOC_READ_REG(SM4_1_BASE_CFG);
tmp &= ~0xf;
// tmp |= 0x9;
SOC_WRITE_REG(SM4_1_BASE_CFG, tmp);
/* 2.打开随机化 */
tmp = SOC_READ_REG(SM4_1_MODE_REG);
/* 随机化加解密过程 */
tmp |= 0x1 << 3;
/* 设置模式 ecb cbc */
tmp &= ~0x7;
tmp |= mode << 1;
/* [0:0] 1:加密 0:解密*/
tmp |= opt_mode;
SOC_WRITE_REG(SM4_1_MODE_REG, tmp);
/* 3.配置密钥 iv */
os_mem_cpy((void *)SM4_1_KEY0_REG, key, 16);
os_mem_cpy((void *)SM4_1_IV0_REG, key, 16);
/* 4.配置待加密数据 */
while (remain) {
os_mem_cpy((void *)SM4_1_DATA0_REG, input_p, 16);
input_p += 16;
/* 5.start */
tmp = SOC_READ_REG(SM4_1_BASE_CFG);
tmp |= 0x6;
SOC_WRITE_REG(SM4_1_BASE_CFG, tmp);
/* 6.等待完成 */
while (1) {
tmp = SOC_READ_REG(SM4_1_BASE_CFG);
if (0x6 != (tmp & 0x6)) {
break;
}
}
/* 7. 拷贝数据 */
os_mem_cpy(output_p, (uint8_t*)SM4_1_DATA0_REG, 16);
output_p += 16;
remain -= 16;
}
}
#define AES1_BASIC_CFG (0x58060000)
#define AES1_DATA0_REG (AES1_BASIC_CFG + 0x10)
#define AES1_KEY0_REG (AES1_BASIC_CFG + 0x20)
#define AES1_RAND0_REG (AES1_BASIC_CFG + 0x40)
#define AES1_RAND1_REG (AES1_BASIC_CFG + 0x44)
#define AES1_IV0_REG (AES1_BASIC_CFG + 0x70)
int sec_sys_aes1(uint8_t *input, uint8_t *output, uint32_t len,
uint8_t *aes_key,uint8_t enc_mode, uint8_t operation)
{
uint32_t tmp, remain;
uint8_t *input_p = input;
uint8_t *output_p = output;
remain = len & (~0xf);
/* 1. 打开模块 */
// sec_sys_enable(SEC_SYS_AES);
/* 2. 设置工作模式 */
tmp = SOC_READ_REG(AES1_BASIC_CFG);
tmp &= ~(0xff); //要设置的全部清零
/* [7:6] 0:ecb 1:cbc 2:ofb 3:cfb 暂时不支持cfb */
tmp &= ~(0x3 << 6);
tmp |= enc_mode << 6; //cbc
tmp |= 0x1 << 5; //使能随机化过程
/* 密钥模式选择[4:3] 0:128bit 1:192bit 2:256bit 3:reserved */
tmp &= ~(0x3 << 3); //128bit
/* 加解密[2:1] */
tmp &= ~(0x3 << 1);
tmp |= operation << 1;
SOC_WRITE_REG(AES1_BASIC_CFG, tmp);
/* 3. 配置随机数 */
SOC_WRITE_REG(AES1_RAND0_REG, 0);
SOC_WRITE_REG(AES1_RAND1_REG, 32);
/* 4. 配置假密钥iv */
os_mem_cpy((void *)AES1_IV0_REG, aes_key, 16);
/* 5. 配置真密钥 */
os_mem_cpy((void *)AES1_KEY0_REG, aes_key, 16);
while (remain) {
/* 6. 配置待加密数据 */
os_mem_cpy((void *)AES1_DATA0_REG, input_p, 16);
input_p += 16;
/* 7. start */
tmp = SOC_READ_REG(AES1_BASIC_CFG);
tmp |= 0x1;
SOC_WRITE_REG(AES1_BASIC_CFG, tmp);
//poll status;
while (1) {
tmp = SOC_READ_REG(AES1_BASIC_CFG);
if ((tmp & 0x1) != 0x1 ) {
break;
}
}
os_mem_cpy(output_p, (uint8_t*)(AES1_DATA0_REG), 16);
output_p += 16;
remain -= 16;
}
return 0;
}
int main(void)
{
uint32_t time_cost = 0;
uint8_t res[1024] = {0};
dbg_uart_init();
gp_timer_init();
gp_timer_set(0, 0xffffffff, 0);
gp_timer_start(0);
while (gp_timer_get_current_val(0) < 1000000);
gp_timer_stop(0);
dstart();
dversion();
/* sm4 */
ahb_enable(3);
/* aes */
ahb_enable(10);
dcase_start("sm4\n");
uint8_t input[1024] = {0};
uint8_t key[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd,
0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
for (int i = 0; i < 1024; i++) {
input[i] = (uint8_t)(i & 0xff);
}
dprintf("sm4 source:");
p_buf(input, 256);
gp_timer_start(0);
sm4_test(input, res, 256, key, key, SM4_ECB, SM4_OPT_ENC);
time_cost = gp_timer_get_current_val(0);
gp_timer_stop(0);
dprintf("time cost: %d, sm4 ecb enc:", time_cost);
p_buf(res, 256);
gp_timer_start(0);
sm4_test(input, res, 256, key, key, SM4_ECB, SM4_OPT_DEC);
time_cost = gp_timer_get_current_val(0);
gp_timer_stop(0);
dprintf("time cost: %d, sm4 ecb dec:", time_cost);
p_buf(res, 256);
gp_timer_start(0);
sm4_test(input, res, 256, key, key, SM4_CBC, SM4_OPT_ENC);
time_cost = gp_timer_get_current_val(0);
gp_timer_stop(0);
dprintf("time cost: %d, sm4 cbc enc:", time_cost);
p_buf(res, 256);
gp_timer_start(0);
sm4_test(input, res, 256, key, key, SM4_CBC, SM4_OPT_DEC);
time_cost = gp_timer_get_current_val(0);
gp_timer_stop(0);
dprintf("time cost: %d, sm4 cbc dec:", time_cost);
p_buf(res, 256);
gp_timer_start(0);
sec_sys_aes1(input, res, 256, key, 0, 0);
time_cost = gp_timer_get_current_val(0);
gp_timer_stop(0);
dprintf("time cost: %d, aes1 ecb enc:", time_cost);
p_buf(res, 256);
gp_timer_start(0);
sec_sys_aes1(key, res, 256, key, 0, 1);
time_cost = gp_timer_get_current_val(0);
gp_timer_stop(0);
dprintf("time cost: %d, aes1 ecb dec:", time_cost);
p_buf(res, 256);
gp_timer_start(0);
sec_sys_aes1(input, res, 256, key, 1, 0);
time_cost = gp_timer_get_current_val(0);
gp_timer_stop(0);
dprintf("time cost: %d, aes1 cbc enc:", time_cost);
p_buf(res, 256);
gp_timer_start(0);
sec_sys_aes1(key, res, 256, key, 1, 1);
time_cost = gp_timer_get_current_val(0);
gp_timer_stop(0);
dprintf("time cost: %d, aes1 cbc dec:", time_cost);
p_buf(res, 256);
dprintf(">>>>crypto test end<<<<\n");
while(1);
return 0;
}