#! /bin/bash
#
# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# This Software is licensed under one of the following licenses:
#
# 1) under the terms of the "Common Public License 1.0" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/cpl.php.
#
# 2) under the terms of the "The BSD License" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/bsd-license.php.
#
# 3) under the terms of the "GNU General Public License (GPL) Version 2" a
#    copy of which is available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/gpl-license.php.
#
# Licensee has the right to choose one of the above licenses.
#
# Redistributions of source code must retain the above copyright
# notice and one of the license notices.
#
# Redistributions in binary form must reproduce both the above copyright
# notice, one of the license notices in the documentation
# and/or other materials provided with the distribution.
#

moddir=$1; shift
KBUILD=$1; shift

test_signed() {
    for m in $modules; do
        if [ "`/sbin/modinfo -Fsig_hashalgo $m 2>/dev/null`" = '' ]; then
                echo "*** Modules are unsigned ($m)! ***"
            exit 1
        fi
    done
}

sign_script() {
    set -e
    cd $moddir
    output_dir="$PWD/signing_output"
    modules=`find * -name *.ko -o -name \*.ko.\?z`
    rm -rf "$output_dir"
    mkdir -p "$output_dir"
    tarball="$output_dir/modules.tgz"
    output_tarball="$output_dir/modules-out.tgz"
    tar czf "$tarball" $modules
    (
        cd `dirname "$MODULES_SIGN_SCRIPT"`
        if ! $MODULES_SIGN_SCRIPT --file `realpath $tarball` \
            --job-type KERNEL --prod \
            --description "Signing kernel-mft" \
            --out-file "$output_tarball" >"$output_dir/script_output.log"
        then
            if [ -f "$output_dir/sign-tool.log" ]; then
                cat "$output_dir/sign-tool.log"
            else
                cat "$output_dir/script_output.log"
            fi
            exit 2
        fi
    )
    tar xf "$output_tarball"
    test_signed # checks $modules
    rm -rf "$output_dir"
    exit $?
}

if [ -x "${MODULES_SIGN_SCRIPT}" ]; then
    sign_script
fi

SOURCES_DIR=
case "$KBUILD" in
    *linux-obj*)
    SOURCES_DIR=$(readlink -f $KBUILD 2>/dev/null | sed -e 's/-obj.*//g')
    ;;
    */usr/src/linux-*-obj/*)
    SOURCES_DIR=$(readlink -f $KBUILD 2>/dev/null | sed -e 's/-obj.*//g')
    ;;
    *)
    SOURCES_DIR=$(readlink -f ${KBUILD/build/source})
    ;;
esac
if [ ! -e "$SOURCES_DIR" ]; then
    SOURCES_DIR=$KBUILD
fi

SIGN_FILE=
if [ -e "${KBUILD}/scripts/sign-file" ]; then
    SIGN_FILE="${KBUILD}/scripts/sign-file"
elif [ -e "${SOURCES_DIR}/scripts/sign-file" ]; then
    SIGN_FILE="${SOURCES_DIR}/scripts/sign-file"
else
    echo "Error: Sign tool does not exist at '$KBUILD' or '$SOURCES_DIR' !" >&2
    exit 1
fi
echo "Found Sign tool at: '${SIGN_FILE}'"

if [ ! -e "${MODULE_SIGN_PRIV_KEY}" ]; then
    echo "Error: MODULE_SIGN_PRIV_KEY is not set to valid path!" >&2
    exit 1
fi
if [ ! -e "${MODULE_SIGN_PUB_KEY}" ]; then
    echo "Error: MODULE_SIGN_PUB_KEY is not set to valid path!" >&2
    exit 1
fi

modules=`find $moddir -name '*.ko' -o -name '*.ko.?z'`
for mod in $modules
do
    dir=`dirname $mod`
    file=`basename $mod`

    ${SIGN_FILE} sha256 ${MODULE_SIGN_PRIV_KEY} ${MODULE_SIGN_PUB_KEY} ${dir}/${file}
    rm -f ${dir}/${file}.{sig,dig}
done

test_signed
exit 0
