解密函数: KNASenc ---NAS加密密钥, KASME中导出; 密钥导出函数KDF= HMAC-SHA-256 ( Key , S ),其中Key为指定的密钥,比如KASME、 KeNB、NH、CK||IK等,而S为输入参数,其构成表示为S = FC || P0 || L0 || P1 || L1 || P2 || L2 || P3 || L3 ||... || Pn || Ln,其中FC为单字节以区分不同算法,P0…Pn为输入参数编码,L0…Ln为两字节的相关P参数的长度表示。 5)、导出NAS加密算法密钥的输入参数S由以下构成: -FC = 0x15 -P0 = algorithm type distinguisher -L0 = length of algorithm type distinguisher (i.e. 0x00 0x01) -P1 = algorithm identity -L1 = length of algorithm identity (i.e. 0x00 0x01) 算法类型区别器P0由下表定义: 算法标识(algorithm identity): 这些算法标识都是一个字节长度,有效位为低位4比特,高位4比特都设为0 (高位4比特中的低2位为将来保留使用,高2位为私有保留使用)。 输入参数S生成: uint8_t s[7]; s[0] = 0x15; // FC导出五种算法密钥的算法 s[1] = 0x01; // P0 NAS-enc-alg s[2] = 0x00; // First byte of L0 s[3] = 0x01; // Second byte of L0 s[4] = enc_alg_id; // P1 NAS-enc-alg s[5] = 0x00; // First byte of L1 s[6] = 0x01; // Second byte of L1 调用openssl函数HMAC,HMAC(EVP_sha256(),KASME, 32, s, 7, NULL, NULL); EVP_sha256:sha256算法函数。 HMAC原型: unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d, size_t n, unsigned char *md, unsigned int *md_len); HMAC生成256bit密钥,解密输入密钥就128位,截取低128位。 代码实现: uint8_t k_nas_enc[16]; memcpy(k_nas_enc, HMAC(EVP_sha256(), k_asme, 32, s, 7, NULL, NULL)+16, 16); EPS系统中涉及加密算法有四种分别为EEA0/EEA1/EEA2/EEA3,其中EEA0意味着没有启用加密算法,但在实际过程中还需像对待有加密算法一样,只不过有些值的输出为0。 EPS加密算法逻辑图如下: EPS加密算法逻辑图如下:
图中发射端的密文块由明文块与密钥流块异或运算获得,而接收端的明文块则由密文块与密钥流异或运算获得。 加密算法的输入参数包括128-bit的加密密钥KEY(KNASenc/KRRCenc/KUPenc)、32-bit的COUNT、5-bit的承载标识BEARER、1-bit的传输方向DIRECTION(“0”为上行,“1”为下行)以及密钥流(KEYSTREAM)要求的长度LENGTH指示。 EEA0算法除了要求LENGTH参数外别无其他参数,且密钥流KEYSTREAM全为0 128-EEA1基于SNOW 3G,等同于UEA2 128-EEA2 基于CTR模式的128-bit AES,下面描述该算法: CTR模式T1,T2…Ti所需的128-bit counter blocks的序列遵循以下构成: 比如T1的高位64比特包括COUNT[0] .. COUNT[31] │ BEARER[0] .. BEARER[4] │ DIRECTION │ 026 (i.e. 26 zero bits),T1的低位64比特为全0。 本系统中数据nas就使用128-EEA2加密,Ti向量iv实现如下: Uint8_t iv[16]; memset(iv, 0, 16); iv[0] = (count >> 24) & 0xFF; iv[1] = (count >> 16) & 0xFF; iv[2] = (count >> 8) & 0xFF; iv[3] = count & 0xFF; iv[4] = (bearer << 3) | (direction << 2); 调用Intel硬件解密接口,msg_enc加密数据,decdata解密后明文数据,msg_enc_len加密数据长度 AES_encdec128_CTR(msg_enc,decdata,msg_enc_len, k_nas_enc,iv);
|