21
vendor/github.com/cruxic/go-hmac-drbg/LICENSE
generated
vendored
Normal file
21
vendor/github.com/cruxic/go-hmac-drbg/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 cruxic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
206
vendor/github.com/cruxic/go-hmac-drbg/hmacdrbg/hmacdrbg.go
generated
vendored
Normal file
206
vendor/github.com/cruxic/go-hmac-drbg/hmacdrbg/hmacdrbg.go
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
package hmacdrbg
|
||||
|
||||
//Ported from: https://github.com/fpgaminer/python-hmac-drbg
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
)
|
||||
|
||||
/**937 bytes (~7500 bits) as per the spec.*/
|
||||
const MaxBytesPerGenerate = 937 // ~ 7500bits/8
|
||||
|
||||
/**Entropy for NewHmacDrbg() and Reseed() must never exceed this number of bytes.*/
|
||||
const MaxEntropyBytes = 125 // = 1000bits
|
||||
|
||||
const MaxPersonalizationBytes = 32 // = 256bits
|
||||
|
||||
type HmacDrbg struct {
|
||||
/**The effective security level (eg 128 bits) which this generator was instantiated with.*/
|
||||
SecurityLevelBits int
|
||||
|
||||
k, v []byte
|
||||
|
||||
reseedCounter int
|
||||
}
|
||||
|
||||
/**Read from an arbitrary number of bytes from HmacDrbg efficiently.
|
||||
Internally it generates blocks of MaxBytesPerGenerate. It then
|
||||
serves these out through the standard `Read` function. Read returns
|
||||
an error if reseed becomes is necessary.
|
||||
*/
|
||||
type HmacDrbgReader struct {
|
||||
Drbg *HmacDrbg
|
||||
buffer []byte //size MaxBytesPerGenerate
|
||||
offset int
|
||||
}
|
||||
|
||||
/**Create a new DRBG.
|
||||
desiredSecurityLevelBits must be one of 112, 128, 192, 256.
|
||||
|
||||
entropy length (in bits) must be at least 1.5 times securityLevelBits.
|
||||
entropy byte length cannot exceed MaxEntropyBytes.
|
||||
|
||||
The personalization can be nil. If non-nil, it's byte length cannot exceed MaxPersonalizationBytes.
|
||||
|
||||
If any of the parameters are out-of-range this function will panic.
|
||||
*/
|
||||
func NewHmacDrbg(securityLevelBits int, entropy, personalization []byte) *HmacDrbg {
|
||||
if securityLevelBits != 112 &&
|
||||
securityLevelBits != 128 &&
|
||||
securityLevelBits != 192 &&
|
||||
securityLevelBits != 256 {
|
||||
|
||||
panic("Illegal desiredSecurityLevelBits")
|
||||
}
|
||||
|
||||
if len(entropy) > MaxEntropyBytes {
|
||||
panic("Input entropy too large")
|
||||
}
|
||||
|
||||
if (len(entropy) * 8 * 2) < (securityLevelBits * 3) {
|
||||
panic("Insufficient entropy for security level")
|
||||
}
|
||||
|
||||
if personalization != nil && len(personalization) > MaxPersonalizationBytes {
|
||||
panic("Personalization too long")
|
||||
}
|
||||
|
||||
self := &HmacDrbg{
|
||||
SecurityLevelBits: securityLevelBits,
|
||||
k: make([]byte, 32),
|
||||
v: make([]byte, 32),
|
||||
reseedCounter: 1,
|
||||
}
|
||||
|
||||
//Instantiate
|
||||
//k already holds 0x00.
|
||||
//Fill v with 0x01.
|
||||
for i := range self.v {
|
||||
self.v[i] = 0x01
|
||||
}
|
||||
|
||||
nPers := 0
|
||||
if personalization != nil {
|
||||
nPers = len(personalization)
|
||||
}
|
||||
seed := make([]byte, len(entropy) + nPers)
|
||||
copy(seed, entropy)
|
||||
if personalization != nil {
|
||||
copy(seed[len(entropy):], personalization)
|
||||
}
|
||||
|
||||
self.update(seed)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *HmacDrbg) _hmac(key, message []byte) []byte {
|
||||
hm := hmac.New(sha256.New, key)
|
||||
hm.Write(message)
|
||||
return hm.Sum(nil)
|
||||
}
|
||||
|
||||
func (self *HmacDrbg) update(providedData []byte) {
|
||||
nProvided := 0
|
||||
if providedData != nil {
|
||||
nProvided = len(providedData)
|
||||
}
|
||||
|
||||
msg := make([]byte, len(self.v) + 1 + nProvided)
|
||||
copy(msg, self.v)
|
||||
//leave hole with 0x00 at msg[len(self.v)]
|
||||
if (providedData != nil) {
|
||||
copy(msg[len(self.v)+1:], providedData)
|
||||
}
|
||||
|
||||
self.k = self._hmac(self.k, msg)
|
||||
self.v = self._hmac(self.k, self.v)
|
||||
|
||||
if providedData != nil {
|
||||
copy(msg, self.v)
|
||||
msg[len(self.v)] = 0x01
|
||||
copy(msg[len(self.v)+1:], providedData)
|
||||
|
||||
self.k = self._hmac(self.k, msg)
|
||||
self.v = self._hmac(self.k, self.v)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *HmacDrbg) Reseed(entropy []byte) error {
|
||||
if len(entropy) * 8 < self.SecurityLevelBits {
|
||||
return errors.New("Reseed entropy is less than security-level")
|
||||
}
|
||||
|
||||
if len(entropy) > MaxEntropyBytes {
|
||||
return errors.New("Reseed entropy exceeds MaxEntropyBytes")
|
||||
}
|
||||
|
||||
self.update(entropy)
|
||||
self.reseedCounter = 1
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/**Fill the given byte array with random bytes.
|
||||
Returns false if a reseed is necessary first.
|
||||
This function will panic if the array is larger than MaxBytesPerGenerate.*/
|
||||
func (self *HmacDrbg) Generate(outputBytes []byte) bool {
|
||||
nWanted := len(outputBytes)
|
||||
if nWanted > MaxBytesPerGenerate {
|
||||
panic("HmacDrbg: generate request too large.")
|
||||
}
|
||||
|
||||
if self.reseedCounter >= 10000 {
|
||||
//set all bytes to zero, just to be clear
|
||||
for i := range outputBytes {
|
||||
outputBytes[i] = 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
nGen := 0
|
||||
var n int
|
||||
for nGen < nWanted {
|
||||
self.v = self._hmac(self.k, self.v)
|
||||
|
||||
n = nWanted - nGen
|
||||
if n > len(self.v) {
|
||||
n = len(self.v)
|
||||
}
|
||||
copy(outputBytes[nGen:], self.v[0:n])
|
||||
nGen += n
|
||||
}
|
||||
|
||||
self.update(nil)
|
||||
self.reseedCounter++
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func NewHmacDrbgReader(drbg *HmacDrbg) *HmacDrbgReader {
|
||||
return &HmacDrbgReader{
|
||||
Drbg: drbg,
|
||||
buffer: make([]byte, MaxBytesPerGenerate),
|
||||
offset: MaxBytesPerGenerate,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *HmacDrbgReader) Read(b []byte) (n int, err error) {
|
||||
nRead := 0
|
||||
nWanted := len(b)
|
||||
for nRead < nWanted {
|
||||
if self.offset >= MaxBytesPerGenerate {
|
||||
if !self.Drbg.Generate(self.buffer) {
|
||||
return nRead, errors.New("MUST_RESEED")
|
||||
}
|
||||
self.offset = 0
|
||||
}
|
||||
|
||||
b[nRead] = self.buffer[self.offset]
|
||||
nRead++
|
||||
self.offset++
|
||||
}
|
||||
|
||||
return nRead, nil
|
||||
}
|
||||
Reference in New Issue
Block a user