github.com/usbarmory/armory-boot@v0.0.0-20240307133412-208c66a380b9/sdp/imx.go (about) 1 // https://github.com/usbarmory/armory-boot 2 // 3 // Copyright (c) WithSecure Corporation 4 // https://foundry.withsecure.com 5 // 6 // Use of this source code is governed by the license 7 // that can be found in the LICENSE file. 8 9 package sdp 10 11 import ( 12 "bytes" 13 "encoding/binary" 14 "errors" 15 ) 16 17 // Program image tags 18 // (p309, 8.7 Program image, IMX6ULLRM). 19 const ( 20 TagIVT = 0xd1 21 TagDCD = 0xd2 22 ) 23 24 // DCD constants 25 // (p312, 8.7.2 Device Configuration Data (DCD), IMX6ULLRM). 26 const ( 27 // write command tag 28 WriteData = 0xcc 29 // DCD pointer offset within IVT 30 DCDOffset = 12 31 // maximum DCD size 32 DCDSize = 1768 33 ) 34 35 // DCDHeader represents a DCD header 36 // (p312, 8.7.2 Device Configuration Data (DCD), IMX6ULLRM). 37 type DCDHeader struct { 38 Tag uint8 39 Length uint16 40 Version uint8 41 } 42 43 // IVT represents an IVT entry 44 // (p311, 8.7.1.1 Image vector table structure, IMX6ULLRM). 45 type IVT struct { 46 Tag uint8 47 Length uint16 48 Version uint8 49 Entry uint32 50 _ uint32 51 DCD uint32 52 BootData uint32 53 Self uint32 54 CSF uint32 55 _ uint32 56 } 57 58 // ParseIVT extracts the Image Vector Table (IVT) from an imx format binary 59 // image. 60 func ParseIVT(imx []byte) (ivt *IVT, err error) { 61 ivt = &IVT{} 62 63 if err = binary.Read(bytes.NewReader(imx), binary.LittleEndian, ivt); err != nil { 64 return nil, err 65 } 66 67 if ivt.Tag != TagIVT { 68 return nil, errors.New("could not find IVT tag") 69 } 70 71 return 72 } 73 74 // ParseDCD extracts the Device Configuration Data (DCD) from an imx format 75 // binary image. 76 func ParseDCD(imx []byte, ivt *IVT) (dcd []byte, err error) { 77 hdr := &DCDHeader{} 78 dcdStart := ivt.DCD - ivt.Self 79 80 if len(imx) < int(dcdStart+4) { 81 return nil, errors.New("could not parse DCD, insufficient length") 82 } 83 84 if err = binary.Read(bytes.NewReader(imx[dcdStart:dcdStart+4]), binary.BigEndian, hdr); err != nil { 85 return 86 } 87 88 if hdr.Tag != TagDCD { 89 return nil, errors.New("could not find DCD tag") 90 } 91 92 if hdr.Length > DCDSize || int(hdr.Length) > int(dcdStart)+len(imx) { 93 return nil, errors.New("could not parse DCD, invalid length") 94 } 95 96 dcd = imx[dcdStart : dcdStart+uint32(hdr.Length)] 97 98 return 99 }