Constant Time HMAC Compare

Compute an HMAC-SHA256 tag and compare it in constant time to avoid leaking the secret through timing.

GoSecurity Boundaries

Code

snippet
package signing

import (
    "crypto/hmac"
    "crypto/sha256"
    "crypto/subtle"
    "encoding/hex"
    "errors"
)

var ErrInvalidMAC = errors.New("invalid message authentication code")

func Sign(secret, message []byte) []byte {
    mac := hmac.New(sha256.New, secret)
    mac.Write(message)
    return mac.Sum(nil)
}

func Verify(secret, message, provided []byte) error {
    expected := Sign(secret, message)
    if subtle.ConstantTimeCompare(expected, provided) != 1 {
        return ErrInvalidMAC
    }
    return nil
}

func SignHex(secret, message []byte) string {
    return hex.EncodeToString(Sign(secret, message))
}