* add reordering window management to PDCP
* update PDCP security and count calculation git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5307 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -27,9 +27,10 @@
|
||||
|
||||
*******************************************************************************/
|
||||
/*! \file pdcp_security.c
|
||||
* \brief PDCP Security Methods
|
||||
* \author ROUX Sebastien
|
||||
* \date 2013
|
||||
* \brief PDCP Security Methods
|
||||
* \author ROUX Sebastie and Navid Nikaein
|
||||
* \email openair_tech@eurecom.fr, navid.nikaein@eurecom.fr
|
||||
* \date 2014
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -48,47 +49,62 @@
|
||||
#if defined(ENABLE_SECURITY)
|
||||
|
||||
static
|
||||
uint32_t pdcp_get_next_count_tx(pdcp_t *pdcp_entity, uint8_t pdcp_header_len, uint16_t pdcp_sn);
|
||||
uint32_t pdcp_get_next_count_tx(pdcp_t *pdcp_entity, srb_flag_t srb_flagP, uint16_t pdcp_sn);
|
||||
static
|
||||
uint32_t pdcp_get_next_count_rx(pdcp_t *pdcp_entity, uint8_t pdcp_header_len, uint16_t pdcp_sn);
|
||||
uint32_t pdcp_get_next_count_rx(pdcp_t *pdcp_entity, srb_flag_t srb_flagP, uint16_t pdcp_sn);
|
||||
|
||||
static
|
||||
uint32_t pdcp_get_next_count_tx(pdcp_t *pdcp_entity, uint8_t pdcp_header_len, uint16_t pdcp_sn)
|
||||
uint32_t pdcp_get_next_count_tx(pdcp_t *pdcp_entity, srb_flag_t srb_flagP, uint16_t pdcp_sn)
|
||||
{
|
||||
uint32_t count;
|
||||
/* For TX COUNT = TX_HFN << length of SN | pdcp SN */
|
||||
if (pdcp_header_len == PDCP_CONTROL_PLANE_DATA_PDU_SN_SIZE) {
|
||||
/* 5 bits length SN */
|
||||
count = (pdcp_entity->tx_hfn << 5) | (pdcp_sn & 0x001F);
|
||||
} else {
|
||||
/* 12 bits length SN */
|
||||
count = (pdcp_entity->tx_hfn << 12) | (pdcp_sn & 0x0FFF);
|
||||
uint32_t count;
|
||||
/* For TX COUNT = TX_HFN << length of SN | pdcp SN */
|
||||
if (srb_flagP) {
|
||||
/* 5 bits length SN */
|
||||
count = ((pdcp_entity->tx_hfn << 5) | (pdcp_sn & 0x001F));
|
||||
} else {
|
||||
if (pdcp_entity->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
|
||||
count = ((pdcp_entity->tx_hfn << 7) | (pdcp_sn & 0x07F));
|
||||
} else { /*Default is the 12 bits length SN */
|
||||
count = ((pdcp_entity->tx_hfn << 12) | (pdcp_sn & 0x0FFF));
|
||||
}
|
||||
// LOG_D(PDCP, "[OSA] TX COUNT = 0x%08x\n", count);
|
||||
|
||||
return count;
|
||||
}
|
||||
LOG_D(PDCP, "[OSA] TX COUNT = 0x%08x\n", count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static
|
||||
uint32_t pdcp_get_next_count_rx(pdcp_t *pdcp_entity, uint8_t pdcp_header_len, uint16_t pdcp_sn)
|
||||
uint32_t pdcp_get_next_count_rx(pdcp_t *pdcp_entity, srb_flag_t srb_flagP, uint16_t pdcp_sn)
|
||||
{
|
||||
uint32_t count;
|
||||
/* For RX COUNT = RX_HFN << length of SN | pdcp SN of received PDU */
|
||||
if (pdcp_header_len == PDCP_CONTROL_PLANE_DATA_PDU_SN_SIZE) {
|
||||
/* 5 bits length SN */
|
||||
count = (pdcp_entity->rx_hfn << 5) | (pdcp_sn & 0x001F);
|
||||
} else {
|
||||
/* 12 bits length SN */
|
||||
count = (pdcp_entity->rx_hfn << 12) | (pdcp_sn & 0x0FFF);
|
||||
uint32_t count;
|
||||
/* For RX COUNT = RX_HFN << length of SN | pdcp SN of received PDU */
|
||||
if (srb_flagP) {
|
||||
/* 5 bits length SN */
|
||||
count = (((pdcp_entity->rx_hfn + pdcp_entity->rx_hfn_offset) << 5) | (pdcp_sn & 0x001F));
|
||||
} else {
|
||||
if (pdcp_entity->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
|
||||
/* 7 bits length SN */
|
||||
count = (((pdcp_entity->rx_hfn + pdcp_entity->rx_hfn_offset) << 7) | (pdcp_sn & 0x007F));
|
||||
} else { // default
|
||||
/* 12 bits length SN */
|
||||
count = (((pdcp_entity->rx_hfn + pdcp_entity->rx_hfn_offset) << 12) | (pdcp_sn & 0x0FFF));
|
||||
}
|
||||
// LOG_D(PDCP, "[OSA] RX COUNT = 0x%08x\n", count);
|
||||
|
||||
return count;
|
||||
|
||||
}
|
||||
// reset the hfn offset
|
||||
pdcp_entity->rx_hfn_offset =0;
|
||||
LOG_D(PDCP, "[OSA] RX COUNT = 0x%08x\n", count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
|
||||
uint8_t pdcp_header_len, uint16_t current_sn, uint8_t *pdcp_pdu_buffer,
|
||||
uint16_t sdu_buffer_size)
|
||||
int pdcp_apply_security(pdcp_t *pdcp_entity,
|
||||
srb_flag_t srb_flagP,
|
||||
rb_id_t rb_id,
|
||||
uint8_t pdcp_header_len,
|
||||
uint16_t current_sn,
|
||||
uint8_t *pdcp_pdu_buffer,
|
||||
uint16_t sdu_buffer_size)
|
||||
{
|
||||
uint8_t *buffer_encrypted = NULL;
|
||||
stream_cipher_t encrypt_params;
|
||||
@@ -99,12 +115,12 @@ int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
|
||||
|
||||
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_IN);
|
||||
|
||||
encrypt_params.direction = (pdcp_entity->is_ue == 1) ? SECU_DIRECTION_UPLINK : SECU_DIRECTION_DOWNLINK;
|
||||
encrypt_params.direction = (pdcp_entity->is_ue == 1) ? SECU_DIRECTION_UPLINK : SECU_DIRECTION_DOWNLINK;
|
||||
encrypt_params.bearer = rb_id - 1;
|
||||
encrypt_params.count = pdcp_get_next_count_tx(pdcp_entity, pdcp_header_len, current_sn);
|
||||
encrypt_params.count = pdcp_get_next_count_tx(pdcp_entity, srb_flagP, current_sn);
|
||||
encrypt_params.key_length = 16;
|
||||
|
||||
if (rb_id < DTCH) {
|
||||
if (srb_flagP) {
|
||||
/* SRBs */
|
||||
uint8_t *mac_i;
|
||||
|
||||
@@ -119,7 +135,8 @@ int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
|
||||
|
||||
/* Both header and data parts are integrity protected for
|
||||
* control-plane PDUs */
|
||||
stream_compute_integrity(pdcp_entity->integrityProtAlgorithm, &encrypt_params,
|
||||
stream_compute_integrity(pdcp_entity->integrityProtAlgorithm,
|
||||
&encrypt_params,
|
||||
mac_i);
|
||||
|
||||
encrypt_params.key = pdcp_entity->kRRCenc; // + 128 // bit key
|
||||
@@ -136,7 +153,8 @@ int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
|
||||
buffer_encrypted = &pdcp_pdu_buffer[pdcp_header_len];
|
||||
|
||||
/* Apply ciphering if any requested */
|
||||
stream_encrypt(pdcp_entity->cipheringAlgorithm, &encrypt_params,
|
||||
stream_encrypt(pdcp_entity->cipheringAlgorithm,
|
||||
&encrypt_params,
|
||||
&buffer_encrypted);
|
||||
|
||||
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_OUT);
|
||||
@@ -144,9 +162,13 @@ int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pdcp_validate_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
|
||||
uint8_t pdcp_header_len, uint16_t current_sn, uint8_t *pdcp_pdu_buffer,
|
||||
uint16_t sdu_buffer_size)
|
||||
int pdcp_validate_security(pdcp_t *pdcp_entity,
|
||||
srb_flag_t srb_flagP,
|
||||
rb_id_t rb_id,
|
||||
uint8_t pdcp_header_len,
|
||||
uint16_t current_sn,
|
||||
uint8_t *pdcp_pdu_buffer,
|
||||
uint16_t sdu_buffer_size)
|
||||
{
|
||||
uint8_t *buffer_decrypted = NULL;
|
||||
stream_cipher_t decrypt_params;
|
||||
@@ -162,12 +184,12 @@ int pdcp_validate_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
|
||||
|
||||
decrypt_params.direction = (pdcp_entity->is_ue == 1) ? SECU_DIRECTION_DOWNLINK : SECU_DIRECTION_UPLINK ;
|
||||
decrypt_params.bearer = rb_id - 1;
|
||||
decrypt_params.count = pdcp_get_next_count_rx(pdcp_entity, pdcp_header_len, current_sn);
|
||||
decrypt_params.count = pdcp_get_next_count_rx(pdcp_entity, srb_flagP, current_sn);
|
||||
decrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len];
|
||||
decrypt_params.blength = (sdu_buffer_size - pdcp_header_len) << 3;
|
||||
decrypt_params.key_length = 16;
|
||||
|
||||
if (rb_id < DTCH) {
|
||||
if (srb_flagP) {
|
||||
LOG_D(PDCP, "[OSA][RB %d] %s Validating control-plane security\n",
|
||||
rb_id, (pdcp_entity->is_ue != 0) ? "eNB -> UE" : "UE -> eNB");
|
||||
decrypt_params.key = pdcp_entity->kRRCenc;// + 128;
|
||||
@@ -178,25 +200,28 @@ int pdcp_validate_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
|
||||
}
|
||||
|
||||
/* Uncipher the block */
|
||||
stream_decrypt(pdcp_entity->cipheringAlgorithm, &decrypt_params, &buffer_decrypted);
|
||||
stream_decrypt(pdcp_entity->cipheringAlgorithm,
|
||||
&decrypt_params,
|
||||
&buffer_decrypted);
|
||||
|
||||
if (rb_id < DTCH) {
|
||||
/* Now check the integrity of the complete PDU */
|
||||
decrypt_params.message = pdcp_pdu_buffer;
|
||||
decrypt_params.blength = sdu_buffer_size << 3;
|
||||
decrypt_params.key = pdcp_entity->kRRCint + 16;// 128;
|
||||
|
||||
if (stream_check_integrity(pdcp_entity->integrityProtAlgorithm,
|
||||
&decrypt_params, &pdcp_pdu_buffer[sdu_buffer_size]) != 0)
|
||||
{
|
||||
LOG_E(PDCP, "[OSA] failed to validate MAC-I of incoming PDU\n");
|
||||
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
|
||||
return -1;
|
||||
}
|
||||
if (srb_flagP) {
|
||||
/* Now check the integrity of the complete PDU */
|
||||
decrypt_params.message = pdcp_pdu_buffer;
|
||||
decrypt_params.blength = sdu_buffer_size << 3;
|
||||
decrypt_params.key = pdcp_entity->kRRCint + 16;// 128;
|
||||
|
||||
if (stream_check_integrity(pdcp_entity->integrityProtAlgorithm,
|
||||
&decrypt_params,
|
||||
&pdcp_pdu_buffer[sdu_buffer_size]) != 0)
|
||||
{
|
||||
LOG_E(PDCP, "[OSA] failed to validate MAC-I of incoming PDU\n");
|
||||
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user