in image/v1.go [316:437]
func (ic *ImageCreator) CreateV1() (ImageV1, error) {
ri := ImageV1{}
if len(ic.SigKeys) > 1 {
return ri, errors.Errorf(
"v1 image format only allows one key, %d keys specified",
len(ic.SigKeys))
}
// First the header
hdr := ImageHdrV1{
Magic: IMAGEv1_MAGIC,
TlvSz: 0, // Filled in later.
KeyId: 0,
Pad1: 0,
HdrSz: IMAGE_HEADER_SIZE,
Pad2: 0,
ImgSz: uint32(len(ic.Body)),
Flags: IMAGEv1_F_SHA256,
Vers: ic.Version,
Pad3: 0,
}
if !ic.Bootable {
hdr.Flags |= IMAGEv1_F_NON_BOOTABLE
}
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.
*/
if ic.HeaderSize < IMAGE_HEADER_SIZE {
return ri, errors.Errorf(
"image header must be at least %d bytes", IMAGE_HEADER_SIZE)
}
hdr.HdrSz = uint16(ic.HeaderSize)
}
if len(ic.SigKeys) > 0 {
keyFlag, err := sigHdrTypeV1(ic.SigKeys[0])
if err != nil {
return ri, err
}
hdr.Flags |= keyFlag
hdr.TlvSz = 4 + ic.SigKeys[0].SigLen()
}
hdr.TlvSz += 4 + 32
if hdr.HdrSz > IMAGE_HEADER_SIZE {
// 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 ri, errors.Errorf(
"image header must be at least %d bytes", IMAGE_HEADER_SIZE)
}
hdr.HdrSz = uint16(ic.HeaderSize)
for i := 0; i < extra; i++ {
ri.Body = append(ri.Body, 0)
}
}
hashBytes, err := calcHashV1(ic.InitialHash, hdr, ic.Body)
if err != nil {
return ri, err
}
/*
* Followed by data.
*/
dataBuf := make([]byte, 1024)
r := bytes.NewReader(ic.Body)
w := bytes.Buffer{}
for {
cnt, err := r.Read(dataBuf)
if err != nil && err != io.EOF {
return ri, errors.Wrapf(err, "failed to read from image body")
}
if cnt == 0 {
break
}
if _, err = w.Write(dataBuf[0:cnt]); err != nil {
return ri, errors.Wrapf(err, "failed to write to image body")
}
}
ri.Body = w.Bytes()
// Hash TLV.
tlv := ImageTlv{
Header: ImageTlvHdr{
Type: IMAGEv1_TLV_SHA256,
Pad: 0,
Len: uint16(len(hashBytes)),
},
Data: hashBytes,
}
ri.Tlvs = append(ri.Tlvs, tlv)
if len(ic.SigKeys) > 0 {
tlv, err := generateV1SigTlv(ic.SigKeys[0], hashBytes)
if err != nil {
return ri, err
}
ri.Tlvs = append(ri.Tlvs, tlv)
}
offs, err := ri.Offsets()
if err != nil {
return ri, err
}
hdr.TlvSz = uint16(offs.TotalSize - offs.Tlvs[0])
ri.Header = hdr
return ri, nil
}