📄 sec2_dpd.c
字号:
/**************************************************************************** * sec2_dpd.c -- Code to construct a packet descriptor for SEC2 Driver **************************************************************************** * Copyright (c) Certicom Corp. 1996-2002. All rights reserved * Copyright (c) 2003-2005 Freescale Semiconductor * All Rights Reserved. Proprietary and Confidential. * * NOTICE: The information contained in this file is proprietary * to Freescale Semiconductor, and is being made available to * Freescale's customers under strict license agreements. * Use or disclosure of this information is permissible only * under the terms of the existing license agreement. ***************************************************************************//* * Revision History: * 1.0 Aug 24,2003 dgs - adapted from the final version of mpc18x * May 26,2004 sec - add support for scatter pointers * 1.1.0 Nov 16,2004 sec - incorporate linux changes from prior versions * 1.1.1 Dec 16,2004 sec - clean up prototypes and warnings * 1.2 Jan 27,2005 sec - bugfix in DPD dumper */#include "vxWorks.h"#include "logLib.h"#include "sec2_const.h"#include "Sec2Descriptors.h"#include "sec2_dpd_Table.h"int sec2_VerifyRequest(void *request, DPD_DETAILS_ENTRY *pDesc);DPD_DETAILS_ENTRY *sec2_GetRequestDescEntry(unsigned long opId);#define DBG#if defined(DBG)extern unsigned long SEC2DebugLevel;#endif/* Build a SEC2-channel-compatible fragment map from a generic one *//* inList: external linked list *//* ptrEnt: will become head of compatible list we'll construct *//* */int MapScatterFragments(unsigned long inList, unsigned long *ptrEnt){ UINT32 i, listSiz; EXT_SCATTER_ELEMENT *inElem; SCATTER_ELEMENT *outList; inElem = (EXT_SCATTER_ELEMENT *)inList; /* How many elements to alloc? */ listSiz = 0; while (inElem != NULL) { listSiz++; inElem = (EXT_SCATTER_ELEMENT *)inElem->next; } SEC2Dump(DBGTXT_SETRQ, ("MapScatterFragments(): list 0x%08lx has %d fragments\n", inList, listSiz)); /* Allocate a chunk off the driver's available heap */ outList = (SCATTER_ELEMENT *) malloc(sizeof(SCATTER_ELEMENT) * listSiz); if (outList == NULL) return(SEC2_FRAGMENT_POOL_EXHAUSTED); /* Stuff allocated chunk with caller's info */ i = 0; inElem = (EXT_SCATTER_ELEMENT *)inList; while (inElem != NULL) { outList[i].segAddr = (void *)__vpa((unsigned long)inElem->fragment); outList[i].segLen = (unsigned short)inElem->size; outList[i].linkStat = 0; inElem = (EXT_SCATTER_ELEMENT *) inElem->next; SEC2Dump(DBGTXT_SETRQ, ("MapScatterFragments(): new fragment 0x%08x, %d bytes\n", (unsigned)outList[i].segAddr, outList[i].segLen)); i++; } /* once done, set the "return" bit in the last element */ outList[i - 1].linkStat |= SEGLIST_RETURN; *ptrEnt = __vpa((unsigned long)outList); return(SEC2_SUCCESS);} /* Free a SEC2-hardware-compatible fragment chain. antithesis of MapScatterFragments *//* Should be called upon as part of a channel interrupt cleanup process */void UnmapScatterFragments(unsigned long *ptrEnt){/* free((void *)Sec2_ChannelAssignments[channel].Dpds[i]->fld[j].ptr); */}/* * Convert driver-native request structure to DPD and insert */int sec2_RequestToDpd(register GENERIC_REQ *pReq, register int channel, DPD_DETAILS_ENTRY *pDesc){ /*register DPD_DETAILS_ENTRY *pDesc;*/ register unsigned long opId; register int i; register int dpdCount; if (pReq == NULL) return SEC2_NULL_REQUEST; dpdCount = 0; /* process request(s) */ /* do {stuff} while pReq points to real request */ /*do {*/ /* pDesc = sec2_GetRequestDescEntry (pReq->opId); if (pDesc == NULL) return SEC2_INVALID_OPERATION_ID;*/ /* * We have sufficient resources (DPD slots) to process this request. * Initialize a DPD and link the prior DPD to this one (if it is not the first) */ memset(Sec2_ChannelAssignments[channel].Dpds[dpdCount], 0x00, sizeof(SEC2_DPD)); /* fill in the dpd header */ opId = pReq->opId; (Sec2_ChannelAssignments[channel].Dpds[dpdCount])->header = pDesc->hdrDesc[1*(opId & DESC_NUM_MASK)]; /* For each field in a request: */ for (i = 0; i < NUM_DPD_FLDS && pDesc->fld[i].txt != NULL; i++) { if (*(long *)pDesc->fld[i].txt == *(long *)"NIL") { (Sec2_ChannelAssignments[channel].Dpds[dpdCount])->fld[i].ptr = 0; (Sec2_ChannelAssignments[channel].Dpds[dpdCount])->fld[i].len = 0; } else { /* deal with basic pointer */ /* if offset AND caller specfied non-NULL pointer, assign/convert that pointer */ if ((pDesc->fld[i].ptrOffset1st != 0) && *(unsigned int *)((unsigned int)pReq + pDesc->fld[i].ptrOffset1st)) { (Sec2_ChannelAssignments[channel].Dpds[dpdCount])->fld[i].ptr = __vpa(*(unsigned int *) ((unsigned int)pReq + pDesc->fld[i].ptrOffset1st)); } /* if scatter pointer, deal with special case */ #if 0 if (pReq->scatterBufs & (0x01 << i)) { SEC2Dump(DBGTXT_SETRQ, ("sec2_RequestToDpd(): pointer word %d is scattered\n", i+1)); /* this should be linked list to fragment map, do conversion */ status = MapScatterFragments(*(unsigned int *)((unsigned int)pReq + pDesc->fld[i].ptrOffset1st), &(DPDPTR->fld[i].ptr)); if (status != SEC2_SUCCESS) /* map failed? */ return(status); } #endif /* deal with length */ (Sec2_ChannelAssignments[channel].Dpds[dpdCount])->fld[i].len = *(unsigned int *) ((unsigned int)pReq + pDesc->fld[i].lenOffset1st); (Sec2_ChannelAssignments[channel].Dpds[dpdCount])->fld[i].len <<= 16;#if 0 if (pDesc->fld[i].extOffset != 0) (Sec2_ChannelAssignments[channel].Dpds[dpdCount])->fld[i].len |= *(unsigned int *) ((unsigned int)pReq + pDesc->fld[i].extOffset) << 8; if (pReq->scatterBufs & (0x01 << i)) (Sec2_ChannelAssignments[channel].Dpds[dpdCount])->fld[i].len |= PTRTYPE_JBIT; /* set scatter flag bit */#endif } }#if 0 /*DRIVER_IPSEC_DBG 打印DPD*/ /* If DPD dump requested, show this packet descriptor content */ if (1/*SEC2DebugLevel | DBGTXT_DPDSHOW*/) { SEC2Dump(DBGTXT_DPDSHOW, ("DPD header = 0x%08lx\n", Sec2_ChannelAssignments[channel].Dpds[dpdCount]->header)); SEC2Dump(DBGTXT_DPDSHOW, ("Primary EU/Mode 0x%02lx:%02lx, ", (Sec2_ChannelAssignments[channel].Dpds[dpdCount]->header & 0xf0000000) >> 28, (Sec2_ChannelAssignments[channel].Dpds[dpdCount]->header & 0x0ff00000) >> 20)); SEC2Dump(DBGTXT_DPDSHOW, ("Secondary EU/Mode 0x%02lx:%02lx, ", (Sec2_ChannelAssignments[channel].Dpds[dpdCount]->header & 0x000f0000) >> 16, (Sec2_ChannelAssignments[channel].Dpds[dpdCount]->header & 0x0000ff00) >> 8)); SEC2Dump(DBGTXT_DPDSHOW, ("Type 0x%02lx, ", (Sec2_ChannelAssignments[channel].Dpds[dpdCount]->header & 0x000000f8) >> 3)); if (Sec2_ChannelAssignments[channel].Dpds[dpdCount]->header & 0x00000002) SEC2Dump(DBGTXT_DPDSHOW, ("Inbound, ")); else SEC2Dump(DBGTXT_DPDSHOW, ("Outbound, ")); if (Sec2_ChannelAssignments[channel].Dpds[dpdCount]->header & 0x00000001) SEC2Dump(DBGTXT_DPDSHOW, ("Done\n")); else SEC2Dump(DBGTXT_DPDSHOW, ("\n")); for (i = 0; i < NUM_DPD_FLDS; i++) SEC2Dump(DBGTXT_DPDSHOW, ("DPD ptr:len/ext p%d = 0x%08lx:%08lx\n", i, Sec2_ChannelAssignments[channel].Dpds[dpdCount]->fld[i].ptr, Sec2_ChannelAssignments[channel].Dpds[dpdCount]->fld[i].len)); } /* if (DPD SHOW) */#endif /* Move onto the next block */ /* pReq = (GENERIC_REQ *)pReq->nextReq; dpdCount++; } while (pReq != NULL); *//* End while (request != NULL) */ return SEC2_SUCCESS;} /* end of RequestToDpd *//* * Validate request content */int sec2_VerifyRequest(register void *request, register DPD_DETAILS_ENTRY *pDesc){ register int i; register unsigned long len;/* register unsigned long addr; */ for (i = 0; i < NUM_DPD_FLDS && pDesc->fld[i].txt != NULL; i++) { /* A NULL pointer to a size checking function means "don't bother checking" */ if (pDesc->fld[i].pFncSize != NULL) { len = *(unsigned int *)((unsigned int)request + pDesc->fld[i].lenOffset1st); if (!pDesc->fld[i].pFncSize(len)) { logMsg("sec2_VerifyRequest->fld(%s) Invalid Length=%ld\n", (int)pDesc->fld[i].txt, len,3,4,5,6); return SEC2_INVALID_LENGTH; } } /* check Extent Length < 128 */ if (pDesc->fld[i].extOffset != 0) { len = *(unsigned int *)((unsigned int)request + pDesc->fld[i].extOffset); if (len >= 128) return SEC2_INVALID_LENGTH; } } return SEC2_SUCCESS;}/* Scan the DPDDetails table for a particular opId value. Return a pointer to the entry if it is found, NULL otherwise*/DPD_DETAILS_ENTRY *sec2_GetRequestDescEntry(unsigned long opId){ int i = 0; opId &= DESC_TYPE_MASK; while (sec2_DpdDetails[i].txt != NULL && sec2_DpdDetails[i].opId != opId) i++; return(sec2_DpdDetails[i].opId == 0 ? NULL : &sec2_DpdDetails[i]);}/* The following Chk() routines and the FitInBlock() routine are used to verify that the length of a data area is consistent with a request type. They are supplied as pointers to functions in the DPDDetails table*/BOOLEAN ChkDesIvLen(unsigned long len){ return len != 0 && len != DES_BLOCK ? FALSE : TRUE;}BOOLEAN ChkDesKeyLen(unsigned long len){ return len != DES_BLOCK && len != (2*DES_BLOCK) && len != (3*DES_BLOCK) ? FALSE : TRUE;}BOOLEAN ChkDesStaticDataLen(unsigned long len){ return (len & 0x7) != 0 ? FALSE : TRUE;}BOOLEAN ChkDesDataLen(unsigned long len){ return (len & 0x7) != 0 ? FALSE : TRUE;}BOOLEAN ChkDesCtxLen(unsigned long len){ return len != 0 && len != DES_BLOCK != 0 ? FALSE : TRUE;}BOOLEAN ChkAesKeyLen(unsigned long len){ return len != 16 && len != 24 && len != 32 ? FALSE : TRUE;}BOOLEAN ChkAesIvLen(unsigned long len){ return len != 0 && len != 16 ? FALSE : TRUE;}BOOLEAN ChkArcKeyLen(unsigned long len){ return len < ARC4_MIN_KEYBYTES || len > ARC4_MAX_KEYBYTES ? FALSE : TRUE;}BOOLEAN ChkArcCtxLen(unsigned long len){ return len != ARC4_CONTEXTBYTES ? FALSE : TRUE;}BOOLEAN ChkOptionalArcCtxLen(unsigned long len){ return len != ARC4_CONTEXTBYTES && len != 0 ? FALSE : TRUE;}BOOLEAN ChkEccLen(unsigned long len){ return len > 64 ? FALSE : TRUE;}#if 0BOOLEAN FitInBlock(unsigned long len){ return len > sec2_BlockSize ? FALSE : TRUE;}#endifBOOLEAN ChkCcmpKeyLen(unsigned long len){ return len != 0 && len != 16 ? FALSE : TRUE;}#if 0static void drv_Show_sec2_dpd(int channel){ /* If DPD dump requested, show this packet descriptor content */ if (SEC2DebugLevel | DBGTXT_DPDSHOW) { SEC2Dump(DBGTXT_DPDSHOW, ("DPD header = 0x%08lx\n", Sec2_ChannelAssignments[channel].Dpds[0]->header)); SEC2Dump(DBGTXT_DPDSHOW, ("Primary EU/Mode 0x%02lx:%02lx, ", (Sec2_ChannelAssignments[channel].Dpds[0]->header & 0xf0000000) >> 28, (Sec2_ChannelAssignments[channel].Dpds[0]->header & 0x0ff00000) >> 20)); SEC2Dump(DBGTXT_DPDSHOW, ("Secondary EU/Mode 0x%02lx:%02lx, ", (Sec2_ChannelAssignments[channel].Dpds[0]->header & 0x000f0000) >> 16, (Sec2_ChannelAssignments[channel].Dpds[0]->header & 0x0000ff00) >> 8)); SEC2Dump(DBGTXT_DPDSHOW, ("Type 0x%02lx, ", (Sec2_ChannelAssignments[channel].Dpds[0]->header & 0x000000f8) >> 3)); if (Sec2_ChannelAssignments[channel].Dpds[0]->header & 0x00000002) SEC2Dump(DBGTXT_DPDSHOW, ("Inbound, ")); else SEC2Dump(DBGTXT_DPDSHOW, ("Outbound, ")); if (Sec2_ChannelAssignments[channel].Dpds[0]->header & 0x00000001) SEC2Dump(DBGTXT_DPDSHOW, ("Done\n")); else SEC2Dump(DBGTXT_DPDSHOW, ("\n")); for (i = 0; i < NUM_DPD_FLDS; i++) SEC2Dump(DBGTXT_DPDSHOW, ("DPD ptr:len/ext p%d = 0x%08lx:%08lx\n", i, Sec2_ChannelAssignments[channel].Dpds[0]->fld[i].ptr, Sec2_ChannelAssignments[channel].Dpds[0]->fld[i].len)); } /* if (DPD SHOW) */}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -