Example #1
0
/*---------------------------------------------------------------------------*/
int
anti_replay_was_replayed(struct anti_replay_info *info)
{
  uint32_t received_counter;
  
  received_counter = anti_replay_get_counter();
  
  if(packetbuf_holds_broadcast()) {
#if DEBUG
    if(received_counter < info->his_broadcast_counter.u32) {
      PRINTF("anti-replay: Broadcast out of order\n");
    }
#endif /* DEBUG */
    if(received_counter <= info->his_broadcast_counter.u32) {
      return 1;
    } else {
      info->his_broadcast_counter.u32 = received_counter;
      return 0;
    }
  } else {
#if DEBUG
    if(received_counter < info->his_unicast_counter.u32) {
      PRINTF("anti-replay: Unicast out of order\n");
    }
#endif /* DEBUG */
    if(received_counter <= info->his_unicast_counter.u32) {
      return 1;
    } else {
      info->his_unicast_counter.u32 = received_counter;
      return 0;
    }
  }
}
Example #2
0
/*---------------------------------------------------------------------------*/
int
anti_replay_was_replayed(struct anti_replay_info *info)
{
  uint32_t received_counter;
  
  received_counter = anti_replay_get_counter();
  
  if(packetbuf_holds_broadcast()) {
    /* broadcast */
    if(received_counter <= info->last_broadcast_counter) {
      return 1;
    } else {
      info->last_broadcast_counter = received_counter;
      return 0;
    }
  } else {
    /* unicast */
    if(received_counter <= info->last_unicast_counter) {
      return 1;
    } else {
      info->last_unicast_counter = received_counter;
      return 0;
    }
  }
}
Example #3
0
/*---------------------------------------------------------------------------*/
void
anti_replay_init_info(struct anti_replay_info *info)
{
  info->last_broadcast_counter
      = info->last_unicast_counter
      = anti_replay_get_counter();
}
Example #4
0
/*---------------------------------------------------------------------------*/
int
anti_replay_set_counter(struct anti_replay_info *receiver_info)
{
#if ANTI_REPLAY_WITH_SUPPRESSION
  if(packetbuf_holds_broadcast()) {
    order_and_set_counter(++anti_replay_my_broadcast_counter);
  } else {
    if(++my_unicast_counter == 0xFFFFFFFF) {
      return 0;
    }
    order_and_set_counter(++receiver_info->my_unicast_counter.u32);
  }
#else /* ANTI_REPLAY_WITH_SUPPRESSION */
  order_and_set_counter(++my_counter);
#endif /* ANTI_REPLAY_WITH_SUPPRESSION */
  return (anti_replay_get_counter() != 0xFFFFFFFF);
}
Example #5
0
/*---------------------------------------------------------------------------*/
static int
parse(void)
{
  int result;
  const linkaddr_t *sender;
  struct anti_replay_info* info;
  
  result = DECORATED_FRAMER.parse();
  if(result == FRAMER_FAILED) {
    return result;
  }
  
  if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != SEC_LVL) {
    PRINTF("noncoresec: received frame with wrong security level\n");
    return FRAMER_FAILED;
  }
  sender = packetbuf_addr(PACKETBUF_ADDR_SENDER);
  if(linkaddr_cmp(sender, &linkaddr_node_addr)) {
    PRINTF("noncoresec: frame from ourselves\n");
    return FRAMER_FAILED;
  }
  
  packetbuf_set_datalen(packetbuf_datalen() - MIC_LEN);
  
  if(!aead(result, 0)) {
    PRINTF("noncoresec: received unauthentic frame %lu\n",
        anti_replay_get_counter());
    return FRAMER_FAILED;
  }
  
  info = nbr_table_get_from_lladdr(anti_replay_table, sender);
  if(!info) {
    info = nbr_table_add_lladdr(anti_replay_table, sender, NBR_TABLE_REASON_LLSEC, NULL);
    if(!info) {
      PRINTF("noncoresec: could not get nbr_table_item\n");
      return FRAMER_FAILED;
    }
    
    /*
     * Locking avoids replay attacks due to removed neighbor table items.
     * Unfortunately, an attacker can mount a memory-based DoS attack
     * on this by replaying broadcast frames from other network parts.
     * However, this is not an issue as long as the network size does not
     * exceed NBR_TABLE_MAX_NEIGHBORS.
     *  
     * To avoid locking, we could swap anti-replay information
     * to external flash. Locking is also unnecessary when using
     * pairwise session keys, as done in coresec.
     */
    if(!nbr_table_lock(anti_replay_table, info)) {
      nbr_table_remove(anti_replay_table, info);
      PRINTF("noncoresec: could not lock\n");
      return FRAMER_FAILED;
    }
    
    anti_replay_init_info(info);
  } else {
    if(anti_replay_was_replayed(info)) {
       PRINTF("noncoresec: received replayed frame %lu\n",
           anti_replay_get_counter());
       return FRAMER_FAILED;
    }
  }
  
  return result;
}