Exemplo n.º 1
0
/*
 * 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 */

}
Exemplo n.º 2
0
/*
 * 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);
}
Exemplo n.º 3
0
/*
 * 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


}
Exemplo n.º 4
0
/*
 * 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

}
Exemplo n.º 5
0
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() */
Exemplo n.º 6
0
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() */