Merge pull request #29 from agross-korg/section-tlv-changes

image: Add support for section TLV
diff --git a/image/create.go b/image/create.go
index ff5d400..176c085 100644
--- a/image/create.go
+++ b/image/create.go
@@ -41,6 +41,7 @@
 	Body         []byte
 	Version      ImageVersion
 	SigKeys      []sec.PrivSignKey
+	Sections     []Section
 	HWKeyIndex   int
 	Nonce        []byte
 	PlainSecret  []byte
@@ -56,6 +57,7 @@
 	SrcEncKeyIndex    int
 	Version           ImageVersion
 	SigKeys           []sec.PrivSignKey
+	Sections          []Section
 	LoaderHash        []byte
 	HdrPad            int
 	ImagePad          int
@@ -150,6 +152,24 @@
 	}, nil
 }
 
+// GenerateEncTlv creates an encryption-secret TLV given a secret.
+func GenerateSectionTlv(section Section) (ImageTlv, error) {
+	data := make([]byte, 8 + len(section.Name))
+
+	binary.LittleEndian.PutUint32(data[0:], uint32(section.Offset))
+	binary.LittleEndian.PutUint32(data[4:], uint32(section.Size))
+	copy(data[8:], section.Name)
+
+	return ImageTlv {
+		Header: ImageTlvHdr{
+			Type: IMAGE_TLV_SECTION,
+			Pad: 0,
+			Len: uint16(len(data)),
+		},
+		Data: data,
+	}, nil
+}
+
 // GenerateSig signs an image using an rsa key.
 func GenerateSigRsa(key sec.PrivSignKey, hash []byte) ([]byte, error) {
 	opts := rsa.PSSOptions{
@@ -316,6 +336,7 @@
 	ic.Version = opts.Version
 	ic.SigKeys = opts.SigKeys
 	ic.HWKeyIndex = opts.SrcEncKeyIndex
+	ic.Sections = opts.Sections
 
 	if opts.LoaderHash != nil {
 		ic.InitialHash = opts.LoaderHash
@@ -501,6 +522,14 @@
 		img.ProtTlvs = append(img.ProtTlvs, tlv)
 	}
 
+	for s := range ic.Sections {
+		tlv, err := GenerateSectionTlv(ic.Sections[s])
+		if err != nil {
+			return img, err
+		}
+		img.ProtTlvs = append(img.ProtTlvs, tlv)
+	}
+
 	img.Header.ProtSz = calcProtSize(img.ProtTlvs)
 
 	// Followed by data.
diff --git a/image/image.go b/image/image.go
index f7ef6e6..7defa38 100644
--- a/image/image.go
+++ b/image/image.go
@@ -55,33 +55,39 @@
  * Image trailer TLV types.
  */
 const (
-	IMAGE_TLV_KEYHASH   = 0x01
-	IMAGE_TLV_SHA256    = 0x10
-	IMAGE_TLV_RSA2048   = 0x20
-	IMAGE_TLV_ECDSA224  = 0x21
-	IMAGE_TLV_ECDSA256  = 0x22
-	IMAGE_TLV_RSA3072   = 0x23
-	IMAGE_TLV_ED25519   = 0x24
-	IMAGE_TLV_ENC_RSA   = 0x30
-	IMAGE_TLV_ENC_KEK   = 0x31
-	IMAGE_TLV_ENC_EC256 = 0x32
-	IMAGE_TLV_AES_NONCE = 0x50
-	IMAGE_TLV_SECRET_ID = 0x60
+	IMAGE_TLV_KEYHASH          = 0x01
+	IMAGE_TLV_SHA256           = 0x10
+	IMAGE_TLV_RSA2048          = 0x20
+	IMAGE_TLV_ECDSA224         = 0x21
+	IMAGE_TLV_ECDSA256         = 0x22
+	IMAGE_TLV_RSA3072          = 0x23
+	IMAGE_TLV_ED25519          = 0x24
+	IMAGE_TLV_ENC_RSA          = 0x30
+	IMAGE_TLV_ENC_KEK          = 0x31
+	IMAGE_TLV_ENC_EC256        = 0x32
+	IMAGE_TLV_AES_NONCE_LEGACY = 0x50
+	IMAGE_TLV_SECRET_ID_LEGACY = 0x60
+	IMAGE_TLV_AES_NONCE        = 0xa1
+	IMAGE_TLV_SECRET_ID        = 0xa2
+	IMAGE_TLV_SECTION          = 0xa3
 )
 
 var imageTlvTypeNameMap = map[uint8]string{
-	IMAGE_TLV_KEYHASH:   "KEYHASH",
-	IMAGE_TLV_SHA256:    "SHA256",
-	IMAGE_TLV_RSA2048:   "RSA2048",
-	IMAGE_TLV_ECDSA224:  "ECDSA224",
-	IMAGE_TLV_ECDSA256:  "ECDSA256",
-	IMAGE_TLV_RSA3072:   "RSA3072",
-	IMAGE_TLV_ED25519:   "ED25519",
-	IMAGE_TLV_ENC_RSA:   "ENC_RSA",
-	IMAGE_TLV_ENC_KEK:   "ENC_KEK",
-	IMAGE_TLV_ENC_EC256: "ENC_EC256",
-	IMAGE_TLV_AES_NONCE: "AES_NONCE",
-	IMAGE_TLV_SECRET_ID: "SEC_KEY_ID",
+	IMAGE_TLV_KEYHASH:          "KEYHASH",
+	IMAGE_TLV_SHA256:           "SHA256",
+	IMAGE_TLV_RSA2048:          "RSA2048",
+	IMAGE_TLV_ECDSA224:         "ECDSA224",
+	IMAGE_TLV_ECDSA256:         "ECDSA256",
+	IMAGE_TLV_RSA3072:          "RSA3072",
+	IMAGE_TLV_ED25519:          "ED25519",
+	IMAGE_TLV_ENC_RSA:          "ENC_RSA",
+	IMAGE_TLV_ENC_KEK:          "ENC_KEK",
+	IMAGE_TLV_ENC_EC256:        "ENC_EC256",
+	IMAGE_TLV_AES_NONCE:        "AES_NONCE",
+	IMAGE_TLV_SECRET_ID:        "SEC_KEY_ID",
+	IMAGE_TLV_AES_NONCE_LEGACY: "AES_NONCE",
+	IMAGE_TLV_SECRET_ID_LEGACY: "SEC_KEY_ID",
+	IMAGE_TLV_SECTION:          "SECTION",
 }
 
 var imageTlvTypeSigTypeMap = map[uint8]sec.SigType{
@@ -144,6 +150,12 @@
 	TotalSize   int
 }
 
+type Section struct {
+	Name   string
+	Size   int
+	Offset int
+}
+
 func ImageTlvTypeIsValid(tlvType uint8) bool {
 	_, ok := imageTlvTypeNameMap[tlvType]
 	return ok