#!/bin/bash # # Usage: check_sb_trailer.sh FILENAME(S) # # Check specified files for secure boot trailer required for Linux on IBM Z # Secure Boot. Use with the Linux kernel image (e.g. /boot/vmlinuz*) and zipl # stage 3 bootloader file (e.g. /lib/s390-tools/stage3.bin). # # Author: Peter Oberparleiter # # Hexdump of expected trailer values STAGE3="0000c00000000000000800008000a000000000000000a000000000207a49504c" KERNEL="000000000000000000000000000000000000000000000000000000207a49504c" SIGNED="7e4d6f64756c65207369676e617475726520617070656e6465647e0a" RC=0 function die() { echo "Error: $*" >&2 exit 1 } function read_trailer() { local var="$1" file="$2" offset="$3" size _trailer size=$(stat "$file" --format "%s") || exit 1 (( offset=size-offset )) [[ "$offset" -lt 0 ]] && die "File $file is too short" _trailer=$(dd if="$file" bs=1 skip=$offset count=32 status=none | hexdump -e '32/1 "%02x" "\n"') [[ -z "$_trailer" ]] && die "Could not read trailer from $file" printf " * Read 32 bytes at offset %08x:\n" "$offset" echo " $_trailer" eval "$var=$_trailer" } function check_trailer() { local file="$1" trailer siglen echo "Checking secure boot trailer of file $file" read_trailer "trailer" "$file" 32 if [[ "${trailer:8}" == "$SIGNED" ]] ; then (( siglen=0x${trailer:0:8}+40 )) echo " * Found signature marker - skipping $siglen bytes" read_trailer "trailer" "$file" $(( 32+siglen )) fi case "$trailer" in "$STAGE3") echo " * Success - stage3 trailer found" ;; "$KERNEL") echo " * Success - Linux kernel trailer found" ;; *) echo " * ERROR: No valid secure boot trailer found" >&2 RC=1 ;; esac } if [[ $# -eq 0 ]] ; then sed -n '/Usage/,/Author/{s/^# \?//g;/Author/!p;/Author/q}' "$0" exit 0 fi for FILE in "$@" ; do check_trailer "$FILE" done exit "$RC"