package drbg
import (
)
type Counter struct {
c aes.CTR
reseedCounter uint64
}
const (
keySize = 256 / 8
SeedSize = keySize + aes.BlockSize
reseedInterval = 1 << 48
maxRequestSize = (1 << 19) / 8
)
func ( *[SeedSize]byte) *Counter {
fips140.RecordApproved()
:= make([]byte, keySize)
:= make([]byte, aes.BlockSize)
[len()-1] = 1
, := aes.New()
if != nil {
panic()
}
:= &Counter{}
.c = *aes.NewCTR(, )
.update()
.reseedCounter = 1
return
}
func ( *Counter) ( *[SeedSize]byte) {
:= make([]byte, SeedSize)
.c.XORKeyStream(, [:])
:= [:keySize]
:= [keySize:]
increment((*[aes.BlockSize]byte)())
, := aes.New()
if != nil {
panic()
}
.c = *aes.NewCTR(, )
}
func ( *[aes.BlockSize]byte) {
:= byteorder.BEUint64([:8])
:= byteorder.BEUint64([8:])
, := bits.Add64(, 1, 0)
, _ = bits.Add64(, 0, )
byteorder.BEPutUint64([:8], )
byteorder.BEPutUint64([8:], )
}
func ( *Counter) (, *[SeedSize]byte) {
fips140.RecordApproved()
var [SeedSize]byte
subtle.XORBytes([:], [:], [:])
.update(&)
.reseedCounter = 1
}
func ( *Counter) ( []byte, *[SeedSize]byte) ( bool) {
fips140.RecordApproved()
if len() > maxRequestSize {
panic("crypto/drbg: internal error: request size exceeds maximum")
}
if .reseedCounter > reseedInterval {
return true
}
if != nil {
.update()
} else {
= new([SeedSize]byte)
}
clear()
.c.XORKeyStream(, )
aes.RoundToBlock(&.c)
.update()
.reseedCounter++
return false
}