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.