github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/backend/crypt/cipher.go (about)

     1  package crypt
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"crypto/aes"
     7  	gocipher "crypto/cipher"
     8  	"crypto/rand"
     9  	"encoding/base32"
    10  	"fmt"
    11  	"io"
    12  	"strconv"
    13  	"strings"
    14  	"sync"
    15  	"unicode/utf8"
    16  
    17  	"github.com/pkg/errors"
    18  	"github.com/rclone/rclone/backend/crypt/pkcs7"
    19  	"github.com/rclone/rclone/fs"
    20  	"github.com/rclone/rclone/fs/accounting"
    21  	"github.com/rfjakob/eme"
    22  	"golang.org/x/crypto/nacl/secretbox"
    23  	"golang.org/x/crypto/scrypt"
    24  )
    25  
    26  // Constants
    27  const (
    28  	nameCipherBlockSize = aes.BlockSize
    29  	fileMagic           = "RCLONE\x00\x00"
    30  	fileMagicSize       = len(fileMagic)
    31  	fileNonceSize       = 24
    32  	fileHeaderSize      = fileMagicSize + fileNonceSize
    33  	blockHeaderSize     = secretbox.Overhead
    34  	blockDataSize       = 64 * 1024
    35  	blockSize           = blockHeaderSize + blockDataSize
    36  	encryptedSuffix     = ".bin" // when file name encryption is off we add this suffix to make sure the cloud provider doesn't process the file
    37  )
    38  
    39  // Errors returned by cipher
    40  var (
    41  	ErrorBadDecryptUTF8          = errors.New("bad decryption - utf-8 invalid")
    42  	ErrorBadDecryptControlChar   = errors.New("bad decryption - contains control chars")
    43  	ErrorNotAMultipleOfBlocksize = errors.New("not a multiple of blocksize")
    44  	ErrorTooShortAfterDecode     = errors.New("too short after base32 decode")
    45  	ErrorTooLongAfterDecode      = errors.New("too long after base32 decode")
    46  	ErrorEncryptedFileTooShort   = errors.New("file is too short to be encrypted")
    47  	ErrorEncryptedFileBadHeader  = errors.New("file has truncated block header")
    48  	ErrorEncryptedBadMagic       = errors.New("not an encrypted file - bad magic string")
    49  	ErrorEncryptedBadBlock       = errors.New("failed to authenticate decrypted block - bad password?")
    50  	ErrorBadBase32Encoding       = errors.New("bad base32 filename encoding")
    51  	ErrorFileClosed              = errors.New("file already closed")
    52  	ErrorNotAnEncryptedFile      = errors.New("not an encrypted file - no \"" + encryptedSuffix + "\" suffix")
    53  	ErrorBadSeek                 = errors.New("Seek beyond end of file")
    54  	defaultSalt                  = []byte{0xA8, 0x0D, 0xF4, 0x3A, 0x8F, 0xBD, 0x03, 0x08, 0xA7, 0xCA, 0xB8, 0x3E, 0x58, 0x1F, 0x86, 0xB1}
    55  	obfuscQuoteRune              = '!'
    56  )
    57  
    58  // Global variables
    59  var (
    60  	fileMagicBytes = []byte(fileMagic)
    61  )
    62  
    63  // ReadSeekCloser is the interface of the read handles
    64  type ReadSeekCloser interface {
    65  	io.Reader
    66  	io.Seeker
    67  	io.Closer
    68  	fs.RangeSeeker
    69  }
    70  
    71  // OpenRangeSeek opens the file handle at the offset with the limit given
    72  type OpenRangeSeek func(ctx context.Context, offset, limit int64) (io.ReadCloser, error)
    73  
    74  // Cipher is used to swap out the encryption implementations
    75  type Cipher interface {
    76  	// EncryptFileName encrypts a file path
    77  	EncryptFileName(string) string
    78  	// DecryptFileName decrypts a file path, returns error if decrypt was invalid
    79  	DecryptFileName(string) (string, error)
    80  	// EncryptDirName encrypts a directory path
    81  	EncryptDirName(string) string
    82  	// DecryptDirName decrypts a directory path, returns error if decrypt was invalid
    83  	DecryptDirName(string) (string, error)
    84  	// EncryptData
    85  	EncryptData(io.Reader) (io.Reader, error)
    86  	// DecryptData
    87  	DecryptData(io.ReadCloser) (io.ReadCloser, error)
    88  	// DecryptDataSeek decrypt at a given position
    89  	DecryptDataSeek(ctx context.Context, open OpenRangeSeek, offset, limit int64) (ReadSeekCloser, error)
    90  	// EncryptedSize calculates the size of the data when encrypted
    91  	EncryptedSize(int64) int64
    92  	// DecryptedSize calculates the size of the data when decrypted
    93  	DecryptedSize(int64) (int64, error)
    94  	// NameEncryptionMode returns the used mode for name handling
    95  	NameEncryptionMode() NameEncryptionMode
    96  }
    97  
    98  // NameEncryptionMode is the type of file name encryption in use
    99  type NameEncryptionMode int
   100  
   101  // NameEncryptionMode levels
   102  const (
   103  	NameEncryptionOff NameEncryptionMode = iota
   104  	NameEncryptionStandard
   105  	NameEncryptionObfuscated
   106  )
   107  
   108  // NewNameEncryptionMode turns a string into a NameEncryptionMode
   109  func NewNameEncryptionMode(s string) (mode NameEncryptionMode, err error) {
   110  	s = strings.ToLower(s)
   111  	switch s {
   112  	case "off":
   113  		mode = NameEncryptionOff
   114  	case "standard":
   115  		mode = NameEncryptionStandard
   116  	case "obfuscate":
   117  		mode = NameEncryptionObfuscated
   118  	default:
   119  		err = errors.Errorf("Unknown file name encryption mode %q", s)
   120  	}
   121  	return mode, err
   122  }
   123  
   124  // String turns mode into a human readable string
   125  func (mode NameEncryptionMode) String() (out string) {
   126  	switch mode {
   127  	case NameEncryptionOff:
   128  		out = "off"
   129  	case NameEncryptionStandard:
   130  		out = "standard"
   131  	case NameEncryptionObfuscated:
   132  		out = "obfuscate"
   133  	default:
   134  		out = fmt.Sprintf("Unknown mode #%d", mode)
   135  	}
   136  	return out
   137  }
   138  
   139  type cipher struct {
   140  	dataKey        [32]byte                  // Key for secretbox
   141  	nameKey        [32]byte                  // 16,24 or 32 bytes
   142  	nameTweak      [nameCipherBlockSize]byte // used to tweak the name crypto
   143  	block          gocipher.Block
   144  	mode           NameEncryptionMode
   145  	buffers        sync.Pool // encrypt/decrypt buffers
   146  	cryptoRand     io.Reader // read crypto random numbers from here
   147  	dirNameEncrypt bool
   148  }
   149  
   150  // newCipher initialises the cipher.  If salt is "" then it uses a built in salt val
   151  func newCipher(mode NameEncryptionMode, password, salt string, dirNameEncrypt bool) (*cipher, error) {
   152  	c := &cipher{
   153  		mode:           mode,
   154  		cryptoRand:     rand.Reader,
   155  		dirNameEncrypt: dirNameEncrypt,
   156  	}
   157  	c.buffers.New = func() interface{} {
   158  		return make([]byte, blockSize)
   159  	}
   160  	err := c.Key(password, salt)
   161  	if err != nil {
   162  		return nil, err
   163  	}
   164  	return c, nil
   165  }
   166  
   167  // Key creates all the internal keys from the password passed in using
   168  // scrypt.
   169  //
   170  // If salt is "" we use a fixed salt just to make attackers lives
   171  // slighty harder than using no salt.
   172  //
   173  // Note that empty passsword makes all 0x00 keys which is used in the
   174  // tests.
   175  func (c *cipher) Key(password, salt string) (err error) {
   176  	const keySize = len(c.dataKey) + len(c.nameKey) + len(c.nameTweak)
   177  	var saltBytes = defaultSalt
   178  	if salt != "" {
   179  		saltBytes = []byte(salt)
   180  	}
   181  	var key []byte
   182  	if password == "" {
   183  		key = make([]byte, keySize)
   184  	} else {
   185  		key, err = scrypt.Key([]byte(password), saltBytes, 16384, 8, 1, keySize)
   186  		if err != nil {
   187  			return err
   188  		}
   189  	}
   190  	copy(c.dataKey[:], key)
   191  	copy(c.nameKey[:], key[len(c.dataKey):])
   192  	copy(c.nameTweak[:], key[len(c.dataKey)+len(c.nameKey):])
   193  	// Key the name cipher
   194  	c.block, err = aes.NewCipher(c.nameKey[:])
   195  	return err
   196  }
   197  
   198  // getBlock gets a block from the pool of size blockSize
   199  func (c *cipher) getBlock() []byte {
   200  	return c.buffers.Get().([]byte)
   201  }
   202  
   203  // putBlock returns a block to the pool of size blockSize
   204  func (c *cipher) putBlock(buf []byte) {
   205  	if len(buf) != blockSize {
   206  		panic("bad blocksize returned to pool")
   207  	}
   208  	c.buffers.Put(buf)
   209  }
   210  
   211  // encodeFileName encodes a filename using a modified version of
   212  // standard base32 as described in RFC4648
   213  //
   214  // The standard encoding is modified in two ways
   215  //  * it becomes lower case (no-one likes upper case filenames!)
   216  //  * we strip the padding character `=`
   217  func encodeFileName(in []byte) string {
   218  	encoded := base32.HexEncoding.EncodeToString(in)
   219  	encoded = strings.TrimRight(encoded, "=")
   220  	return strings.ToLower(encoded)
   221  }
   222  
   223  // decodeFileName decodes a filename as encoded by encodeFileName
   224  func decodeFileName(in string) ([]byte, error) {
   225  	if strings.HasSuffix(in, "=") {
   226  		return nil, ErrorBadBase32Encoding
   227  	}
   228  	// First figure out how many padding characters to add
   229  	roundUpToMultipleOf8 := (len(in) + 7) &^ 7
   230  	equals := roundUpToMultipleOf8 - len(in)
   231  	in = strings.ToUpper(in) + "========"[:equals]
   232  	return base32.HexEncoding.DecodeString(in)
   233  }
   234  
   235  // encryptSegment encrypts a path segment
   236  //
   237  // This uses EME with AES
   238  //
   239  // EME (ECB-Mix-ECB) is a wide-block encryption mode presented in the
   240  // 2003 paper "A Parallelizable Enciphering Mode" by Halevi and
   241  // Rogaway.
   242  //
   243  // This makes for determinstic encryption which is what we want - the
   244  // same filename must encrypt to the same thing.
   245  //
   246  // This means that
   247  //  * filenames with the same name will encrypt the same
   248  //  * filenames which start the same won't have a common prefix
   249  func (c *cipher) encryptSegment(plaintext string) string {
   250  	if plaintext == "" {
   251  		return ""
   252  	}
   253  	paddedPlaintext := pkcs7.Pad(nameCipherBlockSize, []byte(plaintext))
   254  	ciphertext := eme.Transform(c.block, c.nameTweak[:], paddedPlaintext, eme.DirectionEncrypt)
   255  	return encodeFileName(ciphertext)
   256  }
   257  
   258  // decryptSegment decrypts a path segment
   259  func (c *cipher) decryptSegment(ciphertext string) (string, error) {
   260  	if ciphertext == "" {
   261  		return "", nil
   262  	}
   263  	rawCiphertext, err := decodeFileName(ciphertext)
   264  	if err != nil {
   265  		return "", err
   266  	}
   267  	if len(rawCiphertext)%nameCipherBlockSize != 0 {
   268  		return "", ErrorNotAMultipleOfBlocksize
   269  	}
   270  	if len(rawCiphertext) == 0 {
   271  		// not possible if decodeFilename() working correctly
   272  		return "", ErrorTooShortAfterDecode
   273  	}
   274  	if len(rawCiphertext) > 2048 {
   275  		return "", ErrorTooLongAfterDecode
   276  	}
   277  	paddedPlaintext := eme.Transform(c.block, c.nameTweak[:], rawCiphertext, eme.DirectionDecrypt)
   278  	plaintext, err := pkcs7.Unpad(nameCipherBlockSize, paddedPlaintext)
   279  	if err != nil {
   280  		return "", err
   281  	}
   282  	return string(plaintext), err
   283  }
   284  
   285  // Simple obfuscation routines
   286  func (c *cipher) obfuscateSegment(plaintext string) string {
   287  	if plaintext == "" {
   288  		return ""
   289  	}
   290  
   291  	// If the string isn't valid UTF8 then don't rotate; just
   292  	// prepend a !.
   293  	if !utf8.ValidString(plaintext) {
   294  		return "!." + plaintext
   295  	}
   296  
   297  	// Calculate a simple rotation based on the filename and
   298  	// the nameKey
   299  	var dir int
   300  	for _, runeValue := range plaintext {
   301  		dir += int(runeValue)
   302  	}
   303  	dir = dir % 256
   304  
   305  	// We'll use this number to store in the result filename...
   306  	var result bytes.Buffer
   307  	_, _ = result.WriteString(strconv.Itoa(dir) + ".")
   308  
   309  	// but we'll augment it with the nameKey for real calculation
   310  	for i := 0; i < len(c.nameKey); i++ {
   311  		dir += int(c.nameKey[i])
   312  	}
   313  
   314  	// Now for each character, depending on the range it is in
   315  	// we will actually rotate a different amount
   316  	for _, runeValue := range plaintext {
   317  		switch {
   318  		case runeValue == obfuscQuoteRune:
   319  			// Quote the Quote character
   320  			_, _ = result.WriteRune(obfuscQuoteRune)
   321  			_, _ = result.WriteRune(obfuscQuoteRune)
   322  
   323  		case runeValue >= '0' && runeValue <= '9':
   324  			// Number
   325  			thisdir := (dir % 9) + 1
   326  			newRune := '0' + (int(runeValue)-'0'+thisdir)%10
   327  			_, _ = result.WriteRune(rune(newRune))
   328  
   329  		case (runeValue >= 'A' && runeValue <= 'Z') ||
   330  			(runeValue >= 'a' && runeValue <= 'z'):
   331  			// ASCII letter.  Try to avoid trivial A->a mappings
   332  			thisdir := dir%25 + 1
   333  			// Calculate the offset of this character in A-Za-z
   334  			pos := int(runeValue - 'A')
   335  			if pos >= 26 {
   336  				pos -= 6 // It's lower case
   337  			}
   338  			// Rotate the character to the new location
   339  			pos = (pos + thisdir) % 52
   340  			if pos >= 26 {
   341  				pos += 6 // and handle lower case offset again
   342  			}
   343  			_, _ = result.WriteRune(rune('A' + pos))
   344  
   345  		case runeValue >= 0xA0 && runeValue <= 0xFF:
   346  			// Latin 1 supplement
   347  			thisdir := (dir % 95) + 1
   348  			newRune := 0xA0 + (int(runeValue)-0xA0+thisdir)%96
   349  			_, _ = result.WriteRune(rune(newRune))
   350  
   351  		case runeValue >= 0x100:
   352  			// Some random Unicode range; we have no good rules here
   353  			thisdir := (dir % 127) + 1
   354  			base := int(runeValue - runeValue%256)
   355  			newRune := rune(base + (int(runeValue)-base+thisdir)%256)
   356  			// If the new character isn't a valid UTF8 char
   357  			// then don't rotate it.  Quote it instead
   358  			if !utf8.ValidRune(newRune) {
   359  				_, _ = result.WriteRune(obfuscQuoteRune)
   360  				_, _ = result.WriteRune(runeValue)
   361  			} else {
   362  				_, _ = result.WriteRune(newRune)
   363  			}
   364  
   365  		default:
   366  			// Leave character untouched
   367  			_, _ = result.WriteRune(runeValue)
   368  		}
   369  	}
   370  	return result.String()
   371  }
   372  
   373  func (c *cipher) deobfuscateSegment(ciphertext string) (string, error) {
   374  	if ciphertext == "" {
   375  		return "", nil
   376  	}
   377  	pos := strings.Index(ciphertext, ".")
   378  	if pos == -1 {
   379  		return "", ErrorNotAnEncryptedFile
   380  	} // No .
   381  	num := ciphertext[:pos]
   382  	if num == "!" {
   383  		// No rotation; probably original was not valid unicode
   384  		return ciphertext[pos+1:], nil
   385  	}
   386  	dir, err := strconv.Atoi(num)
   387  	if err != nil {
   388  		return "", ErrorNotAnEncryptedFile // Not a number
   389  	}
   390  
   391  	// add the nameKey to get the real rotate distance
   392  	for i := 0; i < len(c.nameKey); i++ {
   393  		dir += int(c.nameKey[i])
   394  	}
   395  
   396  	var result bytes.Buffer
   397  
   398  	inQuote := false
   399  	for _, runeValue := range ciphertext[pos+1:] {
   400  		switch {
   401  		case inQuote:
   402  			_, _ = result.WriteRune(runeValue)
   403  			inQuote = false
   404  
   405  		case runeValue == obfuscQuoteRune:
   406  			inQuote = true
   407  
   408  		case runeValue >= '0' && runeValue <= '9':
   409  			// Number
   410  			thisdir := (dir % 9) + 1
   411  			newRune := '0' + int(runeValue) - '0' - thisdir
   412  			if newRune < '0' {
   413  				newRune += 10
   414  			}
   415  			_, _ = result.WriteRune(rune(newRune))
   416  
   417  		case (runeValue >= 'A' && runeValue <= 'Z') ||
   418  			(runeValue >= 'a' && runeValue <= 'z'):
   419  			thisdir := dir%25 + 1
   420  			pos := int(runeValue - 'A')
   421  			if pos >= 26 {
   422  				pos -= 6
   423  			}
   424  			pos = pos - thisdir
   425  			if pos < 0 {
   426  				pos += 52
   427  			}
   428  			if pos >= 26 {
   429  				pos += 6
   430  			}
   431  			_, _ = result.WriteRune(rune('A' + pos))
   432  
   433  		case runeValue >= 0xA0 && runeValue <= 0xFF:
   434  			thisdir := (dir % 95) + 1
   435  			newRune := 0xA0 + int(runeValue) - 0xA0 - thisdir
   436  			if newRune < 0xA0 {
   437  				newRune += 96
   438  			}
   439  			_, _ = result.WriteRune(rune(newRune))
   440  
   441  		case runeValue >= 0x100:
   442  			thisdir := (dir % 127) + 1
   443  			base := int(runeValue - runeValue%256)
   444  			newRune := rune(base + (int(runeValue) - base - thisdir))
   445  			if int(newRune) < base {
   446  				newRune += 256
   447  			}
   448  			_, _ = result.WriteRune(newRune)
   449  
   450  		default:
   451  			_, _ = result.WriteRune(runeValue)
   452  
   453  		}
   454  	}
   455  
   456  	return result.String(), nil
   457  }
   458  
   459  // encryptFileName encrypts a file path
   460  func (c *cipher) encryptFileName(in string) string {
   461  	segments := strings.Split(in, "/")
   462  	for i := range segments {
   463  		// Skip directory name encryption if the user chose to
   464  		// leave them intact
   465  		if !c.dirNameEncrypt && i != (len(segments)-1) {
   466  			continue
   467  		}
   468  		if c.mode == NameEncryptionStandard {
   469  			segments[i] = c.encryptSegment(segments[i])
   470  		} else {
   471  			segments[i] = c.obfuscateSegment(segments[i])
   472  		}
   473  	}
   474  	return strings.Join(segments, "/")
   475  }
   476  
   477  // EncryptFileName encrypts a file path
   478  func (c *cipher) EncryptFileName(in string) string {
   479  	if c.mode == NameEncryptionOff {
   480  		return in + encryptedSuffix
   481  	}
   482  	return c.encryptFileName(in)
   483  }
   484  
   485  // EncryptDirName encrypts a directory path
   486  func (c *cipher) EncryptDirName(in string) string {
   487  	if c.mode == NameEncryptionOff || !c.dirNameEncrypt {
   488  		return in
   489  	}
   490  	return c.encryptFileName(in)
   491  }
   492  
   493  // decryptFileName decrypts a file path
   494  func (c *cipher) decryptFileName(in string) (string, error) {
   495  	segments := strings.Split(in, "/")
   496  	for i := range segments {
   497  		var err error
   498  		// Skip directory name decryption if the user chose to
   499  		// leave them intact
   500  		if !c.dirNameEncrypt && i != (len(segments)-1) {
   501  			continue
   502  		}
   503  		if c.mode == NameEncryptionStandard {
   504  			segments[i], err = c.decryptSegment(segments[i])
   505  		} else {
   506  			segments[i], err = c.deobfuscateSegment(segments[i])
   507  		}
   508  
   509  		if err != nil {
   510  			return "", err
   511  		}
   512  	}
   513  	return strings.Join(segments, "/"), nil
   514  }
   515  
   516  // DecryptFileName decrypts a file path
   517  func (c *cipher) DecryptFileName(in string) (string, error) {
   518  	if c.mode == NameEncryptionOff {
   519  		remainingLength := len(in) - len(encryptedSuffix)
   520  		if remainingLength > 0 && strings.HasSuffix(in, encryptedSuffix) {
   521  			return in[:remainingLength], nil
   522  		}
   523  		return "", ErrorNotAnEncryptedFile
   524  	}
   525  	return c.decryptFileName(in)
   526  }
   527  
   528  // DecryptDirName decrypts a directory path
   529  func (c *cipher) DecryptDirName(in string) (string, error) {
   530  	if c.mode == NameEncryptionOff || !c.dirNameEncrypt {
   531  		return in, nil
   532  	}
   533  	return c.decryptFileName(in)
   534  }
   535  
   536  func (c *cipher) NameEncryptionMode() NameEncryptionMode {
   537  	return c.mode
   538  }
   539  
   540  // nonce is an NACL secretbox nonce
   541  type nonce [fileNonceSize]byte
   542  
   543  // pointer returns the nonce as a *[24]byte for secretbox
   544  func (n *nonce) pointer() *[fileNonceSize]byte {
   545  	return (*[fileNonceSize]byte)(n)
   546  }
   547  
   548  // fromReader fills the nonce from an io.Reader - normally the OSes
   549  // crypto random number generator
   550  func (n *nonce) fromReader(in io.Reader) error {
   551  	read, err := io.ReadFull(in, (*n)[:])
   552  	if read != fileNonceSize {
   553  		return errors.Wrap(err, "short read of nonce")
   554  	}
   555  	return nil
   556  }
   557  
   558  // fromBuf fills the nonce from the buffer passed in
   559  func (n *nonce) fromBuf(buf []byte) {
   560  	read := copy((*n)[:], buf)
   561  	if read != fileNonceSize {
   562  		panic("buffer to short to read nonce")
   563  	}
   564  }
   565  
   566  // carry 1 up the nonce from position i
   567  func (n *nonce) carry(i int) {
   568  	for ; i < len(*n); i++ {
   569  		digit := (*n)[i]
   570  		newDigit := digit + 1
   571  		(*n)[i] = newDigit
   572  		if newDigit >= digit {
   573  			// exit if no carry
   574  			break
   575  		}
   576  	}
   577  }
   578  
   579  // increment to add 1 to the nonce
   580  func (n *nonce) increment() {
   581  	n.carry(0)
   582  }
   583  
   584  // add an uint64 to the nonce
   585  func (n *nonce) add(x uint64) {
   586  	carry := uint16(0)
   587  	for i := 0; i < 8; i++ {
   588  		digit := (*n)[i]
   589  		xDigit := byte(x)
   590  		x >>= 8
   591  		carry += uint16(digit) + uint16(xDigit)
   592  		(*n)[i] = byte(carry)
   593  		carry >>= 8
   594  	}
   595  	if carry != 0 {
   596  		n.carry(8)
   597  	}
   598  }
   599  
   600  // encrypter encrypts an io.Reader on the fly
   601  type encrypter struct {
   602  	mu       sync.Mutex
   603  	in       io.Reader
   604  	c        *cipher
   605  	nonce    nonce
   606  	buf      []byte
   607  	readBuf  []byte
   608  	bufIndex int
   609  	bufSize  int
   610  	err      error
   611  }
   612  
   613  // newEncrypter creates a new file handle encrypting on the fly
   614  func (c *cipher) newEncrypter(in io.Reader, nonce *nonce) (*encrypter, error) {
   615  	fh := &encrypter{
   616  		in:      in,
   617  		c:       c,
   618  		buf:     c.getBlock(),
   619  		readBuf: c.getBlock(),
   620  		bufSize: fileHeaderSize,
   621  	}
   622  	// Initialise nonce
   623  	if nonce != nil {
   624  		fh.nonce = *nonce
   625  	} else {
   626  		err := fh.nonce.fromReader(c.cryptoRand)
   627  		if err != nil {
   628  			return nil, err
   629  		}
   630  	}
   631  	// Copy magic into buffer
   632  	copy(fh.buf, fileMagicBytes)
   633  	// Copy nonce into buffer
   634  	copy(fh.buf[fileMagicSize:], fh.nonce[:])
   635  	return fh, nil
   636  }
   637  
   638  // Read as per io.Reader
   639  func (fh *encrypter) Read(p []byte) (n int, err error) {
   640  	fh.mu.Lock()
   641  	defer fh.mu.Unlock()
   642  
   643  	if fh.err != nil {
   644  		return 0, fh.err
   645  	}
   646  	if fh.bufIndex >= fh.bufSize {
   647  		// Read data
   648  		// FIXME should overlap the reads with a go-routine and 2 buffers?
   649  		readBuf := fh.readBuf[:blockDataSize]
   650  		n, err = io.ReadFull(fh.in, readBuf)
   651  		if n == 0 {
   652  			// err can't be nil since:
   653  			// n == len(buf) if and only if err == nil.
   654  			return fh.finish(err)
   655  		}
   656  		// possibly err != nil here, but we will process the
   657  		// data and the next call to ReadFull will return 0, err
   658  		// Write nonce to start of block
   659  		copy(fh.buf, fh.nonce[:])
   660  		// Encrypt the block using the nonce
   661  		block := fh.buf
   662  		secretbox.Seal(block[:0], readBuf[:n], fh.nonce.pointer(), &fh.c.dataKey)
   663  		fh.bufIndex = 0
   664  		fh.bufSize = blockHeaderSize + n
   665  		fh.nonce.increment()
   666  	}
   667  	n = copy(p, fh.buf[fh.bufIndex:fh.bufSize])
   668  	fh.bufIndex += n
   669  	return n, nil
   670  }
   671  
   672  // finish sets the final error and tidies up
   673  func (fh *encrypter) finish(err error) (int, error) {
   674  	if fh.err != nil {
   675  		return 0, fh.err
   676  	}
   677  	fh.err = err
   678  	fh.c.putBlock(fh.buf)
   679  	fh.buf = nil
   680  	fh.c.putBlock(fh.readBuf)
   681  	fh.readBuf = nil
   682  	return 0, err
   683  }
   684  
   685  // Encrypt data encrypts the data stream
   686  func (c *cipher) EncryptData(in io.Reader) (io.Reader, error) {
   687  	in, wrap := accounting.UnWrap(in) // unwrap the accounting off the Reader
   688  	out, err := c.newEncrypter(in, nil)
   689  	if err != nil {
   690  		return nil, err
   691  	}
   692  	return wrap(out), nil // and wrap the accounting back on
   693  }
   694  
   695  // decrypter decrypts an io.ReaderCloser on the fly
   696  type decrypter struct {
   697  	mu           sync.Mutex
   698  	rc           io.ReadCloser
   699  	nonce        nonce
   700  	initialNonce nonce
   701  	c            *cipher
   702  	buf          []byte
   703  	readBuf      []byte
   704  	bufIndex     int
   705  	bufSize      int
   706  	err          error
   707  	limit        int64 // limit of bytes to read, -1 for unlimited
   708  	open         OpenRangeSeek
   709  }
   710  
   711  // newDecrypter creates a new file handle decrypting on the fly
   712  func (c *cipher) newDecrypter(rc io.ReadCloser) (*decrypter, error) {
   713  	fh := &decrypter{
   714  		rc:      rc,
   715  		c:       c,
   716  		buf:     c.getBlock(),
   717  		readBuf: c.getBlock(),
   718  		limit:   -1,
   719  	}
   720  	// Read file header (magic + nonce)
   721  	readBuf := fh.readBuf[:fileHeaderSize]
   722  	_, err := io.ReadFull(fh.rc, readBuf)
   723  	if err == io.EOF || err == io.ErrUnexpectedEOF {
   724  		// This read from 0..fileHeaderSize-1 bytes
   725  		return nil, fh.finishAndClose(ErrorEncryptedFileTooShort)
   726  	} else if err != nil {
   727  		return nil, fh.finishAndClose(err)
   728  	}
   729  	// check the magic
   730  	if !bytes.Equal(readBuf[:fileMagicSize], fileMagicBytes) {
   731  		return nil, fh.finishAndClose(ErrorEncryptedBadMagic)
   732  	}
   733  	// retrieve the nonce
   734  	fh.nonce.fromBuf(readBuf[fileMagicSize:])
   735  	fh.initialNonce = fh.nonce
   736  	return fh, nil
   737  }
   738  
   739  // newDecrypterSeek creates a new file handle decrypting on the fly
   740  func (c *cipher) newDecrypterSeek(ctx context.Context, open OpenRangeSeek, offset, limit int64) (fh *decrypter, err error) {
   741  	var rc io.ReadCloser
   742  	doRangeSeek := false
   743  	setLimit := false
   744  	// Open initially with no seek
   745  	if offset == 0 && limit < 0 {
   746  		// If no offset or limit then open whole file
   747  		rc, err = open(ctx, 0, -1)
   748  	} else if offset == 0 {
   749  		// If no offset open the header + limit worth of the file
   750  		_, underlyingLimit, _, _ := calculateUnderlying(offset, limit)
   751  		rc, err = open(ctx, 0, int64(fileHeaderSize)+underlyingLimit)
   752  		setLimit = true
   753  	} else {
   754  		// Otherwise just read the header to start with
   755  		rc, err = open(ctx, 0, int64(fileHeaderSize))
   756  		doRangeSeek = true
   757  	}
   758  	if err != nil {
   759  		return nil, err
   760  	}
   761  	// Open the stream which fills in the nonce
   762  	fh, err = c.newDecrypter(rc)
   763  	if err != nil {
   764  		return nil, err
   765  	}
   766  	fh.open = open // will be called by fh.RangeSeek
   767  	if doRangeSeek {
   768  		_, err = fh.RangeSeek(ctx, offset, io.SeekStart, limit)
   769  		if err != nil {
   770  			_ = fh.Close()
   771  			return nil, err
   772  		}
   773  	}
   774  	if setLimit {
   775  		fh.limit = limit
   776  	}
   777  	return fh, nil
   778  }
   779  
   780  // read data into internal buffer - call with fh.mu held
   781  func (fh *decrypter) fillBuffer() (err error) {
   782  	// FIXME should overlap the reads with a go-routine and 2 buffers?
   783  	readBuf := fh.readBuf
   784  	n, err := io.ReadFull(fh.rc, readBuf)
   785  	if n == 0 {
   786  		// err can't be nil since:
   787  		// n == len(buf) if and only if err == nil.
   788  		return err
   789  	}
   790  	// possibly err != nil here, but we will process the data and
   791  	// the next call to ReadFull will return 0, err
   792  
   793  	// Check header + 1 byte exists
   794  	if n <= blockHeaderSize {
   795  		if err != nil {
   796  			return err // return pending error as it is likely more accurate
   797  		}
   798  		return ErrorEncryptedFileBadHeader
   799  	}
   800  	// Decrypt the block using the nonce
   801  	block := fh.buf
   802  	_, ok := secretbox.Open(block[:0], readBuf[:n], fh.nonce.pointer(), &fh.c.dataKey)
   803  	if !ok {
   804  		if err != nil {
   805  			return err // return pending error as it is likely more accurate
   806  		}
   807  		return ErrorEncryptedBadBlock
   808  	}
   809  	fh.bufIndex = 0
   810  	fh.bufSize = n - blockHeaderSize
   811  	fh.nonce.increment()
   812  	return nil
   813  }
   814  
   815  // Read as per io.Reader
   816  func (fh *decrypter) Read(p []byte) (n int, err error) {
   817  	fh.mu.Lock()
   818  	defer fh.mu.Unlock()
   819  
   820  	if fh.err != nil {
   821  		return 0, fh.err
   822  	}
   823  	if fh.bufIndex >= fh.bufSize {
   824  		err = fh.fillBuffer()
   825  		if err != nil {
   826  			return 0, fh.finish(err)
   827  		}
   828  	}
   829  	toCopy := fh.bufSize - fh.bufIndex
   830  	if fh.limit >= 0 && fh.limit < int64(toCopy) {
   831  		toCopy = int(fh.limit)
   832  	}
   833  	n = copy(p, fh.buf[fh.bufIndex:fh.bufIndex+toCopy])
   834  	fh.bufIndex += n
   835  	if fh.limit >= 0 {
   836  		fh.limit -= int64(n)
   837  		if fh.limit == 0 {
   838  			return n, fh.finish(io.EOF)
   839  		}
   840  	}
   841  	return n, nil
   842  }
   843  
   844  // calculateUnderlying converts an (offset, limit) in a crypted file
   845  // into an (underlyingOffset, underlyingLimit) for the underlying
   846  // file.
   847  //
   848  // It also returns number of bytes to discard after reading the first
   849  // block and number of blocks this is from the start so the nonce can
   850  // be incremented.
   851  func calculateUnderlying(offset, limit int64) (underlyingOffset, underlyingLimit, discard, blocks int64) {
   852  	// blocks we need to seek, plus bytes we need to discard
   853  	blocks, discard = offset/blockDataSize, offset%blockDataSize
   854  
   855  	// Offset in underlying stream we need to seek
   856  	underlyingOffset = int64(fileHeaderSize) + blocks*(blockHeaderSize+blockDataSize)
   857  
   858  	// work out how many blocks we need to read
   859  	underlyingLimit = int64(-1)
   860  	if limit >= 0 {
   861  		// bytes to read beyond the first block
   862  		bytesToRead := limit - (blockDataSize - discard)
   863  
   864  		// Read the first block
   865  		blocksToRead := int64(1)
   866  
   867  		if bytesToRead > 0 {
   868  			// Blocks that need to be read plus left over blocks
   869  			extraBlocksToRead, endBytes := bytesToRead/blockDataSize, bytesToRead%blockDataSize
   870  			if endBytes != 0 {
   871  				// If left over bytes must read another block
   872  				extraBlocksToRead++
   873  			}
   874  			blocksToRead += extraBlocksToRead
   875  		}
   876  
   877  		// Must read a whole number of blocks
   878  		underlyingLimit = blocksToRead * (blockHeaderSize + blockDataSize)
   879  	}
   880  	return
   881  }
   882  
   883  // RangeSeek behaves like a call to Seek(offset int64, whence
   884  // int) with the output wrapped in an io.LimitedReader
   885  // limiting the total length to limit.
   886  //
   887  // RangeSeek with a limit of < 0 is equivalent to a regular Seek.
   888  func (fh *decrypter) RangeSeek(ctx context.Context, offset int64, whence int, limit int64) (int64, error) {
   889  	fh.mu.Lock()
   890  	defer fh.mu.Unlock()
   891  
   892  	if fh.open == nil {
   893  		return 0, fh.finish(errors.New("can't seek - not initialised with newDecrypterSeek"))
   894  	}
   895  	if whence != io.SeekStart {
   896  		return 0, fh.finish(errors.New("can only seek from the start"))
   897  	}
   898  
   899  	// Reset error or return it if not EOF
   900  	if fh.err == io.EOF {
   901  		fh.unFinish()
   902  	} else if fh.err != nil {
   903  		return 0, fh.err
   904  	}
   905  
   906  	underlyingOffset, underlyingLimit, discard, blocks := calculateUnderlying(offset, limit)
   907  
   908  	// Move the nonce on the correct number of blocks from the start
   909  	fh.nonce = fh.initialNonce
   910  	fh.nonce.add(uint64(blocks))
   911  
   912  	// Can we seek underlying stream directly?
   913  	if do, ok := fh.rc.(fs.RangeSeeker); ok {
   914  		// Seek underlying stream directly
   915  		_, err := do.RangeSeek(ctx, underlyingOffset, 0, underlyingLimit)
   916  		if err != nil {
   917  			return 0, fh.finish(err)
   918  		}
   919  	} else {
   920  		// if not reopen with seek
   921  		_ = fh.rc.Close() // close underlying file
   922  		fh.rc = nil
   923  
   924  		// Re-open the underlying object with the offset given
   925  		rc, err := fh.open(ctx, underlyingOffset, underlyingLimit)
   926  		if err != nil {
   927  			return 0, fh.finish(errors.Wrap(err, "couldn't reopen file with offset and limit"))
   928  		}
   929  
   930  		// Set the file handle
   931  		fh.rc = rc
   932  	}
   933  
   934  	// Fill the buffer
   935  	err := fh.fillBuffer()
   936  	if err != nil {
   937  		return 0, fh.finish(err)
   938  	}
   939  
   940  	// Discard bytes from the buffer
   941  	if int(discard) > fh.bufSize {
   942  		return 0, fh.finish(ErrorBadSeek)
   943  	}
   944  	fh.bufIndex = int(discard)
   945  
   946  	// Set the limit
   947  	fh.limit = limit
   948  
   949  	return offset, nil
   950  }
   951  
   952  // Seek implements the io.Seeker interface
   953  func (fh *decrypter) Seek(offset int64, whence int) (int64, error) {
   954  	return fh.RangeSeek(context.TODO(), offset, whence, -1)
   955  }
   956  
   957  // finish sets the final error and tidies up
   958  func (fh *decrypter) finish(err error) error {
   959  	if fh.err != nil {
   960  		return fh.err
   961  	}
   962  	fh.err = err
   963  	fh.c.putBlock(fh.buf)
   964  	fh.buf = nil
   965  	fh.c.putBlock(fh.readBuf)
   966  	fh.readBuf = nil
   967  	return err
   968  }
   969  
   970  // unFinish undoes the effects of finish
   971  func (fh *decrypter) unFinish() {
   972  	// Clear error
   973  	fh.err = nil
   974  
   975  	// reinstate the buffers
   976  	fh.buf = fh.c.getBlock()
   977  	fh.readBuf = fh.c.getBlock()
   978  
   979  	// Empty the buffer
   980  	fh.bufIndex = 0
   981  	fh.bufSize = 0
   982  }
   983  
   984  // Close
   985  func (fh *decrypter) Close() error {
   986  	fh.mu.Lock()
   987  	defer fh.mu.Unlock()
   988  
   989  	// Check already closed
   990  	if fh.err == ErrorFileClosed {
   991  		return fh.err
   992  	}
   993  	// Closed before reading EOF so not finish()ed yet
   994  	if fh.err == nil {
   995  		_ = fh.finish(io.EOF)
   996  	}
   997  	// Show file now closed
   998  	fh.err = ErrorFileClosed
   999  	if fh.rc == nil {
  1000  		return nil
  1001  	}
  1002  	return fh.rc.Close()
  1003  }
  1004  
  1005  // finishAndClose does finish then Close()
  1006  //
  1007  // Used when we are returning a nil fh from new
  1008  func (fh *decrypter) finishAndClose(err error) error {
  1009  	_ = fh.finish(err)
  1010  	_ = fh.Close()
  1011  	return err
  1012  }
  1013  
  1014  // DecryptData decrypts the data stream
  1015  func (c *cipher) DecryptData(rc io.ReadCloser) (io.ReadCloser, error) {
  1016  	out, err := c.newDecrypter(rc)
  1017  	if err != nil {
  1018  		return nil, err
  1019  	}
  1020  	return out, nil
  1021  }
  1022  
  1023  // DecryptDataSeek decrypts the data stream from offset
  1024  //
  1025  // The open function must return a ReadCloser opened to the offset supplied
  1026  //
  1027  // You must use this form of DecryptData if you might want to Seek the file handle
  1028  func (c *cipher) DecryptDataSeek(ctx context.Context, open OpenRangeSeek, offset, limit int64) (ReadSeekCloser, error) {
  1029  	out, err := c.newDecrypterSeek(ctx, open, offset, limit)
  1030  	if err != nil {
  1031  		return nil, err
  1032  	}
  1033  	return out, nil
  1034  }
  1035  
  1036  // EncryptedSize calculates the size of the data when encrypted
  1037  func (c *cipher) EncryptedSize(size int64) int64 {
  1038  	blocks, residue := size/blockDataSize, size%blockDataSize
  1039  	encryptedSize := int64(fileHeaderSize) + blocks*(blockHeaderSize+blockDataSize)
  1040  	if residue != 0 {
  1041  		encryptedSize += blockHeaderSize + residue
  1042  	}
  1043  	return encryptedSize
  1044  }
  1045  
  1046  // DecryptedSize calculates the size of the data when decrypted
  1047  func (c *cipher) DecryptedSize(size int64) (int64, error) {
  1048  	size -= int64(fileHeaderSize)
  1049  	if size < 0 {
  1050  		return 0, ErrorEncryptedFileTooShort
  1051  	}
  1052  	blocks, residue := size/blockSize, size%blockSize
  1053  	decryptedSize := blocks * blockDataSize
  1054  	if residue != 0 {
  1055  		residue -= blockHeaderSize
  1056  		if residue <= 0 {
  1057  			return 0, ErrorEncryptedFileBadHeader
  1058  		}
  1059  	}
  1060  	decryptedSize += residue
  1061  	return decryptedSize, nil
  1062  }
  1063  
  1064  // check interfaces
  1065  var (
  1066  	_ Cipher         = (*cipher)(nil)
  1067  	_ io.ReadCloser  = (*decrypter)(nil)
  1068  	_ io.Seeker      = (*decrypter)(nil)
  1069  	_ fs.RangeSeeker = (*decrypter)(nil)
  1070  	_ io.Reader      = (*encrypter)(nil)
  1071  )