You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2019/06/21 21:25:42 UTC
[mynewt-artifact] 18/23: Some code reorginazation and comments
This is an automated email from the ASF dual-hosted git repository.
ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-artifact.git
commit fb24b39ed90f333627f0ccf885e0d4ab7ee04bbe
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Thu Jun 20 17:45:46 2019 -0700
Some code reorginazation and comments
---
errors/errors.go | 18 ++-
flash/flash.go | 6 +-
image/image.go | 304 ++++++-----------------------------------------
image/image_test.go | 4 +-
image/map.go | 81 +++++++++++++
image/parse.go | 200 +++++++++++++++++++++++++++++++
manifest/manifest.go | 4 +
manifest/mfg_manifest.go | 23 +++-
mfg/map_meta.go | 4 +
mfg/meta.go | 114 ++++--------------
mfg/mfg.go | 65 ++++------
mfg/mfg_test.go | 4 +-
mfg/parse.go | 118 ++++++++++++++++++
mfg/verify.go | 2 +-
misc/misc.go | 28 -----
sec/key.go | 23 ++--
sec/sig.go | 2 +-
17 files changed, 543 insertions(+), 457 deletions(-)
diff --git a/errors/errors.go b/errors/errors.go
index 8154fc5..4b76b41 100644
--- a/errors/errors.go
+++ b/errors/errors.go
@@ -1,5 +1,5 @@
-// This is a thin wrapper over the `pkg/errors` package. It decorates the
-// base package with the following functionality:
+// This is a thin wrapper over the `pkg/errors` package. It decorates this
+// package with the following functionality:
//
// 1. Wrap and Wrapf produce an error with exactly one stack trace. If the
// wrapped error already contains a stack trace, these functions just append
@@ -26,16 +26,21 @@ func Cause(err error) error {
return pkgerrors.Cause(err)
}
-// Errorf formats an error
+// Errorf formats according to a format specifier and returns the string
+// as a value that satisfies error.
+// Errorf also records the stack trace at the point it was called.
func Errorf(format string, args ...interface{}) error {
return pkgerrors.Errorf(format, args...)
}
-// New creates a new error
+// New returns an error with the supplied message.
+// New also records the stack trace at the point it was called.
func New(message string) error {
return pkgerrors.New(message)
}
+// Wrap returns an error annotating err with a stack trace at the point Wrap is
+// called, and the supplied message. If err is nil, Wrap returns nil.
func Wrap(err error, message string) error {
if _, ok := err.(stackTracer); !ok {
return pkgerrors.Wrap(err, message)
@@ -45,10 +50,14 @@ func Wrap(err error, message string) error {
}
}
+// Wrapf returns an error annotating err with a stack trace at the point Wrapf
+// is called, and the format specifier. If err is nil, Wrapf returns nil.
func Wrapf(err error, format string, args ...interface{}) error {
return Wrap(err, fmt.Sprintf(format, args...))
}
+// WithStack annotates err with a stack trace at the point WithStack was called.
+// If err is nil, WithStack returns nil.
func WithStack(err error) error {
if _, ok := err.(stackTracer); !ok {
return pkgerrors.WithStack(err)
@@ -57,6 +66,7 @@ func WithStack(err error) error {
}
}
+// HasStackTrace tells you if the given error contains a stack trace.
func HasStackTrace(err error) bool {
_, ok := err.(stackTracer)
return ok
diff --git a/flash/flash.go b/flash/flash.go
index 6b85814..5903fb2 100644
--- a/flash/flash.go
+++ b/flash/flash.go
@@ -99,6 +99,10 @@ func SortFlashAreasById(areas []FlashArea) []FlashArea {
}
func areasDistinct(a FlashArea, b FlashArea) bool {
+ if a.Device != b.Device {
+ return true
+ }
+
var lo FlashArea
var hi FlashArea
@@ -110,7 +114,7 @@ func areasDistinct(a FlashArea, b FlashArea) bool {
hi = a
}
- return lo.Device != hi.Device || lo.Offset+lo.Size <= hi.Offset
+ return lo.Offset+lo.Size <= hi.Offset
}
// @return overlapping-areas, id-conflicts.
diff --git a/image/image.go b/image/image.go
index 5c489c5..7289f52 100644
--- a/image/image.go
+++ b/image/image.go
@@ -20,16 +20,11 @@
package image
import (
- "bytes"
"encoding/binary"
- "encoding/hex"
- "encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
- "strconv"
- "strings"
"github.com/apache/mynewt-artifact/errors"
"github.com/apache/mynewt-artifact/sec"
@@ -150,120 +145,11 @@ func ImageTlvTypeIsSig(tlvType uint8) bool {
tlvType == IMAGE_TLV_ECDSA256
}
-func ParseVersion(versStr string) (ImageVersion, error) {
- var err error
- var major uint64
- var minor uint64
- var rev uint64
- var buildNum uint64
- var ver ImageVersion
-
- components := strings.Split(versStr, ".")
- major, err = strconv.ParseUint(components[0], 10, 8)
- if err != nil {
- return ver, errors.Errorf("invalid version string %s", versStr)
- }
- if len(components) > 1 {
- minor, err = strconv.ParseUint(components[1], 10, 8)
- if err != nil {
- return ver, errors.Errorf("invalid version string %s", versStr)
- }
- }
- if len(components) > 2 {
- rev, err = strconv.ParseUint(components[2], 10, 16)
- if err != nil {
- return ver, errors.Errorf("invalid version string %s", versStr)
- }
- }
- if len(components) > 3 {
- buildNum, err = strconv.ParseUint(components[3], 10, 32)
- if err != nil {
- return ver, errors.Errorf("invalid version string %s", versStr)
- }
- }
-
- ver.Major = uint8(major)
- ver.Minor = uint8(minor)
- ver.Rev = uint16(rev)
- ver.BuildNum = uint32(buildNum)
- return ver, nil
-}
-
func (ver ImageVersion) String() string {
return fmt.Sprintf("%d.%d.%d.%d",
ver.Major, ver.Minor, ver.Rev, ver.BuildNum)
}
-func (h *ImageHdr) Map(offset int) map[string]interface{} {
- return map[string]interface{}{
- "magic": h.Magic,
- "hdr_sz": h.HdrSz,
- "img_sz": h.ImgSz,
- "flags": h.Flags,
- "vers": h.Vers.String(),
- "_offset": offset,
- }
-}
-
-func rawBodyMap(offset int) map[string]interface{} {
- return map[string]interface{}{
- "_offset": offset,
- }
-}
-
-func (t *ImageTrailer) Map(offset int) map[string]interface{} {
- return map[string]interface{}{
- "magic": t.Magic,
- "tlv_tot_len": t.TlvTotLen,
- "_offset": offset,
- }
-}
-
-func (t *ImageTlv) Map(offset int) map[string]interface{} {
- return map[string]interface{}{
- "type": t.Header.Type,
- "len": t.Header.Len,
- "data": hex.EncodeToString(t.Data),
- "_typestr": ImageTlvTypeName(t.Header.Type),
- "_offset": offset,
- }
-}
-
-func (img *Image) Map() (map[string]interface{}, error) {
- offs, err := img.Offsets()
- if err != nil {
- return nil, err
- }
-
- m := map[string]interface{}{}
- m["header"] = img.Header.Map(offs.Header)
- m["body"] = rawBodyMap(offs.Body)
- trailer := img.Trailer()
- m["trailer"] = trailer.Map(offs.Trailer)
-
- tlvMaps := []map[string]interface{}{}
- for i, tlv := range img.Tlvs {
- tlvMaps = append(tlvMaps, tlv.Map(offs.Tlvs[i]))
- }
- m["tlvs"] = tlvMaps
-
- return m, nil
-}
-
-func (img *Image) Json() (string, error) {
- m, err := img.Map()
- if err != nil {
- return "", err
- }
-
- b, err := json.MarshalIndent(m, "", " ")
- if err != nil {
- return "", errors.Wrapf(err, "failed to marshal image")
- }
-
- return string(b), nil
-}
-
func (tlv *ImageTlv) Write(w io.Writer) (int, error) {
totalSize := 0
@@ -282,18 +168,34 @@ func (tlv *ImageTlv) Write(w io.Writer) (int, error) {
return totalSize, nil
}
-func (i *Image) FindTlvs(tlvType uint8) []ImageTlv {
- var tlvs []ImageTlv
+// FindTlvIndices searches an image for TLVs of the specified type and
+// returns their indices.
+func (i *Image) FindTlvIndices(tlvType uint8) []int {
+ var idxs []int
- for _, tlv := range i.Tlvs {
+ for i, tlv := range i.Tlvs {
if tlv.Header.Type == tlvType {
- tlvs = append(tlvs, tlv)
+ idxs = append(idxs, i)
}
}
+ return idxs
+}
+
+// FindTlvs retrieves all TLVs in an image's footer with the specified type.
+func (i *Image) FindTlvs(tlvType uint8) []*ImageTlv {
+ var tlvs []*ImageTlv
+
+ idxs := i.FindTlvIndices(tlvType)
+ for _, idx := range idxs {
+ tlvs = append(tlvs, &i.Tlvs[idx])
+ }
+
return tlvs
}
+// FindUniqueTlv retrieves a TLV in an image's footer with the specified
+// type. It returns an error if there is more than one TLV with this type.
func (i *Image) FindUniqueTlv(tlvType uint8) (*ImageTlv, error) {
tlvs := i.FindTlvs(tlvType)
if len(tlvs) == 0 {
@@ -304,9 +206,11 @@ func (i *Image) FindUniqueTlv(tlvType uint8) (*ImageTlv, error) {
len(tlvs), tlvType)
}
- return &tlvs[0], nil
+ return tlvs[0], nil
}
+// RemoveTlvsIf removes all TLVs from an image that satisfy the supplied
+// predicate. It returns a slice of the removed TLVs.
func (i *Image) RemoveTlvsIf(pred func(tlv ImageTlv) bool) []ImageTlv {
rmed := []ImageTlv{}
@@ -323,12 +227,15 @@ func (i *Image) RemoveTlvsIf(pred func(tlv ImageTlv) bool) []ImageTlv {
return rmed
}
+// RemoveTlvsWithType removes from an image all TLVs with the specified type.
+// It returns a slice of the removed TLVs.
func (i *Image) RemoveTlvsWithType(tlvType uint8) []ImageTlv {
return i.RemoveTlvsIf(func(tlv ImageTlv) bool {
return tlv.Header.Type == tlvType
})
}
+// ImageTrailer constructs an image trailer corresponding to the given image.
func (img *Image) Trailer() ImageTrailer {
trailer := ImageTrailer{
Magic: IMAGE_TRAILER_MAGIC,
@@ -341,6 +248,7 @@ func (img *Image) Trailer() ImageTrailer {
return trailer
}
+// Hash retrieves the contents of an image's SHA256 TLV.
func (i *Image) Hash() ([]byte, error) {
tlv, err := i.FindUniqueTlv(IMAGE_TLV_SHA256)
if err != nil {
@@ -355,10 +263,13 @@ func (i *Image) Hash() ([]byte, error) {
return tlv.Data, nil
}
+// CalcHash calculates a SHA256 of the given image.
func (i *Image) CalcHash() ([]byte, error) {
return calcHash(nil, i.Header, i.Pad, i.Body)
}
+// WritePlusOffsets writes a binary image to the given writer. It returns
+// the offsets of the image components that got written.
func (i *Image) WritePlusOffsets(w io.Writer) (ImageOffsets, error) {
offs := ImageOffsets{}
offset := 0
@@ -406,10 +317,13 @@ func (i *Image) WritePlusOffsets(w io.Writer) (ImageOffsets, error) {
return offs, nil
}
+// Offsets returns the offsets of each of an image's components if it were
+// serialized.
func (i *Image) Offsets() (ImageOffsets, error) {
return i.WritePlusOffsets(ioutil.Discard)
}
+// TotalSize returns the size of the image if it were serialized, in bytes.
func (i *Image) TotalSize() (int, error) {
offs, err := i.Offsets()
if err != nil {
@@ -418,6 +332,7 @@ func (i *Image) TotalSize() (int, error) {
return offs.TotalSize, nil
}
+// Write serializes and writes a Mynewt image.
func (i *Image) Write(w io.Writer) (int, error) {
offs, err := i.WritePlusOffsets(w)
if err != nil {
@@ -427,6 +342,7 @@ func (i *Image) Write(w io.Writer) (int, error) {
return offs.TotalSize, nil
}
+// WriteToFile writes a Mynewt image to a file.
func (i *Image) WriteToFile(filename string) error {
f, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if err != nil {
@@ -440,6 +356,8 @@ func (i *Image) WriteToFile(filename string) error {
return nil
}
+// CollectSigs returns a slice of all signatures present in an image's
+// trailer.
func (img *Image) CollectSigs() ([]sec.Sig, error) {
var sigs []sec.Sig
@@ -470,151 +388,3 @@ func (img *Image) CollectSigs() ([]sec.Sig, error) {
return sigs, nil
}
-
-func parseRawHeader(imgData []byte, offset int) (ImageHdr, int, error) {
- var hdr ImageHdr
-
- r := bytes.NewReader(imgData)
- r.Seek(int64(offset), io.SeekStart)
-
- if err := binary.Read(r, binary.LittleEndian, &hdr); err != nil {
- return hdr, 0, errors.Wrapf(err, "error reading image header")
- }
-
- if hdr.Magic != IMAGE_MAGIC {
- return hdr, 0, errors.Errorf(
- "image magic incorrect; expected 0x%08x, got 0x%08x",
- uint32(IMAGE_MAGIC), hdr.Magic)
- }
-
- remLen := len(imgData) - offset
- if remLen < int(hdr.HdrSz) {
- return hdr, 0, errors.Errorf(
- "image header incomplete; expected %d bytes, got %d bytes",
- hdr.HdrSz, remLen)
- }
-
- return hdr, int(hdr.HdrSz), nil
-}
-
-func parseRawBody(imgData []byte, hdr ImageHdr,
- offset int) ([]byte, int, error) {
-
- imgSz := int(hdr.ImgSz)
- remLen := len(imgData) - offset
-
- if remLen < imgSz {
- return nil, 0, errors.Errorf(
- "image body incomplete; expected %d bytes, got %d bytes",
- imgSz, remLen)
- }
-
- return imgData[offset : offset+imgSz], imgSz, nil
-}
-
-func parseRawTrailer(imgData []byte, offset int) (ImageTrailer, int, error) {
- var trailer ImageTrailer
-
- r := bytes.NewReader(imgData)
- r.Seek(int64(offset), io.SeekStart)
-
- if err := binary.Read(r, binary.LittleEndian, &trailer); err != nil {
- return trailer, 0, errors.Wrapf(err,
- "image contains invalid trailer at offset %d", offset)
- }
-
- return trailer, IMAGE_TRAILER_SIZE, nil
-}
-
-func parseRawTlv(imgData []byte, offset int) (ImageTlv, int, error) {
- tlv := ImageTlv{}
-
- r := bytes.NewReader(imgData)
- r.Seek(int64(offset), io.SeekStart)
-
- if err := binary.Read(r, binary.LittleEndian, &tlv.Header); err != nil {
- return tlv, 0, errors.Wrapf(err,
- "image contains invalid TLV at offset %d", offset)
- }
-
- tlv.Data = make([]byte, tlv.Header.Len)
- if _, err := r.Read(tlv.Data); err != nil {
- return tlv, 0, errors.Wrapf(err,
- "image contains invalid TLV at offset %d", offset)
- }
-
- return tlv, IMAGE_TLV_SIZE + int(tlv.Header.Len), nil
-}
-
-func ParseImage(imgData []byte) (Image, error) {
- img := Image{}
- offset := 0
-
- hdr, size, err := parseRawHeader(imgData, offset)
- if err != nil {
- return img, err
- }
- offset += size
-
- body, size, err := parseRawBody(imgData, hdr, offset)
- if err != nil {
- return img, err
- }
- offset += size
-
- trailer, size, err := parseRawTrailer(imgData, offset)
- if err != nil {
- return img, err
- }
- offset += size
-
- totalLen := IMAGE_HEADER_SIZE + len(body) + int(trailer.TlvTotLen)
- if len(imgData) < totalLen {
- return img, errors.Errorf("image data truncated: have=%d want=%d",
- len(imgData), totalLen)
- }
-
- // Trim excess data following image trailer.
- imgData = imgData[:totalLen]
-
- var tlvs []ImageTlv
- tlvLen := IMAGE_TRAILER_SIZE
- for offset < len(imgData) {
- tlv, size, err := parseRawTlv(imgData, offset)
- if err != nil {
- return img, err
- }
-
- tlvs = append(tlvs, tlv)
-
- offset += size
- if offset > len(imgData) {
- return img, errors.Errorf("TLVs extend beyond end of image")
- }
-
- tlvLen += size
- }
-
- if int(trailer.TlvTotLen) != tlvLen {
- return img, errors.Errorf(
- "invalid image: trailer indicates TLV-length=%d; actual=%d",
- trailer.TlvTotLen, tlvLen)
- }
-
- img.Header = hdr
- img.Body = body
- img.Tlvs = tlvs
-
- return img, nil
-}
-
-func ReadImage(filename string) (Image, error) {
- ri := Image{}
-
- imgData, err := ioutil.ReadFile(filename)
- if err != nil {
- return ri, errors.Wrapf(err, "failed to read image from file")
- }
-
- return ParseImage(imgData)
-}
diff --git a/image/image_test.go b/image/image_test.go
index 132e6fb..fb0d8df 100644
--- a/image/image_test.go
+++ b/image/image_test.go
@@ -78,7 +78,7 @@ func testOne(t *testing.T, e entry) {
}
}
- err = img.VerifyIntegrity()
+ err = img.Verify()
if !e.integrity {
if err == nil {
fatalErr("integrity", "good", "bad", nil)
@@ -93,7 +93,7 @@ func testOne(t *testing.T, e entry) {
man := readManifest(e.basename)
- err = img.ValidateManifest(man)
+ err = img.VerifyManifest(man)
if !e.man {
if err == nil {
fatalErr("manifest", "good", "bad", nil)
diff --git a/image/map.go b/image/map.go
new file mode 100644
index 0000000..76c6aa0
--- /dev/null
+++ b/image/map.go
@@ -0,0 +1,81 @@
+package image
+
+import (
+ "encoding/hex"
+ "encoding/json"
+
+ "github.com/apache/mynewt-artifact/errors"
+)
+
+func (h *ImageHdr) Map(offset int) map[string]interface{} {
+ return map[string]interface{}{
+ "_offset": offset,
+ "flags": h.Flags,
+ "hdr_sz": h.HdrSz,
+ "img_sz": h.ImgSz,
+ "magic": h.Magic,
+ "vers": h.Vers.String(),
+ }
+}
+
+func rawBodyMap(offset int) map[string]interface{} {
+ return map[string]interface{}{
+ "_offset": offset,
+ }
+}
+
+func (t *ImageTrailer) Map(offset int) map[string]interface{} {
+ return map[string]interface{}{
+ "_offset": offset,
+ "magic": t.Magic,
+ "tlv_tot_len": t.TlvTotLen,
+ }
+}
+
+func (t *ImageTlv) Map(index int, offset int) map[string]interface{} {
+ return map[string]interface{}{
+ "_index": index,
+ "_offset": offset,
+ "_typestr": ImageTlvTypeName(t.Header.Type),
+ "data": hex.EncodeToString(t.Data),
+ "len": t.Header.Len,
+ "type": t.Header.Type,
+ }
+}
+
+// Map produces a JSON-friendly map representation of an image.
+func (img *Image) Map() (map[string]interface{}, error) {
+ offs, err := img.Offsets()
+ if err != nil {
+ return nil, err
+ }
+
+ m := map[string]interface{}{}
+ m["header"] = img.Header.Map(offs.Header)
+ m["body"] = rawBodyMap(offs.Body)
+ trailer := img.Trailer()
+ m["trailer"] = trailer.Map(offs.Trailer)
+
+ tlvMaps := []map[string]interface{}{}
+ for i, tlv := range img.Tlvs {
+ tlvMaps = append(tlvMaps, tlv.Map(i, offs.Tlvs[i]))
+ }
+ m["tlvs"] = tlvMaps
+
+ return m, nil
+}
+
+// Json produces a JSON representation of an image.
+func (img *Image) Json() (string, error) {
+ m, err := img.Map()
+ if err != nil {
+ return "", err
+ }
+
+ b, err := json.MarshalIndent(m, "", " ")
+ if err != nil {
+ return "", errors.Wrapf(err, "failed to marshal image")
+ }
+
+ return string(b), nil
+}
diff --git a/image/parse.go b/image/parse.go
new file mode 100644
index 0000000..f1019a8
--- /dev/null
+++ b/image/parse.go
@@ -0,0 +1,200 @@
+package image
+
+import (
+ "bytes"
+ "encoding/binary"
+ "io"
+ "io/ioutil"
+ "strconv"
+ "strings"
+
+ "github.com/apache/mynewt-artifact/errors"
+)
+
+// ParseVersion parses an image version string (e.g., "1.2.3.4")
+func ParseVersion(versStr string) (ImageVersion, error) {
+ var err error
+ var major uint64
+ var minor uint64
+ var rev uint64
+ var buildNum uint64
+ var ver ImageVersion
+
+ components := strings.SplitN(versStr, ".", 4)
+ major, err = strconv.ParseUint(components[0], 10, 8)
+ if err != nil {
+ return ver, errors.Errorf("invalid version string %s", versStr)
+ }
+ if len(components) > 1 {
+ minor, err = strconv.ParseUint(components[1], 10, 8)
+ if err != nil {
+ return ver, errors.Errorf("invalid version string %s", versStr)
+ }
+ }
+ if len(components) > 2 {
+ rev, err = strconv.ParseUint(components[2], 10, 16)
+ if err != nil {
+ return ver, errors.Errorf("invalid version string %s", versStr)
+ }
+ }
+ if len(components) > 3 {
+ buildNum, err = strconv.ParseUint(components[3], 10, 32)
+ if err != nil {
+ return ver, errors.Errorf("invalid version string %s", versStr)
+ }
+ }
+
+ ver.Major = uint8(major)
+ ver.Minor = uint8(minor)
+ ver.Rev = uint16(rev)
+ ver.BuildNum = uint32(buildNum)
+ return ver, nil
+}
+
+func parseRawHeader(imgData []byte, offset int) (ImageHdr, int, error) {
+ var hdr ImageHdr
+
+ r := bytes.NewReader(imgData)
+ r.Seek(int64(offset), io.SeekStart)
+
+ if err := binary.Read(r, binary.LittleEndian, &hdr); err != nil {
+ return hdr, 0, errors.Wrapf(err, "error reading image header")
+ }
+
+ if hdr.Magic != IMAGE_MAGIC {
+ return hdr, 0, errors.Errorf(
+ "image magic incorrect; expected 0x%08x, got 0x%08x",
+ uint32(IMAGE_MAGIC), hdr.Magic)
+ }
+
+ remLen := len(imgData) - offset
+ if remLen < int(hdr.HdrSz) {
+ return hdr, 0, errors.Errorf(
+ "image header incomplete; expected %d bytes, got %d bytes",
+ hdr.HdrSz, remLen)
+ }
+
+ return hdr, int(hdr.HdrSz), nil
+}
+
+func parseRawBody(imgData []byte, hdr ImageHdr,
+ offset int) ([]byte, int, error) {
+
+ imgSz := int(hdr.ImgSz)
+ remLen := len(imgData) - offset
+
+ if remLen < imgSz {
+ return nil, 0, errors.Errorf(
+ "image body incomplete; expected %d bytes, got %d bytes",
+ imgSz, remLen)
+ }
+
+ return imgData[offset : offset+imgSz], imgSz, nil
+}
+
+func parseRawTrailer(imgData []byte, offset int) (ImageTrailer, int, error) {
+ var trailer ImageTrailer
+
+ r := bytes.NewReader(imgData)
+ r.Seek(int64(offset), io.SeekStart)
+
+ if err := binary.Read(r, binary.LittleEndian, &trailer); err != nil {
+ return trailer, 0, errors.Wrapf(err,
+ "image contains invalid trailer at offset %d", offset)
+ }
+
+ return trailer, IMAGE_TRAILER_SIZE, nil
+}
+
+func parseRawTlv(imgData []byte, offset int) (ImageTlv, int, error) {
+ tlv := ImageTlv{}
+
+ r := bytes.NewReader(imgData)
+ r.Seek(int64(offset), io.SeekStart)
+
+ if err := binary.Read(r, binary.LittleEndian, &tlv.Header); err != nil {
+ return tlv, 0, errors.Wrapf(err,
+ "image contains invalid TLV at offset %d", offset)
+ }
+
+ tlv.Data = make([]byte, tlv.Header.Len)
+ if _, err := r.Read(tlv.Data); err != nil {
+ return tlv, 0, errors.Wrapf(err,
+ "image contains invalid TLV at offset %d", offset)
+ }
+
+ return tlv, IMAGE_TLV_SIZE + int(tlv.Header.Len), nil
+}
+
+func ParseImage(imgData []byte) (Image, error) {
+ img := Image{}
+ offset := 0
+
+ hdr, size, err := parseRawHeader(imgData, offset)
+ if err != nil {
+ return img, err
+ }
+ offset += size
+
+ body, size, err := parseRawBody(imgData, hdr, offset)
+ if err != nil {
+ return img, err
+ }
+ offset += size
+
+ trailer, size, err := parseRawTrailer(imgData, offset)
+ if err != nil {
+ return img, err
+ }
+ offset += size
+
+ totalLen := IMAGE_HEADER_SIZE + len(body) + int(trailer.TlvTotLen)
+ if len(imgData) < totalLen {
+ return img, errors.Errorf("image data truncated: have=%d want=%d",
+ len(imgData), totalLen)
+ }
+
+ // Trim excess data following image trailer.
+ imgData = imgData[:totalLen]
+
+ var tlvs []ImageTlv
+ tlvLen := IMAGE_TRAILER_SIZE
+ for offset < len(imgData) {
+ tlv, size, err := parseRawTlv(imgData, offset)
+ if err != nil {
+ return img, err
+ }
+
+ tlvs = append(tlvs, tlv)
+
+ offset += size
+ if offset > len(imgData) {
+ return img, errors.Errorf("TLVs extend beyond end of image")
+ }
+
+ tlvLen += size
+ }
+
+ if int(trailer.TlvTotLen) != tlvLen {
+ return img, errors.Errorf(
+ "invalid image: trailer indicates TLV-length=%d; actual=%d",
+ trailer.TlvTotLen, tlvLen)
+ }
+
+ img.Header = hdr
+ img.Body = body
+ img.Tlvs = tlvs
+
+ return img, nil
+}
+
+func ReadImage(filename string) (Image, error) {
+ ri := Image{}
+
+ imgData, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return ri, errors.Wrapf(err, "failed to read image from file")
+ }
+
+ return ParseImage(imgData)
+}
diff --git a/manifest/manifest.go b/manifest/manifest.go
index 3a7298a..7508bc0 100644
--- a/manifest/manifest.go
+++ b/manifest/manifest.go
@@ -82,6 +82,7 @@ type Manifest struct {
LoaderPkgSizes []*ManifestSizePkg `json:"loader_pkgsz,omitempty"`
}
+// ReadManifest reads a JSON manifest from a file.
func ReadManifest(path string) (Manifest, error) {
m := Manifest{}
@@ -98,6 +99,7 @@ func ReadManifest(path string) (Manifest, error) {
return m, nil
}
+// Write serializes a manifest as JSON and writes it to the given writer.
func (m *Manifest) Write(w io.Writer) (int, error) {
buffer, err := json.MarshalIndent(m, "", " ")
if err != nil {
@@ -112,6 +114,8 @@ func (m *Manifest) Write(w io.Writer) (int, error) {
return cnt, nil
}
+// FindTargetVar searches a manifest's target definition for a setting with
+// the specified key. Examples of keys are: "app", "bsp", and "syscfg".
func (m *Manifest) FindTargetVar(key string) string {
for _, tv := range m.TgtVars {
parts := strings.SplitN(tv, "=", 2)
diff --git a/manifest/mfg_manifest.go b/manifest/mfg_manifest.go
index 3ebd22a..f742e12 100644
--- a/manifest/mfg_manifest.go
+++ b/manifest/mfg_manifest.go
@@ -75,6 +75,8 @@ type MfgManifest struct {
Meta *MfgManifestMeta `json:"meta,omitempty"`
}
+// ReadMfgManifest reads a JSON mfg manifest from a byte slice and produces an
+// MfgManifest object.
func ParseMfgManifest(jsonText []byte) (MfgManifest, error) {
m := MfgManifest{
// Backwards compatibility: assume 0xff if unspecified.
@@ -88,6 +90,8 @@ func ParseMfgManifest(jsonText []byte) (MfgManifest, error) {
return m, nil
}
+// ReadMfgManifest reads a JSON mfg manifest from a file and produces an
+// MfgManifest object.
func ReadMfgManifest(path string) (MfgManifest, error) {
content, err := ioutil.ReadFile(path)
if err != nil {
@@ -103,6 +107,12 @@ func ReadMfgManifest(path string) (MfgManifest, error) {
return m, nil
}
+// IsBoot indicates whether an mfg manifest target is a boot loader.
+func (mt *MfgManifestTarget) IsBoot() bool {
+ return mt.BinPath != ""
+}
+
+// MarshalJson produces a JSON representation of an mfg manifest.
func (m *MfgManifest) MarshalJson() ([]byte, error) {
buffer, err := json.MarshalIndent(m, "", " ")
if err != nil {
@@ -112,7 +122,9 @@ func (m *MfgManifest) MarshalJson() ([]byte, error) {
return buffer, nil
}
-func (m *MfgManifest) FindFlashArea(device int, offset int) *flash.FlashArea {
+// FindFlashAreaDevOff searches an mfg manifest for a flash area with the
+// specified device and offset.
+func (m *MfgManifest) FindFlashAreaDevOff(device int, offset int) *flash.FlashArea {
for i, _ := range m.FlashAreas {
fa := &m.FlashAreas[i]
if fa.Device == device && fa.Offset == offset {
@@ -123,6 +135,8 @@ func (m *MfgManifest) FindFlashArea(device int, offset int) *flash.FlashArea {
return nil
}
+// FindFlashAreaName searches an mfg manifest for a flash area with the
+// specified name.
func (m *MfgManifest) FindFlashAreaName(name string) *flash.FlashArea {
for i, _ := range m.FlashAreas {
fa := &m.FlashAreas[i]
@@ -134,6 +148,7 @@ func (m *MfgManifest) FindFlashAreaName(name string) *flash.FlashArea {
return nil
}
+// SecSig converts the provided mfg manifest signature into a sec.Sig object.
func (ms *MfgManifestSig) SecSig() (sec.Sig, error) {
keyHash, err := hex.DecodeString(ms.Key)
if err != nil {
@@ -153,6 +168,8 @@ func (ms *MfgManifestSig) SecSig() (sec.Sig, error) {
}, nil
}
+// SecSigs converts all the signutures in the provided mfg manifest into
+// sec.Sig objects.
func (m *MfgManifest) SecSigs() ([]sec.Sig, error) {
var sigs []sec.Sig
for _, ms := range m.Signatures {
@@ -166,7 +183,3 @@ func (m *MfgManifest) SecSigs() ([]sec.Sig, error) {
return sigs, nil
}
-
-func (mt *MfgManifestTarget) IsBoot() bool {
- return mt.BinPath != ""
-}
diff --git a/mfg/map_meta.go b/mfg/map_meta.go
index 19b1ee8..99714ff 100644
--- a/mfg/map_meta.go
+++ b/mfg/map_meta.go
@@ -86,6 +86,7 @@ func (b *MetaTlvBodyMmrRef) Map() map[string]interface{} {
}
}
+// Map produces a JSON-friendly map representation of an MMR TLV.
func (t *MetaTlv) Map(index int, offset int) map[string]interface{} {
hmap := map[string]interface{}{
"_type_name": MetaTlvTypeName(t.Header.Type),
@@ -110,6 +111,7 @@ func (t *MetaTlv) Map(index int, offset int) map[string]interface{} {
}
}
+// Map produces a JSON-friendly map representation of an MMR footer.
func (f *MetaFooter) Map(offset int) map[string]interface{} {
return map[string]interface{}{
"_offset": offset,
@@ -119,6 +121,7 @@ func (f *MetaFooter) Map(offset int) map[string]interface{} {
}
}
+// Map produces a JSON-friendly map representation of an MMR.
func (m *Meta) Map(endOffset int) map[string]interface{} {
offsets := m.Offsets()
startOffset := endOffset - int(m.Footer.Size)
@@ -140,6 +143,7 @@ func (m *Meta) Map(endOffset int) map[string]interface{} {
}
}
+// Json produces a JSON representation of an MMR.
func (m *Meta) Json(offset int) (string, error) {
mmap := m.Map(offset)
diff --git a/mfg/meta.go b/mfg/meta.go
index b4786bc..1e7029c 100644
--- a/mfg/meta.go
+++ b/mfg/meta.go
@@ -160,6 +160,8 @@ func (tlv *MetaTlv) Write(w io.Writer) (int, error) {
return sz, nil
}
+// StructuredBody constructs the appropriate "body" object from a raw TLV
+// (e.g., MetaTlvBodyHash from a TLV with type=META_TLV_TYPE_HASH).
func (tlv *MetaTlv) StructuredBody() (interface{}, error) {
r := bytes.NewReader(tlv.Data)
@@ -197,6 +199,8 @@ func (tlv *MetaTlv) StructuredBody() (interface{}, error) {
}
}
+// WritePlusOffsets writes a binary MMR to the given writer. It returns the
+// offsets of the mfgimage components that got written.
func (meta *Meta) WritePlusOffsets(w io.Writer) (MetaOffsets, error) {
mo := MetaOffsets{}
sz := 0
@@ -221,11 +225,14 @@ func (meta *Meta) WritePlusOffsets(w io.Writer) (MetaOffsets, error) {
return mo, nil
}
+// Offsets returns the offsets of each of an MMR's components if it were
+// serialized.
func (meta *Meta) Offsets() MetaOffsets {
mo, _ := meta.WritePlusOffsets(ioutil.Discard)
return mo
}
+// Write serializes and writes an MMR.
func (meta *Meta) Write(w io.Writer) (int, error) {
mo, err := meta.WritePlusOffsets(w)
if err != nil {
@@ -235,10 +242,12 @@ func (meta *Meta) Write(w io.Writer) (int, error) {
return mo.TotalSize, nil
}
+// Size calculates the total size of an MMR if it were serialied.
func (meta *Meta) Size() int {
return meta.Offsets().TotalSize
}
+// Bytes serializes an MMR to binary form.
func (meta *Meta) Bytes() ([]byte, error) {
b := &bytes.Buffer{}
@@ -250,6 +259,8 @@ func (meta *Meta) Bytes() ([]byte, error) {
return b.Bytes(), nil
}
+// FindTlvIndices searches an MMR for TLVs of the specified type and returns
+// their indices.
func (meta *Meta) FindTlvIndices(typ uint8) []int {
indices := []int{}
@@ -262,6 +273,7 @@ func (meta *Meta) FindTlvIndices(typ uint8) []int {
return indices
}
+// FindTlvIndices searches an MMR for all TLVs of the specified type.
func (meta *Meta) FindTlvs(typ uint8) []*MetaTlv {
indices := meta.FindTlvIndices(typ)
@@ -273,15 +285,18 @@ func (meta *Meta) FindTlvs(typ uint8) []*MetaTlv {
return tlvs
}
+// FindTlvIndices searches an MMR for the first TLV of the specified type.
func (meta *Meta) FindFirstTlv(typ uint8) *MetaTlv {
- indices := meta.FindTlvIndices(typ)
- if len(indices) == 0 {
+ tlvs := meta.FindTlvs(typ)
+ if len(tlvs) == 0 {
return nil
}
- return &meta.Tlvs[indices[0]]
+ return tlvs[0]
}
+// HashOffset calculates the offset of the SHA256 TLV in an MMR if it were
+// serialized.
func (meta *Meta) HashOffset() int {
mo := meta.Offsets()
indices := meta.FindTlvIndices(META_TLV_TYPE_HASH)
@@ -292,6 +307,7 @@ func (meta *Meta) HashOffset() int {
return META_TLV_HEADER_SZ + mo.Tlvs[indices[0]]
}
+// ClearHash zeroes out an MMRs SHA256 TLV.
func (meta *Meta) ClearHash() {
tlv := meta.FindFirstTlv(META_TLV_TYPE_HASH)
if tlv != nil {
@@ -299,6 +315,8 @@ func (meta *Meta) ClearHash() {
}
}
+// Hash locates an MMR's SHA256 TLV and returns its value. It returns nil if
+// the MMR doesn't have a SHA256 TLV.
func (meta *Meta) Hash() []byte {
tlv := meta.FindFirstTlv(META_TLV_TYPE_HASH)
if tlv == nil {
@@ -307,15 +325,15 @@ func (meta *Meta) Hash() []byte {
return tlv.Data
}
+// Clone performs a deep copy of an MMR.
func (meta *Meta) Clone() Meta {
- var tlvs []MetaTlv
- for _, src := range meta.Tlvs {
- dst := MetaTlv{
+ tlvs := make([]MetaTlv, len(meta.Tlvs))
+ for i, src := range meta.Tlvs {
+ tlvs[i] = MetaTlv{
Header: src.Header,
Data: make([]byte, len(src.Data)),
}
- copy(dst.Data, src.Data)
- tlvs = append(tlvs, dst)
+ copy(tlvs[i].Data, src.Data)
}
return Meta{
@@ -323,83 +341,3 @@ func (meta *Meta) Clone() Meta {
Footer: meta.Footer,
}
}
-
-func parseMetaTlv(bin []byte) (MetaTlv, int, error) {
- r := bytes.NewReader(bin)
-
- tlv := MetaTlv{}
- if err := binary.Read(r, binary.LittleEndian, &tlv.Header); err != nil {
- return tlv, 0, errors.Wrapf(err, "error reading TLV header")
- }
-
- data := make([]byte, tlv.Header.Size)
- sz, err := r.Read(data)
- if err != nil {
- return tlv, 0, errors.Wrapf(err,
- "error reading %d bytes of TLV data",
- tlv.Header.Size)
- }
- if sz != len(data) {
- return tlv, 0, errors.Errorf(
- "error reading %d bytes of TLV data: incomplete read",
- tlv.Header.Size)
- }
- tlv.Data = data
-
- return tlv, META_TLV_HEADER_SZ + int(tlv.Header.Size), nil
-}
-
-func parseMetaFooter(bin []byte) (MetaFooter, int, error) {
- r := bytes.NewReader(bin)
-
- var ftr MetaFooter
- if err := binary.Read(r, binary.LittleEndian, &ftr); err != nil {
- return ftr, 0, errors.Wrapf(err,
- "error reading meta footer")
- }
-
- if ftr.Magic != META_MAGIC {
- return ftr, 0, errors.Errorf(
- "meta footer contains invalid magic; exp:0x%08x, got:0x%08x",
- META_MAGIC, ftr.Magic)
- }
-
- return ftr, META_FOOTER_SZ, nil
-}
-
-func ParseMeta(bin []byte) (Meta, int, error) {
- if len(bin) < META_FOOTER_SZ {
- return Meta{}, 0, errors.Errorf(
- "binary too small to accommodate meta footer; "+
- "bin-size=%d ftr-size=%d", len(bin), META_FOOTER_SZ)
- }
-
- ftr, _, err := parseMetaFooter(bin[len(bin)-META_FOOTER_SZ:])
- if err != nil {
- return Meta{}, 0, err
- }
-
- if int(ftr.Size) > len(bin) {
- return Meta{}, 0, errors.Errorf(
- "binary too small to accommodate meta region; "+
- "bin-size=%d meta-size=%d", len(bin), ftr.Size)
- }
-
- ftrOff := len(bin) - META_FOOTER_SZ
- off := len(bin) - int(ftr.Size)
-
- tlvs := []MetaTlv{}
- for off < ftrOff {
- tlv, sz, err := parseMetaTlv(bin[off:])
- if err != nil {
- return Meta{}, 0, err
- }
- tlvs = append(tlvs, tlv)
- off += sz
- }
-
- return Meta{
- Tlvs: tlvs,
- Footer: ftr,
- }, off, nil
-}
diff --git a/mfg/mfg.go b/mfg/mfg.go
index eea6abf..2667003 100644
--- a/mfg/mfg.go
+++ b/mfg/mfg.go
@@ -20,7 +20,6 @@
package mfg
import (
- "bytes"
"crypto/sha256"
"github.com/apache/mynewt-artifact/errors"
@@ -39,33 +38,9 @@ type Mfg struct {
MetaOff int
}
-func Parse(data []byte, metaEndOff int, eraseVal byte) (Mfg, error) {
- m := Mfg{
- Bin: data,
- }
-
- if metaEndOff >= 0 {
- if metaEndOff > len(data) {
- return m, errors.Errorf(
- "MMR offset (%d) beyond end of mfgimage (%d)",
- metaEndOff, len(data))
- }
-
- meta, _, err := ParseMeta(data[:metaEndOff])
- if err != nil {
- return m, err
- }
- m.Meta = &meta
- m.MetaOff = metaEndOff - int(meta.Footer.Size)
-
- for i := 0; i < int(meta.Footer.Size); i++ {
- m.Bin[m.MetaOff+i] = eraseVal
- }
- }
-
- return m, nil
-}
-
+// StripPadding produces a new byte slice by removing padding from an
+// existing byte slice. Padding is defined as a sequence of trailing bytes,
+// all with the specified value.
func StripPadding(b []byte, eraseVal byte) []byte {
var pad int
for pad = 0; pad < len(b); pad++ {
@@ -78,6 +53,8 @@ func StripPadding(b []byte, eraseVal byte) []byte {
return b[:len(b)-pad]
}
+// AddPadding produces a new byte slice by adding extra bytes to the end of
+// an existing slice.
func AddPadding(b []byte, eraseVal byte, padLen int) []byte {
for i := 0; i < padLen; i++ {
b = append(b, eraseVal)
@@ -114,8 +91,10 @@ func (m *Mfg) RecalcHash(eraseVal byte) ([]byte, error) {
return CalcHash(bin), nil
}
+// RefillHash replace's the contents of an mfgimage's SHA256 TLV with a newly
+// calculated hash.
func (m *Mfg) RefillHash(eraseVal byte) error {
- if m.Meta == nil || m.Meta.Hash() == nil {
+ if m.Meta == nil {
return nil
}
tlv := m.Meta.FindFirstTlv(META_TLV_TYPE_HASH)
@@ -135,6 +114,9 @@ func (m *Mfg) RefillHash(eraseVal byte) error {
return nil
}
+// Hash retrieves the SHA256 value associated with an mfgimage. If the
+// mfgimage has an MMR with a SHA256 TLV, the TLV's value is returned.
+// Otherwise, the hash is calculated and returned.
func (m *Mfg) Hash(eraseVal byte) ([]byte, error) {
var hashBytes []byte
@@ -154,21 +136,7 @@ func (m *Mfg) Hash(eraseVal byte) ([]byte, error) {
return hashBytes, nil
}
-func (m *Mfg) HashIsValid(eraseVal byte) (bool, error) {
- // If the mfg doesn't contain a hash TLV, then there is nothing to verify.
- tlv := m.Meta.FindFirstTlv(META_TLV_TYPE_HASH)
- if tlv == nil {
- return true, nil
- }
-
- hash, err := m.RecalcHash(eraseVal)
- if err != nil {
- return false, err
- }
-
- return bytes.Equal(hash, tlv.Data), nil
-}
-
+// Bytes serializes an mfgimage into binary form.
func (m *Mfg) Bytes(eraseVal byte) ([]byte, error) {
binCopy := make([]byte, len(m.Bin))
copy(binCopy, m.Bin)
@@ -188,6 +156,7 @@ func (m *Mfg) Bytes(eraseVal byte) ([]byte, error) {
return binCopy, nil
}
+// Clone performs a deep copy of an mfgimage.
func (m *Mfg) Clone() Mfg {
var meta *Meta
if m.Meta != nil {
@@ -205,7 +174,11 @@ func (m *Mfg) Clone() Mfg {
}
}
-func (m *Mfg) ExtractFlashArea(area flash.FlashArea, eraseVal byte) ([]byte, error) {
+// ExtractFlashArea copies a portion out of a serialized mfgimage. The
+// offset and size to copy indicated by the provided FlashArea.
+func (m *Mfg) ExtractFlashArea(area flash.FlashArea,
+ eraseVal byte) ([]byte, error) {
+
b, err := m.Bytes(eraseVal)
if err != nil {
return nil, err
@@ -228,6 +201,8 @@ func (m *Mfg) ExtractFlashArea(area flash.FlashArea, eraseVal byte) ([]byte, err
return b[area.Offset:end], nil
}
+// Tlvs retrieves the slice of TLVs present in an mfgimage's MMR. It returns
+// nil if the mfgimage has no MMR.
func (m *Mfg) Tlvs() []MetaTlv {
if m.Meta == nil {
return nil
diff --git a/mfg/mfg_test.go b/mfg/mfg_test.go
index 5e7d8ff..a2e503e 100644
--- a/mfg/mfg_test.go
+++ b/mfg/mfg_test.go
@@ -86,7 +86,7 @@ func testOne(t *testing.T, e entry) {
}
}
- err = m.VerifyIntegrity(man.EraseVal)
+ err = m.Verify(man.EraseVal)
if !e.integrity {
if err == nil {
fatalErr("integrity", "good", "bad", nil)
@@ -99,7 +99,7 @@ func testOne(t *testing.T, e entry) {
}
}
- err = m.ValidateManifest(man)
+ err = m.VerifyManifest(man)
if !e.man {
if err == nil {
fatalErr("manifest", "good", "bad", nil)
diff --git a/mfg/parse.go b/mfg/parse.go
new file mode 100644
index 0000000..1d4e4b7
--- /dev/null
+++ b/mfg/parse.go
@@ -0,0 +1,118 @@
+package mfg
+
+import (
+ "bytes"
+ "encoding/binary"
+
+ "github.com/apache/mynewt-artifact/errors"
+)
+
+func parseMetaFooter(bin []byte) (MetaFooter, int, error) {
+ r := bytes.NewReader(bin)
+
+ var ftr MetaFooter
+ if err := binary.Read(r, binary.LittleEndian, &ftr); err != nil {
+ return ftr, 0, errors.Wrapf(err,
+ "error reading meta footer")
+ }
+
+ if ftr.Magic != META_MAGIC {
+ return ftr, 0, errors.Errorf(
+ "meta footer contains invalid magic; exp:0x%08x, got:0x%08x",
+ META_MAGIC, ftr.Magic)
+ }
+
+ return ftr, META_FOOTER_SZ, nil
+}
+
+func parseMetaTlv(bin []byte) (MetaTlv, int, error) {
+ r := bytes.NewReader(bin)
+
+ tlv := MetaTlv{}
+ if err := binary.Read(r, binary.LittleEndian, &tlv.Header); err != nil {
+ return tlv, 0, errors.Wrapf(err, "error reading TLV header")
+ }
+
+ data := make([]byte, tlv.Header.Size)
+ sz, err := r.Read(data)
+ if err != nil {
+ return tlv, 0, errors.Wrapf(err,
+ "error reading %d bytes of TLV data",
+ tlv.Header.Size)
+ }
+ if sz != len(data) {
+ return tlv, 0, errors.Errorf(
+ "error reading %d bytes of TLV data: incomplete read",
+ tlv.Header.Size)
+ }
+ tlv.Data = data
+
+ return tlv, META_TLV_HEADER_SZ + int(tlv.Header.Size), nil
+}
+
+func parseMeta(bin []byte) (Meta, error) {
+ if len(bin) < META_FOOTER_SZ {
+ return Meta{}, errors.Errorf(
+ "binary too small to accommodate meta footer; "+
+ "bin-size=%d ftr-size=%d", len(bin), META_FOOTER_SZ)
+ }
+
+ ftr, _, err := parseMetaFooter(bin[len(bin)-META_FOOTER_SZ:])
+ if err != nil {
+ return Meta{}, err
+ }
+
+ if int(ftr.Size) > len(bin) {
+ return Meta{}, errors.Errorf(
+ "binary too small to accommodate meta region; "+
+ "bin-size=%d meta-size=%d", len(bin), ftr.Size)
+ }
+
+ ftrOff := len(bin) - META_FOOTER_SZ
+ off := len(bin) - int(ftr.Size)
+
+ tlvs := []MetaTlv{}
+ for off < ftrOff {
+ tlv, sz, err := parseMetaTlv(bin[off:])
+ if err != nil {
+ return Meta{}, err
+ }
+ tlvs = append(tlvs, tlv)
+ off += sz
+ }
+
+ return Meta{
+ Tlvs: tlvs,
+ Footer: ftr,
+ }, nil
+}
+
+// Parse parses a serialized mfgimage (e.g., "mfgimg.bin") and produces an
+// Mfg object. metaEndOff is the offset immediately following the MMR, or -1
+// if there is no MMR.
+func Parse(data []byte, metaEndOff int, eraseVal byte) (Mfg, error) {
+ m := Mfg{
+ Bin: data,
+ }
+
+ if metaEndOff >= 0 {
+ if metaEndOff > len(data) {
+ return m, errors.Errorf(
+ "MMR offset (%d) beyond end of mfgimage (%d)",
+ metaEndOff, len(data))
+ }
+
+ meta, err := parseMeta(data[:metaEndOff])
+ if err != nil {
+ return m, err
+ }
+ m.Meta = &meta
+ m.MetaOff = metaEndOff - int(meta.Footer.Size)
+
+ for i := 0; i < int(meta.Footer.Size); i++ {
+ m.Bin[m.MetaOff+i] = eraseVal
+ }
+ }
+
+ return m, nil
+}
diff --git a/mfg/verify.go b/mfg/verify.go
index 17a5a76..ffa2817 100644
--- a/mfg/verify.go
+++ b/mfg/verify.go
@@ -105,7 +105,7 @@ func (m *Mfg) validateManMmrs(man manifest.MfgManifest) error {
func (m *Mfg) validateManTargets(man manifest.MfgManifest) error {
for _, t := range man.Targets {
- fa := man.FindFlashArea(man.Device, t.Offset)
+ fa := man.FindFlashAreaDevOff(man.Device, t.Offset)
if fa == nil {
return errors.Errorf(
"no flash area in mfgimage corresponding to target \"%s\"",
diff --git a/misc/misc.go b/misc/misc.go
deleted file mode 100644
index 2f685e1..0000000
--- a/misc/misc.go
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package misc
-
-import (
- "fmt"
-)
-
-func HashString(hash []byte) string {
- return fmt.Sprintf("%x", hash)
-}
diff --git a/sec/key.go b/sec/key.go
index 473ef62..dabbd1f 100644
--- a/sec/key.go
+++ b/sec/key.go
@@ -168,7 +168,7 @@ func (key *SignKey) PubKey() PubSignKey {
func (key *SignKey) PubBytes() ([]byte, error) {
pk := key.PubKey()
- return pk.PubBytes()
+ return pk.Bytes()
}
func RawKeyHash(pubKeyBytes []byte) []byte {
@@ -256,18 +256,15 @@ func DecryptSecretRsa(privk *rsa.PrivateKey,
func ParseKeBase64(keyBytes []byte) (cipher.Block, error) {
kek, err := base64.StdEncoding.DecodeString(string(keyBytes))
if err != nil {
- return nil, errors.Wrapf(err,
- "Error decoding kek: %s")
+ return nil, errors.Wrapf(err, "error decoding kek")
}
if len(kek) != 16 {
- return nil, errors.Errorf(
- "Unexpected key size: %d != 16", len(kek))
+ return nil, errors.Errorf("unexpected key size: %d != 16", len(kek))
}
cipher, err := aes.NewCipher(kek)
if err != nil {
- return nil, errors.Wrapf(err,
- "Error creating keywrap cipher")
+ return nil, errors.Wrapf(err, "error creating keywrap cipher")
}
return cipher, nil
@@ -276,7 +273,7 @@ func ParseKeBase64(keyBytes []byte) (cipher.Block, error) {
func EncryptSecretAes(c cipher.Block, plainSecret []byte) ([]byte, error) {
cipherSecret, err := keywrap.Wrap(c, plainSecret)
if err != nil {
- return nil, errors.Wrapf(err, "Error key-wrapping")
+ return nil, errors.Wrapf(err, "error key-wrapping")
}
return cipherSecret, nil
@@ -288,14 +285,14 @@ func (key *PubSignKey) AssertValid() {
}
}
-func (key *PubSignKey) PubBytes() ([]byte, error) {
+func (key *PubSignKey) Bytes() ([]byte, error) {
key.AssertValid()
- var pubBytes []byte
+ var b []byte
if key.Rsa != nil {
var err error
- pubBytes, err = asn1.Marshal(*key.Rsa)
+ b, err = asn1.Marshal(*key.Rsa)
if err != nil {
return nil, err
}
@@ -304,11 +301,11 @@ func (key *PubSignKey) PubBytes() ([]byte, error) {
case "P-224":
fallthrough
case "P-256":
- pubBytes, _ = x509.MarshalPKIXPublicKey(*key.Ec)
+ b, _ = x509.MarshalPKIXPublicKey(*key.Ec)
default:
return nil, errors.Errorf("unsupported ECC curve")
}
}
- return pubBytes, nil
+ return b, nil
}
diff --git a/sec/sig.go b/sec/sig.go
index 8aa0b32..d6b8ffe 100644
--- a/sec/sig.go
+++ b/sec/sig.go
@@ -14,7 +14,7 @@ type Sig struct {
}
func checkOneKeyOneSig(k PubSignKey, sig Sig, hash []byte) (bool, error) {
- pubBytes, err := k.PubBytes()
+ pubBytes, err := k.Bytes()
if err != nil {
return false, errors.WithStack(err)
}