alexcrichton / alexcrichton/openssl-src-rs

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

Aberta
#282 1 comentário 0 reações 0 responsáveis Ver no GitHub
Linguagem predominante
Rust
Estrelas
80
Forks
131
Merge médio
49min
PRs com merge (30d)
2

Descrição

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!
````

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.