# # Copyright (C) 2012 OpenWrt.org # Copyright (C) 2018 devolo AG # . /lib/delos-functions.sh signatureFile="/tmp/signature.bin" publicKeyFile="/etc/keys/fw_pub_key.pem" # get the first 4 bytes (magic) of a given file starting at offset in hex format delos_get_magic_long_at() { dd if="$1" skip=$2 bs=1 count=4 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' } # scan through the update image pages until matching magic 'deadc0de' @ page start. return the offset. delos_get_jffs2_trailer_offset() { local magiclong local offsetcount=0 local offset if [ -n "$2" ]; then offsetcount=$2 fi while magiclong=$(delos_get_magic_long_at "$1" "$offsetcount") && [ -n "$magiclong" ]; do [ "$magiclong" = "deadc0de" ] && { offset="$offsetcount" } offsetcount=$(( $offsetcount + $CI_BLKSZ )) done [ -n "$offset" ] && echo "$offset" } delos_check_image_dvl() { # check for valid matching dvl image. local ret case "$board" in dlan-pro-1200-ac) chunk -F "$1" -s inspect || { echo "Invalid image type." return 1 } chunk -F "$1" -s dump -d "$1.$$.device" -v "$1.$$.oem" ret=$? if [ $ret = 0 ] ; then [ -e "$1.$$.device" ] && [ -e "$1.$$.oem" ] && [ "$(uci_get_state delos baptization DeviceType)" = "$(cat "$1.$$.device")" ] && [ "$(uci_get_state delos baptization OemVariant)" = "$(cat "$1.$$.oem")" ] || ret=1 fi if [ $ret != 0 ] ; then echo "Invalid image type." fi # cleanup working files rm -f "$1".$$.* return $ret ;; esac echo "Invalid image type." return 1 } delos_unpack_image_dvl() { # convert to image in sysupgrade format # (only works if image is a file!) case "$board" in dlan-pro-1200-ac) local magicl="$(get_magic_long "$1")" [ "$magicl" != "8664564c" ] && return chunk -F "$1" -s dump -k - -f - >"$1.$$.fw" ret=$? if [ $ret = 0 ] ; then rm -f "$1" mv "$1.$$.fw" "$1" fi ;; esac } platform_check_image_delos() { local magicl="$(get_magic_long "$1")" local magic="$(echo "$magicl" | head -c 4)" [ "$magicl" = "8664564c" ] && { delos_check_image_dvl "$1" return } [ "$magic" != "2705" ] && { echo "Invalid image type." return 1 } # Find trailer local offsetTrailer="$(delos_get_jffs2_trailer_offset "$1")" if [ -z "$offsetTrailer" ]; then echo "Invalid image contents." return 1 fi trailerLength=$(dd if=$1 skip=$offsetTrailer bs=1 2> /dev/null | tr "\0" "\n" | sed -e '/^SIG:/,$d' | wc -c) signatureOffset=$((offsetTrailer+trailerLength)) # Extract signature; Verify signature; There is a \0 before SIG: => signatureOffset-1 dd if="$1" skip=$(( $signatureOffset + 4 )) bs=1 2>/dev/null | openssl base64 -A -d -out "$signatureFile" if [ ! -s "$signatureFile" ]; then echo "No signature found." return 1 fi output=$(head -c $(($signatureOffset-1)) "$1" | openssl dgst -sha256 -verify /etc/keys/fw_pub_key.pem -signature "$signatureFile") opensslExitCode="$?" rm "$signatureFile" [ "$opensslExitCode" != 0 ] || [ "$output" != "Verified OK" ] && { echo "Invalid signature." return 1 } # Extract trailer local trailer="$(dd if="$1" skip=$(( $offsetTrailer + 4 )) bs=1 count=$(( $signatureOffset - $offsetTrailer - 4 )) 2>/dev/null)" if [ -z "$trailer" ]; then echo "Invalid image contents." return 1 fi ( . /usr/share/libubox/jshn.sh json_load "$trailer" # compare current and image platform device type / oem variant json_get_var dev_img device_type DEVICE_TYPE= . /etc/delos-image if [ "$dev_img" = "$DEVICE_TYPE" ] && dvl_check_oemvariant "$trailer"; then : else echo "Image is not qualified for this device." return 1 fi ) || return 1 return 0 } platform_do_upgrade_delos() { default_do_upgrade "$@" } platform_check_config_delos() { # all in one check for gzip, tar, delos config tar -xzf "$1" -O etc/config/delos >/tmp/config-delos 2>/dev/null || { return 1 } local type type="$(uci -c /tmp -q get config-delos.delos.device_type)" || { # backward compatibility accept config w/o device-type return 0 } . /etc/delos-image [ "$type" != "$DEVICE_TYPE" ] && { return 1 } return 0 } platform_pre_upgrade_delos() { delos_unpack_image_dvl "$1" . /lib/functions/leds.sh led_set_attr "devolo:status:wlan" operation update }