cipher.go 31 KB

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