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 }