From a73c88817ce2dc05d4eefc2a8f31b89504523a9a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 3 Sep 2025 16:11:25 +0200 Subject: gpg: Make OCB mode compliant in de-vs mode. * common/compliance.c (gnupg_cipher_is_compliant): Support OCB for gpg. (gnupg_cipher_is_allowed): Ditto. * g10/mainproc.c (proc_encrypted): Determine cipher mode and pass it for the is_compliant test. -- This patch also switches from just assuming CFB mode to passing the correct mode to gnupg_cipher_is_compliant. Except for the legacy EAX mode we only have these two modes and thus it does not really matter. But correcting this is more future proof. This was found while fixing GnuPG-bug-id: 7804 --- common/compliance.c | 9 ++++++--- g10/mainproc.c | 18 ++++++++++++++++-- g10/packet.h | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/common/compliance.c b/common/compliance.c index db17e4aba..110c3ffe4 100644 --- a/common/compliance.c +++ b/common/compliance.c @@ -486,7 +486,8 @@ gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance, switch (module) { case GNUPG_MODULE_NAME_GPG: - return mode == GCRY_CIPHER_MODE_CFB; + return (mode == GCRY_CIPHER_MODE_CFB + || mode == GCRY_CIPHER_MODE_OCB); case GNUPG_MODULE_NAME_GPGSM: return mode == GCRY_CIPHER_MODE_CBC; } @@ -530,7 +531,8 @@ gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer, { case GNUPG_MODULE_NAME_GPG: return (mode == GCRY_CIPHER_MODE_NONE - || mode == GCRY_CIPHER_MODE_CFB); + || mode == GCRY_CIPHER_MODE_CFB + || mode == GCRY_CIPHER_MODE_OCB); case GNUPG_MODULE_NAME_GPGSM: return (mode == GCRY_CIPHER_MODE_NONE || mode == GCRY_CIPHER_MODE_CBC @@ -547,7 +549,8 @@ gnupg_cipher_is_allowed (enum gnupg_compliance_mode compliance, int producer, case CIPHER_ALGO_TWOFISH: return (module == GNUPG_MODULE_NAME_GPG && (mode == GCRY_CIPHER_MODE_NONE - || mode == GCRY_CIPHER_MODE_CFB) + || mode == GCRY_CIPHER_MODE_CFB + || mode == GCRY_CIPHER_MODE_OCB) && ! producer); default: return 0; diff --git a/g10/mainproc.c b/g10/mainproc.c index 5a7961099..fe4242c07 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -579,6 +579,8 @@ proc_encrypted (CTX c, PACKET *pkt) int result = 0; int early_plaintext = literals_seen; unsigned int compliance_de_vs = 0; + enum gcry_cipher_modes ciphermode; + int unknown_ciphermode; if (pkt) { @@ -742,14 +744,26 @@ proc_encrypted (CTX c, PACKET *pkt) result = gpg_error (GPG_ERR_NO_SECKEY); } + /* We need to know the ciphermode for gnupg_cipher_is_compliant. */ + unknown_ciphermode = 0; + if (pkt->pkt.encrypted->aead_algo) + { + unsigned int dummy; + if (openpgp_aead_algo_info (pkt->pkt.encrypted->aead_algo, + &ciphermode, &dummy)) + unknown_ciphermode = 1; /* error -> unknown mode */ + } + else + ciphermode = GCRY_CIPHER_MODE_CFB; + /* Compute compliance with CO_DE_VS. */ if (!result && (is_status_enabled () || opt.flags.require_compliance) /* Overriding session key voids compliance. */ && !opt.override_session_key /* Check symmetric cipher. */ && gnupg_gcrypt_is_compliant (CO_DE_VS) - && gnupg_cipher_is_compliant (CO_DE_VS, c->dek->algo, - GCRY_CIPHER_MODE_CFB)) + && !unknown_ciphermode + && gnupg_cipher_is_compliant (CO_DE_VS, c->dek->algo, ciphermode)) { struct pubkey_enc_list *i; struct symlist_item *si; diff --git a/g10/packet.h b/g10/packet.h index 8162ad802..6b1be6fc8 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -608,7 +608,7 @@ struct packet_struct { PKT_comment *comment; /* PKT_COMMENT */ PKT_user_id *user_id; /* PKT_USER_ID */ PKT_compressed *compressed; /* PKT_COMPRESSED */ - PKT_encrypted *encrypted; /* PKT_ENCRYPTED[_MDC] */ + PKT_encrypted *encrypted; /* PKT_ENCRYPTED[_MDC|_AEAD] */ PKT_mdc *mdc; /* PKT_MDC */ PKT_plaintext *plaintext; /* PKT_PLAINTEXT */ PKT_gpg_control *gpg_control; /* PKT_GPG_CONTROL */ -- cgit v1.2.3