Commit 1a9fd602 authored by He Shanyun's avatar He Shanyun
Browse files

set authentication code for security mode complete

parent 89eae041
......@@ -17,6 +17,12 @@
#include "nr_nas_msg_sim.h"
#include "aka_functions.h"
#include "secu_defs.h"
char netName[] = "5G:mnc093.mcc208.3gppnetwork.org";
char imsi[] = "2089300007487";
// USIM_API_K: 5122250214c33e723a5dd523fc145fc0
uint8_t k[16] = {0x51, 0x22, 0x25, 0x02, 0x14,0xc3, 0x3e, 0x72, 0x3a, 0x5d, 0xd5, 0x23, 0xfc, 0x14, 0x5f, 0xc0};
// OPC: 981d464c7c52eb6e5036234984ad0bcf
const uint8_t opc[16] = {0x98, 0x1d, 0x46, 0x4c,0x7c,0x52,0xeb, 0x6e, 0x50, 0x36, 0x23, 0x49, 0x84, 0xad, 0x0b, 0xcf};
static int nas_protected_security_header_encode(
char *buffer,
......@@ -119,7 +125,6 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
}
void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output) {
char netName[] = "5G:mnc093.mcc208.3gppnetwork.org";
uint8_t S[100];
S[0] = 0x6B;
int netNamesize = strlen(netName);
......@@ -160,6 +165,63 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16
output[i] = out[16 + i];
}
void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32]) {
uint8_t S[100];
uint8_t key[32];
int netNamesize = strlen(netName);
memcpy(&key[0], ck, 16);
memcpy(&key[16], ik, 16); //KEY
S[0] = 0x6A;
memcpy(&S[1], netName, netNamesize);
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
for (int i = 0; i < 6; i++) {
S[3 + netNamesize + i] = sqn[i];
}
S[9 + netNamesize] = 0x00;
S[10 + netNamesize] = 0x06;
kdf(key, 32, S, 11 + netNamesize, kausf, 32);
}
void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32]) {
uint8_t S[100];
int netNamesize = strlen(netName);
S[0] = 0x6C; //FC
memcpy(&S[1], netName, netNamesize);
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
kdf(kausf, 32, S, 3 + netNamesize, kseaf, 32);
}
void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba) {
int imsiLen = strlen(imsi);
uint8_t S[100];
S[0] = 0x6D; //FC = 0x6D
memcpy(&S[1], imsi, imsiLen);
S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8);
S[2 + imsiLen] = (uint8_t)(imsiLen & 0x00ff);
S[3 + imsiLen] = abba & 0x00ff;
S[4 + imsiLen] = (abba & 0xff00) >> 8;
S[5 + imsiLen] = 0x00;
S[6 + imsiLen] = 0x02;
kdf(kseaf, 32, S, 7 + imsiLen, kamf, 32);
}
//------------------------------------------------------------------------------
void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32], uint8_t *knas_int) {
uint8_t S[20];
uint8_t out[32] = { 0 };
S[0] = 0x69; //FC
S[1] = (uint8_t)(nas_alg_type & 0xFF);
S[2] = 0x00;
S[3] = 0x01;
S[4] = nas_alg_id;
S[5] = 0x00;
S[6] = 0x01;
kdf(kamf, 32, S, 7, out, 32);
for (int i = 0; i < 16; i++)
knas_int[i] = out[16 + i];
}
void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
int size = sizeof(mm_msg_header_t);
......@@ -275,14 +337,16 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
}
OctetString knas_int;
void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
uint8_t ak[6];
// USIM_API_K: 5122250214c33e723a5dd523fc145fc0
uint8_t k[16] = {0x51, 0x22, 0x25, 0x02, 0x14,0xc3, 0x3e, 0x72, 0x3a, 0x5d, 0xd5, 0x23, 0xfc, 0x14, 0x5f, 0xc0};
// OPC: 981d464c7c52eb6e5036234984ad0bcf
const uint8_t opc[16] = {0x98, 0x1d, 0x46, 0x4c,0x7c,0x52,0xeb, 0x6e, 0x50, 0x36, 0x23, 0x49, 0x84, 0xad, 0x0b, 0xcf};
uint8_t kausf[32];
uint8_t sqn[6];
uint8_t kseaf[32];
uint8_t kamf[32];
OctetString res;
// get RAND for authentication request
unsigned char rand[16];
......@@ -296,7 +360,44 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
transferRES(ck, ik, resTemp, rand, output);
OctetString res;
// get knas_int
knas_int.length = 16;
knas_int.value = malloc(knas_int.length);
for(int index = 0; index < 6; index++){
sqn[index] = buf[26+index];
}
derive_kausf(ck, ik, sqn, kausf);
derive_kseaf(kausf, kseaf);
derive_kamf(kseaf, kamf, 0x0000);
derive_knas(0x02, 2, kamf, knas_int.value);
printf("kausf:");
for(int i = 0; i < 32; i++){
printf("%x ", kausf[i]);
}
printf("\n");
printf("kseaf:");
for(int i = 0; i < 32; i++){
printf("%x ", kseaf[i]);
}
printf("\n");
printf("kamf:");
for(int i = 0; i < 32; i++){
printf("%x ", kamf[i]);
}
printf("\n");
printf("knas_int:\n");
for(int i = 0; i < 16; i++){
printf("%x ", knas_int.value[i]);
}
printf("\n");
// set res
res.length = 16;
res.value = output;
......@@ -335,7 +436,8 @@ void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
MM_msg *mm_msg;
int i;
nas_stream_cipher_t stream_cipher;
uint8_t mac[4];
// set security protected header
nas_msg.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
nas_msg.header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX;
......@@ -369,4 +471,23 @@ void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
int security_header_len = nas_protected_security_header_encode((char*)(initialNasMsg->data),&(nas_msg.header), size);
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
stream_cipher.key = knas_int.value;
stream_cipher.key_length = 16;
stream_cipher.count = 0;
stream_cipher.bearer = 1;
stream_cipher.direction = 0;
stream_cipher.message = (unsigned char *)(initialNasMsg->data + 6);
/* length in bits */
stream_cipher.blength = (initialNasMsg->length - 6) << 3;
// only for Type of integrity protection algorithm: 128-5G-IA2 (2)
nas_stream_encrypt_eia2(
&stream_cipher,
mac);
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
for(int i = 0; i < 4; i++){
initialNasMsg->data[2+i] = mac[i];
}
}
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