Exemplo n.º 1
0
int packetAddHLRCreateRequest(unsigned char *packet,int packet_maxlen,int *packet_len)
{
  int packet_len_in=*packet_len;

  CHECK_PACKET_LEN(1);
  packet[(*packet_len)++]=ACTION_CREATEHLR;

  if (debug>2) dump("Variable request octets (HLR create)",&packet[packet_len_in],(*packet_len)-packet_len_in);

  return 0;
}
Exemplo n.º 2
0
int packetAddVariableWrite(unsigned char *packet,int packet_maxlen,
			   int *packet_len,
			   int itemId,int instance,unsigned char *value,
			   int start_offset,int value_len,int flags)
{
  /* Work out which item type we are asking for */
  int packet_len_in=*packet_len;

  int max_offset=start_offset+value_len-1;

  if (debug>1) printf("packetAddVariableWrite(start=%d,len=%d,flags=%d)\n",start_offset,value_len,flags);

  /* Sanity check */
  if (instance<0) return setReason("Asked for illegal variable value instance");
  if (instance>0xfe) return setReason("Asked for illegal variable value instance");
  if ((itemId<0x80)&&instance) return setReason("Asked for secondary value of single-value variable");
  if (start_offset<0||start_offset>0xffff) return setReason("Asked for illegal variable value starting offset");
  if (max_offset<0||max_offset>0xffff) return setReason("Asked for illegal variable value ending offset");
  
  /* Add request to the packet */
  CHECK_PACKET_LEN(1+1+((itemId&0x80)?1:0)+2+2+1);
  packet[(*packet_len)++]=ACTION_SET;
  packet[(*packet_len)++]=itemId;
  if (itemId&0x80) packet[(*packet_len)++]=instance;
  packet[(*packet_len)++]=start_offset>>8;
  packet[(*packet_len)++]=start_offset&0xff;
  packet[(*packet_len)++]=value_len>>8;
  packet[(*packet_len)++]=value_len&0xff;
  packet[(*packet_len)++]=flags;
  
  if (debug>2) dump("Packet with var write header",&packet[0],*packet_len);

  CHECK_PACKET_LEN(value_len);
  bcopy(&value[0],&packet[*packet_len],value_len);
  (*packet_len)+=value_len;

  if (debug>2) dump("Variable request octets (write)",&packet[packet_len_in],(*packet_len)-packet_len_in);

  return 0;
}
Exemplo n.º 3
0
int packetFinalise(unsigned char *packet,int packet_maxlen,int *packet_len)
{
  /* Add any padding bytes and EOT to packet */
  int paddingBytes=rand()&0xf;
  int payloadRotation;

  if (paddingBytes)
    {
      CHECK_PACKET_LEN(2+paddingBytes);
      packet[(*packet_len)++]=ACTION_PAD;
      packet[(*packet_len)++]=paddingBytes;
      while(paddingBytes--) packet[(*packet_len)++]=random()&0xff;
    }

  packet[(*packet_len)++]=ACTION_EOT;

  /* Set payload length */
  packet[4]=((*packet_len)>>8)&0xff;
  packet[5]=((*packet_len)&0xff);

  /* Work out by how much to rotate the packet payload.
     The purpose of the rotation is to make it more difficult to
     conduct a known-plaintext attack against any ciphers that we 
     may later support.
  */
  payloadRotation=(*packet_len)-HEADERFIELDS_LEN;
  if (payloadRotation>0xff) payloadRotation=0xff;
  payloadRotation=random()%payloadRotation;
  if (debug>2) 
    fprintf(stderr,"Known Plaintext counter-measure: rotating packet payload by 0x%02x bytes.\n",
	    payloadRotation);
  if (debug>2) dump("unrotated packet",packet,*packet_len);

  /* Now rotate the payload */
  {
    unsigned char temp[256];

    /*Copy first part of payload to a temporary buffer */
    bcopy(&packet[HEADERFIELDS_LEN],&temp[0],payloadRotation);
    /* Copy the main part of the payload left by the rotation factor */
    bcopy(&packet[HEADERFIELDS_LEN+payloadRotation],&packet[HEADERFIELDS_LEN],
	  (*packet_len)-(HEADERFIELDS_LEN)-payloadRotation);
    /* Copy the temporary buffer to the end of the packet to complete the rotation */
    bcopy(&temp[0],&packet[(*packet_len)-payloadRotation],payloadRotation);
  }
  packet[OFS_ROTATIONFIELD]=payloadRotation;
  if (debug>3) dump("rotated packet",packet,*packet_len);

  return 0;
}
Exemplo n.º 4
0
int packetMakeHeader(unsigned char *packet,int packet_maxlen,int *packet_len,
		     unsigned char *transaction_id,int cryptoflags)
{
  int i;

  CHECK_PACKET_LEN(OFS_PAYLOAD);

  /* 0x4110 magic value */
  packet[0]=0x41;
  packet[1]=0x10;
  
  /* encoding version */
  packet[2]=0x00;
  packet[3]=0x01;
  
  /* Payload length (to be filled in later) */
  packet[4]=0x00;
  packet[5]=0x00;
  
  /* Payload cipher (0x0000 = plain text) */
  packet[6]=0x00;
  packet[7]=0x00;

  /* Add 64bit transaction id */
  if (transaction_id)
    /* Use supplied transaction ID */
    for(i=0;i<TRANSID_SIZE;i++) packet[OFS_TRANSIDFIELD+i]=transaction_id[i];
  else
    /* No transaction ID supplied, so create random transaction ID */
    for(i=0;i<TRANSID_SIZE;i++) packet[OFS_TRANSIDFIELD+i]=random()&0xff;

  /* payload rotation (not yet applied) */
  packet[OFS_ROTATIONFIELD]=0x00;

  *packet_len=HEADERFIELDS_LEN;

  /* Clear did/subscriber ID, salt and hashed pin fields.
     However, we cannot zero them, because that would provide significant knowable plain-text
     for a known plain text attack.
     Thus, instead we fill it with random date, but make the modulo sum of each field == 0x00
     to indicate that no PIN has been provided. */
  safeZeroField(packet,*packet_len,SIDDIDFIELD_LEN); *packet_len+=SIDDIDFIELD_LEN;
  safeZeroField(packet,*packet_len,16); *packet_len+=16;
  safeZeroField(packet,*packet_len,16); *packet_len+=16;

  return 0;
}
Exemplo n.º 5
0
int respondSimple(char *sid,int action,unsigned char *action_text,int action_len,
		  unsigned char *transaction_id)
{
  unsigned char packet[8000];
  int pl=0;
  int *packet_len=&pl;
  int packet_maxlen=8000;
  int i;

  /* ACTION_ERROR is associated with an error message.
     For syntactic simplicity, we do not require the respondSimple() call to provide
     the length of the error message. */
  if (action==ACTION_ERROR) {
    action_len=strlen((char *)action_text);
    /* Make sure the error text isn't too long.
       IF it is, trim it, as we still need to communicate the error */
    if (action_len>255) action_len=255;
  }

  /* Prepare the request packet */
  if (packetMakeHeader(packet,8000,packet_len,transaction_id)) return -1;
  if (sid&&sid[0]) 
    { if (packetSetSid(packet,8000,packet_len,sid)) 
	return setReason("invalid SID in reply"); }
  else 
    { if (packetSetDid(packet,8000,packet_len,"")) 
	return setReason("Could not set empty DID in reply"); }  

  CHECK_PACKET_LEN(1+1+action_len);
  packet[(*packet_len)++]=action;
  if (action==ACTION_ERROR) packet[(*packet_len)++]=action_len;
  for(i=0;i<action_len;i++) packet[(*packet_len)++]=action_text[i];

  if (debug>2) dump("Simple response octets",action_text,action_len);

  if (packetFinalise(packet,8000,packet_len)) return -1;

  if (debug) fprintf(stderr,"Sending response of %d bytes.\n",*packet_len);

  if (packetSendRequest(REQ_REPLY,packet,*packet_len,NONBATCH,transaction_id,NULL)) return -1;
  
  return 0;
}
Exemplo n.º 6
0
int packetAddVariableRequest(unsigned char *packet,int packet_maxlen,int *packet_len,
			     char *item,int instance,int start_offset,int bytes)
{
  /* Work out which item type we are asking for */
  int itemId;
  int packet_len_in=*packet_len;
  for(itemId=0;vars[itemId].name;itemId++)
    if (!strcmp(item,vars[itemId].name)) {
      break;
    }

  /* Sanity check the request */
  if (!vars[itemId].name) {
    if (debug) fprintf(stderr,"`%s' is not a known HLR variable.\n",item);
    return setReason("Requested unknown HLR variable");
  }
  itemId=vars[itemId].id;
  if (instance<-1) return setReason("Asked for illegal variable value instance");
  if (instance>0xfe) return setReason("Asked for illegal variable value instance");
  if ((itemId<0x80)&&instance) return setReason("Asked for secondary value of single-value variable");
  if (start_offset<0||start_offset>0xffff) return setReason("Asked for illegal variable value starting offset");
  if (bytes<0||(start_offset+bytes)>0xffff) {
    if (debug) fprintf(stderr,"Asked for %d bytes at offset %d\n",bytes,start_offset);
    return setReason("Asked for illegal variable value ending offset");
  }
  
  /* Add request to the packet */
  CHECK_PACKET_LEN(1+1+((itemId&0x80)?1:0)+2+2);
  packet[(*packet_len)++]=ACTION_GET;
  packet[(*packet_len)++]=itemId;
  if (instance==-1) instance=0xff;
  if (itemId&0x80) packet[(*packet_len)++]=instance;
  packet[(*packet_len)++]=start_offset>>8;
  packet[(*packet_len)++]=start_offset&0xff;
  packet[(*packet_len)++]=bytes>>8;
  packet[(*packet_len)++]=bytes&0xff;
  
  if (debug>2) dump("Variable request octets (var)",&packet[packet_len_in],(*packet_len)-packet_len_in);

  return 0;
}
Exemplo n.º 7
0
int packetFinalise(unsigned char *packet,int packet_maxlen,int recvttl,
		   int *packet_len,int cryptoflags)
{
  /* Add any padding bytes and EOT to packet */
  int paddingBytes=rand()&0xf;
  int payloadRotation;

  if (paddingBytes)
    {
      CHECK_PACKET_LEN(2+paddingBytes);
      packet[(*packet_len)++]=ACTION_PAD;
      packet[(*packet_len)++]=paddingBytes;
      while(paddingBytes--) packet[(*packet_len)++]=random()&0xff;
    }

  /* tell requester what the ttl was when we received the packet */
  if (recvttl>-1) {
    CHECK_PACKET_LEN(2);
    packet[(*packet_len)++]=ACTION_RECVTTL;
    packet[(*packet_len)++]=recvttl;
  }

  /* mark end of packet */
  CHECK_PACKET_LEN(1);
  packet[(*packet_len)++]=ACTION_EOT;

  /* Set payload length */
  packet[4]=((*packet_len)>>8)&0xff;
  packet[5]=((*packet_len)&0xff);

  /* Work out by how much to rotate the packet payload.
     The purpose of the rotation is to make it more difficult to
     conduct a known-plaintext attack against any ciphers that we 
     may later support.
  */
  payloadRotation=(*packet_len)-HEADERFIELDS_LEN;
  if (payloadRotation>0xff) payloadRotation=0xff;
  payloadRotation=random()%payloadRotation;
  if (debug&DEBUG_SECURITY) {
    DEBUGF("Known Plaintext counter-measure: rotating packet payload by 0x%02x bytes",
	    payloadRotation);
    dump("unrotated packet",packet,*packet_len);
  }

  /* Now rotate the payload */
  {
    unsigned char temp[256];

    /*Copy first part of payload to a temporary buffer */
    bcopy(&packet[HEADERFIELDS_LEN],&temp[0],payloadRotation);
    /* Copy the main part of the payload left by the rotation factor */
    bcopy(&packet[HEADERFIELDS_LEN+payloadRotation],&packet[HEADERFIELDS_LEN],
	  (*packet_len)-(HEADERFIELDS_LEN)-payloadRotation);
    /* Copy the temporary buffer to the end of the packet to complete the rotation */
    bcopy(&temp[0],&packet[(*packet_len)-payloadRotation],payloadRotation);
  }
  packet[OFS_ROTATIONFIELD]=payloadRotation;
  if (debug&DEBUG_SECURITY) dump("rotated packet",packet,*packet_len);

  if (cryptoflags) return packetEncipher(packet,packet_maxlen,packet_len,cryptoflags);

  return 0;
}