alexcrichton / alexcrichton/openssl-src-rs

Discussion: Disable Padlock engine (no-padlockeng) to avoid AES-256 hardware bug on VIA/Zhaoxin CPUs?

未关闭
#282 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Rust
星标
80
派生
131
平均合并
49 分钟
30 天内合并 PR
2

描述

Hi! I'd like to bring up a potential issue affecting VIA/Zhaoxin CPU users and discuss possible solutions. I'd really appreciate your thoughts on the best approach.

## Problem

The OpenSSL Padlock engine (`e_padlock.c`) has a known hardware-level bug on VIA and Zhaoxin CPUs that causes **AES-256 and AES-192 to produce garbage output**. Since AES-256 is ubiquitous in modern usage (TLS 1.3, SQLCipher, etc.), this effectively causes silent data corruption on these platforms for any Rust application built with `openssl-src`.

## Background

### What is Padlock?

VIA PadLock is a hardware cryptography accelerator built into VIA and Zhaoxin x86 CPUs. It provides AES acceleration via the `REP XCRYPTCBC` instruction family, detected through a VIA-private CPUID leaf (`EAX=0xC0000001`).

### The Bug

The Padlock engine registers itself for **all** AES key sizes (128/192/256 × ECB/CBC/CFB/OFB/CTR). However, the hardware can only perform key expansion for AES-128. For AES-192/256, it relies on a software key expansion + hardware execution path — which produces incorrect results on all known VIA/Zhaoxin CPUs.

The OpenSSL source itself acknowledges this in `engines/e_padlock.c`:

```c
/*
* Well, the above applies to Stepping 8 CPUs and is listed as
* hardware errata. They most likely will fix it at some point and
* then a check for stepping would be due here.
*/
```

This comment was written years ago. The hardware bug has never been fixed.

### Upstream OpenSSL Issues (still open)

- [openssl/openssl#20073](https://github.com/openssl/openssl/issues/20073) — AES-256/192 garbage output with Padlock on VIA Eden (2023, open)
- [openssl/openssl#24879](https://github.com/openssl/openssl/issues/24879) — AES-256 doesn't work for QUIC with Padlock (2024, open, labeled "help wanted")
- [openEuler gnutls#I61EQI](https://gitee.com/src-openeuler/gnutls/issues/I61EQI) — Same Zhaoxin CPU (KX-U6780A), HTTPS decryption failure

GnuTLS has already addressed this in [commit 2c5ca0a](https://github.com/gnutls/gnutls/commit/2c5ca0a8c771ed952c432dd5ba271719896d0d54) by overriding Padlock AES with AES-NI on Zhaoxin CPUs.

## Real-World Impact

In modern usage, AES-256 is practically unavoidable:

| Scenario | Algorithm | Affected? |
|----------|-----------|-----------|
| TLS 1.3 | AES-256-GCM (2 of 3 suites) | ✅ |
| SQLCipher 4.x | AES-256-CBC (hardcoded) | ✅ |
| SSH (OpenSSH) | Prefers `aes256-gcm` | ✅ |
| HTTPS servers | Typically AES-256-GCM | ✅ |

We hit this in production: SQLCipher databases were corrupted with "file is not a database" errors on Zhaoxin KX-U6780A + Kylin Linux V10 machines. Adding `no-padlockeng` to the Configure arguments completely resolved the issue.

## Why `no-padlockeng` appears safe

The Padlock engine only activates when both conditions are met:
1. **Compile-time**: x86/x86_64 target (`PADLOCK_ASM`)
2. **Runtime**: CPUID detects VIA/Zhaoxin vendor string

So disabling it should have **zero impact** on Intel, AMD, and ARM platforms. The only trade-off is losing Padlock AES-128 hardware acceleration on VIA/Zhaoxin CPUs — but these CPUs also support AES-NI as a fallback.

## Possible Approaches

I can think of a few options, but I'm not sure which one fits best with the project's philosophy. **I'd love to hear your opinion:**

### Option A: Unconditionally disable (simplest)

```rust
configure
// ...existing args...
.arg("no-padlockeng");
```

**Pros**: 1-line change, protects all users by default, zero impact on non-VIA platforms.
**Cons**: Removes Padlock AES-128 acceleration for the rare case where someone specifically needs it on a VIA CPU.

### Option B: Add a Cargo feature (opt-in)

```toml
# Cargo.toml
[features]
no-padlockeng = []
```

```rust
if cfg!(feature = "no-padlockeng") {
configure.arg("no-padlockeng");
}
```

**Pros**: Non-breaking, gives users explicit control.
**Cons**: Users on affected platforms need to know about this feature flag; the bug is silent (data corruption, not a crash), so most won't discover it until damage is done.

### Option C: Do nothing here, wait for upstream OpenSSL fix

**Pros**: No changes needed.
**Cons**: OpenSSL issues #20073 and #24879 have been open for 1-3 years with no fix in sight. Users continue to hit silent corruption.

---

Personally, I lean toward **Option A** because the Padlock engine provides negligible benefit in practice (AES-NI is available as fallback on the same CPUs) while creating a real risk of silent data corruption. But I completely understand if you prefer a more conservative approach like Option B.

What do you think? Happy to submit a PR for whichever approach you prefer. Thanks for your time!
````

贡献指南

这个仓库没有索引到贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。