drbg: support NIST HMAC-DRBG 2

This commit is contained in:
Sun Yimin 2024-06-05 13:01:28 +08:00 committed by GitHub
parent dfc45df2d8
commit 10a97b4c51
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 0 deletions

View File

@ -132,6 +132,43 @@ func NewGmHashDrbgPrng(entropySource io.Reader, securityStrength int, securityLe
return NewHashDrbgPrng(sm3.New, entropySource, securityStrength, true, securityLevel, personalization)
}
// NewHmacDrbgPrng create pseudo random number generator base on hash mac DRBG
func NewHmacDrbgPrng(newHash func() hash.Hash, entropySource io.Reader, securityStrength int, gm bool, securityLevel SecurityLevel, personalization []byte) (*DrbgPrng, error) {
prng := new(DrbgPrng)
if entropySource != nil {
prng.entropySource = entropySource
} else {
prng.entropySource = rand.Reader
}
prng.securityStrength = selectSecurityStrength(securityStrength)
// Get entropy input
entropyInput := make([]byte, prng.securityStrength)
err := prng.getEntropy(entropyInput)
if err != nil {
return nil, err
}
// Get nonce from entropy source here
nonce := make([]byte, prng.securityStrength/2)
err = prng.getEntropy(nonce)
if err != nil {
return nil, err
}
prng.impl, err = NewHmacDrbg(newHash, securityLevel, gm, entropyInput, nonce, personalization)
if err != nil {
return nil, err
}
return prng, nil
}
// NewNistHmacDrbgPrng create pseudo random number generator base on hash mac DRBG which follows NIST standard
func NewNistHmacDrbgPrng(newHash func() hash.Hash, entropySource io.Reader, securityStrength int, securityLevel SecurityLevel, personalization []byte) (*DrbgPrng, error) {
return NewHmacDrbgPrng(newHash, entropySource, securityStrength, false, securityLevel, personalization)
}
func (prng *DrbgPrng) getEntropy(entropyInput []byte) error {
n, err := prng.entropySource.Read(entropyInput)
if err != nil {

View File

@ -95,6 +95,22 @@ func TestNistHashDrbgPrng(t *testing.T) {
}
}
func TestNistHmacDrbgPrng(t *testing.T) {
prng, err := NewNistHmacDrbgPrng(sha256.New, nil, 32, SECURITY_LEVEL_TEST, nil)
if err != nil {
t.Fatal(err)
}
data := make([]byte, MAX_BYTES_PER_GENERATE+1)
n, err := prng.Read(data)
if err != nil {
t.Fatal(err)
}
if n != MAX_BYTES_PER_GENERATE+1 {
t.Errorf("not got enough random bytes")
}
}
func TestGMSecurityStrengthValidation(t *testing.T) {
_, err := NewGmHashDrbgPrng(nil, 24, SECURITY_LEVEL_TEST, nil)
if err == nil {