You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ut...@apache.org on 2019/10/21 17:51:39 UTC
[mynewt-artifact] branch master updated: Add support for protected
TLVs
This is an automated email from the ASF dual-hosted git repository.
utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-artifact.git
The following commit(s) were added to refs/heads/master by this push:
new 8fa4247 Add support for protected TLVs
8fa4247 is described below
commit 8fa4247999900fdd35a1bb60e8105711af884ffd
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Tue Oct 15 10:57:11 2019 -0300
Add support for protected TLVs
Protected TLVs is a new feature supported by MCUBoot beginning with
version 1.4.0. This allows the hash+signature to also include a few TLVs
that should be protected from modification by users. For more details:
https://github.com/JuulLabs-OSS/mcuboot/blob/master/docs/design.md#protected-tlvs
---
image/create.go | 81 +++++++++++++++++++++++++++++++++++---------------
image/image.go | 91 +++++++++++++++++++++++++++++++++++++++++----------------
2 files changed, 124 insertions(+), 48 deletions(-)
diff --git a/image/create.go b/image/create.go
index 8783b70..c51cfe6 100644
--- a/image/create.go
+++ b/image/create.go
@@ -337,7 +337,7 @@ func GenerateImage(opts ImageCreateOpts) (Image, error) {
}
func calcHash(initialHash []byte, hdr ImageHdr, pad []byte,
- plainBody []byte) ([]byte, error) {
+ plainBody []byte, protTlvs []ImageTlv) ([]byte, error) {
hash := sha256.New()
@@ -371,22 +371,53 @@ func calcHash(initialHash []byte, hdr ImageHdr, pad []byte,
return nil, err
}
+ if len(protTlvs) > 0 {
+ trailer := ImageTrailer{
+ Magic: IMAGE_PROT_TRAILER_MAGIC,
+ TlvTotLen: hdr.ProtSz,
+ }
+ if err := add(trailer); err != nil {
+ return nil, err
+ }
+
+ for _, tlv := range protTlvs {
+ if err := add(tlv.Header); err != nil {
+ return nil, err
+ }
+ if err := add(tlv.Data); err != nil {
+ return nil, err
+ }
+ }
+ }
+
return hash.Sum(nil), nil
}
+func calcProtSize(protTlvs []ImageTlv) uint16 {
+ var size = uint16(0)
+ for _, tlv := range protTlvs {
+ size += IMAGE_TLV_SIZE
+ size += tlv.Header.Len
+ }
+ if size > 0 {
+ size += IMAGE_TRAILER_SIZE
+ }
+ return size
+}
+
func (ic *ImageCreator) Create() (Image, error) {
img := Image{}
// First the header
img.Header = ImageHdr{
- Magic: IMAGE_MAGIC,
- Pad1: 0,
- HdrSz: IMAGE_HEADER_SIZE,
- Pad2: 0,
- ImgSz: uint32(len(ic.Body)),
- Flags: 0,
- Vers: ic.Version,
- Pad3: 0,
+ Magic: IMAGE_MAGIC,
+ Pad1: 0,
+ HdrSz: IMAGE_HEADER_SIZE,
+ ProtSz: 0,
+ ImgSz: uint32(len(ic.Body)),
+ Flags: 0,
+ Vers: ic.Version,
+ Pad3: 0,
}
if !ic.Bootable {
@@ -411,6 +442,22 @@ func (ic *ImageCreator) Create() (Image, error) {
img.Pad = make([]byte, extra)
}
+ if ic.HWKeyIndex >= 0 {
+ tlv, err := GenerateHWKeyIndexTLV(uint32(ic.HWKeyIndex))
+ if err != nil {
+ return img, err
+ }
+ img.ProtTlvs = append(img.ProtTlvs, tlv)
+
+ tlv, err = GenerateNonceTLV(ic.Nonce)
+ if err != nil {
+ return img, err
+ }
+ img.ProtTlvs = append(img.ProtTlvs, tlv)
+ }
+
+ img.Header.ProtSz = calcProtSize(img.ProtTlvs)
+
payload := &ic.Body
// Followed by data.
@@ -429,7 +476,7 @@ func (ic *ImageCreator) Create() (Image, error) {
img.Body = append(img.Body, ic.Body...)
}
- hashBytes, err := calcHash(ic.InitialHash, img.Header, img.Pad, *payload)
+ hashBytes, err := calcHash(ic.InitialHash, img.Header, img.Pad, *payload, img.ProtTlvs)
if err != nil {
return img, err
}
@@ -451,19 +498,7 @@ func (ic *ImageCreator) Create() (Image, error) {
}
img.Tlvs = append(img.Tlvs, tlvs...)
- if ic.HWKeyIndex > 0 {
- tlv, err := GenerateHWKeyIndexTLV(uint32(ic.HWKeyIndex))
- if err != nil {
- return img, err
- }
- img.Tlvs = append(img.Tlvs, tlv)
-
- tlv, err = GenerateNonceTLV(ic.Nonce)
- if err != nil {
- return img, err
- }
- img.Tlvs = append(img.Tlvs, tlv)
- } else if ic.CipherSecret != nil {
+ if ic.HWKeyIndex < 0 && ic.CipherSecret != nil {
tlv, err := GenerateEncTlv(ic.CipherSecret)
if err != nil {
return img, err
diff --git a/image/image.go b/image/image.go
index 6387393..9cba94a 100644
--- a/image/image.go
+++ b/image/image.go
@@ -31,8 +31,9 @@ import (
)
const (
- IMAGE_MAGIC = 0x96f3b83d /* Image header magic */
- IMAGE_TRAILER_MAGIC = 0x6907 /* Image tlv info magic */
+ IMAGE_MAGIC = 0x96f3b83d /* Image header magic */
+ IMAGE_TRAILER_MAGIC = 0x6907 /* TLV info magic */
+ IMAGE_PROT_TRAILER_MAGIC = 0x6908 /* Protected TLV info magic */
)
const (
@@ -89,14 +90,14 @@ type ImageVersion struct {
}
type ImageHdr struct {
- Magic uint32
- Pad1 uint32
- HdrSz uint16
- Pad2 uint16
- ImgSz uint32
- Flags uint32
- Vers ImageVersion
- Pad3 uint32
+ Magic uint32
+ Pad1 uint32
+ HdrSz uint16
+ ProtSz uint16
+ ImgSz uint32
+ Flags uint32
+ Vers ImageVersion
+ Pad3 uint32
}
type ImageTlvHdr struct {
@@ -116,18 +117,21 @@ type ImageTrailer struct {
}
type Image struct {
- Header ImageHdr
- Pad []byte
- Body []byte
- Tlvs []ImageTlv
+ Header ImageHdr
+ Pad []byte
+ Body []byte
+ ProtTlvs []ImageTlv
+ Tlvs []ImageTlv
}
type ImageOffsets struct {
- Header int
- Body int
- Trailer int
- Tlvs []int
- TotalSize int
+ Header int
+ Body int
+ ProtTrailer int
+ Trailer int
+ ProtTlvs []int
+ Tlvs []int
+ TotalSize int
}
func ImageTlvTypeIsValid(tlvType uint8) bool {
@@ -190,10 +194,15 @@ func (tlv *ImageTlv) Write(w io.Writer) (int, error) {
// Clone performs a deep copy of an image.
func (img *Image) Clone() Image {
dup := Image{
- Header: img.Header,
- Pad: append([]byte(nil), img.Pad...),
- Body: append([]byte(nil), img.Body...),
- Tlvs: make([]ImageTlv, len(img.Tlvs)),
+ Header: img.Header,
+ Pad: append([]byte(nil), img.Pad...),
+ Body: append([]byte(nil), img.Body...),
+ ProtTlvs: make([]ImageTlv, len(img.ProtTlvs)),
+ Tlvs: make([]ImageTlv, len(img.Tlvs)),
+ }
+
+ for i, tlv := range img.ProtTlvs {
+ dup.ProtTlvs[i] = tlv.Clone()
}
for i, tlv := range img.Tlvs {
@@ -291,7 +300,20 @@ func (i *Image) RemoveTlvsWithType(tlvType uint8) []ImageTlv {
})
}
-// ImageTrailer constructs an image trailer corresponding to the given image.
+// ProtTrailer constructs a protected ImageTrailer corresponding to the given image.
+func (img *Image) ProtTrailer() ImageTrailer {
+ trailer := ImageTrailer{
+ Magic: IMAGE_PROT_TRAILER_MAGIC,
+ TlvTotLen: IMAGE_TRAILER_SIZE,
+ }
+ for _, tlv := range img.ProtTlvs {
+ trailer.TlvTotLen += IMAGE_TLV_SIZE + tlv.Header.Len
+ }
+
+ return trailer
+}
+
+// Trailer constructs an ImageTrailer corresponding to the given image.
func (img *Image) Trailer() ImageTrailer {
trailer := ImageTrailer{
Magic: IMAGE_TRAILER_MAGIC,
@@ -321,7 +343,7 @@ func (i *Image) Hash() ([]byte, error) {
// CalcHash calculates a SHA256 of the given image.
func (i *Image) CalcHash() ([]byte, error) {
- return calcHash(nil, i.Header, i.Pad, i.Body)
+ return calcHash(nil, i.Header, i.Pad, i.Body, i.ProtTlvs)
}
// WritePlusOffsets writes a binary image to the given writer. It returns
@@ -351,6 +373,25 @@ func (i *Image) WritePlusOffsets(w io.Writer) (ImageOffsets, error) {
}
offset += size
+ if i.Header.ProtSz > 0 {
+ protTrailer := i.ProtTrailer()
+ offs.ProtTrailer = offset
+ err = binary.Write(w, binary.LittleEndian, &protTrailer)
+ if err != nil {
+ return offs, errors.Wrapf(err, "failed to write image trailer")
+ }
+ offset += IMAGE_TRAILER_SIZE
+
+ for _, tlv := range i.ProtTlvs {
+ offs.ProtTlvs = append(offs.ProtTlvs, offset)
+ size, err := tlv.Write(w)
+ if err != nil {
+ return offs, errors.Wrapf(err, "failed to write image TLV")
+ }
+ offset += size
+ }
+ }
+
trailer := i.Trailer()
offs.Trailer = offset
err = binary.Write(w, binary.LittleEndian, &trailer)