MesaLink 是百度安全实验室开发的一个内存安全并兼容 OpenSSL 的传输层安全(Transport Layer Security, TLS)协议栈。近年来 TLS 漏洞频发,以 2014 年的 OpenSSL"心血"为代表的内存安全漏洞对业界造成了巨大损失。MesaLink 的主要目标是用 Rust 这样一个保证内存安全的语言,根除 TLS 协议栈中威胁通信安全性和完整性的内存安全漏洞,减小攻击面且保证攻击面收敛可审计。此外,MesaLink 支持跨平台,提供兼容 OpenSSL 的 C API,更可在安卓和 libcurl 中无缝替换 OpenSSL。这极大地降低了开发成本,方便智能设备厂商快速获取安全通信的能力,从而实质性提升智能设备生态的安全性。MesaLink 已经在 Github 上以 BSD 协议开源。两天内已经获得了 400 多个 Star,并登上 Github Trending Project 榜单,在 Rust 语言分榜排行第一。
1 Mitt 2018-04-06 05:46:42 +08:00 ![]() 拿 Rust 保证漏洞安全,怕不是下次出现致命漏洞的是 Rust 哦 |
![]() | 4 Servo 2018-04-06 07:29:19 +08:00 持续关注,看 README 感觉不错。 |
![]() | 5 boywhp 2018-04-06 07:36:00 +08:00 看了一下感觉挺好, 我准备实际测试一下 |
![]() | &bsp; 6 boywhp 2018-04-06 07:56:57 +08:00 gcc -oclient client.c -Os -I ./include/ -L ./ -lmesalink -lpthread -ldl ubuntu x64 实际编译了一下 example 里面的 client 输出 3226577 字节的 binary 感觉体积有点重啊, 比 openssl 要大, 是我哪里没搞对? |
7 bincat OP @boywhp 试下加上 -ffunction-sections -fdata-sections -Wl,--gc-sections |
![]() | 8 boywhp 2018-04-06 08:04:19 +08:00 @bincat gcc -oclient client.c -ffunction-sections -fdata-sections -Wl,--gc-sections -Os -s -I ./include/ -L ./ -lmesalink -lpthread -ldl 编译输出 1146104 可执行文件, 终于可以接受了 |
![]() | 9 metorm 2018-04-06 08:36:58 +08:00 via Android 百度出品…… |
![]() | 10 omph 2018-04-06 08:52:21 +08:00 中国出品基础设施,可贺 |
![]() | 13 metorm 2018-04-06 09:20:18 +08:00 via Android @boywhp 就是感慨一下,没有特别的指向。不过话说回来,百度有没有技术实力去在开源软件中预留后门呢?类似随机数发生器中的逻辑漏洞一类的。 |
14 hehe12dyo 2018-04-06 09:23:45 +08:00 楼上至少有两个大黑客。 |
![]() | 15 qiumaoyuan 2018-04-06 09:26:51 +08:00 @boywhp 请问具体到谁?强在哪? |
16 u5f20u98de 2018-04-06 10:23:36 +08:00 没有什么语言能保证不出逻辑方面的漏洞吧 :) |
17 u5f20u98de 2018-04-06 10:27:18 +08:00 openssl 也曾经出了好几个逻辑方面的漏洞,不过影响没有当初 heartbleed 那么厉害 |
![]() | 18 exch4nge 2018-04-06 10:27:36 +08:00 原来 LZ 就是原作者啊 |
![]() | 19 orangeade 2018-04-06 10:34:46 +08:00 via Android 厉害了,支持开源基础设施 |
![]() | 20 chanssl 2018-04-06 10:40:41 +08:00 支持 |
21 bincat OP ![]() @u5f20u98de 我们使用 Rust 语言减少越界访问、迷途指针等内存安全问题。逻辑漏洞我们靠形式化分析解决,目前正在和一些高校和有分析能力的创业公司合作推进这个方向。 |
![]() | 24 secondwtq 2018-04-06 20:05:39 +08:00 |
![]() | 26 msg7086 2018-04-06 22:36:20 +08:00 连 CPU 都能出致命漏洞,某个语言或者运行时出漏洞很奇怪吗? |
![]() | 27 Kilerd 2018-04-06 23:39:46 +08:00 基础化设施,支持一波。 Rust 写的,支持一波。 |
![]() | 28 waruqi 2018-04-07 00:04:42 +08:00 via Android 看着像基于 rustsl 做的 openssl 接口 wrap ? |
![]() | 30 congeec 2018-04-07 13:28:33 +08:00 via iPhone @abscon 语言可以规范和实现分开来做。比如 C 艹一套标准有多种编译器+标准库的实现。标准库的代码瑕疵可能导致安全漏洞,但是语言规范设计漏洞导致不得 bug 我还没听说过。 Python 么,大家都默认指 CPython。你说 python 爆漏洞,应该指后者吧。 rust 跟 C 艹类似,可以 bare metal, 也可以用标准库。 我觉得一楼指的是语言设计方面的缺陷导致安全隐患。所以问了下 |
31 gnaggnoyil 2018-04-07 14:27:02 +08:00 @congeec C++语言规范经常有因为考虑不周到而导致的漏洞.CWG 和 LWG 的 issue 里一抓一大把.但是 C++语言规范的漏洞顶多是导致各个实现的行为不一致,和所谓安全性漏洞几乎没有关系.OpenSSL 相当多的漏洞主要原因就是 C 的限制导致的代码质量不行,所以我还是很看好用 Rust 重写的 SSL 实现的 |
![]() | 32 linusyang 2018-04-07 15:40:16 +08:00 ![]() @waruqi 我也感觉是这样,本质是一个兼容封装库。找了半天实际的加密算法代码,mesalink -> rustls -> ring,最后发现实际加密算法还是用 C 写的,而且是 BoringSSL(OpenSSL)复制过来的 [1]。有点又绕回来的感觉,这么一层一层封装至少性能上不会比 OpenSSL 更好,也会依赖 OpenSSL 具体实现的安全。 想起来 Hacker News/Reddit 上的老笑话,万事万物都可以用 Rust 重写。用 Rust 写是很好,但不是万金油,我认为只能解决一部分问题,比如内存上的问题。最终还是得做形式化分析,证明完导出代码,比如用 F* 写的一个 TLS 库 [2],用的加密算法也是验证过的 [3],虽然形式化分析是条不归路。 [1] https://github.com/briansmith/ring/tree/master/crypto [2] https://github.com/mitls/mitls-fstar [3] https://github.com/mitls/hacl-star |
![]() | 33 zhicheng 2018-04-07 16:02:08 +08:00 原 po 就是觉得用 C 容易出问题,所以用 rust。那别人评论质疑一下 rust 可能出问题又被粉丝喷,rust 粉丝你们棒棒的。 加密库是个深坑,用 C 写都容易出问题,更别说其它语言了,你们还是回去写 runtime 吧。 |
34 bincat OP @linusyang 使用 ring 来自 BoringSSL 的加密算法原语的原因我们和 ring 的作者 Brian Smith 讨论过,主要的理由是 BoringSSL 的原语的正确性和性能更有保证,尤其是 constant time crypto。性能上其实不差,可以参考完整版的文章 https://zhuanlan.zhihu.com/p/35371177 和 https://gist.github.com/kevinis/ca7fa432af076a5f3330c7e39daf27fc |
![]() | 35 linusyang 2018-04-08 06:24:50 +08:00 ![]() @bincat 我看了一下你们的 benchmark,测试 OpenSSL 的时候并不公平,在测试的每次 iteration 内部有很多 OpenSSL EVP context 初始化和释放的额外开销,导致测试时间多了将近一倍。这个可以用 Instruments.app 或者 valgrind/callgrind 作 profile,很容易就可以查到。 具体来说,OpenSSL 测试的部分用的是 rust-openssl 库,调用的是 symm.rs 里面高层 api,具体的函数是 encrypt_aead [1]。注意到 encrypt_aead 在每次做加密的时候都会新建一个 Crypter 对象,加密完离开作用域会自动调用 drop trait 里定义的 drop()释放。而 Crypter 封装的也是 OpenSSL 的高层 EVP api,初始化的时候会调用一次 EVP_CIPHER_CTX_new 和两次 EVP_CipherInit_ex,释放的时候会调用一次 EVP_CIPHER_CTX_free。这些函数在 test::Bencher 测试的时候,每次循环都会调用,产生的开销还是挺大的。 事实上在加密的时候并不是每次都要新的 Crypter/EVP 对象,因为加密的 IV、Key 和算法都是固定的,理论上只要一个就行了,所以说这部分开销是额外的。但是注意这里不能简单地只建一个 symm::Crypter 复用,因为 EVP api 的限制,每次都要重建,所以用 openssl speed -evp 命令跑出来的也不够快。这里如果不考虑测试函数的正确性,只测 AES-GCM 加密的时间,我们可以只把 Crypter::update 放在 b.iter 的循环里,这样测出来的时间就跟 Ring 的差不多了 [2]。可以参见 https://gist.github.com/linusyang/102325bf5c03928e1ae85c51082cad63。 Ring 的测试里面用的是 aead::seal_in_place 函数 [3],实际封装的是 C 语言写的 AES-GCM 加密函数 [4],不需要新建和释放 EVP 对象,也就没有了这部分的开销。所以最后测出来 Ring 看起来跑得更快,虽然具体加密算法用的就是 OpenSSL 的代码 [5]。 如果要写一个更公平的测试,最好直接调用更底层的 OpenSSL 函数,可以用 rust-openssl 里的 openssl-sys 库封装的 FFI 来写,就可以去掉 EVP 对象这部分的开销。 [1] https://github.com/sfackler/rust-openssl/blob/c1e5a5c/openssl/src/symm.rs#L664 [2] https://gist.github.com/linusyang/102325bf5c03928e1ae85c51082cad63/revisions [3] https://github.com/briansmith/ring/blob/1caad72/src/aead/mod.rs#L200 [4] https://github.com/briansmith/ring/blob/1caad72/crypto/cipher/e_aes.c#L301 [5] https://github.com/briansmith/ring/blob/1caad72/crypto/fipsmodule/aes/asm/aesni-x86_64.pl#L566 |
36 bincat OP @linusyang 多谢回复。我们理解您希望公平地对 openssl 和 ring 的 aead 加密原语性能做对比,我们也清楚其实 ring 的加密原语和 boringssl 一样都来自 openssl。但一个加密算法毕竟是需要通过 API 去访问的,正如您所说,openssl 的加密原语没有错,是 EVP 对象的新建和析构扯了后腿,而 ring 没有这个问题所以性能更好。我们以 openssl 官方 benchmark,即 openssl speed -evp 作为基准来比较,也是想突出这一点。我们会参考您的建议,使用 openssl-sys 再做一次实验。 |