github.com/usbarmory/armory-boot@v0.0.0-20240307133412-208c66a380b9/config/crypto.go (about)

     1  // https://github.com/usbarmory/armory-boot
     2  //
     3  // Copyright (c) WithSecure Corporation
     4  // https://foundry.withsecure.com
     5  //
     6  // Use of this source code is governed by the license
     7  // that can be found in the LICENSE file.
     8  
     9  package config
    10  
    11  import (
    12  	"bytes"
    13  	"crypto/sha256"
    14  	"encoding/hex"
    15  	"errors"
    16  	"fmt"
    17  
    18  	"github.com/usbarmory/tamago/soc/nxp/imx6ul"
    19  )
    20  
    21  func init() {
    22  	if imx6ul.DCP != nil {
    23  		imx6ul.DCP.Init()
    24  	}
    25  }
    26  
    27  // Verify authenticates an input against a signify/minisign generated
    28  // signature, pubKey must be the last line of a signify/minisign public key
    29  // (i.e. without comments).
    30  func Verify(buf []byte, sig []byte, pubKey string) (err error) {
    31  	s, err := DecodeSignature(string(sig))
    32  
    33  	if err != nil {
    34  		return fmt.Errorf("invalid signature, %v", err)
    35  	}
    36  
    37  	pub, err := NewPublicKey(pubKey)
    38  
    39  	if err != nil {
    40  		return fmt.Errorf("invalid public key, %v", err)
    41  	}
    42  
    43  	valid, err := pub.Verify(buf, s)
    44  
    45  	if err != nil {
    46  		return fmt.Errorf("invalid signature, %v", err)
    47  	}
    48  
    49  	if !valid {
    50  		return errors.New("invalid signature")
    51  	}
    52  
    53  	return
    54  }
    55  
    56  // CompareHash computes a SHA256 checksum of the input data, using hardware
    57  // acceleration (NXP DCP), and compares the computed hash with the one passed
    58  // as a string with only hexadecimal characters and even length.
    59  //
    60  // As this function is meant for pre-boot use, the entire input buffer is
    61  // copied in a DMA region for DCP consumption in a single pass, rather than
    62  // buffering over multiple passes, to reduce DCP command overhead. When used in
    63  // other contexts callers must ensure that enough DMA space is available.
    64  //
    65  // This function is only meant to be used with `GOOS=tamago GOARCH=arm` on
    66  // i.MX6 targets.
    67  func CompareHash(buf []byte, s string) (valid bool) {
    68  	var sum [32]byte
    69  	var err error
    70  
    71  	switch {
    72  	case imx6ul.CAAM != nil:
    73  		sum, err = imx6ul.CAAM.Sum256(buf)
    74  	case imx6ul.DCP != nil:
    75  		sum, err = imx6ul.DCP.Sum256(buf)
    76  	default:
    77  		sum = sha256.Sum256(buf)
    78  	}
    79  
    80  	if err != nil {
    81  		return false
    82  	}
    83  
    84  	hash, err := hex.DecodeString(s)
    85  
    86  	if err != nil {
    87  		return false
    88  	}
    89  
    90  	return bytes.Equal(sum[:], hash)
    91  }