MesaLink 开源: OpenSSL 的接班人,"心脏"不再"出血"

2018-04-06 03:44:56 +08:00
 bincat

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 语言分榜排行第一。

项目主页: https://github.com/mesalock-linux/mesalink

10152 次点击
所在节点    程序员
38 条回复
bincat
2018-04-06 11:31:51 +08:00
@u5f20u98de 我们使用 Rust 语言减少越界访问、迷途指针等内存安全问题。逻辑漏洞我们靠形式化分析解决,目前正在和一些高校和有分析能力的创业公司合作推进这个方向。
Mitt
2018-04-06 18:13:44 +08:00
@congeec 离底层越远越不可控不是吗? (逃


@muziki 笑完就过了
Showfom
2018-04-06 19:05:57 +08:00
@metorm 有这能力还敢开源出来么 不怕被大神发现然后丢了母公司的脸么
secondwtq
2018-04-06 20:05:39 +08:00
Rasphino
2018-04-06 20:35:32 +08:00
@Mitt rust 这么糟糕的吗?求解释
msg7086
2018-04-06 22:36:20 +08:00
连 CPU 都能出致命漏洞,某个语言或者运行时出漏洞很奇怪吗?
Kilerd
2018-04-06 23:39:46 +08:00
基础化设施,支持一波。
Rust 写的,支持一波。
waruqi
2018-04-07 00:04:42 +08:00
看着像基于 rustsl 做的 openssl 接口 wrap ?
abscon
2018-04-07 09:19:37 +08:00
@congeec 让程序员生涯苦短的 Python 倒的确爆出过漏洞……
congeec
2018-04-07 13:28:33 +08:00
@abscon 语言可以规范和实现分开来做。比如 C 艹一套标准有多种编译器+标准库的实现。标准库的代码瑕疵可能导致安全漏洞,但是语言规范设计漏洞导致不得 bug 我还没听说过。

Python 么,大家都默认指 CPython。你说 python 爆漏洞,应该指后者吧。

rust 跟 C 艹类似,可以 bare metal, 也可以用标准库。

我觉得一楼指的是语言设计方面的缺陷导致安全隐患。所以问了下
gnaggnoyil
2018-04-07 14:27:02 +08:00
@congeec C++语言规范经常有因为考虑不周到而导致的漏洞.CWG 和 LWG 的 issue 里一抓一大把.但是 C++语言规范的漏洞顶多是导致各个实现的行为不一致,和所谓安全性漏洞几乎没有关系.OpenSSL 相当多的漏洞主要原因就是 C 的限制导致的代码质量不行,所以我还是很看好用 Rust 重写的 SSL 实现的
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
zhicheng
2018-04-07 16:02:08 +08:00
原 po 就是觉得用 C 容易出问题,所以用 rust。那别人评论质疑一下 rust 可能出问题又被粉丝喷,rust 粉丝你们棒棒的。

加密库是个深坑,用 C 写都容易出问题,更别说其它语言了,你们还是回去写 runtime 吧。
bincat
2018-04-07 23:26:22 +08:00
@linusyang 使用 ring 来自 BoringSSL 的加密算法原语的原因我们和 ring 的作者 Brian Smith 讨论过,主要的理由是 BoringSSL 的原语的正确性和性能更有保证,尤其是 constant time crypto。性能上其实不差,可以参考完整版的文章 https://zhuanlan.zhihu.com/p/35371177https://gist.github.com/kevinis/ca7fa432af076a5f3330c7e39daf27fc
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
bincat
2018-04-08 11:43:17 +08:00
@linusyang 多谢回复。我们理解您希望公平地对 openssl 和 ring 的 aead 加密原语性能做对比,我们也清楚其实 ring 的加密原语和 boringssl 一样都来自 openssl。但一个加密算法毕竟是需要通过 API 去访问的,正如您所说,openssl 的加密原语没有错,是 EVP 对象的新建和析构扯了后腿,而 ring 没有这个问题所以性能更好。我们以 openssl 官方 benchmark,即 openssl speed -evp 作为基准来比较,也是想突出这一点。我们会参考您的建议,使用 openssl-sys 再做一次实验。
linusyang
2018-04-08 12:14:18 +08:00
@bincat evp 是要调用的没错啊,问题是你测就要测对等的啊。一个不包含 init 和 free,一个有,不就不对等了嘛。而且所谓 api 原语,ring 里面的 seal 函数不写了么,对应的 api 应该是这个,C analog: `EVP_AEAD_CTX_seal`,这个是没有包含 init 和 free context 的。
linusyang
2018-04-08 12:20:30 +08:00
@bincat 我只是觉得你们用这个简单测试就说 ring 比 openssl 还快,听起来有点想搞大新闻的感觉,有点误导成分,因为测得就不是一个东西。直觉上想想也不对劲,底层代码都是一样的,怎么会快这么多呢…

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/444585

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX