// Copyright 2024 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package drbgimport ()// Counter is an SP 800-90A Rev. 1 CTR_DRBG instantiated with AES-256.//// Per Table 3, it has a security strength of 256 bits, a seed size of 384 bits,// a counter length of 128 bits, a reseed interval of 2^48 requests, and a// maximum request size of 2^19 bits (2^16 bytes, 64 KiB).//// We support a narrow range of parameters that fit the needs of our RNG:// AES-256, no derivation function, no personalization string, no prediction// resistance, and 384-bit additional input.typeCounterstruct {// c is instantiated with K as the key and V as the counter. c aes.CTR reseedCounter uint64}const ( keySize = 256 / 8SeedSize = keySize + aes.BlockSize reseedInterval = 1 << 48 maxRequestSize = (1 << 19) / 8)func ( *[SeedSize]byte) *Counter {// CTR_DRBG_Instantiate_algorithm, per Section 10.2.1.3.1.fips140.RecordApproved() := make([]byte, keySize) := make([]byte, aes.BlockSize)// V starts at 0, but is incremented in CTR_DRBG_Update before each use, // unlike AES-CTR where it is incremented after each use. [len()-1] = 1 , := aes.New()if != nil {panic() } := &Counter{} .c = *aes.NewCTR(, ) .update() .reseedCounter = 1return}func ( *Counter) ( *[SeedSize]byte) {// CTR_DRBG_Update, per Section 10.2.1.2. := make([]byte, SeedSize) .c.XORKeyStream(, [:]) := [:keySize] := [keySize:]// Again, we pre-increment V, like in NewCounter.increment((*[aes.BlockSize]byte)()) , := aes.New()if != nil {panic() } .c = *aes.NewCTR(, )}func increment( *[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) {// CTR_DRBG_Reseed_algorithm, per Section 10.2.1.4.1.fips140.RecordApproved()var [SeedSize]bytesubtle.XORBytes([:], [:], [:]) .update(&) .reseedCounter = 1}// Generate produces at most maxRequestSize bytes of random data in out.func ( *Counter) ( []byte, *[SeedSize]byte) ( bool) {// CTR_DRBG_Generate_algorithm, per Section 10.2.1.5.1.fips140.RecordApproved()iflen() > maxRequestSize {panic("crypto/drbg: internal error: request size exceeds maximum") }// Step 1.if .reseedCounter > reseedInterval {returntrue }// Step 2.if != nil { .update() } else {// If the additional input is null, the first CTR_DRBG_Update is // skipped, but the additional input is replaced with an all-zero string // for the second CTR_DRBG_Update. = new([SeedSize]byte) }// Steps 3-5.clear() .c.XORKeyStream(, )aes.RoundToBlock(&.c)// Step 6. .update()// Step 7. .reseedCounter++// Step 8.returnfalse}
The pages are generated with Goldsv0.7.3-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.