/* * ubsec_SSLCommand: Process a list of Cipher commands. * * Immediate Status is returned. Completion status is returned * on a per command callback */ ubsec_Status_t ubsec_SSLCommand(ubsec_DeviceContext_t Context, ubsec_SSLCommandInfo_pt pCommand, int *NumCommands) { #ifdef UBSEC_SSL_SUPPORT DeviceInfo_pt pDevice=(DeviceInfo_pt)Context; VOLATILE MasterCommand_t *pMCR; VOLATILE Packet_t *pPacket; VOLATILE PacketContext_t *pContext; VOLATILE SSL_MACContext_t *pSSLMACContext; VOLATILE TLS_HMACContext_t *pTLSHMACContext; VOLATILE SSL_CryptoContext_t *pSSLCryptoContext; VOLATILE ARC4_CryptoContext_t *pARC4Context; VOLATILE Hash_Context_t *pHashContext; int i; long *plong; VOLATILE int PacketIndex; int CommandIndex=0; int CommandCount=*NumCommands; ubsec_Status_t Status; unsigned long SaveConfig; ubsec_FragmentInfo_pt pExtraFragment=(ubsec_FragmentInfo_pt) 0; Dbg_Print(DBG_CMD,( "ubsec: SSL command %d",*NumCommands )); /* * Check some parameters */ if(pDevice==NULL_DEVICE_INFO) { Dbg_Print(DBG_FATAL,( "NO DEV\n " )); return(UBSEC_STATUS_NO_DEVICE ); } Dbg_Print(DBG_CMD,( "\n")); if (!(UBSEC_IS_SSL_DEVICE(pDevice))) { Dbg_Print(DBG_FATAL,( "ubsec: SSL Command for a non SSL device %x \n ",pDevice->DeviceID )); return(UBSEC_STATUS_NO_DEVICE ); } /* SaveConfig=OS_EnterCriticalSection(pDevice); */ OS_EnterCriticalSection(pDevice, SaveConfig); /* Get the next MCR to load */ Get_New_MCR: *NumCommands=CommandIndex; /* Update number completed */ if ((pMCR=GetFreeMCR(pDevice,UBSEC_CIPHER_LIST,&Status))== NULL_MASTER_COMMAND) { Dbg_Print(DBG_CMD_FAIL,("ubsec: device busy MCR %x\n",Status)); goto Error_Return; } /* Add packets to this MCR. */ Dbg_Print(DBG_CMD,( "ubsec: mcr_index %d MCR %0x\n",pMCR->Index,pMCR)); /* Initialize the packet information */ PacketIndex = pMCR->NumberOfPackets; pPacket = &(pMCR->PacketArray[PacketIndex]); /* Set up the current packet. */ pContext = &pMCR->ContextList[PacketIndex]; Status=UBSEC_STATUS_SUCCESS; /* Wishful thinking? */ /* Process all the commands in the command list. */ for (; CommandIndex < CommandCount ; CommandIndex++) { /* Add all the packets to the MCR */ if( PacketIndex >= MCR_MAXIMUM_PACKETS ) { Dbg_Print(DBG_CMD,( "ubsec: overran mcr buffer. %d\n",PacketIndex,CommandIndex )); /* * We have filled this MCR. * Advance next free. Wrap around if necessary */ pDevice->NextFreeMCR[0]=(MasterCommand_pt) pMCR->pNextMCR; PushMCR(pDevice); /* Get it going (pipeline) */ goto Get_New_MCR; /* Try to add to the next MCR */ } pPacket->PacketContextBuffer=pContext->PhysicalAddress; /* Save the callback information. */ pMCR->CompletionArray[PacketIndex].CompletionCallback = pCommand->CompletionCallback; pMCR->CompletionArray[PacketIndex].CommandContext = pCommand->CommandContext; /* Now set up the packet processing parameters */ Dbg_Print(DBG_PACKET,( "ubsec: packet_Index %d, Context Buf %0x\n",PacketIndex,pContext )); /* Now setup the particular context */ pExtraFragment=(ubsec_FragmentInfo_pt) 0; switch (UBSEC_SSL_COMMAND(pCommand->Command)) { case UBSEC_SSL_MAC: pContext->cmd_structure_length= CPU_TO_CTRL_SHORT(SSLMAC_CONTEXT_SIZE); pContext->operation_type=OPERATION_SSL_MAC; pCommand->NumDestination=0; /* Make sure */ pSSLMACContext=&pContext->Context.SSL_Mac; RTL_MemZero(pSSLMACContext,sizeof(*pSSLMACContext)); #if (UBS_CRYPTONET_ATTRIBUTE == UBS_BIG_ENDIAN) pSSLMACContext->SequenceHigh=pCommand->Parameters.SSLMACParams.SequenceNumber.HighWord; pSSLMACContext->SequenceLow=pCommand->Parameters.SSLMACParams.SequenceNumber.LowWord; RTL_Memcpy(&pSSLMACContext->HMACKey[0],&pCommand->Parameters.SSLMACParams.key[0],20); #else pSSLMACContext->SequenceHigh=BYTESWAPLONG(pCommand->Parameters.SSLMACParams.SequenceNumber.HighWord); pSSLMACContext->SequenceLow=BYTESWAPLONG(pCommand->Parameters.SSLMACParams.SequenceNumber.LowWord); copywords((UBS_UINT32 *)&pSSLMACContext->HMACKey[0], (UBS_UINT32 *)&pCommand->Parameters.SSLMACParams.key[0],5); #endif pSSLMACContext->DataLength=CPU_TO_CTRL_SHORT(pCommand->Parameters.SSLMACParams.DataLength); pSSLMACContext->ContentType=pCommand->Parameters.SSLMACParams.ContentType; /* for (i=0,plong=(long *)&pSSLMACContext->HMACPad; i <SSL_MAC_PAD_LENGTH_LONG; i++) *plong++=SSL_MAC_PAD_VALUE_LONG; */ RTL_Memset((unsigned char*)pSSLMACContext->HMACPad, 0x36, 48); pExtraFragment=&pCommand->Parameters.HashParams.OutputHMAC; if( UBSEC_MAC_MD5 & pCommand->Command ) pSSLMACContext->CryptoFlag = CF_MD5; else if( UBSEC_MAC_SHA1 & pCommand->Command ) pSSLMACContext->CryptoFlag = CF_SHA1; break; case UBSEC_TLS: pContext->cmd_structure_length= CPU_TO_CTRL_SHORT(TLSHMAC_CONTEXT_SIZE); pContext->operation_type=OPERATION_TLS_HMAC; pCommand->NumDestination=0; /* Make sure */ pTLSHMACContext=&pContext->Context.TLS_HMac; RTL_MemZero(pTLSHMACContext,sizeof(*pTLSHMACContext)); #if (UBS_CRYPTONET_ATTRIBUTE == UBS_BIG_ENDIAN) /* Assume sequence numbers are in proper format. */ pTLSHMACContext->SequenceHigh=pCommand->Parameters.TLSHMACParams.SequenceNumber.HighWord; pTLSHMACContext->SequenceLow=pCommand->Parameters.TLSHMACParams.SequenceNumber.LowWord; #else /* Assume sequence numbers are in proper format. */ pTLSHMACContext->SequenceHigh=BYTESWAPLONG(pCommand->Parameters.TLSHMACParams.SequenceNumber.HighWord); pTLSHMACContext->SequenceLow=BYTESWAPLONG(pCommand->Parameters.TLSHMACParams.SequenceNumber.LowWord); #endif RTL_Memcpy( &pTLSHMACContext->HMACInnerState[0], pCommand->Parameters.TLSHMACParams.HMACState,sizeof(ubsec_HMAC_State_t)); /* printk("md5 = x%x sha = x%x command = x%x\n", UBSEC_MAC_MD5, UBSEC_MAC_SHA1, pCommand->Command); */ pTLSHMACContext->CryptoFlag = 0; if( UBSEC_MAC_MD5 & pCommand->Command ) pTLSHMACContext->CryptoFlag |= CF_MD5; else if( UBSEC_MAC_SHA1 & pCommand->Command ) pTLSHMACContext->CryptoFlag |= CF_SHA1; pTLSHMACContext->ContentType=pCommand->Parameters.TLSHMACParams.ContentType; pTLSHMACContext->Version = CPU_TO_CTRL_SHORT(pCommand->Parameters.TLSHMACParams.Version); pTLSHMACContext->DataLengthHi=HIGH_BYTE(pCommand->Parameters.TLSHMACParams.DataLength); pTLSHMACContext->DataLengthLo=LOW_BYTE(pCommand->Parameters.TLSHMACParams.DataLength); pExtraFragment=&pCommand->Parameters.TLSHMACParams.OutputHMAC; break; case UBSEC_SSL_CRYPTO: pContext->cmd_structure_length= CPU_TO_CTRL_SHORT(SSLCRYPTO_CONTEXT_SIZE); pContext->operation_type=OPERATION_SSL_CRYPTO; pSSLCryptoContext=&pContext->Context.SSL_Crypto; RTL_MemZero(pSSLCryptoContext,sizeof(*pSSLCryptoContext)); if (UBSEC_USING_CRYPT( pCommand->Command )) { pSSLCryptoContext->CryptoFlag |= CF_3DES; #if (UBS_CRYPTONET_ATTRIBUTE == UBS_BIG_ENDIAN) RTL_Memcpy(&pSSLCryptoContext->CryptoKey1[0], pCommand->Parameters.SSLCipherParams.CryptKey, 24); RTL_Memcpy(&pSSLCryptoContext->ComputedIV[0], &pCommand->Parameters.SSLCipherParams.InitialVector[0],8); #else copywords((UBS_UINT32 *)&pSSLCryptoContext->CryptoKey1[0], pCommand->Parameters.SSLCipherParams.CryptKey, 6); copywords((UBS_UINT32 *)&pSSLCryptoContext->ComputedIV[0], (UBS_UINT32 *)&pCommand->Parameters.SSLCipherParams.InitialVector[0],2); #endif } /* Set up the context flags for direction */ if (pCommand->Command & UBSEC_ENCODE) pSSLCryptoContext->CryptoFlag = CF_ENCODE; else pSSLCryptoContext->CryptoFlag = CF_DECODE; break; case UBSEC_HASH: pContext->cmd_structure_length= CPU_TO_CTRL_SHORT(HASH_CONTEXT_SIZE); pContext->operation_type=OPERATION_HASH; pHashContext=&pContext->Context.Hash; RTL_MemZero(pHashContext,sizeof(*pHashContext)); if( UBSEC_MAC_MD5 & pCommand->Command ) pHashContext->CryptoFlag |= CF_MD5; else if( UBSEC_MAC_SHA1 & pCommand->Command ) pHashContext->CryptoFlag |= CF_SHA1; pExtraFragment=&pCommand->Parameters.HashParams.OutputHMAC; pExtraFragment->FragmentLength=0; /* Only pointer is used .*/ pCommand->NumDestination=0; /* Should already be but... */ break; case UBSEC_ARC4: #if defined(UBSEC_582x) /* ARC4_NULL_DATA mode supported in "582x mode" driver for BCM5821 and later chips only */ if ((pCommand->Parameters.ARC4Params.KeyStateFlag & UBSEC_ARC4_STATE_NULL_DATA) && \ (pDevice->DeviceID < BROADCOM_DEVICE_ID_5821)) { Status=UBSEC_STATUS_INVALID_PARAMETER; goto MCR_Done; } #else /* ARC4_NULL_DATA mode not supported in "5820 mode" driver */ if (pCommand->Parameters.ARC4Params.KeyStateFlag & UBSEC_ARC4_STATE_NULL_DATA) { Status=UBSEC_STATUS_INVALID_PARAMETER; goto MCR_Done; } #endif /* UBSEC_582x */ pContext->cmd_structure_length= CPU_TO_CTRL_SHORT(ARC4_CONTEXT_SIZE); pContext->operation_type=OPERATION_ARC4; pARC4Context=&pContext->Context.ARC4_Crypto; RTL_MemZero(pARC4Context,sizeof(*pARC4Context)); if (pCommand->Parameters.ARC4Params.KeyStateFlag & UBSEC_ARC4_STATE_WRITEBACK) { /* printk("\nSRL: keystateflag = %d\n", pCommand->Parameters.ARC4Params.KeyStateFlag); */ pARC4Context->StateInfo|=ARC4_STATE_WRITEBACK; } if (pCommand->Parameters.ARC4Params.KeyStateFlag & UBSEC_ARC4_STATE_STATEKEY) { /* printk("\nSRL: keystateflag = %d\n", pCommand->Parameters.ARC4Params.KeyStateFlag); */ pARC4Context->StateInfo|=ARC4_STATE_STATEKEY; } #if defined(UBSEC_582x) if (pCommand->Parameters.ARC4Params.KeyStateFlag & UBSEC_ARC4_STATE_NULL_DATA) { /* printk("\nSRL: keystateflag = %d\n", pCommand->Parameters.ARC4Params.KeyStateFlag); */ pARC4Context->StateInfo|=ARC4_STATE_NULL_DATA; } #endif /* UBSEC_582x */ #if (UBS_CRYPTONET_ATTRIBUTE == UBS_BIG_ENDIAN) /* The initial "packed key" must be byteswapped for big endian CryptoNet builds */ if (pCommand->Parameters.ARC4Params.KeyStateFlag & UBSEC_ARC4_STATE_STATEKEY) copywords( (UBS_UINT32 *)pARC4Context->KeyState, (UBS_UINT32 *)pCommand->Parameters.ARC4Params.KeyStateIn, sizeof(ubsec_ARC4_State_t)/4); else #endif RTL_Memcpy( pARC4Context->KeyState,pCommand->Parameters.ARC4Params.KeyStateIn,sizeof(ubsec_ARC4_State_t)); pExtraFragment=&pCommand->Parameters.ARC4Params.state_out; break; default: Dbg_Print(DBG_CMD,( "ubsec: SSL Invalid Command %x\n",pCommand->Command )); Status=UBSEC_STATUS_INVALID_PARAMETER; goto MCR_Done; }; /* * Now add the packet input fragment information * First fragment will need to skip the MAC Header * Must have at least one fragment (pCommand->NumSource > 0). * * For ARC4_NULL_DATA mode, we still need to know how big the message is. * You can actually build a DMA-able input fragment list just like if you were * not using ARC4_NULL_DATA mode, but that method incurs unnecessary CPU cycles. * The fastest way is to create a single "dummy" input fragment, with * a FragmentLength equal to the length of the "virtual" message. * The "dummy" fragment's DataAddress will be ignored. Either way, * at least one input fragment must be present. */ if ((Status=SetupInputFragmentList((MasterCommand_pt)pMCR, (Packet_t *)pPacket,pCommand->NumSource,pCommand->SourceFragments))) { goto MCR_Done; } /* * Now add the packet output fragment information */ if ((Status=SetupOutputFragmentList((MasterCommand_pt)pMCR, (Packet_t *)pPacket,pCommand->NumDestination,pCommand->DestinationFragments,pExtraFragment))) { goto MCR_Done; } /* Sync the current context memory region for CryptoNet DMA use */ Dbg_Print(DBG_CNTXT_SYNC,( "ubsec: ubsec_SSLCommand() Sync Context to Device (0x%08X,%d,%d)\n", pMCR->ContextListHandle[PacketIndex], 0, CTRL_TO_CPU_SHORT(pContext->cmd_structure_length))); OS_SyncToDevice(pMCR->ContextListHandle[PacketIndex], 0, CTRL_TO_CPU_SHORT(pContext->cmd_structure_length)); #ifdef UBSEC_STATS if (UBSEC_SSL_COMMAND(pCommand->Command)== UBSEC_SSL_CRYPTO){ if (pCommand->Command & UBSEC_ENCODE){ pDevice->Statistics.BlocksEncryptedCount++; pDevice->Statistics.BytesEncryptedCount+=CTRL_TO_CPU_SHORT(pPacket->PacketLength); } else { pDevice->Statistics.BlocksDecryptedCount++; pDevice->Statistics.BytesDecryptedCount+=CTRL_TO_CPU_SHORT(pPacket->PacketLength); } } #endif /* Now inc the number of packets and prepare for the next command. */ pMCR->NumberOfPackets++; pCommand++; PacketIndex++; pPacket++; pContext++; } /* For (;CommandIndex < CommandCount ; CommandIndex++) */ #ifdef UBSDBG /* Print out the context information if required */ DumpCipherMCR(pMCR); #endif /* * If we are here then the MCR is built. * Either everything went great or we came straight here at the first * error condition we encountered. The MCR is filled only with those * packets that were built successfully (before any encountered error). * Push the MCR to the device. */ MCR_Done: *NumCommands=CommandIndex; /* Update number completed */ PushMCR(pDevice); #ifdef BLOCK /* Wait for all outstanding to complete */ while ((Status=WaitForCompletion(pDevice,(unsigned long)100000,UBSEC_CIPHER_LIST)) == UBSEC_STATUS_SUCCESS); if (Status!=UBSEC_STATUS_TIMEOUT) /* We are nested, return success */ Status=UBSEC_STATUS_SUCCESS; Error_Return: #else /* not BLOCKing */ Error_Return: /* Label to make sure that IRQs are enabled. */ #ifdef COMPLETE_ON_COMMAND_THREAD ubsec_PollDevice(pDevice); /* Try to complete some & cut down on ints */ #endif #endif /* BLOCK */ OS_LeaveCriticalSection(pDevice,SaveConfig); #ifdef UBSEC_STATS if (Status != UBSEC_STATUS_SUCCESS) pDevice->Statistics.CryptoFailedCount++; #endif return(Status); #else /* UBSEC_SSL_SUPPORT not defined */ return(UBSEC_STATUS_NO_DEVICE); #endif /* UBSEC_SSL_SUPPORT */ }
/* * ubsec_CipherCommand: Process a list of Cipher commands. * * Immediate Status is returned. Completion status is returned * on a per command callback */ ubsec_Status_t ubsec_CipherCommand(ubsec_DeviceContext_t Context, ubsec_CipherCommandInfo_pt pCommand, int *NumCommands) { DeviceInfo_pt pDevice=(DeviceInfo_pt)Context; VOLATILE MasterCommand_t *pMCR; VOLATILE Packet_t *pPacket; VOLATILE PacketContext_t *pContext; VOLATILE CipherContext_t *pCipherContext; VOLATILE int PacketIndex; VOLATILE int NumFrags; /* Number of fragments */ ubsec_FragmentInfo_t ExtraFragment, *pExtraFragment; int CommandIndex=0; int CommandCount=*NumCommands; ubsec_Status_t Status; UBS_UINT32 SaveConfig = 0; Dbg_Print(DBG_CMD,( "ubsec: ubsec command %d",*NumCommands )); /* * Check some parameters */ if(pDevice==NULL_DEVICE_INFO) { Dbg_Print(DBG_FATAL,( "NO DEV\n " )); return(UBSEC_STATUS_NO_DEVICE ); } Dbg_Print(DBG_CMD,( "\n")); if (OS_EnterCriticalSection(pDevice,SaveConfig)) { return(UBSEC_STATUS_DEVICE_BUSY); } /* Get the next MCR to load */ Get_New_MCR: *NumCommands=CommandIndex; /* Update number completed */ if ((pMCR=GetFreeMCR(pDevice,UBSEC_CIPHER_LIST,&Status))== NULL_MASTER_COMMAND) { Dbg_Print(DBG_CMD_FAIL,("ubsec: device busy MCR %x\n", Status)); goto Error_Return; } /* Add packets to this MCR. */ Dbg_Print(DBG_CMD,( "ubsec: mcr_index %d MCR %0x\n",pMCR->Index,pMCR)); /* Initialize the packet information */ PacketIndex = pMCR->NumberOfPackets; pPacket = &(pMCR->PacketArray[PacketIndex]); /* Set up the current packet. */ pContext = &pMCR->ContextList[PacketIndex]; Status=UBSEC_STATUS_SUCCESS; /* Wishful thinking? */ /* Process all the commands in the command list. */ for (; CommandIndex < CommandCount ; CommandIndex++) { /* Add all the packets to the MCR */ if( PacketIndex >= MCR_MAXIMUM_PACKETS ) { Dbg_Print(DBG_CMD,( "ubsec: overran mcr buffer. %d %d\n",PacketIndex,CommandIndex )); /* * We have filled this MCR with the max # of packets, * but still have more packets (commands) to do. * Advance next free. Wrap around if necessary */ pDevice->NextFreeMCR[UBSEC_CIPHER_LIST]= (MasterCommand_pt) pMCR->pNextMCR; /* For crypto MCRs, the contexts are accessed using a single handle */ /* for an array of contexts. This means that all contexts for an MCR */ /* are contiguous in memory, and that we can sync all contexts at */ /* once (now that we know that we're finished loading this MCR). */ /* Make DMA memory actually hold CPU-initialized context data */ Dbg_Print(DBG_CNTXT_SYNC,( "ubsec: ubsec_CipherCommand Sync %d Contexts to Device (0x%08X,%d,%d)\n", pMCR->NumberOfPackets, pMCR->ContextListHandle[0], 0, pMCR->NumberOfPackets * sizeof(PacketContext_t))); OS_SyncToDevice(pMCR->ContextListHandle[0],0, pMCR->NumberOfPackets * sizeof(PacketContext_t)); PushMCR(pDevice); /* Get it going (pipeline) */ goto Get_New_MCR; /* Try to add to the next MCR */ } /* Save the callback information. */ pMCR->CompletionArray[PacketIndex].CompletionCallback = pCommand->CompletionCallback; pMCR->CompletionArray[PacketIndex].CommandContext = pCommand->CommandContext; /* Now set up the packet processing parameters */ Dbg_Print(DBG_PACKET,( "ubsec: packet_Index %d, Context Buf %0x\n",PacketIndex,pContext )); pPacket->PacketContextBuffer=pContext->PhysicalAddress; pCipherContext=&pContext->Context.Cipher; RTL_MemZero(pCipherContext,sizeof(*pCipherContext)); #ifdef UBSEC_582x_CLASS_DEVICE /* Some extra fields to be filled in . */ pContext->cmd_structure_length= CPU_TO_CTRL_SHORT(sizeof(*pCipherContext)+4); /* For header. */ pContext->operation_type=OPERATION_IPSEC; /* send mode for DH */ #endif /* * Now add the packet input fragment information * First fragment will need to skip the MAC Header * We need at least one fragment. */ /* Sanity checks.*/ if (!(NumFrags=pCommand->NumSource)) { Dbg_Print(DBG_PACKET,( "ubsec: No Input fragments\n" )); Status=UBSEC_STATUS_INVALID_PARAMETER; goto MCR_Done; } if (NumFrags>(UBSEC_MAX_FRAGMENTS+1)) { Dbg_Print(DBG_PACKET,( "ubsec: Too Many Input fragments\n" )); Status=UBSEC_STATUS_INVALID_PARAMETER; goto MCR_Done; } Dbg_Print(DBG_PACKET,( "ubsec: Num Input Frags %d \n",NumFrags)); /* SetupInputFragmentList will always be successful here because of */ /* the sanity checks performed above. */ SetupInputFragmentList((MasterCommand_t *)pMCR, (Packet_t *)pPacket,NumFrags,pCommand->SourceFragments); /* * Now add the packet output fragment information * We need at least one fragment. */ /* Sanity checks */ if (!(NumFrags=pCommand->NumDestination)) { Dbg_Print(DBG_PACKET,( "ubsec: No Output fragments\n" )); Status=UBSEC_STATUS_INVALID_PARAMETER; goto MCR_Done; } if (NumFrags > (UBSEC_MAX_FRAGMENTS+1)) { Dbg_Print(DBG_PACKET,( "ubsec: Too Many Output fragments\n" )); Status=UBSEC_STATUS_INVALID_PARAMETER; goto MCR_Done; } Dbg_Print(DBG_PACKET,( "ubsec: Num Output Frags %d \n",NumFrags)); if (UBSEC_USING_MAC(pCommand->Command)) { /* We need an 'extra' fragment info struct for the auth data */ ExtraFragment.FragmentAddress = pCommand->AuthenticationInfo.FragmentAddress; /* Easy to do check here for invalid 'extra' fragment address */ if ( (long) ExtraFragment.FragmentAddress & 0x03 ) { Dbg_Print(DBG_PACKET,("ubsec: ################INVALID HMAC ADDRESS %08x\n",ExtraFragment.FragmentAddress)); Status=UBSEC_STATUS_INVALID_PARAMETER; goto Error_Return; } /* The CryptoNet chip knows how big the auth fragment is, but */ /* SetupOutputFragmentList() needs to see a length of zero. */ ExtraFragment.FragmentLength = 0; pExtraFragment = &ExtraFragment; } else { /* not doing authentication; pass NULL extra fragment info */ pExtraFragment = (ubsec_FragmentInfo_pt) 0; } /* SetupOutputFragmentList() checks frag list for allowable fragment */ /* addresses (4-byte aligned) and lengths (4-byte multiples). */ if (SetupOutputFragmentList((MasterCommand_t *)pMCR,(Packet_t *)pPacket,NumFrags, pCommand->DestinationFragments,pExtraFragment)) { Status=UBSEC_STATUS_INVALID_PARAMETER; goto Error_Return; } /* Set up the context flags */ if (pCommand->Command & UBSEC_ENCODE) pCipherContext->CryptoFlag = CF_ENCODE; else pCipherContext->CryptoFlag = CF_DECODE; if (UBSEC_USING_CRYPT( pCommand->Command )) { pCipherContext->CryptoFlag |= CF_3DES; pCipherContext->CryptoOffset = CPU_TO_CTRL_SHORT( pCommand->CryptHeaderSkip ); if (pCommand->Command &UBSEC_3DES) { #if (UBS_CRYPTONET_ATTRIBUTE == UBS_BIG_ENDIAN) RTL_Memcpy( &pCipherContext->CryptoKey1[0], pCommand->CryptKey, 24); #else copywords((UBS_UINT32 *)&pCipherContext->CryptoKey1[0], (UBS_UINT32 *)pCommand->CryptKey, 6); #endif } else { /* Des is implemented by using 3 copies of the same DES key */ #if (UBS_CRYPTONET_ATTRIBUTE == UBS_BIG_ENDIAN) RTL_Memcpy( &pCipherContext->CryptoKey1[0], pCommand->CryptKey, 8); #else copywords((UBS_UINT32 *) &pCipherContext->CryptoKey1[0], (UBS_UINT32 *) pCommand->CryptKey, 2); #endif RTL_Memcpy( &pCipherContext->CryptoKey2[0],&pCipherContext->CryptoKey1[0],sizeof(pCipherContext->CryptoKey1)); RTL_Memcpy( &pCipherContext->CryptoKey3[0],&pCipherContext->CryptoKey1[0],sizeof(pCipherContext->CryptoKey1)); } #if (UBS_CRYPTONET_ATTRIBUTE == UBS_BIG_ENDIAN) RTL_Memcpy(&pCipherContext->ComputedIV[0],&pCommand->InitialVector[0],8); #else copywords((UBS_UINT32 *) &pCipherContext->ComputedIV[0], (UBS_UINT32 *) &pCommand->InitialVector[0],2); #endif } /* If using HMAC then copy the authentication state to the context. */ if( UBSEC_USING_MAC( pCommand->Command ) ) { RTL_Memcpy( &pCipherContext->HMACInnerState[0], pCommand->HMACState, sizeof(ubsec_HMAC_State_t)); if( UBSEC_MAC_MD5 & pCommand->Command ) pCipherContext->CryptoFlag |= CF_MD5; else if( UBSEC_MAC_SHA1 & pCommand->Command ) pCipherContext->CryptoFlag |= CF_SHA1; } Dbg_Print( DBG_PACKET, ("ubsec: CryptoOffset and Flag [%04x][%04x]\n", CTRL_TO_CPU_SHORT( pCipherContext->CryptoOffset ), CTRL_TO_CPU_SHORT( pCipherContext->CryptoFlag )) ); #ifdef UBSEC_STATS if (pCipherContext->CryptoFlag & CF_DECODE) { pDevice->Statistics.BlocksDecryptedCount++; pDevice->Statistics.BytesDecryptedCount+=CTRL_TO_CPU_SHORT(pPacket->PacketLength); } else { pDevice->Statistics.BlocksEncryptedCount++; pDevice->Statistics.BytesEncryptedCount+=CTRL_TO_CPU_SHORT(pPacket->PacketLength); } #endif /* Now inc the number of packets and prepare for the next command. */ pMCR->NumberOfPackets++; pCommand++; PacketIndex++; pPacket++; pContext++; } /* For NumCommands-- */ /* * If we are here then the last packet(s) (commands) have been added to * the current MCR. * Push the MCR to the device. */ MCR_Done: *NumCommands=CommandIndex; /* Update number completed */ /* For crypto MCRs, the contexts are accessed using a single handle */ /* for an array of contexts. This means that all contexts for an MCR */ /* are contiguous in memory, and that we can sync all contexts at */ /* once (now that we know that we're finished loading this MCR). */ /* Make DMA memory actually hold CPU-initialized context data */ Dbg_Print(DBG_CNTXT_SYNC,( "ubsec: ubsec_CipherCommand Sync %d Contexts to Device (0x%08X,%d,%d)\n", pMCR->NumberOfPackets, pMCR->ContextListHandle[0], 0, pMCR->NumberOfPackets * sizeof(PacketContext_t))); OS_SyncToDevice(pMCR->ContextListHandle[0],0, pMCR->NumberOfPackets * sizeof(PacketContext_t)); PushMCR(pDevice); #ifdef BLOCK /* Wait for all outstanding to complete */ while ((Status=WaitForCompletion(pDevice,(UBS_UINT32)100000,UBSEC_CIPHER_LIST)) == UBSEC_STATUS_SUCCESS); if (Status!=UBSEC_STATUS_TIMEOUT) /* We are nested, return success */ Status=UBSEC_STATUS_SUCCESS; Error_Return: #else Error_Return: /* Label to make sure that IRQs are enabled. */ #ifdef COMPLETE_ON_COMMAND_THREAD ubsec_PollDevice(pDevice); /* Try to complete some & cut down on ints */ #endif #endif OS_LeaveCriticalSection(pDevice,SaveConfig); #ifdef UBSEC_STATS if (Status != UBSEC_STATUS_SUCCESS) pDevice->Statistics.CryptoFailedCount++; #endif return(Status); }