最近碰到一个奇怪的问题. 同一个openssl库, 在不同的机器上, 一个能用AES256-SHA密钥套件握手成功, 另一个不能成功. 但是都可以用RC4-SHA握手成功. 握手停在client Finished message, server端收到该消息后, 解密都是成功的, 但是当比较MAC时, 发现不匹配. 初步分析是和平台相关的问题. 通过在openssl里加log, 刚开始定位到问题出在下面这段代码(ssl/t1_enc.c):
-
tls1_mac():
-
-
if (!send &&
-
EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
-
ssl3_cbc_record_digest_supported(mac_ctx)) {
-
/*
-
* This is a CBC-encrypted record. We must avoid leaking any
-
* timing-side channel information about how many blocks of data we
-
* are hashing because that gives an attacker a timing-oracle.
-
*/
-
/* Final param == not SSLv3 */
-
ssl3_cbc_digest_record(mac_ctx,
-
md, &md_size,
-
header, rec->input,
-
rec->length + md_size, orig_len,
-
ssl->s3->read_mac_secret,
-
ssl->s3->read_mac_secret_size, 0);
-
} else {
-
EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
-
EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
-
t = EVP_DigestSignFinal(mac_ctx, md, &md_size);
-
OPENSSL_assert(t > 0);
-
#ifdef OPENSSL_FIPS
-
if (!send && FIPS_mode())
-
tls_fips_digest_extra(ssl->enc_read_ctx,
-
mac_ctx, rec->input, rec->length, orig_len);
-
#endif
-
}
因为AES是CBC密钥而RC4是Stream的, 所以, 计算MAC时在上面代码走的是不同路径. ssl3_cbc_digest_record()是为了修复Lucky13漏洞而由Adam Lan?g?ley引入的常数时间计算MAC算法. 该算法中有很多和平台相关的操作, 至此, 一切都符合我们最初的猜测: ssl3_cbc_digest_record()对平台支持有问题.
但是, 比对2个平台上的log发现, 握手成功的平台上, 代码根本没有走计算MAC这一步, 而是直接在解密后去掉了MAC和pad.
这是2015年的时候解决的一个老bug的草稿, 当时打算写Openssl的握手阶段代码解析的, 可惜这个bug后很快离开了公司, 当时忙着入职新公司, 忘记了把这个文章写完, 现在也不记得整个bug的细节了. 发在这里当个记录吧.
阅读(2229) | 评论(0) | 转发(0) |