LTE ZUC EEA3 EIA3 source code error 官方源代码 的错误之处

近期对我们LTE空口项目中增加了ZUC 祖冲之算法的加密和完整性保护。当然是从官方网站找到了算法协议标准和源代码以及测试数据样本。

但是移植过程中发现一些问题,这里我把自己走过的弯路分享出来!

Note:下文中提到的 identifier "z","L"均来自算法官方源代码的上下文,这里不作详细说明。

1.   EEA算法过程,官方代码没有错误,但是在小端平台不兼容,因此要适配改善。加密最后用Keystream对plainText进行异或加密时,

由于z[i]是大端存储的码流,而plainText本来是unsigned char 类型的码流,但转换为unsigned int类型的M[1]后,无疑就会在小端平台发生大小端颠倒的问题

因此我们应该作一个小的改动,在源代码的EEA3函数最后的for循环里,在C[i] = M[i] ^ z[i]前面增加一行代码:z[i] = ntohl(z[i]);

或者我们采用以字节为最小单位来进行异或操作,change the EEA3()'s parameter "u32 *M" into "u8 *M" type. 如下改进后的for循环(另增加一个switch语句):

  1. u32 tempLen = LENGTH&0xFFFFFFFC; 
  2. u32 zIndex = 0; 
  3. for(i = 0; i<tempLen; i+=4) 
  4.     zIndex = i/4; 
  5.     M[i]      ^= z[zIndex]>>24; 
  6.     M[i+1]  ^= z[zIndex]>>16; 
  7.     M[i+2]  ^= z[zIndex]>>8; 
  8.     M[i+3]  ^= z[zIndex]; 
  9.  
  10. switch(LENGHTH)&0x03 
  11. case 3: 
  12.     M[i+2] ^= z[zIndex+1]>>8; 
  13. case 2: 
  14.     M[i+1] ^= z[zIndex+1]>>16; 
  15. case 1: 
  16.     M[i]     ^= z[zIndex+1]>>24; 
  17. default
  18.     break
u32 tempLen = LENGTH&0xFFFFFFFC;
u32 zIndex = 0;
for(i = 0; i<tempLen; i+=4)
{
    zIndex = i/4;
    M[i]      ^= z[zIndex]>>24;
    M[i+1]  ^= z[zIndex]>>16;
    M[i+2]  ^= z[zIndex]>>8;
    M[i+3]  ^= z[zIndex];
}

switch(LENGHTH)&0x03
{
case 3:
    M[i+2] ^= z[zIndex+1]>>8;
case 2:
    M[i+1] ^= z[zIndex+1]>>16;
case 1:
    M[i]     ^= z[zIndex+1]>>24;
default:
    break;
}

2.  官方源代码的EIA3也是有问题的,首先要把GET_BIT()函数里增加对大小端平台的兼容性适配,改为按字节操作,接口类型也改了

  1. u8 GET_BIT(u8 *DATA, u32 i) 
  2.     return (DATA[i/8]) & (1<<(7-(i%8)))) ? 1 : 0; 
u8 GET_BIT(u8 *DATA, u32 i)
{
    return (DATA[i/8]) & (1<<(7-(i%8)))) ? 1 : 0;
}


在EIA3()函数的最后,源代码是:*MAC = T ^ GET_WORD(z,LENGHTH+32);

这是错误的,参考EEA3_EIA3_specifcation_v1_6.pdf   的4.5小节,最后计算MAC时是 T^Z(32*(L-1)),其实就是异或上 Z的最后四字节。将源代码更正为下面任意一行代码均能通过测试数据的测试。

  1. *MAC = T ^ GET_WORD(z,(LENGHTH+63)&0xFFFFFFE0); 
  2.  
  3. *MAC = T ^ z[L-1];/* 这个效率更高 */ 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值