📄 hi_aes_api.c
字号:
/* extdrv/crypto/aes/hi_aes_api.c * * Copyright (c) 2006 Hisilicon Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. * * History: * 6-Jun-2006 create this file * */#include <string.h>#include <errno.h>#include <asm/io.h>#include <linux/ioctl.h>#include <unistd.h>#include <fcntl.h>#include "hi_aes_api.h"#include <stdio.h>#include <time.h>#include <stdlib.h>#include <sys/time.h>#include <sys/mman.h>#include <sys/types.h>#ifndef READ_REGISTER_ULONG#define READ_REGISTER_ULONG(reg,result) ((result)=*(volatile unsigned int *)(reg))#endif#ifndef WRITE_REGISTER_ULONG#define WRITE_REGISTER_ULONG(reg, data) (*((volatile unsigned int *)(reg))=(data))#endif #ifndef WRITE_REGISTER_CHAR#define WRITE_REGISTER_CHAR(reg, data) (*((volatile unsigned char *)(reg))=(data))#endif /* ****************the code below modified by hisilicon*************/unsigned int* p_map=0;int fd;#define ECS_AES_OFFSET 0x101FC000#define ECS_AES_BASE ((unsigned long)p_map)#define ECS_AES_DIN0 IO_ADDRESS(ECS_AES_BASE + 0x0)#define ECS_AES_DIN1 IO_ADDRESS(ECS_AES_BASE + 0x4)#define ECS_AES_DIN2 IO_ADDRESS(ECS_AES_BASE + 0x8)#define ECS_AES_DIN3 IO_ADDRESS(ECS_AES_BASE + 0xC)#define ECS_AES_IVIN0 IO_ADDRESS(ECS_AES_BASE + 0x10)#define ECS_AES_IVIN1 IO_ADDRESS(ECS_AES_BASE + 0x14)#define ECS_AES_IVIN2 IO_ADDRESS(ECS_AES_BASE + 0x18)#define ECS_AES_IVIN3 IO_ADDRESS(ECS_AES_BASE + 0x1C)#define ECS_AES_KEY0 IO_ADDRESS(ECS_AES_BASE + 0x20)#define ECS_AES_KEY1 IO_ADDRESS(ECS_AES_BASE + 0x24)#define ECS_AES_KEY2 IO_ADDRESS(ECS_AES_BASE + 0x28)#define ECS_AES_KEY3 IO_ADDRESS(ECS_AES_BASE + 0x2C)#define ECS_AES_DOUT0 IO_ADDRESS(ECS_AES_BASE + 0x30)#define ECS_AES_DOUT1 IO_ADDRESS(ECS_AES_BASE + 0x34)#define ECS_AES_DOUT2 IO_ADDRESS(ECS_AES_BASE + 0x38)#define ECS_AES_DOUT3 IO_ADDRESS(ECS_AES_BASE + 0x3C)#define ECS_AES_IVOUT0 IO_ADDRESS(ECS_AES_BASE + 0x40)#define ECS_AES_IVOUT1 IO_ADDRESS(ECS_AES_BASE + 0x44)#define ECS_AES_IVOUT2 IO_ADDRESS(ECS_AES_BASE + 0x48)#define ECS_AES_IVOUT3 IO_ADDRESS(ECS_AES_BASE + 0x4C)#define ECS_AES_CTRL IO_ADDRESS(ECS_AES_BASE + 0x50) #define ECS_AES_INT IO_ADDRESS(ECS_AES_BASE + 0x54) #define ECS_AES_BUSY IO_ADDRESS(ECS_AES_BASE + 0x58) #define ECS_AES_START IO_ADDRESS(ECS_AES_BASE + 0x5C)#define IO_ADDRESS(n) (n) #define MMAP_LENGTH 0x1000#define AES_BUSY 0x01#define AES_START 0x01#define AES_BUSY_ERR 0x02#define AES_CTRLWORD_ERR 0x03//#define DEBUG#define HI_ASSERT(expr) \ do{ \ if (!(expr)) { \ printf("\nASSERT failed at:\n >File name: %s\n >Function : %s\n >Line No. : %d\n >Condition: %s\n", \ __FILE__,__FUNCTION__, __LINE__, #expr);}\ }while(0)static int control_word = 0;static unsigned char * aes_iv;struct trans{unsigned char outtrans[16];unsigned char ivouttrans[16];};static int aes_ctr_operate(unsigned char * pplaintext,unsigned char * pouttext,unsigned int plaintext_length,unsigned char *pcipher,unsigned char *pctr_iv);static int aes_alg_operate(unsigned char * pplaintext,unsigned char * pouttext,unsigned int plaintext_length,unsigned char *pcipher);static int aes_ctrl(unsigned int cmd, unsigned char * arg);int hi_aes_init( ){ fd=open("/dev/mem",O_RDWR|O_SYNC,00777); if(fd<0) { return -1; } p_map = (unsigned int *) mmap( NULL,MMAP_LENGTH,PROT_READ|PROT_WRITE,MAP_SHARED,fd,ECS_AES_OFFSET); if(p_map==0) { return -1; } return 0;}static int reverse_array( unsigned char *src){ int i; unsigned char tmp[16]; if(NULL==src) { printf("the pointer in reverse is null!"); return -1; } for( i = 0; i < 16; i++ ) { tmp[i] = src[(16-1) - i]; } for( i = 0; i < 16; i++ ) { src[i] = tmp[i]; } return 0;}/*static int reverse_1_array(unsigned char *src){ reverse_array((unsigned char *)src); return 0;}*/static int aes_config_key(unsigned char *pkeytmp){ unsigned int * pkey=(unsigned int *) pkeytmp; unsigned int stavalue,k; unsigned int *ptmpkey; if(NULL==pkey) { printf("the pointer is null!"); return -1; } ptmpkey = pkey; /* read AES_BUSY register */ READ_REGISTER_ULONG(ECS_AES_BUSY,stavalue); for(k=0;(k<100000)&&(stavalue==1);k++) { READ_REGISTER_ULONG(ECS_AES_BUSY,stavalue); } if (k>=100000) { printf(" there is something wrong with the module!"); return AES_BUSY_ERR; } /* set key */ WRITE_REGISTER_ULONG(ECS_AES_KEY0,*ptmpkey++); WRITE_REGISTER_ULONG(ECS_AES_KEY1,*ptmpkey++); WRITE_REGISTER_ULONG(ECS_AES_KEY2,*ptmpkey++); WRITE_REGISTER_ULONG(ECS_AES_KEY3,*ptmpkey); #ifdef DEBUG READ_REGISTER_ULONG(ECS_AES_KEY3,stavalue); printf("key3:%x\n",stavalue); READ_REGISTER_ULONG(ECS_AES_KEY2,stavalue); printf("key2:%x\n",stavalue); READ_REGISTER_ULONG(ECS_AES_KEY1,stavalue); printf("key1:%x\n",stavalue); READ_REGISTER_ULONG(ECS_AES_KEY0,stavalue); printf("key0:%x\n",stavalue); #endif return 0;}/* * AES set vector iv routine. * * @param pivin: vector iv value * @param ctrlword: control register value * @return value:0--success; 2--AES_BUSY_ERR. * */static int aes_config_iv(unsigned char *pivintmp, unsigned int ctrlword){ unsigned int stavalue,k; unsigned int *ptmpiv; unsigned int *pivin=(unsigned int *)pivintmp; if(NULL==pivin) { printf("the pointer is null!"); return -1; } READ_REGISTER_ULONG(ECS_AES_BUSY,stavalue); for(k=0;(k<100000)&&(stavalue==1);k++) { READ_REGISTER_ULONG(ECS_AES_BUSY,stavalue); } if (k>=100000) { printf(" there is something wrong with the module!"); return AES_BUSY_ERR; } ptmpiv = pivin; /* set IVIN */ if ((ctrlword & 0x0E) != AES_MODE_ECB) { WRITE_REGISTER_ULONG(ECS_AES_IVIN0,*ptmpiv++); WRITE_REGISTER_ULONG(ECS_AES_IVIN1,*ptmpiv++); WRITE_REGISTER_ULONG(ECS_AES_IVIN2,*ptmpiv++); WRITE_REGISTER_ULONG(ECS_AES_IVIN3,*ptmpiv ); #ifdef DEBUG READ_REGISTER_ULONG(ECS_AES_IVIN3,stavalue); printf("ivin3:%x\n",stavalue); READ_REGISTER_ULONG(ECS_AES_IVIN2,stavalue); printf("ivin2:%x\n",stavalue); READ_REGISTER_ULONG(ECS_AES_IVIN1,stavalue); printf("ivin1:%x\n",stavalue); READ_REGISTER_ULONG(ECS_AES_IVIN0,stavalue); printf("ivin0:%x\n",stavalue); #endif //READ_REGISTER_ULONG(ECS_AES_IVIN3,stavalue); } else { return AES_CTRLWORD_ERR; } return 0;}/* * AES set plaintext routine. * * @param pmin: plaintext point * @param ctrlword: control register value * @return value:0--success; 2--AES_BUSY_ERR. * */static int aes_config_m(unsigned char *pmintmp, unsigned int ctrlword){ unsigned int stavalue,k; unsigned int *ptmpm =(unsigned int *)pmintmp; if(NULL==ptmpm) { printf("the pointer is null!"); return -1; } READ_REGISTER_ULONG(ECS_AES_BUSY,stavalue); for(k=0;(k<100000)&&(stavalue==1);k++) { READ_REGISTER_ULONG(ECS_AES_BUSY,stavalue); } if (k>=100000) { printf(" there is something wrong with the module!"); return AES_BUSY_ERR; } /*judge the cfb mode is 1bit or 8bit */ if ( ((ctrlword & 0x0E) == AES_MODE_CFB1) || ((ctrlword & 0x0E) == AES_MODE_CFB8) ) { WRITE_REGISTER_ULONG(ECS_AES_DIN3, (*(ptmpm+3))&0xFF000000); READ_REGISTER_ULONG(ECS_AES_DIN3,stavalue); #ifdef DEBUG printf("ECS_AES_DIN3:%x\n",stavalue); #endif } else { WRITE_REGISTER_ULONG(ECS_AES_DIN0, *ptmpm++); WRITE_REGISTER_ULONG(ECS_AES_DIN1, *ptmpm++); WRITE_REGISTER_ULONG(ECS_AES_DIN2, *ptmpm++); WRITE_REGISTER_ULONG(ECS_AES_DIN3, *ptmpm ); #ifdef DEBUG printf("here are pplaintext:\n"); READ_REGISTER_ULONG(ECS_AES_DIN3,stavalue); printf("%x\n",stavalue); READ_REGISTER_ULONG(ECS_AES_DIN2,stavalue); printf("%x\n",stavalue); READ_REGISTER_ULONG(ECS_AES_DIN1,stavalue); printf("%x\n",stavalue); READ_REGISTER_ULONG(ECS_AES_DIN0,stavalue); printf("%x\n",stavalue); #endif } /*set control word*/ WRITE_REGISTER_ULONG(ECS_AES_CTRL,ctrlword); return 0;}/* * AES enable encrypt run routine. * * @return value:0--success; 2--AES_BUSY_ERR. * */static int aes_start(void){ unsigned int stavalue,k; READ_REGISTER_ULONG(ECS_AES_BUSY,stavalue); for(k=0;(k<100000)&&(stavalue==1);k++) { READ_REGISTER_ULONG(ECS_AES_BUSY,stavalue); } if (k>=100000) { printf(" there is something wrong with the module!"); return AES_BUSY_ERR; } WRITE_REGISTER_ULONG(ECS_AES_START,AES_START); return 0;}/* * AES get encrypted message routine. * * @param prout: data out value after encrypted * @param pivout: vector iv out value after encrypted * @param ctrlword: control register value * @return value:0--success; 2--AES_BUSY_ERR. * */static int aes_get_riv(unsigned char *prout, unsigned char *pivout, unsigned int ctrlword){ unsigned int stavalue,k; unsigned int *ptmprout; unsigned int *ptmpivout; if(NULL==prout) { printf("the pointer is null!"); return -1; } if(NULL==pivout) { printf("the pointer is null!"); return -1; } ptmprout = (unsigned int *)prout; ptmpivout =(unsigned int *) pivout; READ_REGISTER_ULONG(ECS_AES_BUSY, stavalue); for(k=0;(k<100000)&&(stavalue==1);k++) { READ_REGISTER_ULONG(ECS_AES_BUSY,stavalue); } if (k>=100000) { printf(" there is something wrong with the module!"); return AES_BUSY_ERR; } if(((ctrlword & 0x0E) == AES_MODE_CFB1) || ((ctrlword & 0x0E) == AES_MODE_CFB8)) { READ_REGISTER_ULONG(ECS_AES_DOUT3,*(unsigned int *)(ptmprout+3)); } else { READ_REGISTER_ULONG(ECS_AES_DOUT0,*ptmprout); READ_REGISTER_ULONG(ECS_AES_DOUT1,*(ptmprout+1)); READ_REGISTER_ULONG(ECS_AES_DOUT2,*(ptmprout+2)); READ_REGISTER_ULONG(ECS_AES_DOUT3,*(ptmprout+3)); #ifdef DEBUG printf("here are output from get_iv function:\n"); printf("%x\n",*(ptmprout+3)); printf("%x\n",*(ptmprout+2)); printf("%x\n",*(ptmprout+1)); printf("%x\n",*(ptmprout+0)); #endif } READ_REGISTER_ULONG(ECS_AES_IVOUT0,*(unsigned int*)ptmpivout); READ_REGISTER_ULONG(ECS_AES_IVOUT1,*(unsigned int*)(ptmpivout+1)); READ_REGISTER_ULONG(ECS_AES_IVOUT2,*(unsigned int*)(ptmpivout+2)); READ_REGISTER_ULONG(ECS_AES_IVOUT3,*(unsigned int*)(ptmpivout+3)); READ_REGISTER_ULONG(ECS_AES_INT,stavalue); return 0;}/* * @param cmd: command from the app: * AES_SET_KEY: set key. * AES_SET_IV: set vector iv. * AES_SET_M: set data to be encrypted. * AES_SET_START: start encrypt run. * AES_GET_DATA: get encrypted message. * * @param arg:arg from app layer. * * @return value:0-- set success; -1-- set error. * * here the function name is modified by hisilicon */static int aes_ctrl(unsigned int cmd, unsigned char * argp){ unsigned int step,ctlbyte; step = cmd&0xFF000000; ctlbyte = cmd&0x000000FF; switch(step) { case AES_SET_KEY: { if(0!=aes_config_key(argp)) { return -1; } return 0; } case AES_SET_IV: { if(0!=aes_config_iv(argp, ctlbyte)) { return -1; } return 0; } case AES_SET_M: { if(0!=aes_config_m(argp,ctlbyte)) { return -1; } return 0; } case AES_SET_START: { if(0!=aes_start()) { return -1; } return 0; } case AES_GET_DATA: { if(0!=aes_get_riv( argp, (argp+16), ctlbyte)) { return -1; } return 0; } default: { return -1; } } return 0;} /* this function is modified by hisilicon */int hi_aes_exit(void){ if(-1==close( fd )) { printf("close the file operator failed"); return -1; } if(-1== munmap( p_map, MMAP_LENGTH)) { printf("mumap failed"); return -1; } return 0;}int hi_aes_config(struct aes_encrypt_ctrl *pctrl){ if(NULL==pctrl) { printf("the pointer config is null!"); return -1; } control_word = 0; if(pctrl->aes_type > 7) { printf("aes config set error.\n"); return -1; } if(pctrl->aes_type == 7) pctrl->aes_type = 0; control_word |= pctrl->aes_type << 1; aes_iv = pctrl->iv; return 0;}int hi_aes_crypt(unsigned char * src,unsigned char * aest,unsigned int byte_length,unsigned char *pcipher){ if(NULL==src) { printf("the pointer crypt is null!"); return -1; } if(NULL==aest) { printf("the pointer crypt is null!"); return -1; } if(NULL==pcipher) { printf("the pointer crypt is null!"); return -1; } // crypt_length = byte_length / 16; if((byte_length % 16) != 0) { printf("aes crypt data length is error.\n"); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -