• android 9 OTA到android11弹出密码框


    引言

    把这个问题归纳为OTA的问题,一方面主要是现象本身是OTA的场景下发生的,另外一方面涉及到了问题出现在bootloader侧,实际也是因为aboot的升级导致的问题点。

    原因分析

    花了很长的时间去定位,因为userdata分区加密的影响,FDE加密模式下,通常出现这种情况的是加密Key的惯性思维去考虑fstab下的分区挂载参数、或者keymaster分区加密是不是改动了啥引起的。码字不易,转载请注明出处https://blog.csdn.net/jeephao/article/details/128200232

    另外,因为nongms的Android 9的userdebug版本上又去掉了userdata分区的加密,Andriod 9升级到android 11是正常的,

    Android 9 OS build是否userdata的加密 Yes/No升级到Android 11是否存在密码弹框
    Android 9 with userdebugYesNo
    Android 9 with userNoYes

    出现问题时的Log如下:

    replace_P_km4_4.log 添加一份怀疑keymaster的Log,最初我认为是keymaster的Security Patch Level从9升级到11是回滚,所以出现此现象,结合这里来看,怀疑这个方向肯定是无法避免的,

    	Line     51: 01-01 10:02:52.098     0     0 I         : Kernel command line: core_ctl_disable_cpumask=0-7 kpti=0 console=ttyMSM0,115200,n8 androidboot.console=ttyMSM0 androidboot.hardware=qcom msm_rtb.filter=0x237 ehci-hcd.park=3 lpm_levels.sleep_disabled=1 androidboot.bootdevice=7824900.sdhci earlycon=msm_serial_dm,0x78af000 androidboot.usbconfigfs=true loop.max_part=7 buildvariant=userdebug androidboot.emmc=true androidboot.verifiedbootstate=orange androidboot.keymaster=1 dm="1 vroot none ro 1,0 5422032 verity 1 PARTUUID=ef676b71-1a66-2b8e-6f8a-387d41f4e75e PARTUUID=ef676b71-1a66-2b8e-6f8a-387d41f4e75e 4096 4096 677754 677754 sha1 9e5415b11b8f4fccaebe6c40eb77bf2cd3d84408 06b1484c9b1c0e05e5217547c146ec7b8e002f54a487dd6b01fc8b5c88e7cd63 10 restart_on_corruption ignore_zero_blocks use_fec_from_device PARTUUID=ef676b71-1a66-2b8e-6f8a-387d41f4e75e fec_roots 2 fec_blocks 683092 fec_start 683092" root=/dev/dm-0 androidboot.vbmeta.device=PARTUUID=6a5d2e34-b13d-27ea-03aa-c3ff0462a1f8 androidboot.vbmeta.avb_version=1.0 androidboot.vbmeta
    	Line   1923: 01-01 10:03:20.668   484   880 I Cryptfs : Using scrypt with keymaster for cryptfs KDF
    	Line   2059: 01-01 10:03:21.219   474   474 I hwservicemanager: getTransport: Cannot find entry android.hardware.keymaster@3.0::IKeymasterDevice/default in either framework or device manifest.
    	Line   2060: 01-01 10:03:21.220   484   880 I vold    : List of Keymaster HALs found:
    	Line   2061: 01-01 10:03:21.220   484   880 I vold    : Keymaster HAL #1: Keymaster HAL: 4 from QTI SecurityLevel: TRUSTED_ENVIRONMENT HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
    	Line   2063: 01-01 10:03:21.221   484   880 D vold    : Computing HMAC for Keymaster HAL: 4 from QTI SecurityLevel: TRUSTED_ENVIRONMENT HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
    	Line   2064: 01-01 10:03:21.225   484   880 I vold    : Using Keymaster HAL: 4 from QTI for encryption.  Security level: TRUSTED_ENVIRONMENT, HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
    	Line   2065: 01-01 10:03:21.227   478   478 E KeyMasterHalDevice: Begin send cmd failed
    	Line   2066: 01-01 10:03:21.228   478   478 E KeyMasterHalDevice: ret: 0
    	Line   2067: 01-01 10:03:21.228   478   478 E KeyMasterHalDevice: resp->status: -62
    	Line   2069: 01-01 10:03:21.228   484   880 E vold    : Keymaster key requires upgrade
    	Line   2071: 01-01 10:03:21.232   474   474 I hwservicemanager: getTransport: Cannot find entry android.hardware.keymaster@3.0::IKeymasterDevice/default in either framework or device manifest.
    	Line   2072: 01-01 10:03:21.233   484   880 I vold    : List of Keymaster HALs found:
    	Line   2073: 01-01 10:03:21.233   484   880 I vold    : Keymaster HAL #1: Keymaster HAL: 4 from QTI SecurityLevel: TRUSTED_ENVIRONMENT HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
    	Line   2074: 01-01 10:03:21.233   484   880 I vold    : Using Keymaster HAL: 4 from QTI for encryption.  Security level: TRUSTED_ENVIRONMENT, HAL: android.hardware.keymaster@4.1::IKeymasterDevice/default
    	Line   2075: 01-01 10:03:21.238   478   478 E KeyMasterHalDevice: Upgrade key send cmd failed
    	Line   2076: 01-01 10:03:21.239   478   478 E KeyMasterHalDevice: ret: 0
    	Line   2077: 01-01 10:03:21.239   478   478 E KeyMasterHalDevice: resp->status: -33
    	Line   2909: 03-07 04:52:59.563  1041  1041 I keystore: found android.hardware.keymaster@4.0::IKeymasterDevice with interface name default and seclevel TRUSTED_ENVIRONMENT
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    定位问题方式

    两个不同的项目升级项目共用同一套代码,一个项目从Android 8升级上来没有使能avb,所以对应的keymaster还是KM3,并未使用KM4, 所以早期一直在这个的判断上,花费不少的时间,并且后面发现和keymaster本身不存在直接关系。

    因为ODM供应商说原生的版本没有这个问题,那就只能通过排查镜像的方式定位具体是哪个image升级造成的,后面追踪发现他们虽然添加了MP image的OTA升级,高通代码逻辑里默认没有考虑bootloader的升级,所以就剩下了aboot没有参与升级,这样一来就定位到了最终的原因。

    另外最直接的突破口是通过比较android 9及android 11 bootloader的代码,发现了\bootable\bootloader\lk\platform\msm_shared\boot_verifier.c的差异,于是尝试和android 9保持一致即可正常OTA.

    #if VERIFIED_BOOT_2 && !VB1_KEY_USED && !HON_PRODUCT_EDA61K
    bool send_rot_command(uint32_t is_unlocked)
    {
    	int ret = 0;
    	unsigned char *input = (unsigned char *)OEMPublicKey;
    	unsigned int key_len = sizeof(OEMPublicKey);
    	unsigned char *keystatebuf = NULL;
    	unsigned char digest[SHA256_SIZE] = {0}, final_digest[SHA256_SIZE] = {0};
    	uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
    	uint32_t boot_device_state = boot_verify_get_state();
    	int app_handle = 0;
    	km_set_rot_req_t *read_req = NULL;
    	km_set_rot_rsp_t read_rsp;
    	app_handle = get_secapp_handle();
    	uint32_t version = 0;
    	void *cpy_ptr;
    
    	if( input == NULL || UINT_MAX - 1 < key_len )
            {
                    dprintf(CRITICAL, "Failed to read ROT key\n");
                    ASSERT(0);
            }
    	switch (boot_device_state)
    	{
    		case GREEN:
    		case YELLOW:
    			if(!( keystatebuf = malloc( key_len + 1)))
    			{
    				dprintf(CRITICAL, "Failed to allocate memory for ROT digest\n");
    				ASSERT(0);
    			}
    			memscpy(keystatebuf , key_len + 1,  input, key_len);
    			hash_find((unsigned char *)keystatebuf, key_len , (unsigned char *) digest, auth_algo);
    			keystatebuf[key_len] = (unsigned char )is_unlocked;
    			hash_find((unsigned char *)keystatebuf, key_len + 1, (unsigned char *) final_digest, auth_algo);
    			break;
    		case ORANGE:
    			// Unlocked device and no verification done.
    			// Send the hash of boot device state
    			input = NULL;
    			hash_find((unsigned char *) &is_unlocked, sizeof(unsigned char), (unsigned char *)&final_digest, auth_algo);
                            break;
    		case RED:
                    default:
    			dprintf(CRITICAL, "Invalid state to boot!\n");
    	}
    	dprintf(SPEW, "Digest: ");
            for(uint8_t i = 0; i < SHA256_SIZE; i++)
                    dprintf(SPEW, "0x%x ", final_digest[i]);
            dprintf(SPEW, "\n");
    
    	if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(final_digest))))
    	{
    		dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
    		ASSERT(0);
    	}
    
    	cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
    	read_req->cmd_id = KEYMASTER_SET_ROT;
    	read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
    	read_req->rot_size  = sizeof(final_digest);
    	memscpy(cpy_ptr, sizeof(final_digest), (void *) &final_digest, sizeof(final_digest));
    	dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
    
    	ret = qseecom_send_command(app_handle, (void*) read_req, sizeof(km_set_rot_req_t) + sizeof(final_digest), (void*) &read_rsp, sizeof(read_rsp));
    	if (ret < 0 || read_rsp.status < 0)
    	{
    		dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
    		free(read_req);
    		return false;
    	}
    
    #if OSVERSION_IN_BOOTIMAGE
    	boot_state_info.is_unlocked = is_unlocked;
    	boot_state_info.color = boot_verify_get_state();
    	memscpy(boot_state_info.public_key, sizeof(boot_state_info.public_key), digest, SHA256_SIZE);
    	boot_verify_send_boot_state(&boot_state_info);
    #endif
    	if ( is_secure_boot_enable()
    		&& (dev_boot_state != GREEN))
    	{
    		version = qseecom_get_version();
    		if(allow_set_fuse(version)) {
    			ret = set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
    			if (ret) {
    				ret = false;
    				goto err;
    			}
    			ret = set_tamper_fuse_cmd(HLOS_TAMPER_NOTIFY_FUSE);
    			if (ret) {
    				dprintf(CRITICAL, "send_rot_command: set_tamper_fuse_cmd (TZ_HLOS_TAMPER_NOTIFY_FUSE) fails!\n");
    				ret = false;
    				goto err;
    			}
    		} else {
    			dprintf(CRITICAL, "send_rot_command: TZ didn't support this feature! Version: major = %d, minor = %d, patch = %d\n", (version >> 22) & 0x3FF, (version >> 12) & 0x3FF, version & 0x3FF);
    		goto err;
    		}
    	}
    	dprintf(CRITICAL, "Sending Root of Trust to trustzone: end\n");
    	ret = true;
    err:
    	if(keystatebuf)
    		free(keystatebuf);
            free(read_req);
            return ret;
    }
    #else
    bool send_rot_command(uint32_t is_unlocked)
    {
    	int ret = 0;
    	unsigned char *input = NULL;
    	char *rot_input = NULL;
    	unsigned int digest[9] = {0}, final_digest[8] = {0};
    	uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
    	uint32_t boot_device_state = boot_verify_get_state();
    	int app_handle = 0;
    	uint32_t len_oem_rsa = 0, len_from_cert = 0;
    	km_set_rot_req_t *read_req = NULL;
    	km_set_rot_rsp_t read_rsp;
    	app_handle = get_secapp_handle();
    	uint32_t version = 0;
    
    	int n = 0, e = 0;
    	switch (boot_device_state)
    	{
    		case GREEN:
    			// Locked device and boot.img verified against OEM keystore.
    			// Send hash of key from OEM KEYSTORE + Boot device state
    			n = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->n);
    			e = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->e);
    			/*this assumes a valid acceptable range for RSA, including 4096 bits of modulo n. */
    			if (n<0 || n>1024)
    			{
    				dprintf(CRITICAL, "Invalid n value from key_material\n");
    				ASSERT(0);
    			}
    			/* e can assumes 3,5,17,257,65537 as valid values, which should be 1 byte long only, we accept 2 bytes or 16 bits long */
    			if( e < 0 || e >16)
    			{
    				dprintf(CRITICAL, "Invalid e value from key_material\n");
    				ASSERT(0);
    			}
    			len_oem_rsa = n + e;
    			if(!(input = malloc(len_oem_rsa)))
    			{
    				dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
    				ASSERT(0);
    			}
    			BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->n, input);
    			BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->e, input+n);
    			hash_find((unsigned char *)input, len_oem_rsa, (unsigned char *) &digest, auth_algo);
    			digest[8] = is_unlocked;
    			break;
    		case YELLOW:
    		case RED:
    			// Locked device and boot.img passed (yellow) or failed (red) verification with the certificate embedded to the boot.img.
    			if (!rsa_from_cert)
    			{
    				dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
    				ASSERT(0);
    			}
    			// Send hash of key from certificate in boot image + boot device state
    			n = BN_num_bytes(rsa_from_cert->n);
    			e = BN_num_bytes(rsa_from_cert->e);
    			/*this assumes a valid acceptable range for RSA, including 4096 bits of modulo n. */
    			if (n<0 || n>1024)
    			{
    				dprintf(CRITICAL, "Invalid n value from rsa_from_cert\n");
    				ASSERT(0);
    			}
    			/* e can assumes 3,5,17,257,65537 as valid values, which should be 1 byte long only, we accept 2 bytes or 16 bits long */
    			if( e < 0 || e >16)
    			{
    				dprintf(CRITICAL, "Invalid e value from rsa_from_cert\n");
    				ASSERT(0);
    			}
    			len_from_cert = n + e;
    			if(!(input = malloc(len_from_cert)))
    			{
    				dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
    				ASSERT(0);
    			}
    			BN_bn2bin(rsa_from_cert->n, input);
    			BN_bn2bin(rsa_from_cert->e, input+n);
    			hash_find((unsigned char *)input, len_from_cert, (unsigned char *) &digest, auth_algo);
    			digest[8] = is_unlocked;
    			break;
    		case ORANGE:
    			// Unlocked device and no verification done.
    			// Send the hash of boot device state
    			input = NULL;
    			digest[0] = is_unlocked;
    			break;
    	}
    
    	hash_find((unsigned char *) digest, sizeof(digest), (unsigned char *)&final_digest, auth_algo);
    	dprintf(SPEW, "Digest: ");
    	for(uint8_t i = 0; i < 8; i++)
    		dprintf(SPEW, "0x%x ", final_digest[i]);
    	dprintf(SPEW, "\n");
    	if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(final_digest))))
    	{
    		dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
    		ASSERT(0);
    	}
    
    	void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
    	// set ROT stucture
    	read_req->cmd_id = KEYMASTER_SET_ROT;
    	read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
    	read_req->rot_size  = sizeof(final_digest);
    	// copy the digest
    	memcpy(cpy_ptr, (void *) &final_digest, sizeof(final_digest));
    	dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
    
    	ret = qseecom_send_command(app_handle, (void*) read_req, sizeof(km_set_rot_req_t) + sizeof(final_digest), (void*) &read_rsp, sizeof(read_rsp));
    	if (ret < 0 || read_rsp.status < 0)
    	{
    		dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
    		if(input)
    			free(input);
    		free(read_req);
    		free(rot_input);
    		return false;
    	}
    
    #if OSVERSION_IN_BOOTIMAGE
    	boot_state_info.is_unlocked = is_unlocked;
    	boot_state_info.color = boot_verify_get_state();
    	memscpy(boot_state_info.public_key, sizeof(boot_state_info.public_key), digest, 32);
    	boot_verify_send_boot_state(&boot_state_info);
    #endif
    	if ( is_secure_boot_enable()
    		&& (dev_boot_state != GREEN))
    	{
    		version = qseecom_get_version();
    		if(allow_set_fuse(version)) {
    			ret = set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
    			if (ret) {
    				ret = false;
    				goto err;
    			}
    			ret = set_tamper_fuse_cmd(HLOS_TAMPER_NOTIFY_FUSE);
    			if (ret) {
    				dprintf(CRITICAL, "send_rot_command: set_tamper_fuse_cmd (TZ_HLOS_TAMPER_NOTIFY_FUSE) fails!\n");
    				ret = false;
    				goto err;
    			}
    		} else {
    			dprintf(CRITICAL, "send_rot_command: TZ didn't support this feature! Version: major = %d, minor = %d, patch = %d\n", (version >> 22) & 0x3FF, (version >> 12) & 0x3FF, version & 0x3FF);
    		ret = false;
    		goto err;
    		}
    	}
    	dprintf(CRITICAL, "Sending Root of Trust to trustzone: end\n");
    	ret = true;
    err:
    	if(input)
    		free(input);
    	free(read_req);
    	free(rot_input);
    	return ret;
    }
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265

    实际补丁通过宏控制跳过处理,一对比还是没有后面高通KBA补丁规范,

    
    diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
    old mode 100644
    new mode 100755
    index a422dae..9dcf8a9
    --- a/platform/msm_shared/boot_verifier.c
    +++ b/platform/msm_shared/boot_verifier.c
    @@ -33,14 +33,17 @@
     #include 
     #include 
     #include 
    +
     #ifdef AVB_USE_HON_KEY
    -#include <HON_oem_keystore.h>
     #include "avb/HON_OEMPublicKey.h"
    -#else
    -#include <oem_keystore.h>
    -#if VERIFIED_BOOT_2
    +#elif VERIFIED_BOOT_2 && !AVB_USE_HON_KEY
     #include 
     #endif
    +
    +#ifdef HON_PRODUCT_EDA51
    +#include <HON_oem_keystore.h>
    +#elif HON_PRODUCT_EDA61K
    +#include <oem_keystore.h>
     #endif
     #include 
     #include 
    @@ -457,7 +460,7 @@ static void boot_verify_send_boot_state(km_boot_state_t *boot_state)
     }
     #endif
    
    -#if VERIFIED_BOOT_2 && !VB1_KEY_USED
    +#if VERIFIED_BOOT_2 && !VB1_KEY_USED && !HON_PRODUCT_EDA61K
     bool send_rot_command(uint32_t is_unlocked)
     {
            int ret = 0;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    高通针对此问题的说明

    先上高通的KBA

    
    [Question]
    The hash calculation of RoT in LK was updated by below commit. So, if the two versions of OTA 
    crossed this commit, we'll see userdata decrypting failure after OTA upgrading, then it will cause 
    boot failed.
    
    Even the same key is used and the device is in the same lock state, a different hash of RoT will be 
    sent to keymaster by old and new versions. That will make decrypting userdata failed.
    
    [Solution]
    
    So, just need to set "TARGET_USES_OTA_KEY_FOR_ROT := true " in device makefile of the new 
    version. It makes LK to keep using the old hash calculation of RoT.
    For new launch projects, this flag can be ignored.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    针对高通变更lk于keymaster之间通信的ROT接口的原始改动,也就是引起Android 9 OTA升级到Android 11的罪魁祸首,如下:

    [Question]
    The hash calculation of RoT in LK was updated by below commit. So, if the two versions of OTA 
    crossed this commit, we'll see userdata decrypting failure after OTA upgrading, then it will cause 
    boot failed.
    
    -rw-r--r--	platform/msm_shared/boot_verifier.c	110
    1 files changed, 110 insertions, 0 deletions
    diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
    index e523751..36e1980 100644
    --- a/platform/msm_shared/boot_verifier.c
    +++ b/platform/msm_shared/boot_verifier.c
    @@ -34,6 +34,7 @@
     #include 
     #include 
     #include 
    +#include <avb/OEMPublicKey.h>
     #include 
     #include 
     #include 
    @@ -449,6 +450,114 @@ static void boot_verify_send_boot_state(km_boot_state_t *boot_state)
     }
     #endif
     
    +#if VERIFIED_BOOT_2
    +bool send_rot_command(uint32_t is_unlocked)
    +{
    +	int ret = 0;
    +	unsigned char *input = (unsigned char *)OEMPublicKey;
    +	unsigned int key_len = sizeof(OEMPublicKey);
    +	unsigned char *keystatebuf = NULL;
    +	unsigned char digest[SHA256_SIZE] = {0}, final_digest[SHA256_SIZE] = {0};
    +	uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
    +	uint32_t boot_device_state = boot_verify_get_state();
    +	int app_handle = 0;
    +	km_set_rot_req_t *read_req = NULL;
    +	km_set_rot_rsp_t read_rsp;
    +	app_handle = get_secapp_handle();
    +	uint32_t version = 0;
    +	void *cpy_ptr;
    +
    +	if( input == NULL || UINT_MAX - 1 < key_len )
    +        {
    +                dprintf(CRITICAL, "Failed to read ROT key\n");
    +                ASSERT(0);
    +        }
    +	switch (boot_device_state)
    +	{
    +		case GREEN:
    +		case YELLOW:
    +			if(!( keystatebuf = malloc( key_len + 1)))
    +			{
    +				dprintf(CRITICAL, "Failed to allocate memory for ROT digest\n");
    +				ASSERT(0);
    +			}
    +			memscpy(keystatebuf , key_len + 1,  input, key_len);
    +			hash_find((unsigned char *)keystatebuf, key_len , (unsigned char *) digest, auth_algo);
    +			keystatebuf[key_len] = (unsigned char )is_unlocked;
    +			hash_find((unsigned char *)keystatebuf, key_len + 1, (unsigned char *) final_digest, auth_algo);
    +			break;
    +		case ORANGE:
    +			// Unlocked device and no verification done.
    +			// Send the hash of boot device state
    +			input = NULL;
    +			hash_find((unsigned char *) &is_unlocked, sizeof(unsigned char), (unsigned char *)&final_digest, auth_algo);
    +                        break;
    +		case RED:
    +                default:
    +			dprintf(CRITICAL, "Invalid state to boot!\n");
    +	}
    +	dprintf(SPEW, "Digest: ");
    +        for(uint8_t i = 0; i < SHA256_SIZE; i++)
    +                dprintf(SPEW, "0x%x ", final_digest[i]);
    +        dprintf(SPEW, "\n");
    +
    +	if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(final_digest))))
    +	{
    +		dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
    +		ASSERT(0);
    +	}
    +
    +	cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
    +	read_req->cmd_id = KEYMASTER_SET_ROT;
    +	read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
    +	read_req->rot_size  = sizeof(final_digest);
    +	memscpy(cpy_ptr, sizeof(final_digest), (void *) &final_digest, sizeof(final_digest));
    +	dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
    +
    +	ret = qseecom_send_command(app_handle, (void*) read_req, sizeof(km_set_rot_req_t) + sizeof(final_digest), (void*) &read_rsp, sizeof(read_rsp));
    +	if (ret < 0 || read_rsp.status < 0)
    +	{
    +		dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
    +		free(read_req);
    +		return false;
    +	}
    +
    +#if OSVERSION_IN_BOOTIMAGE
    +	boot_state_info.is_unlocked = is_unlocked;
    +	boot_state_info.color = boot_verify_get_state();
    +	memscpy(boot_state_info.public_key, sizeof(boot_state_info.public_key), digest, SHA256_SIZE);
    +	boot_verify_send_boot_state(&boot_state_info);
    +#endif
    +	if ( is_secure_boot_enable()
    +		&& (dev_boot_state != GREEN))
    +	{
    +		version = qseecom_get_version();
    +		if(allow_set_fuse(version)) {
    +			ret = set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
    +			if (ret) {
    +				ret = false;
    +				goto err;
    +			}
    +			ret = set_tamper_fuse_cmd(HLOS_TAMPER_NOTIFY_FUSE);
    +			if (ret) {
    +				dprintf(CRITICAL, "send_rot_command: set_tamper_fuse_cmd (TZ_HLOS_TAMPER_NOTIFY_FUSE) fails!\n");
    +				ret = false;
    +				goto err;
    +			}
    +		} else {
    +			dprintf(CRITICAL, "send_rot_command: TZ didn't support this feature! Version: major = %d, minor = %d, patch = %d\n", (version >> 22) & 0x3FF, (version >> 12) & 0x3FF, version & 0x3FF);
    +		goto err;
    +		}
    +	}
    +	dprintf(CRITICAL, "Sending Root of Trust to trustzone: end\n");
    +	ret = true;
    +err:
    +	if(keystatebuf)
    +		free(keystatebuf);
    +        free(read_req);
    +        return ret;
    +}
    +#else
     bool send_rot_command(uint32_t is_unlocked)
     {
     	int ret = 0;
    @@ -605,6 +714,7 @@ err:
     	free(rot_input);
     	return ret;
     }
    +#endif
     
     unsigned char* get_boot_fingerprint(unsigned int* buf_size)
     {
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142

    高通添加宏控来绕过此问题,但是自己需要在Makefile添加true属性,need to set "TARGET_USES_OTA_KEY_FOR_ROT := true "

    
    -rw-r--r--	AndroidBoot.mk	10
    -rw-r--r--	makefile	5
    -rw-r--r--	platform/msm_shared/boot_verifier.c	2
    3 files changed, 14 insertions, 3 deletions
    diff --git a/AndroidBoot.mk b/AndroidBoot.mk
    index 8697f7d..6110497 100644
    --- a/AndroidBoot.mk
    +++ b/AndroidBoot.mk
    @@ -51,6 +51,12 @@ else
       VERIFIED_BOOT_2 := VERIFIED_BOOT_2=0
     endif
     
    +ifeq ($(TARGET_USES_OTA_KEY_FOR_ROT),true)
    +  VB1_KEY_USED := VB1_KEY_USED=1
    +else
    +  VB1_KEY_USED := VB1_KEY_USED=0
    +endif
    +
     ifeq ($(BOARD_DTBO_NOT_SUPPORTED),true)
       TARGET_DTBO_NOT_SUPPORTED := TARGET_DTBO_NOT_SUPPORTED=1
     else
    @@ -125,7 +131,7 @@ ABOOT_CLEAN:
     # ELF binary for ABOOT
     TARGET_ABOOT_ELF := $(PRODUCT_OUT)/aboot.elf
     $(TARGET_ABOOT_ELF): ABOOT_CLEAN | $(ABOOT_OUT)
    -	$(MAKE) -C $(LK_PATH) TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=$(CROOT_DIR)/$(ABOOT_OUT) $(BOOTLOADER_PLATFORM) $(EMMC_BOOT) $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(VERIFIED_BOOT_2) $(TARGET_DTBO_NOT_SUPPORTED) $(ENABLE_DISPLAY) $(ENABLE_KASLRSEED) $(ENABLE_BOOTDEVICE_MOUNT) $(DEVICE_STATUS) $(BUILD_VARIANT) $(BOARD_NAME) $(ENABLE_VB_ATTEST) $(OSVERSION_IN_BOOTIMAGE) $(QSEECOM_SECAPP_REGION_2MB) $(TARGET_USE_SYSTEM_AS_ROOT_IMAGE)
    +	$(MAKE) -C $(LK_PATH) TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=$(CROOT_DIR)/$(ABOOT_OUT) $(BOOTLOADER_PLATFORM) $(EMMC_BOOT) $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(VERIFIED_BOOT_2) $(VB1_KEY_USED) $(TARGET_DTBO_NOT_SUPPORTED) $(ENABLE_DISPLAY) $(ENABLE_KASLRSEED) $(ENABLE_BOOTDEVICE_MOUNT) $(DEVICE_STATUS) $(BUILD_VARIANT) $(BOARD_NAME) $(ENABLE_VB_ATTEST) $(OSVERSION_IN_BOOTIMAGE) $(QSEECOM_SECAPP_REGION_2MB) $(TARGET_USE_SYSTEM_AS_ROOT_IMAGE)
     
     # NAND variant output
     TARGET_NAND_BOOTLOADER := $(PRODUCT_OUT)/appsboot.mbn
    @@ -154,7 +160,7 @@ $(TARGET_NAND_BOOTLOADER): appsbootldr_clean | $(NAND_BOOTLOADER_OUT)
     
     # Top level for eMMC variant targets
     $(TARGET_EMMC_BOOTLOADER): emmc_appsbootldr_clean | $(EMMC_BOOTLOADER_OUT) $(INSTALLED_KEYSTOREIMAGE_TARGET)
    -	$(MAKE) -C $(LK_PATH) TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=$(CROOT_DIR)/$(EMMC_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) EMMC_BOOT=1 $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(VERIFIED_BOOT_2) $(TARGET_DTBO_NOT_SUPPORTED) $(ENABLE_DISPLAY) $(ENABLE_KASLRSEED) $(ENABLE_BOOTDEVICE_MOUNT) $(DEVICE_STATUS) $(BUILD_VARIANT) $(BOARD_NAME) $(ENABLE_VB_ATTEST) $(OSVERSION_IN_BOOTIMAGE) $(ENABLE_BG_SUPPORT) $(QSEECOM_SECAPP_REGION_2MB) $(TARGET_USE_SYSTEM_AS_ROOT_IMAGE)
    +	$(MAKE) -C $(LK_PATH) TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=$(CROOT_DIR)/$(EMMC_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) EMMC_BOOT=1 $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(VERIFIED_BOOT_2) $(VB1_KEY_USED) $(TARGET_DTBO_NOT_SUPPORTED) $(ENABLE_DISPLAY) $(ENABLE_KASLRSEED) $(ENABLE_BOOTDEVICE_MOUNT) $(DEVICE_STATUS) $(BUILD_VARIANT) $(BOARD_NAME) $(ENABLE_VB_ATTEST) $(OSVERSION_IN_BOOTIMAGE) $(ENABLE_BG_SUPPORT) $(QSEECOM_SECAPP_REGION_2MB) $(TARGET_USE_SYSTEM_AS_ROOT_IMAGE)
     
     # Keep build NAND & eMMC as default for targets still using TARGET_BOOTLOADER
     TARGET_BOOTLOADER := $(PRODUCT_OUT)/EMMCBOOT.MBN
    diff --git a/makefile b/makefile
    index f6da064..18449e0 100644
    --- a/makefile
    +++ b/makefile
    @@ -122,6 +122,11 @@ ifeq ($(VERIFIED_BOOT_LE),1)
         DEFINES += DEFAULT_UNLOCK=1
       endif
     endif
    +
    +ifeq ($(VB1_KEY_USED),1)
    +  DEFINES += VB1_KEY_USED=1
    +endif
    +
     ifeq ($(VERIFIED_BOOT_2),1)
       DEFINES += VERIFIED_BOOT_2=1
       DEFINES += _SIGNED_KERNEL=1
    diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
    index 36e1980..cee0197 100644
    --- a/platform/msm_shared/boot_verifier.c
    +++ b/platform/msm_shared/boot_verifier.c
    @@ -450,7 +450,7 @@ static void boot_verify_send_boot_state(km_boot_state_t *boot_state)
     }
     #endif
     
    -#if VERIFIED_BOOT_2
    +#if VERIFIED_BOOT_2 && !VB1_KEY_USED
     bool send_rot_command(uint32_t is_unlocked)
     {
     	int ret = 0;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    引入的GMS新问题

    实际修改之后OTA升级的确没有问题,但对于要将GMS进行到底的项目,随之而来的是VTS和CTS google key相关的fail项

    CtsDevicePolicyManagerTestCases和VtsHalKeymasterV4_0TargetTest与keymaster相关项会失败

    ODM供应商说,这两个测试失败引入的原因主要是MP侧devcfg中针对bootloader和keymaster进行ROT通信的配置需要适配,

    如果是全新的launch android 11的项目肯定不需要考虑这点,但是升级项目得修改配置,具体的需要在MP侧找到对应代码分析

    继续更新ing…

  • 相关阅读:
    编排微服务交响曲:Eureka在分布式容器编排中的妙用
    有什么好用的站内搜索SaaS能帮网站实现站内搜索功能?
    SaaSBase:什么是石墨文档?
    linux安装mysql无论如何修改权限和所属用户都出现Permission denied
    Mac环境安装任意版本的node
    C++ set / multiset容器
    Jmeter 分布式压测
    CentOS 7 下 SVN + Apache 对接 LDAP 服务
    oracle安装,导出、导入domp文件、解开oracle行级锁
    flutter系列之:使用SliverList和SliverGird
  • 原文地址:https://blog.csdn.net/jeephao/article/details/128200232