docs: def digest_secure_bootloader(args):
      """ Calculate the digest of a bootloader image, in the same way the hardware
      secure boot engine would do so. Can be used with a pre-loaded key to update a
      secure bootloader. """
      if args.iv is not None:
          print("WARNING: --iv argument is for TESTING PURPOSES ONLY")
          iv = args.iv.read(128)
      else:
          iv = os.urandom(128)
      plaintext_image = args.image.read()
      args.image.seek(0)
  
      # secure boot engine reads in 128 byte blocks (ie SHA512 block
      # size), but also doesn't look for any appended SHA-256 digest
      fw_image = esptool.ESP32FirmwareImage(args.image)
      if fw_image.append_digest:
          if len(plaintext_image) % 128 <= 32:
              # ROM bootloader will read to the end of the 128 byte block, but not
              # to the end of the SHA-256 digest at the end
              new_len = len(plaintext_image) - (len(plaintext_image) % 128)
              plaintext_image = plaintext_image[:new_len]
  
      # if image isn't 128 byte multiple then pad with 0xFF (ie unwritten flash)
      # as this is what the secure boot engine will see
      if len(plaintext_image) % 128 != 0:
          plaintext_image += b"\xFF" * (128 - (len(plaintext_image) % 128))
  
      plaintext = iv + plaintext_image
  
      # Secure Boot digest algorithm in hardware uses AES256 ECB to
      # produce a ciphertext, then feeds output through SHA-512 to
      # produce the digest. Each block in/out of ECB is reordered
      # (due to hardware quirks not for security.)
  
      key = _load_hardware_key(args.keyfile)
      aes = pyaes.AESModeOfOperationECB(key)
      digest = hashlib.sha512()
  
      for block in get_chunks(plaintext, 16):
          block = block[::-1]  # reverse each input block
  
          cipher_block = aes.encrypt(block)
          # reverse and then byte swap each word in the output block
          cipher_block = cipher_block[::-1]
          for block in get_chunks(cipher_block, 4):
              # Python hashlib can build each SHA block internally
              digest.update(block[::-1])
  
      if args.output is None:
          args.output = os.path.splitext(args.image.name)[0] + "-digest-0x0000.bin"
      with open(args.output, "wb") as f:
          f.write(iv)
          digest = digest.digest()
          for word in get_chunks(digest, 4):
              f.write(word[::-1])  # swap word order in the result
          f.write(b'\xFF' * (0x1000 - f.tell()))  # pad to 0x1000
          f.write(plaintext_image)
      print("digest+image written to %s" % args.output)