0%

周谈(29)-snow3g流密码算法

前言

前面讲过ZUC算法是3GPP LTE 第三套加密标准核心算法,而Snow 3G则是第二套加密标准核心算法,ZUCSnow 3G算法的英文描述可以在这个网站上找到:

https://www.gsma.com/security/security-algorithms/

avatar

实现完ZUC的驱动后,这周实现了一下Snow 3G的驱动,顺带学习了一下这个算法。

Snow 3G

Snow 3G也包含了完整性算法UEA2和保密性算法UIA2两个部分,同时也依赖一个算法描述如何生成密钥流。

算法描述

文档链接 https://www.gsma.com/security/wp-content/uploads/2019/05/snow3gspec.pdf

根据输入的密钥和IV初始化,而后根据输入的数据长度产生密钥流。

avatar

在文档后面还有对应的C语言实现程序,当然只是一个基础的实现,如果要应用到实际的产品中还需要重构一下。

保密性算法

文档链接 https://www.gsma.com/security/wp-content/uploads/2019/05/uea2uia2d1v21.pdf

avatar

UEA2是一种流加密算法,按位进行加解密。从上图中可以看到对应的输入参数和输出结果。这些参数首先会根据固定的算法产生IV数据,然后按照算法描述产生密钥流,最终跟要加密或者解密的数据进行运算得到最终的结果。

avatar

同样的,在文档的后面有对应的C语言实现程序。

完整性算法

文档链接跟保密性算法是同一个文档。

avatar

具体的计算过程可以参考文档。在文档的后面也有对应的C语言实现程序。

不过完整性算法的C语言代码,最后计算MAC是有错误的,需要修改一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*原始代码 */
#if 0
for (i=0; i<4; i++)
MAC_I[i] = (mac32 >> (8*(3-i))) & 0xff; /* mac32是一个没有定义的变量 */

return MAC_I;

#else

/* 修改代码 */
for (i=0; i<4; i++) {
MAC_I[i] = ((EVAL >> (56 - (i * 8))) ^ ((z[4]) >> (24 - (i * 8)))) & 0xff;
}

return MAC_I;
#endif

}

我也是参考了一个go语言的snow3g的实现,然后是验证通过了的。

https://github.com/frankurcrazy/snow3g/blob/master/uia2/uia2.go

更多

这个3gpp的英文文档内容还是比较齐全的,而且还自带了算法的实现代码。同样的,ZUC对应的EEA3EIA3算法也有代码。不过,经过验证,我发现了一个问题,那就是ZUC的样例数据是按照大端字节序测试的,在小端主机上面,需要先把原始的数据转换一下字节序,才能得到正确的结果。而那个snow 3g的测试数据本身就认为你是小端的,在小端主机上面不需要转换字节序,计算出的结果就跟他的示例数据是一致的。如果有人研究的话,注意一下这点区别。

多学点知识还是有好处的,这边有个工作中的小插曲。

就是工作上需要在新的机型上验证一个功能,但是验证平台资源比较紧俏,运行速度又慢,而且很多人排着队等着去使用。那没有办法了,你只能在现有的机器资源上面先把代码编译测试了,然后再弄到新的机型上面去验证。也就是先本地验证了把基本的流程走通了,再换环境验证一下。不同的环境就有个系统版本不一致的问题,主要就是那个glibc的库不一样,系统内核版本不一样,那么就需要用到docker这个东西了。需要在本地搭建一个跟新机型上面环境一致的镜像系统,在这个镜像里面编译好了,再把生成的二进制拷贝到新机型上面验证。今年不是刚好看了一些docker的基础使用吗,然后自然就很快的用上了,节省了许多时间。

多学点东西是不错的,有博客记录一下更不错了,到用的时候可以来查一查,事半功倍。


行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

博客地址: https://fishmwei.github.io

掘金主页: https://juejin.cn/user/2084329776486919