xref: /build/core/Makefile
如下code 所示,可见511行是在510行的MKBOOTIMG之后即已经产生boot.img的情况下才调用(BOOT_SIGNER)来为kernel+ramdisk 计算一个总的signature.508$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER)
509 $(call pretty,"Target boot image: $@")
510 $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
511 $(BOOT_SIGNER) /boot $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $@
512 $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE))
BOOT_SIGNER 是在哪里定义的呢?
xref: /build/core/config.mk
BOOT_SIGNER := $(HOST_OUT_EXECUTABLES)/boot_signer
/system/extras/verity/Android.mk
72include $(CLEAR_VARS)
73LOCAL_SRC_FILES := boot_signer
74LOCAL_MODULE := boot_signer
75LOCAL_MODULE_CLASS := EXECUTABLES
76LOCAL_IS_HOST_MODULE := true
77LOCAL_MODULE_TAGS := optional
78LOCAL_REQUIRED_MODULES := BootSignature
79include $(BUILD_PREBUILT)
boot_signer是一个prebuild好的可执行档.
boot_signer.sh 调用boot.signature.jar 包来直接调用bootsignature.java,所以其源码是bootsignature.java
public static void main(String[] args) throws Exception {
291 Security.addProvider(new BouncyCastleProvider());
292
293 if ("-verify".equals(args[0])) {
294 /* args[1] is the path to a signed boot image */
295 verifySignature(args[1]);
296 } else {
303 doSignature(args[0], args[1], args[2], args[3], args[4]);
304 }
305 }
这个函数可以校验boot.img 也可以计算boot.img的signature。我们来看看doSignature
其四个参数的意思如下:
args[0] is the target name, typically /boot
args[1] is the path to a boot image to sign
args[2] is the path to a private key
args[3] is the path to the matching public key certificate
args[4] is the path where to output the signed boot image
public static void doSignature( String target,
221 String imagePath,
222 String keyPath,
223 String certPath,
224 String outPath) throws Exception {
225
226 byte[] image = Utils.read(imagePath);
227 int signableSize = getSignableImageSize(image);
228
229 if (signableSize < image.length) {
230 System.err.println("NOTE: truncating file " + imagePath +
231 " from " + image.length + " to " + signableSize + " bytes");
232 image = Arrays.copyOf(image, signableSize);
233 } else if (signableSize > image.length) {
234 throw new IllegalArgumentException("Invalid image: too short, expected " +
235 signableSize + " bytes");
236 }
237
238 BootSignature bootsig = new BootSignature(target, image.length);
239
240 X509Certificate cert = Utils.loadPEMCertificate(certPath);
241 bootsig.setCertificate(cert);
242
243 PrivateKey key = Utils.loadDERPrivateKeyFromFile(keyPath);
244 bootsig.setSignature(bootsig.sign(image, key),
245 Utils.getSignatureAlgorithmIdentifier(key));
246
247 byte[] encoded_bootsig = bootsig.getEncoded();
248 byte[] image_with_metadata = Arrays.copyOf(image, image.length + encoded_bootsig.length);
249
250 System.arraycopy(encoded_bootsig, 0, image_with_metadata,
251 image.length, encoded_bootsig.length);
252
253 Utils.write(image_with_metadata, outPath);
254 }
227行得到boot.img的size 238行new一个BootSignature。241设定证书。243 装载private key.