github.com/linuxboot/fiano@v1.2.0/pkg/intel/metadata/bg/signature.go (about)

     1  // Copyright 2017-2023 the LinuxBoot Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:generate manifestcodegen
     6  
     7  package bg
     8  
     9  import (
    10  	"crypto"
    11  	"crypto/rand"
    12  	"fmt"
    13  )
    14  
    15  var (
    16  	// RandReader exports the rand.Reader
    17  	RandReader = rand.Reader
    18  )
    19  
    20  // Signature exports the Signature structure
    21  type Signature struct {
    22  	SigScheme Algorithm `json:"sigScheme"`
    23  	Version   uint8     `require:"0x10" json:"sigVersion,omitempty"`
    24  	KeySize   BitSize   `json:"sigKeysize,omitempty"`
    25  	HashAlg   Algorithm `json:"sigHashAlg"`
    26  	Data      []byte    `countValue:"KeySize.InBytes()" prettyValue:"dataPrettyValue()" json:"sigData"`
    27  }
    28  
    29  func (m Signature) dataPrettyValue() interface{} {
    30  	r, _ := m.SignatureData()
    31  	return r
    32  }
    33  
    34  // SignatureData parses field Data and returns the signature as one of these types:
    35  // * SignatureRSAPSS
    36  // * SignatureRSAASA
    37  // * SignatureECDSA
    38  // * SignatureSM2
    39  func (m Signature) SignatureData() (SignatureDataInterface, error) {
    40  	switch m.SigScheme {
    41  	case AlgRSASSA:
    42  		return SignatureRSAASA(m.Data), nil
    43  	}
    44  
    45  	return nil, fmt.Errorf("unexpected signature scheme: %s", m.SigScheme)
    46  }
    47  
    48  // SetSignatureByData sets all the fields of the structure Signature by
    49  // accepting one of these types as the input argument `sig`:
    50  // * SignatureRSAPSS
    51  // * SignatureRSAASA
    52  // * SignatureECDSA
    53  // * SignatureSM2
    54  func (m *Signature) SetSignatureByData(sig SignatureDataInterface, hashAlgo Algorithm) error {
    55  	err := m.SetSignatureData(sig)
    56  	if err != nil {
    57  		return err
    58  	}
    59  
    60  	switch sig := sig.(type) {
    61  	case SignatureRSAASA:
    62  		m.SigScheme = AlgRSASSA
    63  		if hashAlgo.IsNull() {
    64  			m.HashAlg = AlgSHA256
    65  		} else {
    66  			m.HashAlg = hashAlgo
    67  		}
    68  		m.KeySize.SetInBytes(uint16(len(m.Data)))
    69  	default:
    70  		return fmt.Errorf("unexpected signature type: %T", sig)
    71  	}
    72  	return nil
    73  }
    74  
    75  // SetSignatureData sets the value of the field Data by accepting one of these
    76  // types as the input argument `sig`:
    77  // * SignatureRSAPSS
    78  // * SignatureRSAASA
    79  // * SignatureECDSA
    80  // * SignatureSM2
    81  func (m *Signature) SetSignatureData(sig SignatureDataInterface) error {
    82  	switch sig := sig.(type) {
    83  	case SignatureRSAASA:
    84  		m.Data = sig
    85  	default:
    86  		return fmt.Errorf("unexpected signature type: %T", sig)
    87  	}
    88  	return nil
    89  }
    90  
    91  // SetSignature calculates the signature accordingly to arguments signAlgo,
    92  // privKey and signedData; and sets all the fields of the structure Signature.
    93  //
    94  // if signAlgo is zero then it is detected automatically, based on the type
    95  // of the provided private key.
    96  func (m *Signature) SetSignature(signAlgo Algorithm, privKey crypto.Signer, signedData []byte) error {
    97  	m.Version = 0x10
    98  	signData, err := NewSignatureData(signAlgo, privKey, signedData)
    99  	if err != nil {
   100  		return fmt.Errorf("unable to construct the signature data: %w", err)
   101  	}
   102  
   103  	err = m.SetSignatureByData(signData, AlgNull)
   104  	if err != nil {
   105  		return fmt.Errorf("unable to set the signature: %w", err)
   106  	}
   107  
   108  	return nil
   109  }
   110  
   111  // FillSignature sets the signature accordingly to arguments signAlgo,
   112  // pubKey and signedData; and sets all the fields of the structure Signature.
   113  //
   114  // if signAlgo is zero then it is detected automatically, based on the type
   115  // of the provided private key.
   116  func (m *Signature) FillSignature(signAlgo Algorithm, pubKey crypto.PublicKey, signedData []byte, hashAlgo Algorithm) error {
   117  	m.Version = 0x10
   118  	signData, err := NewSignatureByData(signAlgo, pubKey, signedData)
   119  	if err != nil {
   120  		return fmt.Errorf("unable to construct the signature data: %w", err)
   121  	}
   122  
   123  	err = m.SetSignatureByData(signData, hashAlgo)
   124  	if err != nil {
   125  		return fmt.Errorf("unable to set the signature: %w", err)
   126  	}
   127  
   128  	return nil
   129  }