1# 2# Copyright OpenEmbedded Contributors 3# 4# SPDX-License-Identifier: MIT 5# 6 7# This file is part of U-Boot verified boot support and is intended to be 8# inherited from the u-boot recipe. 9# 10# The signature procedure requires the user to generate an RSA key and 11# certificate in a directory and to define the following variable: 12# 13# UBOOT_SIGN_KEYDIR = "/keys/directory" 14# UBOOT_SIGN_KEYNAME = "dev" # keys name in keydir (eg. "dev.crt", "dev.key") 15# UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" 16# UBOOT_SIGN_ENABLE = "1" 17# 18# As verified boot depends on fitImage generation, following is also required: 19# 20# KERNEL_CLASSES ?= " kernel-fitimage " 21# KERNEL_IMAGETYPE ?= "fitImage" 22# 23# The signature support is limited to the use of CONFIG_OF_SEPARATE in U-Boot. 24# 25# For more details on signature process, please refer to U-Boot documentation. 26 27# We need some variables from u-boot-config 28inherit uboot-config 29 30# Enable use of a U-Boot fitImage 31UBOOT_FITIMAGE_ENABLE ?= "0" 32 33# Signature activation - this requires UBOOT_FITIMAGE_ENABLE = "1" 34SPL_SIGN_ENABLE ?= "0" 35 36# Default value for deployment filenames. 37UBOOT_DTB_IMAGE ?= "u-boot-${MACHINE}-${PV}-${PR}.dtb" 38UBOOT_DTB_BINARY ?= "u-boot.dtb" 39UBOOT_DTB_SIGNED ?= "${UBOOT_DTB_BINARY}-signed" 40UBOOT_DTB_SYMLINK ?= "u-boot-${MACHINE}.dtb" 41UBOOT_NODTB_IMAGE ?= "u-boot-nodtb-${MACHINE}-${PV}-${PR}.bin" 42UBOOT_NODTB_BINARY ?= "u-boot-nodtb.bin" 43UBOOT_NODTB_SYMLINK ?= "u-boot-nodtb-${MACHINE}.bin" 44UBOOT_ITS_IMAGE ?= "u-boot-its-${MACHINE}-${PV}-${PR}" 45UBOOT_ITS ?= "u-boot.its" 46UBOOT_ITS_SYMLINK ?= "u-boot-its-${MACHINE}" 47UBOOT_FITIMAGE_IMAGE ?= "u-boot-fitImage-${MACHINE}-${PV}-${PR}" 48UBOOT_FITIMAGE_BINARY ?= "u-boot-fitImage" 49UBOOT_FITIMAGE_SYMLINK ?= "u-boot-fitImage-${MACHINE}" 50SPL_DIR ?= "spl" 51SPL_DTB_IMAGE ?= "u-boot-spl-${MACHINE}-${PV}-${PR}.dtb" 52SPL_DTB_BINARY ?= "u-boot-spl.dtb" 53SPL_DTB_SIGNED ?= "${SPL_DTB_BINARY}-signed" 54SPL_DTB_SYMLINK ?= "u-boot-spl-${MACHINE}.dtb" 55SPL_NODTB_IMAGE ?= "u-boot-spl-nodtb-${MACHINE}-${PV}-${PR}.bin" 56SPL_NODTB_BINARY ?= "u-boot-spl-nodtb.bin" 57SPL_NODTB_SYMLINK ?= "u-boot-spl-nodtb-${MACHINE}.bin" 58 59# U-Boot fitImage description 60UBOOT_FIT_DESC ?= "U-Boot fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}" 61 62# U-Boot fitImage Hash Algo 63UBOOT_FIT_HASH_ALG ?= "sha256" 64 65# U-Boot fitImage Signature Algo 66UBOOT_FIT_SIGN_ALG ?= "rsa2048" 67 68# Generate keys for signing U-Boot fitImage 69UBOOT_FIT_GENERATE_KEYS ?= "0" 70 71# Size of private keys in number of bits 72UBOOT_FIT_SIGN_NUMBITS ?= "2048" 73 74# args to openssl genrsa (Default is just the public exponent) 75UBOOT_FIT_KEY_GENRSA_ARGS ?= "-F4" 76 77# args to openssl req (Default is -batch for non interactive mode and 78# -new for new certificate) 79UBOOT_FIT_KEY_REQ_ARGS ?= "-batch -new" 80 81# Standard format for public key certificate 82UBOOT_FIT_KEY_SIGN_PKCS ?= "-x509" 83 84# length of address in number of <u32> cells 85# ex: 1 32bits address, 2 64bits address 86UBOOT_FIT_ADDRESS_CELLS ?= "1" 87 88# This is only necessary for determining the signing configuration 89KERNEL_PN = "${PREFERRED_PROVIDER_virtual/kernel}" 90 91UBOOT_FIT_UBOOT_LOADADDRESS ?= "${UBOOT_LOADADDRESS}" 92UBOOT_FIT_UBOOT_ENTRYPOINT ?= "${UBOOT_ENTRYPOINT}" 93 94python() { 95 # We need u-boot-tools-native if we're creating a U-Boot fitImage 96 sign = d.getVar('UBOOT_SIGN_ENABLE') == '1' 97 if d.getVar('UBOOT_FITIMAGE_ENABLE') == '1' or sign: 98 d.appendVar('DEPENDS', " u-boot-tools-native dtc-native") 99 if sign: 100 d.appendVar('DEPENDS', " " + d.getVar('KERNEL_PN')) 101} 102 103concat_dtb() { 104 type="$1" 105 binary="$2" 106 107 if [ -e "${UBOOT_DTB_BINARY}" ]; then 108 # Re-sign the kernel in order to add the keys to our dtb 109 ${UBOOT_MKIMAGE_SIGN} \ 110 ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \ 111 -F -k "${UBOOT_SIGN_KEYDIR}" \ 112 -K "${UBOOT_DTB_BINARY}" \ 113 -r ${B}/fitImage-linux \ 114 ${UBOOT_MKIMAGE_SIGN_ARGS} 115 # Verify the kernel image and u-boot dtb 116 ${UBOOT_FIT_CHECK_SIGN} \ 117 -k "${UBOOT_DTB_BINARY}" \ 118 -f ${B}/fitImage-linux 119 cp ${UBOOT_DTB_BINARY} ${UBOOT_DTB_SIGNED} 120 fi 121 122 # If we're not using a signed u-boot fit, concatenate SPL w/o DTB & U-Boot DTB 123 # with public key (otherwise U-Boot will be packaged by uboot_fitimage_assemble) 124 if [ "${SPL_SIGN_ENABLE}" != "1" ] ; then 125 if [ "x${UBOOT_SUFFIX}" = "ximg" -o "x${UBOOT_SUFFIX}" = "xrom" ] && \ 126 [ -e "${UBOOT_DTB_BINARY}" ]; then 127 oe_runmake EXT_DTB="${UBOOT_DTB_SIGNED}" ${UBOOT_MAKE_TARGET} 128 if [ -n "${binary}" ]; then 129 cp ${binary} ${UBOOT_BINARYNAME}-${type}.${UBOOT_SUFFIX} 130 fi 131 elif [ -e "${UBOOT_NODTB_BINARY}" -a -e "${UBOOT_DTB_BINARY}" ]; then 132 if [ -n "${binary}" ]; then 133 cat ${UBOOT_NODTB_BINARY} ${UBOOT_DTB_SIGNED} | tee ${binary} > \ 134 ${UBOOT_BINARYNAME}-${type}.${UBOOT_SUFFIX} 135 else 136 cat ${UBOOT_NODTB_BINARY} ${UBOOT_DTB_SIGNED} > ${UBOOT_BINARY} 137 fi 138 else 139 bbwarn "Failure while adding public key to u-boot binary. Verified boot won't be available." 140 fi 141 fi 142} 143 144deploy_dtb() { 145 type="$1" 146 147 if [ -n "${type}" ]; then 148 uboot_dtb_binary="u-boot-${type}-${PV}-${PR}.dtb" 149 uboot_nodtb_binary="u-boot-nodtb-${type}-${PV}-${PR}.bin" 150 else 151 uboot_dtb_binary="${UBOOT_DTB_IMAGE}" 152 uboot_nodtb_binary="${UBOOT_NODTB_IMAGE}" 153 fi 154 155 if [ -e "${UBOOT_DTB_SIGNED}" ]; then 156 install -Dm644 ${UBOOT_DTB_SIGNED} ${DEPLOYDIR}/${uboot_dtb_binary} 157 if [ -n "${type}" ]; then 158 ln -sf ${uboot_dtb_binary} ${DEPLOYDIR}/${UBOOT_DTB_IMAGE} 159 fi 160 fi 161 162 if [ -f "${UBOOT_NODTB_BINARY}" ]; then 163 install -Dm644 ${UBOOT_NODTB_BINARY} ${DEPLOYDIR}/${uboot_nodtb_binary} 164 if [ -n "${type}" ]; then 165 ln -sf ${uboot_nodtb_binary} ${DEPLOYDIR}/${UBOOT_NODTB_IMAGE} 166 fi 167 fi 168} 169 170concat_spl_dtb() { 171 if [ -e "${SPL_DIR}/${SPL_NODTB_BINARY}" -a -e "${SPL_DIR}/${SPL_DTB_BINARY}" ] ; then 172 cat ${SPL_DIR}/${SPL_NODTB_BINARY} ${SPL_DIR}/${SPL_DTB_SIGNED} > "${SPL_BINARY}" 173 else 174 bbwarn "Failure while adding public key to spl binary. Verified U-Boot boot won't be available." 175 fi 176} 177 178deploy_spl_dtb() { 179 type="$1" 180 181 if [ -n "${type}" ]; then 182 spl_dtb_binary="u-boot-spl-${type}-${PV}-${PR}.dtb" 183 spl_nodtb_binary="u-boot-spl-nodtb-${type}-${PV}-${PR}.bin" 184 else 185 spl_dtb_binary="${SPL_DTB_IMAGE}" 186 spl_nodtb_binary="${SPL_NODTB_IMAGE}" 187 fi 188 189 if [ -e "${SPL_DIR}/${SPL_DTB_SIGNED}" ] ; then 190 install -Dm644 ${SPL_DIR}/${SPL_DTB_SIGNED} ${DEPLOYDIR}/${spl_dtb_binary} 191 if [ -n "${type}" ]; then 192 ln -sf ${spl_dtb_binary} ${DEPLOYDIR}/${SPL_DTB_IMAGE} 193 fi 194 fi 195 196 if [ -f "${SPL_DIR}/${SPL_NODTB_BINARY}" ] ; then 197 install -Dm644 ${SPL_DIR}/${SPL_NODTB_BINARY} ${DEPLOYDIR}/${spl_nodtb_binary} 198 if [ -n "${type}" ]; then 199 ln -sf ${spl_nodtb_binary} ${DEPLOYDIR}/${SPL_NODTB_IMAGE} 200 fi 201 fi 202 203 # For backwards compatibility... 204 install -Dm644 ${SPL_BINARY} ${DEPLOYDIR}/${SPL_IMAGE} 205} 206 207do_uboot_generate_rsa_keys() { 208 if [ "${SPL_SIGN_ENABLE}" = "0" ] && [ "${UBOOT_FIT_GENERATE_KEYS}" = "1" ]; then 209 bbwarn "UBOOT_FIT_GENERATE_KEYS is set to 1 eventhough SPL_SIGN_ENABLE is set to 0. The keys will not be generated as they won't be used." 210 fi 211 212 if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${UBOOT_FIT_GENERATE_KEYS}" = "1" ]; then 213 214 # Generate keys only if they don't already exist 215 if [ ! -f "${SPL_SIGN_KEYDIR}/${SPL_SIGN_KEYNAME}".key ] || \ 216 [ ! -f "${SPL_SIGN_KEYDIR}/${SPL_SIGN_KEYNAME}".crt ]; then 217 218 # make directory if it does not already exist 219 mkdir -p "${SPL_SIGN_KEYDIR}" 220 221 echo "Generating RSA private key for signing U-Boot fitImage" 222 openssl genrsa ${UBOOT_FIT_KEY_GENRSA_ARGS} -out \ 223 "${SPL_SIGN_KEYDIR}/${SPL_SIGN_KEYNAME}".key \ 224 "${UBOOT_FIT_SIGN_NUMBITS}" 225 226 echo "Generating certificate for signing U-Boot fitImage" 227 openssl req ${UBOOT_FIT_KEY_REQ_ARGS} "${UBOOT_FIT_KEY_SIGN_PKCS}" \ 228 -key "${SPL_SIGN_KEYDIR}/${SPL_SIGN_KEYNAME}".key \ 229 -out "${SPL_SIGN_KEYDIR}/${SPL_SIGN_KEYNAME}".crt 230 fi 231 fi 232 233} 234 235addtask uboot_generate_rsa_keys before do_uboot_assemble_fitimage after do_compile 236 237# Create a ITS file for the U-boot FIT, for use when 238# we want to sign it so that the SPL can verify it 239uboot_fitimage_assemble() { 240 rm -f ${UBOOT_ITS} ${UBOOT_FITIMAGE_BINARY} 241 242 # First we create the ITS script 243 cat << EOF >> ${UBOOT_ITS} 244/dts-v1/; 245 246/ { 247 description = "${UBOOT_FIT_DESC}"; 248 #address-cells = <${UBOOT_FIT_ADDRESS_CELLS}>; 249 250 images { 251 uboot { 252 description = "U-Boot image"; 253 data = /incbin/("${UBOOT_NODTB_BINARY}"); 254 type = "standalone"; 255 os = "u-boot"; 256 arch = "${UBOOT_ARCH}"; 257 compression = "none"; 258 load = <${UBOOT_FIT_UBOOT_LOADADDRESS}>; 259 entry = <${UBOOT_FIT_UBOOT_ENTRYPOINT}>; 260EOF 261 262 if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then 263 cat << EOF >> ${UBOOT_ITS} 264 signature { 265 algo = "${UBOOT_FIT_HASH_ALG},${UBOOT_FIT_SIGN_ALG}"; 266 key-name-hint = "${SPL_SIGN_KEYNAME}"; 267 }; 268EOF 269 fi 270 271 cat << EOF >> ${UBOOT_ITS} 272 }; 273 fdt { 274 description = "U-Boot FDT"; 275 data = /incbin/("${UBOOT_DTB_BINARY}"); 276 type = "flat_dt"; 277 arch = "${UBOOT_ARCH}"; 278 compression = "none"; 279EOF 280 281 if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then 282 cat << EOF >> ${UBOOT_ITS} 283 signature { 284 algo = "${UBOOT_FIT_HASH_ALG},${UBOOT_FIT_SIGN_ALG}"; 285 key-name-hint = "${SPL_SIGN_KEYNAME}"; 286 }; 287EOF 288 fi 289 290 cat << EOF >> ${UBOOT_ITS} 291 }; 292 }; 293 294 configurations { 295 default = "conf"; 296 conf { 297 description = "Boot with signed U-Boot FIT"; 298 loadables = "uboot"; 299 fdt = "fdt"; 300 }; 301 }; 302}; 303EOF 304 305 # 306 # Assemble the U-boot FIT image 307 # 308 ${UBOOT_MKIMAGE} \ 309 ${@'-D "${SPL_MKIMAGE_DTCOPTS}"' if len('${SPL_MKIMAGE_DTCOPTS}') else ''} \ 310 -f ${UBOOT_ITS} \ 311 ${UBOOT_FITIMAGE_BINARY} 312 313 if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then 314 # 315 # Sign the U-boot FIT image and add public key to SPL dtb 316 # 317 ${UBOOT_MKIMAGE_SIGN} \ 318 ${@'-D "${SPL_MKIMAGE_DTCOPTS}"' if len('${SPL_MKIMAGE_DTCOPTS}') else ''} \ 319 -F -k "${SPL_SIGN_KEYDIR}" \ 320 -K "${SPL_DIR}/${SPL_DTB_BINARY}" \ 321 -r ${UBOOT_FITIMAGE_BINARY} \ 322 ${SPL_MKIMAGE_SIGN_ARGS} 323 # 324 # Verify the U-boot FIT image and SPL dtb 325 # 326 ${UBOOT_FIT_CHECK_SIGN} \ 327 -k "${SPL_DIR}/${SPL_DTB_BINARY}" \ 328 -f ${UBOOT_FITIMAGE_BINARY} 329 fi 330 331 if [ -e "${SPL_DIR}/${SPL_DTB_BINARY}" ]; then 332 cp ${SPL_DIR}/${SPL_DTB_BINARY} ${SPL_DIR}/${SPL_DTB_SIGNED} 333 fi 334} 335 336uboot_assemble_fitimage_helper() { 337 type="$1" 338 binary="$2" 339 340 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a -n "${UBOOT_DTB_BINARY}" ] ; then 341 concat_dtb $type $binary 342 fi 343 344 if [ "${UBOOT_FITIMAGE_ENABLE}" = "1" -a -n "${SPL_DTB_BINARY}" ]; then 345 uboot_fitimage_assemble 346 fi 347 348 if [ "${SPL_SIGN_ENABLE}" = "1" -a -n "${SPL_DTB_BINARY}" ] ; then 349 concat_spl_dtb 350 fi 351} 352 353do_uboot_assemble_fitimage() { 354 if [ "${UBOOT_SIGN_ENABLE}" = "1" ] ; then 355 cp "${STAGING_DIR_HOST}/sysroot-only/fitImage" "${B}/fitImage-linux" 356 fi 357 358 if [ -n "${UBOOT_CONFIG}" ]; then 359 unset i j k 360 for config in ${UBOOT_MACHINE}; do 361 i=$(expr $i + 1); 362 for type in ${UBOOT_CONFIG}; do 363 j=$(expr $j + 1); 364 if [ $j -eq $i ]; then 365 break; 366 fi 367 done 368 369 for binary in ${UBOOT_BINARIES}; do 370 k=$(expr $j + 1); 371 if [ $k -eq $i ]; then 372 break; 373 fi 374 done 375 376 cd ${B}/${config} 377 uboot_assemble_fitimage_helper ${type} ${binary} 378 done 379 else 380 cd ${B} 381 uboot_assemble_fitimage_helper "" ${UBOOT_BINARY} 382 fi 383} 384 385addtask uboot_assemble_fitimage before do_install do_deploy after do_compile 386 387deploy_helper() { 388 type="$1" 389 390 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a -n "${UBOOT_DTB_SIGNED}" ] ; then 391 deploy_dtb $type 392 fi 393 394 if [ "${UBOOT_FITIMAGE_ENABLE}" = "1" -a -n "${SPL_DTB_BINARY}" ]; then 395 if [ -n "${type}" ]; then 396 uboot_its_image="u-boot-its-${type}-${PV}-${PR}" 397 uboot_fitimage_image="u-boot-fitImage-${type}-${PV}-${PR}" 398 else 399 uboot_its_image="${UBOOT_ITS_IMAGE}" 400 uboot_fitimage_image="${UBOOT_FITIMAGE_IMAGE}" 401 fi 402 403 install -Dm644 ${UBOOT_FITIMAGE_BINARY} ${DEPLOYDIR}/$uboot_fitimage_image 404 install -Dm644 ${UBOOT_ITS} ${DEPLOYDIR}/$uboot_its_image 405 406 if [ -n "${type}" ]; then 407 ln -sf $uboot_its_image ${DEPLOYDIR}/${UBOOT_ITS_IMAGE} 408 ln -sf $uboot_fitimage_image ${DEPLOYDIR}/${UBOOT_FITIMAGE_IMAGE} 409 fi 410 fi 411 412 if [ "${SPL_SIGN_ENABLE}" = "1" -a -n "${SPL_DTB_SIGNED}" ] ; then 413 deploy_spl_dtb $type 414 fi 415} 416 417do_deploy:prepend() { 418 if [ -n "${UBOOT_CONFIG}" ]; then 419 unset i j k 420 for config in ${UBOOT_MACHINE}; do 421 i=$(expr $i + 1); 422 for type in ${UBOOT_CONFIG}; do 423 j=$(expr $j + 1); 424 if [ $j -eq $i ]; then 425 cd ${B}/${config} 426 deploy_helper ${type} 427 fi 428 done 429 unset j 430 done 431 unset i 432 else 433 cd ${B} 434 deploy_helper "" 435 fi 436 437 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a -n "${UBOOT_DTB_BINARY}" ] ; then 438 ln -sf ${UBOOT_DTB_IMAGE} ${DEPLOYDIR}/${UBOOT_DTB_BINARY} 439 ln -sf ${UBOOT_DTB_IMAGE} ${DEPLOYDIR}/${UBOOT_DTB_SYMLINK} 440 ln -sf ${UBOOT_NODTB_IMAGE} ${DEPLOYDIR}/${UBOOT_NODTB_SYMLINK} 441 ln -sf ${UBOOT_NODTB_IMAGE} ${DEPLOYDIR}/${UBOOT_NODTB_BINARY} 442 fi 443 444 if [ "${UBOOT_FITIMAGE_ENABLE}" = "1" ] ; then 445 ln -sf ${UBOOT_ITS_IMAGE} ${DEPLOYDIR}/${UBOOT_ITS} 446 ln -sf ${UBOOT_ITS_IMAGE} ${DEPLOYDIR}/${UBOOT_ITS_SYMLINK} 447 ln -sf ${UBOOT_FITIMAGE_IMAGE} ${DEPLOYDIR}/${UBOOT_FITIMAGE_BINARY} 448 ln -sf ${UBOOT_FITIMAGE_IMAGE} ${DEPLOYDIR}/${UBOOT_FITIMAGE_SYMLINK} 449 fi 450 451 if [ "${SPL_SIGN_ENABLE}" = "1" -a -n "${SPL_DTB_BINARY}" ] ; then 452 ln -sf ${SPL_DTB_IMAGE} ${DEPLOYDIR}/${SPL_DTB_SYMLINK} 453 ln -sf ${SPL_DTB_IMAGE} ${DEPLOYDIR}/${SPL_DTB_BINARY} 454 ln -sf ${SPL_NODTB_IMAGE} ${DEPLOYDIR}/${SPL_NODTB_SYMLINK} 455 ln -sf ${SPL_NODTB_IMAGE} ${DEPLOYDIR}/${SPL_NODTB_BINARY} 456 fi 457} 458 459do_deploy:append() { 460 # If we're creating a u-boot fitImage, point u-boot.bin 461 # symlink since it might get used by image recipes 462 if [ "${UBOOT_FITIMAGE_ENABLE}" = "1" ] ; then 463 ln -sf ${UBOOT_FITIMAGE_IMAGE} ${DEPLOYDIR}/${UBOOT_BINARY} 464 ln -sf ${UBOOT_FITIMAGE_IMAGE} ${DEPLOYDIR}/${UBOOT_SYMLINK} 465 fi 466} 467