void InitMD5State(ubsec_HMAC_State_pt HMAC_State,unsigned char *HashKey) { struct MD5Context ctx; unsigned char pad[64]; /* First prepare the inner block. */ bytnxor((unsigned char *)pad,(unsigned char *)HashKey,ipad, 64); RTL_MemZero(&ctx,sizeof(struct MD5Context)); /* The initial values in memory are 01 23 45 ... per RFC1321 */ ctx.buf[0] = 0x67452301; ctx.buf[1] = 0xefcdab89; ctx.buf[2] = 0x98badcfe; ctx.buf[3] = 0x10325476; MD5Update(&ctx,pad,64); /* ctx comes out as an array of long ints. The byte order of ctx is dependent on the CPU endianess. The byte order of the memory destination is dependent on the CryptoNet memory endianess. Based on our MD5 algorithm's CPU endianess assumptions, the net result is that we do a straight copy if the CPU and CryptoNet memory are of the same endianess. If the CPU and CryptoNet memory are of opposite endianess, we'll do 32-bit byteswapping during the copy, taken care of by the copywords() routine. */ #if (UBS_CPU_ATTRIBUTE != UBS_CRYPTONET_ATTRIBUTE) copywords((UBS_UINT32 *)&HMAC_State->InnerState[0],&ctx.buf[0], MD5_HASH_LENGTH/4); #else RTL_Memcpy(&HMAC_State->InnerState[0],&ctx.buf[0], MD5_HASH_LENGTH); #endif /* UBS_CPU_ATTRIBUTE */ /* Now prepare the Outer block. */ bytnxor((unsigned char *)pad,(unsigned char *)HashKey,opad, 64); RTL_MemZero(&ctx,sizeof(struct MD5Context)); /* The initial values in memory are 01 23 45 ... per RFC1321 */ ctx.buf[0] = 0x67452301; ctx.buf[1] = 0xefcdab89; ctx.buf[2] = 0x98badcfe; ctx.buf[3] = 0x10325476; MD5Update(&ctx,pad,64); /* ctx comes out as an array of long ints. The byte order of ctx is dependent on the CPU endianess. The byte order of the memory destination is dependent on the CryptoNet memory endianess. Based on our MD5 algorithm's CPU endianess assumptions, the net result is that we do a straight copy if the CPU and CryptoNet memory are of the same endianess. If the CPU and CryptoNet memory are of opposite endianess, we'll do 32-bit byteswapping during the copy, taken care of by the copywords() routine. */ #if (UBS_CPU_ATTRIBUTE != UBS_CRYPTONET_ATTRIBUTE) copywords((UBS_UINT32 *)&HMAC_State->OuterState[0],&ctx.buf[0], MD5_HASH_LENGTH/4); #else RTL_Memcpy(&HMAC_State->OuterState[0],&ctx.buf[0], MD5_HASH_LENGTH); #endif /* UBS_CPU_ATTRIBUTE */ }
void dotrap(void) { Var *trapreq; Word *starval; while(refdec(&ntrap) >= 0) { if(flag['S']) exits(truestatus()?"":getstatus()); starval=vlook("*")->val; trapreq=vlook("sysint"); if(trapreq->fn){ start(trapreq->fn, trapreq->pc, (Var*)0); runq->local=newvar(strdup("*"), runq->local); runq->local->val=copywords(starval, (Word*)0); runq->local->changed=1; runq->redir=runq->startredir=0; } else { /* * run the stack down until we uncover the * command reading loop. Xreturn will exit * if there is none (i.e. if this is not * an interactive rc.) */ while(!runq->iflag) Xreturn(); } } }
void Xdol(void) { word *a, *star; char *s, *t; int n; if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->words->word; deglob(s); n = 0; for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; a = runq->argv->next->words; if(n==0 || *t) a = copywords(vlook(s)->val, a); else{ star = vlook("*")->val; if(star && 1<=n && n<=count(star)){ while(--n) star = star->next; a = newword(star->word, a); } } poplist(); runq->argv->words = a; }
void dotrap(void) { int i; struct var *trapreq; struct word *starval; starval = vlook("*")->val; while(ntrap) for(i = 0;i!=NSIG;i++) while(trap[i]){ --trap[i]; --ntrap; if(getpid()!=mypid) Exit(getstatus()); trapreq = vlook(Signame[i]); if(trapreq->fn){ start(trapreq->fn, trapreq->pc, (struct var *)0); runq->local = newvar(strdup("*"), runq->local); runq->local->val = copywords(starval, (struct word *)0); runq->local->changed = 1; runq->redir = runq->startredir = 0; } else if(i==SIGINT || i==SIGQUIT){ /* * run the stack down until we uncover the * command reading loop. Xreturn will exit * if there is none (i.e. if this is not * an interactive rc.) */ while(!runq->iflag) Xreturn(); } else Exit(getstatus()); } }
void Xlocal(void) { if(count(runq->argv->words)!=1){ Xerror1("variable name must be singleton\n"); return; } deglob(runq->argv->words->word); runq->local = newvar(strdup(runq->argv->words->word), runq->local); runq->local->val = copywords(runq->argv->next->words, (word *)0); runq->local->changed = 1; poplist(); poplist(); }
void Xexit(void) { struct var *trapreq; struct word *starval; static int beenhere = 0; if(getpid()==mypid && !beenhere){ trapreq = vlook("sigexit"); if(trapreq->fn){ beenhere = 1; --runq->pc; starval = vlook("*")->val; start(trapreq->fn, trapreq->pc, (struct var *)0); runq->local = newvar(strdup("*"), runq->local); runq->local->val = copywords(starval, (struct word *)0); runq->local->changed = 1; runq->redir = runq->startredir = 0; return; } } Exit(getstatus()); }
/* * 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); }
/* * DH_SetupPublicParams: */ ubsec_Status_t DH_SetupPublicParams(VOLATILE MasterCommand_pt pMCR, ubsec_DH_Params_pt pDHParams) /* pDHParams points to a structure which contains all of the info needed for Diffie-Hellman operations. In addition to regular numerical parameters, "key" memory buffer locations are passed using memory "handles". Handles are defined as memory descriptors from which BOTH the virtual and physical addresses of the designated memory can be derived. The virtual and physical pointers associated with the handle must be extracted by using the following macros: OS_GetVirtualAddress() OS_GetPhysicalAddress() Results from OS_GetPhysicalAddress() may be written to CryptoNet control structures in (DMA) memory. Results from OS_GetVirtualAddress() may be used (if necessary) as regular old pointers. */ { #ifdef UBSEC_DH_SUPPORT VOLATILE DataBufChainList_t *FragPtr,*NextFragPtr; int DataLength; VOLATILE Packet_t *pPacket; DH_Send_CtxCmdBuf_pt pDHSendCtx; VOLATILE int PacketIndex; ubsec_Status_t Status=UBSEC_STATUS_SUCCESS; int NgLen; int NormalizeLen,NrmBits; int element; unsigned char *pNg; UBS_UINT32 *longkey; ubsec_MemAddress_t PhysAddr; PacketIndex = pMCR->NumberOfPackets; pDHSendCtx = (DH_Send_CtxCmdBuf_t *) &pMCR->KeyContextList[PacketIndex]->CtxCmdBuf.DH_Send_CtxCmdBuf; RTL_MemZero(pDHSendCtx,sizeof(*pDHSendCtx)); pPacket = &(pMCR->PacketArray[PacketIndex]); /* Set up the current packet. */ pDHSendCtx->rng_enable= CPU_TO_CTRL_SHORT(pDHParams->RNGEnable); /* The modulus needs to be aligned on a 512/768 or 1024 bit boundary. (2048 for 5820) */ /* * Save amount to normalize/renormalize. */ if (pDHParams->N.KeyLength <=512) NormalizeLen=512; else if (pDHParams->N.KeyLength <=768) NormalizeLen=768; else if (pDHParams->N.KeyLength <=1024) NormalizeLen=1024; else #ifdef UBSEC_582x_CLASS_DEVICE if (pDHParams->N.KeyLength <=1536) NormalizeLen=1536; else if (pDHParams->N.KeyLength <= 2048) NormalizeLen=2048; else #endif return(UBSEC_STATUS_INVALID_PARAMETER); #ifndef UBSEC_HW_NORMALIZE if ((NrmBits = ubsec_NormalizeDataTo(&pDHParams->N,NormalizeLen))) { ubsec_ShiftData(&pDHParams->G, NrmBits); } pMCR->KeyContextList[PacketIndex]->NormBits=NrmBits; #else NrmBits=0; #endif pMCR->KeyContextList[PacketIndex]->ResultKey[0]=&(pDHParams->Y); /* Save here for post-command finishing */ pMCR->KeyContextList[PacketIndex]->ResultKey[1]=NULL; /* Not used */ /* * Output Y value may need to be rounded up to represent an integral * number of 32 bit words, same total length as modulus N. */ #ifndef UBSEC_HW_NORMALIZE pDHParams->Y.KeyLength = NormalizeLen; #else #if 0 pDHParams->Y.KeyLength = ROUNDUP_TO_32_BIT(pDHParams->Y.KeyLength); #else pDHParams->Y.KeyLength = NormalizeLen; #endif #endif /* Now setup some of the parameters that need to be aligned. */ /* RJT_TEST why is this rounded up? */ pDHParams->X.KeyLength = ROUNDUP_TO_32_BIT(pDHParams->X.KeyLength); pMCR->KeyContextList[PacketIndex]->ResultRNG=&(pDHParams->X); /* Save here for post-command finishing */ /* N Copy the modulo value */ pDHSendCtx->modulus_length = (unsigned short)CPU_TO_CTRL_SHORT(pDHParams->N.KeyLength); pNg=(unsigned char *)&pDHSendCtx->Ng[0]; /* For convenience */ NgLen=NormalizeLen/8; #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords((UBS_UINT32 *)&pNg[0],(UBS_UINT32 *)OS_GetVirtualAddress(pDHParams->N.KeyValue),NgLen/4); #else RTL_Memcpy(&pNg[0],OS_GetVirtualAddress(pDHParams->N.KeyValue),NgLen); #endif /* UBS_ENABLE_KEY_SWAP */ #else /* HW does the normalization */ #if defined(UBS_ENABLE_KEY_SWAP) copywords((UBS_UINT32 *)&pNg[0], (UBS_UINT32 *)OS_GetVirtualAddress(pDHParams->N.KeyValue), ROUNDUP_TO_32_BIT(pDHParams->N.KeyLength)/32); #else RTL_Memcpy(&pNg[0],OS_GetVirtualAddress(pDHParams->N.KeyValue),ROUNDUP_TO_32_BIT(pDHParams->N.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif /* * G Copy the input value. This is the public key for private * operation or the Baseg value for public key generation. * It also needs to be aligned on the same length * as N */ pNg+=NgLen; /* Starting G location. */ pDHSendCtx->generator_length=(unsigned short)CPU_TO_CTRL_SHORT(pDHParams->G.KeyLength); #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords((UBS_UINT32 *)&pNg[0],(UBS_UINT32 *)OS_GetVirtualAddress(pDHParams->G.KeyValue),NgLen/4); #else RTL_Memcpy(&pNg[0],OS_GetVirtualAddress(pDHParams->G.KeyValue),NgLen); #endif /* UBS_ENABLE_KEY_SWAP */ #else /* HW does the normalization */ #if defined(UBS_ENABLE_KEY_SWAP) copywords((UBS_UINT32 *)&pNg[0], (UBS_UINT32 *)OS_GetVirtualAddress(pDHParams->G.KeyValue), ROUNDUP_TO_32_BIT(pDHParams->G.KeyLength)/32); #else RTL_Memcpy(&pNg[0],OS_GetVirtualAddress(pDHParams->G.KeyValue),ROUNDUP_TO_32_BIT(pDHParams->G.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif /* "extra" length is always 2 x Ng length */ pMCR->KeyContextList[PacketIndex]->cmd_structure_length+=(NgLen*2); /* * Input Buffer setup for DH Send (Public): * If the private key x is provided by software, save * it in the first input data buffer, otherwise, the * input data buffer will not be used by the chip */ FragPtr=(DataBufChainList_pt)&pPacket->InputHead; if (! pDHParams->RNGEnable ) { /* Random number manually provided */ /* RJT_TEST why is this rounded up? */ pDHParams->UserX.KeyLength = ROUNDUP_TO_32_BIT(pDHParams->UserX.KeyLength); PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDHParams->UserX.KeyValue)); #if defined(UBS_ENABLE_KEY_SWAP) longkey = (UBS_UINT32 *)OS_GetVirtualAddress(pDHParams->UserX.KeyValue); for (element = 0 ; element < ROUNDUP_TO_32_BIT(pDHParams->UserX.KeyLength)/32 ; element++) longkey[element] = BYTESWAPLONG(longkey[element]); #endif /* UBS_ENABLE_KEY_SWAP */ FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDHParams->UserX.KeyLength+7)/8; /* map the length from bits to bytes */ FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); pDHSendCtx->private_key_length = (unsigned short)CPU_TO_CTRL_SHORT(pDHParams->UserX.KeyLength); Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DH_SetupPublicParams Sync UserX Fragment to Device (0x%08X,%d,%d)\n", pDHParams->UserX.KeyValue, 0, DataLength)); OS_SyncToDevice(pDHParams->UserX.KeyValue, 0, DataLength); Dbg_Print(DBG_DHKEY,( "Public (Send) NormBits %d Input Key, UserX: <%d,%08x (%08x)>\n",NrmBits,DataLength, CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr)); } else { /* CryptoNet chip to internally generate random number X */ pDHSendCtx->private_key_length=CPU_TO_CTRL_SHORT(pDHParams->RandomKeyLen); FragPtr->DataLength = 0; FragPtr->DataAddress = 0; DataLength=0; } /* Manual/CryptoNet random number generation if-else */ /* The CryptoNet chip ignores the pPacket->PacketLength field for this */ /* operation. We'll zero that field out for consistency's sake. */ pPacket->PacketLength = 0; FragPtr->pNext = 0; /* Terminate the (empty or single) input fragment list */ #ifdef UBSDBG /* Print out the context information if required */ { int WordLen,i; WordLen=(pMCR->KeyContextList[PacketIndex]->cmd_structure_length-DH_STATIC_SEND_CONTEXT_SIZE)/4; Dbg_Print(DBG_DHKEY,( "ubsec: ---- DH_Public - RNG-Enable [%d] Private Klen [%d] Generator Len [%d]\n", CTRL_TO_CPU_SHORT(pDHSendCtx->rng_enable), CTRL_TO_CPU_SHORT(pDHSendCtx->private_key_length), CTRL_TO_CPU_SHORT(pDHSendCtx->generator_length))); Dbg_Print(DBG_DHKEY,( "ubsec: ---- Modulus Length [%d] ", CTRL_TO_CPU_SHORT(pDHSendCtx->modulus_length))); Dbg_Print(DBG_DHKEY,( "Context Len %d Context Value=[", (pMCR->KeyContextList[PacketIndex]->cmd_structure_length))); for ( i=0 ; i < WordLen ; i++) { Dbg_Print(DBG_DHKEY,( "%08x ",SYS_TO_BE_LONG(pDHSendCtx->Ng[i]))); } Dbg_Print(DBG_DHKEY,( "]\n")); } #endif /* Output Buffer setup for DH Send (Public): * The output buffer has Public Key Y, followed by * Private Key X */ FragPtr=(DataBufChainList_pt)&pPacket->OutputHead; /* The first output data buffer has Public Key Y */ PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDHParams->Y.KeyValue)); FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDHParams->Y.KeyLength+7)/8; /* map the length from bits to bytes */ FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); #ifdef UBSDBG /* Sanity check debug info for conditions that will hang the chip. */ if ( (CTRL_TO_CPU_LONG( FragPtr->DataAddress )) & 0x03) { Dbg_Print(DBG_FATAL,("ubsec:#########INVALID OUTPUT ADDRESS %08x\n", CTRL_TO_CPU_LONG(FragPtr->DataAddress))); Status=UBSEC_STATUS_INVALID_PARAMETER; goto Error_Return; } if ((DataLength) & 0x03) { Dbg_Print(DBG_FATAL,("ubsec:#########INVALID OUTPUT LENGTH %08x\n", DataLength)); Status=UBSEC_STATUS_INVALID_PARAMETER; goto Error_Return; } #endif /* get the next fragment pointer */ NextFragPtr=&pMCR->OutputFragmentList[PacketIndex*(UBSEC_MAX_FRAGMENTS)]; FragPtr->pNext =NextFragPtr->PhysicalAddress; Dbg_Print(DBG_DHKEY,( "Public (Send) NormBits %d Output Key Y: <%d,%08x, (%08x,Next-%08x)>\n", NrmBits,DataLength,CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr,FragPtr->pNext)); FragPtr=NextFragPtr; /* The second output data buffer has Private Key X */ PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDHParams->X.KeyValue)); FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDHParams->X.KeyLength+7)/8; /* map the length from bits to bytes */ FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); Dbg_Print(DBG_DHKEY,( "Public (Send) Output Key X: <%d, %08x, (%08x,Next-%08x)>\n", DataLength, CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr,FragPtr->pNext)); #ifdef UBSDBG /* Sanity check debug info for conditions that will hang the chip. */ if ( (CTRL_TO_CPU_LONG( FragPtr->DataAddress )) & 0x03) { Dbg_Print(DBG_FATAL,("ubsec:#########INVALID OUTPUT_B ADDRESS %08x\n", CTRL_TO_CPU_LONG(FragPtr->DataAddress))); Status=UBSEC_STATUS_INVALID_PARAMETER; goto Error_Return; } if ((DataLength) & 0x03) { Dbg_Print(DBG_FATAL,("ubsec:#########INVALID OUTPUT_B LENGTH %08x\n", DataLength)); Status=UBSEC_STATUS_INVALID_PARAMETER; goto Error_Return; } #endif FragPtr->pNext = 0; #ifndef STATIC_F_LIST /* Fragment lists are external to MCR structures, must sync separately */ /* Always 2 output frags, need to sync one entry in OutputFragmentList */ Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DH_SetupPublicParams Sync OFrag Descriptor to Device (0x%08X,%d,%d)\n", pMCR->OutputFragmentListHandle, PacketIndex*(UBSEC_MAX_FRAGMENTS)*sizeof(DataBufChainList_t), sizeof(DataBufChainList_t))); OS_SyncToDevice(pMCR->OutputFragmentListHandle, PacketIndex*(UBSEC_MAX_FRAGMENTS)*sizeof(DataBufChainList_t), sizeof(DataBufChainList_t)); #endif /* STATIC_F_LIST not defined */ #ifdef UBSDBG Error_Return: #endif return(Status); #else return(UBSEC_STATUS_NO_DEVICE); #endif }
/* * DH_SetupSharedParams: */ ubsec_Status_t DH_SetupSharedParams(VOLATILE MasterCommand_pt pMCR, ubsec_DH_Params_pt pDHParams) { #ifdef UBSEC_DH_SUPPORT VOLATILE DataBufChainList_t *FragPtr, *NextFragPtr; int DataLength; ubsec_Status_t Status=UBSEC_STATUS_SUCCESS; VOLATILE Packet_t *pPacket; DH_REC_CtxCmdBuf_pt pDHRecCtx; VOLATILE int PacketIndex; int NgLen; int element; int NormalizeLen,NrmBits=0; UBS_UINT32 *longkey; ubsec_MemAddress_t PhysAddr; PacketIndex = pMCR->NumberOfPackets; pDHRecCtx = (DH_REC_CtxCmdBuf_t *) &pMCR->KeyContextList[PacketIndex]->CtxCmdBuf.DH_REC_CtxCmdBuf; RTL_MemZero(pDHRecCtx,sizeof(*pDHRecCtx)); pPacket = &(pMCR->PacketArray[PacketIndex]); /* Set up the current packet. */ if (pDHParams->N.KeyLength <=512) NormalizeLen=512; else if (pDHParams->N.KeyLength <=768) NormalizeLen=768; else if (pDHParams->N.KeyLength <=1024) NormalizeLen=1024; else #ifdef UBSEC_582x_CLASS_DEVICE if (pDHParams->N.KeyLength <=1536) NormalizeLen=1536; else NormalizeLen=2048; #else return(UBSEC_STATUS_INVALID_PARAMETER); #endif /* * Output K value may need to be rounded up to represent an integral * number of 32 bit words, same total length as modulus N. */ #ifndef UBSEC_HW_NORMALIZE pDHParams->K.KeyLength = NormalizeLen; if ((NrmBits = ubsec_NormalizeDataTo(&pDHParams->N,NormalizeLen))) { ubsec_ShiftData(&pDHParams->Y, NrmBits); } pMCR->KeyContextList[PacketIndex]->NormBits=NrmBits; #else #if 1 pDHParams->K.KeyLength = NormalizeLen; #else pDHParams->K.KeyLength = ROUNDUP_TO_32_BIT(pDHParams->K.KeyLength); #endif NrmBits=0; #endif pMCR->KeyContextList[PacketIndex]->ResultKey[0]=&pDHParams->K; /* Save here for post-command finishing */ pMCR->KeyContextList[PacketIndex]->ResultKey[1]=NULL; /* Not used */ pMCR->KeyContextList[PacketIndex]->ResultRNG=NULL; /* Not used */ pDHParams->Y.KeyLength = NormalizeLen; /* Now setup some of the parameters that need to be aligned. */ /* RJT_TEST why is this rounded up? */ pDHParams->X.KeyLength = ROUNDUP_TO_32_BIT(pDHParams->X.KeyLength); NgLen=NormalizeLen/8; /* N Copy the modulo value modulo */ pDHRecCtx->modulus_length = (unsigned short)CPU_TO_CTRL_SHORT(pDHParams->N.KeyLength); #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDHRecCtx->N[0], (UBS_UINT32 *)OS_GetVirtualAddress(pDHParams->N.KeyValue), NgLen/4); #else RTL_Memcpy( &pDHRecCtx->N[0],OS_GetVirtualAddress(pDHParams->N.KeyValue),NgLen); #endif /* UBS_ENABLE_KEY_SWAP */ #else /* HW does the normalization */ #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDHRecCtx->N[0], (UBS_UINT32 *)OS_GetVirtualAddress(pDHParams->N.KeyValue), ROUNDUP_TO_32_BIT(pDHParams->N.KeyLength)/32); #else RTL_Memcpy( &pDHRecCtx->N[0],OS_GetVirtualAddress(pDHParams->N.KeyValue),ROUNDUP_TO_32_BIT(pDHParams->N.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif pMCR->KeyContextList[PacketIndex]->cmd_structure_length+=NgLen; /* Set the private key value */ pDHRecCtx->modulus_length = (unsigned short)CPU_TO_CTRL_SHORT(pDHParams->N.KeyLength); pDHRecCtx->private_key_length=(unsigned short)CPU_TO_CTRL_SHORT(pDHParams->X.KeyLength); #ifdef UBSDBG /* Print out the context information if required */ { int WordLen,i; WordLen=(NgLen/4); Dbg_Print(DBG_DHKEY,( "ubsec: ---- DH Shared Mod Length [%d] Pkey Len [%d] Context Len %d, Value -\n[", CTRL_TO_CPU_SHORT(pDHRecCtx->modulus_length), CTRL_TO_CPU_SHORT(pDHRecCtx->private_key_length), pMCR->KeyContextList[PacketIndex]->cmd_structure_length)); for ( i=0 ; i < WordLen ; i++) { Dbg_Print(DBG_DHKEY,( "%08x ",SYS_TO_BE_LONG(pDHRecCtx->N[i]))); } Dbg_Print(DBG_DHKEY,( "]\n")); } #endif /* Input Buffer setup for DH Receive (Shared): */ FragPtr=(DataBufChainList_pt)&pPacket->InputHead; /* The first fragment has Y */ PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDHParams->Y.KeyValue)); #if defined(UBS_ENABLE_KEY_SWAP) longkey = (UBS_UINT32 *)OS_GetVirtualAddress(pDHParams->Y.KeyValue); for (element = 0 ; element < ROUNDUP_TO_32_BIT(pDHParams->Y.KeyLength)/32 ; element++) longkey[element] = BYTESWAPLONG(longkey[element]); #endif /* UBS_ENABLE_KEY_SWAP */ FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDHParams->Y.KeyLength+7)/8; /* map the length from bits to bytes */ FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); /* The CryptoNet chip ignores the pPacket->PacketLength field for this */ /* operation. We'll zero that field out for consistency's sake. */ pPacket->PacketLength = 0; /* get the next fragment pointer */ NextFragPtr=&pMCR->InputFragmentList[PacketIndex*(UBSEC_MAX_FRAGMENTS)]; FragPtr->pNext =NextFragPtr->PhysicalAddress; Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DH_SetupSharedParams Sync Y Fragment to Device (0x%08X,%d,%d)\n", pDHParams->Y.KeyValue, 0, DataLength)); OS_SyncToDevice(pDHParams->Y.KeyValue, 0, DataLength); Dbg_Print(DBG_DHKEY,( "DH Shared Y: FragI <%d,%08x %08x,Next-%08x>\n", DataLength, CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr,FragPtr->pNext)); FragPtr=NextFragPtr; /* The second Input data buffer has Private Key x */ PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDHParams->X.KeyValue)); #if defined(UBS_ENABLE_KEY_SWAP) longkey = (UBS_UINT32 *)OS_GetVirtualAddress(pDHParams->X.KeyValue); for (element = 0 ; element < ROUNDUP_TO_32_BIT(pDHParams->X.KeyLength)/32 ; element++) longkey[element] = BYTESWAPLONG(longkey[element]); #endif /* UBS_ENABLE_KEY_SWAP */ FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDHParams->X.KeyLength+7)/8; /* map the length from bits to bytes */ FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DH_SetupSharedParams Sync X Fragment to Device (0x%08X,%d,%d)\n", pDHParams->X.KeyValue, 0, DataLength)); OS_SyncToDevice(pDHParams->X.KeyValue, 0, DataLength); Dbg_Print(DBG_DHKEY,( "Shared Private Key X: <%d, %08x, (%08x,Next-%08x)>\n", DataLength, CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr,FragPtr->pNext)); FragPtr->pNext = 0; /* Output Buffer setup for DH Received (Shared): * The output buffer contains shared secret K */ FragPtr=(DataBufChainList_pt)&pPacket->OutputHead; PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDHParams->K.KeyValue)); FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDHParams->K.KeyLength+7)/8; /* map the length from bits to bytes */ FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); #ifdef UBSDBG /* Sanity check debug info for conditions that will hang the chip. */ if ( (CTRL_TO_CPU_LONG( FragPtr->DataAddress )) & 0x03) { Dbg_Print(DBG_FATAL,("ubsec:#########INVALID OUTPUT ADDRESS %08x\n", CTRL_TO_CPU_LONG(FragPtr->DataAddress))); Status=UBSEC_STATUS_INVALID_PARAMETER; goto Error_Return; } if ((DataLength) & 0x03) { Dbg_Print(DBG_FATAL,("ubsec:#########INVALID OUTPUT LENGTH %08x\n", DataLength)); Status=UBSEC_STATUS_INVALID_PARAMETER; goto Error_Return; } #endif Dbg_Print(DBG_DHKEY,( "Receive Buffer K:FragO <%d, %08x>\n", DataLength, CTRL_TO_CPU_LONG( FragPtr->DataAddress ))); FragPtr->pNext = 0; #ifdef UBSDBG Error_Return: #endif return(Status); #else return(UBSEC_STATUS_NO_DEVICE); #endif }
ubsec_Status_t DSA_SetupSignParams(MasterCommand_pt pMCR, ubsec_DSA_Params_pt pDSAParams) /* pDSAParams points to a structure which contains all of the info needed for the DSA operations. In addition to regular numerical parameters, "key" memory buffer locations are passed using memory "handles". Handles are defined as memory descriptors from which BOTH the virtual and physical addresses of the designated memory can be derived. The virtual and physical pointers associated with the handle must be extracted by using the following macros: OS_GetVirtualAddress() OS_GetPhysicalAddress() Results from OS_GetPhysicalAddress() may be written to CryptoNet control structures in (DMA) memory. Results from OS_GetVirtualAddress() may be used (if necessary) as regular old pointers. */ { #ifdef UBSEC_DSA_SUPPORT volatile DataBufChainList_t *FragPtr = NULL, *NextFragPtr; int DataLength; volatile Packet_t *pPacket; VOLATILE DSA_Sign_CtxCmdBuf_t *pDSACtx; int PacketIndex; int fragnum; int Offset; int element; int NormBits,NormalizeLen; UBS_UINT32 *longkey; ubsec_MemAddress_t PhysAddr; PacketIndex = pMCR->NumberOfPackets; pDSACtx = &pMCR->KeyContextList[PacketIndex]->CtxCmdBuf.DSA_Sign_CtxCmdBuf; /* Zero out the parameters */ RTL_MemZero(pDSACtx,sizeof(*pDSACtx)); pPacket = &(pMCR->PacketArray[PacketIndex]); /* Set up the current packet */ pDSACtx->sha1_enable= pDSAParams->HashEnable ? CPU_TO_CTRL_SHORT(1) : 0; pDSACtx->p_length = (unsigned short)CPU_TO_CTRL_SHORT(pDSAParams->ModP.KeyLength); if (pDSAParams->ModP.KeyLength <=512) NormalizeLen=512; else if (pDSAParams->ModP.KeyLength <= 768) NormalizeLen=768; else if (pDSAParams->ModP.KeyLength <= 1024) NormalizeLen=1024; else #ifdef UBSEC_582x_CLASS_DEVICE if (pDSAParams->ModP.KeyLength <=1536) NormalizeLen=1536; else if (pDSAParams->ModP.KeyLength<=2048) NormalizeLen=2048; else #endif return(UBSEC_STATUS_INVALID_PARAMETER); /* * Q Needs to be normalized on 160 bits. * P & G need to be shifted the same amount */ #ifndef UBSEC_HW_NORMALIZE NormBits = ubsec_NormalizeDataTo(&pDSAParams->ModQ,160); NormBits=ubsec_NormalizeDataTo(&pDSAParams->ModP, NormalizeLen); ubsec_ShiftData(&pDSAParams->BaseG, NormBits); #else NormBits=0; #endif NormalizeLen/=8; Offset=0; /* q setup, Always 160 Bits. */ #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[0], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->ModQ.KeyValue), 20/4); #else RTL_Memcpy( &pDSACtx->CtxParams[0],OS_GetVirtualAddress(pDSAParams->ModQ.KeyValue),20); #endif /* UBS_ENABLE_KEY_SWAP */ #else #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[0], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->ModQ.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->ModQ.KeyLength)/32); #else RTL_Memcpy( &pDSACtx->CtxParams[0],OS_GetVirtualAddress(pDSAParams->ModQ.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->ModQ.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif Offset+=20; /* p setup */ #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->ModP.KeyValue), NormalizeLen/4); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->ModP.KeyValue) ,NormalizeLen); #endif /* UBS_ENABLE_KEY_SWAP */ #else #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->ModP.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->ModP.KeyLength)/32); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->ModP.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->ModP.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif Offset+=NormalizeLen; /* g setup */ #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->BaseG.KeyValue), NormalizeLen/4); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->BaseG.KeyValue),NormalizeLen); #endif /* UBS_ENABLE_KEY_SWAP */ #else #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->BaseG.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->BaseG.KeyLength)/32); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->BaseG.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->BaseG.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif Offset+=NormalizeLen; /* x setup */ #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->Key.KeyValue), 20/4); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->Key.KeyValue),20); #endif /* UBS_ENABLE_KEY_SWAP */ #else #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->Key.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->Key.KeyLength)/32); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->Key.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->Key.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif Offset+=20; /* Set total length */ pMCR->KeyContextList[PacketIndex]->cmd_structure_length+=Offset; #ifdef UBSDBG /* Print out the context information if required */ { int WordLen,i; WordLen=(pMCR->KeyContextList[PacketIndex]->cmd_structure_length-DSA_STATIC_SIGN_CONTEXT_SIZE)/4; Dbg_Print(DBG_DSAKEY,( "ubsec: ---- DSA Mod P Length [%d] \n", CTRL_TO_CPU_SHORT(pDSACtx->p_length))); Dbg_Print(DBG_DSAKEY,( "ubsec: ---- DSA SHA Enabled [%d]\n", CTRL_TO_CPU_SHORT(pDSACtx->sha1_enable))); Dbg_Print(DBG_DSAKEY,( "ubsec: ---- Context Len %d Value -\n[", pMCR->KeyContextList[PacketIndex]->cmd_structure_length )); for ( i=0 ; i < WordLen ; i++) { Dbg_Print(DBG_DSAKEY,( "%08x ",SYS_TO_BE_LONG(pDSACtx->CtxParams[i]))); } Dbg_Print(DBG_DSAKEY,( "]\n")); } #endif /* Input Buffer setup for DSA Sign. */ pPacket->PacketLength = 0; /* The DSA message is a bytestream. Treat it just like a crypto buffer. */ NextFragPtr=(DataBufChainList_pt)&pPacket->InputHead; for (fragnum=0;fragnum<(int)pDSAParams->NumInputFragments;fragnum++) { FragPtr = NextFragPtr; PhysAddr=pDSAParams->InputFragments[fragnum].FragmentAddress; DataLength=pDSAParams->InputFragments[fragnum].FragmentLength; FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); /* Add (endian-adjusted) fragment length into current packet structure */ pPacket->PacketLength += (unsigned short)DataLength; if (fragnum==0) { /* Next frag descriptor is packet's InputFragmentList */ NextFragPtr=&pMCR->InputFragmentList[PacketIndex*(UBSEC_MAX_FRAGMENTS)]; } else { /* Next frag descriptor is next InputFragmentList entry */ NextFragPtr=&FragPtr[1]; } FragPtr->pNext = NextFragPtr->PhysicalAddress; Dbg_Print(DBG_DSAKEY,( "DSA Sign InputKeyInfo: IFrag[%d] <%d,%08x %08x>\n", fragnum, DataLength, CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr)); } /* for each input fragment of the unhashed message bytestream */ /* ->PacketLength is only for the message 'm'; it does not count the */ /* size of the fragment used for the random number (if present) */ /* Therefore, we're finished updating ->PacketLength. */ #if (UBS_CPU_ATTRIBUTE != UBS_CRYPTONET_ATTRIBUTE) /* fix up the packet length endianess in DMA control memory */ pPacket->PacketLength = CPU_TO_CTRL_SHORT( pPacket->PacketLength ); #endif if (!pDSAParams->RNGEnable) { /* CryptoNet RNG generation not requested */ /* The random number is provided by the user (not CryptoNet). It */ /* will use the next available frag descriptor in InputFragmentList */ pDSACtx->rng_enable=0; /* If here we need to use an additional input frag descriptor */ /* FragPtr is pointing at the last filled fragment descriptor */ /* NextFragPtr is pointing at next available fragment descriptor */ /* FragPtr->pNext is pointing at NextFragPtr's physical address */ /* However, first check for an excessively long fragment list */ if (pDSAParams->NumInputFragments > UBSEC_MAX_FRAGMENTS) return(UBSEC_STATUS_INVALID_PARAMETER); FragPtr=NextFragPtr; PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDSAParams->Random.KeyValue)); #if defined(UBS_ENABLE_KEY_SWAP) longkey = (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->Random.KeyValue); for (element = 0 ; element < ROUNDUP_TO_32_BIT(pDSAParams->Random.KeyLength)/32 ; element++) longkey[element] = BYTESWAPLONG(longkey[element]); #endif /* UBS_ENABLE_KEY_SWAP */ FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDSAParams->Random.KeyLength+7)/8; /* map the length from bits to bytes */ FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); fragnum++; /* Increment for upcoming OS_SyncToDevice() call */ Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DSA_SetupSignParams Sync Random Fragment to Device (0x%08X,%d,%d)\n", pDSAParams->Random.KeyValue, 0, DataLength)); OS_SyncToDevice(pDSAParams->Random.KeyValue, 0, DataLength); Dbg_Print(DBG_DSAKEY,( " DSA Random Num Fragment: <%d,%08x (%08x)>\n", DataLength, CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr)); } else { /* The random number will be generated by the CryptoNet chip. */ /* No additional input fragment descriptor required. */ pDSACtx->rng_enable=CPU_TO_CTRL_SHORT(1); pDSAParams->Random.KeyLength = ROUNDUP_TO_32_BIT(pDSAParams->Random.KeyLength); } FragPtr->pNext = 0; /* Terminate the input fragment descriptor list */ Dbg_Print(DBG_DSAKEY,( "ubsec: ---- RNG_Enabled [%d]\n",pDSACtx->rng_enable)); #ifndef STATIC_F_LIST /* Fragment lists are external to MCR structures, must sync separately */ if (fragnum > 1) { /* We're using at least one InputFragmentList entry */ Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DSA_SetupSignParams Sync %d IFrag Descriptor(s) to Device (0x%08X,%d,%d)\n", fragnum-1, pMCR->InputFragmentListHandle, PacketIndex*(UBSEC_MAX_FRAGMENTS)*sizeof(DataBufChainList_t), (fragnum-1)*sizeof(DataBufChainList_t))); OS_SyncToDevice(pMCR->InputFragmentListHandle, PacketIndex*(UBSEC_MAX_FRAGMENTS)*sizeof(DataBufChainList_t), (fragnum-1)*sizeof(DataBufChainList_t)); } #endif /* STATIC_F_LIST not defined */ /* Now setup the output fragment descriptor list. Always 2 fragments */ FragPtr=(DataBufChainList_pt)&pPacket->OutputHead; PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDSAParams->SigR.KeyValue)); FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDSAParams->SigR.KeyLength+7)/8; FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); /* get the next fragment pointer */ NextFragPtr=&pMCR->OutputFragmentList[PacketIndex*(UBSEC_MAX_FRAGMENTS)]; FragPtr->pNext =NextFragPtr->PhysicalAddress; Dbg_Print(DBG_DSAKEY,( "DSA Sign Sig_R: <%d,%08x, (%08x,Next-%08x)>\n", DataLength,CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr,FragPtr->pNext)); FragPtr=NextFragPtr; PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDSAParams->SigS.KeyValue)); FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDSAParams->SigS.KeyLength+7)/8; FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); FragPtr->pNext = 0; Dbg_Print(DBG_DSAKEY,( "DSA Sign Sig_S: <%d,%08x, (%08x,Next-%08x)>\n", DataLength,CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr,FragPtr->pNext)); #ifndef STATIC_F_LIST /* Fragment lists are external to MCR structures, must sync separately */ /* Always 2 output frags, need to sync one entry in OutputFragmentList */ Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DSA_SetupSignParams Sync OFrag Descriptor to Device (0x%08X,%d,%d)\n", pMCR->OutputFragmentListHandle, PacketIndex*(UBSEC_MAX_FRAGMENTS)*sizeof(DataBufChainList_t), sizeof(DataBufChainList_t))); OS_SyncToDevice(pMCR->OutputFragmentListHandle, PacketIndex*(UBSEC_MAX_FRAGMENTS)*sizeof(DataBufChainList_t), sizeof(DataBufChainList_t)); #endif /* STATIC_F_LIST not defined */ #ifndef UBSEC_HW_NORMALIZE pMCR->KeyContextList[PacketIndex]->NormBits=0; #endif pMCR->KeyContextList[PacketIndex]->ResultKey[0] = &pDSAParams->SigR; /* Save for post-processing callback */ pMCR->KeyContextList[PacketIndex]->ResultKey[1] = &pDSAParams->SigS; /* Save for post-processing callback */ pMCR->KeyContextList[PacketIndex]->ResultRNG = NULL; /* Not used */ return(UBSEC_STATUS_SUCCESS); #else /* UBSEC_DSA_SUPPORT not defined */ return(UBSEC_STATUS_NO_DEVICE); #endif } /* end DSA_SetupSignParams() */
ubsec_Status_t DSA_SetupVerifyParams(MasterCommand_pt pMCR, ubsec_DSA_Params_pt pDSAParams) { #ifdef UBSEC_DSA_SUPPORT volatile DataBufChainList_t *FragPtr, *NextFragPtr; int DataLength; volatile Packet_t *pPacket; VOLATILE DSA_Verify_CtxCmdBuf_t *pDSACtx; int PacketIndex; int fragnum; int Offset; int element; int NormBits,NormalizeLen; UBS_UINT32 *longkey; ubsec_MemAddress_t PhysAddr; /* First do a sanity check for an excessively long input fragment list */ if (pDSAParams->NumInputFragments > (UBSEC_MAX_FRAGMENTS - 1)) return(UBSEC_STATUS_INVALID_PARAMETER); PacketIndex = pMCR->NumberOfPackets; pDSACtx = &pMCR->KeyContextList[PacketIndex]->CtxCmdBuf.DSA_Verify_CtxCmdBuf; RTL_MemZero(pDSACtx,sizeof(*pDSACtx)); pDSACtx->sha1_enable= pDSAParams->HashEnable ? CPU_TO_CTRL_SHORT(1) : 0; pPacket = &(pMCR->PacketArray[PacketIndex]); /* Set up the current packet */ pDSACtx->p_length = (unsigned short)CPU_TO_CTRL_SHORT(pDSAParams->ModP.KeyLength) ; if (pDSAParams->ModP.KeyLength <=512) NormalizeLen=512; else if (pDSAParams->ModP.KeyLength <= 768) NormalizeLen=768; else if (pDSAParams->ModP.KeyLength <= 1024) NormalizeLen=1024; else #ifdef UBSEC_582x_CLASS_DEVICE if (pDSAParams->ModP.KeyLength <=1536) NormalizeLen=1536; else NormalizeLen=2048; #else return(UBSEC_STATUS_INVALID_PARAMETER); #endif #ifndef UBSEC_HW_NORMALIZE /* * Q Needs to be normalized on 160 bits. * P & G need to be shifted the same amount */ NormBits = ubsec_NormalizeDataTo(&pDSAParams->ModQ,160); NormBits=ubsec_NormalizeDataTo(&pDSAParams->ModP, NormalizeLen); ubsec_ShiftData(&pDSAParams->BaseG, NormBits); if (NormBits) ubsec_ShiftData(&pDSAParams->Key, NormBits); #else NormBits=0; #endif NormalizeLen/=8; Offset=0; /* Pad out those parameters that need it. */ pDSAParams->SigS.KeyLength = ROUNDUP_TO_32_BIT(pDSAParams->SigS.KeyLength); pDSAParams->SigR.KeyLength = ROUNDUP_TO_32_BIT(pDSAParams->SigR.KeyLength); /* q setup, Always 160 Bits. */ #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[0], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->ModQ.KeyValue), 20/4); #else RTL_Memcpy( &pDSACtx->CtxParams[0],OS_GetVirtualAddress(pDSAParams->ModQ.KeyValue),20); #endif /* UBS_ENABLE_KEY_SWAP */ #else #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[0], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->ModQ.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->ModQ.KeyLength)/32); #else RTL_Memcpy( &pDSACtx->CtxParams[0],OS_GetVirtualAddress(pDSAParams->ModQ.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->ModQ.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif Offset+=20; /* p setup */ #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->ModP.KeyValue), NormalizeLen/4); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->ModP.KeyValue), NormalizeLen); #endif /* UBS_ENABLE_KEY_SWAP */ #else #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->ModP.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->ModP.KeyLength)/32); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->ModP.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->ModP.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif Offset+=NormalizeLen; /* g setup */ #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->BaseG.KeyValue), NormalizeLen/4); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->BaseG.KeyValue), NormalizeLen); #endif /* UBS_ENABLE_KEY_SWAP */ #else #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->BaseG.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->BaseG.KeyLength)/32); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->BaseG.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->BaseG.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif Offset+=NormalizeLen; /* Y setup */ #ifndef UBSEC_HW_NORMALIZE #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->Key.KeyValue), NormalizeLen/4); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->Key.KeyValue), NormalizeLen); #endif /* UBS_ENABLE_KEY_SWAP */ #else #if defined(UBS_ENABLE_KEY_SWAP) copywords( (UBS_UINT32 *)&pDSACtx->CtxParams[Offset/4], (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->Key.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->Key.KeyLength)/32); #else RTL_Memcpy( &pDSACtx->CtxParams[Offset/4],OS_GetVirtualAddress(pDSAParams->Key.KeyValue), ROUNDUP_TO_32_BIT(pDSAParams->Key.KeyLength)/8); #endif /* UBS_ENABLE_KEY_SWAP */ #endif Offset+=NormalizeLen; /* Set total length */ pMCR->KeyContextList[PacketIndex]->cmd_structure_length+=Offset; #ifdef UBSDBG /* Print out the context information if required */ { int WordLen,i; WordLen=(pMCR->KeyContextList[PacketIndex]->cmd_structure_length-DSA_STATIC_SIGN_CONTEXT_SIZE)/4; Dbg_Print(DBG_DSAKEY,( "ubsec: ---- DSA Verify Mod P Length [%d] \n",pDSACtx->p_length)); Dbg_Print(DBG_DSAKEY,( "ubsec: ---- DSA SHA Enabled [%d]\n",pDSACtx->sha1_enable)); Dbg_Print(DBG_DSAKEY,( "ubsec: ---- Context Len %d Value -\n[", pMCR->KeyContextList[PacketIndex]->cmd_structure_length )); for ( i=0 ; i < WordLen ; i++) { Dbg_Print(DBG_DSAKEY,( "%08x ",SYS_TO_BE_LONG(pDSACtx->CtxParams[i]))); } Dbg_Print(DBG_DSAKEY,( "]\n")); } #endif /* Input Buffer(s) setup for DSA Verify */ pPacket->PacketLength = 0; /* The DSA message is a bytestream. Treat it just like a crypto buffer. */ NextFragPtr=(DataBufChainList_pt)&pPacket->InputHead; for (fragnum=0;fragnum<(int)pDSAParams->NumInputFragments;fragnum++) { FragPtr = NextFragPtr; PhysAddr=pDSAParams->InputFragments[fragnum].FragmentAddress; DataLength=pDSAParams->InputFragments[fragnum].FragmentLength; FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); /* Add (endian-adjusted) fragment length into MCR structure */ pPacket->PacketLength += (unsigned short)DataLength; if (fragnum==0) { /* Next frag descriptor is packet's InputFragmentList */ NextFragPtr=&pMCR->InputFragmentList[PacketIndex*(UBSEC_MAX_FRAGMENTS)]; } else { /* Next frag descriptor is next InputFragmentList entry */ NextFragPtr=&FragPtr[1]; } FragPtr->pNext = NextFragPtr->PhysicalAddress; Dbg_Print(DBG_DSAKEY,( "DSA Verify InputKeyInfo : IFrag[%d] <%d,%08x %08x>\n", fragnum, DataLength, CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr)); } /* for each input fragment */ /* ->PacketLength is only for the message 'm'; it does not */ /* count the sizes of the fragments used for 'R' and 'S'. */ /* Therefore, we're finished updating ->PacketLength. */ #if (UBS_CPU_ATTRIBUTE != UBS_CRYPTONET_ATTRIBUTE) /* fix up the packet length endianess in DMA control memory */ pPacket->PacketLength = CPU_TO_CTRL_SHORT( pPacket->PacketLength ); #endif /* Here with FragPtr pointing at last filled fragment descriptor */ /* NextFragPtr is pointing at next available fragment descriptor */ /* FragPtr->pNext is pointing at NextFragPtr's physical address */ /* Now setup R */ FragPtr=NextFragPtr; PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDSAParams->SigR.KeyValue)); #if defined(UBS_ENABLE_KEY_SWAP) longkey = (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->SigR.KeyValue); for (element = 0 ; element < ROUNDUP_TO_32_BIT(pDSAParams->SigR.KeyLength)/32 ; element++) longkey[element] = BYTESWAPLONG(longkey[element]); #endif /* UBS_ENABLE_KEY_SWAP */ FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDSAParams->SigR.KeyLength+7)/8; FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); /* Get and goto the next fragment */ NextFragPtr=&FragPtr[1]; FragPtr->pNext =NextFragPtr->PhysicalAddress; Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DSA_SetupVerifyParams Sync SigR Fragment to Device (0x%08X,%d,%d)\n", pDSAParams->SigR.KeyValue, 0, DataLength)); OS_SyncToDevice(pDSAParams->SigR.KeyValue, 0, DataLength); Dbg_Print(DBG_DSAKEY,( "DSA Verify Sig_R: <%d,%08x, (%08x,Next-%08x)>\n", DataLength,CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr,FragPtr->pNext)); FragPtr=NextFragPtr; /* Set up S */ PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDSAParams->SigS.KeyValue)); #if defined(UBS_ENABLE_KEY_SWAP) longkey = (UBS_UINT32 *)OS_GetVirtualAddress(pDSAParams->SigS.KeyValue); for (element = 0 ; element < ROUNDUP_TO_32_BIT(pDSAParams->SigS.KeyLength)/32 ; element++) longkey[element] = BYTESWAPLONG(longkey[element]); #endif /* UBS_ENABLE_KEY_SWAP */ FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDSAParams->SigS.KeyLength+7)/8; FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DSA_SetupVerifyParams Sync SigS Fragment to Device (0x%08X,%d,%d)\n", pDSAParams->SigS.KeyValue, 0, DataLength)); OS_SyncToDevice(pDSAParams->SigS.KeyValue, 0, DataLength); Dbg_Print(DBG_DSAKEY,( "DSA Verify Sig_S: <%d,%08x, (%08x,Next-%08x)>\n", DataLength,CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr,FragPtr->pNext)); FragPtr->pNext = 0; /* Terminate the InputFragmentList. */ #ifndef STATIC_F_LIST /* Fragment lists are external to MCR structures, must sync separately */ Dbg_Print(DBG_FRAG_SYNC,( "ubsec: DSA_SetupSignParams Sync %d IFrag Descriptor(s) to Device (0x%08X,%d,%d)\n", fragnum+1, pMCR->InputFragmentListHandle, PacketIndex*(UBSEC_MAX_FRAGMENTS)*sizeof(DataBufChainList_t), (fragnum+1)*sizeof(DataBufChainList_t))); OS_SyncToDevice(pMCR->InputFragmentListHandle, PacketIndex*(UBSEC_MAX_FRAGMENTS)*sizeof(DataBufChainList_t), (fragnum+1)*sizeof(DataBufChainList_t)); #endif /* STATIC_F_LIST not defined */ /* Output Buffers setup for DSA Verify. Always only one fragment */ FragPtr=(DataBufChainList_pt)&pPacket->OutputHead; PhysAddr=(ubsec_MemAddress_t)(OS_GetPhysicalAddress(pDSAParams->V.KeyValue)); FragPtr->DataAddress = CPU_TO_CTRL_LONG( (UBS_UINT32)PhysAddr ); DataLength=(pDSAParams->V.KeyLength+7)/8; FragPtr->DataLength = CPU_TO_CTRL_SHORT( (unsigned short)DataLength ); FragPtr->pNext = 0; Dbg_Print(DBG_DSAKEY,( "DSA Verify V: <%d,%08x, (%08x,Next-%08x)>\n", DataLength,CTRL_TO_CPU_LONG( FragPtr->DataAddress ), FragPtr,FragPtr->pNext)); /* The (only) Output Fragment descriptor (inside the MCR packet struct) */ /* will get sync'd to the CryptoNet device when the MCR gets sync'd. */ #ifndef UBSEC_HW_NORMALIZE pMCR->KeyContextList[PacketIndex]->NormBits=0; #endif pMCR->KeyContextList[PacketIndex]->ResultKey[0] = &pDSAParams->V; /* Save for post-processing callback */ pMCR->KeyContextList[PacketIndex]->ResultKey[1] = NULL; /* Not used */ pMCR->KeyContextList[PacketIndex]->ResultRNG = NULL; /* Not used */ return(UBSEC_STATUS_SUCCESS); #else return(UBSEC_STATUS_NO_DEVICE); #endif } /* end DSA_SetupVerifyParams() */