mirror of https://github.com/k3s-io/k3s
69 lines
1.3 KiB
Go
69 lines
1.3 KiB
Go
package goproxy
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/rsa"
|
|
"crypto/sha256"
|
|
"crypto/x509"
|
|
"errors"
|
|
)
|
|
|
|
type CounterEncryptorRand struct {
|
|
cipher cipher.Block
|
|
counter []byte
|
|
rand []byte
|
|
ix int
|
|
}
|
|
|
|
func NewCounterEncryptorRandFromKey(key interface{}, seed []byte) (r CounterEncryptorRand, err error) {
|
|
var keyBytes []byte
|
|
switch key := key.(type) {
|
|
case *rsa.PrivateKey:
|
|
keyBytes = x509.MarshalPKCS1PrivateKey(key)
|
|
default:
|
|
err = errors.New("only RSA keys supported")
|
|
return
|
|
}
|
|
h := sha256.New()
|
|
if r.cipher, err = aes.NewCipher(h.Sum(keyBytes)[:aes.BlockSize]); err != nil {
|
|
return
|
|
}
|
|
r.counter = make([]byte, r.cipher.BlockSize())
|
|
if seed != nil {
|
|
copy(r.counter, h.Sum(seed)[:r.cipher.BlockSize()])
|
|
}
|
|
r.rand = make([]byte, r.cipher.BlockSize())
|
|
r.ix = len(r.rand)
|
|
return
|
|
}
|
|
|
|
func (c *CounterEncryptorRand) Seed(b []byte) {
|
|
if len(b) != len(c.counter) {
|
|
panic("SetCounter: wrong counter size")
|
|
}
|
|
copy(c.counter, b)
|
|
}
|
|
|
|
func (c *CounterEncryptorRand) refill() {
|
|
c.cipher.Encrypt(c.rand, c.counter)
|
|
for i := 0; i < len(c.counter); i++ {
|
|
if c.counter[i]++; c.counter[i] != 0 {
|
|
break
|
|
}
|
|
}
|
|
c.ix = 0
|
|
}
|
|
|
|
func (c *CounterEncryptorRand) Read(b []byte) (n int, err error) {
|
|
if c.ix == len(c.rand) {
|
|
c.refill()
|
|
}
|
|
if n = len(c.rand) - c.ix; n > len(b) {
|
|
n = len(b)
|
|
}
|
|
copy(b, c.rand[c.ix:c.ix+n])
|
|
c.ix += n
|
|
return
|
|
}
|