Skip to content

rsa: verify PUBKEY_ENC_UNKNOWN via the raw compare path (fixes gpg/apt RSA verify)#29

Open
MarkAtwood wants to merge 1 commit into
wolfSSL:libgcrypt-1.11.0-wolfCrypt-fips-readyfrom
MarkAtwood:fix/rsa-verify-unknown-encoding
Open

rsa: verify PUBKEY_ENC_UNKNOWN via the raw compare path (fixes gpg/apt RSA verify)#29
MarkAtwood wants to merge 1 commit into
wolfSSL:libgcrypt-1.11.0-wolfCrypt-fips-readyfrom
MarkAtwood:fix/rsa-verify-unknown-encoding

Conversation

@MarkAtwood

Copy link
Copy Markdown

Fixes #28.

wc_rsa_verify() rejected every RSA signature whose libgcrypt encoding context
is PUBKEY_ENC_UNKNOWN, because the switch (ctx.encoding) only handled the
named encodings (PSS / PKCS1 / PKCS1_RAW / RAW / OAEP) and routed everything else
to default: rc = GPG_ERR_BAD_SIGNATURE.

GnuPG's OpenPGP RSA verification supplies the full pre-encoded PKCS#1 v1.5
message and leaves ctx.encoding == PUBKEY_ENC_UNKNOWN, so all GnuPG/apt RSA
signature verification failed (keys "Unusable", "1 bad signature"). Stock
libgcrypt performs the raw mpi_cmp(result, data) for all non-PSS encodings;
this PR routes PUBKEY_ENC_UNKNOWN into the same wc_RsaDirect + mpi_cmp
group.

Test

export GNUPGHOME=$(mktemp -d)
gpg --batch --pinentry-mode=loopback --passphrase "" \
    --quick-generate-key "test@example.com" rsa2048 sign 0
gpg --check-sigs
# before: "gpg: 1 bad signature"
# after:  clean

Notes

  • The crypto itself is correct: an OpenSSL-produced PKCS#1 v1.5 RSA-SHA256
    signature verifies through native wolfCrypt with the key loaded via
    wc_RsaPublicKeyDecodeRaw + wc_RsaDirect(RSA_PUBLIC_DECRYPT) (recovered EM is
    byte-for-byte correct). Only the shim's encoding dispatch was wrong.
  • A more defensive alternative is to make the default: case perform the raw
    compare (matching stock libgcrypt) instead of adding an explicit case — happy
    to switch to that form if preferred.

GnuPG's OpenPGP RSA signature verification supplies the full pre-encoded
PKCS#1 v1.5 message and leaves ctx.encoding == PUBKEY_ENC_UNKNOWN.
wc_rsa_verify()'s switch only handled the named encodings and routed
UNKNOWN to default -> GPG_ERR_BAD_SIGNATURE, so every GnuPG/apt RSA
signature verification failed (keys reported "Unusable", "1 bad
signature"). Stock libgcrypt performs the raw mpi_cmp for all non-PSS
encodings; route UNKNOWN into the existing wc_RsaDirect + mpi_cmp path.

Verified: gpg --check-sigs goes from "1 bad signature" to clean.

Fixes wolfSSL#28
Copilot AI review requested due to automatic review settings July 2, 2026 22:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes RSA signature verification failures in the wolfCrypt-backed wc_rsa_verify() path when the libgcrypt encoding context is PUBKEY_ENC_UNKNOWN, which is commonly encountered during GnuPG OpenPGP RSA verification (and thus impacts apt signature verification via gpg/libgcrypt).

Changes:

  • Route PUBKEY_ENC_UNKNOWN through the same “raw public operation + mpi_cmp” verification path used for other non-PSS encodings, instead of treating it as a bad signature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants