/** @ingroup n8_packet  
 * @brief Precomputes values for MD5 hashes.
 *
 *  @param cipherInfo_p        RW:  Cipher information
 *  @param packetObject_p      RO:  Pointer to packet object.  May be NULL.
 *  @param req_pp              RW:  Pointer to request pointer.
 *
 * @par Externals
 *    None
 *
 * @return
 *    Status code
 *
 * @par Errors
 *    None
 * @par Assumptions
 *    None
 *****************************************************************************/
static N8_Status_t n8_initializeSSL_req(N8_CipherInfo_t *cipherInfo_p, 
                                        N8_Packet_t  *packetObject_p,
                                        N8_Buffer_t **ctx_pp,
                                        uint32_t *ctxa_p,
                                        API_Request_t **req_pp)
{
   N8_Status_t        ret = N8_STATUS_OK; 
   API_Request_t     *req_p = NULL;

   do
   {
      CHECK_OBJECT(cipherInfo_p, ret);
      CHECK_OBJECT(packetObject_p, ret);
      /* initialize set the return request pointer to NULL.  it wil be reset
       * with an actual value later if necessary. */
      *req_pp = NULL;

      ret =
         n8_precompute_ssl_ipad_opad(packetObject_p->cipherInfo.macSecret,
                                     packetObject_p->cipherInfo.precompute1,
                                     packetObject_p->cipherInfo.precompute2);
      CHECK_RETURN(ret);

   } while (FALSE);
   /*
    * Clean up if we arrived from an error condition.
    */
   if (ret != N8_STATUS_OK)
   {
      freeRequest(req_p);
   }
   return ret;
} /* n8_initializeSSL_req */
Ejemplo n.º 2
0
// Called by libuv when the stat call for size completes.
static void fileSizeCallback(uv_fs_t* request)
{
  if (handleRequestError(request)) return;

  double size = (double)request->statbuf.st_size;
  schedulerResume(freeRequest(request), true);
  wrenSetSlotDouble(getVM(), 2, size);
  schedulerFinishResume();
}
Ejemplo n.º 3
0
static void fileOpenCallback(uv_fs_t* request)
{
  if (handleRequestError(request)) return;
  
  double fd = (double)request->result;
  schedulerResume(freeRequest(request), true);
  wrenSetSlotDouble(getVM(), 2, fd);
  schedulerFinishResume();
}
Ejemplo n.º 4
0
/** @ingroup n8_event
 * @brief Run through the list of events and complete them.
 *
 * Run through the SDK's internal list of events, checking each one for its 
 * completion status. If the event is completed, the user's callback is 
 * invoked and the event freed.
 *
 * @par Externals
 *    n8_callback_gp    - Pointer to the callback threads data structure.
 *
 * @return
 *    N8_STATUS_OK - all's well.<br>
 *
 * @par Errors
 *    <description of possible errors><br>
 *
 * @par Assumptions
 *    This is the only function that should increment eventReadIndex,
 *    the read index in the SDK's list of Events.
 *    This function should not be called if the callback thread is running.
 *****************************************************************************/
int N8_EventPoll(void)
{
   int         nextRead;
   N8_Event_t *events_p;
   int         eventsComplete = 0;
   QMgrRequest_t *qreq_p = NULL;
   N8_Status_t usrStatus;

   while (n8_callbackData_gp->eventReadIndex != n8_callbackData_gp->eventWriteIndex)
   {
      events_p = &n8_callbackData_gp->n8_Events[n8_callbackData_gp->eventReadIndex];
      qreq_p = (QMgrRequest_t *) events_p->state;

      if ( qreq_p->requestStatus == N8_QUEUE_REQUEST_FINISHED )
      {
         if ( qreq_p->requestError != N8_QUEUE_REQUEST_ERROR )
         {
            /* Do the callback if needed. */
            if ( qreq_p->callback != NULL )
            {
               qreq_p->callback( qreq_p );
            }
            /* events_p->status = N8_QUEUE_REQUEST_FINISHED; */
            usrStatus = N8_STATUS_OK;
         }
         else
         {
            /* events_p->status = N8_QUEUE_REQUEST_COMMAND_ERROR; */
            usrStatus = N8_HARDWARE_ERROR;
         }

         /* free the request. */
         freeRequest((API_Request_t *)qreq_p);

         /* Perform the user's callback. */
         if (events_p->usrCallback)
         {
            events_p->usrCallback( events_p->usrData, usrStatus );
         }

         /* Free the position in the Event queue */
         nextRead = n8_callbackData_gp->eventReadIndex + 1;
         if (nextRead == n8_callbackData_gp->eventMax)
         {
            nextRead = 0;
         }
         n8_callbackData_gp->eventReadIndex = nextRead;
	 eventsComplete++;
	 }
   }

   return eventsComplete;
}
Ejemplo n.º 5
0
N8_Status_t n8_handleEvent(N8_Event_t *e_p,
                           void *hReq_p,
                           N8_Unit_t unit,
                           N8_QueueStatusCodes_t requestStatus)
{
   N8_Status_t ret = N8_STATUS_OK;
   QMgrRequest_t *req_p;
   
   req_p = (QMgrRequest_t *)hReq_p;
   
   if (e_p != NULL)
   {
      /* This is an asynchronous request                                */
      e_p->state =  (void *) req_p;
      e_p->status = requestStatus;
      e_p->unit = unit;
#ifdef SUPPORT_CALLBACK_THREAD
      if ((e_p->usrCallback != NULL) ||
          (e_p->usrData != NULL))
      {
         ret = queueEvent(e_p);
      }
#endif
   }                                                          
   else
   {
      /* This is an synchronous request.  Therefore we don't need an    */
      /* event, we know that the request has completed.                 */
#ifdef SUPPORT_DEVICE_POLL
      N8_QMgrDequeue();
#endif
      if ( req_p->requestError != N8_QUEUE_REQUEST_ERROR )
      {
         /* Do the callback if needed. */
         if ( req_p->callback != NULL )
         {
            req_p->callback( req_p );
         }
         /* Free the request if the event has completed successfully. */
         /* If not the error handling should free the request.        */
         if (((API_Request_t *)req_p)->userRequest != N8_TRUE)
         {
            /* Don't delete "user allocated/ pooled" requests */
            freeRequest( (API_Request_t *)req_p );
         }
      }
      else
      {
         ret = N8_HARDWARE_ERROR;
      }
   }
   return ret;
} /* n8_handleEvent */
Ejemplo n.º 6
0
// Called by libuv when the stat call completes.
static void statPathCallback(uv_fs_t* request)
{
  if (handleRequestError(request)) return;
  
  WrenVM* vm = getVM();
  wrenEnsureSlots(vm, 4);
  wrenSetSlotNewList(vm, 2);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_dev);
  wrenInsertInList(vm, 2, -1, 3);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_ino);
  wrenInsertInList(vm, 2, -1, 3);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_mode);
  wrenInsertInList(vm, 2, -1, 3);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_nlink);
  wrenInsertInList(vm, 2, -1, 3);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_uid);
  wrenInsertInList(vm, 2, -1, 3);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_gid);
  wrenInsertInList(vm, 2, -1, 3);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_rdev);
  wrenInsertInList(vm, 2, -1, 3);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_size);
  wrenInsertInList(vm, 2, -1, 3);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blksize);
  wrenInsertInList(vm, 2, -1, 3);
  
  wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blocks);
  wrenInsertInList(vm, 2, -1, 3);
  
  // TODO: Include access, modification, and change times once we figure out
  // how we want to represent it.
  //  time_t    st_atime;   /* time of last access */
  //  time_t    st_mtime;   /* time of last modification */
  //  time_t    st_ctime;   /* time of last status change */
  
  schedulerResume(freeRequest(request), true);
  schedulerFinishResume();
}
Ejemplo n.º 7
0
static void fileReadBytesCallback(uv_fs_t* request)
{
  if (handleRequestError(request)) return;

  FileRequestData* data = (FileRequestData*)request->data;
  uv_buf_t buffer = data->buffer;
  size_t count = request->result;

  // TODO: Having to copy the bytes here is a drag. It would be good if Wren's
  // embedding API supported a way to *give* it bytes that were previously
  // allocated using Wren's own allocator.
  schedulerResume(freeRequest(request), true);
  wrenSetSlotBytes(getVM(), 2, buffer.base, count);
  schedulerFinishResume();

  // TODO: Likewise, freeing this after we resume is lame.
  free(buffer.base);
}
Ejemplo n.º 8
0
static void directoryListCallback(uv_fs_t* request)
{
  if (handleRequestError(request)) return;

  uv_dirent_t entry;

  WrenVM* vm = getVM();
  wrenEnsureSlots(vm, 3);
  wrenSetSlotNewList(vm, 2);
  
  while (uv_fs_scandir_next(request, &entry) != UV_EOF)
  {
    wrenSetSlotString(vm, 1, entry.name);
    wrenInsertInList(vm, 2, -1, 1);
  }
  
  schedulerResume(freeRequest(request), true);
  schedulerFinishResume();
}
Ejemplo n.º 9
0
void MemoryPort::handleResponses()
{
    // handle responses:
    // - read in entries from memSysResponseFIFO if:
    //      * memSysResponseFIFO not empty
    //      * output FIFO not full
    // - check if entry corresponds to existing filled MSHR
    // - log statistics
    // - free up MSHR and put response data onto output FIFO

    // move responses to output FIFO
    int maxRespFromMemSysPerCycle = m_maxRespFromMemSysPerCycle;
    while(m_memSysResponseFIFO->num_available() > 0 && peOutput.num_free() > 0)
    {
        MemoryOperation * op = m_memSysResponseFIFO->read();

        m_responses++;

        // TODO return actual data instead of the address
        peOutput.write(op->address);

        // TODO log statistics

        // free memory and MSHR entry
        int ind = findMSHRForResponse(op->address);
        m_mshrEntries[ind].valid = false;
        m_mshrEntries[ind].memRequestIssued = false;
        m_availableMSHRCount++;

        freeRequest(op);

        // limit response rate
        if(--maxRespFromMemSysPerCycle == 0)
            break;
    }
}
Ejemplo n.º 10
0
/** @ingroup dh
 * @brief Computes a Diffie-Hellman exponentiation as required to compute
 * Diffie-Hellman public values from a secret value and a Diffie-Hellman
 * key (or group).  
 *
 * Description:
 * The key or group is specified by DHKeyObject which must have been
 * previously initialized with the appropriate group generator g, modulus p,
 * and modulus size by a call to N8_DHInitializeKey. The DH secret value
 * used as the exponent is specified in XValue, and must be of the same
 * size as the modulus size in DHKeyObject. GValue specifies the value
 * to be exponentiated and must also be the same size as the modulus. 
 * GValue may be null, in which case the generator g from DHKeyObject is
 * used as the GValue. The result of the calculation is returned in
 * GXValue and is the same size as the modulus.  The value computed is
 * GXValue = ( GValue ** XValue ) mod p. Thus this routine computes a
 * modular exponentiation.
 * This call can be used to compute from a private x value the value
 * X = g**x mod p that is the public X value sent to the other respondent
 * in a Diffie-Hellman exchange.  (In this case the GValue is set to null,
 * and x is used for XValue.)  When the respondent's corresponding Y value
 * (Y = g**y mod p, y = the respondent's private y) is received, this call
 * can then be used to compute the common shared secret XY = g**(xy) = YX by
 * using X for the GValue and the received Y as the XValue. 
 * 
 * Parameters:
 * @param key_p         RO:     The caller supplied DHKeyObject containing
 *                              the appropriate Diffie-Hellman values
 *                              and pre-computed DH constants.
 * @param gValue        RO:     The value to be raised to a power. 
 *                              If null, then the generator g value from
 *                              DHKeyObject is used. GValue must be the
 *                              same size as the modulus p from DHKeyObject.
 * @param xValue        RO:     The exponent. Must be supplied. XValue
 *                              must be the same size as the
 *                              modulus p from DHKeyObject
 * @param gxValue       WO:     GValue raised to the XValue power, mod p.  
 *                              GXValue will be the same
 *                              size as the modulus p from DHKeyObject.
 * @param event_p       RW:     On input, if null the call is synchronous 
 *                              and no event is returned. The operation 
 *                              is complete when the call returns. If 
 *                              non-null, then the call is asynchronous; 
 *                              an event is returned that can be used to 
 *                              determine when the operation completes.
 *
 * @return 
 *    ret - returns N8_STATUS_OK if successful or Error value.
 *
 * @par Errors:
 *          N8_INVALID_OBJECT   -   context request object is NULL<BR>
 *          N8_INVALID_KEY      -   The DHKeyObject is not a valid key
 *                                  object 
 *                                  for this operation.
 *
 * @par Assumptions:
 **********************************************************************/
N8_Status_t N8_DHCompute(N8_DH_KeyObject_t  *key_p,
                         N8_Buffer_t        *gValue_p,
                         N8_Buffer_t        *xValue_p,
                         N8_Buffer_t        *gxValue_p,
                         N8_Event_t         *event_p)
{
   N8_Status_t    ret = N8_STATUS_OK;
   API_Request_t *req_p = NULL;
   unsigned int   nBytes;

   N8_Buffer_t    *g_p;
   N8_Buffer_t    *x_p;
   N8_Buffer_t    *res_p;

   uint32_t        g_a;
   uint32_t        x_a;
   uint32_t        res_a;

   unsigned int    g_len;
   unsigned int    x_len;
   unsigned int    res_len;
   
   N8_Boolean_t       useShortCommandBlock = N8_FALSE;
   do
   {
      ret = N8_preamble();
      CHECK_RETURN(ret);
      
      CHECK_OBJECT(key_p, ret);
      CHECK_OBJECT(xValue_p, ret);
      CHECK_OBJECT(gxValue_p, ret);
      CHECK_STRUCTURE(key_p->structureID, N8_DH_STRUCT_ID, ret);

      /* compute the lengths of all of the parameters as a convenience */
      g_len      = key_p->modulusLength;
      x_len      = key_p->modulusLength;
      res_len    = key_p->modulusLength;

      nBytes = (NEXT_WORD_SIZE(x_len) +
                NEXT_WORD_SIZE(res_len));

      /* gValue_p is allowed to be NULL.  if so, use the g from the key object. */
      if (gValue_p == NULL)
      {
         useShortCommandBlock = N8_TRUE;

         /* allocate user-space buffer */
         ret = createPKRequestBuffer(&req_p,
                                     key_p->unitID,
                                     N8_CB_COMPUTE_G_XMODP_NUMCMDS_SHORT,
                                     resultHandlerGeneric, nBytes); 
      }
      else
      {
         nBytes += NEXT_WORD_SIZE(g_len);

         /* allocate user-space buffer */
         ret = createPKRequestBuffer(&req_p,
                                     key_p->unitID,
                                     N8_CB_COMPUTE_G_XMODP_NUMCMDS_LONG,
                                     resultHandlerGeneric, nBytes); 
      }

      CHECK_RETURN(ret);

      /* set up the addressing for the pointers */
      x_p =  (N8_Buffer_t *) ((int)req_p + req_p->dataoffset);
      x_a =                  req_p->qr.physicalAddress + req_p->dataoffset;
      res_p    = x_p + NEXT_WORD_SIZE(x_len);
      res_a    = x_a + NEXT_WORD_SIZE(x_len);

      memcpy(x_p, xValue_p, x_len);
      
      req_p->copyBackSize = x_len;
      req_p->copyBackFrom_p = res_p;
      req_p->copyBackTo_p = gxValue_p;

      if (useShortCommandBlock == N8_TRUE)
      {
         ret = cb_computeGXmodp_short(req_p,
                                      x_a,
                                      key_p->p_a,
                                      key_p->cp_a,
                                      key_p->gRmodP_a,
                                      res_a,
                                      key_p->modulusLength,
                                      req_p->PK_CommandBlock_ptr);
      }
      else
      {
         /* gValue_p is not NULL, copy the user-space */
         /* data into our kernel space buffers        */
         g_p    = res_p + NEXT_WORD_SIZE(res_len);
         g_a    = res_a + NEXT_WORD_SIZE(res_len);
         memcpy(g_p, gValue_p, g_len);

         ret = cb_computeGXmodp_long(req_p,
                                     g_a,
                                     x_a,
                                     key_p->p_a,
                                     key_p->cp_a,
                                     key_p->RmodP_a,
                                     res_a,
                                     key_p->modulusLength,
                                     req_p->PK_CommandBlock_ptr);
      }

      CHECK_RETURN(ret);

      QUEUE_AND_CHECK(event_p, req_p, ret);
      HANDLE_EVENT(event_p, req_p, ret);

   } while (FALSE);
   DBG(("DH computed\n"));

   /*
    * Deallocate the request if we arrived from an error condition.
    */
   if (ret != N8_STATUS_OK)
   {
      freeRequest(req_p);
   }
  
   return ret;
} /* N8_DHCompute */
Ejemplo n.º 11
0
/** @ingroup dh
 * @brief Initializes the specified DHKeyObject so that it can be used
 * in Diffie-Hellman operations. The KeyMaterial object (structure)
 * contains the appropriate group generator g, modulus p,  and modulus size.
 *
 * Description:
 * This call pre-computes various constant values from the supplied
 * parameters and initializes DHKeyObject with these values.  By
 * pre-computing these values, Diffie-Hellman computations can be done
 * faster than if these constants must be computed on each operation. 
 * Once a DHKeyObject has been initialized, it can be used repeatedly
 * in multiple DH operations. It does not ever need to be re-initialized,
 * unless the actual key value(s) change (i.e., unless the key itself
 * changes).
 * 
 * @param key_p         RW: The caller allocated DHKeyObject, initialized
 *                          by this call with the appropriate DH key 
 *                          material and pre-computed DH constants 
 *                          depending on the value of the KeyType parameter
 * @param material_p    RO: Pointer to the key material to use in initializing
 *                          DHKeyObject. 
 *
 * @return 
 *    ret - returns N8_STATUS_OK if successful or Error value.
 *
 * @par Errors:
 *          N8_INVALID_OBJECT   -   DH key or key material object is NULL<BR>
 *
 * @par Assumptions:
 *      None.
 **********************************************************************/
N8_Status_t N8_DHInitializeKey(N8_DH_KeyObject_t     *key_p,
                               N8_DH_KeyMaterial_t   *material_p,
                               N8_Event_t            *event_p)
{
   N8_Status_t     ret = N8_STATUS_OK;
   int             nBytes;
   API_Request_t  *req_p = NULL;

   do
   {
      ret = N8_preamble();
      CHECK_RETURN(ret);

      CHECK_OBJECT(key_p, ret);
      CHECK_OBJECT(material_p, ret);

      key_p->unitID = material_p->unitID;

      /* check the modulus size to ensure it is 1 <= ms <= 512.  return
       * N8_INVALID_SIZE if not. */
      if (material_p->modulusSize < N8_DH_MIN_MODULUS_SIZE ||
          material_p->modulusSize > N8_DH_MAX_MODULUS_SIZE)
      {
         ret = N8_INVALID_KEY_SIZE;
         break;
      }

      /* Allocate space for the initialized key.  we must compute 'R mod p' and 'cp'
       * for use in subsequent DHComputes. */
      key_p->modulusLength = material_p->modulusSize;
      nBytes = (NEXT_WORD_SIZE(key_p->modulusLength) +    /* g */
                NEXT_WORD_SIZE(key_p->modulusLength) +    /* p */
                NEXT_WORD_SIZE(key_p->modulusLength) +    /* R mod p */
                NEXT_WORD_SIZE(key_p->modulusLength) +    /* g R mod p */
                NEXT_WORD_SIZE(PK_DH_CP_Byte_Length));/* cp */

      /* Allocate a kernel buffer to hold data accessed by the NSP2000 */
      key_p->kmem_p = N8_KMALLOC_PK(nBytes);
      CHECK_OBJECT(key_p->kmem_p, ret);
      memset(key_p->kmem_p->VirtualAddress, 0, nBytes);

      /* Compute virtual addresses within the kernel buffer */
      key_p->g        = (N8_Buffer_t *) key_p->kmem_p->VirtualAddress;
      key_p->p        = key_p->g        + NEXT_WORD_SIZE(key_p->modulusLength);
      key_p->R_mod_p  = key_p->p        + NEXT_WORD_SIZE(key_p->modulusLength);
      key_p->gR_mod_p = key_p->R_mod_p  + NEXT_WORD_SIZE(key_p->modulusLength);
      key_p->cp       = key_p->gR_mod_p + NEXT_WORD_SIZE(key_p->modulusLength);

      /* Compute physical addresses within the kernel buffer */
      key_p->g_a      = key_p->kmem_p->PhysicalAddress;
      key_p->p_a      = key_p->g_a      + NEXT_WORD_SIZE(key_p->modulusLength);
      key_p->RmodP_a  = key_p->p_a      + NEXT_WORD_SIZE(key_p->modulusLength);
      key_p->gRmodP_a = key_p->RmodP_a  + NEXT_WORD_SIZE(key_p->modulusLength);
      key_p->cp_a     = key_p->gRmodP_a + NEXT_WORD_SIZE(key_p->modulusLength);

      /* Set up the memory for p and g and copy from the key material */
      memcpy(key_p->p, material_p->p, material_p->modulusSize);
      memcpy(key_p->g, material_p->g, material_p->modulusSize);

      /* Set the structure ID */
      key_p->structureID = N8_DH_STRUCT_ID;

      /* allocate user-space command buffer */
      ret = createPKRequestBuffer(&req_p, key_p->unitID,
                                  N8_CB_PRECOMPUTE_DHVALUES_NUMCMDS,
                                  NULL, 0);

      CHECK_RETURN(ret);

      ret = cb_precomputeDHValues(req_p, key_p->g_a, key_p->p_a, 
		                  key_p->RmodP_a, key_p->gRmodP_a, key_p->cp_a,
                                  key_p->modulusLength,
                                  req_p->PK_CommandBlock_ptr,
                                  key_p->unitID);
      CHECK_RETURN(ret);
      QUEUE_AND_CHECK(event_p, req_p, ret);
      HANDLE_EVENT(event_p, req_p, ret);
   } while(FALSE);

   /*
    * Deallocate the request if we arrived from an error condition.
    */
   if (ret != N8_STATUS_OK)
   {
      /* free the request */
      freeRequest(req_p);
      /* free the key also, if it has been allocated */
      if (key_p != NULL)
      {
         /* ignore the return code as we want to return the original anyway */
         (void) N8_DHFreeKey(key_p);
      }
   }
  
   return ret;
} /* N8_DHInitializeKey */
Ejemplo n.º 12
0
void *thread_func(void *new_socket_ref)
{

  int new_socket = *(int*)new_socket_ref;
  //int* index = (int *) param;

     do{
       //printf("--------------\nHebra %i\n",*index);
	result = recv(new_socket,buffer,80,0);

	if(result==-1){
	  perror("Servidor:Recv");
	  exit(1);
	}
	/*	if(strcmp(buffer,"EOT")==0){  
	  printf("Se ha recibido EOT\n");
	  EOT=1;
	}else if(strcmp(buffer,"EOT")!=0){  
	printf("El mensaje recibido fue:\n%s\n",buffer);*/
	printf("%s\n",buffer);
	  split_request(buffer,&req);
	  
	  switch(req.req_type){
	  case GET_STATE:
	    printf("GET_STATE %s\n",req.req[0]);
	    //printf("Buscamos usuario...\n");
	    user_ptr = getUser(req.req[0],user_list);
	    if(user_ptr!=NULL){

	      sprintf(buffer,"%i %s %i",
		      STATE,user_ptr->name,user_ptr->state);
	      //printf("Encontrado\n Respuesta a enviar: %s\n",buffer);
	    }else{
	      printf("El usuario no existe\n");
	      sprintf(buffer,"%i",ERROR);
	    }
	    if(send(new_socket,buffer,80,0)==-1){
	      printf("Servidor:Send\n");
	      exit(1);
	    }
	    break;
	  case POST_NAME_LOCATION_STATE:
	    printf("POST_NAME_LOCATION_STATE %s %s %i\n",
		   req.req[0],req.req[1],atoi(req.req[2]));
	    
	    strcpy(user.name,req.req[0]);
	    strcpy(user.location,req.req[1]);
	    user.state = atoi(req.req[2]); 
	    user_list = addUser(&user,user_list);
	    showUsers(user_list);
	    sprintf(buffer,"%i",OK);	    
	    if(send(new_socket,buffer,80,0)==-1){
	      printf("Servidor:Send\n");
	      exit(1);
	    }
	    
	    break;
	  case AUTH:
	    printf("AUTH %s\n",req.req[0]);
	    //Comprobamos si existe el usuario
	    user_ptr = getUser(req.req[0],user_list);
	    if(user_ptr!=NULL){//Si Existe mandamos reto
	      challenge = random();
	      sprintf(buffer,"%i %i",CHALLENGE,challenge);
	      printf("Enviado reto: %s\n",buffer);
	      if(send(new_socket,buffer,80,0)==-1){
		printf("Servidor:Send\n");
		exit(1);
	      }
	      result = recv(new_socket,buffer,80,0);

	      if(result==-1){
		perror("Servidor:Recv");
		exit(1);
	      }
	      split_request(buffer,&req);
	      //printf("Recibimos %s\n",buffer);
	      strcpy(location,req.req[1]);
	      state = atoi(req.req[2]);
	      //Esperamos md5 name:reto:secreto
	      result = recv(new_socket,out,16,0);
	      for (i=0; i<16; i++) {
		printf("%02x", out[i]);
	      }
	      printf("\n");
	      //Comparamos md5 recibido con nuestro md5
	      sprintf(buffer,"%s%i%s",user_ptr->name,challenge,user_ptr->secret);
	      printf("OUR MD5 %s : ",buffer);
	      getMD5(buffer,strlen(buffer),md5);
	      for (i=0; i<16; i++) {
		printf("%02x", md5[i]);
	      }
	      printf("\n");
	      if(memcmp(md5,out,16)==0){
		printf("MATCH MD5\n");
		strcpy(user_ptr->location,location);
		user_ptr->state = state;
		sprintf(buffer,"%i",OK);
		if(send(new_socket,buffer,80,0)==-1){
		  printf("Servidor:Send\n");
		  exit(1);
		}	
	      }else{
		printf("MD5 incorrecto.\n");
		sprintf(buffer,"%i",ERROR);
		if(send(new_socket,buffer,80,0)==-1){
		  printf("Servidor:Send\n");
		  exit(1);
		}	
		
	      }
	      
	    }else{//Si no existe mandamos error
	      printf("No existe el usuario.\n");
	      sprintf(buffer,"%i",ERROR);
	      if(send(new_socket,buffer,80,0)==-1){
		printf("Servidor:Send\n");
		exit(1);
	      }
	    }


	    break;
	  case GET_LOCATION:
	    printf("GET_LOCATION %s\n",req.req[0]);
	    user_ptr = getUser(req.req[0],user_list);
	    if(user_ptr!=NULL){
	      sprintf(buffer,"%i %s %s",
		      LOCATION,user_ptr->name,user_ptr->location);
	    }else{
	      sprintf(buffer,"%i",ERROR);
	    }
	    if(send(new_socket,buffer,80,0)==-1){
	      printf("Servidor:Send\n");
	      exit(1);
	    }
	    break;
	  case EXIT:
            printf("EXIT\n");
	    printf("Fin de la conexion\n");
	    EOT=1;
	  }
	  freeRequest(&req);
	  //}
	  //printf("-----\n");
      }while(!EOT);

 
// the function must return something - NULL will do 
  return NULL;

}
Ejemplo n.º 13
0
/** @ingroup n8_event
 * @brief Runs as a seperate thread polling the list of events and completing 
 *        them.
 *
 * This function is started as a seperate thread. It continually runs through
 * the SDK's internal list of events, checking each one for its 
 * completion status. If the event is completed, the user's callback is 
 * invoked and the event freed.
 *
 * @par Externals
 *
 * @return
 *    N8_STATUS_OK - all's well.<br>
 *
 * @par Errors
 *    <description of possible errors><br>
 *
 * @par Assumptions
 *    This is the only function that should increment eventReadIndex,
 *    the read index in the SDK's list of Events.
 *    N8_EventPoll should not be called if this thread is running.
 *****************************************************************************/
N8_Status_t n8_callbackThread(N8_CallbackData_t *callbackData_p)
{
   int         nextRead;
   N8_Event_t *events_p;
   QMgrRequest_t *qreq_p = NULL;
   N8_Status_t usrStatus;

   /* Perform Linux Kernal specific initialization */
#ifdef __KERNEL__
   threadStruct = current;
   /* Mask out the unwanted signals */
   current->blocked.sig[0] |= sigmask(SIGINT) | sigmask(SIGTERM);
   recalc_sigpending(current);

   /* set name of this process (max 15 chars + 0 !) */
   strcpy(current->comm, "NSP2000 Thread");
#endif
        
   while (callbackData_p->n8_thread == TRUE)
   {
      if (callbackData_p->eventReadIndex != callbackData_p->eventWriteIndex)
      {
         events_p = &callbackData_p->n8_Events[callbackData_p->eventReadIndex];
         qreq_p = (QMgrRequest_t *) events_p->state;

         if ( qreq_p->requestStatus == N8_QUEUE_REQUEST_FINISHED )
         {
            if ( qreq_p->requestError != N8_QUEUE_REQUEST_ERROR )
            {
               /* Do the callback if needed. */
               if ( qreq_p->callback != NULL )
               {
                  qreq_p->callback( qreq_p );
               }
               /* events_p->status = N8_QUEUE_REQUEST_FINISHED; */
	       usrStatus = N8_STATUS_OK;
            }
            else
            {
               /* events_p->status = N8_QUEUE_REQUEST_COMMAND_ERROR; */
	       usrStatus = N8_HARDWARE_ERROR;
            }

            /* free the request. */
            freeRequest((API_Request_t *)qreq_p);

            /* Perform the user's callback. */
            if (events_p->usrCallback)
            {
               events_p->usrCallback( events_p->usrData, usrStatus );
            }

            /* Free the position in the Event queue */
            nextRead = callbackData_p->eventReadIndex + 1;
            if (nextRead == callbackData_p->eventMax)
            {
               nextRead = 0;
            }
            callbackData_p->eventReadIndex = nextRead;
	 }
         else
         {
            N8_WaitOnRequest(callbackData_p->timeout);
         }
      }
      else
      {
         N8_WaitOnRequest(callbackData_p->timeout);
      }
   }

   /* Free the resources allocated by callback initialization.          */
   /* This is done here instead of in callbackShutdown to avoid freeing */
   /* resources while the callback thread continues to reference them.  */
   callbackData_p->eventMax = 0;
   N8_deleteProcessSem(&callbackData_p->eventLock);
   N8_UFREE(callbackData_p);

   return N8_STATUS_OK;
}
Ejemplo n.º 14
0
static void fileCloseCallback(uv_fs_t* request)
{
  if (handleRequestError(request)) return;

  schedulerResume(freeRequest(request), false);
}
Ejemplo n.º 15
0
/** @ingroup ipsec_packet
 * @brief Encrypt and authenticate an entire IPSec record.
 *
 * Encrypt and authenticate an entire IPSec record.  PacketObject is a packet 
 * object previously initialized by a call to N8_PacketInitialize specifying 
 * IPSec as the packet protocol to use. PacketObject provides encryption and 
 * authentication information to be used in the call. The decryption algorithm 
 * can only be DES as specified when PacketObject was initialized. The 
 * authentication algorithm can be HMAC-MD5-96 or HMACSHA-1-96 as specified 
 * when PacketObject was initialized. Thus, two combinations of 
 * encryption/authentication can be performed: DES/HMAC-MD5-96 and 
 * DES/HMAC-SHA-1-96. The SPI parameter specifies the IPSec Security Parameter 
 * Index of the message. The SPI is used along with the sequence number and 
 * the DES initialization vector (taken from information specified in the
 * PacketObject) in the authentication computation. The message contents of the
 * IPSec packet is given in Data; its length in bytes must be specified in
 * packetLength. Note that Data must include all of the information to be
 * encrypted according to the IPSec specification; this includes the TCP and
 * IP headers if present (the IP header is only present in tunnel mode) and must
 * also include the terminating pad, pad length and next header fields.
 * The byte length of Data is specified in packetLength and must also include all
 * of these fields. packetLength must be a multiple of 8. The fully encrypted and
 * authenticated Data is returned in Result, including the encrypted  data
 * followed by the HMAC-MD5-96 or HMAC-SHA-1-96 authentication value. 
 *
 * @param packetObject_p RW:    The  object denoting the decryption and
 *                              verification computation to be done.  PacketObject
 *                              must have been initialized for use with IPSec. 
 *                              The state in PacketObject will be updated if 
 *                              necessary as part of the call. <BR> 
 * @param packet_p       RO:    The ESP packet beginning with the Security 
 *                              Parameter Index,  Sequence Number and data payload
 *                              including DES initialization vector and ending 
 *                              with the pad, pad length, and next header fields 
 *                              as specified by the IPSec protocol.<BR>
 * @param packetLength     RO:    The length of Data, in bytes, from 8 bytes - 17 KBytes 
 *                              inclusive. A length < 8 or not a multiple of 8 is 
 *                              illegal and results in an error.<BR>
 * @param result_p       WO:    The encrypted / authenticated data, complete with 
 *                              authentication data. Result must be of sufficient 
 *                              size to hold the fully encrypted & authenticated 
 *                              message; its size must be at least packetLength +
 *                              IPSEC_AUTHENTICATION_DATA_LENGTH  
 *                              (hash size for all hash algorithms).<BR>
 * @param event_p        RW:    On input, if null the call is synchronous and no 
 *                              event is returned. The operation is complete when 
 *                              the call returns. If non-null, then the call is 
 *                              asynchronous; an event is returned that can be used 
 *                              to determine when the operation completes.
 *
 *
 * @return 
 *    packetObject_p - The state in PacketObject will be updated if necessary as 
 *                     part of the call.
 *    result_p       - The encrypted / authenticated data, complete with 
 *                     authentication data.
 *    ret   - returns N8_STATUS_OK if successful or Error value.
 *
 * @par Errors:
 *    N8_INVALID_OBJECT   - packet object is zero, couldn't write to unspecified
 *                          address<BR>
 *    N8_INVALID_INPUT_SIZE - The value of packetLength is less then 8 or bigger 
 *                            then 17 KBytes or is not a multiple of 8.
 *    N8_UNIMPLEMENTED_FUNCTION - not supported protocol configuration requested
 *    N8_HARDWARE_ERROR   - couldn't write to context memory
 *   
 *
 * @par Assumptions:
 *      packetObject_p was initialized and all parameters checked.<BR>
 *      For IPSec, the authentication data is always
 *      12 (IPSEC_AUTHENTICATION_DATA_LENGTH) bytes (the 12 most  
 *      significant bytes of the standard 16 byte MD5 or 20 byte SHA-1 value) and
 *      is not encrypted. Result is always packetLength + 12 bytes in length. 
 *      The caller is responsible for ensuring that Result is this size.
 *****************************************************************************/
N8_Status_t N8_IPSecEncryptAuthenticate(N8_Packet_t       *packetObject_p, 
                                        N8_IPSecPacket_t  *packet_p, 
                                        int                packetLength,  
                                        N8_IPSecPacket_t  *result_p, 
                                        N8_Event_t        *event_p )
{
   N8_Status_t ret = N8_STATUS_OK;    /* the return status: OK or ERROR */
     
   API_Request_t  *req_p = NULL;       /* request buffer */
   EA_CMD_BLOCK_t *next_cb_p = NULL;
   int dataLength;
   unsigned long pack_a;
   N8_Buffer_t *pack_p = NULL;
   unsigned long res_a;
   N8_Buffer_t *res_p = NULL;
   N8_Buffer_t *ctx_p = NULL;
   uint32_t     ctx_a;
   int nBytes;
   int numCommands;
   int numCtxBytes = 0;
   void *callbackFcn = NULL;
   n8_ctxLoadFcn_t    ctxLoadFcn;
   DBG(("N8_IPSecEncryptAuthenticate\n"));     
   do
   {
      /* verify data length */
      if ((packetLength < IPSEC_DATA_LENGTH_MIN) || (packetLength > IPSEC_DATA_LENGTH_MAX))
      {
         DBG(("Data length is out of range\n"));
         ret = N8_INVALID_INPUT_SIZE;
         break;
      }

      if (packetLength % IPSEC_DATA_BLOCK_SIZE)
      {
         DBG(("Data length is not a multiple of %d\n", IPSEC_DATA_BLOCK_SIZE));
         ret = N8_INVALID_INPUT_SIZE;
         break;
      }

      /* verify packet object */
      CHECK_OBJECT(packetObject_p, ret);
      CHECK_STRUCTURE(packetObject_p->structureID, N8_PACKET_STRUCT_ID, ret);
      /* verify data object */
      CHECK_OBJECT(packet_p, ret);
      /* verify result object */
      CHECK_OBJECT(result_p, ret);

      dataLength = packetLength - IPSEC_PACKET_HEADER_LENGTH;
      numCommands = N8_CB_EA_IPSECENCRYPTAUTHENTICATE_NUMCMDS;
      if (packetObject_p->contextLoadNeeded == N8_TRUE)
      {
         numCommands += packetObject_p->ctxLoadCmds;
         numCtxBytes = NEXT_WORD_SIZE(EA_CTX_Record_Byte_Length);
      }

      /* compute the space needed for the size of context load, if required */ 
      nBytes = NEXT_WORD_SIZE(HMAC_LENGTH) + numCtxBytes;              

      /* If the data must be copied to a kernel before the chip can operate  */
      /* on it, compute the additional space required and setup the callback */
      /* function to copy the result once the operation has completed.       */
      if (packetObject_p->mode == N8_PACKETMEMORY_NONE)
      {
         nBytes += NEXT_WORD_SIZE(dataLength) + /* packet data length pack_p  */
                   NEXT_WORD_SIZE(packetLength);/* result packet length res_p */
         callbackFcn = resultHandlerGeneric;
      }

      /* create request buffer */
      ret = createEARequestBuffer(&req_p,
                                  packetObject_p->unitID,
                                  numCommands,
                                  callbackFcn,
                                  nBytes);
      CHECK_RETURN(ret);

      /* Compute the context memory pointers. */
      ctx_a = req_p->qr.physicalAddress + req_p->dataoffset;
      ctx_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset);

      /* Compute the addresses for the packet and result buffer. */
      if (packetObject_p->mode == N8_PACKETMEMORY_NONE)
      {
         /* The data must be copied to this kernel before the chip can operate  */
         /* on it, compute the addresses within the kernel buffer and copy in   */
         /* the packet.                                                         */
         pack_a = ctx_a + numCtxBytes;
         pack_p = ctx_p + numCtxBytes;

         res_a = pack_a + NEXT_WORD_SIZE(dataLength);
         res_p = pack_p + NEXT_WORD_SIZE(dataLength);

         memcpy(pack_p, &packet_p[IPSEC_DATA_OFFSET], dataLength);
      
      }
      else
      {
         /* The chip can access the data directly, compute the */
         /* physical addresses of the packet & result buffer.  */
         pack_a = N8_VirtToPhys(&packet_p[IPSEC_DATA_OFFSET]);
         res_a =  N8_VirtToPhys(&result_p[IPSEC_DATA_OFFSET]);
      }


      next_cb_p = req_p->EA_CommandBlock_ptr;
      
      memcpy(result_p, packet_p, IPSEC_PACKET_HEADER_LENGTH);

      packetObject_p->cipherInfo.key.IPsecKeyDES.sequence_number =
         IPSEC_EXTRACT_SEQUENCE_NIMBER(packet_p);

      /* generate the command blocks necessary to load the context, if required */
      if (packetObject_p->contextLoadNeeded == N8_TRUE)
      {
         /* Generate the command blocks for the Context Load */
         ctxLoadFcn = (n8_ctxLoadFcn_t)packetObject_p->ctxLoadFcn;
         ret = ctxLoadFcn(req_p,
                          next_cb_p,
                          packetObject_p,
                          &packetObject_p->cipherInfo,
                          packetObject_p->packetHashAlgorithm,
                          ctx_p,
                          ctx_a,
                          &next_cb_p);
         CHECK_RETURN(ret);

         packetObject_p->contextLoadNeeded = N8_FALSE;
      }

      memcpy(&packetObject_p->cipherInfo.IV[0], packet_p+IPSEC_IV_OFFSET,
             N8_DES_KEY_LENGTH); 

      cb_ea_IPsec(next_cb_p,
                  packetObject_p,
                  pack_a, 
                  res_a,
                  dataLength,
                  IPSEC_EXTRACT_SPI(packet_p),
                  packetObject_p->encOpCode);


      req_p->copyBackTo_p   = result_p + IPSEC_DATA_OFFSET;
      req_p->copyBackFrom_p = res_p;
      req_p->copyBackSize   = dataLength + HMAC_LENGTH;

      QUEUE_AND_CHECK(event_p, req_p, ret)
      HANDLE_EVENT(event_p, req_p, ret);
   } while (FALSE);

   if (ret != N8_STATUS_OK)
   {
      freeRequest(req_p);
   }
   DBG(("N8_IPSecEncryptAuthenticate - FINISHED\n"));
   return ret;
} /* N8_IPSecEncryptAuthenticate */
Ejemplo n.º 16
0
/** @ingroup ipsec_packet
 * @brief Decrypt and verify an entire IPSec record.
 *
 * Decrypt and verify an entire IPSec record. PacketObject is a packet object 
 * previously initialized by a call to N8_PacketInitialize specifying IPSec 
 * as the packet protocol to use. PacketObject provides encryption and 
 * authentication information to be used in the call. The decryption algorithm 
 * can only be DES as specified when PacketObject was initialized. The 
 * authentication algorithm can be HMAC-MD5-96 or HMAC-SHA-1-96 as specified 
 * when PacketObject was initialized. Thus, two combinations of 
 * decryption/verification can be performed: DES/HMAC-MD5-96 and DES/HMAC-SHA-1-96. 
 * The SPI parameter specifies the IPSec Security Parameter Index of the message. 
 * The SPI is used along with the sequence number and the DES initialization 
 * vector (taken from PacketObject) in the authentication computation. The 
 * message contents of the encrypted and authenticated IPSec packet is given 
 * in EncryptedData; its length in bytes must be specified in encryptedPacketLength. 
 * Note that EncryptedData must end with the unencrypted12-byte authentication 
 * value as required by the IPSec specification. The byte length of EncryptedData 
 * including the 12 byte authentication value is specified in encryptedPacketLength. 
 * encryptedPacketLength must be at least 20 (i.e., EncryptedData must consist of 
 * at least one DES block to be decrypted plus the mandatory 12 byte 
 * authentication value), and must be of the form 12 + n*8 for n > 0. The decrypted 
 * EncryptedData is returned in Result, including the decrypted  data followed by 
 * the 12 bytes of authentication data. Result is always encryptedPacketLength 
 * bytes in length. The caller is responsible for ensuring that Result is at  
 * least this size.  This call also calculates the authentication value on the 
 * EncryptedData and compares this calculated value to the value at the end of 
 * EncryptedData. If these two values are equal, the verification succeeds and 
 * True is returned in Verify, otherwise False is returned in Verify.
 *  
 *
 * @param packetObject_p RW:    The  object denoting the decryption and 
 *                              verification computation to be done. PacketObject
 *                              must have been initialized for use with IPSec. 
 *                              The state in PacketObject will be updated if 
 *                              necessary as part of the call. <BR> 
 * @param encryptedPacket_p RO:   The message portion / contents of the IPSec packet.<BR>
 * @param encryptedPacketLength RO:  The length of EncryptedData, in bytes, 
 *                              from 20 bytes - 18 KBytes inclusive. A length 
 *                              less than 20 or not of the form 12+n*8 is illegal
 *                              and results in an error.<BR>
 * @param Verify         WO:    Returned as True if the computed authentication 
 *                              value on EncryptedData matches the authentication 
 *                              value contained at the end of EncryptedData; 
 *                              otherwise False is returned. If Verify is False, 
 *                              the contents of Result may be gibberish and/or 
 *                              have been altered.<BR>
 * @param result_p       WO:    The decrypted / authenticated data, complete 
 *                              with authentication data. Result must be of 
 *                              sufficient size to hold the decrypted & 
 *                              authenticated message; its size must be at least 
 *                              EncryptedDataLeng.<BR>
 * @param event_p          RW:    On input, if null the call is synchronous and no 
 *                              event is returned. The operation is complete when 
 *                              the call returns. If non-null, then the call is 
 *                              asynchronous; an event is returned that can be used 
 *                              to determine when the operation completes.
 *
 *
 * @return 
 *    packetObject_p - The state in PacketObject will be updated if necessary as 
 *                     part of the call.
 *    result_p       - The encrypted / authenticated data, complete with 
 *                     authentication data.
 *    ret   - returns N8_STATUS_OK if successful or Error value.
 *
 * @par Errors:
 *    N8_INVALID_OBJECT   - packet object is zero, couldn't write to unspecified
 *                          address<BR>
 *    N8_INVALID_INPUT_SIZE - The value of packetLength is < 20 or > 18 KBytes or 
 *                          is not of the form 12 + n*8; no operation is 
 *                          performed and no result is  returned.
 *    N8_UNIMPLEMENTED_FUNCTION - not supported protocol configuration requested
 *    N8_HARDWARE_ERROR   - couldn't write to context memory
 *   
 *
 * @par Assumptions:
 *      packetObject_p was initialized and all parameters checked.
 *****************************************************************************/
N8_Status_t N8_IPSecDecryptVerify( N8_Packet_t   *packetObject_p, 
                                   N8_IPSecPacket_t *encryptedPacket_p, 
                                   int               encryptedPacketLength,
                                   N8_Buffer_t      *computedHMAC_p,
                                   N8_Boolean_t     *verify_p,
                                   N8_IPSecPacket_t *result_p, 
                                   N8_Event_t       *event_p )
{
   N8_Status_t ret = N8_STATUS_OK;    /* the return status: OK or ERROR */

   API_Request_t  *req_p = NULL;       /* request buffer */
   EA_CMD_BLOCK_t *next_cb_p = NULL;
   int dataLength;
   unsigned long pack_a;
   N8_Buffer_t *pack_p = NULL;
   unsigned long res_a;
   N8_Buffer_t *res_p = NULL;
   N8_Buffer_t *ctx_p = NULL;
   uint32_t     ctx_a;
   int nBytes;
   int numCommands;
   int numCtxBytes = 0;
   ipsecVerifyPostDataStruct_t *postData_p = NULL;
   n8_ctxLoadFcn_t    ctxLoadFcn;

   DBG(("N8_IPSecDecryptVerify\n"));
   do
   {
      *verify_p = N8_FALSE;
      /* verify data length */
      if ((encryptedPacketLength < IPSEC_DECRYPTED_DATA_LENGTH_MIN) ||
          (encryptedPacketLength > IPSEC_DATA_LENGTH_MAX))
      {
         DBG(("Data length is out of range\n"));
         ret = N8_INVALID_INPUT_SIZE;
         break;
      }
    
      if ((encryptedPacketLength - IPSEC_AUTHENTICATION_DATA_LENGTH) % IPSEC_DATA_BLOCK_SIZE)
      {
         DBG(("Data length is not a multiple of %d\n", IPSEC_DATA_BLOCK_SIZE));
         ret = N8_INVALID_INPUT_SIZE;
         break;
      }
      /* verify packet object */
      CHECK_OBJECT(packetObject_p, ret);
      CHECK_STRUCTURE(packetObject_p->structureID, N8_PACKET_STRUCT_ID, ret);
      /* verify encrypted data object */
      CHECK_OBJECT(encryptedPacket_p, ret);
      /* verify result object */
      CHECK_OBJECT(result_p, ret);
#ifdef NO_MAC_COPYBACK
      CHECK_OBJECT(computedHMAC_p, ret);
#endif 

      dataLength = encryptedPacketLength - IPSEC_PACKET_HEADER_LENGTH;

      numCommands = N8_CB_EA_IPSECDECRYPTVERIFY_NUMCMDS;
      if (packetObject_p->contextLoadNeeded == N8_TRUE)
      {
         numCommands += packetObject_p->ctxLoadCmds;
         numCtxBytes = NEXT_WORD_SIZE(sizeof(EA_ARC4_CTX));
      }

      /* compute the space needed for the chip to place the result */
      nBytes = NEXT_WORD_SIZE(HMAC_LENGTH) + numCtxBytes; /* context to load */
      if (packetObject_p->mode == N8_PACKETMEMORY_NONE)
      {
         nBytes += NEXT_WORD_SIZE(dataLength * 2);
      }

      /* create request buffer */
      ret = createEARequestBuffer(&req_p,
                                  packetObject_p->unitID,
                                  numCommands,
                                  resultHandlerIPSecVerify,
                                  nBytes);
      CHECK_RETURN(ret);

      req_p->copyBackCommandBlock = N8_TRUE;

      /* Compute the addresses for the context. */
      ctx_a = req_p->qr.physicalAddress + req_p->dataoffset;
      ctx_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset);

      /* Compute the addresses for the packet and result buffer. */
      if (packetObject_p->mode == N8_PACKETMEMORY_NONE)
      {
         /* The data must be copied to this kernel before the chip can operate  */
         /* on it, compute the addresses within the kernel buffer and copy in   */
         /* the packet.                                                         */
         pack_a = ctx_a + numCtxBytes;
         pack_p = ctx_p + numCtxBytes;

         res_a = pack_a + NEXT_WORD_SIZE(dataLength);
         res_p = pack_p + NEXT_WORD_SIZE(dataLength);

         memcpy(pack_p, encryptedPacket_p + IPSEC_DATA_OFFSET, dataLength); 
      
      }
      else
      {
         /* The chip can access the data directly, compute the */
         /* physical addresses of the packet & result buffer.  */
         pack_a = N8_VirtToPhys(encryptedPacket_p + IPSEC_DATA_OFFSET);
         res_a =  N8_VirtToPhys(result_p + IPSEC_DATA_OFFSET);
      }

      next_cb_p = req_p->EA_CommandBlock_ptr;

      /* generate the command blocks necessary to load the context, if required */
      if (packetObject_p->contextLoadNeeded == N8_TRUE)
      {
         /* Generate the command blocks for the Context Load */
         ctxLoadFcn = (n8_ctxLoadFcn_t)packetObject_p->ctxLoadFcn;
         ret = ctxLoadFcn(req_p,
                          next_cb_p,
                          packetObject_p,
                          &packetObject_p->cipherInfo,
                          packetObject_p->packetHashAlgorithm,
                          ctx_p,
                          ctx_a,
                          &next_cb_p);
         CHECK_RETURN(ret);

         packetObject_p->contextLoadNeeded = N8_FALSE;
      }

      memcpy(&packetObject_p->cipherInfo.IV[0], encryptedPacket_p+8,8);
      packetObject_p->cipherInfo.key.IPsecKeyDES.sequence_number =
         IPSEC_EXTRACT_SEQUENCE_NIMBER(encryptedPacket_p);

      cb_ea_IPsec(next_cb_p,
                  packetObject_p,
                  pack_a, 
                  res_a,
                  dataLength,
                  IPSEC_EXTRACT_SPI(encryptedPacket_p),
                  packetObject_p->decOpCode);

      postData_p = (ipsecVerifyPostDataStruct_t *)req_p->postProcessBuffer;
      postData_p->computedHMAC_p = computedHMAC_p;
      postData_p->data_p = result_p + IPSEC_DATA_OFFSET;
      postData_p->res_p = res_p;
      postData_p->dataLength = dataLength;
      postData_p->verify_p = verify_p;
      postData_p->hashAlgorithm = packetObject_p->packetHashAlgorithm;

      /* setup post processing buffer pointer */
      req_p->postProcessingData_p = (void *) postData_p;

      /* decrypt data */
      QUEUE_AND_CHECK(event_p, req_p, ret)
      HANDLE_EVENT(event_p, req_p, ret);
      /* compare authentication values */

      memcpy(result_p, encryptedPacket_p, IPSEC_PACKET_HEADER_LENGTH); 
      if (*verify_p == N8_TRUE)
      {
         packetObject_p->cipherInfo.key.IPsecKeyDES.sequence_number =
            IPSEC_EXTRACT_SEQUENCE_NIMBER(encryptedPacket_p);
         memcpy(&packetObject_p->cipherInfo.IV[0],
                encryptedPacket_p+IPSEC_IV_OFFSET,
                N8_DES_KEY_LENGTH);

      }

   } while (FALSE);

   if (ret != N8_STATUS_OK)
   {
      freeRequest(req_p);
   }
   DBG(("N8_IPSecDecryptVerify - FINISHED\n"));
   return ret;
} /* N8_IPSecDecryptVerify */
Ejemplo n.º 17
0
/** @ingroup n8_ssltls
 * @brief Encrypt/Authenticate an SSL or TLS message
 *
 * An entire SSL or TLS record is encrypted/authenticated.
 *
 *  @param packetObj_p         RW:  Pointer to a packet object which was
 *                                  previously initialized for SSL or TLS
 *  @param packet_p            RO:  Pointer to packet
 *  @param result_p            RW:  Pointer to pre-allocated buffer where the
 *                                  results will be stored.
 *  @param request             RW:  Kernel request buffer used when mode =
 *                                  N8_PACKETMEMORY_REQUEST.
 *  @param event_p             RW:  Asynchronous event pointer.
 *
 * @par Externals
 *    None
 *
 * @return
 *    Error condition if raised.
 *
 * @par Errors
 *    None
 *
 * @par Assumptions
 *    None
 *****************************************************************************/
N8_Status_t 
N8_SSLTLSEncryptAuthenticateMemory(N8_Packet_t             *packetObj_p,
                                   const N8_SSLTLSPacket_t *packet_p,
                                   N8_SSLTLSPacket_t       *result_p,
                                   N8_RequestHandle_t       request,
                                   N8_Event_t              *event_p)
{

   N8_Status_t ret = N8_STATUS_OK;
   API_Request_t *req_p = NULL;
   EA_CMD_BLOCK_t *next_cb_p = NULL;
   uint16_t length;
   short int encLen;
   short int packetLen;
   N8_Buffer_t *res_p = NULL;
   uint32_t     res_a;
   N8_Buffer_t *input_p = NULL;
   uint32_t     input_a;
   N8_Buffer_t *ctx_p = NULL;
   uint32_t     ctx_a = 0;
   int          nBytes;
   unsigned int numCommands = 0;
   unsigned int numCtxBytes = 0;
   N8_MemoryHandle_t *request_p;
   n8_ctxLoadFcn_t    ctxLoadFcn;
   n8_SSLTLSFcn_t     encryptFcn;

   do
   {
      /* verify the pointers passed in are not null */
      CHECK_OBJECT(packetObj_p, ret);
      CHECK_STRUCTURE(packetObj_p->structureID, N8_PACKET_STRUCT_ID, ret);
      CHECK_OBJECT(packet_p, ret);
      CHECK_OBJECT(result_p, ret);

      request_p = (N8_MemoryHandle_t *) request;

      /* Check that request_p & mode are consistent */
      if (request_p == NULL)
      {
         if (packetObj_p->mode != N8_PACKETMEMORY_NONE)
         {
            /* No request_p means mode should be "none" */
            ret = N8_INCONSISTENT;
            break;
         }
      }
      else if (packetObj_p->mode != N8_PACKETMEMORY_REQUEST)
      {
         /* They said they would give us a request and they didn't */
         ret = N8_INCONSISTENT;
         break;
      }

      /*
       * convert the length from network order to host order
       */
      length = SSLTLS_EXTRACT_LENGTH(packet_p);
      /* check to see the data length is within range
       * [0..N8_SSLTLS_MAX_DATA_SIZE_ENCRYPT] 
       */
      if (length > N8_SSLTLS_MAX_DATA_SIZE_ENCRYPT)
      {
         ret = N8_INVALID_INPUT_SIZE;
         break;
      }

      numCommands = packetObj_p->encCommands;
      if (packetObj_p->contextLoadNeeded == N8_TRUE)
      {
         numCommands += packetObj_p->ctxLoadCmds;
         numCtxBytes = NEXT_WORD_SIZE(sizeof(EA_ARC4_CTX));
      }

      /* create a kernel memory structure for temporarily storing the results */
      /* compute the lengths for the result packet */
      encLen = N8_ComputeEncryptedLength(length,
                                         packetObj_p->hashPacket.hashSize,
                                         packetObj_p->packetCipher); 
      packetLen = encLen + SSLTLS_HEADER_LEN;

      /* compute the total number of bytes in kernel space we need to allocate.
       * note we round up to the next word boundary. */
      /* Note that if the in packet is NULL, we don't check the out packet */
      if (request_p == NULL)
      {
         nBytes = (NEXT_WORD_SIZE(length) + /* input */
                   NEXT_WORD_SIZE(encLen) + /* output */
                   numCtxBytes);            /* size of context, if needed */
         /* create an API request buffer */
         ret = createEARequestBuffer(&req_p,
                                     packetObj_p->unitID,
                                     numCommands,
                                     resultHandlerSSLTLSEncrypt,
                                     nBytes); 
         CHECK_RETURN(ret);
         /* User has not provided a request buffer */
         res_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset);
         res_a = req_p->qr.physicalAddress + req_p->dataoffset;

         input_p = res_p + NEXT_WORD_SIZE(length);
         input_a = res_a + NEXT_WORD_SIZE(length);

         ctx_p = input_p + NEXT_WORD_SIZE(encLen);
         ctx_a = input_a + NEXT_WORD_SIZE(encLen);
      }
      else
      {
         /* The user has given us a request structure.  We just need to
            initialize it. */
         req_p = (API_Request_t *) request_p->VirtualAddress;
         initializeEARequestBuffer(req_p,
                                   request_p,
                                   packetObj_p->unitID,
                                   numCommands,
                                   resultHandlerSSLTLSEncrypt,
                                   N8_TRUE);

         /* User has provided a request packet, which must contain enough
            space for the input and output packets. The user may
            reuse the input pointer for the output. */
         input_p = (N8_Buffer_t *)((unsigned long) packet_p + SSLTLS_DATA_OFFSET);
         input_a = N8_VirtToPhys(input_p);

         res_p = (N8_Buffer_t *)((unsigned long) result_p + SSLTLS_DATA_OFFSET);
         res_a = N8_VirtToPhys(res_p);
         /* If we are loading context memory, we load it at the last 
            N8_CTX_BYTES before the data section */
         if (numCtxBytes > 0)
         {
            ctx_p = (N8_Buffer_t *)((unsigned long) req_p + sizeof(API_Request_t) + N8_COMMAND_BLOCK_BYTES);
            ctx_a = N8_VirtToPhys(ctx_p);
         }
      }

      next_cb_p = req_p->EA_CommandBlock_ptr;

      /* generate the command blocks necessary to load the context, if required */
      if (packetObj_p->contextLoadNeeded == N8_TRUE)
      {
         /* Generate the command blocks for the Context Load */
         ctxLoadFcn = (n8_ctxLoadFcn_t)packetObj_p->ctxLoadFcn;
         ret = ctxLoadFcn(req_p, 
                          next_cb_p,
                          packetObj_p,
                          &packetObj_p->cipherInfo, 
                          packetObj_p->packetHashAlgorithm,
                          ctx_p,
                          ctx_a,
                          &next_cb_p);
         CHECK_RETURN(ret);
         packetObj_p->contextLoadNeeded = N8_FALSE;
      }

      req_p->copyBackFrom_p = res_p;
      req_p->postProcessingData_p = (void *) packetObj_p;
      /* This sets up the offset for the start of the copy back of the IV */
      req_p->postProcessBuffer[0] = encLen - N8_DES_KEY_LENGTH;

      if (request_p == NULL)
      {
         memcpy(input_p, &packet_p[SSLTLS_DATA_OFFSET], length);
         req_p->copyBackTo_p = &result_p[SSLTLS_DATA_OFFSET];
         req_p->copyBackSize = encLen;
      }
      else
      {
         req_p->copyBackSize = 0;
      }

      /* Generate the command blocks for the Encrypt */
      encryptFcn = (n8_SSLTLSFcn_t)packetObj_p->SSLTLScmdFcn;
      ret = encryptFcn(next_cb_p,
                       packetObj_p,
                       packet_p,
                       input_a,
                       res_a,
                       packetObj_p->encOpCode);
      CHECK_RETURN(ret);

      /* set up the return packet.  note that this can be done before the
       * command is executed as it is only constant header information. */
      memcpy(&result_p[SSLTLS_TYPE_OFFSET],
             &packet_p[SSLTLS_TYPE_OFFSET],
             sizeof(uint8_t) + sizeof(uint16_t)); 
      SSLTLS_SET_LENGTH(result_p, encLen);

      QUEUE_AND_CHECK(event_p, req_p, ret);
      HANDLE_EVENT(event_p, req_p, ret);
   } while (FALSE);

   /* clean up if necessary.  note that if there is no error condition, the
    * request will be de-allocated in the result handler. */ 
   if (ret != N8_STATUS_OK)
   {
      freeRequest(req_p);
   }
   return ret;

} /* N8_SSLEncryptAuthenticateMemory */
Ejemplo n.º 18
0
void* handleConnection(void* aCon)
{
    connection con = *( (connection*) aCon );

    printf( "\nConnection with client %d established.", con );

    char* buffer;
    if ( readHttpRequest( con, &buffer ) != 0 ) {
        //printf( "\nError reading message." );
        sendHttpResponse( con, 500, ERROR_500 );
        end_contact( con );
        return 0;
    }

    struct Request req = parseRequest( buffer );

    printf( "\nReceived request from client:" );
    printRequestData( &req );

    if ( req.invalid != 0 ) {
        printf( "\nInvalid request: %s", buffer );
        sendHttpResponse( con, 400, ERROR_400 );
        freeRequest( &req );
        end_contact( con );
        return 0;
    }

    free( buffer );

    checkCommandValid( &req );

    if ( req.invalid != 0 ) {
        printf( "\nInvalid command: %s", req.command );
        sendHttpResponse( con, 405, ERROR_405 );
        freeRequest( &req );
        end_contact( con );
        return 0;
    }

    checkPathValid( &req );

    if ( req.invalid != 0 ) {
        printf( "\nInvalid path requested: %s", req.path );
        sendHttpResponse( con, 403, ERROR_403 );
        freeRequest( &req );
        end_contact( con );
        return 0;
    }

    getFullPath( &req );

    if ( req.invalid != 0 ) {
        printf( "\nUnknown file: %s", req.path );
        sendHttpResponse( con, 404, ERROR_404 );
        freeRequest( &req );
        end_contact( con );
        return 0;
    }

    FILE * fd = fopen( req.path, "r" );

    if( !fd )
    {
        printf( "\nCould not open file: %s", req.path );
        sendHttpResponse( con, 403, ERROR_403 );
        freeRequest( &req );
        end_contact( con );
        return 0;
    }

    if( sendHttpResponse( con, 200, STATUS_200 ) );
    {
        int num_bytes = 0;

        char * readbuf = malloc( 1024 );
        while( !feof( fd ) )
        {
            num_bytes = fread( readbuf, 1, 1, fd );
            if( num_bytes < 0 )
                break;

            if( write( con, readbuf, num_bytes ) < 0 )
                break;

        }

        write( con, "\r\n\r\n", 4 );
        fclose( fd );
        free( readbuf );
    }

    printf( "\nClosing Connection %d", con);
    end_contact( con );

    return 0;
}
Ejemplo n.º 19
0
/** @ingroup n8_ssltls
 * @brief Decrypt and verify an entire SSL or TLS message.
 *
 * Decrypt an verify a SSL or TLS message.  If the verification fails, it will
 * be noted in the return value.
 *
 *  @param packetObj_p         RW:  Pre-initialized packet object.
 *  @param packet_p            RO:  A complete, encrypted SSL or TLS packet
 *                                  including the header.
 *  @param computedMAC_p       RW:  Pointer to result space for the MAC
 *                                  computation output.
 *  @param verify_p:           WO:  Pointer to a verify flag.  If the MAC's
 *                                  match, the verify flag will be set to N8_TRUE.
 *  @param result_p            RW:  Pointer to result space for the decrypted
 *                                  result. 
 *  @param request             RW:  Kernel request buffer used when mode =
 *                                  N8_PACKETMEMORY_REQUEST.
 *  @param event_p             RW:  Asynchronous event pointer.
 *
 * @par Externals
 *    None
 *
 * @return
 *    Error condition if raised.
 *
 * @par Errors
 *    N8_MALLOC_FAILED<br>
 *    N8_INVALID_INPUT_SIZE - the value in the packet header is too large or too
 *                            small.<br>
 *    N8_INCONSISTENT       - the version number in the packet header does not
 *                            match the designation in the packet object.<br>
 *    N8_INVALID_OBJECT     - packet object is not a valid object initialized
 *                            for SSL or TLS<br>
 *    N8_INVALID_VALUE      - the value of the type field in the packet header
 *                            is not one of the legal values for SSL or TLS.<br>
 *
 * @par Assumptions
 *    The result_p and computedMAC_p pointers refer to pre-allocated space of
 * sufficient size.  The calling program retains responsibility for freeing this
 * memory. 
 *****************************************************************************/
N8_Status_t 
N8_SSLTLSDecryptVerifyMemory(N8_Packet_t             *packetObj_p,
                             const N8_SSLTLSPacket_t *packet_p,
                             N8_Buffer_t             *computedMAC_p,
                             N8_Boolean_t            *verify_p,
                             N8_SSLTLSPacket_t       *result_p,
                             N8_RequestHandle_t       request,
                             N8_Event_t              *event_p)
{

   N8_Status_t ret = N8_STATUS_OK;
   API_Request_t *req_p = NULL;
   EA_CMD_BLOCK_t *next_cb_p = NULL;
   N8_SSL_Post_Decrypt_Data_t *postData_p = NULL;
   uint16_t length;
   short int encLen;
   int nBytes;
   N8_Buffer_t *res_p = NULL;
   uint32_t     res_a;
   N8_Buffer_t *input_p = NULL;
   uint32_t     input_a;
   N8_Buffer_t *ctx_p = NULL;
   uint32_t     ctx_a = 0;
   unsigned int numCommands = 0;
   unsigned int numCtxBytes = 0;
   N8_MemoryHandle_t *request_p;
   n8_ctxLoadFcn_t  ctxLoadFcn;
   n8_SSLTLSFcn_t   decryptFcn;
   do
   {
      /* ensure none of the pointers we're given are null */
      CHECK_OBJECT(packetObj_p, ret);
      CHECK_STRUCTURE(packetObj_p->structureID, N8_PACKET_STRUCT_ID, ret);
      CHECK_OBJECT(packet_p, ret);
#ifdef N8_MAC_COPYBACK
      CHECK_OBJECT(computedMAC_p, ret);
#endif
      CHECK_OBJECT(result_p, ret);

      request_p = (N8_MemoryHandle_t *) request;

      /* Check that request_p & mode are consistent */
      if (request_p == NULL)
      {
         if (packetObj_p->mode != N8_PACKETMEMORY_NONE)
         {
            /* No request_p means mode should be "none" */
            ret = N8_INCONSISTENT;
            break;
         }
      }
      else if (packetObj_p->mode != N8_PACKETMEMORY_REQUEST)
      {
         /* They said they would give us a request and they didn't */
         ret = N8_INCONSISTENT;
         break;
      }

      /*
       * convert the length from network order to host order
       */
      length  = ntohs(*((uint16_t *) &packet_p[SSLTLS_LENGTH_OFFSET]));

      /* verify the length is not greater than the max */
      if (length > N8_SSLTLS_MAX_DATA_SIZE_DECRYPT)
      {
         ret = N8_INVALID_INPUT_SIZE;
         break;
      }

      numCommands = packetObj_p->decCommands;
      if (packetObj_p->contextLoadNeeded == N8_TRUE)
      {
         numCommands += packetObj_p->ctxLoadCmds;
         numCtxBytes = NEXT_WORD_SIZE(sizeof(EA_ARC4_CTX));
      }

      encLen = N8_ComputeEncryptedLength(length, 
                                         packetObj_p->hashPacket.hashSize,
                                         packetObj_p->packetCipher);

      /* kernel space is needed for the data portion of the incoming packet plus
       * the hash and padding.  the exact amount is needed for the return
       * packet. */
      /* Note that if the in packet is NULL, we don't check the out packet */
      if (request_p == NULL)
      {
         nBytes = NEXT_WORD_SIZE(length) * 2 + numCtxBytes;
         /* create an API request buffer */
         ret = createEARequestBuffer(&req_p,
                                     packetObj_p->unitID,
                                     numCommands,
                                     resultHandlerSSLTLSDecrypt,
                                     nBytes); 
         CHECK_RETURN(ret);
         /* User has not provided any buffers */
         res_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset);
         res_a = req_p->qr.physicalAddress + req_p->dataoffset;

         input_p = res_p + NEXT_WORD_SIZE(length);
         input_a = res_a + NEXT_WORD_SIZE(length);

         ctx_p = input_p + NEXT_WORD_SIZE(encLen);
         ctx_a = input_a + NEXT_WORD_SIZE(encLen);
      }
      else
      {
         /* User has provided a request packet, which must contain enough
            space for the input and output packets. The user may
            reuse the input pointer for the output. */

         /* The user has given us a request structure.  We just need to
            initialize it. */
         req_p = (API_Request_t *) request_p->VirtualAddress;
         initializeEARequestBuffer(req_p,
                                   request_p,
                                   packetObj_p->unitID,
                                   numCommands,
                                   resultHandlerSSLTLSDecrypt,
                                   N8_TRUE);

         /* Initialize input_p and input_a to the beginning of
            data area in the request */
         input_p = (N8_Buffer_t *)((unsigned long) packet_p + SSLTLS_DATA_OFFSET);
         input_a = N8_VirtToPhys(input_p);


         res_p = result_p + SSLTLS_DATA_OFFSET;
         res_a = N8_VirtToPhys(res_p);

         /* If we are loading context memory, we load it at the last 
            N8_CTX_BYTES before the data section */
         if (numCtxBytes > 0)
         {
            ctx_p = (N8_Buffer_t *)((unsigned long) req_p + sizeof(API_Request_t) + N8_COMMAND_BLOCK_BYTES);
            ctx_a = N8_VirtToPhys(ctx_p);
         }
      }

      next_cb_p = req_p->EA_CommandBlock_ptr;

      /* generate the command blocks necessary to load the context, if required */
      if (packetObj_p->contextLoadNeeded == N8_TRUE)
      {
         /* Generate the command blocks for the Context Load */
         ctxLoadFcn = (n8_ctxLoadFcn_t)packetObj_p->ctxLoadFcn;
         ret = ctxLoadFcn(req_p, 
                          req_p->EA_CommandBlock_ptr,
                          packetObj_p,
                          &packetObj_p->cipherInfo, 
                          packetObj_p->packetHashAlgorithm,
                          ctx_p,
                          ctx_a,
                          &next_cb_p);
         CHECK_RETURN(ret);
         packetObj_p->contextLoadNeeded = N8_FALSE;
      }

      /* copy the data portion of the incoming packet into the input kernel
       * buffer */
      if (request_p == NULL)
      {
         memcpy(input_p, &packet_p[SSLTLS_DATA_OFFSET], length);
      }

      /* use the post processing structure in the API Request */
      postData_p = (N8_SSL_Post_Decrypt_Data_t *)&req_p->postProcessBuffer;

      /* now check the length */
      if (length < packetObj_p->minLength)
      {
         ret = N8_INVALID_INPUT_SIZE;
         break;
      }

      /* if des, ensure the length is a multiple of N8_DES_BLOCK_MULTIPLE */
      if ((packetObj_p->packetCipher == N8_CIPHER_DES) &&
          ((length % N8_DES_BLOCK_MULTIPLE) != 0))
      {
         ret = N8_INVALID_INPUT_SIZE;
         break;
      }

      /* set up the copy back for the result packet.  we only copy back the data
       * portion which we get from the kernel buffer. */
      req_p->copyBackTo_p = &result_p[SSLTLS_DATA_OFFSET];
      req_p->copyBackFrom_p = res_p;
      /* the length the decrypted data is not known until after the operation is
       * run.  we will calculate it in the resultHandler.  set the copyBackSize
       * to zero as a safe thing to do.*/
      req_p->copyBackSize = 0;

      if (packetObj_p->contextHandle.inUse == N8_FALSE)
      {
         /* This sets up the offset for the start of the copy back of the IV. 
            This case can only occur if the cipher is DES, not ARC4 */
         memcpy(&postData_p->nextIV, 
                &(packet_p[5 - N8_DES_KEY_LENGTH + length]),
                N8_DES_KEY_LENGTH);
      }

      /* set up the post processing data */
      postData_p->macLength = packetObj_p->macLength;
      postData_p->computedMAC_p = computedMAC_p;
      postData_p->packetObj_p = packetObj_p;
      postData_p->verify_p = verify_p;
      postData_p->encryptedLength = length;
      if (request_p == NULL)
      {
         postData_p->copyData = N8_TRUE;
      }
      else
      {
         postData_p->copyData = N8_FALSE;
      }
      postData_p->resultPacket_p = result_p;

      /* tell the Queue Manager to copy back the command block results */
      req_p->copyBackCommandBlock = N8_TRUE;
      req_p->postProcessingData_p = (void *) postData_p;

      /* Generate the command blocks for the Decrypt */
      decryptFcn = (n8_SSLTLSFcn_t)packetObj_p->SSLTLScmdFcn;
      ret = decryptFcn(next_cb_p,
                       packetObj_p,
                       packet_p,
                       input_a,
                       res_a,
                       packetObj_p->decOpCode);
      CHECK_RETURN(ret);

      /* set up the return packet 
       * again, recall we cannot set the length in the result packet now and
       * will have to do it in the result handler. */
      memcpy(&result_p[SSLTLS_TYPE_OFFSET],
             &packet_p[SSLTLS_TYPE_OFFSET],
             sizeof(uint8_t) + sizeof(uint16_t));

      QUEUE_AND_CHECK(event_p, req_p, ret);
      HANDLE_EVENT(event_p, req_p, ret);
   } while (FALSE);

   /* clean up if necessary.  note that if there is no error condition, the post
    * data and request will be de-allocated in the result handler. */
   if (ret != N8_STATUS_OK)
   {
      freeRequest(req_p);
   }
   return ret;
} /* N8_SSLTLSDecryptVerify */