V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bincat
V2EX  ›  程序员

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

  •  
  •   bincat · 2018-04-06 03:44:56 +08:00 · 10083 次点击
    这是一个创建于 2184 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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

    第 1 条附言  ·  2018-04-07 23:30:14 +08:00
    完整版文章,包含性能评测数据,已发布在百度安全实验室公众号和知乎,请 V2EX 各位大神移步:
    知乎: https://zhuanlan.zhihu.com/p/35371177
    公众号: https://mp.weixin.qq.com/s/_AHeStAzWx0xftYISTlk6g
    38 条回复    2018-04-08 12:20:30 +08:00
    Mitt
        1
    Mitt  
       2018-04-06 05:46:42 +08:00   ❤️ 1
    拿 Rust 保证漏洞安全,怕不是下次出现致命漏洞的是 Rust 哦
    congeec
        2
    congeec  
       2018-04-06 06:16:06 +08:00 via iPhone
    @Mitt 你见过 C++出漏洞么?
    muziki
        3
    muziki  
       2018-04-06 06:58:20 +08:00 via iPhone
    @Mitt 承包早上的笑点 2333
    Servo
        4
    Servo  
       2018-04-06 07:29:19 +08:00
    持续关注,看 README 感觉不错。
    boywhp
        5
    boywhp  
       2018-04-06 07:36:00 +08:00
    看了一下感觉挺好, 我准备实际测试一下
    boywhp
        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 要大, 是我哪里没搞对?
    bincat
        7
    bincat  
    OP
       2018-04-06 08:00:03 +08:00
    @boywhp 试下加上 -ffunction-sections -fdata-sections -Wl,--gc-sections
    boywhp
        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 可执行文件, 终于可以接受了
    metorm
        9
    metorm  
       2018-04-06 08:36:58 +08:00 via Android
    百度出品……
    omph
        10
    omph  
       2018-04-06 08:52:21 +08:00
    中国出品基础设施,可贺
    itfanr
        11
    itfanr  
       2018-04-06 08:54:12 +08:00
    @Mitt 不至于吧 rust 已经很成熟了
    boywhp
        12
    boywhp  
       2018-04-06 09:09:20 +08:00
    @metorm 百度虽然渣, 但百度里面的技术人员水平比一般公司还是要强的
    metorm
        13
    metorm  
       2018-04-06 09:20:18 +08:00 via Android
    @boywhp 就是感慨一下,没有特别的指向。不过话说回来,百度有没有技术实力去在开源软件中预留后门呢?类似随机数发生器中的逻辑漏洞一类的。
    hehe12dyo
        14
    hehe12dyo  
       2018-04-06 09:23:45 +08:00
    楼上至少有两个大黑客。
    qiumaoyuan
        15
    qiumaoyuan  
       2018-04-06 09:26:51 +08:00
    @boywhp 请问具体到谁?强在哪?
    u5f20u98de
        16
    u5f20u98de  
       2018-04-06 10:23:36 +08:00
    没有什么语言能保证不出逻辑方面的漏洞吧 :)
    u5f20u98de
        17
    u5f20u98de  
       2018-04-06 10:27:18 +08:00
    openssl 也曾经出了好几个逻辑方面的漏洞,不过影响没有当初 heartbleed 那么厉害
    exch4nge
        18
    exch4nge  
       2018-04-06 10:27:36 +08:00
    原来 LZ 就是原作者啊
    orangeade
        19
    orangeade  
       2018-04-06 10:34:46 +08:00 via Android
    厉害了,支持开源基础设施
    chanssl
        20
    chanssl  
       2018-04-06 10:40:41 +08:00
    支持
    bincat
        21
    bincat  
    OP
       2018-04-06 11:31:51 +08:00   ❤️ 4
    @u5f20u98de 我们使用 Rust 语言减少越界访问、迷途指针等内存安全问题。逻辑漏洞我们靠形式化分析解决,目前正在和一些高校和有分析能力的创业公司合作推进这个方向。
    Mitt
        22
    Mitt  
       2018-04-06 18:13:44 +08:00
    @congeec 离底层越远越不可控不是吗? (逃


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

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

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

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

    加密库是个深坑,用 C 写都容易出问题,更别说其它语言了,你们还是回去写 runtime 吧。
    bincat
        34
    bincat  
    OP
       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
        35
    linusyang  
       2018-04-08 06:24:50 +08:00   ❤️ 3
    @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
        36
    bincat  
    OP
       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
        37
    linusyang  
       2018-04-08 12:14:18 +08:00 via Android   ❤️ 1
    @bincat evp 是要调用的没错啊,问题是你测就要测对等的啊。一个不包含 init 和 free,一个有,不就不对等了嘛。而且所谓 api 原语,ring 里面的 seal 函数不写了么,对应的 api 应该是这个,C analog: `EVP_AEAD_CTX_seal`,这个是没有包含 init 和 free context 的。
    linusyang
        38
    linusyang  
       2018-04-08 12:20:30 +08:00 via Android
    @bincat 我只是觉得你们用这个简单测试就说 ring 比 openssl 还快,听起来有点想搞大新闻的感觉,有点误导成分,因为测得就不是一个东西。直觉上想想也不对劲,底层代码都是一样的,怎么会快这么多呢…
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2767 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 12:28 · PVG 20:28 · LAX 05:28 · JFK 08:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.