G'day all,
I'm working through the creation of a cross-platform decryption implementation for CryptoKit's HPKE and wish to use the Sender & Recipient type.
I have been able to engineer the derived key, but the missing link is the nonce that is created and utilised by HPKE.Sender.seal(). I understand that I could create the key exchange and sealed box by myself and set my own random nonce, but I want to be able to utilise the HPKE.Sender.seal() functions to assist with this as well as create ciphertext data externally that can be opened with HPKE.Recipient.open().
By looking at Apple's open-source code available here, I can see that it seems to be exporting a key based on a "base_nonce" label on the context, which I think is what HPKE.Sender's exportSecret(context:outputByteCount:) can achieve.
However using senders exportSecret(context:outputByteCount:) in the following way:
let noncedata = try hpkeSender.exportSecret(context: Data("base_nonce".utf8), outputByteCount: 12)
even just for one message (so the sequence number would be 0 and thus this data block unchanged), the AES-GCM implementation still returns a "cipher: message authentication failed" error. This is specifically in Go, but can be replicated in Python easily. I'm confident that the derived key is correct and is being fed to AES-GCM with the ciphertext correctly, and it's just the nonce generation that is not understood.