From f378e631472f22df653e0880e1ded251b7e856bf Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Sat, 18 Mar 2023 10:22:18 +0100 Subject: [PATCH] lib/protocol: Handle encrypted requests without encrypted hash (fixes #8277) (#8827) The layout of the request differs based on whether it comes from an untrusted device or a trusted device with encrypted enabled. Handle both. Closes #8819. --- lib/protocol/encryption.go | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/protocol/encryption.go b/lib/protocol/encryption.go index ea2a4ad01..322dfedcf 100644 --- a/lib/protocol/encryption.go +++ b/lib/protocol/encryption.go @@ -96,18 +96,26 @@ func (e encryptedModel) Request(deviceID DeviceID, folder, name string, blockNo, return nil, errors.New("short request") } - // Decrypt the block hash. + // Attempt to decrypt the block hash; it may be nil depending on what + // type of device the request comes from. Trusted devices with + // encryption enabled know the hash but don't bother to encrypt & send + // it to us. Untrusted devices have the hash from the encrypted index + // data and do send it. The model knows to only verify the hash if it + // actually gets one. + var realHash []byte fileKey := e.keyGen.FileKey(realName, folderKey) - var additional [8]byte - binary.BigEndian.PutUint64(additional[:], uint64(realOffset)) - realHash, err := decryptDeterministic(hash, fileKey, additional[:]) - if err != nil { - // "Legacy", no offset additional data? - realHash, err = decryptDeterministic(hash, fileKey, nil) - } - if err != nil { - return nil, fmt.Errorf("decrypting block hash: %w", err) + if len(hash) > 0 { + var additional [8]byte + binary.BigEndian.PutUint64(additional[:], uint64(realOffset)) + realHash, err = decryptDeterministic(hash, fileKey, additional[:]) + if err != nil { + // "Legacy", no offset additional data? + realHash, err = decryptDeterministic(hash, fileKey, nil) + } + if err != nil { + return nil, fmt.Errorf("decrypting block hash: %w", err) + } } // Perform that request and grab the data.