Пример #1
0
static enum _ecore_status_t ecore_mfw_update_tlvs(struct ecore_hwfn *p_hwfn,
						  u8 tlv_group, u8 *p_mfw_buf,
						  u32 size)
{
	union ecore_mfw_tlv_data *p_tlv_data;
	struct ecore_tlv_parsed_buf buffer;
	struct ecore_drv_tlv_hdr tlv;
	u32 offset;
	int len;
	u8 *p_tlv;

	p_tlv_data = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_tlv_data));
	if (!p_tlv_data)
		return ECORE_NOMEM;

	if (OSAL_MFW_FILL_TLV_DATA(p_hwfn,tlv_group, p_tlv_data)) {
		OSAL_VFREE(p_hwfn->p_dev, p_tlv_data);
		return ECORE_INVAL;
	}

	OSAL_MEMSET(&tlv, 0, sizeof(tlv));
	for (offset = 0; offset < size;
	     offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
		p_tlv = &p_mfw_buf[offset];
		tlv.tlv_type = TLV_TYPE(p_tlv);
		tlv.tlv_length = TLV_LENGTH(p_tlv);
		tlv.tlv_flags = TLV_FLAGS(p_tlv);

		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
			   "Type %d length = %d flags = 0x%x\n", tlv.tlv_type,
			   tlv.tlv_length, tlv.tlv_flags);

		if (tlv_group == ECORE_MFW_TLV_GENERIC)
			len = ecore_mfw_get_gen_tlv_value(&tlv, &p_tlv_data->generic, &buffer);
		else if (tlv_group == ECORE_MFW_TLV_ETH)
			len = ecore_mfw_get_eth_tlv_value(&tlv, &p_tlv_data->eth, &buffer);
		else if (tlv_group == ECORE_MFW_TLV_FCOE)
			len = ecore_mfw_get_fcoe_tlv_value(&tlv, &p_tlv_data->fcoe, &buffer);
		else
			len = ecore_mfw_get_iscsi_tlv_value(&tlv, &p_tlv_data->iscsi, &buffer);

		if (len > 0) {
			OSAL_WARN(len > 4 * tlv.tlv_length,
				  "Incorrect MFW TLV length %d, it shouldn't be greater than %d\n",
				  len, 4 * tlv.tlv_length);
			len = OSAL_MIN_T(int, len, 4 * tlv.tlv_length);
			tlv.tlv_flags |= ECORE_DRV_TLV_FLAGS_CHANGED;
			TLV_FLAGS(p_tlv) = tlv.tlv_flags;
			OSAL_MEMCPY(p_mfw_buf + offset + sizeof(tlv),
				    buffer.p_val, len);
		}
	}
Пример #2
0
int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
			void *tlv_data, int tlv_data_size)
{
	struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf);
	int new_tlv_space = TLV_SPACE(tlv_data_size);

	if (skb_tailroom(buf) < new_tlv_space)
		return 0;
	skb_put(buf, new_tlv_space);
	tlv->tlv_type = htons(tlv_type);
	tlv->tlv_len  = htons(TLV_LENGTH(tlv_data_size));
	if (tlv_data_size && tlv_data)
		memcpy(TLV_DATA(tlv), tlv_data, tlv_data_size);
	return 1;
}
Пример #3
0
static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len)
{
	struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(skb);

	if (tipc_skb_tailroom(skb) < TLV_SPACE(len))
		return -EMSGSIZE;

	skb_put(skb, TLV_SPACE(len));
	tlv->tlv_type = htons(type);
	tlv->tlv_len = htons(TLV_LENGTH(len));
	if (len && data)
		memcpy(TLV_DATA(tlv), data, len);

	return 0;
}
Пример #4
0
gpg_error_t
_ksba_keyinfo_to_sexp (const unsigned char *der, size_t derlen,
                       ksba_sexp_t *r_string)
{
  gpg_error_t err;
  int c;
  size_t nread, off, len, parm_off, parm_len;
  int parm_type;
  char *parm_oid = NULL;
  int algoidx;
  int is_bitstr;
  const unsigned char *parmder = NULL;
  size_t parmderlen = 0;
  const unsigned char *ctrl;
  const char *elem;
  struct stringbuf sb;

  *r_string = NULL;

  /* check the outer sequence */
  if (!derlen)
    return gpg_error (GPG_ERR_INV_KEYINFO);
  c = *der++; derlen--;
  if ( c != 0x30 )
    return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
  TLV_LENGTH(der);
  /* and now the inner part */
  err = get_algorithm (1, der, derlen, &nread, &off, &len, &is_bitstr,
                       &parm_off, &parm_len, &parm_type);
  if (err)
    return err;
  
  /* look into our table of supported algorithms */
  for (algoidx=0; pk_algo_table[algoidx].oid; algoidx++)
    {
      if ( len == pk_algo_table[algoidx].oidlen
           && !memcmp (der+off, pk_algo_table[algoidx].oid, len))
        break;
    }
  if (!pk_algo_table[algoidx].oid)
    return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
  if (!pk_algo_table[algoidx].supported)
    return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);

  if (parm_off && parm_len && parm_type == TYPE_OBJECT_ID)
    parm_oid = ksba_oid_to_str (der+parm_off, parm_len);
  else if (parm_off && parm_len)
    {
      parmder = der + parm_off;
      parmderlen = parm_len;
    }

  der += nread;
  derlen -= nread;

  if (is_bitstr)
    { /* Funny: X.509 defines the signature value as a bit string but
         CMS as an octet string - for ease of implementation we always
         allow both */
      if (!derlen)
        {
          xfree (parm_oid);
          return gpg_error (GPG_ERR_INV_KEYINFO);
        }
      c = *der++; derlen--;
      if (c) 
        fprintf (stderr, "warning: number of unused bits is not zero\n");
    }

  /* fixme: we should calculate the initial length form the size of the
     sequence, so that we don't need a realloc later */
  init_stringbuf (&sb, 100);
  put_stringbuf (&sb, "(10:public-key(");

  /* fixme: we can also use the oidstring here and prefix it with
     "oid." - this way we can pass more information into Libgcrypt or
     whatever library is used */
  put_stringbuf_sexp (&sb, pk_algo_table[algoidx].algo_string);

  /* Insert the curve name for ECC. */
  if (pk_algo_table[algoidx].pkalgo == PKALGO_ECC && parm_oid)
    {
      put_stringbuf (&sb, "(");
      put_stringbuf_sexp (&sb, "curve");
      put_stringbuf_sexp (&sb, parm_oid);
      put_stringbuf (&sb, ")");
    }

  /* If parameters are given and we have a description for them, parse
     them. */
  if (parmder && parmderlen 
      && pk_algo_table[algoidx].parmelem_string
      && pk_algo_table[algoidx].parmctrl_string)
    {
      elem = pk_algo_table[algoidx].parmelem_string; 
      ctrl = pk_algo_table[algoidx].parmctrl_string; 
      for (; *elem; ctrl++, elem++)
        {
          int is_int;
          
          if ( (*ctrl & 0x80) && !elem[1] )
            {
              /* Hack to allow reading a raw value.  */
              is_int = 1;
              len = parmderlen;
            }
          else
            {
              if (!parmderlen)
                {
                  xfree (parm_oid);
                  return gpg_error (GPG_ERR_INV_KEYINFO);
                }
              c = *parmder++; parmderlen--;
              if ( c != *ctrl )
                {
                  xfree (parm_oid);
                  return gpg_error (GPG_ERR_UNEXPECTED_TAG);
                }
              is_int = c == 0x02;
              TLV_LENGTH (parmder);
            }
          if (is_int && *elem != '-')  /* Take this integer.  */
            { 
              char tmp[2];
              
              put_stringbuf (&sb, "(");
              tmp[0] = *elem; tmp[1] = 0;
              put_stringbuf_sexp (&sb, tmp);
              put_stringbuf_mem_sexp (&sb, parmder, len);
              parmder += len;
              parmderlen -= len;
              put_stringbuf (&sb, ")");
            }
        }
    }


  /* FIXME: We don't release the stringbuf in case of error
     better let the macro jump to a label */
  elem = pk_algo_table[algoidx].elem_string; 
  ctrl = pk_algo_table[algoidx].ctrl_string; 
  for (; *elem; ctrl++, elem++)
    {
      int is_int;

      if ( (*ctrl & 0x80) && !elem[1] )
        {
          /* Hack to allow reading a raw value.  */
          is_int = 1;
          len = derlen;
        }
      else
        {
          if (!derlen)
            {
              xfree (parm_oid);
              return gpg_error (GPG_ERR_INV_KEYINFO);
            }
          c = *der++; derlen--;
          if ( c != *ctrl )
            {
              xfree (parm_oid);
              return gpg_error (GPG_ERR_UNEXPECTED_TAG);
            }
          is_int = c == 0x02;
          TLV_LENGTH (der);
        }
      if (is_int && *elem != '-')  /* Take this integer.  */
        { 
          char tmp[2];

          put_stringbuf (&sb, "(");
          tmp[0] = *elem; tmp[1] = 0;
          put_stringbuf_sexp (&sb, tmp);
          put_stringbuf_mem_sexp (&sb, der, len);
          der += len;
          derlen -= len;
          put_stringbuf (&sb, ")");
        }
    }
  put_stringbuf (&sb, "))");
  xfree (parm_oid);

  *r_string = get_stringbuf (&sb);
  if (!*r_string)
    return gpg_error (GPG_ERR_ENOMEM);

  return 0;
}
Пример #5
0
/* Return the OFF and the LEN of algorithm within DER.  Do some checks
   and return the number of bytes read in r_nread, adding this to der
   does point into the BIT STRING.

   mode 0: just get the algorithm identifier. FIXME: should be able to
           handle BER Encoding. 
   mode 1: as described.
 */
static gpg_error_t
get_algorithm (int mode, const unsigned char *der, size_t derlen,
               size_t *r_nread, size_t *r_pos, size_t *r_len, int *r_bitstr,
               size_t *r_parm_pos, size_t *r_parm_len, int *r_parm_type)
{
  int c;
  const unsigned char *start = der;
  const unsigned char *startseq;
  unsigned long seqlen, len;

  *r_bitstr = 0;
  if (r_parm_pos)
    *r_parm_pos = 0;
  if (r_parm_len)
    *r_parm_len = 0;
  if (r_parm_type)
    *r_parm_type = 0;
  /* get the inner sequence */
  if (!derlen)
    return gpg_error (GPG_ERR_INV_KEYINFO);
  c = *der++; derlen--;
  if ( c != 0x30 )
    return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
  TLV_LENGTH(der); 
  seqlen = len;
  startseq = der;

  /* get the object identifier */
  if (!derlen)
    return gpg_error (GPG_ERR_INV_KEYINFO);
  c = *der++; derlen--; 
  if ( c != 0x06 )
    return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not an OBJECT IDENTIFIER */
  TLV_LENGTH(der);

  /* der does now point to an oid of length LEN */
  *r_pos = der - start;
  *r_len = len;
/*    { */
/*      char *p = ksba_oid_to_str (der, len); */
/*      printf ("algorithm: %s\n", p); */
/*      xfree (p); */
/*    } */
  der += len;
  derlen -= len;
  seqlen -= der - startseq;;

  /* Parse the parameter.  */
  if (seqlen)
    {
      const unsigned char *startparm = der;

      if (!derlen)
        return gpg_error (GPG_ERR_INV_KEYINFO);
      c = *der++; derlen--;
      if ( c == 0x05 ) 
        {
          /*printf ("parameter: NULL \n"); the usual case */
          if (!derlen)
            return gpg_error (GPG_ERR_INV_KEYINFO);
          c = *der++; derlen--;
          if (c) 
            return gpg_error (GPG_ERR_BAD_BER);  /* NULL must have a
                                                    length of 0 */
          seqlen -= 2;
        }
      else if (r_parm_pos && r_parm_len && c == 0x04)
        { 
          /*  This is an octet string parameter and we need it.  */
          if (r_parm_type)
            *r_parm_type = TYPE_OCTET_STRING;
          TLV_LENGTH(der);
          *r_parm_pos = der - start;
          *r_parm_len = len;
          seqlen -= der - startparm;
          der += len;
          derlen -= len;
          seqlen -= len;
        }
      else if (r_parm_pos && r_parm_len && c == 0x06)
        { 
          /*  This is an object identifier.  */
          if (r_parm_type)
            *r_parm_type = TYPE_OBJECT_ID;
          TLV_LENGTH(der);
          *r_parm_pos = der - start;
          *r_parm_len = len;
          seqlen -= der - startparm;
          der += len;
          derlen -= len;
          seqlen -= len;
        }
      else if (r_parm_pos && r_parm_len && c == 0x30)
        { 
          /*  This is a sequence. */
          if (r_parm_type)
            *r_parm_type = TYPE_SEQUENCE;
          TLV_LENGTH(der);
          *r_parm_pos = startparm - start;
          *r_parm_len = len + (der - startparm);
          seqlen -= der - startparm;
          der += len;
          derlen -= len;
          seqlen -= len;
        }
      else
        {
/*            printf ("parameter: with tag %02x - ignored\n", c); */
          TLV_LENGTH(der);
          seqlen -= der - startparm;
          /* skip the value */
          der += len;
          derlen -= len;
          seqlen -= len;
        }
    }

  if (seqlen)
    return gpg_error (GPG_ERR_INV_KEYINFO);

  if (mode)
    {
      /* move forward to the BIT_STR */
      if (!derlen)
        return gpg_error (GPG_ERR_INV_KEYINFO);
      c = *der++; derlen--;
      
      if (c == 0x03)
        *r_bitstr = 1; /* BIT STRING */
      else if (c == 0x04)
        ; /* OCTECT STRING */
      else
        return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a BIT STRING */
      TLV_LENGTH(der);
    }

  *r_nread = der - start;
  return 0;
}
Пример #6
0
/* Mode 0: work as described under _ksba_sigval_to_sexp
   mode 1: work as described under _ksba_encval_to_sexp */
static gpg_error_t
cryptval_to_sexp (int mode, const unsigned char *der, size_t derlen,
                  ksba_sexp_t *r_string)
{
  gpg_error_t err;
  const struct algo_table_s *algo_table;
  int c;
  size_t nread, off, len;
  int algoidx;
  int is_bitstr;
  const unsigned char *ctrl;
  const char *elem;
  struct stringbuf sb;

  /* FIXME: The entire function is very similar to keyinfo_to_sexp */
  *r_string = NULL;

  if (!mode)
    algo_table = sig_algo_table;
  else
    algo_table = enc_algo_table;
  

  err = get_algorithm (1, der, derlen, &nread, &off, &len, &is_bitstr,
                       NULL, NULL, NULL);
  if (err)
    return err;
  
  /* look into our table of supported algorithms */
  for (algoidx=0; algo_table[algoidx].oid; algoidx++)
    {
      if ( len == algo_table[algoidx].oidlen
           && !memcmp (der+off, algo_table[algoidx].oid, len))
        break;
    }
  if (!algo_table[algoidx].oid)
    return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
  if (!algo_table[algoidx].supported)
    return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);

  der += nread;
  derlen -= nread;

  if (is_bitstr)
    { /* Funny: X.509 defines the signature value as a bit string but
         CMS as an octet string - for ease of implementation we always
         allow both */
      if (!derlen)
        return gpg_error (GPG_ERR_INV_KEYINFO);
      c = *der++; derlen--;
      if (c) 
        fprintf (stderr, "warning: number of unused bits is not zero\n");
    }

  /* fixme: we should calculate the initial length form the size of the
     sequence, so that we don't neen a realloc later */
  init_stringbuf (&sb, 100);
  put_stringbuf (&sb, mode? "(7:enc-val(":"(7:sig-val(");
  put_stringbuf_sexp (&sb, algo_table[algoidx].algo_string);

  /* FIXME: We don't release the stringbuf in case of error
     better let the macro jump to a label */
  elem = algo_table[algoidx].elem_string; 
  ctrl = algo_table[algoidx].ctrl_string; 
  for (; *elem; ctrl++, elem++)
    {
      int is_int;

      if ( (*ctrl & 0x80) && !elem[1] )
        {  /* Hack to allow a raw value */
          is_int = 1;
          len = derlen;
        }
      else
        {
          if (!derlen)
            return gpg_error (GPG_ERR_INV_KEYINFO);
          c = *der++; derlen--;
          if ( c != *ctrl )
            return gpg_error (GPG_ERR_UNEXPECTED_TAG);
          is_int = c == 0x02;
          TLV_LENGTH (der);
        }
      if (is_int && *elem != '-')
        { /* take this integer */
          char tmp[2];
          
          put_stringbuf (&sb, "(");
          tmp[0] = *elem; tmp[1] = 0;
          put_stringbuf_sexp (&sb, tmp);
          put_stringbuf_mem_sexp (&sb, der, len);
          der += len;
          derlen -= len;
          put_stringbuf (&sb, ")");
        }
    }
  put_stringbuf (&sb, ")");
  if (!mode && algo_table[algoidx].digest_string)
    {
      /* Insert the hash algorithm if included in the OID.  */
      put_stringbuf (&sb, "(4:hash");
      put_stringbuf_sexp (&sb, algo_table[algoidx].digest_string);
      put_stringbuf (&sb, ")");
    }
  put_stringbuf (&sb, ")");
  
  *r_string = get_stringbuf (&sb);
  if (!*r_string)
    return gpg_error (GPG_ERR_ENOMEM);

  return 0;
}