MCPcopy
hub / github.com/syncthing/syncthing / encryptFileInfo

Function encryptFileInfo

lib/protocol/encryption.go:289–377  ·  view source on GitHub ↗

encryptFileInfo encrypts a FileInfo and wraps it into a new fake FileInfo with an encrypted name.

(keyGen *KeyGenerator, fi FileInfo, folderKey *[keySize]byte)

Source from the content-addressed store, hash-verified

287// encryptFileInfo encrypts a FileInfo and wraps it into a new fake FileInfo
288// with an encrypted name.
289func encryptFileInfo(keyGen *KeyGenerator, fi FileInfo, folderKey *[keySize]byte) FileInfo {
290 fileKey := keyGen.FileKey(fi.Name, folderKey)
291
292 // The entire FileInfo is encrypted with a random nonce, and concatenated
293 // with that nonce.
294
295 bs, err := proto.Marshal(fi.ToWire(false))
296 if err != nil {
297 panic("impossible serialization mishap: " + err.Error())
298 }
299 encryptedFI := encryptBytes(bs, fileKey)
300
301 // The vector is set to something that is higher than any other version sent
302 // previously. We do this because
303 // there is no way for the insecure device on the other end to do proper
304 // conflict resolution, so they will simply accept and keep whatever is the
305 // latest version they see. The secure devices will decrypt the real
306 // FileInfo, see the real Version, and act appropriately regardless of what
307 // this fake version happens to be.
308 // The vector also needs to be deterministic/the same among all trusted
309 // devices with the same vector, such that the pulling/remote completion
310 // works correctly on the untrusted device(s).
311
312 version := Vector{
313 Counters: []Counter{
314 {
315 ID: 1,
316 },
317 },
318 }
319 for _, counter := range fi.Version.Counters {
320 version.Counters[0].Value += counter.Value
321 }
322
323 // Construct the fake block list. Each block will be blockOverhead bytes
324 // larger than the corresponding real one and have an encrypted hash.
325 // Very small blocks will be padded upwards to minPaddedSize.
326 //
327 // The encrypted hash becomes just a "token" for the data -- it doesn't
328 // help verifying it, but it lets the encrypted device do block level
329 // diffs and data reuse properly when it gets a new version of a file.
330
331 var offset int64
332 blocks := make([]BlockInfo, len(fi.Blocks))
333 for i, b := range fi.Blocks {
334 if b.Size < minPaddedSize {
335 b.Size = minPaddedSize
336 }
337 size := b.Size + blockOverhead
338 hash := encryptBlockHash(b.Hash, b.Offset, fileKey)
339 blocks[i] = BlockInfo{
340 Hash: hash,
341 Offset: offset,
342 Size: size,
343 }
344 offset += int64(size)
345 }
346

Callers 3

TestEnDecryptFileInfoFunction · 0.85
encryptFileInfosFunction · 0.85

Calls 9

encryptBytesFunction · 0.85
encryptBlockHashFunction · 0.85
encryptNameFunction · 0.85
FileKeyMethod · 0.80
MarshalMethod · 0.80
ErrorMethod · 0.65
ToWireMethod · 0.45
IsInvalidMethod · 0.45
BlockSizeMethod · 0.45

Tested by 2

TestEnDecryptFileInfoFunction · 0.68