📄 ssx31bdrv_glue.c
字号:
/* toy,2006-7-6 wrapper for user mode and kernel mode*/#ifndef __KERNEL__#include <stdio.h>#include <fcntl.h>#include <sys/ioctl.h>#endif#include "drv/SSX31.h"#include "drv/cmd.h"#include "./ssx31bdrv_glue.h"int ssx31b_GetSANum(){ #ifndef __KERNEL__ /*user mode*/ int fd, err; unsigned short buf[2]; fd=open("/dev/ssx31drv",O_RDWR); if(fd==-1){ printf ("ssx31b_GetSANum: open err:%d", fd); return -1; } buf[0]=0; err=ioctl (fd, SSX_IOC_SA_NUM_MGM, buf); if (err != 0) { printf ("ssx31b_GetSANum: ioctl err\n"); close(fd); return -1; } close(fd); return buf[1]; #else /*kernel mode*/ return __ssx31b_GetSANum();#endif}void ssx31b_ReleaseSANum(unsigned short saNum){#ifndef __KERNEL__ int fd,err; unsigned short buf[2]; fd=open("/dev/ssx31drv",O_RDWR); if(fd==-1){ printf ("ssx31b_ReleaseSANum: open err:%d", fd); return; } buf[0]=1; buf[1]=saNum; err=ioctl (fd, SSX_IOC_SA_NUM_MGM, buf); if (err != 0) { printf ("ssx31b_ReleaseSANum: ioctl err\n"); } close(fd);#else __ssx31b_ReleaseSANum(saNum);#endif return ; }/*function ssx31_sa_register()paramenters: usOpt: 15 9 8 6 5 2 1 0 ---------------------------------------------------------- | reserved | | | | ---------------------------------------------------------- 1~0 bit: Crypto Mode 00:ECB 01: CBC other: reserved 5~2 bit: Ctypto Algrithm 0000:des 0001:3des 0010:aes128 0011:aes192 0100:aes256 0101:scb2 other:reserved 8~6 bit: Hmac Algrithm 000:md5 001:sha1 other:reserved cKey pointer to the Crypto Key Array ( 8 dwords) cKey[0]: Key a[3:0] cKey[1]: Key a[7:4] cKey[2]: Key b[3:0] ....... cKey pointer to the Hmac Key Array (10 dwords) hKey[0]: Key first[3:0] hKey[1]: Key first[7:4] hKey[2]: Key first[3:0] ....... saNum SA number usr want to be registeredreturns: 0: success -1: failed*/int ssx31b_sa_register(unsigned short usOpt, unsigned long* cKey, unsigned long* hKey, unsigned long saNum){#ifndef __KERNEL__ unsigned long ultmp; int itmp,iCAlg,iHAlg,iCryMode; unsigned short cKeyLen,hKeyLen; int fd; unsigned long saa[33] = { 0x0, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; iHAlg=(usOpt&0x01c0)>>6; iCAlg=(usOpt&0x003c)>>2; iCryMode=usOpt&0x0003; if(iHAlg>1 || iCAlg>5 || iCryMode>1){ printf("ssx31b_sa_register: Invalid Algrithms or Mode\n"); return -1; } switch(iCAlg){ case 0: cKeyLen=8; break; case 1: cKeyLen=24; break; case 2: cKeyLen=16; break; case 3: cKeyLen=24; break; case 4: cKeyLen=32; break; case 5: cKeyLen=16; break; default: return -1; } switch(iHAlg){ case 0: hKeyLen=16; break; case 1: hKeyLen=20; break; default: return -1; } if(cKey==NULL && hKey==NULL) { printf("ssx31_sa_register: Invalid Algrithm Keys\n"); return -1; } fd=open("/dev/ssx31drv",O_RDWR); if(fd==-1){ printf ("ssx31_sa_register: open err:%d", fd); return -1; } //printf ("ssx31b_sa_register: got fd=%d\n", fd); ultmp=usOpt&0x01ff; saa[1] |= (ultmp<<10); saa[0]=saNum; if(cKey!=NULL) memcpy((unsigned char*)saa+12,(unsigned char*)cKey,cKeyLen); if(hKey!=NULL) memcpy((unsigned char*)saa+44,(unsigned char*)hKey,hKeyLen); #if 0 /* set the correct parity bit for each byte in the key with 3DES*/ if(iCAlg==1){ int i; unsigned char n1,n2; unsigned char * lkey=(unsigned char*)saa+12; for( i=0; i<24; i++){ n1 = lkey[i] & 0xfe; n2 = n1 ^ (n1 >> 4); n2 ^= (n2 >> 2); n2 ^= (n2 >> 1); lkey[i] = n1 | (~n2 & 0x01); } }#endif#if 0 printf ("ssx31_sa_register: saNum=%d\n",saa[0]); for(itmp=0;itmp<32;itmp++){ printf("%08X ",saa[1+itmp]); if((itmp+1)%4==0) printf("\n"); } #endif if (0 != ioctl (fd, SSX_IOC_UPDATE_SA, saa)) { printf ("ssx31_sa_register: update sa ioctl err\n"); close(fd); return -1; } close(fd); return 0;#else return __ssx31b_sa_register(usOpt, cKey, hKey, saNum);#endif }/*function ssx31_crypto_perform() perform cryptographic operations on given data.paramenters ucOpt: 7 3 2 1 0 -------------------------------- | reserved | | | -------------------------------- 0 bit: 1:decrypt or hash-decrypt; 0:encrypt or encrypt-hash 2~1 bit: 00:crypto operation only; 01:crypto and hash combination operation; 10: hash operation only; 7~3 bit: reserved pucIV: pointer to the Initiation Vector for crypto NULL means IV is provided by this function; saNum: SA Number which registed with ssx31_sa_register(); pucInDat: pointer to the data buf to be processed; in the case of de-doing, it includes data block and ICV inDatLen: length of the data buf to be processed in the case of de-doing, it is data block len + ICV len make sure the data block length <=SSX31_MAX_PROCESS_DATABLK_SIZE and >0 pucOutDat: pointer to the data buf where result is stored NULL means result replaces the input buf pucInDat; the result includes en-ed or de-ed data block followed by ICV; if the case is de-doing, then only the de-ed data block; pOutDatLen: poniter to length of processed data and ICV if the case is de-doing, then only the length of de-ed data;returns: 0: success; -1: failed -2: ICV check failed positive integer: indicates some reason*/int ssx31b_crypto_perform(unsigned char ucOpt, unsigned char* pucIV, unsigned short blklen, unsigned long saNum,unsigned char*pucInDat, unsigned long inDatLen, unsigned char *pucOutDat, unsigned long* pOutDatLen){#ifndef __KERNEL__ unsigned char *buf=NULL; unsigned long ulInDatBlkLen,ulPktLenAligned = 0; long ii,lCnt; unsigned long * pultmp; int ipadLen,err=0; int fd,inputWithICV=0; if(pucInDat==NULL ||inDatLen == 0 ||pOutDatLen==NULL ||blklen==0){ printf("ssx31_crypto_perform: param setting fault, such as input data required!\n"); return -1; } *pOutDatLen=0; ulInDatBlkLen=inDatLen; ii=ucOpt; if((ii==5) ||(ii==3) ){ inputWithICV=1; if(ulInDatBlkLen<=20){ printf("ssx31_crypto_perform: source data and ICV required!\n"); return -1; } ulInDatBlkLen-=20; /*exclude the ICV*/ if(ulInDatBlkLen%blklen!=0){ printf("ssx31_crypto_perform: data block to be de-ed should be %d bytes aligned!\n",blklen); return -1; } } ulPktLenAligned=((ulInDatBlkLen+blklen-1)/blklen)*blklen; /*make it blklen bytes aligned*/ ipadLen=ulPktLenAligned-ulInDatBlkLen; ulPktLenAligned+=16; /*+IV length*/ ii=ulInDatBlkLen; if(ii>SSX31_MAX_PROCESS_DATABLK_SIZE){ printf("ssx31_crypto_perform: data block length must be not excel %d bytes!\n",SSX31_MAX_PROCESS_DATABLK_SIZE); return -1; } fd = open ("/dev/ssx31drv", O_RDWR); if (fd==-1) { printf ("ssx31_crypto_perform: open err:%d\n", fd); return -1; } //printf ("ssx31_crypto_perform: got fd=%d\n", fd); buf=(unsigned char*)malloc(4*4+ulPktLenAligned+20); /*5*4 for ICV*/ if(buf==NULL) { printf ("ssx31_crypto_perform: mem allocate error!\n"); close(fd); return -1; } memset(buf,0,36+ulPktLenAligned); pultmp=(unsigned long*)buf; pultmp[0]=(ucOpt&0x01); /*outbound or inbound*/ pultmp[1]=(ucOpt&0x06)>>1; /*crypto/hash*/ pultmp[2]=saNum; pultmp[3]=ulPktLenAligned; memset(buf+16,0,16); if(pucIV==NULL) for(ii=0;ii<16;ii++) buf[16+ii]=ii|0x080; else memcpy(buf+16,pucIV,blklen); memcpy(buf+32,pucInDat,ulInDatBlkLen); while(ipadLen){ buf[32+ulInDatBlkLen+ipadLen-1]=ipadLen; ipadLen--; }#if 0 printf("ssx31_crypto_perform: encapsulated packet to deliver: \n"); for(ii=0;ii<ulPktLenAligned+16;ii++){ printf("%02X",buf[ii]); if((ii+1)%4==0) printf(" "); if((ii+1)%16==0) printf("\n"); } #endif lCnt=0; if ( 0 >= (lCnt= ioctl (fd, SSX_IOC_BASIC_PROC, buf) )) { printf ("ssx31_crypto_perform: ioctl SSX_IOC_BASIC_PROC err!\n"); err=-1; goto rtn; }/*toyinfo*/ //printf ("ssx31b_crypto_perform: going to read\n"); ii=ucOpt; if((ii&0x06)==0) { /*no hash*/ if (lCnt < 1+ulPktLenAligned) { printf ("ssx31_crypto_perform: ioctl() err, returns=%d (IV+Data) is not enough\n",lCnt); err=-1; goto rtn; } } else{ /*with hash*/ if (lCnt < 1+ulPktLenAligned+20) { printf ("ssx31_crypto_perform: ioctl() err, returns=%d (IV+Data+ICV) is not enough\n",lCnt); err=-1; goto rtn; } } err=buf[0]; if (err!= 0) { printf ("ssx31_crypto_perform: crypto return err, status=0x%02x\n",err); goto rtn; }#if 0 printf("\nssx31_crypto_perform: output packet(ERR+IV+Data+ICV if has): ioctl() returns=%d\n",lCnt); printf("ssx31_crypto_perform: err status:0X%2X\n",buf[0]); for(ii=0;ii<lCnt-1;ii++){ printf("%02X",buf[1+ii]); if((ii+1)%4==0) printf(" "); if((ii+1)%16==0) printf("\n"); } #endif if(inputWithICV){ /*de-doing*/ if(memcmp(buf+1+ulPktLenAligned,pucInDat+ulInDatBlkLen,20)){ printf("\n"); for(ii=0;ii<20;ii++) printf("%02x",buf[1+ulPktLenAligned+ii]); printf("\n"); for(ii=0;ii<20;ii++) printf("%02x",pucInDat[ulInDatBlkLen+ii]); printf("\nssx31_crypto_perform: ICV check failed\n"); err=-2; goto rtn; } else *pOutDatLen=lCnt-1-16-20; /*output the de-ed data block*/ } else *pOutDatLen=lCnt-1-16; /*output the en-ed data block + ICV if has any one*/ if(pucOutDat==NULL) memcpy(pucInDat,buf+17,*pOutDatLen); else memcpy(pucOutDat,buf+17,*pOutDatLen);rtn: close(fd); free(buf); return err;#else return __ssx31b_crypto_perform(ucOpt, pucIV, blklen, saNum, pucInDat, inDatLen, pucOutDat, pOutDatLen);#endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -