/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipfreescale_coldfire.c,v $ $Revision: 1.14 $ * $Source: /home/interpeak/CVSRoot/ipfreescale/src/ipfreescale_coldfire.c,v $ * $Author: markus $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Markus Carlstedt ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** * IPFREESCALE - Hardware crypto support product - coldfire implementation. */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipfreescale_config.h" #ifdef IPFREESCALE_COLDFIRE /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include "ipfreescale.h" #include "ipfreescale_h.h" #include "ipfreescale_coldfire.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ /* Array used for des key parity fix */ #ifdef IPFREESCALE_COLDFIRE_FIX_DES_PARITY IP_CONST Ip_u8 ipfreescale_parity_odd[256] = { 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110, 112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127, 128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143, 145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158, 161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174, 176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191, 193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206, 208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223, 224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239, 241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254 }; #endif /* Global data for coldfire implementation */ IP_GLOBAL Ipfreescale_coldfire_data ipfreescale_coldfire; /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipfreescale_coldfire_eu_reset *=========================================================================== * Description: Reset a SEC execution unit. * Parameters: eu - execution unit to reset. * Returns: 0 = success. * -1 = fail. */ IP_STATIC int ipfreescale_coldfire_eu_reset(int eu) { IP_VOLATILE Ip_u32 *rcr; IP_VOLATILE Ip_u32 *sr; int maxwait = IPFREESCALE_COLDFIRE_MAXWAIT; switch(eu) { case IPFREESCALE_COLDFIRE_EU_AFEU: rcr = ipfreescale_coldfire.afrcr; sr = ipfreescale_coldfire.afsr; break; case IPFREESCALE_COLDFIRE_EU_DEU: rcr = ipfreescale_coldfire.drcr; sr = ipfreescale_coldfire.dsr; break; case IPFREESCALE_COLDFIRE_EU_MDEU: rcr = ipfreescale_coldfire.mdrcr; sr = ipfreescale_coldfire.mdsr; break; case IPFREESCALE_COLDFIRE_EU_RNG: rcr = ipfreescale_coldfire.rngrcr; sr = ipfreescale_coldfire.rngsr; break; case IPFREESCALE_COLDFIRE_EU_AESU: rcr = ipfreescale_coldfire.aesrcr; sr = ipfreescale_coldfire.aessr; break; default: return 0; } /* Reset the execution unit */ IP_BIT_SET(*rcr, IPFREESCALE_COLDFIRE_RCR_SR); /* Wait for reset sequence to complete */ while(maxwait-- > 0) { if(IP_BIT_ISSET(*sr, IPFREESCALE_COLDFIRE_SR_RD)) return 0; } return -1; } /* *=========================================================================== * ipfreescale_coldfire_channel_reset *=========================================================================== * Description: Reset a SEC channel. * Parameters: ch - channel to reset. * Returns: 0 = success. * -1 = fail. */ IP_STATIC int ipfreescale_coldfire_channel_reset(int ch) { int maxwait = IPFREESCALE_COLDFIRE_MAXWAIT; /* Reset the channel */ IP_BIT_SET(*ipfreescale_coldfire.channel[ch].cccr, IPFREESCALE_COLDFIRE_CCCRn_RST); /* Wait for reset sequence to complete */ while(maxwait-- > 0) { if(!IP_BIT_ISSET(*ipfreescale_coldfire.channel[ch].cccr, IPFREESCALE_COLDFIRE_CCCRn_RST)) return 0; } return -1; } /* *=========================================================================== * ipfreescale_coldfire_channel_init *=========================================================================== * Description: Initialize a SEC channel. * Parameters: ch - channel to initialize. * Returns: 0 = success. * -1 = fail. */ IP_STATIC int ipfreescale_coldfire_channel_init(int ch) { if(ipfreescale_coldfire_channel_reset(ch) != 0) return -1; /* Enable channel done interrupt */ IP_BIT_SET(*ipfreescale_coldfire.channel[ch].cccr, IPFREESCALE_COLDFIRE_CCCRn_CDIE); /* Enable fetch next descriptor */ IP_BIT_SET(*ipfreescale_coldfire.channel[ch].cccr, IPFREESCALE_COLDFIRE_CCCRn_NE); return 0; } /* *=========================================================================== * ipfreescale_coldfire_channel_launch *=========================================================================== * Description: Launch descriptor to SEC channel. * Parameters: ch - channel to launch. * dp - pointer to descriptor. * Returns: nothing. */ IP_STATIC void ipfreescale_coldfire_channel_launch(int ch, Ipfreescale_coldfire_descriptor *dp) { *ipfreescale_coldfire.channel[ch].fr = (Ip_u32)dp; } /* *=========================================================================== * ipfreescale_coldfire_channel_waitforcompletion *=========================================================================== * Description: Wait for SEC channel to complete. * Parameters: ch - channel to wait for. * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_STATIC int ipfreescale_coldfire_channel_waitforcompletion(int ch) { int maxwait = IPFREESCALE_COLDFIRE_MAXWAIT; while(maxwait-- > 0) { if(ch == 0) { if(IP_BIT_ISSET(*ipfreescale_coldfire.sisrh, IPFREESCALE_COLDFIRE_SISRH_CHA0DN)) { IP_BIT_SET(*ipfreescale_coldfire.sicrh, IPFREESCALE_COLDFIRE_SICRH_CHA0DN); return 1; } } else if(ch == 1) { if(IP_BIT_ISSET(*ipfreescale_coldfire.sisrh, IPFREESCALE_COLDFIRE_SISRH_CHA1DN)) { IP_BIT_SET(*ipfreescale_coldfire.sicrh, IPFREESCALE_COLDFIRE_SICRH_CHA1DN); return 1; } } else { IP_PANIC(); } /* Let other tasks run */ ipfreescale_coldfire_yield_task(); } /* Check for channel errors */ if(IP_BIT_ISSET(*ipfreescale_coldfire.channel[ch].ccpsrl, IPFREESCALE_COLDFIRE_CCPSRLn_EUERR | IPFREESCALE_COLDFIRE_CCPSRLn_SERR | IPFREESCALE_COLDFIRE_CCPSRLn_DERR | IPFREESCALE_COLDFIRE_CCPSRLn_PERR | IPFREESCALE_COLDFIRE_CCPSRLn_TEA)) { return -1; } else { /* Timeout */ return 0; } } /* *=========================================================================== * ipfreescale_coldfire_reset *=========================================================================== * Description: Reset SEC. * Parameters: none. * Returns: nothing. */ IP_STATIC int ipfreescale_coldfire_reset(void) { int maxwait = IPFREESCALE_COLDFIRE_MAXWAIT; /* Reset the Coldfire SEC */ IP_BIT_SET(*ipfreescale_coldfire.mcr, IPFREESCALE_COLDFIRE_SMCR_SWR); /* Wait for reset sequence to complete */ while(maxwait-- > 0) { if(!IP_BIT_ISSET(*ipfreescale_coldfire.mcr, IPFREESCALE_COLDFIRE_SMCR_SWR)) return 0; } return -1; } /* *=========================================================================== * ipfreescale_coldfire_regs *=========================================================================== * Description: Populate SEC register structure. * Parameters: none. * Returns: nothing. */ IP_STATIC void ipfreescale_coldfire_regs(void) { int i; /* Registers */ ipfreescale_coldfire.jtagid = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_MCF_JTAGID_OFFSET); ipfreescale_coldfire.mcr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_SMCR_OFFSET); ipfreescale_coldfire.simrh = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_SIMRH_OFFSET); ipfreescale_coldfire.simrl = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_SIMRL_OFFSET); ipfreescale_coldfire.sisrh = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_SISRH_OFFSET); ipfreescale_coldfire.sisrl = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_SISRL_OFFSET); ipfreescale_coldfire.sicrh = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_SICRH_OFFSET); ipfreescale_coldfire.sicrl = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_SICRL_OFFSET); ipfreescale_coldfire.afrcr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_AFRCR_OFFSET); ipfreescale_coldfire.afsr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_AFSR_OFFSET); ipfreescale_coldfire.drcr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_DRCR_OFFSET); ipfreescale_coldfire.dsr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_DSR_OFFSET); ipfreescale_coldfire.mdrcr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_MDRCR_OFFSET); ipfreescale_coldfire.mdsr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_MDSR_OFFSET); ipfreescale_coldfire.rngrcr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_RNGRCR_OFFSET); ipfreescale_coldfire.rngsr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_RNGSR_OFFSET); ipfreescale_coldfire.aesrcr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_AESRCR_OFFSET); ipfreescale_coldfire.aessr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_AESSR_OFFSET); for(i=0; ihdr = peu<<28 | pmode<<20 | type<<4; } /* *=========================================================================== * ipfreescale_coldfire_descr_load_rng *=========================================================================== * Description: Load random number generation descriptor. * Parameters: data - pointer to random data. * length - length of random data. * dp - pointer to SEC descriptor. * Returns: nothing. */ IP_STATIC void ipfreescale_coldfire_descr_load_rng(Ip_u8 *data, Ip_u32 length, Ipfreescale_coldfire_descriptor *dp) { dp->len_1 = 0; dp->ptr_1 = IP_NULL; dp->len_2 = 0; dp->ptr_2 = IP_NULL; dp->len_3 = 0; dp->ptr_3 = IP_NULL; dp->len_4 = 0; dp->ptr_4 = IP_NULL; dp->len_5 = length - length%4; /* Must be multiple of 4 */ dp->ptr_5 = data; dp->len_6 = 0; dp->ptr_6 = IP_NULL; dp->len_7 = 0; dp->ptr_7 = IP_NULL; dp->next = IP_NULL; } /* *=========================================================================== * ipfreescale_coldfire_descr_load_mdeu *=========================================================================== * Description: Load message digest descriptor. * Parameters: data - pointer to data to hash. * length - length of data to hash. * digest - pointer to digest. * digestlen - length of digest. * dp - pointer to SEC descriptor. * Returns: nothing. */ IP_STATIC void ipfreescale_coldfire_descr_load_mdeu(IP_CONST Ip_u8 *data, Ip_u32 length, Ip_u8 *digest, Ip_u32 digestlen, Ipfreescale_coldfire_descriptor *dp) { dp->len_1 = 0; dp->ptr_1 = IP_NULL; dp->len_2 = 0; dp->ptr_2 = IP_NULL; dp->len_3 = 0; dp->ptr_3 = IP_NULL; dp->len_4 = length; dp->ptr_4 = (Ip_u8 *)data; dp->len_5 = 0; dp->ptr_5 = IP_NULL; dp->len_6 = digestlen; dp->ptr_6 = digest; dp->len_7 = 0; dp->ptr_7 = IP_NULL; dp->next = IP_NULL; } /* *=========================================================================== * ipfreescale_coldfire_descr_load_deu_cbc *=========================================================================== * Description: Load DES-CBC descriptor. * Parameters: out - pointer to output data * in - pointer to input data * length - length of data * key - pointer to the key. * keylen - length of key. * iv - pointer to the initialization vector. * dp - pointer to SEC descriptor. * Returns: nothing. */ IP_STATIC void ipfreescale_coldfire_descr_load_deu_cbc(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, Ip_u8 *key, int keylen, Ip_u8 *iv, Ipfreescale_coldfire_descriptor *dp) { dp->len_1 = 0; dp->ptr_1 = IP_NULL; dp->len_2 = IPFREESCALE_DES_IV_SIZE; dp->ptr_2 = iv; dp->len_3 = keylen; dp->ptr_3 = key; dp->len_4 = length; dp->ptr_4 = (Ip_u8 *)in; dp->len_5 = length; dp->ptr_5 = out; dp->len_6 = IPFREESCALE_DES_IV_SIZE; dp->ptr_6 = iv; dp->len_7 = 0; dp->ptr_7 = IP_NULL; dp->next = IP_NULL; } /* *=========================================================================== * ipfreescale_coldfire_descr_load_deu_ecb *=========================================================================== * Description: Load DES-ECB descriptor. * Parameters: out - pointer to output data * in - pointer to input data * length - length of data * key - pointer to the key. * keylen - length of key. * dp - pointer to SEC descriptor. * Returns: nothing. */ IP_STATIC void ipfreescale_coldfire_descr_load_deu_ecb(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, Ip_u8 *key, int keylen, Ipfreescale_coldfire_descriptor *dp) { dp->len_1 = 0; dp->ptr_1 = IP_NULL; dp->len_2 = 0; dp->ptr_2 = IP_NULL; dp->len_3 = keylen; dp->ptr_3 = key; dp->len_4 = length; dp->ptr_4 = (Ip_u8 *)in; dp->len_5 = length; dp->ptr_5 = out; dp->len_6 = 0; dp->ptr_6 = IP_NULL; dp->len_7 = 0; dp->ptr_7 = IP_NULL; dp->next = IP_NULL; } /* *=========================================================================== * ipfreescale_coldfire_descr_load_aesu_cbc *=========================================================================== * Description: Load AES-CBC descriptor. * Parameters: out - pointer to output data * in - pointer to input data * length - length of data * key - pointer to the key. * keylen - length of key. * iv - pointer to the initialization vector. * dp - pointer to SEC descriptor. * Returns: nothing. */ IP_STATIC void ipfreescale_coldfire_descr_load_aesu_cbc(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, Ip_u8 *key, Ip_u32 keylen, Ip_u8 *iv, Ipfreescale_coldfire_descriptor *dp) { dp->len_1 = 0; dp->ptr_1 = IP_NULL; dp->len_2 = IPFREESCALE_AES_IV_SIZE; dp->ptr_2 = iv; dp->len_3 = keylen; dp->ptr_3 = key; dp->len_4 = length; dp->ptr_4 = (Ip_u8 *)in; dp->len_5 = length; dp->ptr_5 = out; dp->len_6 = IPFREESCALE_AES_IV_SIZE; dp->ptr_6 = iv; dp->len_7 = 0; dp->ptr_7 = IP_NULL; dp->next = IP_NULL; } /* *=========================================================================== * ipfreescale_coldfire_descr_load_aesu_ecb *=========================================================================== * Description: Load AES-ECB descriptor. * Parameters: out - pointer to output data * in - pointer to input data * length - length of data * key - pointer to the key. * keylen - length of key. * dp - pointer to SEC descriptor. * Returns: nothing. */ IP_STATIC void ipfreescale_coldfire_descr_load_aesu_ecb(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, Ip_u8 *key, Ip_u32 keylen, Ipfreescale_coldfire_descriptor *dp) { dp->len_1 = 0; dp->ptr_1 = IP_NULL; dp->len_2 = 0; dp->ptr_2 = IP_NULL; dp->len_3 = keylen; dp->ptr_3 = key; dp->len_4 = length; dp->ptr_4 = (Ip_u8 *)in; dp->len_5 = length; dp->ptr_5 = out; dp->len_6 = 0; dp->ptr_6 = IP_NULL; dp->len_7 = 0; dp->ptr_7 = IP_NULL; dp->next = IP_NULL; } /* *=========================================================================== * ipfreescale_coldfire_descr_load_afeu *=========================================================================== * Description: Load RC4 descriptor. * Parameters: out - pointer to output data * in - pointer to input data * length - length of data * key - pointer to the key. * keylen - length of key. * ctxi - pointer to the input context. * ctxo - pointer to the output context. * dp - pointer to SEC descriptor. * Returns: nothing. */ IP_STATIC void ipfreescale_coldfire_descr_load_afeu(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, Ip_u8 *key, Ip_u32 keylen, Ip_u8 *ctxi, Ip_u8 *ctxo, Ipfreescale_coldfire_descriptor *dp) { dp->len_1 = 0; dp->ptr_1 = IP_NULL; if(key == IP_NULL) { dp->len_2 = IPFREESCALE_RC4_CTX_SIZE; dp->ptr_2 = ctxi; dp->len_3 = 0; dp->ptr_3 = IP_NULL; } else { dp->len_2 = 0; dp->ptr_2 = IP_NULL; dp->len_3 = keylen; dp->ptr_3 = key; } dp->len_4 = length; dp->ptr_4 = (Ip_u8 *)in; dp->len_5 = length; dp->ptr_5 = out; if(ctxo != IP_NULL) { dp->len_6 = IPFREESCALE_RC4_CTX_SIZE; dp->ptr_6 = ctxo; } else { dp->len_6 = 0; dp->ptr_6 = IP_NULL; } dp->len_7 = 0; dp->ptr_7 = IP_NULL; dp->next = IP_NULL; } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ #ifdef IPFREESCALE_USE_STATISTICS /* *=========================================================================== * ipfreescale_coldfire_print_stats *=========================================================================== * Description: Print SEC statistics. * Parameters: where - output destination ("syslog" or "stdout") * Returns: nothing. */ IP_GLOBAL void ipfreescale_coldfire_print_stats(char *where) { int i; char *buf; buf = ipcom_malloc(512); if(buf == IP_NULL) goto done; for(i=0; i= 0) ipfreescale_coldfire_release_channel(ch); return ret; } /* *=========================================================================== * ipfreescale_coldfire_md5_digest *=========================================================================== * Description: Calculate message digest using the MD5 algorithm. * Parameters: data - pointer to buffer with the data to hash. * length - length of data in bytes. * digest - pointer to buffer for the digest (16 bytes). * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_GLOBAL int ipfreescale_coldfire_md5_digest(IP_CONST Ip_u8 *data, Ip_u32 length, Ip_u8 *digest) { Ipfreescale_coldfire_descriptor descr; int ch, pmode, ret = -1; /* Acquire a crypto channel */ ch = ipfreescale_coldfire_reserve_channel(); if(ch < 0) { IPCOM_LOG0(INFO, "ipfreescale_coldfire_md5_digest() :: No channel available"); goto done; } /* Mode */ pmode = 1<<4; /* initialize */ pmode |= 1<<2; /* pad */ pmode |= 2; /* md5 */ /* Create descriptor */ ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_MDEU, pmode, IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_NO_AFEU, &descr); /* Load descriptor */ ipfreescale_coldfire_descr_load_mdeu(data, length, digest, IPFREESCALE_MD5_DIGEST_SIZE, &descr); /* Engage crypto hardware */ ipfreescale_coldfire_flush_descriptor(&descr); ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_MDEU, IPFREESCALE_COLDFIRE_EU_NONE); done: /* Release the crypto channel */ if(ch >= 0) ipfreescale_coldfire_release_channel(ch); return ret; } /* *=========================================================================== * ipfreescale_coldfire_sha1_digest *=========================================================================== * Description: Calculate message digest using the SHA1 algorithm. * Parameters: data - pointer to buffer with the data to hash. * length - length of data in bytes. * digest - pointer to buffer for the digest (20 bytes). * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_GLOBAL int ipfreescale_coldfire_sha1_digest(IP_CONST Ip_u8 *data, Ip_u32 length, Ip_u8 *digest) { Ipfreescale_coldfire_descriptor descr; int ch, pmode, ret = -1; /* Acquire a crypto channel */ ch = ipfreescale_coldfire_reserve_channel(); if(ch < 0) { IPCOM_LOG0(INFO, "ipfreescale_coldfire_sha1_digest() :: No channel available"); goto done; } /* Mode */ pmode = 1<<4; /* initialize */ pmode |= 1<<2; /* pad */ pmode |= 0; /* sha1 */ /* Create descriptor */ ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_MDEU, pmode, IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_NO_AFEU, &descr); /* Load descriptor */ ipfreescale_coldfire_descr_load_mdeu(data, length, digest, IPFREESCALE_SHA1_DIGEST_SIZE, &descr); /* Engage crypto hardware */ ipfreescale_coldfire_flush_descriptor(&descr); ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_MDEU, IPFREESCALE_COLDFIRE_EU_NONE); done: /* Release the crypto channel */ if(ch >= 0) ipfreescale_coldfire_release_channel(ch); return ret; } /* *=========================================================================== * ipfreescale_coldfire_des_cbc_cipher *=========================================================================== * Description: Encrypt or decrypt a data buffer using DES-CBC cipher. * Parameters: data - pointer to buffer with the data. * length - length of data in bytes. * key - pointer to buffer with the key (8 bytes). * iv - Initialization vector (8 bytes). Updated by hardware. * enc - 1 = encryption. 0 = decryption. * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_GLOBAL int ipfreescale_coldfire_des_cbc_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u8 *iv, int enc) { Ipfreescale_coldfire_descriptor descr; int ch, pmode, ret = -1; /* Acquire a crypto channel */ ch = ipfreescale_coldfire_reserve_channel(); if(ch < 0) { IPCOM_LOG0(INFO, "ipfreescale_coldfire_des_cbc_cipher() :: No channel available"); goto done; } /* Mode */ pmode = 1<<2; /* cbc */ if(enc) pmode |= 1; /* encrypt/decrypt */ /* Create descriptor */ ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_DEU, pmode, IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_NO_AFEU, &descr); #ifdef IPFREESCALE_COLDFIRE_FIX_DES_PARITY { unsigned int i; for (i=0; i= 0) ipfreescale_coldfire_release_channel(ch);; return ret; } /* *=========================================================================== * ipfreescale_coldfire_des_ecb_cipher *=========================================================================== * Description: Encrypt or decrypt a data buffer using DES-ECB cipher. * Parameters: data - pointer to buffer with the data. * length - length of data in bytes. * key - pointer to buffer with the key (8 bytes). * enc - 1 = encryption. 0 = decryption. * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_GLOBAL int ipfreescale_coldfire_des_ecb_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, int enc) { Ipfreescale_coldfire_descriptor descr; int ch, pmode, ret = -1; /* Acquire a crypto channel */ ch = ipfreescale_coldfire_reserve_channel(); if(ch < 0) { IPCOM_LOG0(INFO, "ipfreescale_coldfire_des_ecb_cipher() :: No channel available"); goto done; } /* Mode */ pmode = 0<<2; /* ecb */ if(enc) pmode |= 1; /* encrypt/decrypt */ /* Create descriptor */ ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_DEU, pmode, IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_NO_AFEU, &descr); #ifdef IPFREESCALE_COLDFIRE_FIX_DES_PARITY { unsigned int i; for (i=0; i= 0) ipfreescale_coldfire_release_channel(ch); return ret; } /* *=========================================================================== * ipfreescale_coldfire_3des_cbc_cipher *=========================================================================== * Description: Encrypt or decrypt a data buffer using 3DES-CBC cipher. * Parameters: data - pointer to buffer with the data. * length - length of data in bytes. * key - pointer to buffer with the key (24 bytes). * iv - Initialization vector (8 bytes). Updated by hardware. * enc - 1 = encryption. 0 = decryption. * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_GLOBAL int ipfreescale_coldfire_3des_cbc_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u8 *iv, int enc) { Ipfreescale_coldfire_descriptor descr; int ch, pmode, ret = -1; /* Acquire a crypto channel */ ch = ipfreescale_coldfire_reserve_channel(); if(ch < 0) { IPCOM_LOG0(INFO, "ipfreescale_coldfire_3des_cbc_cipher() :: No channel available"); goto done; } /* Mode */ pmode = 1<<2; /* cbc */ pmode |= 1<<1; /* triple des */ if(enc) pmode |= 1; /* encrypt/decrypt */ /* Create descriptor */ ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_DEU, pmode, IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_NO_AFEU, &descr); #ifdef IPFREESCALE_COLDFIRE_FIX_DES_PARITY { unsigned int i; for (i=0; i= 0) ipfreescale_coldfire_release_channel(ch); return ret; } /* *=========================================================================== * ipfreescale_coldfire_3des_ecb_cipher *=========================================================================== * Description: Encrypt or decrypt a data buffer using 3DES-ECB cipher. * Parameters: data - pointer to buffer with the data. * length - length of data in bytes. * key - pointer to buffer with the key (24 bytes). * enc - 1 = encryption. 0 = decryption. * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_GLOBAL int ipfreescale_coldfire_3des_ecb_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, int enc) { Ipfreescale_coldfire_descriptor descr; int ch, pmode, ret = -1; /* Acquire a crypto channel */ ch = ipfreescale_coldfire_reserve_channel(); if(ch < 0) { IPCOM_LOG0(INFO, "ipfreescale_coldfire_3des_ecb_cipher() :: No channel available"); goto done; } /* Mode */ pmode = 0<<2; /* ecb */ pmode |= 1<<1; /* triple des */ if(enc) pmode |= 1; /* encrypt/decrypt */ /* Create descriptor */ ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_DEU, pmode, IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_NO_AFEU, &descr); #ifdef IPFREESCALE_COLDFIRE_FIX_DES_PARITY { unsigned int i; for (i=0; i= 0) ipfreescale_coldfire_release_channel(ch); return ret; } /* *=========================================================================== * ipfreescale_coldfire_aes_cbc_cipher *=========================================================================== * Description: Encrypt or decrypt a data buffer using AES-CBC cipher. * Parameters: data - pointer to buffer with the data. * length - length of data in bytes. * key - pointer to buffer with the key (16 bytes). * iv - Initialization vector (16 bytes). Updated by hardware. * enc - 1 = encryption. 0 = decryption. * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_GLOBAL int ipfreescale_coldfire_aes_cbc_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u32 keylen, Ip_u8 *iv, int enc) { Ipfreescale_coldfire_descriptor descr; int ch, pmode, ret = -1; /* Acquire a crypto channel */ ch = ipfreescale_coldfire_reserve_channel(); if(ch < 0) { IPCOM_LOG0(INFO, "ipfreescale_coldfire_aes_cbc_cipher() :: No channel available"); goto done; } /* Mode */ pmode = 1<<1; /* cbc */ if(enc) pmode |= 1; /* encrypt/decrypt */ /* Create descriptor */ ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_AESU, pmode, IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_NO_AFEU, &descr); /* Load descriptor */ ipfreescale_coldfire_descr_load_aesu_cbc(out, in, length, key, keylen, iv, &descr); /* Engage crypto hardware */ ipfreescale_coldfire_flush_descriptor(&descr); ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_AESU, IPFREESCALE_COLDFIRE_EU_NONE); done: /* Release the crypto channel */ if(ch >= 0) ipfreescale_coldfire_release_channel(ch); return ret; } /* *=========================================================================== * ipfreescale_coldfire_aes_ecb_cipher *=========================================================================== * Description: Encrypt or decrypt a data buffer using AES-ECB cipher. * Parameters: data - pointer to buffer with the data. * length - length of data in bytes. * key - pointer to buffer with the key (16 bytes). * enc - 1 = encryption. 0 = decryption. * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_GLOBAL int ipfreescale_coldfire_aes_ecb_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u32 keylen, int enc) { Ipfreescale_coldfire_descriptor descr; int ch, pmode, ret = -1; /* Acquire a crypto channel */ ch = ipfreescale_coldfire_reserve_channel(); if(ch < 0) { IPCOM_LOG0(INFO, "ipfreescale_coldfire_aes_ecb_cipher() :: No channel available"); goto done; } /* Mode */ pmode = 0<<1; /* cbc */ if(enc) pmode |= 1; /* encrypt/decrypt */ /* Create descriptor */ ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_AESU, pmode, IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_NO_AFEU, &descr); /* Load descriptor */ ipfreescale_coldfire_descr_load_aesu_ecb(out, in, length, key, keylen, &descr); /* Engage crypto hardware */ ipfreescale_coldfire_flush_descriptor(&descr); ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_AESU, IPFREESCALE_COLDFIRE_EU_NONE); done: /* Release the crypto channel */ if(ch >= 0) ipfreescale_coldfire_release_channel(ch); return ret; } /* *=========================================================================== * ipfreescale_coldfire_rc4_cipher *=========================================================================== * Description: RC4 stream cipher. Provide either key + output context * for operation with key load and context save or input context + * output context for operation with context load and context save. * Parameters: data - pointer to buffer with the data to cipher. * length - length of data in bytes. * key - pointer to buffer with the key. * keylen - length of encryption key (1-16 bytes). * ctxi - buffer with input context (259 bytes). * ctxo - buffer with output context (259 bytes). * Returns: -1 = error * 0 = timeout * 1 = ok */ IP_GLOBAL int ipfreescale_coldfire_rc4_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u32 keylen, Ip_u8 *ctxi, Ip_u8 *ctxo) { Ipfreescale_coldfire_descriptor descr; int ch, pmode = 0, ret = -1; /* Acquire a crypto channel */ ch = ipfreescale_coldfire_reserve_channel(); if(ch < 0) { IPCOM_LOG0(INFO, "ipfreescale_coldfire_rc4_cipher() :: No channel available"); goto done; } /* Mode */ if(ctxi != IP_NULL) { pmode += 1; /* prevent permute */ pmode += 1<<2; /* context from input fifo */ } pmode += 1<<1; /* dump context */ /* Create descriptor */ ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_AFEU, pmode, IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_AFEU, &descr); /* Load descriptor */ if(key != IP_NULL) ipfreescale_coldfire_descr_load_afeu(out, in, length, key, keylen, IP_NULL, ctxo, &descr); else if(ctxi != IP_NULL) ipfreescale_coldfire_descr_load_afeu(out, in, length, IP_NULL, 0, ctxi, ctxo, &descr); else { IP_PANIC(); goto done; } /* Engage crypto hardware */ ipfreescale_coldfire_flush_descriptor(&descr); ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_AFEU, IPFREESCALE_COLDFIRE_EU_NONE); done: /* Release the crypto channel */ if(ch >= 0) ipfreescale_coldfire_release_channel(ch); return ret; } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ #else int ipfreescale_coldfire_empty_file; #endif /* #ifdef IPFREESCALE_COLDFIRE */ /* **************************************************************************** * END OF FILE **************************************************************************** */