| OLD | NEW |
| 1 #!/bin/sh | 1 #!/bin/sh |
| 2 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 # | 5 # |
| 6 # Derived from dev_debug_vboot. | 6 # Derived from dev_debug_vboot. |
| 7 # | 7 # |
| 8 # This script checks if system firmware and SSD images are ready for verified | 8 # This script checks if system firmware and SSD images are ready for verified |
| 9 # booting. | 9 # booting. |
| 10 # | 10 # |
| 11 | 11 |
| 12 alert() { |
| 13 echo "$*" 1>&2 |
| 14 } |
| 15 |
| 12 if [ "$#" != "2" ]; then | 16 if [ "$#" != "2" ]; then |
| 13 echo "ERROR: Usage: $0 kernel_device main_firmware" 1>&2 | 17 alert "ERROR: Usage: $0 kernel_device main_firmware" |
| 14 exit 1 | 18 exit 1 |
| 15 fi | 19 fi |
| 16 | 20 |
| 21 DEVKEYS="/usr/share/vboot/devkeys" |
| 17 TMPDIR="$(mktemp -d)" | 22 TMPDIR="$(mktemp -d)" |
| 18 KERN_DEV="$(readlink -f "$1")" | 23 KERN_DEV="$(readlink -f "$1")" |
| 19 FIRMWARE_IMAGE="$(readlink -f "$2")" | 24 FIRMWARE_IMAGE="$(readlink -f "$2")" |
| 20 RETURN=0 | 25 RETURN=0 |
| 21 | 26 |
| 22 invoke() { | 27 invoke() { |
| 23 # Usage: invoke "message" "shell-command" | 28 # Usage: invoke "message" "shell-command" |
| 24 result=0 | 29 result=0 |
| 25 message="$1" | 30 message="$1" |
| 26 shift | 31 shift |
| 27 eval "$@" >_stdout 2>_stderr || result=$? | 32 eval "$@" >_stdout 2>_stderr || result=$? |
| 28 if [ "$result" != 0 ]; then | 33 if [ "$result" != 0 ]; then |
| 29 echo "ERROR: Failed to $message" 1>&2 | 34 alert "ERROR: Failed to $message" |
| 30 echo "Command detail: $@" 1>&2 | 35 alert "Command detail: $@" |
| 31 cat _stdout _stderr 1>&2 | 36 cat _stdout _stderr 1>&2 |
| 32 RETURN=1 | 37 RETURN=1 |
| 33 fi | 38 fi |
| 34 } | 39 } |
| 35 | 40 |
| 36 detect_section_name() { | 41 detect_section_name() { |
| 37 # Usage: detect_section_name official_name alias_name | 42 # Usage: detect_section_name official_name alias_name |
| 38 if [ -f "$2" ]; then | 43 if [ -f "$2" ]; then |
| 39 echo "$2" | 44 echo "$2" |
| 40 else | 45 else |
| 41 echo "$1" | 46 echo "$1" |
| 42 fi | 47 fi |
| 43 } | 48 } |
| 44 | 49 |
| 45 verify_keys() { | 50 verify_keys() { |
| 46 # Usage: verify_keys kernel_device main_firmware | 51 # Usage: verify_keys kernel_device main_firmware |
| 47 | 52 |
| 48 # Define section names | 53 # Define section names |
| 49 GBB="$(detect_section_name GBB GBB_Area)" | 54 GBB="$(detect_section_name GBB GBB_Area)" |
| 50 FW_MAIN_A="$(detect_section_name FW_MAIN_A Firmware_A_Data)" | 55 FW_MAIN_A="$(detect_section_name FW_MAIN_A Firmware_A_Data)" |
| 51 FW_MAIN_B="$(detect_section_name FW_MAIN_B Firmware_B_Data)" | 56 FW_MAIN_B="$(detect_section_name FW_MAIN_B Firmware_B_Data)" |
| 52 VBLOCK_A="$(detect_section_name VBLOCK_A Firmware_A_Key)" | 57 VBLOCK_A="$(detect_section_name VBLOCK_A Firmware_A_Key)" |
| 53 VBLOCK_B="$(detect_section_name VBLOCK_B Firmware_B_Key)" | 58 VBLOCK_B="$(detect_section_name VBLOCK_B Firmware_B_Key)" |
| 54 | 59 |
| 55 invoke "dump kernel" dd if="$1" bs=1M count=64 of=hd_kern.blob | 60 invoke "dump kernel" dd if="$1" bs=1M count=64 of=hd_kern.blob |
| 56 invoke "extract firmware" dump_fmap -x "$2" | 61 invoke "extract firmware" dump_fmap -x "$2" |
| 57 invoke "get keys from firmware" \ | 62 invoke "get keys from firmware" \ |
| 58 gbb_utility -g --rootkey rootkey.vbpubk "$GBB" | 63 gbb_utility -g --rootkey rootkey.vbpubk \ |
| 64 --recoverykey recoverykey.vbpubk "$GBB" |
| 59 invoke "unpack rootkey" \ | 65 invoke "unpack rootkey" \ |
| 60 vbutil_key --unpack rootkey.vbpubk | 66 vbutil_key --unpack rootkey.vbpubk |
| 67 invoke "unpack recovery key" \ |
| 68 vbutil_key --unpack recoverykey.vbpubk |
| 69 |
| 70 # check if rootkey is developer key. 130 is the magic number for DEV key |
| 71 local key |
| 72 local rootkey_hash="$(od "rootkey.vbpubk" | |
| 73 head -130 | |
| 74 md5sum | |
| 75 sed 's/ .*$//' 2>/dev/null || true)" |
| 76 if [ "$rootkey_hash" = "a13642246ef93daaf75bd791446fec9b" ]; then |
| 77 alert "ERROR: YOU ARE TRYING TO FINALIZE WITH DEV ROOTKEY." |
| 78 fi |
| 61 | 79 |
| 62 # Verify firmware A/B with root key | 80 # Verify firmware A/B with root key |
| 63 invoke "verify VBLOCK_A with FW_MAIN_A" \ | 81 invoke "verify VBLOCK_A with FW_MAIN_A" \ |
| 64 vbutil_firmware --verify "$VBLOCK_A" --signpubkey rootkey.vbpubk \ | 82 vbutil_firmware --verify "$VBLOCK_A" --signpubkey rootkey.vbpubk \ |
| 65 --fv "$FW_MAIN_A" --kernelkey kernel_subkey_a.vbpubk | 83 --fv "$FW_MAIN_A" --kernelkey kernel_subkey_a.vbpubk |
| 66 invoke "verify VBLOCK_B with FW_MAIN_B" \ | 84 invoke "verify VBLOCK_B with FW_MAIN_B" \ |
| 67 vbutil_firmware --verify "$VBLOCK_B" --signpubkey rootkey.vbpubk \ | 85 vbutil_firmware --verify "$VBLOCK_B" --signpubkey rootkey.vbpubk \ |
| 68 --fv "$FW_MAIN_B" --kernelkey kernel_subkey_b.vbpubk | 86 --fv "$FW_MAIN_B" --kernelkey kernel_subkey_b.vbpubk |
| 69 | 87 |
| 70 # Unpack keys and keyblocks | 88 # Unpack keys and keyblocks |
| 71 for key in kernel_subkey_a.vbpubk kernel_subkey_b.vbpubk; do | 89 for key in kernel_subkey_a.vbpubk kernel_subkey_b.vbpubk; do |
| 72 invoke "unpack $key" vbutil_key --unpack $key | 90 invoke "unpack $key" vbutil_key --unpack $key |
| 73 done | 91 done |
| 74 for keyblock in *kern*.blob; do | 92 for keyblock in *kern*.blob; do |
| 75 invoke "unpack $keyblock" vbutil_keyblock --unpack $keyblock | 93 invoke "unpack $keyblock" vbutil_keyblock --unpack $keyblock |
| 76 done | 94 done |
| 77 | 95 |
| 78 # Test each kernel by each key | 96 # Test each kernel by each key |
| 79 for key in kernel_subkey_a.vbpubk kernel_subkey_b.vbpubk | 97 for key in kernel_subkey_a.vbpubk kernel_subkey_b.vbpubk |
| 80 do | 98 do |
| 81 for kern in *kern*.blob; do | 99 for kern in *kern*.blob; do |
| 82 invoke "verify $kern by $key" \ | 100 invoke "verify $kern by $key" \ |
| 83 vbutil_kernel --verify $kern --signpubkey $key | 101 vbutil_kernel --verify $kern --signpubkey $key |
| 84 done | 102 done |
| 85 done | 103 done |
| 104 |
| 105 if [ "$RETURN" != "0" ]; then |
| 106 # Error encountered. Let's try if we can provide more information. |
| 107 key="recoverykey.vbpubk" |
| 108 vbutil_kernel --verify "$kern" --signpubkey "$key" >/dev/null 2>&1 && |
| 109 alert "ERROR: YOU ARE USING A RECOVERY KEY SIGNED IMAGE." || |
| 110 true |
| 111 for key in recovery_key.vbpubk kernel_subkey.vbpubk; do |
| 112 if [ -f "$DEVKEYS/$key" ]; then |
| 113 vbutil_kernel --verify "$kern" \ |
| 114 --signpubkey "$DEVKEYS/$key" >/dev/null 2>&1 && |
| 115 alert "ERROR: YOU ARE FINALIZING WITH DEV-SIGNED IMAGE ($key)." || |
| 116 true |
| 117 fi |
| 118 done |
| 119 fi |
| 120 |
| 86 return $RETURN | 121 return $RETURN |
| 87 } | 122 } |
| 88 | 123 |
| 89 # verify_keys is run inside a sub-shell, so we need to check its return value | 124 # verify_keys is run inside a sub-shell, so we need to check its return value |
| 90 # instead of reading the global variable RETURN. | 125 # instead of reading the global variable RETURN. |
| 91 ( cd "$TMPDIR" | 126 ( cd "$TMPDIR" |
| 92 verify_keys "$KERN_DEV" "$FIRMWARE_IMAGE" ) || RETURN=1 | 127 verify_keys "$KERN_DEV" "$FIRMWARE_IMAGE" ) || RETURN=1 |
| 93 /bin/rm -rf "$TMPDIR" | 128 /bin/rm -rf "$TMPDIR" |
| 94 exit $RETURN | 129 exit $RETURN |
| 95 | 130 |
| OLD | NEW |