Skip to content

Commit

Permalink
feat(packet): expose v2 parsed fields in the SymmetricallyEncrypted s…
Browse files Browse the repository at this point in the history
…truct (#183)

The SymmetricallyEncrypted (SEIPD) packet type did not expose the parsed fields
for SEIPDv2. Thus, it prevents external users of the packet parser to inspect parsed values.
This commit addressed this issue by making them public.
  • Loading branch information
lubux authored Aug 28, 2023
1 parent 5aa5874 commit 3c4c8a2
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 33 deletions.
8 changes: 4 additions & 4 deletions openpgp/packet/symmetrically_encrypted.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ type SymmetricallyEncrypted struct {
prefix []byte

// Specific to version 2
cipher CipherFunction
mode AEADMode
chunkSizeByte byte
salt [aeadSaltSize]byte
Cipher CipherFunction
Mode AEADMode
ChunkSizeByte byte
Salt [aeadSaltSize]byte
}

const (
Expand Down
35 changes: 18 additions & 17 deletions openpgp/packet/symmetrically_encrypted_aead.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ package packet
import (
"crypto/cipher"
"crypto/sha256"
"io"

"github.com/ProtonMail/go-crypto/openpgp/errors"
"golang.org/x/crypto/hkdf"
"io"
)

// parseAead parses a V2 SEIPD packet (AEAD) as specified in
Expand All @@ -21,26 +22,26 @@ func (se *SymmetricallyEncrypted) parseAead(r io.Reader) error {
}

// Cipher
se.cipher = CipherFunction(headerData[0])
se.Cipher = CipherFunction(headerData[0])
// cipherFunc must have block size 16 to use AEAD
if se.cipher.blockSize() != 16 {
return errors.UnsupportedError("invalid aead cipher: " + string(se.cipher))
if se.Cipher.blockSize() != 16 {
return errors.UnsupportedError("invalid aead cipher: " + string(se.Cipher))
}

// Mode
se.mode = AEADMode(headerData[1])
if se.mode.TagLength() == 0 {
return errors.UnsupportedError("unknown aead mode: " + string(se.mode))
se.Mode = AEADMode(headerData[1])
if se.Mode.TagLength() == 0 {
return errors.UnsupportedError("unknown aead mode: " + string(se.Mode))
}

// Chunk size
se.chunkSizeByte = headerData[2]
if se.chunkSizeByte > 16 {
return errors.UnsupportedError("invalid aead chunk size byte: " + string(se.chunkSizeByte))
se.ChunkSizeByte = headerData[2]
if se.ChunkSizeByte > 16 {
return errors.UnsupportedError("invalid aead chunk size byte: " + string(se.ChunkSizeByte))
}

// Salt
if n, err := io.ReadFull(r, se.salt[:]); n < aeadSaltSize {
if n, err := io.ReadFull(r, se.Salt[:]); n < aeadSaltSize {
return errors.StructuralError("could not read aead salt: " + err.Error())
}

Expand All @@ -52,19 +53,19 @@ func (se *SymmetricallyEncrypted) associatedData() []byte {
return []byte{
0xD2,
symmetricallyEncryptedVersionAead,
byte(se.cipher),
byte(se.mode),
se.chunkSizeByte,
byte(se.Cipher),
byte(se.Mode),
se.ChunkSizeByte,
}
}

// decryptAead decrypts a V2 SEIPD packet (AEAD) as specified in
// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
func (se *SymmetricallyEncrypted) decryptAead(inputKey []byte) (io.ReadCloser, error) {
aead, nonce := getSymmetricallyEncryptedAeadInstance(se.cipher, se.mode, inputKey, se.salt[:], se.associatedData())
aead, nonce := getSymmetricallyEncryptedAeadInstance(se.Cipher, se.Mode, inputKey, se.Salt[:], se.associatedData())

// Carry the first tagLen bytes
tagLen := se.mode.TagLength()
tagLen := se.Mode.TagLength()
peekedBytes := make([]byte, tagLen)
n, err := io.ReadFull(se.Contents, peekedBytes)
if n < tagLen || (err != nil && err != io.EOF) {
Expand All @@ -74,7 +75,7 @@ func (se *SymmetricallyEncrypted) decryptAead(inputKey []byte) (io.ReadCloser, e
return &aeadDecrypter{
aeadCrypter: aeadCrypter{
aead: aead,
chunkSize: decodeAEADChunkSize(se.chunkSizeByte),
chunkSize: decodeAEADChunkSize(se.ChunkSizeByte),
initialNonce: nonce,
associatedData: se.associatedData(),
chunkIndex: make([]byte, 8),
Expand Down
24 changes: 12 additions & 12 deletions openpgp/packet/symmetrically_encrypted_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,20 +175,20 @@ func TestAeadRfcVector(t *testing.T) {
t.Errorf("found wrong version, want: %d, got: %d", symmetricallyEncryptedVersionAead, se.Version)
}

if se.cipher != CipherAES128 {
t.Errorf("found wrong cipher, want: %d, got: %d", CipherAES128, se.cipher)
if se.Cipher != CipherAES128 {
t.Errorf("found wrong cipher, want: %d, got: %d", CipherAES128, se.Cipher)
}

if se.mode != AEADModeGCM {
t.Errorf("found wrong mode, want: %d, got: %d", AEADModeGCM, se.mode)
if se.Mode != AEADModeGCM {
t.Errorf("found wrong mode, want: %d, got: %d", AEADModeGCM, se.Mode)
}

if !bytes.Equal(se.salt[:], expectedSalt) {
t.Errorf("found wrong salt, want: %x, got: %x", expectedSalt, se.salt)
if !bytes.Equal(se.Salt[:], expectedSalt) {
t.Errorf("found wrong salt, want: %x, got: %x", expectedSalt, se.Salt)
}

if se.chunkSizeByte != 0x06 {
t.Errorf("found wrong chunk size byte, want: %d, got: %d", 0x06, se.chunkSizeByte)
if se.ChunkSizeByte != 0x06 {
t.Errorf("found wrong chunk size byte, want: %d, got: %d", 0x06, se.ChunkSizeByte)
}

aeadReader, err := se.Decrypt(CipherFunction(0), key)
Expand Down Expand Up @@ -270,12 +270,12 @@ func testSerializeAead(t *testing.T, cipherSuite CipherSuite) {
t.Errorf("found wrong version, want: %d, got: %d", symmetricallyEncryptedVersionAead, se.Version)
}

if se.cipher != cipherSuite.Cipher {
t.Errorf("found wrong cipher, want: %d, got: %d", cipherSuite.Cipher, se.cipher)
if se.Cipher != cipherSuite.Cipher {
t.Errorf("found wrong cipher, want: %d, got: %d", cipherSuite.Cipher, se.Cipher)
}

if se.mode != cipherSuite.Mode {
t.Errorf("found wrong mode, want: %d, got: %d", cipherSuite.Mode, se.mode)
if se.Mode != cipherSuite.Mode {
t.Errorf("found wrong mode, want: %d, got: %d", cipherSuite.Mode, se.Mode)
}

r, err := se.Decrypt(CipherFunction(0), key)
Expand Down

0 comments on commit 3c4c8a2

Please sign in to comment.