github.com/ethersphere/bee/v2@v2.2.0/pkg/encryption/store/decrypt_store.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package store 6 7 import ( 8 "context" 9 "encoding/binary" 10 11 "github.com/ethersphere/bee/v2/pkg/encryption" 12 "github.com/ethersphere/bee/v2/pkg/file" 13 "github.com/ethersphere/bee/v2/pkg/file/redundancy" 14 storage "github.com/ethersphere/bee/v2/pkg/storage" 15 "github.com/ethersphere/bee/v2/pkg/swarm" 16 ) 17 18 type decryptingStore struct { 19 storage.Getter 20 } 21 22 func New(s storage.Getter) storage.Getter { 23 return &decryptingStore{s} 24 } 25 26 func (s *decryptingStore) Get(ctx context.Context, addr swarm.Address) (ch swarm.Chunk, err error) { 27 switch l := len(addr.Bytes()); l { 28 case swarm.HashSize: 29 // normal, unencrypted content 30 return s.Getter.Get(ctx, addr) 31 32 case encryption.ReferenceSize: 33 // encrypted reference 34 ref := addr.Bytes() 35 address := swarm.NewAddress(ref[:swarm.HashSize]) 36 ch, err := s.Getter.Get(ctx, address) 37 if err != nil { 38 return nil, err 39 } 40 41 d, err := DecryptChunkData(ch.Data(), ref[swarm.HashSize:]) 42 if err != nil { 43 return nil, err 44 } 45 return swarm.NewChunk(address, d), nil 46 47 default: 48 return nil, storage.ErrReferenceLength 49 } 50 } 51 52 func DecryptChunkData(chunkData []byte, encryptionKey encryption.Key) ([]byte, error) { 53 decryptedSpan, decryptedData, err := decrypt(chunkData, encryptionKey) 54 if err != nil { 55 return nil, err 56 } 57 58 // removing extra bytes which were just added for padding 59 level, span := redundancy.DecodeSpan(decryptedSpan) 60 length := binary.LittleEndian.Uint64(span) 61 if length > swarm.ChunkSize { 62 dataRefSize := uint64(swarm.HashSize + encryption.KeyLength) 63 dataShards, parities := file.ReferenceCount(length, level, true) 64 length = dataRefSize*uint64(dataShards) + uint64(parities*swarm.HashSize) 65 } 66 67 c := make([]byte, length+8) 68 copy(c[:8], decryptedSpan) 69 copy(c[8:], decryptedData[:length]) 70 71 return c, nil 72 } 73 74 func decrypt(chunkData []byte, key encryption.Key) ([]byte, []byte, error) { 75 decryptedSpan, err := encryption.NewSpanEncryption(key).Decrypt(chunkData[:swarm.SpanSize]) 76 if err != nil { 77 return nil, nil, err 78 } 79 decryptedData, err := encryption.NewDataEncryption(key).Decrypt(chunkData[swarm.SpanSize:]) 80 if err != nil { 81 return nil, nil, err 82 } 83 return decryptedSpan, decryptedData, nil 84 }