// 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;
}
Exemple #2
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);
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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);
}