renamed openair-cn to openair3
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7886 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -0,0 +1,404 @@
|
||||
/*******************************************************************************
|
||||
OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
||||
|
||||
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
|
||||
|
||||
*******************************************************************************/
|
||||
/*****************************************************************************
|
||||
|
||||
Source usim_api.h
|
||||
|
||||
Version 0.1
|
||||
|
||||
Date 2012/10/09
|
||||
|
||||
Product NAS stack
|
||||
|
||||
Subsystem Application Programming Interface
|
||||
|
||||
Author Frederic Maurel
|
||||
|
||||
Description Implements the API used by the NAS layer to read/write
|
||||
data to/from the USIM application
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include "usim_api.h"
|
||||
#include "nas_log.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "aka_functions.h"
|
||||
#include <string.h> // memcpy, memset
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
/****************************************************************************/
|
||||
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
||||
/****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/******************* L O C A L D E F I N I T I O N S *******************/
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* The name of the file where are stored data of the USIM application
|
||||
*/
|
||||
#define USIM_API_NVRAM_FILENAME ".usim.nvram"
|
||||
|
||||
/*
|
||||
* The name of the environment variable which defines the directory
|
||||
* where the USIM application file is located
|
||||
*/
|
||||
#define USIM_API_NVRAM_DIRNAME "USIM_DIR"
|
||||
|
||||
/*
|
||||
* Subscriber authentication security key
|
||||
*/
|
||||
#define USIM_API_K_SIZE 16
|
||||
#define USIM_API_K_VALUE "8BAF473F2F8FD09487CCCBD7097C6862"
|
||||
|
||||
static uint8_t _usim_api_k[USIM_API_K_SIZE];
|
||||
|
||||
|
||||
/*
|
||||
* List of last used Sequence Numbers SQN
|
||||
*/
|
||||
static struct _usim_api_data_s {
|
||||
/* Highest sequence number the USIM has ever accepted */
|
||||
uint32_t sqn_ms;
|
||||
/* List of the last used sequence numbers */
|
||||
#define USIM_API_SQN_LIST_SIZE 32
|
||||
uint8_t n_sqns;
|
||||
uint32_t sqn[USIM_API_SQN_LIST_SIZE];
|
||||
} _usim_api_data;
|
||||
|
||||
static uint8_t _usim_api_hex_char_to_hex_value (char c);
|
||||
static void _usim_api_hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size);
|
||||
static int _usim_api_check_sqn(uint32_t seq, uint8_t ind);
|
||||
|
||||
/****************************************************************************/
|
||||
/****************** E X P O R T E D F U N C T I O N S ******************/
|
||||
/****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: usim_api_read() **
|
||||
** **
|
||||
** Description: Reads data from the USIM application **
|
||||
** **
|
||||
** Inputs: None **
|
||||
** Others: File where are stored USIM data **
|
||||
** **
|
||||
** Outputs: data: Pointer to the USIM application data **
|
||||
** Return: RETURNerror, RETURNok **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int usim_api_read(usim_data_t* data)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
/* Get USIM application pathname */
|
||||
char* path = memory_get_path(USIM_API_NVRAM_DIRNAME,
|
||||
USIM_API_NVRAM_FILENAME);
|
||||
|
||||
if (path == NULL) {
|
||||
LOG_TRACE(ERROR, "USIM-API - Failed to get USIM pathname");
|
||||
LOG_FUNC_RETURN (RETURNerror);
|
||||
}
|
||||
|
||||
/* Read USIM application data */
|
||||
if (memory_read(path, data, sizeof(usim_data_t)) != RETURNok) {
|
||||
LOG_TRACE(ERROR, "USIM-API - %s file is either not valid "
|
||||
"or not present", path);
|
||||
free(path);
|
||||
LOG_FUNC_RETURN (RETURNerror);
|
||||
}
|
||||
|
||||
/* initialize the subscriber authentication security key */
|
||||
_usim_api_hex_string_to_hex_value(_usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE);
|
||||
|
||||
free(path);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: usim_api_write() **
|
||||
** **
|
||||
** Description: Writes data to the USIM application **
|
||||
** **
|
||||
** Inputs: data: Pointer to the USIM application data **
|
||||
** Others: None **
|
||||
** **
|
||||
** Outputs: None **
|
||||
** Return: RETURNerror, RETURNok **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int usim_api_write(const usim_data_t* data)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
/* Get USIM application pathname */
|
||||
char* path = memory_get_path(USIM_API_NVRAM_DIRNAME,
|
||||
USIM_API_NVRAM_FILENAME);
|
||||
|
||||
if (path == NULL) {
|
||||
LOG_TRACE(ERROR, "USIM-API - Failed to get USIM pathname");
|
||||
LOG_FUNC_RETURN (RETURNerror);
|
||||
}
|
||||
|
||||
/* Write USIM application data */
|
||||
if (memory_write(path, data, sizeof(usim_data_t)) != RETURNok) {
|
||||
|
||||
LOG_TRACE(ERROR, "USIM-API - Unable to write USIM file %s", path);
|
||||
free(path);
|
||||
LOG_FUNC_RETURN (RETURNerror);
|
||||
}
|
||||
|
||||
free(path);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: usim_api_authenticate() **
|
||||
** **
|
||||
** Description: Performs mutual authentication of the USIM to the network,**
|
||||
** checking whether authentication token AUTN can be accep- **
|
||||
** ted. If so, returns an authentication response RES and **
|
||||
** the ciphering and integrity keys. **
|
||||
** In case of synch failure, returns a re-synchronization **
|
||||
** token AUTS. **
|
||||
** **
|
||||
** 3GPP TS 31.102, section 7.1.1.1 **
|
||||
** **
|
||||
** Authentication and key generating function algorithms are **
|
||||
** specified in 3GPP TS 35.206. **
|
||||
** **
|
||||
** Inputs: rand_pP: Random challenge number **
|
||||
** autn_pP: Authentication token **
|
||||
** AUTN = (SQN xor AK) || AMF || MAC **
|
||||
** 48 16 64 bits **
|
||||
** Others: Security key **
|
||||
** **
|
||||
** Outputs: auts_pP: Re-synchronization token **
|
||||
** res_pP: Authentication response **
|
||||
** ck_pP: Ciphering key **
|
||||
** ik_pP Integrity key **
|
||||
** **
|
||||
** Return: RETURNerror, RETURNok **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP,
|
||||
OctetString* auts_pP, OctetString* res_pP,
|
||||
OctetString* ck_pP, OctetString* ik_pP)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
LOG_TRACE(DEBUG, "USIM-API - rand :%s",dump_octet_string(rand_pP));
|
||||
LOG_TRACE(DEBUG, "USIM-API - autn :%s",dump_octet_string(autn_pP));
|
||||
|
||||
/* Compute the authentication response RES = f2K (RAND) */
|
||||
/* Compute the cipher key CK = f3K (RAND) */
|
||||
/* Compute the integrity key IK = f4K (RAND) */
|
||||
/* Compute the anonymity key AK = f5K (RAND) */
|
||||
#define USIM_API_AK_SIZE 6
|
||||
u8 ak[USIM_API_AK_SIZE];
|
||||
f2345(_usim_api_k, rand_pP->value,
|
||||
res_pP->value, ck_pP->value, ik_pP->value, ak);
|
||||
LOG_TRACE(DEBUG, "USIM-API - res(f2) :%s",dump_octet_string(res_pP));
|
||||
LOG_TRACE(DEBUG, "USIM-API - ck(f3) :%s",dump_octet_string(ck_pP));
|
||||
LOG_TRACE(DEBUG, "USIM-API - ik(f4) :%s",dump_octet_string(ik_pP));
|
||||
LOG_TRACE(DEBUG, "USIM-API - ak(f5) : %02X%02X%02X%02X%02X%02X",
|
||||
ak[0],ak[1],ak[2],ak[3],ak[4],ak[5]);
|
||||
|
||||
/* Retrieve the sequence number SQN = (SQN ⊕ AK) ⊕ AK */
|
||||
#define USIM_API_SQN_SIZE USIM_API_AK_SIZE
|
||||
u8 sqn[USIM_API_SQN_SIZE];
|
||||
|
||||
for (i = 0; i < USIM_API_SQN_SIZE; i++) {
|
||||
sqn[i] = autn_pP->value[i] ^ ak[i];
|
||||
}
|
||||
|
||||
LOG_TRACE(DEBUG, "USIM-API - Retrieved SQN %02X%02X%02X%02X%02X%02X",
|
||||
sqn[0],sqn[1],sqn[2],sqn[3],sqn[4],sqn[5]);
|
||||
|
||||
/* Compute XMAC = f1K (SQN || RAND || AMF) */
|
||||
#define USIM_API_XMAC_SIZE 8
|
||||
u8 xmac[USIM_API_XMAC_SIZE];
|
||||
f1(_usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac);
|
||||
LOG_TRACE(DEBUG,
|
||||
"USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
xmac[0],xmac[1],xmac[2],xmac[3],
|
||||
xmac[4],xmac[5],xmac[6],xmac[7]);
|
||||
|
||||
/* Compare the XMAC with the MAC included in AUTN */
|
||||
#define USIM_API_AMF_SIZE 2
|
||||
|
||||
if ( memcmp(xmac, &autn_pP->value[USIM_API_SQN_SIZE + USIM_API_AMF_SIZE],
|
||||
USIM_API_XMAC_SIZE) != 0 ) {
|
||||
LOG_TRACE(INFO,
|
||||
"USIM-API - Comparing the XMAC with the MAC included in AUTN Failed");
|
||||
//LOG_FUNC_RETURN (RETURNerror);
|
||||
} else {
|
||||
LOG_TRACE(INFO,
|
||||
"USIM-API - Comparing the XMAC with the MAC included in AUTN Succeeded");
|
||||
}
|
||||
|
||||
/* Verify that the received sequence number SQN is in the correct range */
|
||||
rc = _usim_api_check_sqn(*(uint32_t*)(sqn), sqn[USIM_API_SQN_SIZE - 1]);
|
||||
|
||||
if (rc != RETURNok) {
|
||||
/* Synchronisation failure; compute the AUTS parameter */
|
||||
|
||||
/* Concealed value of the counter SQNms in the USIM:
|
||||
* Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */
|
||||
f5star(_usim_api_k, rand_pP->value, ak);
|
||||
|
||||
#define USIM_API_SQNMS_SIZE USIM_API_SQN_SIZE
|
||||
u8 sqn_ms[USIM_API_SQNMS_SIZE];
|
||||
memset(sqn_ms, 0, USIM_API_SQNMS_SIZE);
|
||||
#define USIM_API_SQN_MS_SIZE 3
|
||||
|
||||
for (i = 0; i < USIM_API_SQN_MS_SIZE; i++) {
|
||||
#warning "LG:BUG HERE TODO"
|
||||
sqn_ms[USIM_API_SQNMS_SIZE - i] =
|
||||
((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQN_MS_SIZE - i];
|
||||
}
|
||||
|
||||
u8 sqnms[USIM_API_SQNMS_SIZE];
|
||||
|
||||
for (i = 0; i < USIM_API_SQNMS_SIZE; i++) {
|
||||
sqnms[i] = sqn_ms[i] ^ ak[i];
|
||||
}
|
||||
|
||||
LOG_TRACE(DEBUG, "USIM-API - SQNms %02X%02X%02X%02X%02X%02X",
|
||||
sqnms[0],sqnms[1],sqnms[2],sqnms[3],sqnms[4],sqnms[5]);
|
||||
|
||||
/* Synchronisation message authentication code:
|
||||
* MACS = f1*K(SQNMS || RAND || AMF) */
|
||||
#define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE
|
||||
u8 macs[USIM_API_MACS_SIZE];
|
||||
f1star(_usim_api_k, rand_pP->value, sqn_ms,
|
||||
&rand_pP->value[USIM_API_SQN_SIZE], macs);
|
||||
LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
macs[0],macs[1],macs[2],macs[3],
|
||||
macs[4],macs[5],macs[6],macs[7]);
|
||||
|
||||
/* Synchronisation authentication token:
|
||||
* AUTS = Conc(SQNMS) || MACS */
|
||||
memcpy(&auts_pP->value[0], sqnms, USIM_API_SQNMS_SIZE);
|
||||
memcpy(&auts_pP->value[USIM_API_SQNMS_SIZE], macs, USIM_API_MACS_SIZE);
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/********************* L O C A L F U N C T I O N S *********************/
|
||||
/****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: _usim_api_hex_char_to_hex_value() **
|
||||
** **
|
||||
** Description: Converts an hexadecimal ASCII coded digit into its value. **
|
||||
** **
|
||||
** Inputs: c: A char holding the ASCII coded value **
|
||||
** Others: None **
|
||||
** **
|
||||
** Outputs: None **
|
||||
** Return: Converted value **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static uint8_t _usim_api_hex_char_to_hex_value (char c)
|
||||
{
|
||||
if (c >= 'A') {
|
||||
/* Remove case bit */
|
||||
c &= ~('a' ^ 'A');
|
||||
|
||||
return (c - 'A' + 10);
|
||||
} else {
|
||||
return (c - '0');
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: _usim_api_hex_string_to_hex_value() **
|
||||
** **
|
||||
** Description: Converts an hexadecimal ASCII coded string into its value.**
|
||||
** **
|
||||
** Inputs: hex_value: A pointer to the location to store the **
|
||||
** conversion result **
|
||||
** size: The size of hex_value in bytes **
|
||||
** Others: None **
|
||||
** **
|
||||
** Outputs: hex_value: Converted value **
|
||||
** Return: None **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static void _usim_api_hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < size; i++) {
|
||||
hex_value[i] = (_usim_api_hex_char_to_hex_value(hex_string[2 * i]) << 4) | _usim_api_hex_char_to_hex_value(hex_string[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: _usim_api_check_sqn() **
|
||||
** **
|
||||
** Description: Verifies the freshness of sequence numbers to determine **
|
||||
** whether the specified sequence number is in the correct **
|
||||
** range and acceptabled by the USIM. **
|
||||
** **
|
||||
** 3GPP TS 33.102, Annex C.2 **
|
||||
** **
|
||||
** Inputs: seq: Sequence number value **
|
||||
** ind: Index value **
|
||||
** Others: None **
|
||||
** **
|
||||
** Outputs: None **
|
||||
** Return: RETURNerror, RETURNok **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _usim_api_check_sqn(uint32_t seq, uint8_t ind)
|
||||
{
|
||||
/* TODO */
|
||||
return (RETURNok);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user