func()

in linux/sks.go [81:126]


func (tpm *tpmDevice) SignWithKey(keyID string, digest []byte) ([]byte, error) {
	// First get the org root key so the requested child key can be loaded and
	// used.
	orgRootKey, err := tpm.GetOrgRootKey()
	if err != nil {
		return nil, fmt.Errorf("error while getting root key: %w", err)
	}
	defer tpm.FlushKey(orgRootKey, true)

	// Next get the requested key, or bail if it can't be loaded.
	key, err := tpm.LoadKey(keyID, orgRootKey.GetHandle(), 0, nil)
	if err != nil {
		return nil, fmt.Errorf("could not load requested key %q: %w", keyID, err)
	}
	defer tpm.FlushKey(key, true)

	signature, err := tpm2.Sign(
		tpm.rwc,
		key.GetLoadedHandle(),
		"",
		digest,
		nil,
		&tpm2.SigScheme{
			Alg:  tpm2.AlgECDSA,
			Hash: tpm2.AlgSHA256,
		},
	)
	if err != nil {
		return nil, fmt.Errorf("could not sign with key %q: %w", keyID, err)
	}

	// The standard elliptic Marshal includes more data than needed, which
	// causes signature validation problems. Create a simple struct with just
	// the EC points and marshal that in ASN.1 format.
	basicSig := utils.ECCSignature{
		R: signature.ECC.R,
		S: signature.ECC.S,
	}

	derBytes, err := asn1.Marshal(basicSig)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal ECC signature: %w", err)
	}

	return derBytes, nil
}