Add a New Comment (Rich Markup)
( Jump to the original submission )
The workaround makes dkg-sop emit AEAD messages with OCB again, and I can confirm that indeed the MDC packet is gone.
I have applied a quick workaround. OCB should work now ...
Very strange. It seems that LibTMCG is called with cipher mode 14 (indicates EAX), however, OCB is stated as preferred AEAD algorithm in a signature subpacket of the public key. It looks like dkg-sop was built with GCRYPT_VERSION_NUMBER >= 0x010900, which selects EAX as default AEAD algorithm. That means I have to write the code for AEAD algorithm selection. This was not done yet due to missing tests with libgcrypt 1.9.x
Script started on 2022-02-14 23:44:30+01:00 [TERM="xterm" TTY="/dev/pts/5" COLUMNS="314" LINES="110"] +zsh:1> sq packet dump bob-ocb.pgp Public-Key Packet, new CTB, 397 bytes Version: 4 Creation time: 2019-10-15 10:18:26 UTC Pk algo: RSA (Encrypt or Sign) Pk size: 3072 bits Fingerprint: D1A66E1A23B182C9980F788CFBFCC82A015E7330 KeyID: FBFCC82A015E7330 User ID Packet, new CTB, 33 bytes Value: Bob Babbage <bob@openpgp.example> Signature Packet, new CTB, 534 bytes Version: 4 Type: PositiveCertification Pk algo: RSA (Encrypt or Sign) Hash algo: SHA512 Hashed area: Signature creation time: 2022-02-14 13:51:15 UTC (critical) Symmetric algo preferences: AES256 Issuer: FBFCC82A015E7330 Notation: salt@notations.sequoia-pgp.org 00000000 a8 2d e4 3b 11 6d ed 35 de 6b 6f 4e a7 e1 64 94 00000010 0d eb 39 50 95 af f0 1a da ca 80 ad 28 1a 14 3d Hash preferences: SHA512, SHA384, SHA256, SHA224, SHA1 Compression preferences: Zlib, BZip2, Zip Keyserver preferences: no modify Key flags: CS Features: MDC, AEAD Issuer Fingerprint: D1A66E1A23B182C9980F788CFBFCC82A015E7330 AEAD preferences: OCB Digest prefix: E02E Level: 0 (signature over data) Signature Packet, new CTB, 462 bytes Version: 4 Type: PositiveCertification Pk algo: RSA (Encrypt or Sign) Hash algo: SHA512 Hashed area: Key flags: CS Symmetric algo preferences: AES256, AES192, AES128, TripleDES Hash preferences: SHA512, SHA384, SHA256, SHA224, SHA1 Compression preferences: Zlib, BZip2, Zip Features: MDC Keyserver preferences: no modify Issuer Fingerprint: D1A66E1A23B182C9980F788CFBFCC82A015E7330 Signature creation time: 2019-10-15 10:27:06 UTC Unhashed area: Issuer: FBFCC82A015E7330 Digest prefix: 6F6C Level: 0 (signature over data) Public-Subkey Packet, new CTB, 397 bytes Version: 4 Creation time: 2019-10-15 10:18:26 UTC Pk algo: RSA (Encrypt or Sign) Pk size: 3072 bits Fingerprint: 1DDCE15F09217CEE2F3B37607C2FAA4DF93C37B2 KeyID: 7C2FAA4DF93C37B2 Signature Packet, new CTB, 438 bytes Version: 4 Type: SubkeyBinding Pk algo: RSA (Encrypt or Sign) Hash algo: SHA512 Hashed area: Issuer Fingerprint: D1A66E1A23B182C9980F788CFBFCC82A015E7330 Signature creation time: 2019-10-15 10:18:26 UTC Key flags: EtEr Unhashed area: Issuer: FBFCC82A015E7330 Digest prefix: E9FF Level: 0 (signature over data) +zsh:1> /home/teythoon/repos/pep/pgpzoo/bin/dkg-sop -V -V -V encrypt bob-ocb.pgp +zsh:1> sq packet dump INFO: using LibTMCG version 1.4.0 INFO: SymmetricEncryptAEAD called with skalgo = 9 cipher mode = 14 INFO: SymmetricEncryptAEAD |in| = 36 and |ad| = 13 INFO: SymmetricEncryptAEAD nonce = fa 29 c3 24 1f 75 aa a9 a af 0 c0 24 c6 86 cb INFO: SymmetricEncryptAEAD chunkdim = 65536 and chunks = 0 INFO: SymmetricEncryptAEAD ad = d4 1 9 1 a 0 0 0 0 0 0 0 0 INFO: SymmetricEncryptAEAD on final chunk #0 with nbytes = 0 INFO: SymmetricEncryptAEAD len = 36 INFO: SymmetricEncryptAEAD in = cb c 62 0 62 a db 4e 68 65 6c 6c 6f a d3 14 4e f6 a0 5f a3 6d bc 6b 37 8b 86 dc a5 74 dc 61 9c b2 48 5 INFO: SymmetricEncryptAEAD out = 9f 15 9c 6d 6d b7 55 ec 6a d1 c1 dd e7 ae 5 a6 d7 d4 20 ce bf c9 d8 f5 2 17 9b 31 57 fd fa cf 64 4f 15 a8 INFO: SymmetricEncryptAEAD tag = a9 a 1c 86 63 e 6c 2f cc e1 eb f1 7b 3f 8d 9b INFO: SymmetricEncryptAEAD totalbytes = 36 INFO: SymmetricEncryptAEAD final tag = fd ce f6 5b cc d6 cf 5a 3 e 3 80 a3 4e df e0 INFO: PacketDecode() = 6 version = 4 INFO: key ID of primary key: fb fc c8 2a 1 5e 73 30 INFO: PacketDecode() = 13 version = 0 INFO: signature subpacket type = 2 found INFO: signature subpacket type = 11 found INFO: signature subpacket type = 16 found INFO: signature subpacket type = 20 found INFO: notation data found INFO: signature subpacket type = 21 found INFO: signature subpacket type = 22 found INFO: signature subpacket type = 23 found INFO: signature subpacket type = 27 found INFO: signature subpacket type = 30 found INFO: signature subpacket type = 33 found INFO: signature subpacket type = 34 found INFO: PacketDecode() = 2 version = 4 INFO: embeddedsigs.size() = 0 INFO: recipientfprs.size() = 0 INFO: attestedcerts.size() = 0 INFO: mdbits = 3067 INFO: signature subpacket type = 27 found INFO: signature subpacket type = 11 found INFO: signature subpacket type = 21 found INFO: signature subpacket type = 22 found INFO: signature subpacket type = 30 found INFO: signature subpacket type = 23 found INFO: signature subpacket type = 33 found INFO: signature subpacket type = 2 found INFO: signature subpacket type = 16 found INFO: PacketDecode() = 2 version = 4 INFO: embeddedsigs.size() = 0 INFO: recipientfprs.size() = 0 INFO: attestedcerts.size() = 0 INFO: mdbits = 3071 INFO: PacketDecode() = 14 version = 4 INFO: key ID of subkey: 7c 2f aa 4d f9 3c 37 b2 INFO: signature subpacket type = 33 found INFO: signature subpacket type = 2 found INFO: signature subpacket type = 27 found INFO: signature subpacket type = 16 found INFO: PacketDecode() = 2 version = 4 INFO: embeddedsigs.size() = 0 INFO: recipientfprs.size() = 0 INFO: attestedcerts.size() = 0 INFO: mdbits = 3071 INFO: key ID of primary key: fb fc c8 2a 1 5e 73 30 INFO: fingerprint of primary key: d1 a6 6e 1a 23 b1 82 c9 98 f 78 8c fb fc c8 2a 1 5e 73 30 INFO: number of selfsigs = 0 INFO: number of keyrevsigs = 0 INFO: number of certrevsigs = 0 INFO: number of userids = 1 INFO: number of userattributes = 0 INFO: number of subkeys = 1 INFO: number of revkeys = 0 INFO: userid = "Bob Babbage <bob@openpgp.example>" INFO: number of selfsigs = 2 INFO: number of revsigs = 0 INFO: number of certsigs = 0 INFO: number of attestsigs = 0 INFO: sig type = 0x13 pkalgo = 1 hashalgo = 10 revocable = true exportable = true version = 4 creationtime = 1571135226 expirationtime = 0 keyexpirationtime = 0 revcode = 0 packet.size() = 465 hspd.size() = 56 issuer = fb fc c8 2a 1 5e 73 30 issuerfpr = d1 a6 6e 1a 23 b1 82 c9 98 f 78 8c fb fc c8 2a 1 5e 73 30 keyflags = 3 revkeys.size() = 0 embeddedsigs.size() = 0 recipientfprs.size() = 0 attestedcerts.size() = 0 left = 6f 6c INFO: left = 6f 6c INFO: hash = 6f 6c b1 e9 e0 d0 73 5a f3 8c 78 46 1e c7 7f f ea b7 1c 5c 79 5e 14 ec 62 18 91 e4 44 31 1 32 f0 29 a0 8d 32 48 ff e2 e4 a9 ff 84 49 3f 84 5f fe e4 be a6 5b ea 2d 9b af c e9 75 85 49 a9 46 INFO: sig type = 0x13 pkalgo = 1 hashalgo = 10 revocable = true exportable = true version = 4 creationtime = 1644846675 expirationtime = 0 keyexpirationtime = 0 revcode = 0 packet.size() = 537 hspd.size() = 138 issuer = fb fc c8 2a 1 5e 73 30 issuerfpr = d1 a6 6e 1a 23 b1 82 c9 98 f 78 8c fb fc c8 2a 1 5e 73 30 keyflags = 3 revkeys.size() = 0 embeddedsigs.size() = 0 recipientfprs.size() = 0 attestedcerts.size() = 0 left = e0 2e INFO: left = e0 2e INFO: hash = e0 2e 50 34 3b df 67 52 22 5b f4 c7 12 ef 43 30 85 d7 fd 29 fb 1 f3 42 ed 31 3b 4c 22 d7 11 d3 9f 3b 20 4b 84 93 d1 ba 9a 7a c0 e 7e 39 61 6b f2 9f 1b aa fe c2 84 dd 23 b0 a8 95 c9 34 8f c2 INFO: user ID is valid INFO: primary key update flags to 3 INFO: primary key update features to 1 INFO: primary key update psa to 9 8 7 2 INFO: primary key update pha to 10 9 8 11 2 INFO: primary key update pca to 2 3 1 INFO: primary key update flags to 3 INFO: primary key update features to 3 INFO: primary key update psa to 9 INFO: primary key update pha to 10 9 8 11 2 INFO: primary key update pca to 2 3 1 INFO: primary key update paa to 2 INFO: key flags on primary key are CS INFO: key ID of subkey: 7c 2f aa 4d f9 3c 37 b2 INFO: fingerprint of subkey: 1d dc e1 5f 9 21 7c ee 2f 3b 37 60 7c 2f aa 4d f9 3c 37 b2 INFO: number of selfsigs = 0 INFO: number of bindsigs = 1 INFO: number of pbindsigs = 0 INFO: number of keyrevsigs = 0 INFO: number of certrevsigs = 0 INFO: number of revkeys = 0 INFO: creationtime = 1571134706 INFO: expirationtime = 0 INFO: bindingtime = 0 INFO: sig type = 0x18 pkalgo = 1 hashalgo = 10 revocable = true exportable = true version = 4 creationtime = 1571134706 expirationtime = 0 keyexpirationtime = 0 revcode = 0 packet.size() = 441 hspd.size() = 32 issuer = fb fc c8 2a 1 5e 73 30 issuerfpr = d1 a6 6e 1a 23 b1 82 c9 98 f 78 8c fb fc c8 2a 1 5e 73 30 keyflags = c revkeys.size() = 0 embeddedsigs.size() = 0 recipientfprs.size() = 0 attestedcerts.size() = 0 left = e9 ff INFO: left = e9 ff INFO: hash = e9 ff d9 12 d4 da 96 a8 77 b4 ce 95 e 44 16 f0 6f e2 e f8 39 85 57 3d c7 71 97 94 e9 24 8 9f 38 aa 81 ac 86 60 d9 f2 35 1d ad f8 97 8d 3 e2 de f6 e0 1c 3d ba 35 3d 4d 96 36 a0 19 fa 8d e3 12 INFO: bindingtime = 1571134706 INFO: subkey is valid INFO: key flags on subkey are Ee INFO: RSA with |n| = 3072 bits, |e| = 17 bits INFO: RSA with |n| = 3072 bits, |e| = 17 bits WARNING: selected algorithm is none of the preferred AEAD algorithms; AEAD disabled INFO: 1 subkey(s) selected for encryption of session key Public-Key Encrypted Session Key Packet, new CTB, 396 bytes Version: 3 Recipient: 7C2FAA4DF93C37B2 Pk algo: RSA (Encrypt or Sign) Sym. Encrypted and Integrity Protected Data Packet, new CTB, 55 bytes Version: 1 No session key supplied Script done on 2022-02-14 23:44:30+01:00 [COMMAND_EXIT_CODE="0"]
This is bob's cert:
-----BEGIN PGP PUBLIC KEY BLOCK----- Comment: D1A6 6E1A 23B1 82C9 980F 788C FBFC C82A 015E 7330 Comment: Bob Babbage <bob@openpgp.example> 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 bVrj5KjhX2PVNEJd3XZRzaXZE2aAMQ== =y9r4 -----END PGP PUBLIC KEY BLOCK-----
comment #4:
> Hm, my dkg-sop no longer produces AEAD encrypted messages
Please, can you run dkg-sop with options "-V -V -V"
> I know it used to do that in the past, at least for OCB (EAX never worked for me, I guess because my gcrypt is < 1.9.
Yes, OCB should be supported by libgcrypt 1.8.x
Hm, my dkg-sop no longer produces AEAD encrypted messages:
/home/teythoon/repos/pep/pgpzoo/bin/dkg-sop encrypt bob-ocb.pgp <<< hello | sq packet dump Public-Key Encrypted Session Key Packet, new CTB, 396 bytes Version: 3 Recipient: 7C2FAA4DF93C37B2 Pk algo: RSA (Encrypt or Sign) Sym. Encrypted and Integrity Protected Data Packet, new CTB, 55 bytes Version: 1 No session key supplied
Reverting the topmost change doesn't bring that back. I don't know what else could have changed. I know it used to do that in the past, at least for OCB (EAX never worked for me, I guess because my gcrypt is < 1.9.
Yes, it is fixed, thanks!
This is a bug in dkg-sop that has been fixed with the following commit: https://git.savannah.nongnu.org/cgit/dkgpg.git/commit/?id=7e6671bc43b4222d7e40e770bb3b4f788b5e2c2c
Thanks for reporting. I will analyze this issue soon.
When I encrypt a message using AEAD with dkgpg, I still get a MDC packet:
-----BEGIN PGP MESSAGE----- wcDMA3wvqk35PDeyAQv/aQgiCXjHq7BMmC9ANNPCNa/AdcZNbTmWw7+uH5WnKakF oStGC2INJow7ZiDCpn9DOjfbZzomv5sSFJy5UkvlcpWX3TVmYfsC9gvlhcydAcmJ 8IkiqAAdD7DRJwS5O4fRcd+hJoFnMShXnOSdKve1LDE3wcEgPbB4URmgj/Vvh8mm a/jLxvDkhs3JlExc0f8e3PIsj8AhPNGIpaunhRrXuG+DzI9UJXR5OlTq+nHN2Vo5 cwnMnaka473lvsiIKv1laHqjp1EaiF1EWEGOup9q0WGor7Sw5GhDtcoc3ziDByP2 p5UT4erHdq1T9iuxoFjk62zW+3yYA0JZaNHyNtWCXeAlP4KRY2dvG1m08jinhQiK x/c7nHr8DFqOwPSPH0S51caRxuDg8muMo6hT/5Dsq4Kff1jLOuCoBemeL3djwqoE pYlCi2iXomQ+rWl7SHW4KNufaN52WcjzVR7vocN2EtUivry408If7oDy4a8vqaXd 1Boq5m3YeihQ0r+Lb4Gz1F8BCQIK2p3MBJpLflOnOZysyHcMaXwSfZ2ORfGsdvWg vSnm9dTzo9IKMkFzj4mE9qV0weJ8em46wXn5K8xcJLZw1151dJREe+qX3lthRuT/ Wn87gGzvFQq6SRek3VaSpA== =Npcn -----END PGP MESSAGE-----
This is encrypted with Bob's secret key from the shared test certificates. With a patched version of Sequoia with the message grammar checks removed, I can dump it:
% target/debug/sq decrypt --recipient-key /tmp/bob*pgp --dump </tmp/msg Public-Key Encrypted Session Key Packet, new CTB, 396 bytes Version: 3 Recipient: 7C2FAA4DF93C37B2 Pk algo: RSA (Encrypt or Sign) Encrypted and protected using AES with 256-bit key/OCB mode AEAD Encrypted Data Packet, new CTB, 95 bytes │ Version: 1 │ Symmetric algo: AES with 256-bit key │ AEAD: OCB mode │ Chunk size: 65536 │ IV: DA9DCC049A4B7E53A7399CACC8770C │ ├── Literal Data Packet, new CTB, 20 bytes │ Format: Binary data │ Timestamp: 2022-02-08 15:07:19 UTC │ └── Modification Detection Code Packet, new CTB, 20 bytes Digest: B9A88EF662B41DE3A38D21BAF858FDCDF9F14171 Computed digest: 0000000000000000000000000000000000000000 Hello World :)
(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)
Attach Files: Comment:
No files currently attached
Depends on the following items: None found
Items that depend on this one: None found
There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.
Only logged-in users can vote.
Please enter the title of George Orwell's famous dystopian book (it's a date):
Follow 6 latest changes.
Copyright © 2023 Free Software Foundation, Inc. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. The Levitating, Meditating, Flute-playing Gnu logo is a GNU GPL'ed image provided by the Nevrax Design Team. Source Code
Powered by Savane 3.11