in fakekms/symmetric_rpcs.go [284:345]
func (f *fakeKMS) MacSign(ctx context.Context, req *kmspb.MacSignRequest) (*kmspb.MacSignResponse, error) {
if err := allowlist("name", "data", "data_crc32c").check(req); err != nil {
return nil, err
}
name, err := parseCryptoKeyVersionName(req.Name)
if err != nil {
return nil, err
}
ckv, err := f.cryptoKeyVersion(name)
if err != nil {
return nil, err
}
if ckv.pb.State != kmspb.CryptoKeyVersion_ENABLED {
return nil, errFailedPrecondition("key version %s is not enabled", name)
}
def, _ := algorithmDef(ckv.pb.Algorithm)
if def.Purpose != kmspb.CryptoKey_MAC {
return nil, errFailedPrecondition("keys with algorithm %s may not be used for MAC signing",
nameForValue(kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm_name, int32(ckv.pb.Algorithm)))
}
hash := def.Opts.(crypto.Hash)
if req.Data == nil {
return nil, errInvalidArgument("data is empty")
}
var data []byte = req.Data
if len(data) > 64*1024 {
return nil, errInvalidArgument("len(data)=%d, want len(data)<=%d", len(data), 64*1024)
}
dataChecksum := crc32c(data)
if req.DataCrc32C != nil && dataChecksum.Value != req.DataCrc32C.Value {
return nil, errInvalidArgument("invalid data checksum")
}
var key []byte
var ok bool
if key, ok = ckv.keyMaterial.([]byte); !ok {
return nil, err
}
mac := hmac.New(hash.New, key)
_, err = mac.Write(data)
if err != nil {
return nil, errInternal("MAC signing failed: %v", err)
}
macTag := mac.Sum(nil)
return &kmspb.MacSignResponse{
Name: req.Name,
Mac: macTag,
MacCrc32C: crc32c(macTag),
VerifiedDataCrc32C: req.DataCrc32C != nil,
ProtectionLevel: ckv.pb.ProtectionLevel,
}, nil
}