Files
m241Neelima/components/ip_net2-6.9/ipfreescale/src/ipfreescale_coldfire.c
T
2026-07-30 11:19:44 +05:30

1608 lines
54 KiB
C

/*
******************************************************************************
* 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 <markus@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 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 <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_syslog.h>
#include <ipcom_err.h>
#include <ipcom_os.h>
#include <iphwcrypto.h>
#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; i<IPFREESCALE_COLDFIRE_NUM_CHANNELS; i++)
{
ipfreescale_coldfire.channel[i].cccr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_CCCR_OFFSET + i * IPFREESCALE_COLDFIRE_CHANNEL_OFFSET);
ipfreescale_coldfire.channel[i].ccpsrh = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_CCPSRH_OFFSET + i * IPFREESCALE_COLDFIRE_CHANNEL_OFFSET);
ipfreescale_coldfire.channel[i].ccpsrl = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_CCPSRL_OFFSET + i * IPFREESCALE_COLDFIRE_CHANNEL_OFFSET);
ipfreescale_coldfire.channel[i].fr = (Ip_u32 *)((Ip_u32)IPFREESCALE_COLDFIRE_MBAR + (Ip_u32)IPFREESCALE_COLDFIRE_FR_OFFSET + i * IPFREESCALE_COLDFIRE_CHANNEL_OFFSET);
}
}
/*
*===========================================================================
* ipfreescale_coldfire_channel_error
*===========================================================================
* Description: Handle SEC channel error.
* Parameters: status - error status.
* ch - channel that caused the error.
* peu - primary execution unit.
* seu - secondary execution unit.
* Returns: nothing.
*/
IP_STATIC void
ipfreescale_coldfire_channel_error(int status, int ch, int peu, int seu)
{
if(status == 0)
{
/* Timeout */
IPFREESCALE_STATS(ch, e_tmo++);
IPCOM_LOG1(ERR, "ipfreescale_coldfire_channel_error() :: Channel %d timed out", ch);
}
else
{
/* Channel error */
if(IP_BIT_ISSET(*ipfreescale_coldfire.channel[ch].ccpsrl, IPFREESCALE_COLDFIRE_CCPSRLn_EUERR))
{
IPFREESCALE_STATS(ch, e_euerr++);
IPCOM_LOG1(ERR, "ipfreescale_coldfire_channel_error() :: Channel %d caused euerr", ch);
/* Reset the assigned execution units */
if(ipfreescale_coldfire_eu_reset(peu) != 0)
{
IPCOM_LOG1(ERR, "ipfreescale_coldfire_channel_error() :: Failed to reset eu %d", peu);
}
if(ipfreescale_coldfire_eu_reset(seu) != 0)
{
IPCOM_LOG1(ERR, "ipfreescale_coldfire_channel_error() :: Failed to reset eu %d", seu);
}
}
if(IP_BIT_ISSET(*ipfreescale_coldfire.channel[ch].ccpsrl, IPFREESCALE_COLDFIRE_CCPSRLn_SERR))
{
IPFREESCALE_STATS(ch, e_serr++);
IPCOM_LOG1(ERR, "ipfreescale_coldfire_channel_error() :: Channel %d caused serr", ch);
}
if(IP_BIT_ISSET(*ipfreescale_coldfire.channel[ch].ccpsrl, IPFREESCALE_COLDFIRE_CCPSRLn_DERR))
{
IPFREESCALE_STATS(ch, e_derr++);
IPCOM_LOG1(ERR, "ipfreescale_coldfire_channel_error() :: Channel %d caused derr", ch);
}
if(IP_BIT_ISSET(*ipfreescale_coldfire.channel[ch].ccpsrl, IPFREESCALE_COLDFIRE_CCPSRLn_PERR))
{
IPFREESCALE_STATS(ch, e_perr++);
IPCOM_LOG1(ERR, "ipfreescale_coldfire_channel_error() :: Channel %d caused perr", ch);
}
if(IP_BIT_ISSET(*ipfreescale_coldfire.channel[ch].ccpsrl, IPFREESCALE_COLDFIRE_CCPSRLn_TEA))
{
IPFREESCALE_STATS(ch, e_tea++);
IPCOM_LOG1(ERR, "ipfreescale_coldfire_channel_error() :: Channel %d caused tea", ch);
}
}
/* Re-initialize the channel */
if(ipfreescale_coldfire_channel_init(ch) != 0)
{
IPCOM_LOG1(ERR, "ipfreescale_coldfire_channel_error() :: Failed to initialize channel %d", ch);
}
}
/*
*===========================================================================
* ipfreescale_coldfire_descriptor_create
*===========================================================================
* Description: Create a SEC descriptor.
* Parameters: peu - primary execution unit.
* seu - secondary execution unit.
* dp - pointer to SEC descriptor.
* Returns: nothing.
*/
IP_STATIC void
ipfreescale_coldfire_descr_create(int peu, int pmode, int type, Ipfreescale_coldfire_descriptor *dp)
{
dp->hdr = 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<IPFREESCALE_COLDFIRE_NUM_CHANNELS; i++)
{
ipcom_sprintf(buf, "Channel %d:"IP_LF
" Usage:"IP_LF
" mdeu: %d"IP_LF
" deu: %d"IP_LF
" aesu: %d"IP_LF
" afeu: %d"IP_LF
" rng: %d"IP_LF
" Errors:"IP_LF
" tmo: %d"IP_LF
" euerr: %d"IP_LF
" serr: %d"IP_LF
" derr: %d"IP_LF
" perr: %d"IP_LF
" tea: %d"IP_LF,
i,
IPFREESCALE_STATS(i, u_mdeu),
IPFREESCALE_STATS(i, u_deu),
IPFREESCALE_STATS(i, u_aesu),
IPFREESCALE_STATS(i, u_afeu),
IPFREESCALE_STATS(i, u_rng),
IPFREESCALE_STATS(i, e_tmo),
IPFREESCALE_STATS(i, e_euerr),
IPFREESCALE_STATS(i, e_serr),
IPFREESCALE_STATS(i, e_derr),
IPFREESCALE_STATS(i, e_perr),
IPFREESCALE_STATS(i, e_tea));
if(ipcom_strcasecmp(where, "syslog") == 0)
{
IPCOM_LOG1(INFO, "%s", buf);
}
else if(ipcom_strcasecmp(where, "stdout") == 0)
{
ipcom_printf("%s\n", buf);
}
}
done:
if(buf != IP_NULL)
ipcom_free(buf);
}
/*
*===========================================================================
* ipfreescale_coldfire_clear_stats
*===========================================================================
* Description: Clear SEC statistics
* Parameters: none.
* Returns: nothing.
*/
IP_GLOBAL void
ipfreescale_coldfire_clear_stats(void)
{
int i;
for(i=0; i<IPFREESCALE_COLDFIRE_NUM_CHANNELS; i++)
ipcom_memset(&ipfreescale_coldfire.channel[i].stats, 0, sizeof(Ipfreescale_coldfire_stats));
}
#endif /* #ifdef IPFREESCALE_USE_STATISTICS */
/*
*===========================================================================
* ipfreescale_coldfire_init
*===========================================================================
* Description: Initialize SEC.
* Parameters: none.
* Returns: IPCOM_SUCCESS = ok.
* IPCOM_ERR_FAILED = error.
*/
IP_GLOBAL Ip_err
ipfreescale_coldfire_init(void)
{
Ip_err ret;
int i;
ipcom_memset(&ipfreescale_coldfire, 0, sizeof(ipfreescale_coldfire));
/* Create the channel resource mutex */
ret = ipcom_mutex_create(&ipfreescale_coldfire.chmtx);
if(ret != IPCOM_SUCCESS)
{
IPCOM_LOG0(ERR, "ipfreescale_coldfire_init() :: Failed to create mutex");
goto fail;
}
ipfreescale_coldfire_regs();
if(ipfreescale_coldfire_reset() != 0)
{
IPCOM_LOG0(ERR, "ipfreescale_coldfire_init() :: Failed to reset SEC");
ret = IPCOM_ERR_FAILED;
goto fail;
}
/* Mask unwanted interrupts */
IP_BIT_SET(*ipfreescale_coldfire.simrh, IPFREESCALE_COLDFIRE_SIMRH_AERR);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_TEA);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_DEUDN);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_DEUERR);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_AESUDN);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_AESUERR);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_MDEUDN);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_MDEUERR);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_AFEUDN);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_AFEUERR);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_RNGDN);
IP_BIT_SET(*ipfreescale_coldfire.simrl, IPFREESCALE_COLDFIRE_SIMRL_RNGERR);
/* Initialize channels */
for(i=0; i<IPFREESCALE_COLDFIRE_NUM_CHANNELS; i++)
{
/* Mask channel error interrupt */
if(i == 0)
IP_BIT_SET(*ipfreescale_coldfire.simrh, IPFREESCALE_COLDFIRE_SIMRH_CHA0ERR);
else if(i == 1)
IP_BIT_SET(*ipfreescale_coldfire.simrh, IPFREESCALE_COLDFIRE_SIMRH_CHA1ERR);
else
IP_PANIC();
/* Initialize channel */
if(ipfreescale_coldfire_channel_init(i) != 0)
{
IPCOM_LOG1(ERR, "ipfreescale_coldfire_init() :: Failed to initialize channel %d", i);
ret = IPCOM_ERR_FAILED;
goto fail;
}
}
/* Check processor type */
switch(*ipfreescale_coldfire.jtagid & IPFREESCALE_MCF_JTAGID_PROCESSOR)
{
case IPFREESCALE_MCF_JTAGID_MCF5485:
IPCOM_LOG0(INFO, "ipfreescale_start() :: Processor type is MCF5485.");
break;
case IPFREESCALE_MCF_JTAGID_MCF5475:
IPCOM_LOG0(INFO, "ipfreescale_start() :: Processor type is MCF5475.");
break;
default:
IPCOM_LOG0(WARNING, "ipfreescale_start() :: Processor type is unknown!");
break;
}
return IPCOM_SUCCESS;
fail:
if(ipfreescale_coldfire.chmtx != IP_NULL)
(void)ipcom_mutex_delete(&ipfreescale_coldfire.chmtx);
return ret;
}
/*
*===========================================================================
* ipfreescale_coldfire_reserve_channel
*===========================================================================
* Description: Reserve a SEC channel.
* Parameters: none.
* Returns: channel number or -1 if failed.
*/
IP_GLOBAL int
ipfreescale_coldfire_reserve_channel(void)
{
int i, ch = -1;
ipcom_mutex_lock(ipfreescale_coldfire.chmtx);
for(i=0; i<IPFREESCALE_COLDFIRE_NUM_CHANNELS; i++)
{
if(ipfreescale_coldfire.channel[i].in_use == IP_FALSE)
{
/* Mark channel busy */
ipfreescale_coldfire.channel[i].in_use = IP_TRUE;
ch = i;
break;
}
}
ipcom_mutex_unlock(ipfreescale_coldfire.chmtx);
return ch;
}
/*
*===========================================================================
* ipfreescale_coldfire_release_channel
*===========================================================================
* Description: Release a SEC channel.
* Parameters: ch - channel to release.
* Returns: nothing.
*/
IP_GLOBAL void
ipfreescale_coldfire_release_channel(int ch)
{
ipcom_mutex_lock(ipfreescale_coldfire.chmtx);
ipfreescale_coldfire.channel[ch].in_use = IP_FALSE;
ipcom_mutex_unlock(ipfreescale_coldfire.chmtx);
}
/*
*===========================================================================
* ipfreescale_coldfire_engage
*===========================================================================
* Description: Engage a SEC channel. Launch descriptor to channel and wait
* for completion.
* Parameters: dp - pointer to SEC descriptor.
* ch - channel.
* peu - primary execution unit.
* seu - secondary execution unit.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_GLOBAL int
ipfreescale_coldfire_engage(Ipfreescale_coldfire_descriptor *dp, int ch, int peu, int seu)
{
int status;
switch(peu)
{
case IPFREESCALE_COLDFIRE_EU_AFEU:
IPFREESCALE_STATS(ch, u_afeu++);
break;
case IPFREESCALE_COLDFIRE_EU_DEU:
IPFREESCALE_STATS(ch, u_deu++);
break;
case IPFREESCALE_COLDFIRE_EU_MDEU:
IPFREESCALE_STATS(ch, u_mdeu++);
break;
case IPFREESCALE_COLDFIRE_EU_RNG:
IPFREESCALE_STATS(ch, u_rng++);
break;
case IPFREESCALE_COLDFIRE_EU_AESU:
IPFREESCALE_STATS(ch, u_aesu++);
break;
default:
break;
}
if(seu == IPFREESCALE_COLDFIRE_EU_MDEU)
IPFREESCALE_STATS(ch, u_mdeu++);
ipfreescale_coldfire_channel_launch(ch, dp);
status = ipfreescale_coldfire_channel_waitforcompletion(ch);
if(status <= 0)
ipfreescale_coldfire_channel_error(status, ch, peu, seu);
return status;
}
/*
*===========================================================================
* ipfreescale_coldfire_random_gen
*===========================================================================
* Description: Generate sequence of random data.
* Parameters: data - pointer to buffer for random data.
* length - number of bytes in sequence.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_GLOBAL int
ipfreescale_coldfire_random_gen(Ip_u8 *data, Ip_u32 length)
{
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_random_gen() :: No channel available");
goto done;
}
/* Mode */
pmode = 0;
/* Create descriptor */
ipfreescale_coldfire_descr_create(IPFREESCALE_COLDFIRE_EU_RNG,
pmode,
IPFREESCALE_COLDFIRE_COMMON_NONSNOOP_NO_AFEU,
&descr);
/* Load descriptor */
ipfreescale_coldfire_descr_load_rng(data, length, &descr);
/* Engage crypto hardware */
ipfreescale_coldfire_flush_descriptor(&descr);
ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_RNG, IPFREESCALE_COLDFIRE_EU_NONE);
done:
/* Release the crypto channel */
if(ch >= 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<IPFREESCALE_DES_KEY_SIZE; i++)
((Ip_u8 *)key)[i] = ipfreescale_parity_odd[((Ip_u8 *)key)[i]];
}
#endif
/* Load descriptor */
ipfreescale_coldfire_descr_load_deu_cbc(out, in, length, key, IPFREESCALE_DES_KEY_SIZE, iv, &descr);
/* Engage crypto hardware */
ipfreescale_coldfire_flush_descriptor(&descr);
ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_DEU, IPFREESCALE_COLDFIRE_EU_NONE);
done:
/* Release the crypto channel */
if(ch >= 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<IPFREESCALE_DES_KEY_SIZE; i++)
((Ip_u8 *)key)[i] = ipfreescale_parity_odd[((Ip_u8 *)key)[i]];
}
#endif
/* Load descriptor */
ipfreescale_coldfire_descr_load_deu_ecb(out, in, length, key, IPFREESCALE_DES_KEY_SIZE, &descr);
/* Engage crypto hardware */
ipfreescale_coldfire_flush_descriptor(&descr);
ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_DEU, IPFREESCALE_COLDFIRE_EU_NONE);
done:
/* Release the crypto channel */
if(ch >= 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<IPFREESCALE_3DES_KEY_SIZE; i++)
((Ip_u8 *)key)[i] = ipfreescale_parity_odd[((Ip_u8 *)key)[i]];
}
#endif
/* Load descriptor */
ipfreescale_coldfire_descr_load_deu_cbc(out, in, length, key, IPFREESCALE_3DES_KEY_SIZE, iv, &descr);
/* Engage crypto hardware */
ipfreescale_coldfire_flush_descriptor(&descr);
ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_DEU, IPFREESCALE_COLDFIRE_EU_NONE);
done:
/* Release the crypto channel */
if(ch >= 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<IPFREESCALE_3DES_KEY_SIZE; i++)
((Ip_u8 *)key)[i] = ipfreescale_parity_odd[((Ip_u8 *)key)[i]];
}
#endif
/* Load descriptor */
ipfreescale_coldfire_descr_load_deu_ecb(out, in, length, key, IPFREESCALE_3DES_KEY_SIZE, &descr);
/* Engage crypto hardware */
ipfreescale_coldfire_flush_descriptor(&descr);
ret = ipfreescale_coldfire_engage(&descr, ch, IPFREESCALE_COLDFIRE_EU_DEU, IPFREESCALE_COLDFIRE_EU_NONE);
done:
/* Release the crypto channel */
if(ch >= 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
****************************************************************************
*/