github.com/trustbloc/kms-go@v1.1.2/secretlock/local/masterlock/pbkdf2/master_secret_lock_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 SPDX-License-Identifier: Apache-2.0 4 */ 5 6 package pbkdf2 7 8 import ( 9 "crypto/rand" 10 "crypto/sha256" 11 "crypto/sha512" 12 "hash" 13 "testing" 14 15 "github.com/google/tink/go/subtle/random" 16 "github.com/stretchr/testify/require" 17 18 "github.com/trustbloc/kms-go/spi/secretlock" 19 ) 20 21 func TestMasterLock(t *testing.T) { 22 keySize := sha256.New().Size() 23 testKey := random.GetRandomBytes(uint32(keySize)) 24 goodPassphrase := "somepassphrase" 25 defIter := 4096 26 27 salt := make([]byte, keySize) 28 _, err := rand.Read(salt) 29 require.NoError(t, err) 30 31 mkLock, err := NewMasterLock(goodPassphrase, sha256.New, defIter, salt) 32 require.NoError(t, err) 33 34 // try to create a bad master key lock (unsupported hash) 35 mkLockBad, err := NewMasterLock(goodPassphrase, sha512.New, defIter, salt) 36 require.Error(t, err) 37 require.Empty(t, mkLockBad) 38 39 encryptedMk, err := mkLock.Encrypt("", &secretlock.EncryptRequest{Plaintext: string(testKey)}) 40 require.NoError(t, err) 41 require.NotEmpty(t, encryptedMk) 42 43 decryptedMk, err := mkLock.Decrypt("", &secretlock.DecryptRequest{Ciphertext: encryptedMk.Ciphertext}) 44 require.NoError(t, err) 45 require.Equal(t, testKey, []byte(decryptedMk.Plaintext)) 46 47 // try decrypting a non valid base64URL string 48 decryptedMk, err = mkLock.Decrypt("", &secretlock.DecryptRequest{Ciphertext: "bad{}base64URLstring[]"}) 49 require.Error(t, err) 50 require.Empty(t, decryptedMk) 51 52 // create a new lock instance with the same passphrase, hash, salt 53 mkLock2, err := NewMasterLock(goodPassphrase, sha256.New, defIter, salt) 54 require.NoError(t, err) 55 56 // ensure Decrypt() is successful and returns the same result as the original lock 57 decryptedMk2, err := mkLock2.Decrypt("", &secretlock.DecryptRequest{Ciphertext: encryptedMk.Ciphertext}) 58 require.NoError(t, err) 59 require.Equal(t, testKey, []byte(decryptedMk2.Plaintext)) 60 61 // recreate new lock with empty salt 62 mkLock2, err = NewMasterLock(goodPassphrase, sha256.New, defIter, nil) 63 require.NoError(t, err) 64 65 decryptedMk2, err = mkLock2.Decrypt("", &secretlock.DecryptRequest{Ciphertext: encryptedMk.Ciphertext}) 66 require.Error(t, err) 67 require.Empty(t, decryptedMk2) 68 69 // recreate new lock with a different salt 70 salt2 := make([]byte, keySize) 71 _, err = rand.Read(salt2) 72 require.NoError(t, err) 73 74 mkLock2, err = NewMasterLock(goodPassphrase, sha256.New, defIter, salt2) 75 require.NoError(t, err) 76 77 decryptedMk2, err = mkLock2.Decrypt("", &secretlock.DecryptRequest{Ciphertext: encryptedMk.Ciphertext}) 78 require.Error(t, err) 79 require.Empty(t, decryptedMk2) 80 81 // try with a bad passhrase 82 mkLock2, err = NewMasterLock("badPassphrase", sha256.New, defIter, salt) 83 require.NoError(t, err) 84 85 decryptedMk2, err = mkLock2.Decrypt("", &secretlock.DecryptRequest{Ciphertext: encryptedMk.Ciphertext}) 86 require.Error(t, err) 87 require.Empty(t, decryptedMk2) 88 89 // try creating a lock with a nil hash 90 mkLock2, err = NewMasterLock(goodPassphrase, nil, defIter, salt) 91 require.Error(t, err) 92 require.Empty(t, mkLock2) 93 94 // try creating a lock with an empty passphrase 95 mkLock2, err = NewMasterLock("", sha256.New, defIter, salt) 96 require.Error(t, err) 97 require.Empty(t, mkLock2) 98 } 99 100 func benchmark(b *testing.B, h func() hash.Hash, iter int) { 101 b.Helper() 102 103 var ( 104 sink uint8 105 lck secretlock.Service 106 ) 107 108 password := "somepassphrase" 109 salt := make([]byte, h().Size()) 110 _, err := rand.Read(salt) 111 require.NoError(b, err) 112 113 b.ResetTimer() 114 115 for i := 0; i < b.N; i++ { 116 lck, err = NewMasterLock(password, h, iter, salt) 117 require.NoError(b, err) 118 119 mlck, ok := lck.(*masterLockPBKDF2) 120 require.True(b, ok) 121 122 sink += uint8(mlck.aead.Overhead()) 123 } 124 125 MajorSink = sink 126 } 127 128 // nolint:gochecknoglobals // needed to avoid Go compiler perf optimizations for benchmarks (avoid optimize loop body). 129 var MajorSink uint8 130 131 func BenchmarkHMACSHA256_4k(b *testing.B) { 132 benchmark(b, sha256.New, 4096) 133 } 134 135 func BenchmarkHMACSHA256_8k(b *testing.B) { 136 benchmark(b, sha256.New, 8192) 137 } 138 139 func BenchmarkHMACSHA256_64k(b *testing.B) { 140 benchmark(b, sha256.New, 65536) 141 }