func()

in image/create.go [490:618]


func (ic *ImageCreator) Create() (Image, error) {
	img := Image{}

	// First the header
	img.Header = ImageHdr{
		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 {
		img.Header.Flags |= IMAGE_F_NON_BOOTABLE
	}

	// Set encrypted image flag if image is to be treated as encrypted
	if ic.CipherSecret != nil && ic.HWKeyIndex < 0 {
		img.Header.Flags |= IMAGE_F_ENCRYPTED
	}

	if ic.HeaderSize != 0 {
		// Pad the header out to the given size.  There will just be zeros
		// between the header and the start of the image when it is padded.
		extra := ic.HeaderSize - IMAGE_HEADER_SIZE
		if extra < 0 {
			return img, errors.Errorf(
				"image header must be at least %d bytes", IMAGE_HEADER_SIZE)
		}

		img.Header.HdrSz = uint16(ic.HeaderSize)
		img.Pad = make([]byte, extra)
	}

	if ic.HWKeyIndex >= 0 {
		tlv, err := GenerateHWKeyIndexTLV(uint32(ic.HWKeyIndex),
			ic.UseLegacyTLV)
		if err != nil {
			return img, err
		}
		img.ProtTlvs = append(img.ProtTlvs, tlv)

		tlv, err = GenerateNonceTLV(ic.Nonce, ic.UseLegacyTLV)
		if err != nil {
			return img, err
		}
		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.
	var hashBytes []byte
	var err error
	if ic.PlainSecret != nil {
            if img.HasEncryptionPayload() {
                // If the image has an encryption payload, it is an encrypted image 
                // that will be HW decrypted while running and the hash must be 
                // calculated on the encrypted image body.
                encBody, err := sec.EncryptAES(ic.Body, ic.PlainSecret, ic.Nonce)
                if err != nil {
                    return img, err
                }
                img.Body = append(img.Body, encBody...)
                hashBytes, err = img.CalcHash(ic.InitialHash)
                if err != nil {
                    return img, err
                }
            } else {
                // For normal encrypted images, must calculate the hash with the plain
                // body and encrypt the payload afterwards
                img.Body = append(img.Body, ic.Body...)
                hashBytes, err = img.CalcHash(ic.InitialHash)
                if err != nil {
                    return img, err
                }
                encBody, err := sec.EncryptAES(ic.Body, ic.PlainSecret, ic.Nonce)
                if err != nil {
                    return img, err
                }
                img.Body = nil
                img.Body = append(img.Body, encBody...)
            }
	} else {
		img.Body = append(img.Body, ic.Body...)
		hashBytes, err = img.CalcHash(ic.InitialHash)
		if err != nil {
			return img, err
		}
	}

	// Hash TLV.
	tlv := ImageTlv{
		Header: ImageTlvHdr{
			Type: IMAGE_TLV_SHA256,
			Pad:  0,
			Len:  uint16(len(hashBytes)),
		},
		Data: hashBytes,
	}
	img.Tlvs = append(img.Tlvs, tlv)

	tlvs, err := BuildSigTlvs(ic.SigKeys, hashBytes)
	if err != nil {
		return img, err
	}
	img.Tlvs = append(img.Tlvs, tlvs...)

	if ic.HWKeyIndex < 0 && ic.CipherSecret != nil {
		tlv, err := GenerateEncTlv(ic.CipherSecret)
		if err != nil {
			return img, err
		}
		img.Tlvs = append(img.Tlvs, tlv)
	}

	return img, nil
}