Commit d77827b3 authored by winckel's avatar winckel

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4891 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent e9c4d622
/usr/share/automake-1.11/COPYING
\ No newline at end of file
This diff is collapsed.
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = access_restriction auc db s6a utils tests .
AM_CFLAGS = @ADD_CFLAGS@ \
-I$(top_srcdir)/access_restriction \
-I$(top_srcdir)/auc \
-I$(top_srcdir)/db \
-I$(top_srcdir)/s6a \
-I$(top_srcdir)/utils
bin_PROGRAMS = openair-hss
openair_hssdir=$(sysconfdir)/openair-hss
openair_hss_DATA = $(top_builddir)/conf/hss.conf $(top_srcdir)/conf/hss_fd.conf
openair_hss_LDADD = \
$(top_builddir)/s6a/libs6a.la \
$(top_builddir)/db/libdb.la \
$(top_builddir)/auc/libauc.la \
$(top_builddir)/access_restriction/libaccess_restriction.la \
$(top_builddir)/utils/libutils.la
openair_hss_SOURCES = \
hss_config.h \
hss_main.c
AM_CFLAGS = @ADD_CFLAGS@ \
-I$(top_srcdir) \
-I$(top_srcdir)/utils
noinst_LTLIBRARIES = libaccess_restriction.la
libaccess_restriction_la_LDFLAGS = -all-static
libaccess_restriction_la_SOURCES = \
access_restriction.c access_restriction.h
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "conversion.h"
#include "access_restriction.h"
/* TODO: identification of MCC and MNC within an IMSI should be done according
* to a table that maps MCC to 2 or 3 digits expected...
* By default we will assume there is only 2 digits for our use.
*/
/* Split a PLMN formed of <MCC><MNC> to mcc and mnc.
* In case MNC is formed of only two digits a 0 is inserted at the most significant
* digit.
* When PLMN is represented using european convention it contains only two digits,
* while three digits are used in North American Standard.
* Encoding of PLMN is defined in ITU E.212.
* @param plmn string either 5 or 6 digits resulting of the concatenation of
* MCC and MNC.
*/
int split_plmn(uint8_t plmn[3], uint8_t mcc[3], uint8_t mnc[3])
{
if (plmn == NULL) {
return -1;
}
mcc[0] = plmn[0] & 0x0F;
mcc[1] = (plmn[0] & 0xF0) >> 4;
mcc[2] = plmn[1] & 0x0F;
if ((plmn[1] & 0xF0) == 0xF0) {
/* Only 2 digits case */
mnc[1] = plmn[2] & 0x0F;
mnc[2] = (plmn[2] & 0xF0) >> 4;
mnc[0] = 0;
} else {
mnc[0] = plmn[2] & 0x0F;
mnc[1] = (plmn[2] & 0xF0) >> 4;
mnc[2] = ((plmn[1] & 0xF0) >> 4);
}
return 0;
}
/* Apply restriction (if any) to current 'visited' PLMN for this user.
* Criterias are based on ODB (operator determined barring), visited PLMN
* and user PLMN (obtain from IMSI).
* @param imsi is the user identity formed of MCC.MNC.MSIN (14 or 15 digits long)
* @param vplmn is the plmn of the cell the UE is currently attached to
*/
#define FORMAT_MCC(mCC) (mCC[0] * 100 + mCC[1] * 10 + mCC[2])
#define FORMAT_MNC(mNC) (mNC[0] * 100 + mNC[1] * 10 + mNC[2])
int apply_access_restriction(char *imsi, uint8_t *vplmn)
{
uint8_t vmcc[3], vmnc[3];
uint8_t hmcc[3], hmnc[3];
uint8_t imsi_hex[15];
if (bcd_to_hex(imsi_hex, imsi, strlen(imsi)) != 0) {
fprintf(stderr, "Failed to convert imsi %s to hex representation\n",
imsi);
return -1;
}
/* There is a problem while converting the PLMN... */
if (split_plmn(vplmn, vmcc, vmnc) != 0) {
fprintf(stderr, "Fail to convert vplmn %02x%02x%02x to mcc/mnc for imsi %s\n",
vplmn[0], vplmn[1], vplmn[2], imsi);
return -1;
}
fprintf(stderr, "Converted %02x%02x%02x to plmn %u.%u\n", vplmn[0], vplmn[1], vplmn[2],
FORMAT_MCC(vmcc), FORMAT_MNC(vmnc));
/* MCC is always 3 digits */
memcpy(hmcc, &imsi_hex[0], 3);
if (memcmp(vmcc, hmcc, 3) != 0) {
fprintf(stderr, "Only France MCC is handled for now, got imsi plmn %u.%u for a visited plmn %u.%u\n",
FORMAT_MCC(hmcc), FORMAT_MNC(hmnc), FORMAT_MCC(vmcc), FORMAT_MNC(vmnc));
/* Reject the association */
return -1;
}
/* In France MNC is composed of 2 digits and thus imsi by 14 digit */
hmnc[0] = 0;
memcpy(&hmnc[1], &imsi_hex[3], 2);
if ((memcmp(vmcc, hmcc, 3) != 0) && (memcmp(vmnc, hmnc, 3) != 0)) {
fprintf(stderr, "UE is roaming from %u.%u to %u.%u which is not allowed"
" by the ODB\n", FORMAT_MCC(hmcc), FORMAT_MNC(hmnc), FORMAT_MCC(vmcc), FORMAT_MNC(vmnc));
return -1;
}
/* User has successfully passed all the checking -> accept the association */
return 0;
}
#ifndef ACCESS_RESTRICTION_H_
#define ACCESS_RESTRICTION_H_
int split_plmn(uint8_t *plmn, uint8_t mcc[3], uint8_t mnc[3]);
int apply_access_restriction(char *imsi, uint8_t *vplmn);
#endif /* ACCESS_RESTRICTION_H_ */
AM_CFLAGS = @ADD_CFLAGS@ \
-I$(top_srcdir) \
-I$(top_srcdir)/utils
noinst_LTLIBRARIES = libauc.la
libauc_la_LDFLAGS = -all-static
libauc_la_SOURCES = \
auc.h \
fx.c \
kdf.c \
random.c \
rijndael.c \
sequence_number.c
\ No newline at end of file
#include <stdint.h>
#include <stdio.h>
#include <gmp.h>
#ifndef AUC_H_
#define AUC_H_
#define SQN_LENGTH_BITS (48)
#define SQN_LENGTH_OCTEST (SQN_LENGTH_BITS/8)
#define IK_LENGTH_BITS (128)
#define IK_LENGTH_OCTETS (IK_LENGTH_BITS/8)
#define RAND_LENGTH_OCTETS (16)
#define RAND_LENGTH_BITS (RAND_LENGTH_OCTETS*8)
#define XRES_LENGTH_OCTETS (8)
#define AUTN_LENGTH_OCTETS (16)
#define KASME_LENGTH_OCTETS (32)
#define MAC_S_LENGTH (8)
extern uint8_t opc[16];
typedef mpz_t random_t;
typedef mpz_t sqn_t;
typedef uint8_t u8;
typedef struct {
uint8_t rand[16];
uint8_t rand_new;
uint8_t xres[8];
uint8_t autn[16];
uint8_t kasme[32];
} auc_vector_t;
void RijndaelKeySchedule(u8 key[16]);
void RijndaelEncrypt(u8 in[16], u8 out[16]);
/* Sequence number functions */
struct sqn_ue_s;
struct sqn_ue_s *sqn_exists(uint64_t imsi);
void sqn_insert(struct sqn_ue_s *item);
void sqn_init(struct sqn_ue_s *item);
struct sqn_ue_s *sqn_new(uint64_t imsi);
void sqn_list_init(void);
void sqn_get(uint64_t imsi, uint8_t sqn[6]);
/* Random number functions */
struct random_state_s;
void random_init(void);
void generate_random(uint8_t *random, ssize_t length);
void SetOPc(u8 op_c[16]);
void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
u8 mac_a[8] );
void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
u8 mac_s[8] );
void f2345 ( u8 k[16], u8 rand[16],
u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6] );
void f5star( u8 k[16], u8 rand[16],
u8 ak[6] );
void generate_autn(u8 sqn[6], u8 ak[6], u8 amf[2], u8 mac_a[8], u8 autn[16]);
int generate_vector(uint64_t imsi, uint8_t key[16], uint8_t plmn[3],
uint8_t sqn[6], auc_vector_t *vector);
inline
void kdf(uint8_t *key, uint16_t key_len, uint8_t *s, uint16_t s_len, uint8_t *out,
uint16_t out_len);
inline
void derive_kasme(uint8_t ck[16], uint8_t ik[16], uint8_t plmn[3], uint8_t sqn[6],
uint8_t ak[6], uint8_t kasme[32]);
uint8_t *sqn_ms_derive(uint8_t *key, uint8_t *auts, uint8_t *rand);
static inline void print_buffer(const char *prefix, uint8_t *buffer, int length)
{
int i;
fprintf(stdout, "%s", prefix);
for (i = 0; i < length; i++) {
fprintf(stdout, "%02x.", buffer[i]);
}
fprintf(stdout, "\n");
}
#endif /* AUC_H_ */
/*-------------------------------------------------------------------
* Example algorithms f1, f1*, f2, f3, f4, f5, f5*
*-------------------------------------------------------------------
*
* A sample implementation of the example 3GPP authentication and
* key agreement functions f1, f1*, f2, f3, f4, f5 and f5*. This is
* a byte-oriented implementation of the functions, and of the block
* cipher kernel function Rijndael.
*
* This has been coded for clarity, not necessarily for efficiency.
*
* The functions f2, f3, f4 and f5 share the same inputs and have
* been coded together as a single function. f1, f1* and f5* are
* all coded separately.
*
*-----------------------------------------------------------------*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "auc.h"
/*--------- Operator Variant Algorithm Configuration Field --------*/
/*------- Insert your value of OP here -------*/
u8 OP[16];
/*--------------------------- prototypes --------------------------*/
void ComputeOPc( u8 op_c[16] );
void SetOPc(u8 op_c[16])
{
memcpy(OP, op_c, 16);
}
void generate_autn(u8 sqn[6], u8 ak[6], u8 amf[2], u8 mac_a[8], u8 autn[16])
{
int i;
for (i = 0; i < 6; i++) {
autn[i] = sqn[i] ^ ak[i];
}
memcpy(&autn[6], amf, 2);
memcpy(&autn[8], mac_a, 8);
}
/*-------------------------------------------------------------------
* Algorithm f1
*-------------------------------------------------------------------
*
* Computes network authentication code MAC-A from key K, random
* challenge RAND, sequence number SQN and authentication management
* field AMF.
*
*-----------------------------------------------------------------*/
void f1 ( u8 k[16], u8 _rand[16], u8 sqn[6], u8 amf[2],
u8 mac_a[8] )
{
u8 op_c[16];
u8 temp[16];
u8 in1[16];
u8 out1[16];
u8 rijndaelInput[16];
u8 i;
RijndaelKeySchedule( k );
ComputeOPc( op_c );
for (i=0; i<16; i++)
rijndaelInput[i] = _rand[i] ^ op_c[i];
RijndaelEncrypt( rijndaelInput, temp );
for (i=0; i<6; i++)
{
in1[i] = sqn[i];
in1[i+8] = sqn[i];
}
for (i=0; i<2; i++)
{
in1[i+6] = amf[i];
in1[i+14] = amf[i];
}
/* XOR op_c and in1, rotate by r1=64, and XOR *
* on the constant c1 (which is all zeroes) */
for (i=0; i<16; i++)
rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i];
/* XOR on the value temp computed before */
for (i=0; i<16; i++)
rijndaelInput[i] ^= temp[i];
RijndaelEncrypt( rijndaelInput, out1 );
for (i=0; i<16; i++)
out1[i] ^= op_c[i];
for (i=0; i<8; i++)
mac_a[i] = out1[i];
return;
} /* end of function f1 */
/*-------------------------------------------------------------------
* Algorithms f2-f5
*-------------------------------------------------------------------
*
* Takes key K and random challenge RAND, and returns response RES,
* confidentiality key CK, integrity key IK and anonymity key AK.
*
*-----------------------------------------------------------------*/
void f2345 ( u8 k[16], u8 _rand[16],
u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6] )
{
u8 op_c[16];
u8 temp[16];
u8 out[16];
u8 rijndaelInput[16];
u8 i;
RijndaelKeySchedule( k );
ComputeOPc( op_c );
for (i=0; i<16; i++)
rijndaelInput[i] = _rand[i] ^ op_c[i];
RijndaelEncrypt( rijndaelInput, temp );
/* To obtain output block OUT2: XOR OPc and TEMP, *
* rotate by r2=0, and XOR on the constant c2 (which *
* is all zeroes except that the last bit is 1). */
for (i=0; i<16; i++)
rijndaelInput[i] = temp[i] ^ op_c[i];
rijndaelInput[15] ^= 1;
RijndaelEncrypt( rijndaelInput, out );
for (i=0; i<16; i++)
out[i] ^= op_c[i];
for (i=0; i<8; i++)
res[i] = out[i+8];
for (i=0; i<6; i++)
ak[i] = out[i];
/* To obtain output block OUT3: XOR OPc and TEMP, *
* rotate by r3=32, and XOR on the constant c3 (which *
* is all zeroes except that the next to last bit is 1). */
for (i=0; i<16; i++)
rijndaelInput[(i+12) % 16] = temp[i] ^ op_c[i];
rijndaelInput[15] ^= 2;
RijndaelEncrypt( rijndaelInput, out );
for (i=0; i<16; i++)
out[i] ^= op_c[i];
for (i=0; i<16; i++)
ck[i] = out[i];
/* To obtain output block OUT4: XOR OPc and TEMP, *
* rotate by r4=64, and XOR on the constant c4 (which *
* is all zeroes except that the 2nd from last bit is 1). */
for (i=0; i<16; i++)
rijndaelInput[(i+8) % 16] = temp[i] ^ op_c[i];
rijndaelInput[15] ^= 4;
RijndaelEncrypt( rijndaelInput, out );
for (i=0; i<16; i++)
out[i] ^= op_c[i];
for (i=0; i<16; i++)
ik[i] = out[i];
return;
} /* end of function f2345 */
/*-------------------------------------------------------------------
* Algorithm f1*
*-------------------------------------------------------------------
*
* Computes resynch authentication code MAC-S from key K, random
* challenge RAND, sequence number SQN and authentication management
* field AMF.
*
*-----------------------------------------------------------------*/
void f1star( u8 k[16], u8 _rand[16], u8 sqn[6], u8 amf[2],
u8 mac_s[8] )
{
u8 op_c[16];
u8 temp[16];
u8 in1[16];
u8 out1[16];
u8 rijndaelInput[16];
u8 i;
RijndaelKeySchedule( k );
ComputeOPc( op_c );
for (i=0; i<16; i++)
rijndaelInput[i] = _rand[i] ^ op_c[i];
RijndaelEncrypt( rijndaelInput, temp );
for (i=0; i<6; i++)
{
in1[i] = sqn[i];
in1[i+8] = sqn[i];
}
for (i=0; i<2; i++)
{
in1[i+6] = amf[i];
in1[i+14] = amf[i];
}
/* XOR op_c and in1, rotate by r1=64, and XOR *
* on the constant c1 (which is all zeroes) */
for (i=0; i<16; i++)
rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i];
/* XOR on the value temp computed before */
for (i=0; i<16; i++)
rijndaelInput[i] ^= temp[i];
RijndaelEncrypt( rijndaelInput, out1 );
for (i=0; i<16; i++)
out1[i] ^= op_c[i];
for (i=0; i<8; i++)
mac_s[i] = out1[i+8];
return;
} /* end of function f1star */
/*-------------------------------------------------------------------
* Algorithm f5*
*-------------------------------------------------------------------
*
* Takes key K and random challenge RAND, and returns resynch
* anonymity key AK.
*
*-----------------------------------------------------------------*/
void f5star( u8 k[16], u8 _rand[16],
u8 ak[6] )
{
u8 op_c[16];
u8 temp[16];
u8 out[16];
u8 rijndaelInput[16];
u8 i;
RijndaelKeySchedule( k );
ComputeOPc( op_c );
for (i=0; i<16; i++)
rijndaelInput[i] = _rand[i] ^ op_c[i];
RijndaelEncrypt( rijndaelInput, temp );
/* To obtain output block OUT5: XOR OPc and TEMP, *
* rotate by r5=96, and XOR on the constant c5 (which *
* is all zeroes except that the 3rd from last bit is 1). */
for (i=0; i<16; i++)
rijndaelInput[(i+4) % 16] = temp[i] ^ op_c[i];
rijndaelInput[15] ^= 8;
RijndaelEncrypt( rijndaelInput, out );
for (i=0; i<16; i++)
out[i] ^= op_c[i];
for (i=0; i<6; i++)
ak[i] = out[i];
return;
} /* end of function f5star */
/*-------------------------------------------------------------------
* Function to compute OPc from OP and K. Assumes key schedule has
a lready been performed. *
*-----------------------------------------------------------------*/
void ComputeOPc( u8 op_c[16] )
{
u8 i;
RijndaelEncrypt( OP, op_c );
for (i=0; i<16; i++)
op_c[i] ^= OP[i];
return;
} /* end of function ComputeOPc */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <gmp.h>
#include <nettle/hmac.h>
#include "auc.h"
uint8_t opc[16] = {
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
};
/*
* @param key the input key
* @param key_len length of the key
* @param s string for key derivation as defined in 3GPP TS.33401 Annex A
* @param s_len length of s
* @param out buffer to place the output of kdf
* @param ou_len expected length for the output key
*/
inline
void kdf(uint8_t *key, uint16_t key_len, uint8_t *s, uint16_t s_len, uint8_t *out,
uint16_t out_len)
{
struct hmac_sha256_ctx ctx;
memset(&ctx, 0, sizeof(ctx));
hmac_sha256_set_key(&ctx, key_len, key);
hmac_sha256_update(&ctx, s_len, s);
hmac_sha256_digest(&ctx, out_len, out);
}
/*
* Derive the Kasme using the KDF (key derive function).
* See 3GPP TS.33401 Annex A.2
* The input String S to the KDF is composed of 14 bytes:
* FC = 0x10
* P0 = SN id = PLMN
* L0 = length(SN id) = 0x00 0x03
* P1 = SQN xor AK
* L1 = length(P1) = 0x00 0x06
*/
inline
void derive_kasme(uint8_t ck[16], uint8_t ik[16], uint8_t plmn[3], uint8_t sqn[6],
uint8_t ak[6], uint8_t *kasme)
{
uint8_t s[14];
int i;
uint8_t key[32];
/* The input key is equal to the concatenation of CK and IK */
memcpy(&key[0], ck, 16);
memcpy(&key[16], ik, 16);
SetOPc(opc);
/* FC */
s[0] = 0x10;
/* SN id is composed of MCC and MNC
* Octets:
* 1 MCC digit 2 | MCC digit 1
* 2 MNC digit 3 | MCC digit 3
* 3 MNC digit 2 | MNC digit 1
*/
memcpy(&s[1], plmn, 3);
/* L0 */
s[4] = 0x00;
s[5] = 0x03;
/* P1 */
for (i = 0; i < 6; i++) {
s[6 + i] = sqn[i] ^ ak[i];
}
/* L1 */
s[12] = 0x00;
s[13] = 0x06;
#if defined(DEBUG_AUC_KDF)
for (i = 0; i < 32; i++)
printf("0x%02x ", key[i]);
printf("\n");
for (i = 0; i < 14; i++)
printf("0x%02x ", s[i]);
printf("\n");
#endif
kdf(key, 32, s, 14, kasme, 32);
}
int generate_vector(uint64_t imsi, uint8_t key[16], uint8_t plmn[3],
uint8_t sqn[6], auc_vector_t *vector)
{
/* in E-UTRAN an authentication vector is composed of:
* - RAND
* - XRES
* - AUTN
* - KASME
*/
uint8_t amf[] = { 0x80, 0x00 };
uint8_t mac_a[8];
uint8_t ck[16];
uint8_t ik[16];
uint8_t ak[6];
int i;
if (vector == NULL) {
return EINVAL;
}
/* Compute MAC */
f1(key, vector->rand, sqn, amf, mac_a);
print_buffer("MAC_A : ", mac_a, 8);
print_buffer("SQN : ", sqn, 6);
print_buffer("AK : ", ak, 6);
print_buffer("RAND : ", vector->rand, 16);
/* Compute XRES, CK, IK, AK */
f2345(key, vector->rand, vector->xres, ck, ik, ak);
/* AUTN = SQN ^ AK || AMF || MAC */
generate_autn(sqn, ak, amf, mac_a, vector->autn);
print_buffer("XRES : ", vector->xres, 8);
derive_kasme(ck, ik, plmn, sqn, ak, vector->kasme);
print_buffer("KASME : ", vector->kasme, 32);
return 0;
}
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <gmp.h>
#include <sys/time.h>
#include "auc.h"
typedef struct random_state_s {
pthread_mutex_t lock;
gmp_randstate_t state;
} random_state_t;
random_state_t random_state;
void random_init(void)
{
// mpz_t number;
// pthread_mutex_init(&random_state.lock, NULL);
// mpz_init(number);
// gmp_randinit_default(random_state.state);
// srand(time(NULL));
struct timeval t1;
gettimeofday(&t1, NULL);
srand(t1.tv_usec * t1.tv_sec);
}
/* Generate a random number between 0 and 2^length - 1 where length is expressed
* in bits.
*/
void generate_random(uint8_t *random_p, ssize_t length)
{
// random_t random_nb;
// mpz_init_set_ui(random_nb, 0);
// pthread_mutex_lock(&random_state.lock);
// mpz_urandomb(random_nb, random_state.state, 8 * length);
// pthread_mutex_unlock(&random_state.lock);
// mpz_export(random_p, NULL, 1, length, 0, 0, random_nb);
int r = 0, i, mask = 0, shift;
for (i = 0; i < length; i ++) {
// if ((i % sizeof(i)) == 0)
// r = rand();
// shift = 8 * (i % sizeof(i));
// mask = 0xFF << shift;
// random_p[i] = (r & mask) >> shift;
random_p[i] = rand();
}
}
#include <stdlib.h>
#include <stdint.h>
#include <gmp.h>
#include "auc.h"
typedef uint8_t u8;
typedef uint32_t u32;
/*-------------------- Rijndael round subkeys ---------------------*/
u8 roundKeys[11][4][4];
/*--------------------- Rijndael S box table ----------------------*/
u8 S[256] = {
99,124,119,123,242,107,111,197, 48, 1,103, 43,254,215,171,118,
202,130,201,125,250, 89, 71,240,173,212,162,175,156,164,114,192,
183,253,147, 38, 54, 63,247,204, 52,165,229,241,113,216, 49, 21,
4,199, 35,195, 24,150, 5,154, 7, 18,128,226,235, 39,178,117,
9,131, 44, 26, 27,110, 90,160, 82, 59,214,179, 41,227, 47,132,
83,209, 0,237, 32,252,177, 91,106,203,190, 57, 74, 76, 88,207,
208,239,170,251, 67, 77, 51,133, 69,249, 2,127, 80, 60,159,168,
81,163, 64,143,146,157, 56,245,188,182,218, 33, 16,255,243,210,
205, 12, 19,236, 95,151, 68, 23,196,167,126, 61,100, 93, 25,115,
96,129, 79,220, 34, 42,144,136, 70,238,184, 20,222, 94, 11,219,
224, 50, 58, 10, 73, 6, 36, 92,194,211,172, 98,145,149,228,121,
231,200, 55,109,141,213, 78,169,108, 86,244,234,101,122,174, 8,
186,120, 37, 46, 28,166,180,198,232,221,116, 31, 75,189,139,138,
112, 62,181,102, 72, 3,246, 14, 97, 53, 87,185,134,193, 29,158,
225,248,152, 17,105,217,142,148,155, 30,135,233,206, 85, 40,223,
140,161,137, 13,191,230, 66,104, 65,153, 45, 15,176, 84,187, 22,
};
/*------- This array does the multiplication by x in GF(2^8) ------*/
u8 Xtime[256] = {
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
96, 98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,
128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,
160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,
192,194,196,198,200,202,204,206,208,210,212,214,216,218,220,222,
224,226,228,230,232,234,236,238,240,242,244,246,248,250,252,254,
27, 25, 31, 29, 19, 17, 23, 21, 11, 9, 15, 13, 3, 1, 7, 5,
59, 57, 63, 61, 51, 49, 55, 53, 43, 41, 47, 45, 35, 33, 39, 37,
91, 89, 95, 93, 83, 81, 87, 85, 75, 73, 79, 77, 67, 65, 71, 69,
123,121,127,125,115,113,119,117,107,105,111,109, 99, 97,103,101,
155,153,159,157,147,145,151,149,139,137,143,141,131,129,135,133,
187,185,191,189,179,177,183,181,171,169,175,173,163,161,167,165,
219,217,223,221,211,209,215,213,203,201,207,205,195,193,199,197,
251,249,255,253,243,241,247,245,235,233,239,237,227,225,231,229
};
/*-------------------------------------------------------------------
* Rijndael key schedule function. Takes 16-byte key and creates
* all Rijndael's internal subkeys ready for encryption.
*-----------------------------------------------------------------*/
void RijndaelKeySchedule( u8 key[16] )
{
u8 roundConst;
int i, j;
/* first round key equals key */
for (i=0; i<16; i++)
roundKeys[0][i & 0x03][i>>2] = key[i];
roundConst = 1;
/* now calculate round keys */
for (i=1; i<11; i++)
{
roundKeys[i][0][0] = S[roundKeys[i-1][1][3]]
^ roundKeys[i-1][0][0] ^ roundConst;
roundKeys[i][1][0] = S[roundKeys[i-1][2][3]]
^ roundKeys[i-1][1][0];
roundKeys[i][2][0] = S[roundKeys[i-1][3][3]]
^ roundKeys[i-1][2][0];
roundKeys[i][3][0] = S[roundKeys[i-1][0][3]]
^ roundKeys[i-1][3][0];
for (j=0; j<4; j++)
{
roundKeys[i][j][1] = roundKeys[i-1][j][1] ^ roundKeys[i][j][0];
roundKeys[i][j][2] = roundKeys[i-1][j][2] ^ roundKeys[i][j][1];
roundKeys[i][j][3] = roundKeys[i-1][j][3] ^ roundKeys[i][j][2];
}
/* update round constant */
roundConst = Xtime[roundConst];
}
return;
} /* end of function RijndaelKeySchedule */
/* Round key addition function */
void KeyAdd(u8 state[4][4], u8 roundKeys[11][4][4], int round)
{
int i, j;
for (i=0; i<4; i++)
for (j=0; j<4; j++)
state[i][j] ^= roundKeys[round][i][j];
return;
}
/* Byte substitution transformation */
int ByteSub(u8 state[4][4])
{
int i, j;
for (i=0; i<4; i++)
for (j=0; j<4; j++)
state[i][j] = S[state[i][j]];
return 0;
}
/* Row shift transformation */
void ShiftRow(u8 state[4][4])
{
u8 temp;
/* left rotate row 1 by 1 */
temp = state[1][0];
state[1][0] = state[1][1];
state[1][1] = state[1][2];
state[1][2] = state[1][3];
state[1][3] = temp;
/* left rotate row 2 by 2 */
temp = state[2][0];
state[2][0] = state[2][2];
state[2][2] = temp;
temp = state[2][1];
state[2][1] = state[2][3];
state[2][3] = temp;
/* left rotate row 3 by 3 */
temp = state[3][0];
state[3][0] = state[3][3];
state[3][3] = state[3][2];
state[3][2] = state[3][1];
state[3][1] = temp;
return;
}
/* MixColumn transformation*/
void MixColumn(u8 state[4][4])
{
u8 temp, tmp, tmp0;
int i;
/* do one column at a time */
for (i=0; i<4;i++)
{
temp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i];
tmp0 = state[0][i];
/* Xtime array does multiply by x in GF2^8 */
tmp = Xtime[state[0][i] ^ state[1][i]];
state[0][i] ^= temp ^ tmp;
tmp = Xtime[state[1][i] ^ state[2][i]];
state[1][i] ^= temp ^ tmp;
tmp = Xtime[state[2][i] ^ state[3][i]];
state[2][i] ^= temp ^ tmp;
tmp = Xtime[state[3][i] ^ tmp0];
state[3][i] ^= temp ^ tmp;
}
return;
}
/*-------------------------------------------------------------------
* Rijndael encryption function. Takes 16-byte input and creates
* 16-byte output (using round keys already derived from 16-byte
* key).
*-----------------------------------------------------------------*/
void RijndaelEncrypt( u8 input[16], u8 output[16] )
{
u8 state[4][4];
int i, r;
/* initialise state array from input byte string */
for (i=0; i<16; i++)
state[i & 0x3][i>>2] = input[i];
/* add first round_key */
KeyAdd(state, roundKeys, 0);
/* do lots of full rounds */
for (r=1; r<=9; r++)
{
ByteSub(state);
ShiftRow(state);
MixColumn(state);
KeyAdd(state, roundKeys, r);
}
/* final round */
ByteSub(state);
ShiftRow(state);
KeyAdd(state, roundKeys, r);
/* produce output byte string from state array */
for (i=0; i<16; i++)
{
output[i] = state[i & 0x3][i>>2];
}
return;
} /* end of function RijndaelEncrypt */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "auc.h"
uint8_t *sqn_ms_derive(uint8_t *key, uint8_t *auts, uint8_t *rand_p)
{
/* AUTS = Conc(SQN MS ) || MAC-S
* Conc(SQN MS ) = SQN MS ^ f5* (RAND)
* MAC-S = f1* (SQN MS || RAND || AMF)
*/
uint8_t ak[6];
uint8_t *conc_sqn_ms;
uint8_t *mac_s;
uint8_t mac_s_computed[MAC_S_LENGTH];
uint8_t *sqn_ms;
uint8_t amf[2] = { 0, 0 };
int i;
conc_sqn_ms = auts;
mac_s = &auts[6];
sqn_ms = malloc(SQN_LENGTH_OCTEST);
SetOPc(opc);
/* Derive AK from key and rand */
f5star(key, rand_p, ak);
for (i = 0; i < 6; i++) {
sqn_ms[i] = ak[i] ^ conc_sqn_ms[i];
}
print_buffer("KEY : ", key, 16);
print_buffer("RAND : ", rand_p, 16);
print_buffer("AUTS : ", auts, 14);
print_buffer("AK : ", ak, 6);
print_buffer("SQN_MS : ", sqn_ms, 6);
print_buffer("MAC_S : ", mac_s, 8);
f1star(key, rand_p, sqn_ms, amf, mac_s_computed);
print_buffer("MAC_S +: ", mac_s_computed, 8);
if (memcmp(mac_s_computed, mac_s, 8) != 0) {
fprintf(stderr, "Failed to verify computed SQN_MS\n");
free(sqn_ms);
return NULL;
}
return sqn_ms;
}
#!/bin/sh
autoreconf --force --install -I m4
\ No newline at end of file
## MySQL mandatory options
MYSQL_server = "127.0.0.1";
MYSQL_user = "hssadmin";
MYSQL_pass = "admin";
MYSQL_db = "oai_db";
## Freediameter options
FD_conf = "/etc/openair-hss/hss_fd.conf";
## MySQL mandatory options
MYSQL_server = "127.0.0.1";
MYSQL_user = "hssadmin";
MYSQL_pass = "admin";
MYSQL_db = "oai_db";
## Freediameter options
FD_conf = "@AM_CONF_DIR@/hss_fd.conf";
# -------- Local ---------
# Uncomment if the framework cannot resolv it.
Identity = "hss.eur";
# TLS configuration (see previous section)
TLS_Cred = "/homes/roux/lte-epc/openair3/OPENAIRHSS/conf/hss.cert.pem",
"/homes/roux/lte-epc/openair3/OPENAIRHSS/conf/hss.key.pem";
TLS_CA = "/homes/roux/lte-epc/openair3/OPENAIRHSS/conf/cacert.pem";
# Disable use of TCP protocol (only listen and connect in SCTP)
# Default : TCP enabled
No_TCP;
#No_SCTP;
# Disable use of IPv6 addresses (only IP)
# Default : IPv6 enabled
# No_IPv6;
# Limit the number of SCTP streams
SCTP_streams = 15;
NoRelay;
TLS_old_method;
# Core 2 DUO
AppServThreads = 4;
# -------- Extensions ---------
# Uncomment (and create rtd.conf) to specify routing table for this peer.
#LoadExtension = "rt_default.fdx" : "rtd.conf";
# Uncomment (and create acl.conf) to allow incoming connections from other peers.
#LoadExtension = "acl_wl.fdx" : "/homes/roux/lte-epc/openair3/OPENAIRHSS/conf/acl.conf";
# Uncomment to display periodic state information
#LoadExtension = "dbg_monitor.fdx";
# Uncomment to enable an interactive Python interpreter session.
# (see doc/dbg_interactive.py.sample for more information)
#LoadExtension = "dbg_interactive.fdx";
# Load the RFC4005 dictionary objects
#LoadExtension = "dict_nasreq.fdx";
LoadExtension = "dict_nas_mipv6.fdx";
LoadExtension = "dict_s6a.fdx";
# Load RFC4072 dictionary objects
#LoadExtension = "dict_eap.fdx";
# Load the Diameter EAP server extension (requires diameap.conf)
#LoadExtension = "app_diameap.fdx" : "diameap.conf";
# Load the Accounting Server extension (requires app_acct.conf)
#LoadExtension = "app_acct.fdx" : "app_acct.conf";
# -------- Peers ---------
# The framework will actively attempt to establish and maintain a connection
# with the peers listed here.
# For only accepting incoming connections, see the acl_wl.fx extension.
#ConnectPeer = "ubuntu.localdomain" { ConnectTo = "127.0.0.1"; No_TLS; };
#ConnectPeer = "roux.test.fr" { No_TLS; };
rm -rf demoCA
mkdir demoCA
echo 01 > demoCA/serial
touch demoCA/index.txt
echo "Creating certificate for HSS"
#
# # CA self certificate
# openssl req -new -batch -x509 -days 3650 -nodes -newkey rsa:1024 -out cacert.pem -keyout cakey.pem -subj /CN=test.fr/C=FR/ST=Biot/L=Aix/O=test.fr/OU=mobiles
#
# openssl genrsa -out hss.key.pem 1024
# openssl req -new -batch -out hss.csr.pem -key hss.key.pem -subj /CN=hss.test.fr/C=FR/ST=Biot/L=Aix/O=test.fr/OU=mobiles
# openssl ca -cert cacert.pem -keyfile cakey.pem -in hss.csr.pem -out hss.cert.pem -outdir . -batch
# CA self certificate
openssl req -new -batch -x509 -days 3650 -nodes -newkey rsa:1024 -out cacert.pem -keyout cakey.pem -subj /CN=eur/C=FR/ST=PACA/L=Aix/O=Eurecom/OU=CM
openssl genrsa -out hss.key.pem 1024
openssl req -new -batch -out hss.csr.pem -key hss.key.pem -subj /CN=hss.eur/C=FR/ST=PACA/L=Aix/O=Eurecom/OU=CM
openssl ca -cert cacert.pem -keyfile cakey.pem -in hss.csr.pem -out hss.cert.pem -outdir . -batch
# openssl genrsa -out $hss.key.pem 1024
# openssl req -new -batch -out $hss.csr.pem -key $hss.key.pem -subj /CN=$hss.test.fr/C=FR/ST=Biot/L=Aix/O=test.fr/OU=mobiles
# openssl ca -cert cacert.pem -keyfile cakey.pem -in $hss.csr.pem -out $hss.cert.pem -outdir . -batch
AC_PREREQ([2.65])
define([svnversion], esyscmd([sh -c "svnversion ..|tr -d '\n'"]))
AC_DEFINE(SVN_REVISION, "svnversion", [SVN Revision])
AC_INIT([openair-hss], [1.0.0.svnversion], [openair_admin@eurecom.fr])
AC_CANONICAL_BUILD
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([1.11 silent-rules])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AM_MAINTAINER_MODE
AM_SILENT_RULES([yes])
PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=true], [HAVE_CHECK=false])
AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xtrue)
AM_PROG_LEX
AM_PROG_LIBTOOL
AC_PROG_YACC
AC_PROG_CXX
AC_PROG_RANLIB
AC_TYPE_INT8_T
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_TYPE_UINT8_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_CHECK_HEADERS([libintl.h malloc.h netinet/in.h stddef.h])
AC_CHECK_FUNCS([memset strdup strerror])
AC_C_INLINE
AC_FUNC_ALLOCA
AC_FUNC_MALLOC
AC_FUNC_REALLOC
dnl *** Autoconf support ***
AC_ARG_ENABLE(autoconf,
[ --disable-autoconf disable automatic generation of configure script ],
enable_autoconf=$enableval, enable_autoconf=yes
)
AC_PATH_PROG(AUTOCONF, autoconf, @echo autoconf not available)
AC_PATH_PROG(AUTOHEADER, autoheader, @echo autoheader not available)
if test -z "$AUTOCONF"; then enable_autoconf=no ; fi
if test -z "$AUTOHEADER"; then enable_autoconf=no ; fi
if test x$enable_autoconf = xyes; then
CONFIGURE_DEPENDS="configure.in"
fi
AC_SUBST(CONFIGURE_DEPENDS)
AC_CHECK_LIB([mysqlclient],
[mysql_init],
[],
[])
dnl ***freediameter support***
AC_CHECK_LIB([fdcore], [fd_core_initialize], [],
[AC_MSG_ERROR(Free diameter lib not installed)])
AC_CHECK_LIB([fdproto], [fd_core_initialize], [],
[AC_MSG_ERROR(Free diameter lib not installed)])
dnl *** Freediameter requirements ***
AC_CHECK_HEADERS([signalent.h])
AC_CHECK_FUNCS([ntohll strndup])
AC_DEFINE([HAVE_AI_ADDRCONFIG], [],
[Define to 1 if you have AI_ADDRCONFIG defined in netdb.h])
AC_DEFINE([HAVE_CLOCK_GETTIME], [],
[Define to 1 if you have clock_gettime in librt])
AC_DEFINE([HAVE_PTHREAD_BAR], [],
[Define to 1 if you have pthread_barrier_wait in libpthread])
AC_DEFINE([SCTP_CONNECTX_4_ARGS], [],
[Define to 1 if sctp_connectx function accepts 4 arguments])
AC_CHECK_LIB([rt], [clock_gettime], [AC_DEFINE(HAVE_CLOCK_GETTIME, 1)], [])
AC_CHECK_LIB([pthread], [pthread_barrier_wait],
[AC_DEFINE(HAVE_PTHREAD_BAR, 1)], [])
AC_CHECK_DECL([AI_ADDRCONFIG],
[AC_DEFINE(HAVE_AI_ADDRCONFIG, 1)],
[], [[#include <netdb.h>]])
AC_MSG_CHECKING(if sctp_connectx accepts 4 arguments)
AC_LINK_IFELSE([
AC_LANG_SOURCE(
[[int main() { return sctp_connectx(0, NULL, 0, NULL); }]])
], [AC_DEFINE(SCTP_CONNECTX_4_ARGS, 1)])
AC_CHECK_LIB([gnutls],
[gnutls_hash],
[AC_DEFINE(GNUTLS_VERSION_210, 1,
[Define to 1 if you have gnutls 2.10 installed])],
[])
AC_CHECK_LIB([gnutls],
[gnutls_x509_trust_list_verify_crt],
[AC_DEFINE(GNUTLS_VERSION_300, 1,
[Define to 1 if you have gnutls 3.0 installed])],
[])
AC_CHECK_LIB([gnutls],
[gnutls_handshake_set_timeout],
[AC_DEFINE(GNUTLS_VERSION_310, 1,
[Define to 1 if you have gnutls 3.1 installed])],
[])
AC_DEFINE(FREE_DIAMETER_MINIMUM_VERSION, "1.1.5", [freeDiameter minimum version])
AC_CHECK_LIB(gmp, __gmpz_init, ,
[AC_MSG_ERROR([GNU MP not found, see http://gmplib.org/])])
AC_CHECK_LIB([nettle],
[nettle_hmac_sha256_set_key],
[],
[AC_MSG_ERROR(nettle is not installed)])
AC_CHECK_LIB([pthread],
[pthread_getspecific],
[],
[AC_MSG_ERROR(lib pthread is not installed)])
AC_SUBST(ADD_CFLAGS)
dnl Add these flags
CFLAGS="$CFLAGS -Wall"
CFLAGS="$CFLAGS -Wshadow"
CFLAGS="$CFLAGS -Wcast-align"
CFLAGS="$CFLAGS -Wchar-subscripts"
CFLAGS="$CFLAGS -Wmissing-prototypes"
CFLAGS="$CFLAGS -Wmissing-declarations"
CFLAGS="$CFLAGS -Werror=implicit-function-declaration"
AC_C_BIGENDIAN
if test "x$ac_cv_c_bigendian" = "xyes"; then
CFLAGS="$CFLAGS -DBYTE_ORDER=BIG_ENDIAN"
else
CFLAGS="$CFLAGS -DBYTE_ORDER=LITTLE_ENDIAN"
fi
AC_SUBST([AM_CFLAGS])
AC_ARG_ENABLE(dh_install, AS_HELP_STRING([--enable-dh-install], [Replace some variables for installation]),
[],
[])
if test x$enable_dh_install == xyes; then
AC_SUBST(AM_CONF_DIR, $sysconfdir/openair-hss)
else
AC_SUBST(AM_CONF_DIR, $srcdir/conf)
fi
AC_OUTPUT( \
conf/hss.conf \
access_restriction/Makefile \
auc/Makefile \
db/Makefile \
s6a/Makefile \
utils/Makefile \
tests/Makefile \
Makefile \
)
echo "
($PACKAGE_NAME) version $PACKAGE_VERSION
Prefix.........: $prefix
C Compiler.....: $CC $CFLAGS
Linker.........: $LD $LDFLAGS $LIBS
Tests..........: ${HAVE_CHECK}
"
\ No newline at end of file
AM_CFLAGS = @ADD_CFLAGS@ \
-I$(top_srcdir) \
-I$(top_srcdir)/s6a \
-I$(top_srcdir)/utils
noinst_LTLIBRARIES = libdb.la
libdb_la_LDFLAGS = -all-static
libdb_la_SOURCES = \
db_proto.h db_connector.c \
db_subscription_data.c \
db_epc_equipment.c
\ No newline at end of file
This diff is collapsed.
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <error.h>
#include <mysql/mysql.h>
#include "hss_config.h"
#include "db_proto.h"
int hss_mysql_query_mmeidentity(const int id_mme_identity,
mysql_mme_identity_t *mme_identity_p)
{
MYSQL_RES *res;
MYSQL_ROW row;
char query[255];
if ((db_desc->db_conn == NULL) || (mme_identity_p == NULL)) {
return EINVAL;
}
memset(mme_identity_p, 0, sizeof(mysql_mme_identity_t));
sprintf(query, "SELECT mmehost,mmerealm FROM mmeidentity WHERE "
"mmeidentity.idmmeidentity='%d' ", id_mme_identity);
DB_DEBUG("Query: %s\n", query);
pthread_mutex_lock(&db_desc->db_cs_mutex);
if (mysql_query(db_desc->db_conn, query))
{
pthread_mutex_unlock(&db_desc->db_cs_mutex);
DB_ERROR("Query execution failed: %s\n",
mysql_error(db_desc->db_conn));
mysql_thread_end();
return EINVAL;
}
res = mysql_store_result(db_desc->db_conn);
pthread_mutex_unlock(&db_desc->db_cs_mutex);
if ((row = mysql_fetch_row(res)) != NULL) {
if (row[0] != NULL) {
memcpy(mme_identity_p->mme_host, row[0], strlen(row[0]));
} else {
mme_identity_p->mme_host[0] = '\0';
}
if (row[1] != NULL) {
memcpy(mme_identity_p->mme_realm, row[1], strlen(row[1]));
} else {
mme_identity_p->mme_realm[0] = '\0';
}
mysql_free_result(res);
mysql_thread_end();
return 0;
}
mysql_free_result(res);
mysql_thread_end();
return EINVAL;
}
int hss_mysql_check_epc_equipment(mysql_mme_identity_t *mme_identity_p)
{
MYSQL_RES *res;
MYSQL_ROW row;
char query[255];
if ((db_desc->db_conn == NULL) || (mme_identity_p == NULL)) {
return EINVAL;
}
sprintf(query, "SELECT idmmeidentity FROM mmeidentity WHERE mmeidentity.mmehost='%s' ",
mme_identity_p->mme_host);
DB_DEBUG("Query: %s\n", query);
pthread_mutex_lock(&db_desc->db_cs_mutex);
if (mysql_query(db_desc->db_conn, query))
{
pthread_mutex_unlock(&db_desc->db_cs_mutex);
DB_ERROR("Query execution failed: %s\n",
mysql_error(db_desc->db_conn));
mysql_thread_end();
return EINVAL;
}
res = mysql_store_result(db_desc->db_conn);
pthread_mutex_unlock(&db_desc->db_cs_mutex);
if ((row = mysql_fetch_row(res)) != NULL) {
mysql_free_result(res);
mysql_thread_end();
return 0;
}
mysql_free_result(res);
mysql_thread_end();
return EINVAL;
}
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <mysql/mysql.h>
#include <netinet/in.h> /* To provide internet addresses strings helpers */
#ifndef DB_PROTO_H_
#define DB_PROTO_H_
#define DB_DEBUG(fmt, args...) fprintf(stdout, "%s:%d: "fmt, __FILE__, __LINE__, ##args)
#define DB_ERROR(fmt, args...) fprintf(stderr, "%s:%d: "fmt, __FILE__, __LINE__, ##args)
typedef struct {
/* The mysql reference connector object */
MYSQL *db_conn;
char *server;
char *user;
char *password;
char *database;
pthread_mutex_t db_cs_mutex;
} database_t;
extern database_t *db_desc;
typedef uint32_t pre_emp_vul_t;
typedef uint32_t pre_emp_cap_t;
typedef uint8_t access_restriction_t;
typedef uint32_t ambr_t;
typedef uint8_t qci_t;
typedef uint8_t prio_level_t;
typedef uint32_t rau_tau_t;
#define IMSI_LENGTH_MAX (15)
typedef struct {
char imsi[IMSI_LENGTH_MAX + 1];
} mysql_auth_info_req_t;
/* Expressed in bytes */
#define KEY_LENGTH (16)
#define SQN_LENGTH (6)
#define RAND_LENGTH (16)
typedef struct {
uint8_t key[KEY_LENGTH];
uint8_t sqn[SQN_LENGTH];
/* RAND should not be here... */
uint8_t rand[RAND_LENGTH];
} mysql_auth_info_resp_t;
typedef struct {
char imsi[IMSI_LENGTH_MAX + 1];
/* New computed SQN that will be used on next auth info req */
uint8_t sqn[SQN_LENGTH];
} mysql_sqn_push_t;
typedef struct {
/* An MME may have already been registered as serving the UE. */
char mme_host[255];
char mme_realm[200];
} mysql_mme_identity_t;
typedef struct {
char imsi[16];
/* MSISDN this parameter may be NULL */
char msisdn[16];
/* Maximum aggregated bitrates for the user */
ambr_t aggr_ul;
ambr_t aggr_dl;
/* Subscribed RAU-TAU timer */
rau_tau_t rau_tau;
access_restriction_t access_restriction;
mysql_mme_identity_t mme_identity;
} mysql_ul_ans_t;
typedef struct {
/* Bit masks indicating presence of optional fields */
#define MME_IDENTITY_PRESENT (0x1)
#define MME_SUPPORTED_FEATURES_PRESENT (0x1)
#define IMEI_PRESENT (0x1)
#define SV_PRESENT (0x1)
#define UE_SRVCC_PRESENT (0x1)
unsigned mme_identity_present:1;
unsigned mme_supported_features_present:1;
unsigned imei_present:1;
unsigned sv_present:1;
unsigned ue_srvcc_present:1;
/* IMSI */
char imsi[16];
/* Origin host and realm */
mysql_mme_identity_t mme_identity;
/* IMEISV */
char imei[16];
char software_version[2];
uint32_t ue_srvcc;
uint32_t mme_supported_features;
} mysql_ul_push_t;
typedef enum {
IPV4 = 0,
IPV6 = 1,
IPV4V6 = 2,
IPV4_OR_IPV6 = 3,
} pdn_type_t;
typedef struct {
char ipv4_address[INET_ADDRSTRLEN];
char ipv6_address[INET6_ADDRSTRLEN];
} pdn_address_t;
typedef struct {
char apn[61];
pdn_type_t pdn_type;
pdn_address_t pdn_address;
ambr_t aggr_ul;
ambr_t aggr_dl;
qci_t qci;
prio_level_t priority_level;
pre_emp_cap_t pre_emp_cap;
pre_emp_vul_t pre_emp_vul;
} mysql_pdn_t;
typedef struct {
/* IMSI */
char imsi[16];
} mysql_pu_req_t;
typedef mysql_mme_identity_t mysql_pu_ans_t;
int hss_mysql_connect(const hss_config_t *hss_config_p);
void hss_mysql_disconnect(void);
int hss_mysql_get_user(const char *imsi);
int hss_mysql_update_loc(const char *imsi, mysql_ul_ans_t *mysql_ul_ans);
int hss_mysql_query_mmeidentity(const int id_mme_identity,
mysql_mme_identity_t *mme_identity_p);
int hss_mysql_check_epc_equipment(mysql_mme_identity_t *mme_identity_p);
int mysql_push_up_loc(mysql_ul_push_t *ul_push_p);
int hss_mysql_purge_ue(mysql_pu_req_t *mysql_pu_req,
mysql_pu_ans_t *mysql_pu_ans);
int hss_mysql_query_pdns(const char *imsi,
mysql_pdn_t **pdns_p,
uint8_t *nb_pdns);
int hss_mysql_auth_info(mysql_auth_info_req_t *auth_info_req,
mysql_auth_info_resp_t *auth_info_resp);
int hss_mysql_push_rand_sqn(const char *imsi, uint8_t *rand_p, uint8_t *sqn);
int hss_mysql_increment_sqn(const char *imsi);
#endif /* DB_PROTO_H_ */
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <error.h>
#include <mysql/mysql.h>
#include "hss_config.h"
#include "db_proto.h"
int hss_mysql_query_pdns(const char *imsi,
mysql_pdn_t **pdns_p,
uint8_t *nb_pdns)
{
int ret;
MYSQL_RES *res;
MYSQL_ROW row;
char query[255];
mysql_pdn_t *pdn_array = NULL;
if (db_desc->db_conn == NULL) {
return EINVAL;
}
if (nb_pdns == NULL || pdns_p == NULL) {
return EINVAL;
}
sprintf(query, "SELECT * FROM `pdn` WHERE "
"`pdn`.`users_imsi`=%s LIMIT 10; ", imsi);
printf("Query: %s\n", query);
pthread_mutex_lock(&db_desc->db_cs_mutex);
if (mysql_query(db_desc->db_conn, query))
{
pthread_mutex_unlock(&db_desc->db_cs_mutex);
fprintf(stderr, "Query execution failed: %s\n",
mysql_error(db_desc->db_conn));
mysql_thread_end();
return EINVAL;
}
res = mysql_store_result(db_desc->db_conn);
pthread_mutex_unlock(&db_desc->db_cs_mutex);
*nb_pdns = 0;
while ((row = mysql_fetch_row(res)) != NULL)
{
mysql_pdn_t *pdn_elm; /* Local PDN element in array */
unsigned long *lengths;
lengths = mysql_fetch_lengths(res);
*nb_pdns += 1;
if (*nb_pdns == 1) {
/* First row, must malloc */
pdn_array = malloc(sizeof(mysql_pdn_t));
} else {
pdn_array = realloc(pdn_array, *nb_pdns * sizeof(mysql_pdn_t));
}
if (pdn_array == NULL) {
/* Error on malloc */
ret = ENOMEM;
goto err;
}
pdn_elm = &pdn_array[*nb_pdns - 1];
/* Copying the APN */
memset(pdn_elm, 0, sizeof(mysql_pdn_t));
memcpy(pdn_elm->apn, row[1], lengths[1]);
/* PDN Type + PDN address */
if (strcmp(row[2], "IPv6") == 0) {
pdn_elm->pdn_type = IPV6;
memcpy(pdn_elm->pdn_address.ipv6_address, row[4], lengths[4]);
pdn_elm->pdn_address.ipv6_address[lengths[4]] = '\0';
} else if (strcmp(row[2], "IPv4v6") == 0) {
pdn_elm->pdn_type = IPV4V6;
memcpy(pdn_elm->pdn_address.ipv4_address, row[3], lengths[3]);
pdn_elm->pdn_address.ipv4_address[lengths[3]] = '\0';
memcpy(pdn_elm->pdn_address.ipv6_address, row[4], lengths[4]);
pdn_elm->pdn_address.ipv6_address[lengths[4]] = '\0';
} else if (strcmp(row[2], "IPv4_or_IPv6") == 0) {
pdn_elm->pdn_type = IPV4_OR_IPV6;
memcpy(pdn_elm->pdn_address.ipv4_address, row[3], lengths[3]);
pdn_elm->pdn_address.ipv4_address[lengths[3]] = '\0';
memcpy(pdn_elm->pdn_address.ipv6_address, row[4], lengths[4]);
pdn_elm->pdn_address.ipv6_address[lengths[4]] = '\0';
} else {
pdn_elm->pdn_type = IPV4;
memcpy(pdn_elm->pdn_address.ipv4_address, row[3], lengths[3]);
pdn_elm->pdn_address.ipv4_address[lengths[3]] = '\0';
}
pdn_elm->aggr_ul = atoi(row[5]);
pdn_elm->aggr_dl = atoi(row[6]);
pdn_elm->qci = atoi(row[9]);
pdn_elm->priority_level = atoi(row[10]);
if (strcmp(row[11], "ENABLED") == 0) {
pdn_elm->pre_emp_cap = 0;
} else {
pdn_elm->pre_emp_cap = 1;
}
if (strcmp(row[12], "DISABLED") == 0) {
pdn_elm->pre_emp_vul = 1;
} else {
pdn_elm->pre_emp_vul = 0;
}
}
mysql_free_result(res);
mysql_thread_end();
/* We did not find any APN for the requested IMSI */
if (*nb_pdns == 0) {
return EINVAL;
} else {
*pdns_p = pdn_array;
return 0;
}
err:
if (pdn_array) {
free(pdn_array);
}
pdn_array = NULL;
*pdns_p = pdn_array;
*nb_pdns = 0;
mysql_free_result(res);
mysql_thread_end();
return ret;
}
-- phpMyAdmin SQL Dump
-- version 3.4.10.1deb1
-- http://www.phpmyadmin.net
--
-- Client: localhost
-- Généré le : Mer 18 Décembre 2013 à 18:01
-- Version du serveur: 5.5.34
-- Version de PHP: 5.3.10-1ubuntu3.9
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Base de données: `oai_db`
--
-- --------------------------------------------------------
--
-- Structure de la table `apn`
--
CREATE TABLE IF NOT EXISTS `apn` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`apn-name` varchar(60) NOT NULL,
`pdn-type` enum('IPv4','IPv6','IPv4v6','IPv4_or_IPv6') NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `apn-name` (`apn-name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- Structure de la table `mmeidentity`
--
CREATE TABLE IF NOT EXISTS `mmeidentity` (
`idmmeidentity` int(11) NOT NULL AUTO_INCREMENT,
`mmehost` varchar(255) DEFAULT NULL,
`mmerealm` varchar(200) DEFAULT NULL,
`UE-Reachability` tinyint(1) NOT NULL COMMENT 'Indicates whether the MME supports UE Reachability Notifcation',
PRIMARY KEY (`idmmeidentity`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=39 ;
--
-- Contenu de la table `mmeidentity`
--
INSERT INTO `mmeidentity` (`idmmeidentity`, `mmehost`, `mmerealm`, `UE-Reachability`) VALUES
(29, 'yang.eur', 'eur', 0),
(28, 'nord.eur', 'eur', 0),
(30, 'hades.eur', 'eur', 0),
(35, 'olympie-Latitude-E6520.eur', 'eur', 0),
(33, 'orcus.eur', 'eur', 0),
(36, 'caviar.eur', 'eur', 0),
(37, 'sud.eur', 'eur', 0),
(38, 'tapenade.eur', 'eur', 1);
-- --------------------------------------------------------
--
-- Structure de la table `pdn`
--
CREATE TABLE IF NOT EXISTS `pdn` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`apn` varchar(60) NOT NULL,
`pdn_type` enum('IPv4','IPv6','IPv4v6','IPv4_or_IPv6') NOT NULL DEFAULT 'IPv4',
`pdn_ipv4` varchar(15) DEFAULT '0.0.0.0',
`pdn_ipv6` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT '0:0:0:0:0:0:0:0',
`aggregate_ambr_ul` int(10) unsigned DEFAULT '50000000',
`aggregate_ambr_dl` int(10) unsigned DEFAULT '100000000',
`pgw_id` int(11) NOT NULL,
`users_imsi` varchar(15) NOT NULL,
`qci` tinyint(3) unsigned NOT NULL DEFAULT '9',
`priority_level` tinyint(3) unsigned NOT NULL DEFAULT '15',
`pre_emp_cap` enum('ENABLED','DISABLED') DEFAULT 'DISABLED',
`pre_emp_vul` enum('ENABLED','DISABLED') DEFAULT 'DISABLED',
`LIPA-Permissions` enum('LIPA-prohibited','LIPA-only','LIPA-conditional') NOT NULL DEFAULT 'LIPA-only',
PRIMARY KEY (`id`,`pgw_id`,`users_imsi`),
KEY `fk_pdn_pgw1_idx` (`pgw_id`),
KEY `fk_pdn_users1_idx` (`users_imsi`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
--
-- Contenu de la table `pdn`
--
INSERT INTO `pdn` (`id`, `apn`, `pdn_type`, `pdn_ipv4`, `pdn_ipv6`, `aggregate_ambr_ul`, `aggregate_ambr_dl`, `pgw_id`, `users_imsi`, `qci`, `priority_level`, `pre_emp_cap`, `pre_emp_vul`, `LIPA-Permissions`) VALUES
(2, 'wap.test.fr', 'IPv4v6', '10.0.0.5', '0:0:0:0:0:0:0:1', 1048576, 14400000, 2, '20834123456789', 8, 2, 'ENABLED', 'DISABLED', 'LIPA-only'),
(3, 'toto.eurecom.fr', 'IPv4v6', '0.0.0.0', '2001:0db8:85a3:0042:1000:8a2e:0370:7334', 50000, 100000, 2, '20834123456710', 1, 3, 'DISABLED', 'DISABLED', 'LIPA-only'),
(4, 'edge.eurecom.fr', 'IPv4_or_IPv6', '0.0.0.0', '2001:0db8:85a3:0042:1000:8a2e:0370:7356', 50000000, 100000000, 1, '20834123456789', 3, 4, 'ENABLED', 'DISABLED', 'LIPA-only'),
(7, 'internet.v6.eur', 'IPv6', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 4, '20834123456789', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'),
(1, 'internet.v4.eur', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '20834123456789', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only');
-- --------------------------------------------------------
--
-- Structure de la table `pgw`
--
CREATE TABLE IF NOT EXISTS `pgw` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ipv4` varchar(15) NOT NULL,
`ipv6` varchar(39) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ipv4` (`ipv4`),
UNIQUE KEY `ipv6` (`ipv6`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
--
-- Contenu de la table `pgw`
--
INSERT INTO `pgw` (`id`, `ipv4`, `ipv6`) VALUES
(1, '127.0.0.1', '0:0:0:0:0:0:0:1'),
(2, '192.168.56.101', ''),
(3, '10.0.0.2', '0');
-- --------------------------------------------------------
--
-- Structure de la table `terminal-info`
--
CREATE TABLE IF NOT EXISTS `terminal-info` (
`imei` varchar(15) NOT NULL,
`sv` varchar(2) NOT NULL,
UNIQUE KEY `imei` (`imei`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Structure de la table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`imsi` varchar(15) NOT NULL,
`msisdn` varchar(46) DEFAULT NULL,
`imei` varchar(15) DEFAULT NULL,
`imei_sv` varchar(2) DEFAULT NULL,
`ms_ps_status` enum('PURGED','NOT_PURGED') DEFAULT 'PURGED' COMMENT 'Indicates that ESM and EMM status are purged from MME',
`rau_tau_timer` int(10) unsigned DEFAULT '120',
`ue_ambr_ul` bigint(20) unsigned DEFAULT '50000000' COMMENT 'Subscribed UE AMBR in uplink',
`ue_ambr_dl` bigint(20) unsigned DEFAULT '100000000' COMMENT 'Subscribed UE AMBR in downlink',
`access_restriction` int(10) unsigned DEFAULT '60' COMMENT '3GPP TS.29272 #7.3.31',
`mme_cap` int(10) unsigned zerofill DEFAULT NULL,
`mmeidentity_idmmeidentity` int(11) NOT NULL DEFAULT '0',
`key` varbinary(16) NOT NULL DEFAULT '0' COMMENT 'UE security key',
`RFSP-Index` smallint(5) unsigned NOT NULL DEFAULT '1' COMMENT 'Index to RRM configuration. Possible values from 1 to 256',
`urrp_mme` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'UE reachability request requested by HSS',
`sqn` int(10) unsigned zerofill NOT NULL,
`rand` varbinary(16) NOT NULL,
PRIMARY KEY (`imsi`,`mmeidentity_idmmeidentity`),
KEY `fk_users_mmeidentity_idx1` (`mmeidentity_idmmeidentity`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Contenu de la table `users`
--
INSERT INTO `users` (`imsi`, `msisdn`, `imei`, `imei_sv`, `ms_ps_status`, `rau_tau_timer`, `ue_ambr_ul`, `ue_ambr_dl`, `access_restriction`, `mme_cap`, `mmeidentity_idmmeidentity`, `key`, `RFSP-Index`, `urrp_mme`, `sqn`, `rand`) VALUES
('20834123456789', '380561234567', '12345678', '23', 'NOT_PURGED', 50, 50000000, 100000000, 47, 0000000000, 36, '+Eų\0,IHH', 0, 0, 0000000096, 'PxX \Z1x'),
('208920000000008', NULL, NULL, NULL, 'PURGED', 120, 50000000, 100000000, 60, 0000000000, 0, 'G?/Д |hb', 1, 0, 0000027276, '''$y2dm');
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
openair-hss (1.0.0-1) UNRELEASED; urgency=low
* Initial release. (Closes: #XXXXXX)
-- Sebastien Roux <roux@nord> Wed, 10 Apr 2013 09:54:55 +0200
Source: openair-hss
Maintainer: Sebastien ROUX <sebastien.roux@eurecom.fr>
Section: misc
Priority: optional
Standards-Version: 3.9.2
Build-Depends: debhelper (>= 8),
make, gcc, bison, flex, autotools,
libmysqlclient-dev, libsctp-dev,
freediameter-dev, freediameter-dictionary-s6a, freediameter-dictionary-mip6,
libgmp-dev, libnettle-dev
Package: openair-hss
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Implementation of R10 HSS for 3GPP LTE core network
\ No newline at end of file
etc/openair-hss/
\ No newline at end of file
openair-hss_1.0.0-1_i386.deb misc optional
conf/hss.conf
conf/hss_fd.conf
db/oai_db.sql
\ No newline at end of file
#!/usr/bin/make -f
export DH_OPTIONS
%:
dh $@
override_dh_auto_configure:
dh_auto_configure -- --enable-dh-install LDFLAGS='-L/usr/local/lib'
# Don't run tests:
override_dh_auto_test:
\ No newline at end of file
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include <stdio.h>
#include <string.h>
#include "hss_config.h"
#include "db_proto.h"
#include "s6a_proto.h"
#include "auc.h"
int main(int argc, char *argv[])
{
hss_config_t hss_config;
memset(&hss_config, 0, sizeof(hss_config_t));
if (config_init(argc, argv, &hss_config) != 0) {
return -1;
}
if (hss_mysql_connect(&hss_config) != 0) {
return -1;
}
random_init();
s6a_init(&hss_config);
while(1) {
/* TODO: handle signals here */
sleep(1);
}
return 0;
}
AM_CFLAGS = @ADD_CFLAGS@ \
-I$(top_srcdir) \
-I$(top_srcdir)/access_restriction \
-I$(top_srcdir)/auc \
-I$(top_srcdir)/db \
-I$(top_srcdir)/utils
noinst_LTLIBRARIES = libs6a.la
libs6a_la_LDFLAGS = -all-static
libs6a_la_SOURCES = \
s6a_common.c \
s6a_fd.c s6a_proto.h \
s6a_auth_info.c \
s6a_up_loc.c \
s6a_purge_ue.c \
s6a_error.c \
s6a_subscription_data.c \
s6a_in_addr.c \
s6a_peers.c \
s6a_supported_features.h s6a_supported_features.c
\ No newline at end of file
This diff is collapsed.
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include "hss_config.h"
#include "db_proto.h"
#include "s6a_proto.h"
int s6a_add_result_code(struct msg *ans, struct avp *failed_avp, int result_code, int experimental)
{
struct avp *avp;
union avp_value value;
if (DIAMETER_ERROR_IS_VENDOR(result_code) && experimental != 0) {
struct avp *experimental_result;
CHECK_FCT(fd_msg_avp_new(s6a_cnf.dataobj_s6a_experimental_result,
0, &experimental_result));
CHECK_FCT(fd_msg_avp_new(s6a_cnf.dataobj_s6a_vendor_id,
0, &avp));
value.u32 = VENDOR_3GPP;
CHECK_FCT(fd_msg_avp_setvalue(avp, &value));
CHECK_FCT(fd_msg_avp_add(experimental_result, MSG_BRW_LAST_CHILD, avp));
CHECK_FCT(fd_msg_avp_new(s6a_cnf.dataobj_s6a_experimental_result_code,
0, &avp));
value.u32 = result_code;
CHECK_FCT(fd_msg_avp_setvalue(avp, &value));
CHECK_FCT(fd_msg_avp_add(experimental_result, MSG_BRW_LAST_CHILD, avp));
CHECK_FCT(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, experimental_result));
/* Add Origin_Host & Origin_Realm AVPs */
CHECK_FCT(fd_msg_add_origin(ans, 0));
} else {
/* This is a code defined in the base protocol: result-code AVP should
* be used.
*/
CHECK_FCT(fd_msg_rescode_set(ans, retcode_2_string(result_code), NULL,
failed_avp, 1));
}
return 0;
}
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include "hss_config.h"
#include "db_proto.h"
#include "s6a_proto.h"
inline char *experimental_retcode_2_string(int ret_code)
{
switch(ret_code) {
/* Experimental-Result-Codes */
case DIAMETER_ERROR_USER_UNKNOWN:
return "DIAMETER_ERROR_USER_UNKNOWN";
case DIAMETER_ERROR_ROAMING_NOT_ALLOWED:
return "DIAMETER_ERROR_ROAMING_NOT_ALLOWED";
case DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION:
return "DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION";
case DIAMETER_ERROR_RAT_NOT_ALLOWED:
return "DIAMETER_ERROR_RAT_NOT_ALLOWED";
case DIAMETER_ERROR_EQUIPMENT_UNKNOWN:
return "DIAMETER_ERROR_EQUIPMENT_UNKNOWN";
case DIAMETER_ERROR_UNKOWN_SERVING_NODE:
return "DIAMETER_ERROR_UNKOWN_SERVING_NODE";
case DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE:
return "DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE";
default:
break;
}
return "DIAMETER_AVP_UNSUPPORTED";
}
inline char *retcode_2_string(int ret_code)
{
switch(ret_code) {
case ER_DIAMETER_SUCCESS:
return "DIAMETER_SUCCESS";
case ER_DIAMETER_MISSING_AVP:
return "DIAMETER_MISSING_AVP";
case ER_DIAMETER_INVALID_AVP_VALUE:
return "DIAMETER_INVALID_AVP_VALUE";
default:
break;
}
return "DIAMETER_AVP_UNSUPPORTED";
}
This diff is collapsed.
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include "hss_config.h"
#include "db_proto.h"
#include "s6a_proto.h"
/* http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml*/
/* Perform a conversion between ipv4 in BCD to AVP served-party-ip-address */
int s6a_add_ipv4_address(struct avp *avp, const char *ipv4_addr)
{
struct avp *child_avp;
union avp_value value;
uint8_t ipv4[6]; /* Converted IPv4 address with family */
in_addr_t sin;
if (ipv4_addr == NULL) {
return -1;
}
/* This is an IPv4 family -> ipv4 buffer should start with 0x0001 */
ipv4[0] = 0x00;
ipv4[1] = 0x01;
sin = inet_addr(ipv4_addr);
/* No need to add the address if it is an any address */
if (sin != INADDR_ANY) {
memcpy(&ipv4[2], &sin, 4);
CHECK_FCT(fd_msg_avp_new(s6a_cnf.dataobj_s6a_served_party_ip_addr, 0, &child_avp));
value.os.data = ipv4;
value.os.len = 6;
CHECK_FCT(fd_msg_avp_setvalue(child_avp, &value));
CHECK_FCT(fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, child_avp));
return 0;
}
/* No IP address added to AVP */
return -1;
}
/* Perform a conversion between ipv6 in BCD to AVP served-party-ip-address */
int s6a_add_ipv6_address(struct avp *avp, const char *ipv6_addr)
{
struct avp *child_avp;
union avp_value value;
uint8_t ipv6[18];
struct in6_addr sin6;
if (ipv6_addr == NULL) {
return -1;
}
memset(&sin6, 0, sizeof(struct in6_addr));
/* This is an IPv6 family -> ipv6 buffer should start with 0x0002 */
ipv6[0] = 0x00;
ipv6[1] = 0x02;
if (inet_pton(AF_INET6, ipv6_addr, &sin6) == -1) {
fprintf(stderr, "INET6 address conversion has failed\n");
return -1;
}
/* If the IPV6 address is 0:0:0:0:0:0:0:0 then we don't add it to the
* served-party ip address and consider the ip address can be dynamically
* allocated.
*/
if (!IN6_IS_ADDR_UNSPECIFIED(sin6.s6_addr32)) {
memcpy(&ipv6[2], &sin6.s6_addr, 16);
CHECK_FCT(fd_msg_avp_new(s6a_cnf.dataobj_s6a_served_party_ip_addr, 0, &child_avp));
value.os.data = ipv6;
value.os.len = 18;
CHECK_FCT(fd_msg_avp_setvalue(child_avp, &value));
CHECK_FCT(fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, child_avp));
return 0;
}
return -1;
}
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
/*! \file s6a_peers.c
* \brief Authenticate a new peer connecting to the HSS by checking the database
* \author Sebastien ROUX <sebastien.roux@eurecom.fr>
* \date 2013
* \version 0.1
*/
#include <stdio.h>
#include <string.h>
#include "hss_config.h"
#include "db_proto.h"
#include "s6a_proto.h"
int s6a_peer_validate(struct peer_info *info, int *auth, int (**cb2)(struct peer_info *))
{
mysql_mme_identity_t mme_identity;
if (info == NULL) {
return EINVAL;
}
memset(&mme_identity, 0, sizeof(mysql_mme_identity_t));
/* We received a new connection. Check the database for allowed equipments
* on EPC
*/
memcpy(mme_identity.mme_host, info->pi_diamid, info->pi_diamidlen);
if (hss_mysql_check_epc_equipment(&mme_identity) != 0) {
/* The MME has not been found in list of known peers -> reject it */
*auth = -1;
fprintf(stdout, "Rejecting %s: either db has no knowledge of this peer "
"or sql query failed\n", info->pi_diamid);
} else {
*auth = 1;
/* For now we don't use security */
info->config.pic_flags.sec = PI_SEC_NONE;
info->config.pic_flags.persist = PI_PRST_NONE;
fprintf(stdout, "Accepting %s peer\n", info->pi_diamid);
}
return 0;
}
This diff is collapsed.
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
/*! \file s6a_purge_ue.c
* \brief Handle a purge UE request and generate the corresponding answer
* \author Sebastien ROUX <sebastien.roux@eurecom.fr>
* \date 2013
* \version 0.1
*/
#include "hss_config.h"
#include "db_proto.h"
#include "s6a_proto.h"
int s6a_purge_ue_cb(struct msg **msg, struct avp *paramavp,
struct session *sess, void *opaque,
enum disp_action *act)
{
struct msg *ans, *qry;
struct avp *avp, *failed_avp = NULL;
struct avp_hdr *hdr;
int ret = 0;
int result_code = ER_DIAMETER_SUCCESS;
int experimental = 0;
uint32_t pur_flags = 0;
/* MySQL requests and asnwer data */
mysql_pu_req_t pu_req;
mysql_pu_ans_t pu_ans;
if (msg == NULL) {
return EINVAL;
}
memset(&pu_req, 0, sizeof(mysql_pu_req_t));
qry = *msg;
/* Create the answer */
CHECK_FCT(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, 0));
ans = *msg;
/* Retrieving IMSI AVP */
CHECK_FCT(fd_msg_search_avp(qry, s6a_cnf.dataobj_s6a_imsi, &avp));
if (avp) {
CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
if (hdr->avp_value->os.len > IMSI_LENGTH) {
result_code = ER_DIAMETER_INVALID_AVP_VALUE;
goto out;
}
sprintf(pu_req.imsi, "%*s", (int)hdr->avp_value->os.len, hdr->avp_value->os.data);
} else {
result_code = ER_DIAMETER_MISSING_AVP;
goto out;
}
/* Retrieving the PUR-Flags if present */
CHECK_FCT(fd_msg_search_avp(qry, s6a_cnf.dataobj_s6a_pur_flags, &avp));
if (avp) {
CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
pur_flags = hdr->avp_value->u32;
if (FLAG_IS_SET(pur_flags, PUR_UE_PURGED_IN_SGSN)) {
/* This bit shall not be set by a standalone MME. */
result_code = ER_DIAMETER_INVALID_AVP_VALUE;
goto out;
}
}
if ((ret = hss_mysql_purge_ue(&pu_req, &pu_ans)) != 0) {
/* We failed to find the IMSI in the database. Replying to the request
* with the user unknown cause.
*/
experimental = 1;
result_code = DIAMETER_ERROR_USER_UNKNOWN;
goto out;
}
/* Retrieving Origin host AVP */
CHECK_FCT(fd_msg_search_avp(qry, s6a_cnf.dataobj_s6a_origin_host, &avp));
if (!avp) {
result_code = ER_DIAMETER_MISSING_AVP;
goto out;
}
/* Retrieve the header from origin host and realm avps */
CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
if (strncmp(pu_ans.mme_host, (char *)hdr->avp_value->os.data, hdr->avp_value->os.len) != 0)
{
result_code = DIAMETER_ERROR_UNKOWN_SERVING_NODE;
experimental = 1;
goto out;
}
/* Retrieving Origin realm AVP */
CHECK_FCT(fd_msg_search_avp(qry, s6a_cnf.dataobj_s6a_origin_realm, &avp));
if (!avp) {
result_code = ER_DIAMETER_MISSING_AVP;
goto out;
}
CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
if (strncmp(pu_ans.mme_realm, (char *)hdr->avp_value->os.data, hdr->avp_value->os.len) != 0)
{
result_code = DIAMETER_ERROR_UNKOWN_SERVING_NODE;
experimental = 1;
goto out;
}
out:
/* Append the result code to the answer */
CHECK_FCT(s6a_add_result_code(ans, failed_avp, result_code, experimental));
CHECK_FCT(fd_msg_send(msg, NULL, NULL ));
return 0;
}
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
/*! \file s6a_supported_features.c
* \brief
* \author Sebastien ROUX <sebastien.roux@eurecom.fr>
* \date 2013
* \version 0.1
*/
#include "hss_config.h"
#include "db_proto.h"
#include "s6a_proto.h"
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2013 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include "hss_config.h"
#ifndef S6A_SUPPORTED_FEATURES_H_
#define S6A_SUPPORTED_FEATURES_H_
/* Operator Determined Barring of all Packet Oriented Services. */
#define ODB_ALL_APN(x) (x & 0x1)
/* Operator Determined Barring of Packet Oriented Services from access points
* that are within the HPLMN whilst the subscriber is roaming in a VPLMN.
*/
#define ODB_HPLMN_APN(x) ((x & 0x2) >> 1)
/* Operator Determined Barring of Packet Oriented Services from access points
* that are within the roamed to VPLMN
*/
#define ODB_VPLMN_APN(x) ((x & 0x4) >> 2)
/* Operator Determined Barring of all outgoing calls */
#define ODB_ALL_OG(x) ((x & 0x8) >> 3)
/* Operator Determined Barring of all outgoing international calls */
#define ODB_ALL_INT_OG ((x & 0x10) >> 4)
/* Operator Determined Barring of all outgoing international calls except those
* directed to the home PLMN country
*/
#define ODB_ALL_INT_NOT_TO_HPLMN(x) ((x & 0x20) >> 5)
/* Operator Determined Barring of all outgoing inter-zonal calls */
#define ODB_ALL_INT_ZONE_OG(x) ((x & 0x40) >> 6)
/* Operator Determined Barring of all outgoing inter-zonal calls except those
* directed to the home PLMN country
*/
#define ODB_ALL_INT_ZONE_OG_NOT_TO_HPLMN(x) ((x & 0x80) >> 7)
/* Operator Determined Barring of all outgoing international calls except those
* directed to the home PLMN country and Barring of all outgoing inter-zonal calls
*/
#define ODB_ALL_INT_ZONE_OG_AND_INT_OG_NOT_TO_HPLMN(x) ((x & 0x100) >> 8)
/* Regional Subscription */
#define REG_SUB(x) ((x & 0x200) >> 9)
/* Trace Function */
#define TRACE(x) ((x & 0x400) >> 10)
/* All LCS Privacy Exception Classes */
#define LCS_ALL_PRIV_EXCEP(x) ((x & 0x800) >> 11)
/* Allow location by any LCS client */
#define LCS_UNIVERSAL(x) ((x & 0x1000) >> 12)
/* Allow location by any value added LCS client to which a call/session is
* established from the target UE
*/
#define LCS_CALL_SESS_RELATED(x) ((x & 0x2000) >> 13)
/* Allow location by designated external value added LCS clients */
#define LCS_CALL_SESS_UNRELATED(x) ((x & 0x4000) >> 14)
/* Allow location by designated PLMN operator LCS clients */
#define LCS_PLMN_OPERATOR(x) ((x & 0x8000) >> 15)
/* Allow location by LCS clients of a designated LCS service type */
#define LCS_SERVICE_TYPE(x) ((x & 0x10000) >> 16)
/* All Mobile Originating Location Request Classes */
#define LCS_ALL_MOLR_SS(x) ((x & 0x20000) >> 17)
/* Allow an MS to request its own location */
#define LCS_BASIC_SELF_LOCATION(x) ((x & 0x40000) >> 18)
/* Allow an MS to perform self location without interaction with the PLMN */
#define LCS_AUTO_SELF_LOCATION(x) ((x & 0x80000) >> 19)
/* Allow an MS to request transfer of its location to another LCS client */
#define LCS_TRANSFER_TO_THIRD_PARTY(x) ((x & 0x100000) >> 20)
/* Short Message MO-PP */
#define SM_MO_PP(x) ((x & 0x200000) >> 21)
/* Barring of Outgoing Calls */
#define BARRING_OUTGOING_CALLS(x) ((x & 0x400000) >> 22)
/* Barring of all outgoing calls */
#define BAOC(x) ((x & 0x800000) >> 23)
/* Barring of outgoing international calls */
#define BOIC(x) ((x & 0x1000000) >> 24)
/* Barring of outgoing international calls except those directed to the home PLMN
* Country
*/
#define BOIC_EXCEPT_HC(x) ((x & 0x2000000) >> 25)
/* UE Reachability Notifcation */
#define UE_REACH_NOTIF(x) ((x & 0x4000000) >> 26)
/* Terminating Access Domain Selection Data Retrieval */
#define T_ADS_DATA_RETR(x) ((x & 0x8000000) >> 27)
/* State/Location Information Retrieval */
#define STATE_LOCATION_INFO_RETR(x) ((x & 0x10000000) >> 28)
/* Partial Purge from a Combined MME/SGSN */
#define PARTIAL_PURGE(x) ((x & 0x20000000) >> 29)
#define SUPP_FEAT_PAD_VALID(x) ((x & 0xfc000000) == 0)
#endif /* S6A_SUPPORTED_FEATURES_H_ */
This diff is collapsed.
# if HAVE_CHECK
# TESTS = up_loc_test
# else
# TESTS =
# endif
AM_CFLAGS = @CHECK_CFLAGS@ \
-I$(top_srcdir)/auc
if HAVE_CHECK
TESTS = up_loc_test test_security_f1 \
test_security_f2_f3_f5 \
test_security_f4_f5star \
test_kdf \
test_security_kasme
else
TESTS =
endif
test_common = \
$(top_builddir)/auc/libauc.la \
libtest_utils.la \
@CHECK_LIBS@
up_loc_test_LDADD = \
libtest_utils.la \
@CHECK_LIBS@
test_security_f1_LDADD = \
$(test_common)
test_security_f2_f3_f5_LDADD = \
$(test_common)
test_security_f4_f5star_LDADD = \
$(test_common)
test_security_kasme_LDADD = \
$(test_common)
test_kdf_LDADD = \
$(test_common)
noinst_LTLIBRARIES = libtest_utils.la
libtest_utils_la_SOURCES = \
test_utils.h test_utils.c \
test_fd.h test_fd.c
check_PROGRAMS = \
up_loc_test test_security_f1 \
test_security_f2_f3_f5 \
test_security_f4_f5star \
test_security_kasme \
test_kdf
up_loc_test_SOURCES = up_loc_test.c
test_security_f1_SOURCE = test_security_f1.c
test_security_f2_f3_f5_SOURCE = test_security_f2_f3_f5.c
test_security_f4_f5star_SOURCE = test_security_f4_f5star.c
test_security_kasme_SOURCE = test_security_kasme.c
test_kdf_SOURCE = test_kdf.c
\ No newline at end of file
#include "config.h"
#include <freeDiameter/freeDiameter-host.h>
#include <freeDiameter/libfdcore.h>
#include "test_utils.h"
#include "test_fd.h"
extern int fd_ext_add( char * filename, char * conffile );
void s6a_fd_init(void)
{
struct peer_info peer;
fd_g_debug_lvl = NONE;
memset(&peer, 0, sizeof(struct peer_info));
peer.pi_diamid = "hss.test.fr";
peer.pi_diamidlen = strlen(peer.pi_diamid);
/* Only SCTP */
peer.config.pic_flags.pro4 = PI_P4_SCTP;
peer.config.pic_flags.sec = PI_SEC_NONE;
peer.config.pic_flags.exp = PI_EXP_NONE;
peer.config.pic_port = 18678;
if (fd_core_initialize() != 0) {
fail("fd_core_initialize failed");
}
if (fd_core_start() != 0) {
fail("fd_core_start failed");
}
if (fd_core_parseconf("../../conf/hss_fd.conf") != 0) {
fail("fd_core_waitstartcomplete failed");
}
if (fd_core_waitstartcomplete() != 0) {
fail("fd_core_waitstartcomplete failed");
}
// if (fd_peer_add(&peer, NULL, NULL, NULL) != 0) {
// fail("fd_peer_add failed");
// }
}
void s6a_fd_stop(void)
{
if (fd_core_shutdown() != 0) {
fail("fd_core_shutdown failed");
}
if (fd_core_wait_shutdown_complete() != 0) {
fail("fd_core_shutdown failed");
}
}
#ifndef TEST_FD_H_
#define TEST_FD_H_
void s6a_fd_init(void);
void s6a_fd_stop(void);
#endif /* TEST_FD_H_ */
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include "config.h"
#include "test_utils.h"
#include "test_fd.h"
#include "auc.h"
static
void do_kdf(uint8_t *key, unsigned key_length, uint8_t *data, unsigned data_length,
uint8_t *exp, unsigned exp_length)
{
uint8_t result[32];
kdf(key, key_length, data, data_length, result, 32);
if (compare_buffer(result, exp_length, exp, exp_length) != 0) {
fail("Fail: kdf\n");
}
}
void
doit (void)
{
/* RFC 4231 */
/* Test case 1 #4.2 */
do_kdf(HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
"0b0b0b0b"),
HL("4869205468657265"),
HL("b0344c61d8db38535ca8afceaf0bf12b"
"881dc200c9833da726e9376c2e32cff7"));
/* Test case 2 #4.3 */
do_kdf(HL("4a656665"),
HL("7768617420646f2079612077616e7420"
"666f72206e6f7468696e673f"),
HL("5bdcc146bf60754e6a042426089575c7"
"5a003f089d2739839dec58b964ec3843"));
/* Test case 3 #4.4 */
do_kdf(HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaa"),
HL("dddddddddddddddddddddddddddddddd"
"dddddddddddddddddddddddddddddddd"
"dddddddddddddddddddddddddddddddd"
"dddd"),
HL("773ea91e36800e46854db8ebd09181a7"
"2959098b3ef8c122d9635514ced565fe"));
/* Test case 4 #4.5 */
do_kdf(HL("0102030405060708090a0b0c0d0e0f10"
"111213141516171819"),
HL("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
"cdcd"),
HL("82558a389a443c0ea4cc819899f2083a"
"85f0faa3e578f8077a2e3ff46729665b"));
/* Test case 5 #4.6 */
do_kdf(HL("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c"
"0c0c0c0c"),
HL("546573742057697468205472756e6361"
"74696f6e"),
HL("a3b6167473100ee06e0c796c2955552b"));
/* Test case 6 #4.7 */
do_kdf(HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaa"),
HL("54657374205573696e67204c61726765"
"72205468616e20426c6f636b2d53697a"
"65204b6579202d2048617368204b6579"
"204669727374"),
HL("60e431591ee0b67f0d8a26aacbf5b77f"
"8e0bc6213728c5140546040f0ee37f54"));
/* Test case 6 #4.7 */
do_kdf(HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaa"),
HL("54686973206973206120746573742075"
"73696e672061206c6172676572207468"
"616e20626c6f636b2d73697a65206b65"
"7920616e642061206c61726765722074"
"68616e20626c6f636b2d73697a652064"
"6174612e20546865206b6579206e6565"
"647320746f2062652068617368656420"
"6265666f7265206265696e6720757365"
"642062792074686520484d414320616c"
"676f726974686d2e"),
HL("9b09ffa71b942fcb27635fbcd5b0e944"
"bfdc63644f0713938a7f51535c3a35e2"));
}
This diff is collapsed.
This diff is collapsed.
#include <stdint.h>
#include <unistd.h>
#include "config.h"
#include "test_utils.h"
#include "test_fd.h"
void
doit (void)
{
s6a_fd_init();
sleep(1);
s6a_fd_stop();
success ("freediameter start/stop ok\n");
}
AM_CFLAGS = @ADD_CFLAGS@
AM_YFLAGS = -d
AM_LFLAGS = -o$(LEX_OUTPUT_ROOT).c
BUILT_SOURCE = hss_parser.h
noinst_LTLIBRARIES = libutils.la
libutils_la_LDFLAGS = -all-static
libutils_la_SOURCES = \
hss_parser.y hss_scanner.l \
hss_config.h hss_config.c \
conversion.h conversion.c
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment