@ -1,9 +1,13 @@
package cfig
import avb. *
import avb. AVBInfo
import avb.alg.Algorithms
import avb.blob.AuthBlob
import avb.blob.AuxBlob
import avb.blob.Footer
import avb.blob.Header
import avb.desc.*
import avb.AuxBlob
import cfig.Helper.Companion.paddingWith
import cfig.io.Struct3
import com.fasterxml.jackson.databind.ObjectMapper
import org.apache.commons.codec.binary.Hex
@ -14,7 +18,6 @@ import java.io.FileOutputStream
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardOpenOption
import java.security.MessageDigest
@ExperimentalUnsignedTypes
class Avb {
@ -22,227 +25,119 @@ class Avb {
private val MAX _FOOTER _SIZE = 4096
private val BLOCK _SIZE = 4096
private var required _libavb _version _minor = 0
//migrated from: avbtool::Avb::add_hash_footer
fun add _hash _footer ( image _file : String ,
partition _size : Long , //aligned by Avb::BLOCK_SIZE
use _persistent _digest : Boolean ,
do _not _use _ab : Boolean ,
salt : String ,
hash _algorithm : String ,
partition _name : String ,
rollback _index : Long ,
common _algorithm : String ,
inReleaseString : String ? ) {
log . info ( " add_hash_footer( $image _file) ... " )
var original _image _size : ULong
//required libavb version
if ( use _persistent _digest || do _not _use _ab ) {
required _libavb _version _minor = 1
}
log . info ( " Required_libavb_version: 1. $required _libavb_version_minor " )
// SIZE + metadata (footer + vbmeta struct)
val max _metadata _size = MAX _VBMETA _SIZE + MAX _FOOTER _SIZE
if ( partition _size < max _metadata _size ) {
throw IllegalArgumentException ( " Parition SIZE of $partition _size is too small. " +
" Needs to be at least $max _metadata_size " )
}
val max _image _size = partition _size - max _metadata _size
log . info ( " max_image_size: $max _image_size " )
//TODO: typical block size = 4096L, from avbtool::Avb::ImageHandler::block_size
//since boot.img is not in sparse format, we are safe to hardcode it to 4096L for now
if ( partition _size % BLOCK _SIZE != 0L ) {
throw IllegalArgumentException ( " Partition SIZE of $partition _size is not " +
" a multiple of the image block SIZE 4096 " )
}
//truncate AVB footer if there is. Then add_hash_footer() is idempotent
val fis = FileInputStream ( image _file )
val originalFileSize = File ( image _file ) . length ( )
if ( originalFileSize > max _image _size ) {
throw IllegalArgumentException ( " Image size of $originalFileSize exceeds maximum image size " +
" of $max _image_size in order to fit in a partition size of $partition _size. " )
}
fis . skip ( originalFileSize - 64 )
try {
val footer = Footer ( fis )
original _image _size = footer . originalImageSize
FileOutputStream ( File ( image _file ) , true ) . channel . use {
log . info ( " original image $image _file has AVB footer, " +
" truncate it to original SIZE: ${footer.originalImageSize} " )
it . truncate ( footer . originalImageSize . toLong ( ) )
//migrated from: avbtool::Avb::addHashFooter
fun addHashFooter ( image _file : String ,
partition _size : Long , //aligned by Avb::BLOCK_SIZE
partition _name : String ,
newAvbInfo : AVBInfo ) {
log . info ( " addHashFooter( $image _file) ... " )
imageSizeCheck ( partition _size , image _file )
//truncate AVB footer if there is. Then addHashFooter() is idempotent
trimFooter ( image _file )
val newImageSize = File ( image _file ) . length ( )
//VBmeta blob: update hash descriptor
newAvbInfo . apply {
val itr = this . auxBlob !! . hashDescriptors . iterator ( )
var hd = HashDescriptor ( )
while ( itr . hasNext ( ) ) { //remove previous hd entry
val itrValue = itr . next ( )
if ( itrValue . partition _name == partition _name ) {
itr . remove ( )
hd = itrValue
}
}
} catch ( e : IllegalArgumentException ) {
log . info ( " original image $image _file doesn't have AVB footer " )
original _image _size = originalFileSize . toULong ( )
//HashDescriptor
hd . update ( image _file )
log . info ( " updated hash descriptor: " + Hex . encodeHexString ( hd . encode ( ) ) )
this . auxBlob !! . hashDescriptors . add ( hd )
}
//salt
var saltByteArray = Helper . fromHexString ( salt )
if ( salt . isBlank ( ) ) {
//If salt is not explicitly specified, choose a hash that's the same size as the hash size
val expectedDigestSize = MessageDigest . getInstance ( Helper . pyAlg2java ( hash _algorithm ) ) . digest ( ) . size
FileInputStream ( File ( " /dev/urandom " ) ) . use {
val randomSalt = ByteArray ( expectedDigestSize )
it . read ( randomSalt )
log . warn ( " salt is empty, using random salt[ $expectedDigestSize ]: " + Helper . toHexString ( randomSalt ) )
saltByteArray = randomSalt
}
} else {
log . info ( " preset salt[ ${saltByteArray.size} ] is valid: $salt " )
}
val vbmetaBlob = packVbMeta ( newAvbInfo )
log . debug ( " vbmeta_blob: " + Helper . toHexString ( vbmetaBlob ) )
Helper . dumpToFile ( " hashDescriptor.vbmeta.blob " , vbmetaBlob )
//hash digest
val digest = MessageDigest . getInstance ( Helper . pyAlg2java ( hash _algorithm ) ) . apply {
update ( saltByteArray )
update ( File ( image _file ) . readBytes ( ) )
} . digest ( )
log . info ( " Digest(salt + file): " + Helper . toHexString ( digest ) )
//HashDescriptor
val hd = HashDescriptor ( )
hd . image _size = File ( image _file ) . length ( ) . toULong ( )
hd . hash _algorithm = hash _algorithm
hd . partition _name = partition _name
hd . salt = saltByteArray
hd . flags = 0U
if ( do _not _use _ab ) hd . flags = hd . flags or 1u
if ( ! use _persistent _digest ) hd . digest = digest
log . info ( " encoded hash descriptor: " + Hex . encodeHexString ( hd . encode ( ) ) )
//VBmeta blob
val vbmeta _blob = generateVbMetaBlob ( common _algorithm ,
null ,
arrayOf ( hd as Descriptor ) ,
null ,
rollback _index ,
0 ,
null ,
null ,
0U ,
inReleaseString )
log . debug ( " vbmeta_blob: " + Helper . toHexString ( vbmeta _blob ) )
Helper . dumpToFile ( " hashDescriptor.vbmeta.blob " , vbmeta _blob )
log . info ( " Padding image ... " )
// image + padding
if ( hd . image _size . toLong ( ) % BLOCK _SIZE != 0L ) {
val padding _needed = BLOCK _SIZE - ( hd . image _size . toLong ( ) % BLOCK _SIZE )
FileOutputStream ( image _file , true ) . use { fos ->
fos . write ( ByteArray ( padding _needed . toInt ( ) ) )
}
log . info ( " $image _file padded: ${hd.image_size} -> ${File(image_file).length()} " )
} else {
log . info ( " $image _file doesn't need padding " )
}
val imgPaddingNeeded = Helper . round _to _multiple ( newImageSize , BLOCK _SIZE ) - newImageSize
// + vbmeta + padding
log . info ( " Appending vbmeta ... " )
val vbmeta _offset = File ( image _file ) . length ( )
val padding _needed = Helper . round _to _multiple ( vbmeta _blob . size . toLong ( ) , BLOCK _SIZE ) - vbmeta _blob . size
val vbmeta _blob _with _padding = Helper . join ( vbmeta _blob , Struct3 ( " ${padding_needed} x " ) . pack ( null ) )
FileOutputStream ( image _file , true ) . use { fos ->
fos . write ( vbmeta _blob _with _padding )
}
val vbmetaOffset = File ( image _file ) . length ( )
val vbmetaBlobWithPadding = vbmetaBlob . paddingWith ( BLOCK_SIZE . toUInt ( ) )
// + DONT_CARE chunk
log . info ( " Appending DONT_CARE chunk ... " )
val vbmeta _end _offset = vbmeta _offset + vbmeta _blob _with _padding . size
FileOutputStream ( image _file , true ) . use { fos ->
fos . write ( Struct3 ( " ${partition_size - vbmeta_end_offset - 1 * BLOCK_SIZE} x " ) . pack ( null ) )
}
val vbmetaEndOffset = vbmetaOffset + vbmetaBlobWithPadding . size
val dontCareChunkSize = partition _size - vbmetaEndOffset - 1 * BLOCK _SIZE
// + AvbFooter + padding
log . info ( " Appending footer ... " )
val footer = Footer ( )
footer . originalImageSize = original _image _size
footer . vbMetaOffset = vbmeta _offset . toULong ( )
footer . vbMetaSize = vbmeta _blob . size . toULong ( )
val footerBob = footer . encode ( )
val footerBlobWithPadding = Helper . join (
Struct3 ( " ${BLOCK_SIZE - Footer.SIZE} x " ) . pack ( null ) , footerBob )
log . info ( " footer: " + Helper . toHexString ( footerBob ) )
log . info ( footer . toString ( ) )
newAvbInfo . footer !! . apply {
originalImageSize = newImageSize . toULong ( )
vbMetaOffset = vbmetaOffset . toULong ( )
vbMetaSize = vbmetaBlob . size . toULong ( )
}
log . info ( newAvbInfo . footer . toString ( ) )
val footerBlobWithPadding = newAvbInfo . footer !! . encode ( ) . paddingWith ( BLOCK_SIZE . toUInt ( ) , true )
FileOutputStream ( image _file , true ) . use { fos ->
log . info ( " 1/4 Padding image with $imgPaddingNeeded bytes ... " )
fos . write ( ByteArray ( imgPaddingNeeded . toInt ( ) ) )
log . info ( " 2/4 Appending vbmeta ( ${vbmetaBlobWithPadding.size} bytes)... " )
fos . write ( vbmetaBlobWithPadding )
log . info ( " 3/4 Appending DONT CARE CHUNK ( $dontCareChunkSize bytes) ... " )
fos . write ( ByteArray ( dontCareChunkSize . toInt ( ) ) )
log . info ( " 4/4 Appending AVB footer ( ${footerBlobWithPadding.size} bytes)... " )
fos . write ( footerBlobWithPadding )
}
log . info ( " add_hash_footer( $image _file) done ... " )
log . info ( " add HashFooter($image _file) done ." )
}
//avbtool::Avb::_generate_vbmeta_blob()
private fun generateVbMetaBlob ( algorithm _name : String ,
public _key _metadata _path : String ? ,
descriptors : Array < Descriptor > ,
chain _partitions : String ? ,
inRollbackIndex : Long ,
inFlags : Long ,
props : Map < String , String > ? ,
kernel _cmdlines : List < String > ? ,
required _libavb _version _minor : UInt ,
inReleaseString : String ? ) : ByteArray {
//encoded descriptors
var encodedDesc : ByteArray = byteArrayOf ( )
descriptors . forEach { encodedDesc = Helper . join ( encodedDesc , it . encode ( ) ) }
props ?. let {
it . forEach { t , u ->
Helper . join ( encodedDesc , PropertyDescriptor ( t , u ) . encode ( ) )
private fun trimFooter ( image _file : String ) {
var footer : Footer ? = null
FileInputStream ( image _file ) . use {
it . skip ( File ( image _file ) . length ( ) - 64 )
try {
footer = Footer ( it )
log . info ( " original image $image _file has AVB footer " )
} catch ( e : IllegalArgumentException ) {
log . info ( " original image $image _file doesn't have AVB footer " )
}
}
kernel _cmdlines ?. let {
it . forEach { eachCmdline ->
Helper . join ( encodedDesc , KernelCmdlineDescriptor ( cmdline = eachCmdline ) . encode ( ) )
footer ?. let {
FileOutputStream ( File ( image _file ) , true ) . channel . use { fc ->
log . info ( " original image $image _file has AVB footer, " +
" truncate it to original SIZE: ${it.originalImageSize} " )
fc . truncate ( it . originalImageSize . toLong ( ) )
}
}
//algorithm
val alg = Algorithms . get ( algorithm _name ) !!
//encoded pubkey
val encodedKey = AuxBlob . encodePubKey ( alg )
//3 - whole aux blob
val auxBlob = Blob . getAuxDataBlob ( encodedDesc , encodedKey , byteArrayOf ( ) )
//1 - whole header blob
val headerBlob = Header ( ) . apply {
bump _required _libavb _version _minor ( required _libavb _version _minor )
auxiliary _data _block _size = auxBlob . size . toULong ( )
authentication _data _block _size = Helper . round _to _multiple (
( alg . hash _num _bytes + alg . signature _num _bytes ) . toLong ( ) , 64 ) . toULong ( )
algorithm _type = alg . algorithm _type . toUInt ( )
hash _offset = 0U
hash _size = alg . hash _num _bytes . toULong ( )
signature _offset = alg . hash _num _bytes . toULong ( )
signature _size = alg . signature _num _bytes . toULong ( )
descriptors _offset = 0U
descriptors _size = encodedDesc . size . toULong ( )
public _key _offset = descriptors _size
public _key _size = encodedKey . size . toULong ( )
//TODO: support pubkey metadata
public _key _metadata _size = 0U
public _key _metadata _offset = public _key _offset + public _key _size
}
rollback _index = inRollbackIndex . toULong ( )
flags = inFlags . toUInt ( )
if ( inReleaseString != null ) {
log . info ( " Using preset release string: $inReleaseString " )
this . release _string = inReleaseString
}
} . encode ( )
private fun imageSizeCheck ( partition _size : Long , image _file : String ) {
//image size sanity check
val maxMetadataSize = MAX _VBMETA _SIZE + MAX _FOOTER _SIZE
if ( partition _size < maxMetadataSize ) {
throw IllegalArgumentException ( " Parition SIZE of $partition _size is too small. " +
" Needs to be at least $maxMetadataSize " )
}
val maxImageSize = partition _size - maxMetadataSize
log . info ( " max_image_size: $maxImageSize " )
//2 - auth blob
val authBlob = Blob . getAuthBlob ( headerBlob , auxBlob , algorithm _name )
//TODO: typical block size = 4096L, from avbtool::Avb::ImageHandler::block_size
//since boot.img is not in sparse format, we are safe to hardcode it to 4096L for now
if ( partition _size % BLOCK _SIZE != 0L ) {
throw IllegalArgumentException ( " Partition SIZE of $partition _size is not " +
" a multiple of the image block SIZE 4096 " )
}
return Helper . join ( headerBlob , authBlob , auxBlob )
val originalFileSize = File ( image _file ) . length ( )
if ( originalFileSize > maxImageSize ) {
throw IllegalArgumentException ( " Image size of $originalFileSize exceeds maximum image size " +
" of $maxImageSize in order to fit in a partition size of $partition _size. " )
}
}
fun parseVbMeta ( image _file : String ) : AVBInfo {
@ -250,6 +145,7 @@ class Avb {
val jsonFile = getJsonFileName ( image _file )
var footer : Footer ? = null
var vbMetaOffset : ULong = 0U
// footer
FileInputStream ( image _file ) . use { fis ->
fis . skip ( File ( image _file ) . length ( ) - Footer . SIZE )
try {
@ -261,6 +157,7 @@ class Avb {
}
}
// header
var vbMetaHeader = Header ( )
FileInputStream ( image _file ) . use { fis ->
fis . skip ( vbMetaOffset . toLong ( ) )
@ -273,34 +170,69 @@ class Avb {
val auxBlockOffset = authBlockOffset + vbMetaHeader . authentication _data _block _size
val descStartOffset = auxBlockOffset + vbMetaHeader . descriptors _offset
val ai = AVBInfo ( )
ai . footer = footer
ai . auxBlob = AuxBlob ( )
ai . header = vbMetaHeader
if ( vbMetaHeader . public _key _size > 0U ) {
ai . auxBlob !! . pubkey = AuxBlob . PubKeyInfo ( )
ai . auxBlob !! . pubkey !! . offset = vbMetaHeader . public _key _offset . toLong ( )
ai . auxBlob !! . pubkey !! . size = vbMetaHeader . public _key _size . toLong ( )
}
if ( vbMetaHeader . public _key _metadata _size > 0U ) {
ai . auxBlob !! . pubkeyMeta = AuxBlob . PubKeyMetadataInfo ( )
ai . auxBlob !! . pubkeyMeta !! . offset = vbMetaHeader . public _key _metadata _offset . toLong ( )
ai . auxBlob !! . pubkeyMeta !! . size = vbMetaHeader . public _key _metadata _size . toLong ( )
val ai = AVBInfo ( vbMetaHeader , null , AuxBlob ( ) , footer )
// Auth blob
if ( vbMetaHeader . authentication _data _block _size > 0U ) {
FileInputStream ( image _file ) . use { fis ->
fis . skip ( vbMetaOffset . toLong ( ) )
fis . skip ( Header . SIZE . toLong ( ) )
fis . skip ( vbMetaHeader . hash _offset . toLong ( ) )
val ba = ByteArray ( vbMetaHeader . hash _size . toInt ( ) )
fis . read ( ba )
log . debug ( " Parsed Auth Hash (Header & Aux Blob): " + Hex . encodeHexString ( ba ) )
val bb = ByteArray ( vbMetaHeader . signature _size . toInt ( ) )
fis . read ( bb )
log . debug ( " Parsed Auth Signature (of hash): " + Hex . encodeHexString ( bb ) )
ai . authBlob = AuthBlob ( )
ai . authBlob !! . offset = authBlockOffset
ai . authBlob !! . size = vbMetaHeader . authentication _data _block _size
ai . authBlob !! . hash = Hex . encodeHexString ( ba )
ai . authBlob !! . signature = Hex . encodeHexString ( bb )
}
}
// aux - desc
var descriptors : List < Any > = mutableListOf ( )
if ( vbMetaHeader . descriptors _size > 0U ) {
FileInputStream ( image _file ) . use { fis ->
fis . skip ( descStartOffset . toLong ( ) )
descriptors = UnknownDescriptor . parseDescriptors2 ( fis , vbMetaHeader . descriptors _size . toLong ( ) )
}
descriptors . forEach {
log . debug ( it . toString ( ) )
when ( it ) {
is PropertyDescriptor -> {
ai . auxBlob !! . propertyDescriptor . add ( it )
}
is HashDescriptor -> {
ai . auxBlob !! . hashDescriptors . add ( it )
}
is KernelCmdlineDescriptor -> {
ai . auxBlob !! . kernelCmdlineDescriptor . add ( it )
}
is HashTreeDescriptor -> {
ai . auxBlob !! . hashTreeDescriptor . add ( it )
}
is ChainPartitionDescriptor -> {
ai . auxBlob !! . chainPartitionDescriptor . add ( it )
}
is UnknownDescriptor -> {
ai . auxBlob !! . unknownDescriptors . add ( it )
}
else -> {
throw IllegalArgumentException ( " invalid descriptor: $it " )
}
}
}
}
// aux - pubkey
if ( vbMetaHeader . public _key _size > 0U ) {
ai . auxBlob !! . pubkey = AuxBlob . PubKeyInfo ( )
ai . auxBlob !! . pubkey !! . offset = vbMetaHeader . public _key _offset . toLong ( )
ai . auxBlob !! . pubkey !! . size = vbMetaHeader . public _key _size . toLong ( )
FileInputStream ( image _file ) . use { fis ->
fis . skip ( auxBlockOffset . toLong ( ) )
fis . skip ( vbMetaHeader . public _key _offset . toLong ( ) )
@ -309,65 +241,21 @@ class Avb {
log . debug ( " Parsed Pub Key: " + Hex . encodeHexString ( ai . auxBlob !! . pubkey !! . pubkey ) )
}
}
// aux - pkmd
if ( vbMetaHeader . public _key _metadata _size > 0U ) {
FileInputStream ( image _file ) . use { fis ->
fis . skip ( vbMetaOffset . toLong ( ) )
fis . skip ( Header . SIZE . toLong ( ) )
fis . skip ( vbMetaHeader . public _key _metadata _offset . toLong ( ) )
val ba = ByteArray ( vbMetaHeader . public _key _metadata _size . toInt ( ) )
fis . read ( ba )
log . debug ( " Parsed Pub Key Metadata: " + Hex . encodeHexString ( ba ) )
}
}
ai . auxBlob !! . pubkeyMeta = AuxBlob . PubKeyMetadataInfo ( )
ai . auxBlob !! . pubkeyMeta !! . offset = vbMetaHeader . public _key _metadata _offset . toLong ( )
ai . auxBlob !! . pubkeyMeta !! . size = vbMetaHeader . public _key _metadata _size . toLong ( )
if ( vbMetaHeader . authentication _data _block _size > 0U ) {
FileInputStream ( image _file ) . use { fis ->
fis . skip ( vbMetaOffset . toLong ( ) )
fis . skip ( Header . SIZE . toLong ( ) )
fis . skip ( vbMetaHeader . hash _offset . toLong ( ) )
val ba = ByteArray ( vbMetaHeader . hash _size . toInt ( ) )
fis . read ( ba )
log . debug ( " Parsed Auth Hash (Header & Aux Blob): " + Hex . encodeHexString ( ba ) )
val bb = ByteArray ( vbMetaHeader . signature _size . toInt ( ) )
fis . read ( bb )
log . debug ( " Parsed Auth Signature (of hash): " + Hex . encodeHexString ( bb ) )
ai . authBlob = AuthBlob ( )
ai . authBlob !! . offset = authBlockOffset
ai . authBlob !! . size = vbMetaHeader . authentication _data _block _size
ai . authBlob !! . hash = Hex . encodeHexString ( ba )
ai . authBlob !! . signature = Hex . encodeHexString ( bb )
fis . skip ( auxBlockOffset . toLong ( ) )
fis . skip ( vbMetaHeader . public _key _metadata _offset . toLong ( ) )
ai . auxBlob !! . pubkeyMeta !! . pkmd = ByteArray ( vbMetaHeader . public _key _metadata _size . toInt ( ) )
fis . read ( ai . auxBlob !! . pubkeyMeta !! . pkmd )
log . debug ( " Parsed Pub Key Metadata: " + Helper . toHexString ( ai . auxBlob !! . pubkeyMeta !! . pkmd ) )
}
}
descriptors . forEach {
when ( it ) {
is PropertyDescriptor -> {
ai . auxBlob !! . propertyDescriptor . add ( it )
}
is HashDescriptor -> {
ai . auxBlob !! . hashDescriptors . add ( it )
}
is KernelCmdlineDescriptor -> {
ai . auxBlob !! . kernelCmdlineDescriptor . add ( it )
}
is HashTreeDescriptor -> {
ai . auxBlob !! . hashTreeDescriptor . add ( it )
}
is ChainPartitionDescriptor -> {
ai . auxBlob !! . chainPartitionDescriptor . add ( it )
}
is UnknownDescriptor -> {
ai . auxBlob !! . unknownDescriptors . add ( it )
}
else -> {
throw IllegalArgumentException ( " invalid descriptor: $it " )
}
}
}
val aiStr = ObjectMapper ( ) . writerWithDefaultPrettyPrinter ( ) . writeValueAsString ( ai )
log . debug ( aiStr )
ObjectMapper ( ) . writerWithDefaultPrettyPrinter ( ) . writeValue ( File ( jsonFile ) , ai )
log . info ( " vbmeta info written to $jsonFile " )
@ -377,22 +265,9 @@ class Avb {
private fun packVbMeta ( info : AVBInfo ? = null , image _file : String ? = null ) : ByteArray {
val ai = info ?: ObjectMapper ( ) . readValue ( File ( getJsonFileName ( image _file !! ) ) , AVBInfo :: class . java )
val alg = Algorithms . get ( ai . header !! . algorithm _type . toInt ( ) ) !!
val encodedDesc = ai . auxBlob !! . encodeDescriptors ( )
//encoded pubkey
val encodedKey = AuxBlob . encodePubKey ( alg )
//3 - whole aux blob
var auxBlob = byteArrayOf ( )
if ( ai . header !! . auxiliary _data _block _size > 0U ) {
if ( encodedKey . contentEquals ( ai . auxBlob !! . pubkey !! . pubkey ) ) {
log . info ( " Using the same key as original vbmeta " )
} else {
log . warn ( " Using different key from original vbmeta " )
}
auxBlob = Blob . getAuxDataBlob ( encodedDesc , encodedKey , byteArrayOf ( ) )
} else {
log . info ( " No aux blob " )
}
val auxBlob = ai . auxBlob ?. encode ( alg ) ?: byteArrayOf ( )
//1 - whole header blob
val headerBlob = ai . header !! . apply {
@ -401,7 +276,7 @@ class Avb {
( alg . hash _num _bytes + alg . signature _num _bytes ) . toLong ( ) , 64 ) . toULong ( )
descriptors _offset = 0U
descriptors _size = encodedDesc. size . toULong ( )
descriptors _size = ai. auxBlob ?. descriptorSize ?. toULong ( ) ?: 0U
hash _offset = 0U
hash _size = alg . hash _num _bytes . toULong ( )
@ -410,17 +285,17 @@ class Avb {
signature _size = alg . signature _num _bytes . toULong ( )
public _key _offset = descriptors _size
public _key _size = encodedKey . size . toULong ( )
public _key _size = AuxBlob . encodePubKey ( alg ) . size . toULong ( )
//TODO: support pubkey metadata
public _key _metadata _size = 0U
public _key _metadata _size = ai . auxBlob !! . pubkeyMeta ?. pkmd ?. size ?. toULong ( ) ?: 0U
public _key _metadata _offset = public _key _offset + public _key _size
log . info ( " pkmd size: $public _key_metadata_size, pkmd offset : $public _key_metadata_offset " )
} . encode ( )
//2 - auth blob
var authBlob = byteArrayOf ( )
if ( ai . authBlob != null ) {
authBlob = Blob. getAuth Blob( headerBlob , auxBlob , alg . name )
authBlob = AuthBlob. create Blob( headerBlob , auxBlob , alg . name )
} else {
log . info ( " No auth blob " )
}