github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/backend/crypt/cipher_test.go (about)

     1  package crypt
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/base32"
     7  	"fmt"
     8  	"io"
     9  	"io/ioutil"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/ncw/rclone/backend/crypt/pkcs7"
    14  	"github.com/pkg/errors"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestNewNameEncryptionMode(t *testing.T) {
    20  	for _, test := range []struct {
    21  		in          string
    22  		expected    NameEncryptionMode
    23  		expectedErr string
    24  	}{
    25  		{"off", NameEncryptionOff, ""},
    26  		{"standard", NameEncryptionStandard, ""},
    27  		{"obfuscate", NameEncryptionObfuscated, ""},
    28  		{"potato", NameEncryptionOff, "Unknown file name encryption mode \"potato\""},
    29  	} {
    30  		actual, actualErr := NewNameEncryptionMode(test.in)
    31  		assert.Equal(t, actual, test.expected)
    32  		if test.expectedErr == "" {
    33  			assert.NoError(t, actualErr)
    34  		} else {
    35  			assert.Error(t, actualErr, test.expectedErr)
    36  		}
    37  	}
    38  }
    39  
    40  func TestNewNameEncryptionModeString(t *testing.T) {
    41  	assert.Equal(t, NameEncryptionOff.String(), "off")
    42  	assert.Equal(t, NameEncryptionStandard.String(), "standard")
    43  	assert.Equal(t, NameEncryptionObfuscated.String(), "obfuscate")
    44  	assert.Equal(t, NameEncryptionMode(3).String(), "Unknown mode #3")
    45  }
    46  
    47  func TestValidString(t *testing.T) {
    48  	for _, test := range []struct {
    49  		in       string
    50  		expected error
    51  	}{
    52  		{"", nil},
    53  		{"\x01", ErrorBadDecryptControlChar},
    54  		{"a\x02", ErrorBadDecryptControlChar},
    55  		{"abc\x03", ErrorBadDecryptControlChar},
    56  		{"abc\x04def", ErrorBadDecryptControlChar},
    57  		{"\x05d", ErrorBadDecryptControlChar},
    58  		{"\x06def", ErrorBadDecryptControlChar},
    59  		{"\x07", ErrorBadDecryptControlChar},
    60  		{"\x08", ErrorBadDecryptControlChar},
    61  		{"\x09", ErrorBadDecryptControlChar},
    62  		{"\x0A", ErrorBadDecryptControlChar},
    63  		{"\x0B", ErrorBadDecryptControlChar},
    64  		{"\x0C", ErrorBadDecryptControlChar},
    65  		{"\x0D", ErrorBadDecryptControlChar},
    66  		{"\x0E", ErrorBadDecryptControlChar},
    67  		{"\x0F", ErrorBadDecryptControlChar},
    68  		{"\x10", ErrorBadDecryptControlChar},
    69  		{"\x11", ErrorBadDecryptControlChar},
    70  		{"\x12", ErrorBadDecryptControlChar},
    71  		{"\x13", ErrorBadDecryptControlChar},
    72  		{"\x14", ErrorBadDecryptControlChar},
    73  		{"\x15", ErrorBadDecryptControlChar},
    74  		{"\x16", ErrorBadDecryptControlChar},
    75  		{"\x17", ErrorBadDecryptControlChar},
    76  		{"\x18", ErrorBadDecryptControlChar},
    77  		{"\x19", ErrorBadDecryptControlChar},
    78  		{"\x1A", ErrorBadDecryptControlChar},
    79  		{"\x1B", ErrorBadDecryptControlChar},
    80  		{"\x1C", ErrorBadDecryptControlChar},
    81  		{"\x1D", ErrorBadDecryptControlChar},
    82  		{"\x1E", ErrorBadDecryptControlChar},
    83  		{"\x1F", ErrorBadDecryptControlChar},
    84  		{"\x20", nil},
    85  		{"\x7E", nil},
    86  		{"\x7F", ErrorBadDecryptControlChar},
    87  		{"£100", nil},
    88  		{`hello? sausage/êé/Hello, 世界/ " ' @ < > & ?/z.txt`, nil},
    89  		{"£100", nil},
    90  		// Following tests from https://secure.php.net/manual/en/reference.pcre.pattern.modifiers.php#54805
    91  		{"a", nil},                                        // Valid ASCII
    92  		{"\xc3\xb1", nil},                                 // Valid 2 Octet Sequence
    93  		{"\xc3\x28", ErrorBadDecryptUTF8},                 // Invalid 2 Octet Sequence
    94  		{"\xa0\xa1", ErrorBadDecryptUTF8},                 // Invalid Sequence Identifier
    95  		{"\xe2\x82\xa1", nil},                             // Valid 3 Octet Sequence
    96  		{"\xe2\x28\xa1", ErrorBadDecryptUTF8},             // Invalid 3 Octet Sequence (in 2nd Octet)
    97  		{"\xe2\x82\x28", ErrorBadDecryptUTF8},             // Invalid 3 Octet Sequence (in 3rd Octet)
    98  		{"\xf0\x90\x8c\xbc", nil},                         // Valid 4 Octet Sequence
    99  		{"\xf0\x28\x8c\xbc", ErrorBadDecryptUTF8},         // Invalid 4 Octet Sequence (in 2nd Octet)
   100  		{"\xf0\x90\x28\xbc", ErrorBadDecryptUTF8},         // Invalid 4 Octet Sequence (in 3rd Octet)
   101  		{"\xf0\x28\x8c\x28", ErrorBadDecryptUTF8},         // Invalid 4 Octet Sequence (in 4th Octet)
   102  		{"\xf8\xa1\xa1\xa1\xa1", ErrorBadDecryptUTF8},     // Valid 5 Octet Sequence (but not Unicode!)
   103  		{"\xfc\xa1\xa1\xa1\xa1\xa1", ErrorBadDecryptUTF8}, // Valid 6 Octet Sequence (but not Unicode!)
   104  	} {
   105  		actual := checkValidString([]byte(test.in))
   106  		assert.Equal(t, actual, test.expected, fmt.Sprintf("in=%q", test.in))
   107  	}
   108  }
   109  
   110  func TestEncodeFileName(t *testing.T) {
   111  	for _, test := range []struct {
   112  		in       string
   113  		expected string
   114  	}{
   115  		{"", ""},
   116  		{"1", "64"},
   117  		{"12", "64p0"},
   118  		{"123", "64p36"},
   119  		{"1234", "64p36d0"},
   120  		{"12345", "64p36d1l"},
   121  		{"123456", "64p36d1l6o"},
   122  		{"1234567", "64p36d1l6org"},
   123  		{"12345678", "64p36d1l6orjg"},
   124  		{"123456789", "64p36d1l6orjge8"},
   125  		{"1234567890", "64p36d1l6orjge9g"},
   126  		{"12345678901", "64p36d1l6orjge9g64"},
   127  		{"123456789012", "64p36d1l6orjge9g64p0"},
   128  		{"1234567890123", "64p36d1l6orjge9g64p36"},
   129  		{"12345678901234", "64p36d1l6orjge9g64p36d0"},
   130  		{"123456789012345", "64p36d1l6orjge9g64p36d1l"},
   131  		{"1234567890123456", "64p36d1l6orjge9g64p36d1l6o"},
   132  	} {
   133  		actual := encodeFileName([]byte(test.in))
   134  		assert.Equal(t, actual, test.expected, fmt.Sprintf("in=%q", test.in))
   135  		recovered, err := decodeFileName(test.expected)
   136  		assert.NoError(t, err)
   137  		assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", test.expected))
   138  		in := strings.ToUpper(test.expected)
   139  		recovered, err = decodeFileName(in)
   140  		assert.NoError(t, err)
   141  		assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", in))
   142  	}
   143  }
   144  
   145  func TestDecodeFileName(t *testing.T) {
   146  	// We've tested decoding the valid ones above, now concentrate on the invalid ones
   147  	for _, test := range []struct {
   148  		in          string
   149  		expectedErr error
   150  	}{
   151  		{"64=", ErrorBadBase32Encoding},
   152  		{"!", base32.CorruptInputError(0)},
   153  		{"hello=hello", base32.CorruptInputError(5)},
   154  	} {
   155  		actual, actualErr := decodeFileName(test.in)
   156  		assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr))
   157  	}
   158  }
   159  
   160  func TestEncryptSegment(t *testing.T) {
   161  	c, _ := newCipher(NameEncryptionStandard, "", "", true)
   162  	for _, test := range []struct {
   163  		in       string
   164  		expected string
   165  	}{
   166  		{"", ""},
   167  		{"1", "p0e52nreeaj0a5ea7s64m4j72s"},
   168  		{"12", "l42g6771hnv3an9cgc8cr2n1ng"},
   169  		{"123", "qgm4avr35m5loi1th53ato71v0"},
   170  		{"1234", "8ivr2e9plj3c3esisjpdisikos"},
   171  		{"12345", "rh9vu63q3o29eqmj4bg6gg7s44"},
   172  		{"123456", "bn717l3alepn75b2fb2ejmi4b4"},
   173  		{"1234567", "n6bo9jmb1qe3b1ogtj5qkf19k8"},
   174  		{"12345678", "u9t24j7uaq94dh5q53m3s4t9ok"},
   175  		{"123456789", "37hn305g6j12d1g0kkrl7ekbs4"},
   176  		{"1234567890", "ot8d91eplaglb62k2b1trm2qv0"},
   177  		{"12345678901", "h168vvrgb53qnrtvvmb378qrcs"},
   178  		{"123456789012", "s3hsdf9e29ithrqbjqu01t8q2s"},
   179  		{"1234567890123", "cf3jimlv1q2oc553mv7s3mh3eo"},
   180  		{"12345678901234", "moq0uqdlqrblrc5pa5u5c7hq9g"},
   181  		{"123456789012345", "eeam3li4rnommi3a762h5n7meg"},
   182  		{"1234567890123456", "mijbj0frqf6ms7frcr6bd9h0env53jv96pjaaoirk7forcgpt70g"},
   183  	} {
   184  		actual := c.encryptSegment(test.in)
   185  		assert.Equal(t, test.expected, actual, fmt.Sprintf("Testing %q", test.in))
   186  		recovered, err := c.decryptSegment(test.expected)
   187  		assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", test.expected))
   188  		assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", test.expected))
   189  		in := strings.ToUpper(test.expected)
   190  		recovered, err = c.decryptSegment(in)
   191  		assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", in))
   192  		assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", in))
   193  	}
   194  }
   195  
   196  func TestDecryptSegment(t *testing.T) {
   197  	// We've tested the forwards above, now concentrate on the errors
   198  	longName := make([]byte, 3328)
   199  	for i := range longName {
   200  		longName[i] = 'a'
   201  	}
   202  	c, _ := newCipher(NameEncryptionStandard, "", "", true)
   203  	for _, test := range []struct {
   204  		in          string
   205  		expectedErr error
   206  	}{
   207  		{"64=", ErrorBadBase32Encoding},
   208  		{"!", base32.CorruptInputError(0)},
   209  		{string(longName), ErrorTooLongAfterDecode},
   210  		{encodeFileName([]byte("a")), ErrorNotAMultipleOfBlocksize},
   211  		{encodeFileName([]byte("123456789abcdef")), ErrorNotAMultipleOfBlocksize},
   212  		{encodeFileName([]byte("123456789abcdef0")), pkcs7.ErrorPaddingTooLong},
   213  		{c.encryptSegment("\x01"), ErrorBadDecryptControlChar},
   214  		{c.encryptSegment("\xc3\x28"), ErrorBadDecryptUTF8},
   215  	} {
   216  		actual, actualErr := c.decryptSegment(test.in)
   217  		assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr))
   218  	}
   219  }
   220  
   221  func TestEncryptFileName(t *testing.T) {
   222  	// First standard mode
   223  	c, _ := newCipher(NameEncryptionStandard, "", "", true)
   224  	assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptFileName("1"))
   225  	assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptFileName("1/12"))
   226  	assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", c.EncryptFileName("1/12/123"))
   227  	// Standard mode with directory name encryption off
   228  	c, _ = newCipher(NameEncryptionStandard, "", "", false)
   229  	assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptFileName("1"))
   230  	assert.Equal(t, "1/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptFileName("1/12"))
   231  	assert.Equal(t, "1/12/qgm4avr35m5loi1th53ato71v0", c.EncryptFileName("1/12/123"))
   232  	// Now off mode
   233  	c, _ = newCipher(NameEncryptionOff, "", "", true)
   234  	assert.Equal(t, "1/12/123.bin", c.EncryptFileName("1/12/123"))
   235  	// Obfuscation mode
   236  	c, _ = newCipher(NameEncryptionObfuscated, "", "", true)
   237  	assert.Equal(t, "49.6/99.23/150.890/53.!!lipps", c.EncryptFileName("1/12/123/!hello"))
   238  	assert.Equal(t, "161.\u00e4", c.EncryptFileName("\u00a1"))
   239  	assert.Equal(t, "160.\u03c2", c.EncryptFileName("\u03a0"))
   240  	// Obfuscation mode with directory name encryption off
   241  	c, _ = newCipher(NameEncryptionObfuscated, "", "", false)
   242  	assert.Equal(t, "1/12/123/53.!!lipps", c.EncryptFileName("1/12/123/!hello"))
   243  	assert.Equal(t, "161.\u00e4", c.EncryptFileName("\u00a1"))
   244  	assert.Equal(t, "160.\u03c2", c.EncryptFileName("\u03a0"))
   245  }
   246  
   247  func TestDecryptFileName(t *testing.T) {
   248  	for _, test := range []struct {
   249  		mode           NameEncryptionMode
   250  		dirNameEncrypt bool
   251  		in             string
   252  		expected       string
   253  		expectedErr    error
   254  	}{
   255  		{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s", "1", nil},
   256  		{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12", nil},
   257  		{NameEncryptionStandard, true, "p0e52nreeAJ0A5EA7S64M4J72S/L42G6771HNv3an9cgc8cr2n1ng", "1/12", nil},
   258  		{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil},
   259  		{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1/qgm4avr35m5loi1th53ato71v0", "", ErrorNotAMultipleOfBlocksize},
   260  		{NameEncryptionStandard, false, "1/12/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil},
   261  		{NameEncryptionOff, true, "1/12/123.bin", "1/12/123", nil},
   262  		{NameEncryptionOff, true, "1/12/123.bix", "", ErrorNotAnEncryptedFile},
   263  		{NameEncryptionOff, true, ".bin", "", ErrorNotAnEncryptedFile},
   264  		{NameEncryptionObfuscated, true, "!.hello", "hello", nil},
   265  		{NameEncryptionObfuscated, true, "hello", "", ErrorNotAnEncryptedFile},
   266  		{NameEncryptionObfuscated, true, "161.\u00e4", "\u00a1", nil},
   267  		{NameEncryptionObfuscated, true, "160.\u03c2", "\u03a0", nil},
   268  		{NameEncryptionObfuscated, false, "1/12/123/53.!!lipps", "1/12/123/!hello", nil},
   269  	} {
   270  		c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt)
   271  		actual, actualErr := c.DecryptFileName(test.in)
   272  		what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
   273  		assert.Equal(t, test.expected, actual, what)
   274  		assert.Equal(t, test.expectedErr, actualErr, what)
   275  	}
   276  }
   277  
   278  func TestEncDecMatches(t *testing.T) {
   279  	for _, test := range []struct {
   280  		mode NameEncryptionMode
   281  		in   string
   282  	}{
   283  		{NameEncryptionStandard, "1/2/3/4"},
   284  		{NameEncryptionOff, "1/2/3/4"},
   285  		{NameEncryptionObfuscated, "1/2/3/4/!hello\u03a0"},
   286  		{NameEncryptionObfuscated, "Avatar The Last Airbender"},
   287  	} {
   288  		c, _ := newCipher(test.mode, "", "", true)
   289  		out, err := c.DecryptFileName(c.EncryptFileName(test.in))
   290  		what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
   291  		assert.Equal(t, out, test.in, what)
   292  		assert.Equal(t, err, nil, what)
   293  	}
   294  }
   295  
   296  func TestEncryptDirName(t *testing.T) {
   297  	// First standard mode
   298  	c, _ := newCipher(NameEncryptionStandard, "", "", true)
   299  	assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptDirName("1"))
   300  	assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptDirName("1/12"))
   301  	assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", c.EncryptDirName("1/12/123"))
   302  	// Standard mode with dir name encryption off
   303  	c, _ = newCipher(NameEncryptionStandard, "", "", false)
   304  	assert.Equal(t, "1/12", c.EncryptDirName("1/12"))
   305  	assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123"))
   306  	// Now off mode
   307  	c, _ = newCipher(NameEncryptionOff, "", "", true)
   308  	assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123"))
   309  }
   310  
   311  func TestDecryptDirName(t *testing.T) {
   312  	for _, test := range []struct {
   313  		mode           NameEncryptionMode
   314  		dirNameEncrypt bool
   315  		in             string
   316  		expected       string
   317  		expectedErr    error
   318  	}{
   319  		{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s", "1", nil},
   320  		{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12", nil},
   321  		{NameEncryptionStandard, true, "p0e52nreeAJ0A5EA7S64M4J72S/L42G6771HNv3an9cgc8cr2n1ng", "1/12", nil},
   322  		{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil},
   323  		{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1/qgm4avr35m5loi1th53ato71v0", "", ErrorNotAMultipleOfBlocksize},
   324  		{NameEncryptionStandard, false, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", nil},
   325  		{NameEncryptionStandard, false, "1/12/123", "1/12/123", nil},
   326  		{NameEncryptionOff, true, "1/12/123.bin", "1/12/123.bin", nil},
   327  		{NameEncryptionOff, true, "1/12/123", "1/12/123", nil},
   328  		{NameEncryptionOff, true, ".bin", ".bin", nil},
   329  	} {
   330  		c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt)
   331  		actual, actualErr := c.DecryptDirName(test.in)
   332  		what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
   333  		assert.Equal(t, test.expected, actual, what)
   334  		assert.Equal(t, test.expectedErr, actualErr, what)
   335  	}
   336  }
   337  
   338  func TestEncryptedSize(t *testing.T) {
   339  	c, _ := newCipher(NameEncryptionStandard, "", "", true)
   340  	for _, test := range []struct {
   341  		in       int64
   342  		expected int64
   343  	}{
   344  		{0, 32},
   345  		{1, 32 + 16 + 1},
   346  		{65536, 32 + 16 + 65536},
   347  		{65537, 32 + 16 + 65536 + 16 + 1},
   348  		{1 << 20, 32 + 16*(16+65536)},
   349  		{(1 << 20) + 65535, 32 + 16*(16+65536) + 16 + 65535},
   350  		{1 << 30, 32 + 16384*(16+65536)},
   351  		{(1 << 40) + 1, 32 + 16777216*(16+65536) + 16 + 1},
   352  	} {
   353  		actual := c.EncryptedSize(test.in)
   354  		assert.Equal(t, test.expected, actual, fmt.Sprintf("Testing %d", test.in))
   355  		recovered, err := c.DecryptedSize(test.expected)
   356  		assert.NoError(t, err, fmt.Sprintf("Testing reverse %d", test.expected))
   357  		assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %d", test.expected))
   358  	}
   359  }
   360  
   361  func TestDecryptedSize(t *testing.T) {
   362  	// Test the errors since we tested the reverse above
   363  	c, _ := newCipher(NameEncryptionStandard, "", "", true)
   364  	for _, test := range []struct {
   365  		in          int64
   366  		expectedErr error
   367  	}{
   368  		{0, ErrorEncryptedFileTooShort},
   369  		{0, ErrorEncryptedFileTooShort},
   370  		{1, ErrorEncryptedFileTooShort},
   371  		{7, ErrorEncryptedFileTooShort},
   372  		{32 + 1, ErrorEncryptedFileBadHeader},
   373  		{32 + 16, ErrorEncryptedFileBadHeader},
   374  		{32 + 16 + 65536 + 1, ErrorEncryptedFileBadHeader},
   375  		{32 + 16 + 65536 + 16, ErrorEncryptedFileBadHeader},
   376  	} {
   377  		_, actualErr := c.DecryptedSize(test.in)
   378  		assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("Testing %d", test.in))
   379  	}
   380  }
   381  
   382  func TestNoncePointer(t *testing.T) {
   383  	var x nonce
   384  	assert.Equal(t, (*[24]byte)(&x), x.pointer())
   385  }
   386  
   387  func TestNonceFromReader(t *testing.T) {
   388  	var x nonce
   389  	buf := bytes.NewBufferString("123456789abcdefghijklmno")
   390  	err := x.fromReader(buf)
   391  	assert.NoError(t, err)
   392  	assert.Equal(t, nonce{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, x)
   393  	buf = bytes.NewBufferString("123456789abcdefghijklmn")
   394  	err = x.fromReader(buf)
   395  	assert.Error(t, err, "short read of nonce")
   396  }
   397  
   398  func TestNonceFromBuf(t *testing.T) {
   399  	var x nonce
   400  	buf := []byte("123456789abcdefghijklmnoXXXXXXXX")
   401  	x.fromBuf(buf)
   402  	assert.Equal(t, nonce{'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'}, x)
   403  	buf = []byte("0123456789abcdefghijklmn")
   404  	x.fromBuf(buf)
   405  	assert.Equal(t, nonce{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}, x)
   406  	buf = []byte("0123456789abcdefghijklm")
   407  	assert.Panics(t, func() { x.fromBuf(buf) })
   408  }
   409  
   410  func TestNonceIncrement(t *testing.T) {
   411  	for _, test := range []struct {
   412  		in  nonce
   413  		out nonce
   414  	}{
   415  		{
   416  			nonce{0x00},
   417  			nonce{0x01},
   418  		},
   419  		{
   420  			nonce{0xFF},
   421  			nonce{0x00, 0x01},
   422  		},
   423  		{
   424  			nonce{0xFF, 0xFF},
   425  			nonce{0x00, 0x00, 0x01},
   426  		},
   427  		{
   428  			nonce{0xFF, 0xFF, 0xFF},
   429  			nonce{0x00, 0x00, 0x00, 0x01},
   430  		},
   431  		{
   432  			nonce{0xFF, 0xFF, 0xFF, 0xFF},
   433  			nonce{0x00, 0x00, 0x00, 0x00, 0x01},
   434  		},
   435  		{
   436  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   437  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   438  		},
   439  		{
   440  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   441  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   442  		},
   443  		{
   444  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   445  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   446  		},
   447  		{
   448  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   449  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   450  		},
   451  		{
   452  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   453  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   454  		},
   455  		{
   456  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   457  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   458  		},
   459  		{
   460  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   461  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   462  		},
   463  		{
   464  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   465  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   466  		},
   467  		{
   468  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   469  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   470  		},
   471  		{
   472  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   473  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   474  		},
   475  		{
   476  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   477  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   478  		},
   479  		{
   480  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   481  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   482  		},
   483  		{
   484  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   485  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   486  		},
   487  		{
   488  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   489  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   490  		},
   491  		{
   492  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   493  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   494  		},
   495  		{
   496  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   497  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   498  		},
   499  		{
   500  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   501  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   502  		},
   503  		{
   504  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   505  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   506  		},
   507  		{
   508  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   509  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   510  		},
   511  		{
   512  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   513  			nonce{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
   514  		},
   515  	} {
   516  		x := test.in
   517  		x.increment()
   518  		assert.Equal(t, test.out, x)
   519  	}
   520  }
   521  
   522  func TestNonceAdd(t *testing.T) {
   523  	for _, test := range []struct {
   524  		add uint64
   525  		in  nonce
   526  		out nonce
   527  	}{
   528  		{
   529  			0x01,
   530  			nonce{0x00},
   531  			nonce{0x01},
   532  		},
   533  		{
   534  			0xFF,
   535  			nonce{0xFF},
   536  			nonce{0xFE, 0x01},
   537  		},
   538  		{
   539  			0xFFFF,
   540  			nonce{0xFF, 0xFF},
   541  			nonce{0xFE, 0xFF, 0x01},
   542  		},
   543  		{
   544  			0xFFFFFF,
   545  			nonce{0xFF, 0xFF, 0xFF},
   546  			nonce{0xFE, 0xFF, 0xFF, 0x01},
   547  		},
   548  		{
   549  			0xFFFFFFFF,
   550  			nonce{0xFF, 0xFF, 0xFF, 0xFF},
   551  			nonce{0xFe, 0xFF, 0xFF, 0xFF, 0x01},
   552  		},
   553  		{
   554  			0xFFFFFFFFFF,
   555  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   556  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01},
   557  		},
   558  		{
   559  			0xFFFFFFFFFFFF,
   560  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   561  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01},
   562  		},
   563  		{
   564  			0xFFFFFFFFFFFFFF,
   565  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   566  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01},
   567  		},
   568  		{
   569  			0xFFFFFFFFFFFFFFFF,
   570  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   571  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01},
   572  		},
   573  		{
   574  			0xFFFFFFFFFFFFFFFF,
   575  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   576  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01},
   577  		},
   578  		{
   579  			0xFFFFFFFFFFFFFFFF,
   580  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   581  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01},
   582  		},
   583  		{
   584  			0xFFFFFFFFFFFFFFFF,
   585  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   586  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01},
   587  		},
   588  		{
   589  			0xFFFFFFFFFFFFFFFF,
   590  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   591  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01},
   592  		},
   593  		{
   594  			0xFFFFFFFFFFFFFFFF,
   595  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   596  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   597  		},
   598  		{
   599  			0xFFFFFFFFFFFFFFFF,
   600  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   601  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   602  		},
   603  		{
   604  			0xFFFFFFFFFFFFFFFF,
   605  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   606  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   607  		},
   608  		{
   609  			0xFFFFFFFFFFFFFFFF,
   610  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   611  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   612  		},
   613  		{
   614  			0xFFFFFFFFFFFFFFFF,
   615  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   616  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   617  		},
   618  		{
   619  			0xFFFFFFFFFFFFFFFF,
   620  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   621  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   622  		},
   623  		{
   624  			0xFFFFFFFFFFFFFFFF,
   625  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   626  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   627  		},
   628  		{
   629  			0xFFFFFFFFFFFFFFFF,
   630  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   631  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   632  		},
   633  		{
   634  			0xFFFFFFFFFFFFFFFF,
   635  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   636  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   637  		},
   638  		{
   639  			0xFFFFFFFFFFFFFFFF,
   640  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   641  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   642  		},
   643  		{
   644  			0xFFFFFFFFFFFFFFFF,
   645  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   646  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
   647  		},
   648  		{
   649  			0xFFFFFFFFFFFFFFFF,
   650  			nonce{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
   651  			nonce{0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
   652  		},
   653  	} {
   654  		x := test.in
   655  		x.add(test.add)
   656  		assert.Equal(t, test.out, x)
   657  	}
   658  }
   659  
   660  // randomSource can read or write a random sequence
   661  type randomSource struct {
   662  	counter int64
   663  	size    int64
   664  }
   665  
   666  func newRandomSource(size int64) *randomSource {
   667  	return &randomSource{
   668  		size: size,
   669  	}
   670  }
   671  
   672  func (r *randomSource) next() byte {
   673  	r.counter++
   674  	return byte(r.counter % 257)
   675  }
   676  
   677  func (r *randomSource) Read(p []byte) (n int, err error) {
   678  	for i := range p {
   679  		if r.counter >= r.size {
   680  			err = io.EOF
   681  			break
   682  		}
   683  		p[i] = r.next()
   684  		n++
   685  	}
   686  	return n, err
   687  }
   688  
   689  func (r *randomSource) Write(p []byte) (n int, err error) {
   690  	for i := range p {
   691  		if p[i] != r.next() {
   692  			return 0, errors.Errorf("Error in stream at %d", r.counter)
   693  		}
   694  	}
   695  	return len(p), nil
   696  }
   697  
   698  func (r *randomSource) Close() error { return nil }
   699  
   700  // Check interfaces
   701  var (
   702  	_ io.ReadCloser  = (*randomSource)(nil)
   703  	_ io.WriteCloser = (*randomSource)(nil)
   704  )
   705  
   706  // Test test infrastructure first!
   707  func TestRandomSource(t *testing.T) {
   708  	source := newRandomSource(1E8)
   709  	sink := newRandomSource(1E8)
   710  	n, err := io.Copy(sink, source)
   711  	assert.NoError(t, err)
   712  	assert.Equal(t, int64(1E8), n)
   713  
   714  	source = newRandomSource(1E8)
   715  	buf := make([]byte, 16)
   716  	_, _ = source.Read(buf)
   717  	sink = newRandomSource(1E8)
   718  	_, err = io.Copy(sink, source)
   719  	assert.Error(t, err, "Error in stream")
   720  }
   721  
   722  type zeroes struct{}
   723  
   724  func (z *zeroes) Read(p []byte) (n int, err error) {
   725  	for i := range p {
   726  		p[i] = 0
   727  		n++
   728  	}
   729  	return n, nil
   730  }
   731  
   732  // Test encrypt decrypt with different buffer sizes
   733  func testEncryptDecrypt(t *testing.T, bufSize int, copySize int64) {
   734  	c, err := newCipher(NameEncryptionStandard, "", "", true)
   735  	assert.NoError(t, err)
   736  	c.cryptoRand = &zeroes{} // zero out the nonce
   737  	buf := make([]byte, bufSize)
   738  	source := newRandomSource(copySize)
   739  	encrypted, err := c.newEncrypter(source, nil)
   740  	assert.NoError(t, err)
   741  	decrypted, err := c.newDecrypter(ioutil.NopCloser(encrypted))
   742  	assert.NoError(t, err)
   743  	sink := newRandomSource(copySize)
   744  	n, err := io.CopyBuffer(sink, decrypted, buf)
   745  	assert.NoError(t, err)
   746  	assert.Equal(t, copySize, n)
   747  	blocks := copySize / blockSize
   748  	if (copySize % blockSize) != 0 {
   749  		blocks++
   750  	}
   751  	var expectedNonce = nonce{byte(blocks), byte(blocks >> 8), byte(blocks >> 16), byte(blocks >> 32)}
   752  	assert.Equal(t, expectedNonce, encrypted.nonce)
   753  	assert.Equal(t, expectedNonce, decrypted.nonce)
   754  }
   755  
   756  func TestEncryptDecrypt1(t *testing.T) {
   757  	testEncryptDecrypt(t, 1, 1E7)
   758  }
   759  
   760  func TestEncryptDecrypt32(t *testing.T) {
   761  	testEncryptDecrypt(t, 32, 1E8)
   762  }
   763  
   764  func TestEncryptDecrypt4096(t *testing.T) {
   765  	testEncryptDecrypt(t, 4096, 1E8)
   766  }
   767  
   768  func TestEncryptDecrypt65536(t *testing.T) {
   769  	testEncryptDecrypt(t, 65536, 1E8)
   770  }
   771  
   772  func TestEncryptDecrypt65537(t *testing.T) {
   773  	testEncryptDecrypt(t, 65537, 1E8)
   774  }
   775  
   776  var (
   777  	file0 = []byte{
   778  		0x52, 0x43, 0x4c, 0x4f, 0x4e, 0x45, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
   779  		0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
   780  	}
   781  	file1 = []byte{
   782  		0x52, 0x43, 0x4c, 0x4f, 0x4e, 0x45, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
   783  		0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
   784  		0x09, 0x5b, 0x44, 0x6c, 0xd6, 0x23, 0x7b, 0xbc, 0xb0, 0x8d, 0x09, 0xfb, 0x52, 0x4c, 0xe5, 0x65,
   785  		0xAA,
   786  	}
   787  	file16 = []byte{
   788  		0x52, 0x43, 0x4c, 0x4f, 0x4e, 0x45, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
   789  		0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
   790  		0xb9, 0xc4, 0x55, 0x2a, 0x27, 0x10, 0x06, 0x29, 0x18, 0x96, 0x0a, 0x3e, 0x60, 0x8c, 0x29, 0xb9,
   791  		0xaa, 0x8a, 0x5e, 0x1e, 0x16, 0x5b, 0x6d, 0x07, 0x5d, 0xe4, 0xe9, 0xbb, 0x36, 0x7f, 0xd6, 0xd4,
   792  	}
   793  )
   794  
   795  func TestEncryptData(t *testing.T) {
   796  	for _, test := range []struct {
   797  		in       []byte
   798  		expected []byte
   799  	}{
   800  		{[]byte{}, file0},
   801  		{[]byte{1}, file1},
   802  		{[]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, file16},
   803  	} {
   804  		c, err := newCipher(NameEncryptionStandard, "", "", true)
   805  		assert.NoError(t, err)
   806  		c.cryptoRand = newRandomSource(1E8) // nodge the crypto rand generator
   807  
   808  		// Check encode works
   809  		buf := bytes.NewBuffer(test.in)
   810  		encrypted, err := c.EncryptData(buf)
   811  		assert.NoError(t, err)
   812  		out, err := ioutil.ReadAll(encrypted)
   813  		assert.NoError(t, err)
   814  		assert.Equal(t, test.expected, out)
   815  
   816  		// Check we can decode the data properly too...
   817  		buf = bytes.NewBuffer(out)
   818  		decrypted, err := c.DecryptData(ioutil.NopCloser(buf))
   819  		assert.NoError(t, err)
   820  		out, err = ioutil.ReadAll(decrypted)
   821  		assert.NoError(t, err)
   822  		assert.Equal(t, test.in, out)
   823  	}
   824  }
   825  
   826  func TestNewEncrypter(t *testing.T) {
   827  	c, err := newCipher(NameEncryptionStandard, "", "", true)
   828  	assert.NoError(t, err)
   829  	c.cryptoRand = newRandomSource(1E8) // nodge the crypto rand generator
   830  
   831  	z := &zeroes{}
   832  
   833  	fh, err := c.newEncrypter(z, nil)
   834  	assert.NoError(t, err)
   835  	assert.Equal(t, nonce{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, fh.nonce)
   836  	assert.Equal(t, []byte{'R', 'C', 'L', 'O', 'N', 'E', 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}, fh.buf[:32])
   837  
   838  	// Test error path
   839  	c.cryptoRand = bytes.NewBufferString("123456789abcdefghijklmn")
   840  	fh, err = c.newEncrypter(z, nil)
   841  	assert.Nil(t, fh)
   842  	assert.Error(t, err, "short read of nonce")
   843  
   844  }
   845  
   846  // Test the stream returning 0, io.ErrUnexpectedEOF - this used to
   847  // cause a fatal loop
   848  func TestNewEncrypterErrUnexpectedEOF(t *testing.T) {
   849  	c, err := newCipher(NameEncryptionStandard, "", "", true)
   850  	assert.NoError(t, err)
   851  
   852  	in := &errorReader{io.ErrUnexpectedEOF}
   853  	fh, err := c.newEncrypter(in, nil)
   854  	assert.NoError(t, err)
   855  
   856  	n, err := io.CopyN(ioutil.Discard, fh, 1E6)
   857  	assert.Equal(t, io.ErrUnexpectedEOF, err)
   858  	assert.Equal(t, int64(32), n)
   859  }
   860  
   861  type errorReader struct {
   862  	err error
   863  }
   864  
   865  func (er errorReader) Read(p []byte) (n int, err error) {
   866  	return 0, er.err
   867  }
   868  
   869  type closeDetector struct {
   870  	io.Reader
   871  	closed int
   872  }
   873  
   874  func newCloseDetector(in io.Reader) *closeDetector {
   875  	return &closeDetector{
   876  		Reader: in,
   877  	}
   878  }
   879  
   880  func (c *closeDetector) Close() error {
   881  	c.closed++
   882  	return nil
   883  }
   884  
   885  func TestNewDecrypter(t *testing.T) {
   886  	c, err := newCipher(NameEncryptionStandard, "", "", true)
   887  	assert.NoError(t, err)
   888  	c.cryptoRand = newRandomSource(1E8) // nodge the crypto rand generator
   889  
   890  	cd := newCloseDetector(bytes.NewBuffer(file0))
   891  	fh, err := c.newDecrypter(cd)
   892  	assert.NoError(t, err)
   893  	// check nonce is in place
   894  	assert.Equal(t, file0[8:32], fh.nonce[:])
   895  	assert.Equal(t, 0, cd.closed)
   896  
   897  	// Test error paths
   898  	for i := range file0 {
   899  		cd := newCloseDetector(bytes.NewBuffer(file0[:i]))
   900  		fh, err = c.newDecrypter(cd)
   901  		assert.Nil(t, fh)
   902  		assert.Error(t, err, ErrorEncryptedFileTooShort.Error())
   903  		assert.Equal(t, 1, cd.closed)
   904  	}
   905  
   906  	er := &errorReader{errors.New("potato")}
   907  	cd = newCloseDetector(er)
   908  	fh, err = c.newDecrypter(cd)
   909  	assert.Nil(t, fh)
   910  	assert.Error(t, err, "potato")
   911  	assert.Equal(t, 1, cd.closed)
   912  
   913  	// bad magic
   914  	file0copy := make([]byte, len(file0))
   915  	copy(file0copy, file0)
   916  	for i := range fileMagic {
   917  		file0copy[i] ^= 0x1
   918  		cd := newCloseDetector(bytes.NewBuffer(file0copy))
   919  		fh, err := c.newDecrypter(cd)
   920  		assert.Nil(t, fh)
   921  		assert.Error(t, err, ErrorEncryptedBadMagic.Error())
   922  		file0copy[i] ^= 0x1
   923  		assert.Equal(t, 1, cd.closed)
   924  	}
   925  }
   926  
   927  // Test the stream returning 0, io.ErrUnexpectedEOF
   928  func TestNewDecrypterErrUnexpectedEOF(t *testing.T) {
   929  	c, err := newCipher(NameEncryptionStandard, "", "", true)
   930  	assert.NoError(t, err)
   931  
   932  	in2 := &errorReader{io.ErrUnexpectedEOF}
   933  	in1 := bytes.NewBuffer(file16)
   934  	in := ioutil.NopCloser(io.MultiReader(in1, in2))
   935  
   936  	fh, err := c.newDecrypter(in)
   937  	assert.NoError(t, err)
   938  
   939  	n, err := io.CopyN(ioutil.Discard, fh, 1E6)
   940  	assert.Equal(t, io.ErrUnexpectedEOF, err)
   941  	assert.Equal(t, int64(16), n)
   942  }
   943  
   944  func TestNewDecrypterSeekLimit(t *testing.T) {
   945  	c, err := newCipher(NameEncryptionStandard, "", "", true)
   946  	assert.NoError(t, err)
   947  	c.cryptoRand = &zeroes{} // nodge the crypto rand generator
   948  
   949  	// Make random data
   950  	const dataSize = 150000
   951  	plaintext, err := ioutil.ReadAll(newRandomSource(dataSize))
   952  	assert.NoError(t, err)
   953  
   954  	// Encrypt the data
   955  	buf := bytes.NewBuffer(plaintext)
   956  	encrypted, err := c.EncryptData(buf)
   957  	assert.NoError(t, err)
   958  	ciphertext, err := ioutil.ReadAll(encrypted)
   959  	assert.NoError(t, err)
   960  
   961  	trials := []int{0, 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65,
   962  		127, 128, 129, 255, 256, 257, 511, 512, 513, 1023, 1024, 1025, 2047, 2048, 2049,
   963  		4095, 4096, 4097, 8191, 8192, 8193, 16383, 16384, 16385, 32767, 32768, 32769,
   964  		65535, 65536, 65537, 131071, 131072, 131073, dataSize - 1, dataSize}
   965  	limits := []int{-1, 0, 1, 65535, 65536, 65537, 131071, 131072, 131073}
   966  
   967  	// Open stream with a seek of underlyingOffset
   968  	var reader io.ReadCloser
   969  	open := func(ctx context.Context, underlyingOffset, underlyingLimit int64) (io.ReadCloser, error) {
   970  		end := len(ciphertext)
   971  		if underlyingLimit >= 0 {
   972  			end = int(underlyingOffset + underlyingLimit)
   973  			if end > len(ciphertext) {
   974  				end = len(ciphertext)
   975  			}
   976  		}
   977  		reader = ioutil.NopCloser(bytes.NewBuffer(ciphertext[int(underlyingOffset):end]))
   978  		return reader, nil
   979  	}
   980  
   981  	inBlock := make([]byte, dataSize)
   982  
   983  	// Check the seek worked by reading a block and checking it
   984  	// against what it should be
   985  	check := func(rc io.Reader, offset, limit int) {
   986  		n, err := io.ReadFull(rc, inBlock)
   987  		if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
   988  			require.NoError(t, err)
   989  		}
   990  		seekedDecrypted := inBlock[:n]
   991  
   992  		what := fmt.Sprintf("offset = %d, limit = %d", offset, limit)
   993  		if limit >= 0 {
   994  			assert.Equal(t, limit, n, what)
   995  		}
   996  		require.Equal(t, plaintext[offset:offset+n], seekedDecrypted, what)
   997  
   998  		// We should have completely emptied the reader at this point
   999  		n, err = reader.Read(inBlock)
  1000  		assert.Equal(t, io.EOF, err)
  1001  		assert.Equal(t, 0, n)
  1002  	}
  1003  
  1004  	// Now try decoding it with a open/seek
  1005  	for _, offset := range trials {
  1006  		for _, limit := range limits {
  1007  			if offset+limit > len(plaintext) {
  1008  				continue
  1009  			}
  1010  			rc, err := c.DecryptDataSeek(context.Background(), open, int64(offset), int64(limit))
  1011  			assert.NoError(t, err)
  1012  
  1013  			check(rc, offset, limit)
  1014  		}
  1015  	}
  1016  
  1017  	// Try decoding it with a single open and lots of seeks
  1018  	fh, err := c.DecryptDataSeek(context.Background(), open, 0, -1)
  1019  	assert.NoError(t, err)
  1020  	for _, offset := range trials {
  1021  		for _, limit := range limits {
  1022  			if offset+limit > len(plaintext) {
  1023  				continue
  1024  			}
  1025  			_, err := fh.RangeSeek(context.Background(), int64(offset), io.SeekStart, int64(limit))
  1026  			assert.NoError(t, err)
  1027  
  1028  			check(fh, offset, limit)
  1029  		}
  1030  	}
  1031  
  1032  	// Do some checks on the open callback
  1033  	for _, test := range []struct {
  1034  		offset, limit         int64
  1035  		wantOffset, wantLimit int64
  1036  	}{
  1037  		// unlimited
  1038  		{0, -1, int64(fileHeaderSize), -1},
  1039  		{1, -1, int64(fileHeaderSize), -1},
  1040  		{blockDataSize - 1, -1, int64(fileHeaderSize), -1},
  1041  		{blockDataSize, -1, int64(fileHeaderSize) + blockSize, -1},
  1042  		{blockDataSize + 1, -1, int64(fileHeaderSize) + blockSize, -1},
  1043  		// limit=1
  1044  		{0, 1, int64(fileHeaderSize), blockSize},
  1045  		{1, 1, int64(fileHeaderSize), blockSize},
  1046  		{blockDataSize - 1, 1, int64(fileHeaderSize), blockSize},
  1047  		{blockDataSize, 1, int64(fileHeaderSize) + blockSize, blockSize},
  1048  		{blockDataSize + 1, 1, int64(fileHeaderSize) + blockSize, blockSize},
  1049  		// limit=100
  1050  		{0, 100, int64(fileHeaderSize), blockSize},
  1051  		{1, 100, int64(fileHeaderSize), blockSize},
  1052  		{blockDataSize - 1, 100, int64(fileHeaderSize), 2 * blockSize},
  1053  		{blockDataSize, 100, int64(fileHeaderSize) + blockSize, blockSize},
  1054  		{blockDataSize + 1, 100, int64(fileHeaderSize) + blockSize, blockSize},
  1055  		// limit=blockDataSize-1
  1056  		{0, blockDataSize - 1, int64(fileHeaderSize), blockSize},
  1057  		{1, blockDataSize - 1, int64(fileHeaderSize), blockSize},
  1058  		{blockDataSize - 1, blockDataSize - 1, int64(fileHeaderSize), 2 * blockSize},
  1059  		{blockDataSize, blockDataSize - 1, int64(fileHeaderSize) + blockSize, blockSize},
  1060  		{blockDataSize + 1, blockDataSize - 1, int64(fileHeaderSize) + blockSize, blockSize},
  1061  		// limit=blockDataSize
  1062  		{0, blockDataSize, int64(fileHeaderSize), blockSize},
  1063  		{1, blockDataSize, int64(fileHeaderSize), 2 * blockSize},
  1064  		{blockDataSize - 1, blockDataSize, int64(fileHeaderSize), 2 * blockSize},
  1065  		{blockDataSize, blockDataSize, int64(fileHeaderSize) + blockSize, blockSize},
  1066  		{blockDataSize + 1, blockDataSize, int64(fileHeaderSize) + blockSize, 2 * blockSize},
  1067  		// limit=blockDataSize+1
  1068  		{0, blockDataSize + 1, int64(fileHeaderSize), 2 * blockSize},
  1069  		{1, blockDataSize + 1, int64(fileHeaderSize), 2 * blockSize},
  1070  		{blockDataSize - 1, blockDataSize + 1, int64(fileHeaderSize), 2 * blockSize},
  1071  		{blockDataSize, blockDataSize + 1, int64(fileHeaderSize) + blockSize, 2 * blockSize},
  1072  		{blockDataSize + 1, blockDataSize + 1, int64(fileHeaderSize) + blockSize, 2 * blockSize},
  1073  	} {
  1074  		what := fmt.Sprintf("offset = %d, limit = %d", test.offset, test.limit)
  1075  		callCount := 0
  1076  		testOpen := func(ctx context.Context, underlyingOffset, underlyingLimit int64) (io.ReadCloser, error) {
  1077  			switch callCount {
  1078  			case 0:
  1079  				assert.Equal(t, int64(0), underlyingOffset, what)
  1080  				assert.Equal(t, int64(-1), underlyingLimit, what)
  1081  			case 1:
  1082  				assert.Equal(t, test.wantOffset, underlyingOffset, what)
  1083  				assert.Equal(t, test.wantLimit, underlyingLimit, what)
  1084  			default:
  1085  				t.Errorf("Too many calls %d for %s", callCount+1, what)
  1086  			}
  1087  			callCount++
  1088  			return open(ctx, underlyingOffset, underlyingLimit)
  1089  		}
  1090  		fh, err := c.DecryptDataSeek(context.Background(), testOpen, 0, -1)
  1091  		assert.NoError(t, err)
  1092  		gotOffset, err := fh.RangeSeek(context.Background(), test.offset, io.SeekStart, test.limit)
  1093  		assert.NoError(t, err)
  1094  		assert.Equal(t, gotOffset, test.offset)
  1095  	}
  1096  }
  1097  
  1098  func TestDecrypterCalculateUnderlying(t *testing.T) {
  1099  	for _, test := range []struct {
  1100  		offset, limit           int64
  1101  		wantOffset, wantLimit   int64
  1102  		wantDiscard, wantBlocks int64
  1103  	}{
  1104  		// unlimited
  1105  		{0, -1, int64(fileHeaderSize), -1, 0, 0},
  1106  		{1, -1, int64(fileHeaderSize), -1, 1, 0},
  1107  		{blockDataSize - 1, -1, int64(fileHeaderSize), -1, blockDataSize - 1, 0},
  1108  		{blockDataSize, -1, int64(fileHeaderSize) + blockSize, -1, 0, 1},
  1109  		{blockDataSize + 1, -1, int64(fileHeaderSize) + blockSize, -1, 1, 1},
  1110  		// limit=1
  1111  		{0, 1, int64(fileHeaderSize), blockSize, 0, 0},
  1112  		{1, 1, int64(fileHeaderSize), blockSize, 1, 0},
  1113  		{blockDataSize - 1, 1, int64(fileHeaderSize), blockSize, blockDataSize - 1, 0},
  1114  		{blockDataSize, 1, int64(fileHeaderSize) + blockSize, blockSize, 0, 1},
  1115  		{blockDataSize + 1, 1, int64(fileHeaderSize) + blockSize, blockSize, 1, 1},
  1116  		// limit=100
  1117  		{0, 100, int64(fileHeaderSize), blockSize, 0, 0},
  1118  		{1, 100, int64(fileHeaderSize), blockSize, 1, 0},
  1119  		{blockDataSize - 1, 100, int64(fileHeaderSize), 2 * blockSize, blockDataSize - 1, 0},
  1120  		{blockDataSize, 100, int64(fileHeaderSize) + blockSize, blockSize, 0, 1},
  1121  		{blockDataSize + 1, 100, int64(fileHeaderSize) + blockSize, blockSize, 1, 1},
  1122  		// limit=blockDataSize-1
  1123  		{0, blockDataSize - 1, int64(fileHeaderSize), blockSize, 0, 0},
  1124  		{1, blockDataSize - 1, int64(fileHeaderSize), blockSize, 1, 0},
  1125  		{blockDataSize - 1, blockDataSize - 1, int64(fileHeaderSize), 2 * blockSize, blockDataSize - 1, 0},
  1126  		{blockDataSize, blockDataSize - 1, int64(fileHeaderSize) + blockSize, blockSize, 0, 1},
  1127  		{blockDataSize + 1, blockDataSize - 1, int64(fileHeaderSize) + blockSize, blockSize, 1, 1},
  1128  		// limit=blockDataSize
  1129  		{0, blockDataSize, int64(fileHeaderSize), blockSize, 0, 0},
  1130  		{1, blockDataSize, int64(fileHeaderSize), 2 * blockSize, 1, 0},
  1131  		{blockDataSize - 1, blockDataSize, int64(fileHeaderSize), 2 * blockSize, blockDataSize - 1, 0},
  1132  		{blockDataSize, blockDataSize, int64(fileHeaderSize) + blockSize, blockSize, 0, 1},
  1133  		{blockDataSize + 1, blockDataSize, int64(fileHeaderSize) + blockSize, 2 * blockSize, 1, 1},
  1134  		// limit=blockDataSize+1
  1135  		{0, blockDataSize + 1, int64(fileHeaderSize), 2 * blockSize, 0, 0},
  1136  		{1, blockDataSize + 1, int64(fileHeaderSize), 2 * blockSize, 1, 0},
  1137  		{blockDataSize - 1, blockDataSize + 1, int64(fileHeaderSize), 2 * blockSize, blockDataSize - 1, 0},
  1138  		{blockDataSize, blockDataSize + 1, int64(fileHeaderSize) + blockSize, 2 * blockSize, 0, 1},
  1139  		{blockDataSize + 1, blockDataSize + 1, int64(fileHeaderSize) + blockSize, 2 * blockSize, 1, 1},
  1140  	} {
  1141  		what := fmt.Sprintf("offset = %d, limit = %d", test.offset, test.limit)
  1142  		underlyingOffset, underlyingLimit, discard, blocks := calculateUnderlying(test.offset, test.limit)
  1143  		assert.Equal(t, test.wantOffset, underlyingOffset, what)
  1144  		assert.Equal(t, test.wantLimit, underlyingLimit, what)
  1145  		assert.Equal(t, test.wantDiscard, discard, what)
  1146  		assert.Equal(t, test.wantBlocks, blocks, what)
  1147  	}
  1148  }
  1149  
  1150  func TestDecrypterRead(t *testing.T) {
  1151  	c, err := newCipher(NameEncryptionStandard, "", "", true)
  1152  	assert.NoError(t, err)
  1153  
  1154  	// Test truncating the file at each possible point
  1155  	for i := 0; i < len(file16)-1; i++ {
  1156  		what := fmt.Sprintf("truncating to %d/%d", i, len(file16))
  1157  		cd := newCloseDetector(bytes.NewBuffer(file16[:i]))
  1158  		fh, err := c.newDecrypter(cd)
  1159  		if i < fileHeaderSize {
  1160  			assert.EqualError(t, err, ErrorEncryptedFileTooShort.Error(), what)
  1161  			continue
  1162  		}
  1163  		if err != nil {
  1164  			assert.NoError(t, err, what)
  1165  			continue
  1166  		}
  1167  		_, err = ioutil.ReadAll(fh)
  1168  		var expectedErr error
  1169  		switch {
  1170  		case i == fileHeaderSize:
  1171  			// This would normally produce an error *except* on the first block
  1172  			expectedErr = nil
  1173  		default:
  1174  			expectedErr = io.ErrUnexpectedEOF
  1175  		}
  1176  		if expectedErr != nil {
  1177  			assert.EqualError(t, err, expectedErr.Error(), what)
  1178  		} else {
  1179  			assert.NoError(t, err, what)
  1180  		}
  1181  		assert.Equal(t, 0, cd.closed, what)
  1182  	}
  1183  
  1184  	// Test producing an error on the file on Read the underlying file
  1185  	in1 := bytes.NewBuffer(file1)
  1186  	in2 := &errorReader{errors.New("potato")}
  1187  	in := io.MultiReader(in1, in2)
  1188  	cd := newCloseDetector(in)
  1189  	fh, err := c.newDecrypter(cd)
  1190  	assert.NoError(t, err)
  1191  	_, err = ioutil.ReadAll(fh)
  1192  	assert.Error(t, err, "potato")
  1193  	assert.Equal(t, 0, cd.closed)
  1194  
  1195  	// Test corrupting the input
  1196  	// shouldn't be able to corrupt any byte without some sort of error
  1197  	file16copy := make([]byte, len(file16))
  1198  	copy(file16copy, file16)
  1199  	for i := range file16copy {
  1200  		file16copy[i] ^= 0xFF
  1201  		fh, err := c.newDecrypter(ioutil.NopCloser(bytes.NewBuffer(file16copy)))
  1202  		if i < fileMagicSize {
  1203  			assert.Error(t, err, ErrorEncryptedBadMagic.Error())
  1204  			assert.Nil(t, fh)
  1205  		} else {
  1206  			assert.NoError(t, err)
  1207  			_, err = ioutil.ReadAll(fh)
  1208  			assert.Error(t, err, ErrorEncryptedFileBadHeader.Error())
  1209  		}
  1210  		file16copy[i] ^= 0xFF
  1211  	}
  1212  }
  1213  
  1214  func TestDecrypterClose(t *testing.T) {
  1215  	c, err := newCipher(NameEncryptionStandard, "", "", true)
  1216  	assert.NoError(t, err)
  1217  
  1218  	cd := newCloseDetector(bytes.NewBuffer(file16))
  1219  	fh, err := c.newDecrypter(cd)
  1220  	assert.NoError(t, err)
  1221  	assert.Equal(t, 0, cd.closed)
  1222  
  1223  	// close before reading
  1224  	assert.Equal(t, nil, fh.err)
  1225  	err = fh.Close()
  1226  	assert.NoError(t, err)
  1227  	assert.Equal(t, ErrorFileClosed, fh.err)
  1228  	assert.Equal(t, 1, cd.closed)
  1229  
  1230  	// double close
  1231  	err = fh.Close()
  1232  	assert.Error(t, err, ErrorFileClosed.Error())
  1233  	assert.Equal(t, 1, cd.closed)
  1234  
  1235  	// try again reading the file this time
  1236  	cd = newCloseDetector(bytes.NewBuffer(file1))
  1237  	fh, err = c.newDecrypter(cd)
  1238  	assert.NoError(t, err)
  1239  	assert.Equal(t, 0, cd.closed)
  1240  
  1241  	// close after reading
  1242  	out, err := ioutil.ReadAll(fh)
  1243  	assert.NoError(t, err)
  1244  	assert.Equal(t, []byte{1}, out)
  1245  	assert.Equal(t, io.EOF, fh.err)
  1246  	err = fh.Close()
  1247  	assert.NoError(t, err)
  1248  	assert.Equal(t, ErrorFileClosed, fh.err)
  1249  	assert.Equal(t, 1, cd.closed)
  1250  }
  1251  
  1252  func TestPutGetBlock(t *testing.T) {
  1253  	c, err := newCipher(NameEncryptionStandard, "", "", true)
  1254  	assert.NoError(t, err)
  1255  
  1256  	block := c.getBlock()
  1257  	c.putBlock(block)
  1258  	c.putBlock(block)
  1259  
  1260  	assert.Panics(t, func() { c.putBlock(block[:len(block)-1]) })
  1261  }
  1262  
  1263  func TestKey(t *testing.T) {
  1264  	c, err := newCipher(NameEncryptionStandard, "", "", true)
  1265  	assert.NoError(t, err)
  1266  
  1267  	// Check zero keys OK
  1268  	assert.Equal(t, [32]byte{}, c.dataKey)
  1269  	assert.Equal(t, [32]byte{}, c.nameKey)
  1270  	assert.Equal(t, [16]byte{}, c.nameTweak)
  1271  
  1272  	require.NoError(t, c.Key("potato", ""))
  1273  	assert.Equal(t, [32]byte{0x74, 0x55, 0xC7, 0x1A, 0xB1, 0x7C, 0x86, 0x5B, 0x84, 0x71, 0xF4, 0x7B, 0x79, 0xAC, 0xB0, 0x7E, 0xB3, 0x1D, 0x56, 0x78, 0xB8, 0x0C, 0x7E, 0x2E, 0xAF, 0x4F, 0xC8, 0x06, 0x6A, 0x9E, 0xE4, 0x68}, c.dataKey)
  1274  	assert.Equal(t, [32]byte{0x76, 0x5D, 0xA2, 0x7A, 0xB1, 0x5D, 0x77, 0xF9, 0x57, 0x96, 0x71, 0x1F, 0x7B, 0x93, 0xAD, 0x63, 0xBB, 0xB4, 0x84, 0x07, 0x2E, 0x71, 0x80, 0xA8, 0xD1, 0x7A, 0x9B, 0xBE, 0xC1, 0x42, 0x70, 0xD0}, c.nameKey)
  1275  	assert.Equal(t, [16]byte{0xC1, 0x8D, 0x59, 0x32, 0xF5, 0x5B, 0x28, 0x28, 0xC5, 0xE1, 0xE8, 0x72, 0x15, 0x52, 0x03, 0x10}, c.nameTweak)
  1276  
  1277  	require.NoError(t, c.Key("Potato", ""))
  1278  	assert.Equal(t, [32]byte{0xAE, 0xEA, 0x6A, 0xD3, 0x47, 0xDF, 0x75, 0xB9, 0x63, 0xCE, 0x12, 0xF5, 0x76, 0x23, 0xE9, 0x46, 0xD4, 0x2E, 0xD8, 0xBF, 0x3E, 0x92, 0x8B, 0x39, 0x24, 0x37, 0x94, 0x13, 0x3E, 0x5E, 0xF7, 0x5E}, c.dataKey)
  1279  	assert.Equal(t, [32]byte{0x54, 0xF7, 0x02, 0x6E, 0x8A, 0xFC, 0x56, 0x0A, 0x86, 0x63, 0x6A, 0xAB, 0x2C, 0x9C, 0x51, 0x62, 0xE5, 0x1A, 0x12, 0x23, 0x51, 0x83, 0x6E, 0xAF, 0x50, 0x42, 0x0F, 0x98, 0x1C, 0x86, 0x0A, 0x19}, c.nameKey)
  1280  	assert.Equal(t, [16]byte{0xF8, 0xC1, 0xB6, 0x27, 0x2D, 0x52, 0x9B, 0x4A, 0x8F, 0xDA, 0xEB, 0x42, 0x4A, 0x28, 0xDD, 0xF3}, c.nameTweak)
  1281  
  1282  	require.NoError(t, c.Key("potato", "sausage"))
  1283  	assert.Equal(t, [32]uint8{0x8e, 0x9b, 0x6b, 0x99, 0xf8, 0x69, 0x4, 0x67, 0xa0, 0x71, 0xf9, 0xcb, 0x92, 0xd0, 0xaa, 0x78, 0x7f, 0x8f, 0xf1, 0x78, 0xbe, 0xc9, 0x6f, 0x99, 0x9f, 0xd5, 0x20, 0x6e, 0x64, 0x4a, 0x1b, 0x50}, c.dataKey)
  1284  	assert.Equal(t, [32]uint8{0x3e, 0xa9, 0x5e, 0xf6, 0x81, 0x78, 0x2d, 0xc9, 0xd9, 0x95, 0x5d, 0x22, 0x5b, 0xfd, 0x44, 0x2c, 0x6f, 0x5d, 0x68, 0x97, 0xb0, 0x29, 0x1, 0x5c, 0x6f, 0x46, 0x2e, 0x2a, 0x9d, 0xae, 0x2c, 0xe3}, c.nameKey)
  1285  	assert.Equal(t, [16]uint8{0xf1, 0x7f, 0xd7, 0x14, 0x1d, 0x65, 0x27, 0x4f, 0x36, 0x3f, 0xc2, 0xa0, 0x4d, 0xd2, 0x14, 0x8a}, c.nameTweak)
  1286  
  1287  	require.NoError(t, c.Key("potato", "Sausage"))
  1288  	assert.Equal(t, [32]uint8{0xda, 0x81, 0x8c, 0x67, 0xef, 0x11, 0xf, 0xc8, 0xd5, 0xc8, 0x62, 0x4b, 0x7f, 0xe2, 0x9e, 0x35, 0x35, 0xb0, 0x8d, 0x79, 0x84, 0x89, 0xac, 0xcb, 0xa0, 0xff, 0x2, 0x72, 0x3, 0x1a, 0x5e, 0x64}, c.dataKey)
  1289  	assert.Equal(t, [32]uint8{0x2, 0x81, 0x7e, 0x7b, 0xea, 0x99, 0x81, 0x5a, 0xd0, 0x2d, 0xb9, 0x64, 0x48, 0xb0, 0x28, 0x27, 0x7c, 0x20, 0xb4, 0xd4, 0xa4, 0x68, 0xad, 0x4e, 0x5c, 0x29, 0xf, 0x79, 0xef, 0xee, 0xdb, 0x3b}, c.nameKey)
  1290  	assert.Equal(t, [16]uint8{0x9a, 0xb5, 0xb, 0x3d, 0xcb, 0x60, 0x59, 0x55, 0xa5, 0x4d, 0xe6, 0xb6, 0x47, 0x3, 0x23, 0xe2}, c.nameTweak)
  1291  
  1292  	require.NoError(t, c.Key("", ""))
  1293  	assert.Equal(t, [32]byte{}, c.dataKey)
  1294  	assert.Equal(t, [32]byte{}, c.nameKey)
  1295  	assert.Equal(t, [16]byte{}, c.nameTweak)
  1296  }