/*---------------------------------------------------------------------------*/ static enum adaptivesec_verify verify(struct akes_nbr *sender) { if(packetbuf_holds_broadcast()) { if(verify_broadcast(sender)) { PRINTF("coresec-strategy: Inauthentic broadcast\n"); return 0; } } else { #if ANTI_REPLAY_WITH_SUPPRESSION packetbuf_set_attr(PACKETBUF_ATTR_NEIGHBOR_INDEX, sender->foreign_index); #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ if(adaptivesec_verify(sender->pairwise_key)) { PRINTF("coresec-strategy: Inauthentic unicast\n"); return ADAPTIVESEC_VERIFY_INAUTHENTIC; } } #if !POTR_ENABLED if(anti_replay_was_replayed(&sender->anti_replay_info)) { PRINTF("coresec-strategy: Replayed\n"); return ADAPTIVESEC_VERIFY_REPLAYED; } #endif /* !POTR_ENABLED */ return ADAPTIVESEC_VERIFY_SUCCESS; }
/*---------------------------------------------------------------------------*/ static enum cmd_broker_result on_helloack(uint8_t *payload, int p_flag) { struct akes_nbr_entry *entry; uint8_t *secret; uint8_t key[AKES_NBR_CHALLENGE_LEN * 2]; int is_new; PRINTF("akes: Received HELLOACK\n"); if(!akes_is_acceptable_helloack()) { return CMD_BROKER_ERROR; } akes_nbr_delete_expired_tentatives(); entry = akes_nbr_get_sender_entry(); if(entry && entry->permanent && p_flag) { PRINTF("akes: No need to start a new session\n"); return CMD_BROKER_ERROR; } secret = AKES_SCHEME.get_secret_with_helloack_sender(packetbuf_addr(PACKETBUF_ADDR_SENDER)); if(!secret) { PRINTF("akes: No secret with HELLOACK sender\n"); return CMD_BROKER_ERROR; } /* copy challenges and generate key */ akes_nbr_copy_challenge(key, hello_challenge); akes_nbr_copy_challenge(key + AKES_NBR_CHALLENGE_LEN, payload); generate_pairwise_key(key, secret); #if ANTI_REPLAY_WITH_SUPPRESSION packetbuf_set_attr(PACKETBUF_ATTR_NEIGHBOR_INDEX, payload[AKES_NBR_CHALLENGE_LEN]); anti_replay_parse_counter(payload + AKES_NBR_CHALLENGE_LEN + 1); #endif /* ANTI_REPLAY_WITH_SUPPRESSION */ if(adaptivesec_verify(key)) { PRINTF("akes: Invalid HELLOACK\n"); return CMD_BROKER_ERROR; } is_new = 1; if(entry) { if(entry->permanent) { if( #if AKES_NBR_WITH_PAIRWISE_KEYS !memcmp(key, entry->permanent->pairwise_key, AES_128_KEY_LENGTH)) { #else /* AKES_NBR_WITH_PAIRWISE_KEYS */ !memcmp(payload, entry->permanent->helloack_challenge, AKES_NBR_CACHED_HELLOACK_CHALLENGE_LEN)) { #endif /* AKES_NBR_WITH_PAIRWISE_KEYS */ PRINTF("akes: Replayed HELLOACK\n"); return CMD_BROKER_ERROR; } else { akes_nbr_delete(entry, AKES_NBR_PERMANENT); is_new = 0; } } if(entry->tentative) { #if !AKES_NBR_WITH_PAIRWISE_KEYS if(!entry->tentative->meta->has_wait_timer) { PRINTF("akes: Awaiting acknowledgement of ACK\n"); return CMD_BROKER_ERROR; } #endif /* !AKES_NBR_WITH_PAIRWISE_KEYS */ if(ctimer_expired(&entry->tentative->meta->wait_timer)) { PRINTF("akes: Awaiting ACK\n"); return CMD_BROKER_ERROR; } else { PRINTF("akes: Skipping HELLOACK\n"); ctimer_stop(&entry->tentative->meta->wait_timer); akes_nbr_delete(entry, AKES_NBR_TENTATIVE); } } }