Added function for derive keys

master
David Rupprecht 4 years ago committed by David Rupprecht
parent ceda458bb3
commit 306bb6b38b

@ -146,6 +146,7 @@ LIBLTE_ERROR_ENUM liblte_security_generate_k_up(uint8*
uint8* k_up_enc,
uint8* k_up_int);
LIBLTE_ERROR_ENUM liblte_security_generate_sk_gnb(uint8_t* k_enb, uint8_t* sk_gnb, uint16_t scg_counter);
/*********************************************************************
Name: liblte_security_128_eia2
@ -336,4 +337,16 @@ liblte_security_milenage_f2345(uint8* k, uint8* op, uint8* rand, uint8* res, uin
// Functions
LIBLTE_ERROR_ENUM liblte_security_milenage_f5_star(uint8* k, uint8* op, uint8* rand, uint8* ak);
LIBLTE_ERROR_ENUM liblte_security_generate_k_nr_rrc(uint8* k_gnb,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8* k_rrc_enc,
uint8* k_rrc_int);
LIBLTE_ERROR_ENUM liblte_security_generate_k_nr_up(uint8* k_gnb,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8* k_up_enc,
uint8* k_up_int);
#endif // SRSLTE_LIBLTE_SECURITY_H

@ -104,6 +104,20 @@ uint8_t security_generate_k_up(uint8_t* k_enb,
uint8_t* k_up_enc,
uint8_t* k_up_int);
uint8_t security_generate_k_nr_rrc(uint8_t* k_gnb,
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8_t* k_rrc_enc,
uint8_t* k_rrc_int);
uint8_t security_generate_k_nr_up(uint8_t* k_gnb,
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8_t* k_up_enc,
uint8_t* k_up_int);
uint8_t security_generate_sk_gnb(uint8_t* k_enb, uint8_t* sk_gnb, uint16_t scg_count);
/******************************************************************************
* Integrity Protection
*****************************************************************************/

@ -276,6 +276,115 @@ LIBLTE_ERROR_ENUM liblte_security_generate_k_rrc(uint8*
return (err);
}
LIBLTE_ERROR_ENUM liblte_security_generate_k_nr_rrc(uint8* k_gnb,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8* k_rrc_enc,
uint8* k_rrc_int)
{
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
uint8 s[7];
if (k_gnb != NULL && k_rrc_enc != NULL && k_rrc_int != NULL) {
// Construct S for KRRCenc
s[0] = 0x69; // FC
s[1] = 0x03; // P0
s[2] = 0x00; // First byte of L0
s[3] = 0x01; // Second byte of L0
s[4] = enc_alg_id; // P1
s[5] = 0x00; // First byte of L1
s[6] = 0x01; // Second byte of L1
// Derive KRRCenc
sha256(k_gnb, 32, s, 7, k_rrc_enc, 0);
// Construct S for KRRCint
s[0] = 0x69; // FC
s[1] = 0x04; // P0
s[2] = 0x00; // First byte of L0
s[3] = 0x01; // Second byte of L0
s[4] = int_alg_id; // P1
s[5] = 0x00; // First byte of L1
s[6] = 0x01; // Second byte of L1
// Derive KRRCint
sha256(k_gnb, 32, s, 7, k_rrc_int, 0);
err = LIBLTE_SUCCESS;
}
return (err);
}
LIBLTE_ERROR_ENUM liblte_security_generate_k_nr_up(uint8* k_gnb,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8* k_up_enc,
uint8* k_up_int)
{
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
uint8 s[7];
if (k_gnb != NULL && k_up_enc != NULL && k_up_int != NULL) {
// Construct S for KUPenc
s[0] = 0x69; // FC
s[1] = 0x05; // P0
s[2] = 0x00; // First byte of L0
s[3] = 0x01; // Second byte of L0
s[4] = enc_alg_id; // P1
s[5] = 0x00; // First byte of L1
s[6] = 0x01; // Second byte of L1
// Derive KUPenc
sha256(k_gnb, 32, s, 7, k_up_enc, 0);
// Construct S for KUPint
s[0] = 0x69; // FC
s[1] = 0x06; // P0
s[2] = 0x00; // First byte of L0
s[3] = 0x01; // Second byte of L0
s[4] = int_alg_id; // P1
s[5] = 0x00; // First byte of L1
s[6] = 0x01; // Second byte of L1
// Derive KUPint
sha256(k_gnb, 32, s, 7, k_up_int, 0);
err = LIBLTE_SUCCESS;
}
return (err);
}
/*********************************************************************
Name: liblte_security_generate_sk_gnb
Description: Derivation of S-KeNB or S-KgNB for dual connectivity.
Document Reference: 33.401 v10.0.0 Annex A.15
*********************************************************************/
LIBLTE_ERROR_ENUM liblte_security_generate_sk_gnb(uint8_t* k_enb, uint8_t* sk_gnb, uint16_t scg_counter)
{
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
uint8 s[5];
if (k_enb != NULL && sk_gnb != NULL) {
// Construct S for sk_gnb
s[0] = 0x1C; // FC
s[1] = (scg_counter >> 8) & 0xFF; // first byte of P0
s[2] = scg_counter & 0xFF; // second byte of P0
s[3] = 0x00; // First byte of L0
s[4] = 0x02; // Second byte of L0
// Derive sk_gnb
sha256(k_enb, 32, s, 5, sk_gnb, 0);
err = LIBLTE_SUCCESS;
}
return (err);
}
/*********************************************************************
Name: liblte_security_generate_k_up

@ -93,6 +93,37 @@ uint8_t security_generate_k_up(uint8_t* k_enb,
k_up_int);
}
uint8_t security_generate_k_nr_rrc(uint8_t* k_gnb,
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8_t* k_rrc_enc,
uint8_t* k_rrc_int)
{
return liblte_security_generate_k_nr_rrc(k_gnb,
(LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM)enc_alg_id,
(LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM)int_alg_id,
k_rrc_enc,
k_rrc_int);
}
uint8_t security_generate_k_nr_up(uint8_t* k_gnb,
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8_t* k_up_enc,
uint8_t* k_up_int)
{
return liblte_security_generate_k_nr_up(k_gnb,
(LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM)enc_alg_id,
(LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM)int_alg_id,
k_up_enc,
k_up_int);
}
uint8_t security_generate_sk_gnb(uint8_t* k_enb, uint8_t* sk_gnb, uint16_t scg_count)
{
return liblte_security_generate_sk_gnb(k_enb, sk_gnb, scg_count);
}
/******************************************************************************
* Integrity Protection
*****************************************************************************/

@ -153,6 +153,73 @@ int test_set_2()
;
}
int test_set_ksg()
{
LIBLTE_ERROR_ENUM err_lte = LIBLTE_ERROR_INVALID_INPUTS;
int32 err_cmp = 0;
uint8_t k_enb[] = {0xfe, 0x7d, 0xee, 0x80, 0x8d, 0x7f, 0x3b, 0x88, 0x2a, 0x08, 0x2c, 0xbd, 0xc8, 0x39, 0x0d, 0x12,
0x9e, 0x5d, 0x28, 0xaf, 0x0e, 0x83, 0x22, 0xeb, 0x57, 0x3a, 0xda, 0x36, 0xf2, 0x1a, 0x5a, 0x89};
uint8_t sk_gnb_o[32];
uint16_t scg_counter = 0;
err_lte = liblte_security_generate_sk_gnb(k_enb, sk_gnb_o, scg_counter);
TESTASSERT(err_lte == LIBLTE_SUCCESS);
arrprint(sk_gnb_o, sizeof(sk_gnb_o));
uint8_t sk_gnb[] = {0x45, 0xcb, 0xc3, 0xf8, 0xa8, 0x11, 0x93, 0xfd, 0x5c, 0x52, 0x29, 0x30, 0x0d, 0x59, 0xed, 0xf8,
0x12, 0xe9, 0x98, 0xa1, 0x15, 0xec, 0x4e, 0x0c, 0xe9, 0x03, 0xba, 0x89, 0x36, 0x7e, 0x26, 0x28};
err_cmp = arrcmp(sk_gnb_o, sk_gnb, sizeof(sk_gnb));
TESTASSERT(err_cmp == 0);
return SRSLTE_SUCCESS;
}
int test_set_nr_rrc_up()
{
LIBLTE_ERROR_ENUM err_lte = LIBLTE_ERROR_INVALID_INPUTS;
int32 err_cmp = 0;
uint8_t sk_gnb[] = {0x45, 0xcb, 0xc3, 0xf8, 0xa8, 0x11, 0x93, 0xfd, 0x5c, 0x52, 0x29, 0x30, 0x0d, 0x59, 0xed, 0xf8,
0x12, 0xe9, 0x98, 0xa1, 0x15, 0xec, 0x4e, 0x0c, 0xe9, 0x03, 0xba, 0x89, 0x36, 0x7e, 0x26, 0x28};
uint8_t sk_gnb_o[32];
uint8_t k_rrc_enc_o[32];
uint8_t k_rrc_int_o[32];
err_lte = liblte_security_generate_k_nr_rrc(sk_gnb,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_128_EEA2,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_EIA0,
k_rrc_enc_o,
k_rrc_int_o);
TESTASSERT(err_lte == LIBLTE_SUCCESS);
printf("RRC ENC output:\n");
arrprint(&k_rrc_enc_o[0], sizeof(k_rrc_enc_o));
uint8_t k_rrc_enc[] = {0x52, 0xa9, 0x95, 0xdf, 0xf8, 0x9b, 0xc2, 0x94, 0xbd, 0x89, 0xff,
0xb1, 0x37, 0xa2, 0x9f, 0x24, 0x66, 0xa0, 0x9e, 0x99, 0x23, 0x86,
0xc8, 0xd1, 0xdf, 0x78, 0x92, 0x96, 0x4c, 0x6f, 0xb5, 0x22};
err_cmp = arrcmp(k_rrc_enc_o, k_rrc_enc, sizeof(k_rrc_enc_o));
TESTASSERT(err_cmp == 0);
uint8_t k_up_enc_o[32];
uint8_t k_up_int_o[32];
err_lte = liblte_security_generate_k_nr_up(sk_gnb,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_128_EEA2,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_EIA0,
k_up_enc_o,
k_up_int_o);
uint8_t k_up_enc[] = {0x7c, 0xe2, 0x06, 0x70, 0xbb, 0xbc, 0xc5, 0x90, 0x40, 0x87, 0xc0, 0xd4, 0x26, 0x53, 0xc5, 0x40,
0x15, 0x20, 0x52, 0xd3, 0xdf, 0xbc, 0x3f, 0x05, 0x86, 0x9b, 0x7f, 0x92, 0x00, 0x95, 0xbe, 0x68};
printf("UP ENC output:\n");
arrprint(&k_up_enc_o[0], sizeof(k_up_enc_o));
err_cmp = arrcmp(k_up_enc_o, k_up_enc, sizeof(k_up_enc_o));
TESTASSERT(err_cmp == 0);
return SRSLTE_SUCCESS;
}
/*
Own test sets
*/
@ -161,5 +228,7 @@ int main(int argc, char* argv[])
{
TESTASSERT(test_set_2() == SRSLTE_SUCCESS);
TESTASSERT(test_set_ksg() == SRSLTE_SUCCESS);
TESTASSERT(test_set_nr_rrc_up() == SRSLTE_SUCCESS);
return SRSLTE_SUCCESS;
}

Loading…
Cancel
Save