| 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 | 
|---|