Commit e28577d0 authored by lfq's avatar lfq

add sm9 digital signature

parent 5de1609a
......@@ -1799,6 +1799,7 @@ add_library(LIB_NAS_SIMUE
${NAS_SRC}UE/nas_proc.c
${NAS_SRC}UE/nas_user.c
${NAS_SRC}NR_UE/nr_nas_msg_sim.c
${OPENAIR3_DIR}/sm9/SM9_sv.c
${libnas_api_OBJS}
${libnas_ue_api_OBJS}
${libnas_emm_msg_OBJS}
......@@ -1816,6 +1817,7 @@ add_library(LIB_NAS_SIMUE
target_include_directories(LIB_NAS_SIMUE PRIVATE ${OPENAIR_DIR}/common/utils/ds/)
target_link_libraries(LIB_NAS_SIMUE PRIVATE lte_rrc)
target_link_libraries(LIB_NAS_SIMUE INTERFACE ${OPENAIR3_DIR}/sm9/miracl.a)
set(NAS_SIM_LIB LIB_NAS_SIMUE)
......@@ -1843,6 +1845,7 @@ target_include_directories(LIB_NAS_UE PRIVATE ${OPENAIR_DIR}/common/utils/ds/)
set(NAS_UE_LIB LIB_NAS_UE)
target_link_libraries(LIB_NAS_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
include_directories(${OPENAIR3_DIR}/sm9)
include_directories(${NAS_SRC}NR_UE)
include_directories(${NAS_SRC}UE)
include_directories(${NAS_SRC}UE/API/USER)
......
......@@ -459,6 +459,7 @@ ldpc_interface_t ldpc_interface = {0}, ldpc_interface_offload = {0};
int main(int argc, char **argv)
{
srand((unsigned int)time(NULL));
int set_exe_prio = 1;
if (checkIfFedoraDistribution())
if (checkIfGenericKernelOnFedora())
......
......@@ -1272,7 +1272,6 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
if (Srb_id != 1 && Srb_id != 2) {
LOG_E(NR_RRC, "Received message on DL-DCCH (SRB%ld), should not have ...\n", Srb_id);
}
LOG_D(NR_RRC, "Decoding DL-DCCH Message\n");
asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_DL_DCCH_Message, (void **)&dl_dcch_msg, Buffer, Buffer_size, 0, 0);
......
......@@ -51,6 +51,9 @@ int encode_fgs_authentication_response(fgs_authentication_response_msg *authenti
else
encoded += encode_result;
memcpy((void *)buffer + encoded, (void *)authentication_response->eap.value, authentication_response->eap.length);
encoded += authentication_response->eap.length;
return encoded;
}
......@@ -57,6 +57,7 @@ typedef struct fgs_authentication_response_msg_tag {
SpareHalfOctet sparehalfoctet:4;
MessageType messagetype;
AuthenticationResponseParameter authenticationresponseparameter;
OctetString eap;
} fgs_authentication_response_msg;
int encode_fgs_authentication_response(fgs_authentication_response_msg *authentication_response, uint8_t *buffer, uint32_t len);
......
......@@ -53,6 +53,8 @@
#include "openair3/SECU/nas_stream_eia2.h"
#include "openair3/UTILS/conversions.h"
#include "SM9_sv.h"
uint8_t *registration_request_buf;
uint32_t registration_request_len;
extern char *baseNetAddress;
......@@ -512,8 +514,28 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
}
static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, uint8_t *buf)
{
LOG_I(NAS, "======================= signature verification(SM9) start =======================\n");
uint8_t amf_id[6] = {0};
sprintf(amf_id, "amf%02x", buf[50]);
LOG_I(NAS, "****** amf_id: %s ******\n", amf_id);
uint8_t amf_msg[8] = {0};
memcpy(amf_msg,&buf[51],8);
uint8_t amf_h[32] = {0};
memcpy(amf_h,&buf[59],32);
uint8_t amf_s[64] = {0};
memcpy(amf_s,&buf[91],64);
uint8_t hid = 0x01;
int res_sm9 = SM9_Verify(amf_h, amf_s, &hid, amf_id, amf_msg, 8, nas->uicc->pukplmn);
if(!res_sm9) {
LOG_I(NAS, "****** Signature verification passed ******\n");
} else {
LOG_E(NAS, "****** Signature verification failure ******\n");
}
LOG_I(NAS, "======================= signature verification(SM9) end =======================\n");
derive_ue_keys(buf, nas);
OctetString res;
res.length = 16;
......@@ -542,6 +564,49 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN
//set response parameter
mm_msg->fgs_auth_response.authenticationresponseparameter.res = res;
size += 18;
// EAP Msg
//EAP HEAD: 1(head IEI) + 2(length) +
//DATA : 1(code) + 1(id) + 2(length) + 1(type)
// 8(msg) + 32(h) + 64(s) = 112 byte
LOG_I(NAS, "======================= signature generation(SM9) start =======================\n");
uint8_t eap_buf[112] = {0};
OctetString eap;
eap.length = 112;
eap.value = eap_buf;
// eap.value = calloc(1,112);
// memset(eap.value,0,112);
eap.value[0] = 0x78; //EAP IEI
eap.value[1] = 0x00; //length-h
eap.value[2] = 109; //length-l
eap.value[3] = 0x02; //EAP code
eap.value[4] = 0x01; //EAP id
eap.value[5] = 0x00; //EAP length-h
eap.value[6] = 109; //EAP length-l
eap.value[7] = 255; //EAP type
uint8_t msg[8] = {0};
uint8_t h[32] = {0};
uint8_t s[64] = {0};
for (int i = 0; i < 8; ++i) {
msg[i] = rand() % 256;
}
uint8_t sm9_rand[32] = {0};
for (int i = 0; i < 32; ++i) {
sm9_rand[i] = rand() % 256;
}
res_sm9 = SM9_Sign(msg, 8, sm9_rand, nas->uicc->prkue, nas->uicc->pukplmn, h, s);
if(!res_sm9) {
LOG_I(NAS, "****** Signature generation successfully ******\n");
} else {
LOG_E(NAS, "****** Signature generation failure ******\n");
}
memcpy(&eap.value[8], msg, 8); //SM9 msg
memcpy(&eap.value[16], h, 32); //SM9 SIG-h
memcpy(&eap.value[48], s, 64); //SM9 SIG-s
mm_msg->fgs_auth_response.eap = eap;
size += eap.length;
LOG_I(NAS, "======================= signature generation(SM9) end =======================\n");
// encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
......@@ -1037,6 +1102,7 @@ static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[8], const
void *nas_nrue_task(void *args_p)
{
nr_ue_nas.uicc = checkUicc(0);
SM9_Init();
while (1) {
nas_nrue(NULL);
}
......
......@@ -42,6 +42,8 @@ extern uint16_t NB_UE_INST;
{"nmc_size" "number of digits in NMC", 0, .iptr=&uicc->nmc_size, .defintval=2, TYPE_INT, 0 }, \
{"key", "USIM Ki\n", 0, .strptr=&uicc->keyStr, .defstrval="fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING, 0 }, \
{"opc", "USIM OPc\n", 0, .strptr=&uicc->opcStr, .defstrval="c42449363bbad02b66d16bc975d77cc1", TYPE_STRING, 0 }, \
{"pukplmn", "USIM PUKplmn\n", 0, .strptr=&uicc->pukplmnStr, .defstrval="9ce85304fa6120935d33102c09e43f5271a6399ecad5ecee7d0294afabe0c0819cd98006b55c063af9f37ad15ec6e6d5e6a33004ae53fe27599badab5aa83f367e5b4b88d4ba53707b7d9f1d771e32d33172e0e948d63caa73bb3fa2beb1101fb2ab148c8d75b03849447d4a6f77e537c674b3e0d39ebce9b624e8951edc01f0", TYPE_STRING, 0 }, \
{"prkue", "USIM PRKue\n", 0, .strptr=&uicc->prkueStr, .defstrval="04f62815ff8a062e7763650db869e1b6a92ceb286f6675c4c2b892fbc6621b09945e710c222f58775a56b136788733ae54f502992725551e0c7526514e588746", TYPE_STRING, 0 }, \
{"amf", "USIM amf\n", 0, .strptr=&uicc->amfStr, .defstrval="8000", TYPE_STRING, 0 }, \
{"sqn", "USIM sqn\n", 0, .strptr=&uicc->sqnStr, .defstrval="000000", TYPE_STRING, 0 }, \
{"dnn", "UE dnn (apn)\n", 0, .strptr=&uicc->dnnStr, .defstrval="oai", TYPE_STRING, 0 }, \
......@@ -82,6 +84,8 @@ uicc_t *init_uicc(char *sectionName) {
uicc->dnnStr, uicc->nssai_sst, uicc->nssai_sd);
to_hex(uicc->keyStr,uicc->key, sizeof(uicc->key) );
to_hex(uicc->opcStr,uicc->opc, sizeof(uicc->opc) );
to_hex(uicc->pukplmnStr,uicc->pukplmn, sizeof(uicc->pukplmn) );
to_hex(uicc->prkueStr,uicc->prkue, sizeof(uicc->prkue) );
to_hex(uicc->sqnStr,uicc->sqn, sizeof(uicc->sqn) );
to_hex(uicc->amfStr,uicc->amf, sizeof(uicc->amf) );
return uicc;
......
......@@ -48,6 +48,8 @@ typedef struct {
char *imeisvStr;
char *keyStr;
char *opcStr;
char *pukplmnStr;
char *prkueStr;
char *amfStr;
char *sqnStr;
char *dnnStr;
......@@ -55,6 +57,8 @@ typedef struct {
int nssai_sd;
uint8_t key[16];
uint8_t opc[16];
uint8_t pukplmn[128];
uint8_t prkue[64];
uint8_t amf[2];
uint8_t sqn[6];
int nmc_size;
......
This diff is collapsed.
//************************************************************************
// File name: SM9_sv.h
// Version: SM9_sv_V1.0
// Date: Dec 15,2016
// Description: implementation of SM9 signature algorithm and verification algorithm
// all operations based on BN curve line function
// Function List:
// 1.bytes128_to_ecn2 //convert 128 bytes into ecn2
// 2.zzn12_ElementPrint //print all element of struct zzn12
// 3.ecn2_Bytes128_Print //print 128 bytes of ecn2
// 4.LinkCharZzn12 //link two different types(unsigned char and zzn12)to one(unsigned char)
// 5.Test_Point //test if the given point is on SM9 curve
// 6.Test_Range //test if the big x belong to the range[1,N-1]
// 7.SM9_Init //initiate SM9 curve
// 8.SM9_H1 //function H1 in SM9 standard 5.4.2.2
// 9.SM9_H2 //function H2 in SM9 standard 5.4.2.3
// 10.SM9_GenerateSignKey //generate signed private and public key
// 11.SM9_Sign //SM9 signature algorithm
// 12.SM9_Verify //SM9 verification
// 13.SM9_SelfCheck() //SM9 slef-check
//
// Notes:
// This SM9 implementation source code can be used for academic, non-profit making or non-commercial use only.
// This SM9 implementation is created on MIRACL. SM9 implementation source code provider does not provide MIRACL library, MIRACL license or any permission to use MIRACL library. Any commercial use of MIRACL requires a license which may be obtained from Shamus Software Ltd.
//**************************************************************************/
#ifndef SM9_SV_H
#define SM9_SV_H
#include <stdlib.h>
#include <math.h>
#include "miracl.h"
// #include "R-ate.h"
#define SM3_len 256
#define SM3_T1 0x79CC4519
#define SM3_T2 0x7A879D8A
#define SM3_IVA 0x7380166f
#define SM3_IVB 0x4914b2b9
#define SM3_IVC 0x172442d7
#define SM3_IVD 0xda8a0600
#define SM3_IVE 0xa96f30bc
#define SM3_IVF 0x163138aa
#define SM3_IVG 0xe38dee4d
#define SM3_IVH 0xb0fb0e4e
/* Various logical functions */
#define SM3_p1(x) (x^SM3_rotl32(x,15)^SM3_rotl32(x,23))
#define SM3_p0(x) (x^SM3_rotl32(x,9)^SM3_rotl32(x,17))
#define SM3_ff0(a,b,c) (a^b^c)
#define SM3_ff1(a,b,c) ((a&b)|(a&c)|(b&c))
#define SM3_gg0(e,f,g) (e^f^g)
#define SM3_gg1(e,f,g) ((e&f)|((~e)&g))
#define SM3_rotl32(x,n) ((((unsigned int) x) << n) | (((unsigned int) x) >> (32 - n)))
#define SM3_rotr32(x,n) ((((unsigned int) x) >> n) | (((unsigned int) x) << (32 - n)))
typedef struct {
unsigned int state[8];
unsigned int length;
unsigned int curlen;
unsigned char buf[64];
} SM3_STATE;
typedef struct
{
zzn4 a, b, c;
BOOL unitary;// "unitary property means that fast squaring can be used, and inversions are just conjugates
BOOL miller; // "miller" property means that arithmetic on this instance can ignore multiplications
// or divisions by constants - as instance will eventually be raised to (p-1).
} zzn12;
#define BNLEN 32 //BN curve with 256bit is used in SM9 algorithm
#define SM9_ASK_MEMORY_ERR 0x00000001 //申请内存失败
#define SM9_H_OUTRANGE 0x00000002 //签名H不属于[1,N-1]
#define SM9_DATA_MEMCMP_ERR 0x00000003 //数据对比不一致
//#ifndef SM9_MEMBER_ERR
#define SM9_MEMBER_ERR 0x00000004 //群的阶错误
//#endif
#define SM9_S_NOT_VALID_G1 0x00000006 //S不属于群G1
#define SM9_G1BASEPOINT_SET_ERR 0x00000007 //G1基点设置错误
#define SM9_G2BASEPOINT_SET_ERR 0x00000008 //G2基点设置错误
#define SM9_L_error 0x00000009 //参数L错误
#define SM9_GEPUB_ERR 0x0000000A //生成公钥错误
#define SM9_GEPRI_ERR 0x0000000B //生成私钥错误
#define SM9_SIGN_ERR 0x0000000C //签名错误
//#ifndef SM9_MY_ECAP_12A_ERR
#define SM9_MY_ECAP_12A_ERR 0x00000005 //R-ate对计算出现错误
//#endif
BOOL bytes128_to_ecn2(unsigned char Ppubs[], ecn2 *res);
void zzn12_ElementPrint(zzn12 x);
void ecn2_Bytes128_Print(ecn2 x);
void LinkCharZzn12(unsigned char *message, int len, zzn12 w, unsigned char *Z, int Zlen);
int Test_Point(epoint* point);
int Test_Range(big x);
int SM9_Init();
int SM9_H1(unsigned char Z[], int Zlen, big n, big h1);
int SM9_H2(unsigned char Z[], int Zlen, big n, big h2);
int SM9_GenerateSignKey(unsigned char hid[], unsigned char *ID, int IDlen, big ks, unsigned char Ppubs[], unsigned char dsa[]);
int SM9_Sign(unsigned char *message, int len, unsigned char rand[],
unsigned char dsa[], unsigned char Ppub[], unsigned char H[], unsigned char S[]);
int SM9_Verify(unsigned char H[], unsigned char S[], unsigned char hid[], unsigned char *IDA, unsigned char *message, int len,
unsigned char Ppub[]);
int SM9_SelfCheck(unsigned char* message);
#endif
\ No newline at end of file
This diff is collapsed.
......@@ -5,4 +5,6 @@ opc= "000102030405060708090a0b0c0d0e0f";
dnn= "internet";
nssai_sst=1;
nssai_sd=0xFFFFFF;
pukplmn= "9ce85304fa6120935d33102c09e43f5271a6399ecad5ecee7d0294afabe0c0819cd98006b55c063af9f37ad15ec6e6d5e6a33004ae53fe27599badab5aa83f367e5b4b88d4ba53707b7d9f1d771e32d33172e0e948d63caa73bb3fa2beb1101fb2ab148c8d75b03849447d4a6f77e537c674b3e0d39ebce9b624e8951edc01f0";
prkue= "04f62815ff8a062e7763650db869e1b6a92ceb286f6675c4c2b892fbc6621b09945e710c222f58775a56b136788733ae54f502992725551e0c7526514e588746";
}
uicc0 = {
imsi = "466920000000150";
key = "00112233445566778899aabbccddeeff";
opc= "000102030405060708090a0b0c0d0e0f";
dnn= "internet";
nssai_sst=1;
nssai_sd=0xFFFFFF;
pukplmn= "872419c291f34e98e25a7fd2f71822e06a82335347fce926baa08de66b821d742c8477dbc1835310d5a726356e0b278dd79c26025765728eda6650266d7046cf5806a048bb2b33f0a543904cab5a4e0c4f3b7e2d966a560bc025e10be994b1476863f62d100af6114ff3a3ff8380fafff3e5bcde6740c701fcacfb95cc1f63ea";
prkue= "7aa80e66e466dde9bd57a73c3b5cd7748f87fc76bcf4c42ebc964d0dd03726233c76c2ab08ab2b93435437fe7841ddd0697e92ffb0191dafd088251cbe3dd722";
}
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