static void process_start(TPM_ALG_ID alg, int handle, void *response_body, size_t *response_size) { uint8_t *response = response_body; struct test_context *new_context; if (find_context(handle)) { *response = EXC_HASH_DUPLICATED_HANDLE; *response_size = 1; return; } if (!hash_test_db.max_contexts) { /* Check how many contexts could possible fit. */ hash_test_db.max_contexts = shared_mem_size() / sizeof(struct test_context); } if (!hash_test_db.contexts) shared_mem_acquire(shared_mem_size(), (char **)&hash_test_db.contexts); if (!hash_test_db.contexts || (hash_test_db.current_context_count == hash_test_db.max_contexts)) { *response = EXC_HASH_TOO_MANY_HANDLES; *response_size = 1; return; } new_context = hash_test_db.contexts + hash_test_db.current_context_count++; new_context->context_handle = handle; _cpri__StartHash(alg, 0, &new_context->hstate); }
static int read_and_hash_chunk(int offset, int size) { char *buf; int rv; if (size == 0) return EC_SUCCESS; rv = shared_mem_acquire(size, &buf); if (rv == EC_ERROR_BUSY) { /* Couldn't update hash right now; try again later */ hook_call_deferred(vboot_hash_next_chunk, WORK_INTERVAL_US); return rv; } else if (rv != EC_SUCCESS) { vboot_hash_abort(); return rv; } rv = flash_read(offset, size, buf); if (rv == EC_SUCCESS) SHA256_update(&ctx, (const uint8_t *)buf, size); else vboot_hash_abort(); shared_mem_release(buf); return rv; }
void check_rw_signature(void) { struct sha256_ctx ctx; int good, res; uint8_t *hash; uint32_t *rsa_workbuf; /* Only the Read-Only firmware needs to do the signature check */ if (system_get_image_copy() != SYSTEM_IMAGE_RO) return; /* Check if we have a RW firmware flashed */ if (*rw_rst == 0xffffffff) return; CPRINTS("Verifying RW image..."); /* Large buffer for RSA computation : could be re-use afterwards... */ res = shared_mem_acquire(3 * RSANUMBYTES, (char **)&rsa_workbuf); if (res) { CPRINTS("No memory for RW verification"); return; } /* SHA-256 Hash of the RW firmware */ /* TODO(crosbug.com/p/44803): Do we have to hash the whole region? */ SHA256_init(&ctx); SHA256_update(&ctx, (void *)CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_MEM_OFF, CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE); hash = SHA256_final(&ctx); good = rsa_verify((const struct rsa_public_key *)CONFIG_RO_PUBKEY_ADDR, (const uint8_t *)CONFIG_RW_SIG_ADDR, hash, rsa_workbuf); if (good) { CPRINTS("RW image verified"); /* Jump to the RW firmware */ system_run_image_copy(SYSTEM_IMAGE_RW); } else { CPRINTS("RSA verify FAILED"); pd_log_event(PD_EVENT_ACC_RW_FAIL, 0, 0, NULL); /* RW firmware is invalid : do not jump there */ if (system_is_locked()) system_disable_jump(); } shared_mem_release(rsa_workbuf); }
static int command_flash_write(int argc, char **argv) { int offset = -1; int size = CONFIG_FLASH_ERASE_SIZE; int rv; char *data; int i; if (flash_get_protect() & EC_FLASH_PROTECT_ALL_NOW) return EC_ERROR_ACCESS_DENIED; rv = parse_offset_size(argc, argv, 1, &offset, &size); if (rv) return rv; if (size > shared_mem_size()) size = shared_mem_size(); /* Acquire the shared memory buffer */ rv = shared_mem_acquire(size, &data); if (rv) { ccputs("Can't get shared mem\n"); return rv; } /* Fill the data buffer with a pattern */ for (i = 0; i < size; i++) data[i] = i; ccprintf("Writing %d bytes to 0x%x...\n", size, offset, offset); rv = flash_write(offset, size, data); /* Free the buffer */ shared_mem_release(data); return rv; }
static int command_host_command(int argc, char **argv) { struct host_cmd_handler_args args; char *cmd_params; enum ec_status res; char *e; int rv; /* Use shared memory for command params space */ if (shared_mem_acquire(EC_PROTO2_MAX_PARAM_SIZE, &cmd_params)) { ccputs("Can't acquire shared memory buffer.\n"); return EC_ERROR_UNKNOWN; } /* Assume no version or params unless proven otherwise */ args.version = 0; args.params_size = 0; args.params = cmd_params; if (argc < 2) { shared_mem_release(cmd_params); return EC_ERROR_PARAM_COUNT; } args.command = strtoi(argv[1], &e, 0); if (*e) { shared_mem_release(cmd_params); return EC_ERROR_PARAM1; } if (argc > 2) { args.version = strtoi(argv[2], &e, 0); if (*e) { shared_mem_release(cmd_params); return EC_ERROR_PARAM2; } } if (argc > 3) { rv = parse_params(argv[3], cmd_params); if (rv < 0) { shared_mem_release(cmd_params); return EC_ERROR_PARAM3; } args.params_size = rv; } args.response = cmd_params; args.response_max = EC_PROTO2_MAX_PARAM_SIZE; args.response_size = 0; res = host_command_process(&args); if (res != EC_RES_SUCCESS) ccprintf("Command returned %d\n", res); else if (args.response_size) ccprintf("Response: %.*h\n", args.response_size, cmd_params); else ccprintf("Command succeeded; no response.\n"); shared_mem_release(cmd_params); return EC_SUCCESS; }