// Fetch a block from the host into fd->curr_block and fd->block_data. // Returns 0 on successful fetch, negative otherwise. static int fetch_block(struct fuse_data* fd, uint32_t block) { if (block == fd->curr_block) { return 0; } if (block >= fd->file_blocks) { memset(fd->block_data, 0, fd->block_size); fd->curr_block = block; return 0; } if (block_cache_fetch(fd, block) == 0) { fd->curr_block = block; return 0; } size_t fetch_size = fd->block_size; if (block * fd->block_size + fetch_size > fd->file_size) { // If we're reading the last (partial) block of the file, // expect a shorter response from the host, and pad the rest // of the block with zeroes. fetch_size = fd->file_size - (block * fd->block_size); memset(fd->block_data + fetch_size, 0, fd->block_size - fetch_size); } int result = fd->vtab->read_block(fd->cookie, block, fd->block_data, fetch_size); if (result < 0) return result; fd->curr_block = block; // Verify the hash of the block we just got from the host. // // - If the hash of the just-received data matches the stored hash // for the block, accept it. // - If the stored hash is all zeroes, store the new hash and // accept the block (this is the first time we've read this // block). // - Otherwise, return -EINVAL for the read. uint8_t hash[SHA256_DIGEST_SIZE]; SHA256_hash(fd->block_data, fd->block_size, hash); uint8_t* blockhash = fd->hashes + block * SHA256_DIGEST_SIZE; if (memcmp(hash, blockhash, SHA256_DIGEST_SIZE) == 0) { return 0; } int i; for (i = 0; i < SHA256_DIGEST_SIZE; ++i) { if (blockhash[i] != 0) { fd->curr_block = -1; return -EIO; } } memcpy(blockhash, hash, SHA256_DIGEST_SIZE); block_cache_enter(fd, block); return 0; }
void bootimage_done(bootimage *img) { unsigned sz = img->next_offset; if (sz & 4095) { sz += (4096 - (sz & 4095)); } img->entry[1].info.image_size = sz; img->entry[1].info.entry_count = img->count; SHA256_hash((void*) &(img->entry[1]), 4096 - 64, img->entry[0].file.sha256); }
void hash_payload(mpz_t hashed, mpz_t payload) { int i; char payload_str[strlen(DHE_PRIME)]; //not going to be hashing anything larger char hex_hash[HEX_HASH_STR_LEN]; gmp_sprintf(payload_str, "%Zx", payload); memcpy(hex_hash, SHA256_hash(payload_str), HEX_HASH_STR_LEN); gmp_sscanf(hex_hash, "%Zx", hashed); }
const uint8_t *DCRYPTO_SHA256_hash(const void *data, uint32_t n, uint8_t *digest) { if (dcrypto_grab_sha_hw()) /* dcrypto_sha_wait() will release the hw. */ dcrypto_sha_hash(SHA256_MODE, data, n, digest); #ifndef SECTION_IS_RO else SHA256_hash(data, n, digest); #endif return digest; }
bootentry_file *bootimage_add_filedata(bootimage *img, unsigned type, void *data, unsigned len) { unsigned n = img->count; if (img->count == 64) return NULL; img->count++; // align to page boundary img->next_offset = (img->next_offset + 4095) & (~4095); img->entry[n].file.kind = KIND_FILE; img->entry[n].file.type = type; img->entry[n].file.offset = img->next_offset; img->entry[n].file.length = len; SHA256_hash(data, len, img->entry[n].file.sha256); img->data[n] = data; img->offset[n] = img->next_offset; img->length[n] = len; img->next_offset += len; return &(img->entry[n].file); }