Example #1
0
void ssh_xfree(void *ptr)
{
#ifdef SSH_DEBUG_MALLOC
  if (ptr != NULL)
    {
      unsigned long size;

      if (SSH_GET_32BIT((unsigned char *) ptr - 4) !=
          SSH_DEBUG_MALLOC_MAGIC_IN_USE)
        {
          if (SSH_GET_32BIT((unsigned char *) ptr - 4) ==
              SSH_DEBUG_MALLOC_MAGIC_FREED)
            ssh_fatal("Freeing block that is already freed");
          ssh_fatal("Freeing block that is either not mallocated, or whose magic number before the object was overwritten");
        }

      size = SSH_GET_32BIT((unsigned char *) ptr -
                           SSH_DEBUG_MALLOC_SIZE_BEFORE);
      if (SSH_GET_32BIT((unsigned char *) ptr + size) !=
          SSH_DEBUG_MALLOC_MAGIC_AFTER)
        ssh_fatal("Freeing block whose magic number after the object was overwritten");

      /* Mark the old block freed */
      SSH_PUT_32BIT((unsigned char *) ptr - 4, SSH_DEBUG_MALLOC_MAGIC_FREED);
      SSH_PUT_32BIT((unsigned char *) ptr + size,
                    SSH_DEBUG_MALLOC_MAGIC_FREED);
      free((unsigned char *) ptr - SSH_DEBUG_MALLOC_SIZE_BEFORE);
    }
#else /* SSH_DEBUG_MALLOC */
  if (ptr != NULL)
    free(ptr);
#endif /* SSH_DEBUG_MALLOC */
}
Example #2
0
void gcm_update_block(void *context, const unsigned char *buf)
{
  SshGCMCtx *ctx = (SshGCMCtx *)context;
  SshUInt32 *X = ctx->X;

  X[0] ^= SSH_GET_32BIT(buf);
  X[1] ^= SSH_GET_32BIT(buf + 4);
  X[2] ^= SSH_GET_32BIT(buf + 8);
  X[3] ^= SSH_GET_32BIT(buf + 12);

  ssh_gf2n_128_mul(X, ctx->H, ctx->mod);
}
Example #3
0
void gcm_update_block_words_table(void *context, const unsigned char *buf)
{
  SshGCMCtx *ctx = (SshGCMCtx *)context;
  SshUInt32 *m = ctx->workspace;
  SshUInt32 *X = ctx->X;
  SshUInt32 t[4], i;

  X[0] ^= SSH_GET_32BIT(buf);
  X[1] ^= SSH_GET_32BIT(buf + 4);
  X[2] ^= SSH_GET_32BIT(buf + 8);
  X[3] ^= SSH_GET_32BIT(buf + 12);

  t[0] = t[1] = t[2] = t[3] = 0;

  i = 0;
#ifdef MINIMAL_STACK
  while (i < 16)
    {
      GF2N_128_TABLE_BYTE_MUL(t, X, m, i);
      GF2N_128_TABLE_BYTE_MUL(t, X, m, i + 1);
      GF2N_128_TABLE_BYTE_MUL(t, X, m, i + 2);
      GF2N_128_TABLE_BYTE_MUL(t, X, m, i + 3);
      i += 4;
    }
#else  /* MINIMAL_STACK */
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 0);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 1);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 2);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 3);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 4);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 5);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 6);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 7);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 8);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 9);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 10);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 11);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 12);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 13);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 14);
  GF2N_128_TABLE_BYTE_MUL(t, X, m, 15);
#endif /* MINIMAL_STACK */

  X[0] = t[0];
  X[1] = t[1];
  X[2] = t[2];
  X[3] = t[3];
}
Example #4
0
/* Format time string in RFC-2550 compatible format as snprintf renderer. The
   datum points to the memory buffer having the 32-bit long time in seconds
   from the epoch in the network byte order. */
int ssh_time32buf_render(unsigned char *buf, int buf_size, int precision,
		    void *datum)
{
  unsigned char *ptr = datum;
  int len;

  len = ssh_time_format(buf, buf_size + 1, SSH_GET_32BIT(ptr));
  if (len + 1 >= buf_size)
    return buf_size + 1;
  return len;
}
Example #5
0
File: t-tr.c Project: AnthraX1/rk
SshBuffer *handler_input_cross(Handler c)
{
  int len;
  unsigned char *cp;
  SshBuffer *packet;
  
  packet = c->incoming;
  if (packet == NULL)
    {
      /* No partial packet already received; initialize for receiving packet
         header. */
      packet = ssh_buffer_allocate();
      c->incoming = packet;
      c->incoming_offset = 0;
      c->incoming_len = 4;
      ssh_buffer_append_space(packet, &cp, c->incoming_len);
    }

keep_reading:
  /* Keep reading until either entire header or entire packet received
     (determined by incoming_len).  Space has already been allocated
     in the buffer. */
  while (c->incoming_offset < c->incoming_len)
    {
      len = c->incoming_len - c->incoming_offset;
      cp = ssh_buffer_ptr(packet);
      cp += c->incoming_offset;
      len = ssh_stream_read(c->stream, cp, len);
      if (len < 0)
        return NULL;
      if (len == 0)
        ssh_fatal("%s: handler_input_cross: received unexpected eof", c->side);
      c->incoming_offset += len;
    }

  /* If this was the header received, read the rest of the packet if there
     is non-zero length payload. */
  if (c->incoming_len == 4 && c->incoming_offset == 4)
    {
      cp = ssh_buffer_ptr(packet);
      c->incoming_len = 4 + SSH_GET_32BIT(cp);
      if (c->incoming_len > 4)
        {
          ssh_buffer_append_space(packet, &cp, c->incoming_len - 4);
          goto keep_reading;
        }
    }

  /* The entire packet has been received.  Return it. */
  c->incoming = NULL;
  cp = ssh_buffer_ptr(packet);

  return packet;
}
static int
ssh_appgw_http_unmarshal_int(SshBuffer buf, int *result)
{
  if (ssh_buffer_len(buf) < 4)
    {
      *result = 0;
      return 0;
    }

  *result = (int)(SSH_GET_32BIT(ssh_buffer_ptr(buf)));
  ssh_buffer_consume(buf,4);
  return 1;
}
Example #7
0
void ssh_engine_tcp_init(SshEngine engine, SshEngineFlowData flow)
{
#ifdef SSH_IPSEC_TCP_SEQUENCE_RANDOMIZER
  SshUInt8 tmp[4];
#endif /* SSH_IPSEC_TCP_SEQUENCE_RANDOMIZER */

  SSH_DEBUG(SSH_D_LOWOK, ("initializing tcpdata"));

  flow->u.tcp.state = SSH_ENGINE_TCP_INITIAL;
#ifdef SSH_IPSEC_TCP_SEQUENCE_RANDOMIZER
  if (flow->data_flags & (SSH_ENGINE_FLOW_D_LOCAL_ENDPNT))
    {
      SSH_DEBUG(SSH_D_MY,
                ("flow has local endpoint: not randomizing sequence numbers"));
      flow->u.tcp.delta_i_to_r = 0;
      flow->u.tcp.delta_r_to_i = 0;
    }
  else
    {
      SSH_DEBUG(SSH_D_MY,
                ("flow has remote endpoints: setting random sequence deltas"));

      tmp[0] = ssh_engine_random_get_byte(engine);
      tmp[1] = ssh_engine_random_get_byte(engine);
      tmp[2] = ssh_engine_random_get_byte(engine);
      tmp[3] = ssh_engine_random_get_byte(engine);
      flow->u.tcp.delta_i_to_r = SSH_GET_32BIT(tmp);

      tmp[0] = ssh_engine_random_get_byte(engine);
      tmp[1] = ssh_engine_random_get_byte(engine);
      tmp[2] = ssh_engine_random_get_byte(engine);
      tmp[3] = ssh_engine_random_get_byte(engine);
      flow->u.tcp.delta_r_to_i = SSH_GET_32BIT(tmp);
    }
#endif /* SSH_IPSEC_TCP_SEQUENCE_RANDOMIZER */
}
Example #8
0
void mp_unlinearize_msb_first(SshInt *value, const unsigned char *buf,
                              unsigned int len)
{
  unsigned int i;
  ssh_mp_set_ui(value, 0);
  for (i = 0; i + 4 <= len; i += 4)
    {
      unsigned long limb = SSH_GET_32BIT(buf + i);
      ssh_mp_mul_2exp(value, value, 32);
      ssh_mp_add_ui(value, value, limb);
    }
  for (; i < len; i++)
    {
      ssh_mp_mul_2exp(value, value, 8);
      ssh_mp_add_ui(value, value, buf[i]);
    }
}
Example #9
0
void ssh_buf_to_mp_lsb(SshInt *x, const unsigned char *cp, size_t len)
{
  size_t i;
  unsigned long limb;

  ssh_mp_set_ui(x, 0);
  for (i = len - 3; i > 4; i -= 4)
    {
      limb = SSH_GET_32BIT(cp + i - 1);
      ssh_mp_mul_2exp(x, x, 32);
      ssh_mp_add_ui(x, x, limb);
    }
  for (; i > 0; i--)
    {
      ssh_mp_mul_2exp(x, x, 8);
      ssh_mp_add_ui(x, x, cp[i - 1]);
    }
}
Example #10
0
void ssh_buf_to_mp(SshInt *x, const unsigned char *cp, size_t len)
{
  size_t i;
  unsigned long limb;

  ssh_mp_set_ui(x, 0);
  for (i = 0; i + 4 <= len; i += 4)
    {
      limb = SSH_GET_32BIT(cp + i);
      ssh_mp_mul_2exp(x, x, 32);
      ssh_mp_add_ui(x, x, limb);
    }
  for (; i < len; i++)
    {
      ssh_mp_mul_2exp(x, x, 8);
      ssh_mp_add_ui(x, x, cp[i]);
    }
}
Example #11
0
/* Generate stateless cookie based on the secret, nonce,
   spi_i and ip-address. */
SshIkev2Error ikev2_generate_cookie(SshIkev2Packet packet,
				    SshIkev2Sa ike_sa,
				    unsigned char *notify_data,
				    size_t notify_len)
{
  SshCryptoStatus status;
  unsigned char buffer[16];
  SshMac mac;
  size_t len;

  SSH_DEBUG(SSH_D_LOWOK, ("Starting cookie generation for SA %p", ike_sa));
  packet->ed->ike_ed->cookie_len = 4 +
    ssh_mac_length(IKEV2_COOKIE_MAC_ALGORITHM);
  packet->ed->ike_ed->cookie =
    ssh_obstack_alloc(packet->ed->obstack,
		      packet->ed->ike_ed->cookie_len);
  if (packet->ed->ike_ed->cookie == NULL)
    {
      SSH_DEBUG(SSH_D_ERROR, ("Error: Out of memory allocating cookie"));
      return SSH_IKEV2_ERROR_OUT_OF_MEMORY;
    }

  if (notify_len > 4 && notify_data != NULL &&
      SSH_GET_32BIT(notify_data) ==
      ike_sa->server->context->cookie_version_number - 1)
    {
      ike_sa->server->context->cookie_secret_use_counter_prev++;
      SSH_PUT_32BIT(packet->ed->ike_ed->cookie,
		    ike_sa->server->context->cookie_version_number - 1);
      status = ssh_mac_allocate(IKEV2_COOKIE_MAC_ALGORITHM,
				ike_sa->server->context->cookie_secret_prev,
				IKEV2_COOKIE_SECRET_LEN, &mac);
    }
  else
    {
      ike_sa->server->context->cookie_secret_use_counter++;
      SSH_PUT_32BIT(packet->ed->ike_ed->cookie,
		    ike_sa->server->context->cookie_version_number);
      status = ssh_mac_allocate(IKEV2_COOKIE_MAC_ALGORITHM,
				ike_sa->server->context->cookie_secret,
				IKEV2_COOKIE_SECRET_LEN, &mac);
    }
  if (status != SSH_CRYPTO_OK)
    {
      SSH_DEBUG(SSH_D_ERROR, ("Error: ssh_mac_allocate(%s) failed: %s",
			      IKEV2_COOKIE_MAC_ALGORITHM,
			      ssh_crypto_status_message(status)));
      return SSH_IKEV2_ERROR_OUT_OF_MEMORY;
    }

  ssh_mac_reset(mac);
  ssh_mac_update(mac, packet->ed->nonce->nonce_data,
		 packet->ed->nonce->nonce_size);
  SSH_IP_ENCODE(packet->remote_ip, buffer, len);
  ssh_mac_update(mac, buffer, len);
  ssh_mac_update(mac, packet->ike_spi_i, 8);
  status = ssh_mac_final(mac, packet->ed->ike_ed->cookie + 4);
  ssh_mac_free(mac);
  if (status != SSH_CRYPTO_OK)
    {
      SSH_DEBUG(SSH_D_ERROR, ("Error: ssh_mac_final(%s) failed: %s",
			      IKEV2_COOKIE_MAC_ALGORITHM,
			      ssh_crypto_status_message(status)));
      return SSH_IKEV2_ERROR_CRYPTO_FAIL;
    }
#ifdef SSH_IKEV2_CRYPTO_KEY_DEBUG
  SSH_DEBUG_HEXDUMP(SSH_D_DATADUMP,
		    ("Cookie generated"),
		    packet->ed->ike_ed->cookie,
		    packet->ed->ike_ed->cookie_len);
#endif /* SSH_IKEV2_CRYPTO_KEY_DEBUG */
  return SSH_IKEV2_ERROR_OK;
}
Example #12
0
Boolean ssh_packet_wrapper_input(SshPacketWrapper down)
{
  size_t data_to_read, data_read;
  int ret;
  unsigned char *ptr;
  SshPacketType type;
  Boolean return_value = FALSE;

  for (;;)
    {
      /* If we cannot receive, return immediately. */
      if (!down->can_receive || down->incoming_eof || down->destroy_pending ||
          down->shortcircuit_up_stream != NULL)
        return return_value;

      /* Get length of data read so far. */
      data_read = ssh_buffer_len(&down->incoming);

      /* Add enough space to buffer for reading either header or
         entire packet.  This also sets `ptr' to point to the place
         where data should be read, and `data_to_read' to the number
         of bytes that should be there after reading (should read
         data_to_read - data_read bytes). */
      if (data_read < 4)
        {
          /* Packet header not yet in buffer.  Read only header. */
          data_to_read = 4;
          ssh_buffer_append_space(&down->incoming, &ptr, 4 - data_read);
        }
      else
        {
          /* Packet header already in buffer. */
          ptr = ssh_buffer_ptr(&down->incoming);
          data_to_read = 4 + SSH_GET_32BIT(ptr);
          if (data_to_read > 100000000L)
            ssh_fatal("ssh_packet_wrapper_input: "
                      "invalid packet received: len %ld",
                      (long)data_to_read);
          SSH_ASSERT(data_to_read > data_read);
          ssh_buffer_append_space(&down->incoming, &ptr,
                                  data_to_read - data_read);
        }

      /* Keep reading until entire packet read, or no more data available. */
      while (data_read < data_to_read)
        {
          /* Try to read the remaining bytes. */
          ptr = (unsigned char *)ssh_buffer_ptr(&down->incoming) + data_read;
          ret = ssh_stream_read(down->stream, ptr, data_to_read - data_read);
          if (ret < 0)
            {
              /* No more data available at this time.  Remove
                 allocated but unread space from end of buffer. */
              ssh_buffer_consume_end(&down->incoming,
                                     data_to_read - data_read);
              return return_value;
            }

          if (ret == 0)
            {
              /* EOF received. */
              ssh_buffer_consume_end(&down->incoming,
                                     data_to_read - data_read);
              down->incoming_eof = TRUE;

              /* Pass the EOF to the application callback. */
              down->cannot_destroy = TRUE;
              if (down->received_eof)
                (*down->received_eof)(down->context);
              down->cannot_destroy = FALSE;
              if (down->destroy_requested)
                {
                  ssh_packet_wrapper_destroy(down);
                  return FALSE;
                }
              return TRUE;
            }

          if (data_read < 4 && data_read + ret >= 4)
            {
              /* Header has now been fully received.  Prepare to receive rest
                 of packet. */
              data_read += ret;
              ptr = ssh_buffer_ptr(&down->incoming);
              data_to_read = 4 + SSH_GET_32BIT(ptr);
              if (data_to_read > 100000000L)
                ssh_fatal("ssh_packet_wrapper_input: "
                          "invalid packet received: len %ld",
                          (long)data_to_read);
              if (data_to_read > data_read)
                ssh_buffer_append_space(&down->incoming, &ptr,
                                    data_to_read - data_read);
            }
          else
            data_read += ret;
        }

      /* An entire packet has been received. */
      SSH_ASSERT(ssh_buffer_len(&down->incoming) == data_to_read);

      /* Get packet type. */
      ptr = ssh_buffer_ptr(&down->incoming);
      type = (SshPacketType)ptr[4];

      /* Call the application callback if set. */
      down->cannot_destroy = TRUE;
      if (down->received_packet)
        (*down->received_packet)(type, ptr + 5, data_to_read - 5,
                                 down->context);
      down->cannot_destroy = FALSE;
      if (down->destroy_requested)
        {
          ssh_packet_wrapper_destroy(down);
          return FALSE;
        }
      ssh_buffer_clear(&down->incoming);

      return_value = TRUE;
    }
  /*NOTREACHED*/
}
Example #13
0
static Boolean
ssh_engine_tcp_option_parse(SshUInt8 option_type,
                            const unsigned char *buffer,
                            size_t buf_len,
                            SshTcpOption option_return)
{
  SshUInt8 opt_len = 0;

  SSH_ASSERT(buffer != NULL);
  SSH_ASSERT(buf_len > 0);
  SSH_ASSERT(option_return != NULL);

  while (buf_len)
    {
      SshUInt8 kind = SSH_GET_8BIT(buffer);

      switch (kind)
        {
        case SSH_TCPOPT_EOL:
          goto not_found;

        case SSH_TCPOPT_NOP:
          opt_len = 1;
          break;

        case SSH_TCPOPT_MSS:
          if (buf_len < 4)
            goto invalid_len;

          opt_len = SSH_GET_8BIT(buffer+1);
          if (opt_len != 4)
            goto invalid_len;

          if (option_type == kind)
            {
              option_return->u.mss = SSH_GET_16BIT(buffer+2);
              SSH_DEBUG(SSH_D_MY5, ("MSS = %u", option_return->u.mss));
              return TRUE;
            }
          break;

        case SSH_TCPOPT_WS:
          if (buf_len < 3)
            goto invalid_len;

          opt_len = SSH_GET_8BIT(buffer+1);
          if (opt_len != 3)
            goto invalid_len;

          if (option_type == kind)
            {
              option_return->u.ws = SSH_GET_8BIT(buffer+2);
              SSH_DEBUG(SSH_D_MY5,
                        ("Window scale factor = %u", option_return->u.ws));
              return TRUE;
            }
          break;

        case SSH_TCPOPT_TS:
          if (buf_len <= 10)
            goto invalid_len;

          opt_len = SSH_GET_8BIT(buffer+1);
          if (opt_len != 10)
            goto invalid_len;

          if (option_type == kind)
            {
              option_return->u.ts.ts = SSH_GET_32BIT(buffer+2);
              option_return->u.ts.ts_reply = SSH_GET_32BIT(buffer+6);
              SSH_DEBUG(SSH_D_MY5,
                        ("Timestamp=%lu, Timestamp_reply=%ul",
                         option_return->u.ts.ts,
                         option_return->u.ts.ts_reply));
              return TRUE;
            }
          break;

        default:
          if (buf_len < 2)  /* At least 'kind' and 'len' fields */
            goto invalid_len;
          opt_len = SSH_GET_8BIT(buffer+1);
          if (opt_len >= buf_len)
            goto invalid_len;
          break;
        }

      SSH_ASSERT(buf_len >= opt_len);

      buffer += opt_len;
      buf_len -= opt_len;
    }

 not_found:

  SSH_DEBUG(SSH_D_MY, ("TCP option (%u) not found", option_type));
  return FALSE;

 invalid_len:

  SSH_DEBUG(SSH_D_NETGARB, ("Invalid TCP option length!"));
  return FALSE;
}
void
ikev2_fb_sa_handler(SshIkeNegotiation negotiation,
		    SshIkePMPhaseQm pm_info,
		    int number_of_sas, SshIkeIpsecSelectedSA sas,
		    SshIkeIpsecKeymat keymat,
		    void *sa_callback_context)
{
  SshIkev2FbNegotiation neg;

  neg = SSH_IKEV2_FB_QM_GET_P1_NEGOTIATION(pm_info);
  if (neg == NULL)
    return;

  neg->ike_sa->last_input_stamp = ssh_time();

  SSH_DEBUG(SSH_D_LOWOK, ("SA handler entered, IKE SA %p (neg %p)",
			  pm_info->phase_i->policy_manager_data, neg));

  if (number_of_sas != 1)
    {
      SSH_DEBUG(SSH_D_FAIL, ("Quick-Mode does not result in one bundle"));
      goto error;
    }

  if (neg->ed->callback)
    {
      int i, iproto;
      SshIkev2PayloadTransform *t;
      SshIkeIpsecSelectedProtocol p;
      SshIkeIpsecAttributeEncapsulationModeValues encap;

      /* Assert that `neg->qm_info' is set correctly. */
      SSH_ASSERT(neg->qm_info == pm_info);

      for (i = 0; i < SSH_IKEV2_TRANSFORM_TYPE_MAX; i++)
	neg->ed->ipsec_ed->ipsec_sa_transforms[i] = &neg->transforms[i];

      /* Fill in the selected transforms into ipsec_ed */

      t = neg->ed->ipsec_ed->ipsec_sa_transforms;

      for (iproto = 0; iproto < sas[0].number_of_protocols; iproto++)
	{
	  p = &sas[0].protocols[iproto];
	  if (p->protocol_id == SSH_IKE_PROTOCOL_IPSEC_ESP)
	    {
	      t[SSH_IKEV2_TRANSFORM_TYPE_ENCR]->id =
		ikev2_fb_v1_esp_id_to_v2_id(p->transform_id.generic);
	      if (p->attributes.key_length)
		t[SSH_IKEV2_TRANSFORM_TYPE_ENCR]->transform_attribute =
		  (0x800e << 16) | p->attributes.key_length;

	      if (p->attributes.auth_algorithm)
		t[SSH_IKEV2_TRANSFORM_TYPE_INTEG]->id =
		  ikev2_fb_v1_auth_id_to_v2_id(p->attributes.auth_algorithm);
	      else
		t[SSH_IKEV2_TRANSFORM_TYPE_INTEG] = NULL;
	    }
	  else if (p->protocol_id == SSH_IKE_PROTOCOL_IPSEC_AH)
	    {
	      t[SSH_IKEV2_TRANSFORM_TYPE_INTEG]->id =
		ikev2_fb_v1_ah_id_to_v2_id(p->transform_id.generic);
	      t[SSH_IKEV2_TRANSFORM_TYPE_ENCR] = NULL;
	    }
	  else if (p->protocol_id == SSH_IKE_PROTOCOL_IPCOMP)
	    {
	      if (p->spi_size_out == 2)
		{
		  int j;

		  for (j = 0; j < neg->ipcomp_num; j++)
		    {
		      if (neg->ipcomp_algs[j] == p->transform_id.ipcomp)
			{
			  neg->ipcomp_num = 1;
			  neg->ipcomp_algs[0] = p->transform_id.ipcomp;
			  neg->ipcomp_cpi_out[0] = SSH_GET_16BIT(p->spi_out);
			  break;
			}
		    }
		}
	    }

	  if (p->attributes.group_desc)
	    t[SSH_IKEV2_TRANSFORM_TYPE_D_H]->id = p->attributes.group_desc;
	  else
	    t[SSH_IKEV2_TRANSFORM_TYPE_D_H] = NULL;

	  t[SSH_IKEV2_TRANSFORM_TYPE_ESN]->id = (p->attributes.longseq_size)
	    ? SSH_IKEV2_TRANSFORM_ESN_ESN
	    : SSH_IKEV2_TRANSFORM_ESN_NO_ESN;

	  /* For initiator, notify policymanager about transport mode */
	  encap = p->attributes.encapsulation_mode;
	  if (encap == IPSEC_VALUES_ENCAPSULATION_MODE_TRANSPORT ||
	      encap == IPSEC_VALUES_ENCAPSULATION_MODE_UDP_TRANSPORT ||
	      encap == IPSEC_VALUES_ENCAPSULATION_MODE_UDP_DRAFT_TRANSPORT)
	    {
	      (void)
		ikev2_fb_construct_notify(neg,
					  0,
					  SSH_IKEV2_NOTIFY_USE_TRANSPORT_MODE,
					  TRUE,
					  0, NULL, 0, NULL);
	    }
	}

      if (neg->ipcomp_num > 0)
	{
	  for (i = 0; i < neg->ipcomp_num; i++)
	    {
	      unsigned char data[3];

	      SSH_PUT_16BIT(data, neg->ipcomp_cpi_out[i]);
	      data[2] = neg->ipcomp_algs[i];

	      (void)
		ikev2_fb_construct_notify(neg,
					  0,
					  SSH_IKEV2_NOTIFY_IPCOMP_SUPPORTED,
					  TRUE,
					  0, NULL, sizeof(data), data);
	    }
	}
    }

  /* Set the outbound SPI to the IPSec exchange data */
  if (sas->protocols[0].spi_size_out != 4)
    goto error;
  neg->ed->ipsec_ed->spi_outbound = SSH_GET_32BIT(sas->protocols[0].spi_out);

  SSH_DEBUG(SSH_D_LOWOK, ("Outbound SPI %lx",
			  (unsigned long) neg->ed->ipsec_ed->spi_outbound));

  if (!ikev2_fb_fill_keymat(neg->ed, negotiation, sas, keymat))
    {
      SSH_DEBUG(SSH_D_FAIL, ("Cannot generate IKEv2 keying material"));
      goto error;
    }

  SSH_IKEV2_FB_V2_CALL(neg, ipsec_sa_install)
    (neg->server->sad_handle, neg->ed, ikev2_fb_ipsec_sa_install_done, neg);
  return;

 error:

  /* Even in the case of error, we call the IKEv2 SA installation
     policy call. The key material is cleared to ensure the installation
     will fail at the policy manager. */
  ssh_free(neg->ed->ipsec_ed->ikev1_keymat);
  neg->ed->ipsec_ed->ikev1_keymat = NULL;
  neg->ed->ipsec_ed->ikev1_keymat_len = 0;

  SSH_IKEV2_FB_V2_CALL(neg, ipsec_sa_install)
    (neg->server->sad_handle, neg->ed, ikev2_fb_ipsec_sa_install_done, neg);
}
Example #15
0
int ssh_packet_impl_write(void *context, const unsigned char *buf,
                          size_t size)
{
  SshPacketImpl up = (SshPacketImpl)context;
  size_t offset, payload_len, len;
  unsigned char *ucp;

  /* If shortcircuiting, direct the write down. */
  if (up->shortcircuit_stream)
    {
      SSH_ASSERT(ssh_buffer_len(&up->incoming) == 0);
      return ssh_stream_write(up->shortcircuit_stream, buf, size);
    }

  offset = 0;

normal:
  while (up->can_receive && !up->incoming_eof && offset < size &&
         !up->shortcircuit_stream)
    {
      /* If already processing a partial packet, continue it now. */
      if (ssh_buffer_len(&up->incoming) > 0)
        goto partial;

      /* If only partial packet available, do special proccessing. */
      if (size - offset < 4)
        goto partial;  /* Need partial packet processing. */
      payload_len = SSH_GET_32BIT(buf + offset);
      if (payload_len < 1)
        goto partial;

      if (size - offset < 4 + payload_len)
        goto partial;  /* Need partial packet processing. */

      /* The entire packet is available; pass it to the callback. */
      if (up->received_packet)
        (*up->received_packet)((SshPacketType)buf[offset + 4],
                               buf + offset + 5, payload_len - 1, up->context);
      offset += 4 + payload_len;
    }
  /* We cannot take more data now.  If we processed some data, return
     the number of bytes processed. */
  if (offset > 0)
    return offset;

  /* We couldn't take any data.  Remember that we have returned error to
     the writer and must call the callback later. */
  up->up_write_blocked = TRUE;
  return -1;

partial:
  /* Process partial packet.  First we read its header. */
  len = ssh_buffer_len(&up->incoming);
  if (len < 4)
    {
      len = 4 - len;
      if (size - offset < len)
        len = size - offset;
      if (ssh_buffer_append(&up->incoming, buf + offset, len)
          != SSH_BUFFER_OK)
        {
          (*up->received_eof)(up->context);
          return 0;
        }

      offset += len;
    }
  if (ssh_buffer_len(&up->incoming) < 4)
    return offset;

  /* Get the length of the packet. */
  ucp = ssh_buffer_ptr(&up->incoming);
  payload_len = SSH_GET_32BIT(ucp);
  if (payload_len < 1)
    {
      /* Received an invalid packet with length = 0, even though we should
         always have at least the packet type. */
      (*up->received_eof)(up->context);
      return 0;
    }

  /* Add remaining data in the packet to the buffer. */
  len = 4 + payload_len - ssh_buffer_len(&up->incoming);
  if (len > size - offset)
    len = size - offset;
  if (ssh_buffer_append(&up->incoming, buf + offset, len)
      != SSH_BUFFER_OK)
    {
      (*up->received_eof)(up->context);
      return 0;
    }
  offset += len;

  /* If some data still not available, return. */
  if (ssh_buffer_len(&up->incoming) < 4 + payload_len)
    return offset;

  /* The entire packet is now in buffer. */
  ucp = ssh_buffer_ptr(&up->incoming);
  if (up->received_packet)
    (*up->received_packet)((SshPacketType)ucp[4], ucp + 5,
                           payload_len - 1,
                           up->context);

  /* Clear the incoming partial packet buffer and resume normal processing. */
  ssh_buffer_clear(&up->incoming);
  goto normal;
}
Example #16
0
SshCryptoStatus
ssh_gcm_init(void *context, const unsigned char *key, size_t keylen,
	     Boolean for_encryption, const SshCipherDefStruct *cipher_def,
	     size_t table_size)
{
  SshGCMCtx *created = context;
  SshCryptoStatus status;
  unsigned char encr_zero[16];
  unsigned char dummy_iv[16];
  int i;

  SSH_DEBUG(SSH_D_LOWOK, ("Entered"));

  memset(dummy_iv, 0, sizeof(dummy_iv));

  if (cipher_def->block_length != 16)
    {
      SSH_DEBUG(SSH_D_FAIL, ("Block sizes other than 128 bits not supported"));
      return SSH_CRYPTO_BLOCK_SIZE_ERROR;
    }

  memset(created, 0, sizeof(*created));
  created->for_encryption = (SshUInt8)for_encryption;

  created->cipher_def = cipher_def;
  created->cipher_context = (unsigned char *)created +
    sizeof(SshGCMCtx);

  status = (*created->cipher_def->init)(created->cipher_context, key, keylen, 
					TRUE);
  
  if (status == SSH_CRYPTO_OK)
    {

      memset(encr_zero, 0, sizeof(encr_zero));
      
      status = (*created->cipher_def->transform)(created->cipher_context, 
						 encr_zero,
						 encr_zero,
						 sizeof(encr_zero), 
						 dummy_iv);
    }

  if (status != SSH_CRYPTO_OK)
    {
#ifdef KERNEL
      SSH_DEBUG(SSH_D_FAIL, ("Cipher initialization failed status=%u",
			     (unsigned int)status));
#else /* !KERNEL */
      SSH_DEBUG(SSH_D_FAIL, ("Cipher transform failed status=%s",
			     ssh_crypto_status_message(status)));
#endif /* KERNEL */
      return status;
    }

 created->mod = (1 << 31) + (1 << 30) + (1 << 29) + (1 << 24);

 created->H[0] = SSH_GET_32BIT(encr_zero);
 created->H[1] = SSH_GET_32BIT(encr_zero + 4);
 created->H[2] = SSH_GET_32BIT(encr_zero + 8);
 created->H[3] = SSH_GET_32BIT(encr_zero + 12);
 
 switch (table_size)
   {
   case 0:
     created->update_block = gcm_update_block;
     created->workspace = NULL;
     break;

     case 65536:
       created->update_block = gcm_update_block_words_table;
       created->workspace = (unsigned char *)created + sizeof(SshGCMCtx) +
       (*cipher_def->ctxsize)();
     
      for (i = 0; i < 16; i++)
	ssh_gf2n_128_table_byte_init((unsigned char *)created->workspace + 
				     i * 256 * sizeof(SshUInt32[4]),
				     created->H, created->mod, i);
      created->table_64k = 1;
      break;

   case 8192:
     created->update_block = gcm_update_block_words_nibble;
     created->workspace = (unsigned char *)created + sizeof(SshGCMCtx) +
       (*cipher_def->ctxsize)();

     for (i = 0; i < 32; i++)
       ssh_gf2n_128_table_nibble_init((unsigned char *)created->workspace + 
				      i * 16 * sizeof(SshUInt32[4]), 
				      created->H, created->mod, i);
     created->table_8k = 1;
     break;

   case 4096:
     created->update_block = gcm_update_block_shoup_8_bit;
     created->workspace = (unsigned char *)created + sizeof(SshGCMCtx) +
       (*cipher_def->ctxsize)();

     ssh_gf2n_128_table_byte_init(created->workspace,
				  created->H, created->mod, 0);
     created->table_4k = 1;
     break;

   case 256:
     created->update_block = gcm_update_block_shoup_4_bit;
     created->workspace = (unsigned char *)created + sizeof(SshGCMCtx) +
       (*cipher_def->ctxsize)();

     ssh_gf2n_128_table_nibble_init(created->workspace,
				    created->H, created->mod, 0);
     created->table_256 = 1;
     break;

   default:
     return SSH_CRYPTO_UNSUPPORTED;
   }
  return SSH_CRYPTO_OK;
}
Example #17
0
File: sha.c Project: AnthraX1/rk
static void sha_transform(SshSHAContext *context, const unsigned char *block)
{
  static SshUInt32 W[80];
  SshUInt32 a, b, c, d, e, f;

  a = context->A;
  b = context->B;
  c = context->C;
  d = context->D;
  e = context->E;

#if 1
  
  /* Unroll as much as one can, removing unneccessary copying etc.

     What actually happens is that the compiler must interleave all these
     operations some efficient way. On processors with only few registers
     it might be better to implement the table generation before actual
     'nonlinear' operations. On Intel processors that might be the case,
     although one never knows without trying. */

#define TABLE_IN(i)                  \
  W[i] = SSH_GET_32BIT(block); block += 4;

#define TABLE_MORE(i, t)                           \
  t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; \
  W[i] = ROLL_1(t);                                                  

#define NONLINEAR1(F, a, b, c, d, e, f, i) \
  TABLE_IN(i);         \
  f = ROLL_5(a);       \
  f += F(b, c, d);     \
  b = ROLL_30(b);      \
  f += e + W[i];

#define NONLINEAR2(F, a, b, c, d, e, f, i) \
  TABLE_MORE(i, f);    \
  f = ROLL_5(a);       \
  f += F(b, c, d);     \
  b = ROLL_30(b);      \
  f += e + W[i];
  
  NONLINEAR1(F1, a, b, c, d, e, f,  0);
  NONLINEAR1(F1, f, a, b, c, d, e,  1);
  NONLINEAR1(F1, e, f, a, b, c, d,  2);
  NONLINEAR1(F1, d, e, f, a, b, c,  3);
  NONLINEAR1(F1, c, d, e, f, a, b,  4);
  NONLINEAR1(F1, b, c, d, e, f, a,  5);
  NONLINEAR1(F1, a, b, c, d, e, f,  6);
  NONLINEAR1(F1, f, a, b, c, d, e,  7);
  NONLINEAR1(F1, e, f, a, b, c, d,  8);
  NONLINEAR1(F1, d, e, f, a, b, c,  9);
  NONLINEAR1(F1, c, d, e, f, a, b, 10);
  NONLINEAR1(F1, b, c, d, e, f, a, 11);
  NONLINEAR1(F1, a, b, c, d, e, f, 12);
  NONLINEAR1(F1, f, a, b, c, d, e, 13);
  NONLINEAR1(F1, e, f, a, b, c, d, 14);
  NONLINEAR1(F1, d, e, f, a, b, c, 15);
  NONLINEAR2(F1, c, d, e, f, a, b, 16);
  NONLINEAR2(F1, b, c, d, e, f, a, 17);
  NONLINEAR2(F1, a, b, c, d, e, f, 18);
  NONLINEAR2(F1, f, a, b, c, d, e, 19);
  
  NONLINEAR2(F2, e, f, a, b, c, d, 20);
  NONLINEAR2(F2, d, e, f, a, b, c, 21);
  NONLINEAR2(F2, c, d, e, f, a, b, 22);
  NONLINEAR2(F2, b, c, d, e, f, a, 23);
  NONLINEAR2(F2, a, b, c, d, e, f, 24);
  NONLINEAR2(F2, f, a, b, c, d, e, 25);
  NONLINEAR2(F2, e, f, a, b, c, d, 26);
  NONLINEAR2(F2, d, e, f, a, b, c, 27);
  NONLINEAR2(F2, c, d, e, f, a, b, 28);
  NONLINEAR2(F2, b, c, d, e, f, a, 29);
  NONLINEAR2(F2, a, b, c, d, e, f, 30);
  NONLINEAR2(F2, f, a, b, c, d, e, 31);
  NONLINEAR2(F2, e, f, a, b, c, d, 32);
  NONLINEAR2(F2, d, e, f, a, b, c, 33);
  NONLINEAR2(F2, c, d, e, f, a, b, 34);
  NONLINEAR2(F2, b, c, d, e, f, a, 35);
  NONLINEAR2(F2, a, b, c, d, e, f, 36);
  NONLINEAR2(F2, f, a, b, c, d, e, 37);
  NONLINEAR2(F2, e, f, a, b, c, d, 38);
  NONLINEAR2(F2, d, e, f, a, b, c, 39);
  
  NONLINEAR2(F3, c, d, e, f, a, b, 40);
  NONLINEAR2(F3, b, c, d, e, f, a, 41);
  NONLINEAR2(F3, a, b, c, d, e, f, 42);
  NONLINEAR2(F3, f, a, b, c, d, e, 43);
  NONLINEAR2(F3, e, f, a, b, c, d, 44);
  NONLINEAR2(F3, d, e, f, a, b, c, 45);
  NONLINEAR2(F3, c, d, e, f, a, b, 46);
  NONLINEAR2(F3, b, c, d, e, f, a, 47);
  NONLINEAR2(F3, a, b, c, d, e, f, 48);
  NONLINEAR2(F3, f, a, b, c, d, e, 49);
  NONLINEAR2(F3, e, f, a, b, c, d, 50);
  NONLINEAR2(F3, d, e, f, a, b, c, 51);
  NONLINEAR2(F3, c, d, e, f, a, b, 52);
  NONLINEAR2(F3, b, c, d, e, f, a, 53);
  NONLINEAR2(F3, a, b, c, d, e, f, 54);
  NONLINEAR2(F3, f, a, b, c, d, e, 55);
  NONLINEAR2(F3, e, f, a, b, c, d, 56);
  NONLINEAR2(F3, d, e, f, a, b, c, 57);
  NONLINEAR2(F3, c, d, e, f, a, b, 58);
  NONLINEAR2(F3, b, c, d, e, f, a, 59);
  
  NONLINEAR2(F4, a, b, c, d, e, f, 60);
  NONLINEAR2(F4, f, a, b, c, d, e, 61);
  NONLINEAR2(F4, e, f, a, b, c, d, 62);
  NONLINEAR2(F4, d, e, f, a, b, c, 63);
  NONLINEAR2(F4, c, d, e, f, a, b, 64);
  NONLINEAR2(F4, b, c, d, e, f, a, 65);
  NONLINEAR2(F4, a, b, c, d, e, f, 66);
  NONLINEAR2(F4, f, a, b, c, d, e, 67);
  NONLINEAR2(F4, e, f, a, b, c, d, 68);
  NONLINEAR2(F4, d, e, f, a, b, c, 69);
  NONLINEAR2(F4, c, d, e, f, a, b, 70);
  NONLINEAR2(F4, b, c, d, e, f, a, 71);
  NONLINEAR2(F4, a, b, c, d, e, f, 72);
  NONLINEAR2(F4, f, a, b, c, d, e, 73);
  NONLINEAR2(F4, e, f, a, b, c, d, 74);
  NONLINEAR2(F4, d, e, f, a, b, c, 75);
  NONLINEAR2(F4, c, d, e, f, a, b, 76);
  NONLINEAR2(F4, b, c, d, e, f, a, 77);
  NONLINEAR2(F4, a, b, c, d, e, f, 78);
  NONLINEAR2(F4, f, a, b, c, d, e, 79);

  /* Remember the correct order of rotated variables. */
  context->A += e;
  context->B += f;
  context->C += a;
  context->D += b;
  context->E += c;
  
#else
  
  /*

    Inefficient version (but actually not that slow, only slightly slower
    than the above one).

    */

  /* t is not currently defined so you need to define that if want to use
     these routines. */
  
  for (t = 0; t < 16; t++)
    {
      W[t] = SSH_GET_32BIT(block);
      block += 4;
    }

  for (t = 16; t < 80; t++)
    {
      f = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
      W[t] = ROLL_1(f);
    }

  for (t = 0; t < 80; t++)
    {
      f = ROLL_5(a);

      if (t < 40)
        {
          if (t < 20)
            f += F1(b, c, d);
          else
            f += F2(b, c, d);
        }
      else
        {
          if (t < 60)
            f += F3(b, c, d);
          else
            f += F4(b, c, d);
        }

      f += e + W[t];
      f &= 0xFFFFFFFFL;
      
      e = d;
      d = c;
      c = ROLL_30(b);
      b = a;
      a = f;
    }
  
  context->A += a;
  context->B += b;
  context->C += c;
  context->D += d;
  context->E += e;

#endif /* unrolled. */

  context->A &= 0xFFFFFFFFL;
  context->B &= 0xFFFFFFFFL;
  context->C &= 0xFFFFFFFFL;
  context->D &= 0xFFFFFFFFL;
  context->E &= 0xFFFFFFFFL;
}
Example #18
0
void *ssh_xrealloc(void *ptr, unsigned long new_size)
{
  void *new_ptr;

  if (ptr == NULL)
    return ssh_xmalloc(new_size);

  if (new_size > XMALLOC_MAX_SIZE)
    ssh_fatal("ssh_xrealloc: allocation too large (allocating %ld bytes)",
              (long)new_size);
  
  if (new_size == 0)
    new_size = 1;
#ifdef SSH_DEBUG_MALLOC
  if (SSH_GET_32BIT((unsigned char *) ptr - 4) !=
      SSH_DEBUG_MALLOC_MAGIC_IN_USE)
    {
      if (SSH_GET_32BIT((unsigned char *) ptr - 4) ==
          SSH_DEBUG_MALLOC_MAGIC_FREED)
        ssh_fatal("Reallocating block that is already freed");
      ssh_fatal("Reallocating block that is either not mallocated, or whose magic number before the object was overwritten");
    }
  else
    {
      unsigned long old_size;

      old_size = SSH_GET_32BIT((unsigned char *) ptr -
                               SSH_DEBUG_MALLOC_SIZE_BEFORE);
      if (SSH_GET_32BIT((unsigned char *) ptr + old_size) !=
          SSH_DEBUG_MALLOC_MAGIC_AFTER)
        ssh_fatal("Reallocating block whose magic number after the object was overwritten");

      /* Mark the old block freed */
      SSH_PUT_32BIT((unsigned char *) ptr - 4, SSH_DEBUG_MALLOC_MAGIC_FREED);
      SSH_PUT_32BIT((unsigned char *) ptr + old_size,
                    SSH_DEBUG_MALLOC_MAGIC_FREED);

      new_ptr = (void *)realloc((unsigned char *) ptr -
                                SSH_DEBUG_MALLOC_SIZE_BEFORE,
                                (size_t) new_size +
                                SSH_DEBUG_MALLOC_SIZE_BEFORE +
                                SSH_DEBUG_MALLOC_SIZE_AFTER);
      if (new_ptr == NULL)
        ssh_fatal("ssh_xrealloc: out of memory (new_size %ld bytes)",
                  (long)new_size);

      SSH_PUT_32BIT(new_ptr, new_size);
      SSH_PUT_32BIT((unsigned char *) new_ptr + 4,
                    SSH_DEBUG_MALLOC_MAGIC_IN_USE);
      SSH_PUT_32BIT((unsigned char *) new_ptr + new_size +
                    SSH_DEBUG_MALLOC_SIZE_BEFORE,
                    SSH_DEBUG_MALLOC_MAGIC_AFTER);
      new_ptr = (unsigned char *) new_ptr + SSH_DEBUG_MALLOC_SIZE_BEFORE;
    }
#else /* SSH_DEBUG_MALLOC */
  new_ptr = (void *)realloc(ptr, (size_t) new_size);
  if (new_ptr == NULL)
    ssh_fatal("ssh_xrealloc: out of memory (new_size %ld bytes)",
              (long)new_size);
#endif /* SSH_DEBUG_MALLOC */
  return new_ptr;
}
Example #19
0
void gcm_update_block_shoup_4_bit(void *context, const unsigned char *buf)
{
  SshGCMCtx *ctx = (SshGCMCtx *)context;
  SshUInt32 *m = ctx->workspace;
  SshUInt32 *X = ctx->X;
  SshUInt32 i, t[4];
  unsigned char w;
  
  X[0] ^= SSH_GET_32BIT(buf);
  X[1] ^= SSH_GET_32BIT(buf + 4);
  X[2] ^= SSH_GET_32BIT(buf + 8);
  X[3] ^= SSH_GET_32BIT(buf + 12);

  t[0] = t[1] = t[2] = t[3] = 0;

  i = 0;
#ifdef MINIMAL_STACK
  while (i < 28)
    {
      GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 31 - i);
      GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
      GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 30 - i);
      GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
      GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 29 - i);
      GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
      GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 28 - i);
      GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);

      i+= 4;
    }
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 3);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 2);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 1);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  /* No carry after the last multiplication */
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 0);
#else /* MINIMAL_STACK */

  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 31);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 30);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 29);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 28);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 27);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 26);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 25);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 24);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 23);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 22);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 21);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 20);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 19);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 18);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 17);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);

  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 16);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 15);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 14);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 13);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 12);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 11);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 10);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 9);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 8);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 7);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 6);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 5);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 4);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 3);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 2);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);

  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 1);
  GF2N_128_TABLE_SHOUP_4_BIT_MUL_POW(t, w);
  /* No carry after the last multiplication */
  GF2N_128_TABLE_SHOUP_4_BIT_MUL(t, X, m, 0);
#endif /* MINIMAL_STACK */


  X[0] = t[0];
  X[1] = t[1];
  X[2] = t[2];
  X[3] = t[3];
}
Example #20
0
/* This function reads complete payload from the HTTP stream described
   at the context argument (also the thread running this session is
   identified b the context's upper context), and calls the input
   processing thread when done. This gets called when the CA replies
   to the clients message or poll. */
static void
pkix_http_stream_callback(SshStreamNotification not, void *context)
{
  int i;
  size_t len;
  SshUInt8 type_or_version;
  unsigned char input[256], *data;
  PkixHttpReadContext c = (PkixHttpReadContext)context;
  SshFSMThread thread = (SshFSMThread) c->upper_context;
  SshPkiThreadData tdata = ssh_fsm_get_tdata(thread);
  SshPkiGlobalData gdata = ssh_fsm_get_gdata(thread);

  while (TRUE)
    {
      i = ssh_stream_read(c->http_stream, input, sizeof(input));
      if (i == 0)
        {
          if ((len = ssh_buffer_len(c->input)) > 5)
            {
              data = ssh_buffer_ptr(c->input);
              len = SSH_GET_32BIT(data);
              type_or_version = data[4];

              if (type_or_version < 10)
                {
                  tdata->input_version = SSH_PKI_VERSION_0;
                  tdata->input_flags = 0;
                  tdata->input_type = type_or_version;
                  tdata->input_len = len - 1;
                  tdata->input = ssh_memdup(data + 5, tdata->input_len);
                }
              else
                {
                  if (type_or_version == 10)
                    {
                      data += 4; /* skip to end of length */
                      tdata->input_version = SSH_PKI_VERSION_1;
                      tdata->input_len = len - 3;
                      tdata->input_flags = data[1];
                      tdata->input_type  = data[2];
                      data += 3;
                      tdata->input = ssh_memdup(data, tdata->input_len);
                    }
                  else
                    {
                      tdata->input_version = type_or_version;
                      tdata->input_type = SSH_PKI_MSG_ERRORREP;
                    }
                }

              if (tdata->input == NULL)
                tdata->input_type = SSH_PKI_MSG_ERRORREP;

              ssh_buffer_free(c->input);
              ssh_stream_destroy(c->http_stream);
              ssh_fsm_continue(gdata->input_thread);
              ssh_free(c);
              return;
            }
          else
            {
            error:
              tdata->input_type = SSH_PKI_MSG_ERRORREP;
              ssh_fsm_set_next(thread, pkix_aborted);
              ssh_fsm_continue(gdata->input_thread);
              ssh_stream_destroy(c->http_stream);
              ssh_buffer_free(c->input);
              ssh_free(c);
              return;
            }
        }
      else if (i < 0)
        {
          return;
        }
      else
        {
          if (ssh_buffer_append(c->input, input, i) != SSH_BUFFER_OK)
            {
              goto error;
            }
        }

    }
}