1 /* 2 * (C) Copyright 2018, Linaro Limited 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <avb_verify.h> 8 #include <blk.h> 9 #include <fastboot.h> 10 #include <image.h> 11 #include <malloc.h> 12 #include <part.h> 13 #include <tee.h> 14 #include <tee/optee_ta_avb.h> 15 16 static const unsigned char avb_root_pub[1032] = { 17 0x0, 0x0, 0x10, 0x0, 0x55, 0xd9, 0x4, 0xad, 0xd8, 0x4, 18 0xaf, 0xe3, 0xd3, 0x84, 0x6c, 0x7e, 0xd, 0x89, 0x3d, 0xc2, 19 0x8c, 0xd3, 0x12, 0x55, 0xe9, 0x62, 0xc9, 0xf1, 0xf, 0x5e, 20 0xcc, 0x16, 0x72, 0xab, 0x44, 0x7c, 0x2c, 0x65, 0x4a, 0x94, 21 0xb5, 0x16, 0x2b, 0x0, 0xbb, 0x6, 0xef, 0x13, 0x7, 0x53, 22 0x4c, 0xf9, 0x64, 0xb9, 0x28, 0x7a, 0x1b, 0x84, 0x98, 0x88, 23 0xd8, 0x67, 0xa4, 0x23, 0xf9, 0xa7, 0x4b, 0xdc, 0x4a, 0xf, 24 0xf7, 0x3a, 0x18, 0xae, 0x54, 0xa8, 0x15, 0xfe, 0xb0, 0xad, 25 0xac, 0x35, 0xda, 0x3b, 0xad, 0x27, 0xbc, 0xaf, 0xe8, 0xd3, 26 0x2f, 0x37, 0x34, 0xd6, 0x51, 0x2b, 0x6c, 0x5a, 0x27, 0xd7, 27 0x96, 0x6, 0xaf, 0x6b, 0xb8, 0x80, 0xca, 0xfa, 0x30, 0xb4, 28 0xb1, 0x85, 0xb3, 0x4d, 0xaa, 0xaa, 0xc3, 0x16, 0x34, 0x1a, 29 0xb8, 0xe7, 0xc7, 0xfa, 0xf9, 0x9, 0x77, 0xab, 0x97, 0x93, 30 0xeb, 0x44, 0xae, 0xcf, 0x20, 0xbc, 0xf0, 0x80, 0x11, 0xdb, 31 0x23, 0xc, 0x47, 0x71, 0xb9, 0x6d, 0xd6, 0x7b, 0x60, 0x47, 32 0x87, 0x16, 0x56, 0x93, 0xb7, 0xc2, 0x2a, 0x9a, 0xb0, 0x4c, 33 0x1, 0xc, 0x30, 0xd8, 0x93, 0x87, 0xf0, 0xed, 0x6e, 0x8b, 34 0xbe, 0x30, 0x5b, 0xf6, 0xa6, 0xaf, 0xdd, 0x80, 0x7c, 0x45, 35 0x5e, 0x8f, 0x91, 0x93, 0x5e, 0x44, 0xfe, 0xb8, 0x82, 0x7, 36 0xee, 0x79, 0xca, 0xbf, 0x31, 0x73, 0x62, 0x58, 0xe3, 0xcd, 37 0xc4, 0xbc, 0xc2, 0x11, 0x1d, 0xa1, 0x4a, 0xbf, 0xfe, 0x27, 38 0x7d, 0xa1, 0xf6, 0x35, 0xa3, 0x5e, 0xca, 0xdc, 0x57, 0x2f, 39 0x3e, 0xf0, 0xc9, 0x5d, 0x86, 0x6a, 0xf8, 0xaf, 0x66, 0xa7, 40 0xed, 0xcd, 0xb8, 0xed, 0xa1, 0x5f, 0xba, 0x9b, 0x85, 0x1a, 41 0xd5, 0x9, 0xae, 0x94, 0x4e, 0x3b, 0xcf, 0xcb, 0x5c, 0xc9, 42 0x79, 0x80, 0xf7, 0xcc, 0xa6, 0x4a, 0xa8, 0x6a, 0xd8, 0xd3, 43 0x31, 0x11, 0xf9, 0xf6, 0x2, 0x63, 0x2a, 0x1a, 0x2d, 0xd1, 44 0x1a, 0x66, 0x1b, 0x16, 0x41, 0xbd, 0xbd, 0xf7, 0x4d, 0xc0, 45 0x4a, 0xe5, 0x27, 0x49, 0x5f, 0x7f, 0x58, 0xe3, 0x27, 0x2d, 46 0xe5, 0xc9, 0x66, 0xe, 0x52, 0x38, 0x16, 0x38, 0xfb, 0x16, 47 0xeb, 0x53, 0x3f, 0xe6, 0xfd, 0xe9, 0xa2, 0x5e, 0x25, 0x59, 48 0xd8, 0x79, 0x45, 0xff, 0x3, 0x4c, 0x26, 0xa2, 0x0, 0x5a, 49 0x8e, 0xc2, 0x51, 0xa1, 0x15, 0xf9, 0x7b, 0xf4, 0x5c, 0x81, 50 0x9b, 0x18, 0x47, 0x35, 0xd8, 0x2d, 0x5, 0xe9, 0xad, 0xf, 51 0x35, 0x74, 0x15, 0xa3, 0x8e, 0x8b, 0xcc, 0x27, 0xda, 0x7c, 52 0x5d, 0xe4, 0xfa, 0x4, 0xd3, 0x5, 0xb, 0xba, 0x3a, 0xb2, 53 0x49, 0x45, 0x2f, 0x47, 0xc7, 0xd, 0x41, 0x3f, 0x97, 0x80, 54 0x4d, 0x3f, 0xc1, 0xb5, 0xbb, 0x70, 0x5f, 0xa7, 0x37, 0xaf, 55 0x48, 0x22, 0x12, 0x45, 0x2e, 0xf5, 0xf, 0x87, 0x92, 0xe2, 56 0x84, 0x1, 0xf9, 0x12, 0xf, 0x14, 0x15, 0x24, 0xce, 0x89, 57 0x99, 0xee, 0xb9, 0xc4, 0x17, 0x70, 0x70, 0x15, 0xea, 0xbe, 58 0xc6, 0x6c, 0x1f, 0x62, 0xb3, 0xf4, 0x2d, 0x16, 0x87, 0xfb, 59 0x56, 0x1e, 0x45, 0xab, 0xae, 0x32, 0xe4, 0x5e, 0x91, 0xed, 60 0x53, 0x66, 0x5e, 0xbd, 0xed, 0xad, 0xe6, 0x12, 0x39, 0xd, 61 0x83, 0xc9, 0xe8, 0x6b, 0x6c, 0x2d, 0xa5, 0xee, 0xc4, 0x5a, 62 0x66, 0xae, 0x8c, 0x97, 0xd7, 0xd, 0x6c, 0x49, 0xc7, 0xf5, 63 0xc4, 0x92, 0x31, 0x8b, 0x9, 0xee, 0x33, 0xda, 0xa9, 0x37, 64 0xb6, 0x49, 0x18, 0xf8, 0xe, 0x60, 0x45, 0xc8, 0x33, 0x91, 65 0xef, 0x20, 0x57, 0x10, 0xbe, 0x78, 0x2d, 0x83, 0x26, 0xd6, 66 0xca, 0x61, 0xf9, 0x2f, 0xe0, 0xbf, 0x5, 0x30, 0x52, 0x5a, 67 0x12, 0x1c, 0x0, 0xa7, 0x5d, 0xcc, 0x7c, 0x2e, 0xc5, 0x95, 68 0x8b, 0xa3, 0x3b, 0xf0, 0x43, 0x2e, 0x5e, 0xdd, 0x0, 0xdb, 69 0xd, 0xb3, 0x37, 0x99, 0xa9, 0xcd, 0x9c, 0xb7, 0x43, 0xf7, 70 0x35, 0x44, 0x21, 0xc2, 0x82, 0x71, 0xab, 0x8d, 0xaa, 0xb4, 71 0x41, 0x11, 0xec, 0x1e, 0x8d, 0xfc, 0x14, 0x82, 0x92, 0x4e, 72 0x83, 0x6a, 0xa, 0x6b, 0x35, 0x5e, 0x5d, 0xe9, 0x5c, 0xcc, 73 0x8c, 0xde, 0x39, 0xd1, 0x4a, 0x5b, 0x5f, 0x63, 0xa9, 0x64, 74 0xe0, 0xa, 0xcb, 0xb, 0xb8, 0x5a, 0x7c, 0xc3, 0xb, 0xe6, 75 0xbe, 0xfe, 0x8b, 0xf, 0x7d, 0x34, 0x8e, 0x2, 0x66, 0x74, 76 0x1, 0x6c, 0xca, 0x76, 0xac, 0x7c, 0x67, 0x8, 0x2f, 0x3f, 77 0x1a, 0xa6, 0x2c, 0x60, 0xb3, 0xff, 0xda, 0x8d, 0xb8, 0x12, 78 0xc, 0x0, 0x7f, 0xcc, 0x50, 0xa1, 0x5c, 0x64, 0xa1, 0xe2, 79 0x5f, 0x32, 0x65, 0xc9, 0x9c, 0xbe, 0xd6, 0xa, 0x13, 0x87, 80 0x3c, 0x2a, 0x45, 0x47, 0xc, 0xca, 0x42, 0x82, 0xfa, 0x89, 81 0x65, 0xe7, 0x89, 0xb4, 0x8f, 0xf7, 0x1e, 0xe6, 0x23, 0xa5, 82 0xd0, 0x59, 0x37, 0x79, 0x92, 0xd7, 0xce, 0x3d, 0xfd, 0xe3, 83 0xa1, 0xb, 0xcf, 0x6c, 0x85, 0xa0, 0x65, 0xf3, 0x5c, 0xc6, 84 0x4a, 0x63, 0x5f, 0x6e, 0x3a, 0x3a, 0x2a, 0x8b, 0x6a, 0xb6, 85 0x2f, 0xbb, 0xf8, 0xb2, 0x4b, 0x62, 0xbc, 0x1a, 0x91, 0x25, 86 0x66, 0xe3, 0x69, 0xca, 0x60, 0x49, 0xb, 0xf6, 0x8a, 0xbe, 87 0x3e, 0x76, 0x53, 0xc2, 0x7a, 0xa8, 0x4, 0x17, 0x75, 0xf1, 88 0xf3, 0x3, 0x62, 0x1b, 0x85, 0xb2, 0xb0, 0xef, 0x80, 0x15, 89 0xb6, 0xd4, 0x4e, 0xdf, 0x71, 0xac, 0xdb, 0x2a, 0x4, 0xd4, 90 0xb4, 0x21, 0xba, 0x65, 0x56, 0x57, 0xe8, 0xfa, 0x84, 0xa2, 91 0x7d, 0x13, 0xe, 0xaf, 0xd7, 0x9a, 0x58, 0x2a, 0xa3, 0x81, 92 0x84, 0x8d, 0x9, 0xa0, 0x6a, 0xc1, 0xbb, 0xd9, 0xf5, 0x86, 93 0xac, 0xbd, 0x75, 0x61, 0x9, 0xe6, 0x8c, 0x3d, 0x77, 0xb2, 94 0xed, 0x30, 0x20, 0xe4, 0x0, 0x1d, 0x97, 0xe8, 0xbf, 0xc7, 95 0x0, 0x1b, 0x21, 0xb1, 0x16, 0xe7, 0x41, 0x67, 0x2e, 0xec, 96 0x38, 0xbc, 0xe5, 0x1b, 0xb4, 0x6, 0x23, 0x31, 0x71, 0x1c, 97 0x49, 0xcd, 0x76, 0x4a, 0x76, 0x36, 0x8d, 0xa3, 0x89, 0x8b, 98 0x4a, 0x7a, 0xf4, 0x87, 0xc8, 0x15, 0xf, 0x37, 0x39, 0xf6, 99 0x6d, 0x80, 0x19, 0xef, 0x5c, 0xa8, 0x66, 0xce, 0x1b, 0x16, 100 0x79, 0x21, 0xdf, 0xd7, 0x31, 0x30, 0xc4, 0x21, 0xdd, 0x34, 101 0x5b, 0xd2, 0x1a, 0x2b, 0x3e, 0x5d, 0xf7, 0xea, 0xca, 0x5, 102 0x8e, 0xb7, 0xcb, 0x49, 0x2e, 0xa0, 0xe3, 0xf4, 0xa7, 0x48, 103 0x19, 0x10, 0x9c, 0x4, 0xa7, 0xf4, 0x28, 0x74, 0xc8, 0x6f, 104 0x63, 0x20, 0x2b, 0x46, 0x24, 0x26, 0x19, 0x1d, 0xd1, 0x2c, 105 0x31, 0x6d, 0x5a, 0x29, 0xa2, 0x6, 0xa6, 0xb2, 0x41, 0xcc, 106 0xa, 0x27, 0x96, 0x9, 0x96, 0xac, 0x47, 0x65, 0x78, 0x68, 107 0x51, 0x98, 0xd6, 0xd8, 0xa6, 0x2d, 0xa0, 0xcf, 0xec, 0xe2, 108 0x74, 0xf2, 0x82, 0xe3, 0x97, 0xd9, 0x7e, 0xd4, 0xf8, 0xb, 109 0x70, 0x43, 0x3d, 0xb1, 0x7b, 0x97, 0x80, 0xd6, 0xcb, 0xd7, 110 0x19, 0xbc, 0x63, 0xb, 0xfd, 0x4d, 0x88, 0xfe, 0x67, 0xac, 111 0xb8, 0xcc, 0x50, 0xb7, 0x68, 0xb3, 0x5b, 0xd6, 0x1e, 0x25, 112 0xfc, 0x5f, 0x3c, 0x8d, 0xb1, 0x33, 0x7c, 0xb3, 0x49, 0x1, 113 0x3f, 0x71, 0x55, 0xe, 0x51, 0xba, 0x61, 0x26, 0xfa, 0xea, 114 0xe5, 0xb5, 0xe8, 0xaa, 0xcf, 0xcd, 0x96, 0x9f, 0xd6, 0xc1, 115 0x5f, 0x53, 0x91, 0xad, 0x5, 0xde, 0x20, 0xe7, 0x51, 0xda, 116 0x5b, 0x95, 0x67, 0xed, 0xf4, 0xee, 0x42, 0x65, 0x70, 0x13, 117 0xb, 0x70, 0x14, 0x1c, 0xc9, 0xe0, 0x19, 0xca, 0x5f, 0xf5, 118 0x1d, 0x70, 0x4b, 0x6c, 0x6, 0x74, 0xec, 0xb5, 0x2e, 0x77, 119 0xe1, 0x74, 0xa1, 0xa3, 0x99, 0xa0, 0x85, 0x9e, 0xf1, 0xac, 120 0xd8, 0x7e, 121 }; 122 123 /** 124 * ============================================================================ 125 * Boot states support (GREEN, YELLOW, ORANGE, RED) and dm_verity 126 * ============================================================================ 127 */ 128 char *avb_set_state(AvbOps *ops, enum avb_boot_state boot_state) 129 { 130 struct AvbOpsData *data; 131 char *cmdline = NULL; 132 133 if (!ops) 134 return NULL; 135 136 data = (struct AvbOpsData *)ops->user_data; 137 if (!data) 138 return NULL; 139 140 data->boot_state = boot_state; 141 switch (boot_state) { 142 case AVB_GREEN: 143 cmdline = "androidboot.verifiedbootstate=green"; 144 break; 145 case AVB_YELLOW: 146 cmdline = "androidboot.verifiedbootstate=yellow"; 147 break; 148 case AVB_ORANGE: 149 cmdline = "androidboot.verifiedbootstate=orange"; 150 case AVB_RED: 151 break; 152 } 153 154 return cmdline; 155 } 156 157 char *append_cmd_line(char *cmdline_orig, char *cmdline_new) 158 { 159 char *cmd_line; 160 161 if (!cmdline_new) 162 return cmdline_orig; 163 164 if (cmdline_orig) 165 cmd_line = cmdline_orig; 166 else 167 cmd_line = " "; 168 169 cmd_line = avb_strdupv(cmd_line, " ", cmdline_new, NULL); 170 171 return cmd_line; 172 } 173 174 static int avb_find_dm_args(char **args, char *str) 175 { 176 int i; 177 178 if (!str) 179 return -1; 180 181 for (i = 0; i < AVB_MAX_ARGS && args[i]; ++i) { 182 if (strstr(args[i], str)) 183 return i; 184 } 185 186 return -1; 187 } 188 189 static char *avb_set_enforce_option(const char *cmdline, const char *option) 190 { 191 char *cmdarg[AVB_MAX_ARGS]; 192 char *newargs = NULL; 193 int i = 0; 194 int total_args; 195 196 memset(cmdarg, 0, sizeof(cmdarg)); 197 cmdarg[i++] = strtok((char *)cmdline, " "); 198 199 do { 200 cmdarg[i] = strtok(NULL, " "); 201 if (!cmdarg[i]) 202 break; 203 204 if (++i >= AVB_MAX_ARGS) { 205 printf("%s: Can't handle more then %d args\n", 206 __func__, i); 207 return NULL; 208 } 209 } while (true); 210 211 total_args = i; 212 i = avb_find_dm_args(&cmdarg[0], VERITY_TABLE_OPT_LOGGING); 213 if (i >= 0) { 214 cmdarg[i] = (char *)option; 215 } else { 216 i = avb_find_dm_args(&cmdarg[0], VERITY_TABLE_OPT_RESTART); 217 if (i < 0) { 218 printf("%s: No verity options found\n", __func__); 219 return NULL; 220 } 221 222 cmdarg[i] = (char *)option; 223 } 224 225 for (i = 0; i <= total_args; i++) 226 newargs = append_cmd_line(newargs, cmdarg[i]); 227 228 return newargs; 229 } 230 231 char *avb_set_ignore_corruption(const char *cmdline) 232 { 233 char *newargs = NULL; 234 235 newargs = avb_set_enforce_option(cmdline, VERITY_TABLE_OPT_LOGGING); 236 if (newargs) 237 newargs = append_cmd_line(newargs, 238 "androidboot.veritymode=eio"); 239 240 return newargs; 241 } 242 243 char *avb_set_enforce_verity(const char *cmdline) 244 { 245 char *newargs; 246 247 newargs = avb_set_enforce_option(cmdline, VERITY_TABLE_OPT_RESTART); 248 if (newargs) 249 newargs = append_cmd_line(newargs, 250 "androidboot.veritymode=enforcing"); 251 return newargs; 252 } 253 254 /** 255 * ============================================================================ 256 * IO(mmc) auxiliary functions 257 * ============================================================================ 258 */ 259 static unsigned long mmc_read_and_flush(struct mmc_part *part, 260 lbaint_t start, 261 lbaint_t sectors, 262 void *buffer) 263 { 264 unsigned long blks; 265 void *tmp_buf; 266 size_t buf_size; 267 bool unaligned = is_buf_unaligned(buffer); 268 269 if (start < part->info.start) { 270 printf("%s: partition start out of bounds\n", __func__); 271 return 0; 272 } 273 if ((start + sectors) > (part->info.start + part->info.size)) { 274 sectors = part->info.start + part->info.size - start; 275 printf("%s: read sector aligned to partition bounds (%ld)\n", 276 __func__, sectors); 277 } 278 279 /* 280 * Reading fails on unaligned buffers, so we have to 281 * use aligned temporary buffer and then copy to destination 282 */ 283 284 if (unaligned) { 285 printf("Handling unaligned read buffer..\n"); 286 tmp_buf = get_sector_buf(); 287 buf_size = get_sector_buf_size(); 288 if (sectors > buf_size / part->info.blksz) 289 sectors = buf_size / part->info.blksz; 290 } else { 291 tmp_buf = buffer; 292 } 293 294 blks = blk_dread(part->mmc_blk, 295 start, sectors, tmp_buf); 296 /* flush cache after read */ 297 flush_cache((ulong)tmp_buf, sectors * part->info.blksz); 298 299 if (unaligned) 300 memcpy(buffer, tmp_buf, sectors * part->info.blksz); 301 302 return blks; 303 } 304 305 static unsigned long mmc_write(struct mmc_part *part, lbaint_t start, 306 lbaint_t sectors, void *buffer) 307 { 308 void *tmp_buf; 309 size_t buf_size; 310 bool unaligned = is_buf_unaligned(buffer); 311 312 if (start < part->info.start) { 313 printf("%s: partition start out of bounds\n", __func__); 314 return 0; 315 } 316 if ((start + sectors) > (part->info.start + part->info.size)) { 317 sectors = part->info.start + part->info.size - start; 318 printf("%s: sector aligned to partition bounds (%ld)\n", 319 __func__, sectors); 320 } 321 if (unaligned) { 322 tmp_buf = get_sector_buf(); 323 buf_size = get_sector_buf_size(); 324 printf("Handling unaligned wrire buffer..\n"); 325 if (sectors > buf_size / part->info.blksz) 326 sectors = buf_size / part->info.blksz; 327 328 memcpy(tmp_buf, buffer, sectors * part->info.blksz); 329 } else { 330 tmp_buf = buffer; 331 } 332 333 return blk_dwrite(part->mmc_blk, 334 start, sectors, tmp_buf); 335 } 336 337 static struct mmc_part *get_partition(AvbOps *ops, const char *partition) 338 { 339 int ret; 340 u8 dev_num; 341 int part_num = 0; 342 struct mmc_part *part; 343 struct blk_desc *mmc_blk; 344 345 part = malloc(sizeof(struct mmc_part)); 346 if (!part) 347 return NULL; 348 349 dev_num = get_boot_device(ops); 350 part->mmc = find_mmc_device(dev_num); 351 if (!part->mmc) { 352 printf("No MMC device at slot %x\n", dev_num); 353 goto err; 354 } 355 356 if (mmc_init(part->mmc)) { 357 printf("MMC initialization failed\n"); 358 goto err; 359 } 360 361 ret = mmc_switch_part(part->mmc, part_num); 362 if (ret) 363 goto err; 364 365 mmc_blk = mmc_get_blk_desc(part->mmc); 366 if (!mmc_blk) { 367 printf("Error - failed to obtain block descriptor\n"); 368 goto err; 369 } 370 371 ret = part_get_info_by_name(mmc_blk, partition, &part->info); 372 if (!ret) { 373 printf("Can't find partition '%s'\n", partition); 374 goto err; 375 } 376 377 part->dev_num = dev_num; 378 part->mmc_blk = mmc_blk; 379 380 return part; 381 err: 382 free(part); 383 return NULL; 384 } 385 386 static AvbIOResult mmc_byte_io(AvbOps *ops, 387 const char *partition, 388 s64 offset, 389 size_t num_bytes, 390 void *buffer, 391 size_t *out_num_read, 392 enum mmc_io_type io_type) 393 { 394 ulong ret; 395 struct mmc_part *part; 396 u64 start_offset, start_sector, sectors, residue; 397 u8 *tmp_buf; 398 size_t io_cnt = 0; 399 400 if (!partition || !buffer || io_type > IO_WRITE) 401 return AVB_IO_RESULT_ERROR_IO; 402 403 part = get_partition(ops, partition); 404 if (!part) 405 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 406 407 if (!part->info.blksz) 408 return AVB_IO_RESULT_ERROR_IO; 409 410 start_offset = calc_offset(part, offset); 411 while (num_bytes) { 412 start_sector = start_offset / part->info.blksz; 413 sectors = num_bytes / part->info.blksz; 414 /* handle non block-aligned reads */ 415 if (start_offset % part->info.blksz || 416 num_bytes < part->info.blksz) { 417 tmp_buf = get_sector_buf(); 418 if (start_offset % part->info.blksz) { 419 residue = part->info.blksz - 420 (start_offset % part->info.blksz); 421 if (residue > num_bytes) 422 residue = num_bytes; 423 } else { 424 residue = num_bytes; 425 } 426 427 if (io_type == IO_READ) { 428 ret = mmc_read_and_flush(part, 429 part->info.start + 430 start_sector, 431 1, tmp_buf); 432 433 if (ret != 1) { 434 printf("%s: read error (%ld, %lld)\n", 435 __func__, ret, start_sector); 436 return AVB_IO_RESULT_ERROR_IO; 437 } 438 /* 439 * if this is not aligned at sector start, 440 * we have to adjust the tmp buffer 441 */ 442 tmp_buf += (start_offset % part->info.blksz); 443 memcpy(buffer, (void *)tmp_buf, residue); 444 } else { 445 ret = mmc_read_and_flush(part, 446 part->info.start + 447 start_sector, 448 1, tmp_buf); 449 450 if (ret != 1) { 451 printf("%s: read error (%ld, %lld)\n", 452 __func__, ret, start_sector); 453 return AVB_IO_RESULT_ERROR_IO; 454 } 455 memcpy((void *)tmp_buf + 456 start_offset % part->info.blksz, 457 buffer, residue); 458 459 ret = mmc_write(part, part->info.start + 460 start_sector, 1, tmp_buf); 461 if (ret != 1) { 462 printf("%s: write error (%ld, %lld)\n", 463 __func__, ret, start_sector); 464 return AVB_IO_RESULT_ERROR_IO; 465 } 466 } 467 468 io_cnt += residue; 469 buffer += residue; 470 start_offset += residue; 471 num_bytes -= residue; 472 continue; 473 } 474 475 if (sectors) { 476 if (io_type == IO_READ) { 477 ret = mmc_read_and_flush(part, 478 part->info.start + 479 start_sector, 480 sectors, buffer); 481 } else { 482 ret = mmc_write(part, 483 part->info.start + 484 start_sector, 485 sectors, buffer); 486 } 487 488 if (!ret) { 489 printf("%s: sector read error\n", __func__); 490 return AVB_IO_RESULT_ERROR_IO; 491 } 492 493 io_cnt += ret * part->info.blksz; 494 buffer += ret * part->info.blksz; 495 start_offset += ret * part->info.blksz; 496 num_bytes -= ret * part->info.blksz; 497 } 498 } 499 500 /* Set counter for read operation */ 501 if (io_type == IO_READ && out_num_read) 502 *out_num_read = io_cnt; 503 504 return AVB_IO_RESULT_OK; 505 } 506 507 /** 508 * ============================================================================ 509 * AVB 2.0 operations 510 * ============================================================================ 511 */ 512 513 /** 514 * read_from_partition() - reads @num_bytes from @offset from partition 515 * identified by a string name 516 * 517 * @ops: contains AVB ops handlers 518 * @partition_name: partition name, NUL-terminated UTF-8 string 519 * @offset: offset from the beginning of partition 520 * @num_bytes: amount of bytes to read 521 * @buffer: destination buffer to store data 522 * @out_num_read: 523 * 524 * @return: 525 * AVB_IO_RESULT_OK, if partition was found and read operation succeed 526 * AVB_IO_RESULT_ERROR_IO, if i/o error occurred from the underlying i/o 527 * subsystem 528 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if there is no partition with 529 * the given name 530 */ 531 static AvbIOResult read_from_partition(AvbOps *ops, 532 const char *partition_name, 533 s64 offset_from_partition, 534 size_t num_bytes, 535 void *buffer, 536 size_t *out_num_read) 537 { 538 return mmc_byte_io(ops, partition_name, offset_from_partition, 539 num_bytes, buffer, out_num_read, IO_READ); 540 } 541 542 /** 543 * write_to_partition() - writes N bytes to a partition identified by a string 544 * name 545 * 546 * @ops: AvbOps, contains AVB ops handlers 547 * @partition_name: partition name 548 * @offset_from_partition: offset from the beginning of partition 549 * @num_bytes: amount of bytes to write 550 * @buf: data to write 551 * @out_num_read: 552 * 553 * @return: 554 * AVB_IO_RESULT_OK, if partition was found and read operation succeed 555 * AVB_IO_RESULT_ERROR_IO, if input/output error occurred 556 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition, specified in 557 * @partition_name was not found 558 */ 559 static AvbIOResult write_to_partition(AvbOps *ops, 560 const char *partition_name, 561 s64 offset_from_partition, 562 size_t num_bytes, 563 const void *buffer) 564 { 565 return mmc_byte_io(ops, partition_name, offset_from_partition, 566 num_bytes, (void *)buffer, NULL, IO_WRITE); 567 } 568 569 /** 570 * validate_vmbeta_public_key() - checks if the given public key used to sign 571 * the vbmeta partition is trusted 572 * 573 * @ops: AvbOps, contains AVB ops handlers 574 * @public_key_data: public key for verifying vbmeta partition signature 575 * @public_key_length: length of public key 576 * @public_key_metadata: 577 * @public_key_metadata_length: 578 * @out_key_is_trusted: 579 * 580 * @return: 581 * AVB_IO_RESULT_OK, if partition was found and read operation succeed 582 */ 583 static AvbIOResult validate_vbmeta_public_key(AvbOps *ops, 584 const u8 *public_key_data, 585 size_t public_key_length, 586 const u8 587 *public_key_metadata, 588 size_t 589 public_key_metadata_length, 590 bool *out_key_is_trusted) 591 { 592 if (!public_key_length || !public_key_data || !out_key_is_trusted) 593 return AVB_IO_RESULT_ERROR_IO; 594 595 *out_key_is_trusted = false; 596 if (public_key_length != sizeof(avb_root_pub)) 597 return AVB_IO_RESULT_ERROR_IO; 598 599 if (memcmp(avb_root_pub, public_key_data, public_key_length) == 0) 600 *out_key_is_trusted = true; 601 602 return AVB_IO_RESULT_OK; 603 } 604 605 #ifdef CONFIG_OPTEE_TA_AVB 606 static int get_open_session(struct AvbOpsData *ops_data) 607 { 608 struct udevice *tee = NULL; 609 610 while (!ops_data->tee) { 611 const struct tee_optee_ta_uuid uuid = TA_AVB_UUID; 612 struct tee_open_session_arg arg; 613 int rc; 614 615 tee = tee_find_device(tee, NULL, NULL, NULL); 616 if (!tee) 617 return -ENODEV; 618 619 memset(&arg, 0, sizeof(arg)); 620 tee_optee_ta_uuid_to_octets(arg.uuid, &uuid); 621 rc = tee_open_session(tee, &arg, 0, NULL); 622 if (!rc) { 623 ops_data->tee = tee; 624 ops_data->session = arg.session; 625 } 626 } 627 628 return 0; 629 } 630 631 static AvbIOResult invoke_func(struct AvbOpsData *ops_data, u32 func, 632 ulong num_param, struct tee_param *param) 633 { 634 struct tee_invoke_arg arg; 635 636 if (get_open_session(ops_data)) 637 return AVB_IO_RESULT_ERROR_IO; 638 639 memset(&arg, 0, sizeof(arg)); 640 arg.func = func; 641 arg.session = ops_data->session; 642 643 if (tee_invoke_func(ops_data->tee, &arg, num_param, param)) 644 return AVB_IO_RESULT_ERROR_IO; 645 switch (arg.ret) { 646 case TEE_SUCCESS: 647 return AVB_IO_RESULT_OK; 648 case TEE_ERROR_OUT_OF_MEMORY: 649 return AVB_IO_RESULT_ERROR_OOM; 650 case TEE_ERROR_TARGET_DEAD: 651 /* 652 * The TA has paniced, close the session to reload the TA 653 * for the next request. 654 */ 655 tee_close_session(ops_data->tee, ops_data->session); 656 ops_data->tee = NULL; 657 return AVB_IO_RESULT_ERROR_IO; 658 default: 659 return AVB_IO_RESULT_ERROR_IO; 660 } 661 } 662 #endif 663 664 /** 665 * read_rollback_index() - gets the rollback index corresponding to the 666 * location of given by @out_rollback_index. 667 * 668 * @ops: contains AvbOps handlers 669 * @rollback_index_slot: 670 * @out_rollback_index: used to write a retrieved rollback index. 671 * 672 * @return 673 * AVB_IO_RESULT_OK, if the roolback index was retrieved 674 */ 675 static AvbIOResult read_rollback_index(AvbOps *ops, 676 size_t rollback_index_slot, 677 u64 *out_rollback_index) 678 { 679 #ifndef CONFIG_OPTEE_TA_AVB 680 /* For now we always return 0 as the stored rollback index. */ 681 printf("%s not supported yet\n", __func__); 682 683 if (out_rollback_index) 684 *out_rollback_index = 0; 685 686 return AVB_IO_RESULT_OK; 687 #else 688 AvbIOResult rc; 689 struct tee_param param[2]; 690 691 if (rollback_index_slot >= TA_AVB_MAX_ROLLBACK_LOCATIONS) 692 return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; 693 694 memset(param, 0, sizeof(param)); 695 param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; 696 param[0].u.value.a = rollback_index_slot; 697 param[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT; 698 699 rc = invoke_func(ops->user_data, TA_AVB_CMD_READ_ROLLBACK_INDEX, 700 ARRAY_SIZE(param), param); 701 if (rc) 702 return rc; 703 704 *out_rollback_index = (u64)param[1].u.value.a << 32 | 705 (u32)param[1].u.value.b; 706 return AVB_IO_RESULT_OK; 707 #endif 708 } 709 710 /** 711 * write_rollback_index() - sets the rollback index corresponding to the 712 * location of given by @out_rollback_index. 713 * 714 * @ops: contains AvbOps handlers 715 * @rollback_index_slot: 716 * @rollback_index: rollback index to write. 717 * 718 * @return 719 * AVB_IO_RESULT_OK, if the roolback index was retrieved 720 */ 721 static AvbIOResult write_rollback_index(AvbOps *ops, 722 size_t rollback_index_slot, 723 u64 rollback_index) 724 { 725 #ifndef CONFIG_OPTEE_TA_AVB 726 /* For now this is a no-op. */ 727 printf("%s not supported yet\n", __func__); 728 729 return AVB_IO_RESULT_OK; 730 #else 731 struct tee_param param[2]; 732 733 if (rollback_index_slot >= TA_AVB_MAX_ROLLBACK_LOCATIONS) 734 return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; 735 736 memset(param, 0, sizeof(param)); 737 param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; 738 param[0].u.value.a = rollback_index_slot; 739 param[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; 740 param[1].u.value.a = (u32)(rollback_index >> 32); 741 param[1].u.value.b = (u32)rollback_index; 742 743 return invoke_func(ops->user_data, TA_AVB_CMD_WRITE_ROLLBACK_INDEX, 744 ARRAY_SIZE(param), param); 745 #endif 746 } 747 748 /** 749 * read_is_device_unlocked() - gets whether the device is unlocked 750 * 751 * @ops: contains AVB ops handlers 752 * @out_is_unlocked: device unlock state is stored here, true if unlocked, 753 * false otherwise 754 * 755 * @return: 756 * AVB_IO_RESULT_OK: state is retrieved successfully 757 * AVB_IO_RESULT_ERROR_IO: an error occurred 758 */ 759 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked) 760 { 761 #ifndef CONFIG_OPTEE_TA_AVB 762 /* For now we always return that the device is unlocked. */ 763 764 printf("%s not supported yet\n", __func__); 765 766 *out_is_unlocked = true; 767 768 return AVB_IO_RESULT_OK; 769 #else 770 AvbIOResult rc; 771 struct tee_param param = { .attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT }; 772 773 rc = invoke_func(ops->user_data, TA_AVB_CMD_READ_LOCK_STATE, 1, ¶m); 774 if (rc) 775 return rc; 776 *out_is_unlocked = !param.u.value.a; 777 return AVB_IO_RESULT_OK; 778 #endif 779 } 780 781 /** 782 * get_unique_guid_for_partition() - gets the GUID for a partition identified 783 * by a string name 784 * 785 * @ops: contains AVB ops handlers 786 * @partition: partition name (NUL-terminated UTF-8 string) 787 * @guid_buf: buf, used to copy in GUID string. Example of value: 788 * 527c1c6d-6361-4593-8842-3c78fcd39219 789 * @guid_buf_size: @guid_buf buffer size 790 * 791 * @return: 792 * AVB_IO_RESULT_OK, on success (GUID found) 793 * AVB_IO_RESULT_ERROR_IO, if incorrect buffer size (@guid_buf_size) was 794 * provided 795 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition was not found 796 */ 797 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops, 798 const char *partition, 799 char *guid_buf, 800 size_t guid_buf_size) 801 { 802 struct mmc_part *part; 803 size_t uuid_size; 804 805 part = get_partition(ops, partition); 806 if (!part) 807 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 808 809 uuid_size = sizeof(part->info.uuid); 810 if (uuid_size > guid_buf_size) 811 return AVB_IO_RESULT_ERROR_IO; 812 813 memcpy(guid_buf, part->info.uuid, uuid_size); 814 guid_buf[uuid_size - 1] = 0; 815 816 return AVB_IO_RESULT_OK; 817 } 818 819 /** 820 * get_size_of_partition() - gets the size of a partition identified 821 * by a string name 822 * 823 * @ops: contains AVB ops handlers 824 * @partition: partition name (NUL-terminated UTF-8 string) 825 * @out_size_num_bytes: returns the value of a partition size 826 * 827 * @return: 828 * AVB_IO_RESULT_OK, on success (GUID found) 829 * AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE, out_size_num_bytes is NULL 830 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition was not found 831 */ 832 static AvbIOResult get_size_of_partition(AvbOps *ops, 833 const char *partition, 834 u64 *out_size_num_bytes) 835 { 836 struct mmc_part *part; 837 838 if (!out_size_num_bytes) 839 return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE; 840 841 part = get_partition(ops, partition); 842 if (!part) 843 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 844 845 *out_size_num_bytes = part->info.blksz * part->info.size; 846 847 return AVB_IO_RESULT_OK; 848 } 849 850 /** 851 * ============================================================================ 852 * AVB2.0 AvbOps alloc/initialisation/free 853 * ============================================================================ 854 */ 855 AvbOps *avb_ops_alloc(int boot_device) 856 { 857 struct AvbOpsData *ops_data; 858 859 ops_data = avb_calloc(sizeof(struct AvbOpsData)); 860 if (!ops_data) 861 return NULL; 862 863 ops_data->ops.user_data = ops_data; 864 865 ops_data->ops.read_from_partition = read_from_partition; 866 ops_data->ops.write_to_partition = write_to_partition; 867 ops_data->ops.validate_vbmeta_public_key = validate_vbmeta_public_key; 868 ops_data->ops.read_rollback_index = read_rollback_index; 869 ops_data->ops.write_rollback_index = write_rollback_index; 870 ops_data->ops.read_is_device_unlocked = read_is_device_unlocked; 871 ops_data->ops.get_unique_guid_for_partition = 872 get_unique_guid_for_partition; 873 ops_data->ops.get_size_of_partition = get_size_of_partition; 874 ops_data->mmc_dev = boot_device; 875 876 return &ops_data->ops; 877 } 878 879 void avb_ops_free(AvbOps *ops) 880 { 881 struct AvbOpsData *ops_data; 882 883 if (!ops) 884 return; 885 886 ops_data = ops->user_data; 887 888 if (ops_data) { 889 #ifdef CONFIG_OPTEE_TA_AVB 890 if (ops_data->tee) 891 tee_close_session(ops_data->tee, ops_data->session); 892 #endif 893 avb_free(ops_data); 894 } 895 } 896