package gostdlib import ( "crypto/hmac" "errors" "github.com/safing/jess/tools" ) func init() { tools.Register(&tools.Tool{ Info: &tools.ToolInfo{ Name: "HMAC", Purpose: tools.PurposeMAC, Options: []uint8{ tools.OptionNeedsDedicatedHasher, tools.OptionHasState, }, SecurityLevel: 0, // depends on used hash function Comment: "RFC 2104, FIPS 198", Author: "Mihir Bellare et al., 1996", }, Factory: func() tools.ToolLogic { return &HMAC{} }, }) } // HMAC implements the cryptographic interface for HMAC message authentication codes. type HMAC struct { tools.ToolLogicBase key []byte } // Setup implements the ToolLogic interface. func (hm *HMAC) Setup() (err error) { // get key hm.key, err = hm.Helper().NewSessionKey() if err != nil { return err } return nil } // Reset implements the ToolLogic interface. func (hm *HMAC) Reset() error { // clean up key hm.Helper().Burn(hm.key) return nil } // MAC implements the ToolLogic interface. func (hm *HMAC) MAC(data, associatedData []byte) ([]byte, error) { // create MAC mac := hmac.New(hm.HashTool().New, hm.key) // write data n, err := mac.Write(data) if err != nil { return nil, err } if n != len(data) { return nil, errors.New("failed to fully write data to HMAC hasher") } // write associated data if len(associatedData) > 0 { n, err := mac.Write(associatedData) if err != nil { return nil, err } if n != len(associatedData) { return nil, errors.New("failed to fully write associated data to HMAC hasher") } } // return sum return mac.Sum(nil), nil }