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
}