diff --git a/cmd/crypto/key.go b/cmd/crypto/key.go index 0befcb99f..75f67a5a1 100644 --- a/cmd/crypto/key.go +++ b/cmd/crypto/key.go @@ -35,8 +35,8 @@ import ( type ObjectKey [32]byte // GenerateKey generates a unique ObjectKey from a 256 bit external key -// and a source of randomness. If random is nil the default PRNG of system -// (crypto/rand) is used. +// and a source of randomness. If random is nil the default PRNG of the +// system (crypto/rand) is used. func GenerateKey(extKey [32]byte, random io.Reader) (key ObjectKey) { if random == nil { random = rand.Reader @@ -52,6 +52,19 @@ func GenerateKey(extKey [32]byte, random io.Reader) (key ObjectKey) { return key } +// GenerateIV generates a new random 256 bit IV from the provided source +// of randomness. If random is nil the default PRNG of the system +// (crypto/rand) is used. +func GenerateIV(random io.Reader) (iv [32]byte) { + if random == nil { + random = rand.Reader + } + if _, err := io.ReadFull(random, iv[:]); err != nil { + logger.CriticalIf(context.Background(), errOutOfEntropy) + } + return iv +} + // SealedKey represents a sealed object key. It can be stored // at an untrusted location. type SealedKey struct { diff --git a/cmd/crypto/key_test.go b/cmd/crypto/key_test.go index 93d4e079d..ff5f38081 100644 --- a/cmd/crypto/key_test.go +++ b/cmd/crypto/key_test.go @@ -61,6 +61,32 @@ func TestGenerateKey(t *testing.T) { } } +var generateIVTests = []struct { + Random io.Reader + ShouldPass bool +}{ + {Random: nil, ShouldPass: true}, // 0 + {Random: rand.Reader, ShouldPass: true}, // 1 + {Random: shortRandom(32), ShouldPass: true}, // 2 + {Random: shortRandom(31), ShouldPass: false}, // 3 +} + +func TestGenerateIV(t *testing.T) { + defer func(disableLog bool) { logger.Disable = disableLog }(logger.Disable) + logger.Disable = true + + for i, test := range generateIVTests { + i, test := i, test + func() { + defer recoverTest(i, test.ShouldPass, t) + iv := GenerateIV(test.Random) + if iv == [32]byte{} { + t.Errorf("Test %d: generated IV is zero IV", i) // check that we generate random and unique IV + } + }() + } +} + var sealUnsealKeyTests = []struct { SealExtKey, SealIV [32]byte SealDomain, SealBucket, SealObject string