⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hi_aes_api.c

📁 嵌入式linux系统下hi3510平台的osd开发源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   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 + -