68 lines
1.6 KiB
Go
68 lines
1.6 KiB
Go
package blake3
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/zeebo/blake3"
|
|
|
|
"github.com/safing/jess/tools"
|
|
)
|
|
|
|
func init() {
|
|
tools.Register(&tools.Tool{
|
|
Info: &tools.ToolInfo{
|
|
Name: "BLAKE3-KDF",
|
|
Purpose: tools.PurposeKeyDerivation,
|
|
SecurityLevel: 128,
|
|
Comment: "cryptographic hash function based on Bao and BLAKE2",
|
|
Author: "Jean-Philippe Aumasson et al., 2020",
|
|
},
|
|
Factory: func() tools.ToolLogic { return &KDF{} },
|
|
})
|
|
}
|
|
|
|
// KDF implements the cryptographic interface for BLAKE3 key derivation.
|
|
type KDF struct {
|
|
tools.ToolLogicBase
|
|
reader io.Reader
|
|
}
|
|
|
|
// InitKeyDerivation implements the ToolLogic interface.
|
|
func (keyder *KDF) InitKeyDerivation(nonce []byte, material ...[]byte) error {
|
|
// Check params.
|
|
if len(material) < 1 || len(material[0]) == 0 || len(nonce) == 0 {
|
|
return errors.New("must supply at least one key and a nonce as key material")
|
|
}
|
|
|
|
// Setup KDF.
|
|
// Use nonce as kdf context.
|
|
h := blake3.NewDeriveKey(string(nonce))
|
|
// Then add all the key material.
|
|
for _, m := range material {
|
|
_, _ = h.Write(m)
|
|
}
|
|
// Get key reader.
|
|
keyder.reader = h.Digest()
|
|
|
|
return nil
|
|
}
|
|
|
|
// DeriveKey implements the ToolLogic interface.
|
|
func (keyder *KDF) DeriveKey(size int) ([]byte, error) {
|
|
key := make([]byte, size)
|
|
return key, keyder.DeriveKeyWriteTo(key)
|
|
}
|
|
|
|
// DeriveKeyWriteTo implements the ToolLogic interface.
|
|
func (keyder *KDF) DeriveKeyWriteTo(newKey []byte) error {
|
|
n, err := io.ReadFull(keyder.reader, newKey)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to generate key: %w", err)
|
|
}
|
|
if n != len(newKey) {
|
|
return errors.New("failed to generate key: EOF")
|
|
}
|
|
return nil
|
|
}
|