From b28dba44b7b8529987c2b1819da2472d3c92a8ad Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Tue, 3 Dec 2024 13:58:05 +0100 Subject: [PATCH 1/2] Fix symmetric v6 message encryption Commits 7d95b08316f0edf5773b0ea062694ed4b0e2b6ef and ea316319d029e9e1215c44e980509b3bf898cf05 introduced an error where the plain session key was passed in the wrong format causing the session-key wrapper to fail due to an invalid block size. --- .../bouncycastle/openpgp/PGPEncryptedDataGenerator.java | 7 +++++-- .../openpgp/operator/PBEKeyEncryptionMethodGenerator.java | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java index 8bf0ca6d7e..c849ebf5bf 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java @@ -224,10 +224,13 @@ private OutputStream open( boolean directS2K = !forceSessionKey && methods.size() == 1 && methods.get(0) instanceof PBEKeyEncryptionMethodGenerator; // not public key + boolean isV5StyleAEAD = dataEncryptorBuilder.isV5StyleAEAD(); //v5 - if (dataEncryptorBuilder.getAeadAlgorithm() != -1 && !isV5StyleAEAD) + boolean isSeipdV2 = dataEncryptorBuilder.getAeadAlgorithm() != -1 && !isV5StyleAEAD; + if (isSeipdV2) { sessionKey = PGPUtil.makeRandomKey(defAlgorithm, rand); + sessionInfo = createSessionInfo(defAlgorithm, sessionKey); // In OpenPGP v6, we need an additional step to derive a message key and IV from the session info. // Since we cannot inject the IV into the data encryptor, we append it to the message key. byte[] info = SymmetricEncIntegrityPacket.createAAData( @@ -271,7 +274,7 @@ else if (directS2K) { //https://www.rfc-editor.org/rfc/rfc9580.html#section-3.7.2.1 Table 2 //AEAD(HKDF(S2K(passphrase), info), secrets, packetprefix) - writeOpenPGPv6ESKPacket(method, aeadDataEncryptor.getAEADAlgorithm(), sessionKey); + writeOpenPGPv6ESKPacket(method, aeadDataEncryptor.getAEADAlgorithm(), sessionInfo); } } // OpenPGP v4 diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java index 9a8125bb37..3c4c6f1ce7 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java @@ -201,7 +201,7 @@ private ContainedPacket generateV5ESK(int kekAlgorithm, int aeadAlgorithm, byte[ return SymmetricKeyEncSessionPacket.createV5Packet(kekAlgorithm, aeadAlgorithm, iv, s2k, esk, tag); } - private ContainedPacket generateV6ESK(int kekAlgorithm, int aeadAlgorithm, byte[] sessionKey) + private ContainedPacket generateV6ESK(int kekAlgorithm, int aeadAlgorithm, byte[] sessionInfo) throws PGPException { byte[] ikm = getKey(kekAlgorithm); @@ -217,6 +217,7 @@ private ContainedPacket generateV6ESK(int kekAlgorithm, int aeadAlgorithm, byte[ random.nextBytes(iv); int tagLen = AEADUtils.getAuthTagLength(aeadAlgorithm); + byte[] sessionKey = getSessionKey(sessionInfo); byte[] eskAndTag = getEskAndTag(kekAlgorithm, aeadAlgorithm, sessionKey, kek, iv, info); byte[] esk = Arrays.copyOfRange(eskAndTag, 0, eskAndTag.length - tagLen); byte[] tag = Arrays.copyOfRange(eskAndTag, esk.length, eskAndTag.length); From a78f34421dd7fad67a5a497e8bcf7e4d54bf998d Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Tue, 3 Dec 2024 17:33:40 +0100 Subject: [PATCH 2/2] Do not emit v5 SKESKs if no AEAD is configured --- .../org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java index c849ebf5bf..c503e01400 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPEncryptedDataGenerator.java @@ -225,9 +225,9 @@ private OutputStream open( boolean directS2K = !forceSessionKey && methods.size() == 1 && methods.get(0) instanceof PBEKeyEncryptionMethodGenerator; // not public key - boolean isV5StyleAEAD = dataEncryptorBuilder.isV5StyleAEAD(); //v5 - boolean isSeipdV2 = dataEncryptorBuilder.getAeadAlgorithm() != -1 && !isV5StyleAEAD; - if (isSeipdV2) + boolean isAEAD = dataEncryptorBuilder.getAeadAlgorithm() != -1; + boolean isV5StyleAEAD = isAEAD && dataEncryptorBuilder.isV5StyleAEAD(); //v5 + if (isAEAD && !isV5StyleAEAD) // v6 { sessionKey = PGPUtil.makeRandomKey(defAlgorithm, rand); sessionInfo = createSessionInfo(defAlgorithm, sessionKey);