예제 #1
0
/* Searches for a block in the hash table */
block_node *check_hash(uint32_t block)
{
	block_node *b;
	
	//pthread_mutex_lock(&hash_mutex);
	if (ht[hash_block(block)].active == 0){  /* This will be the common case...let's optimize here with likely() */
		return NULL;
	}

	b = check_list(ht[hash_block(block)].list, block);
	//pthread_mutex_unlock(&hash_mutex);
	
	return b;
}
예제 #2
0
static void setup_macaddr(void)
{
#if CONFIG_IS_ENABLED(CMD_NET)
	int ret;
	const char *cpuid = env_get("cpuid#");
	u8 hash[SHA256_SUM_LEN];
	int size = sizeof(hash);
	u8 mac_addr[6];

	/* Only generate a MAC address, if none is set in the environment */
	if (env_get("ethaddr"))
		return;

	if (!cpuid) {
		debug("%s: could not retrieve 'cpuid#'\n", __func__);
		return;
	}

	ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size);
	if (ret) {
		debug("%s: failed to calculate SHA256\n", __func__);
		return;
	}

	/* Copy 6 bytes of the hash to base the MAC address on */
	memcpy(mac_addr, hash, 6);

	/* Make this a valid MAC address and set it */
	mac_addr[0] &= 0xfe;  /* clear multicast bit */
	mac_addr[0] |= 0x02;  /* set local assignment bit (IEEE802) */
	eth_env_set_enetaddr("ethaddr", mac_addr);
#endif
}
예제 #3
0
static ssize_t
verify_signature_read_cb(struct archive *archive, void *cookie, const void **buf)
{
	struct signature_archive *state = cookie;
	char hash[SHA512_DIGEST_STRING_LENGTH];
	ssize_t len, expected;

	if (state->sign_cur_block >= state->sign_block_number)
		return 0;

	/* The following works for sign_block_len > 1 */
	if (state->sign_cur_block + 1 == state->sign_block_number)
		expected = state->pkg_size % state->sign_block_len;
	else
		expected = state->sign_block_len;

	len = archive_read_data(state->archive, state->sign_buf, expected);
	if (len != expected) {
		warnx("Short read from package");
		return -1;
	}

	hash_block(state->sign_buf, len, hash);

	if (strcmp(hash, state->sign_blocks[state->sign_cur_block]) != 0) {
		warnx("Invalid signature of block %llu",
		    (unsigned long long)state->sign_cur_block);
		return -1;
	}
	++state->sign_cur_block;
	*buf = state->sign_buf;
	return len;
}
예제 #4
0
/*
 * Computes 256 bit Key exchange key as specified in RFC 4357
 */
static int make_cp_exchange_key(BIGNUM *priv_key, EVP_PKEY *pubk,
                                unsigned char *shared_key)
{
    unsigned char dh_key[128];
    int ret;
    gost_hash_ctx hash_ctx;
    DH *dh = DH_new();

    if (!dh)
        return 0;
    memset(dh_key, 0, 128);
    dh->g = BN_dup(pubk->pkey.dsa->g);
    dh->p = BN_dup(pubk->pkey.dsa->p);
    dh->priv_key = BN_dup(priv_key);
    ret =
        compute_pair_key_le(dh_key, ((DSA *)(EVP_PKEY_get0(pubk)))->pub_key,
                            dh);
    DH_free(dh);
    if (!ret)
        return 0;
    init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet);
    start_hash(&hash_ctx);
    hash_block(&hash_ctx, dh_key, 128);
    finish_hash(&hash_ctx, shared_key);
    done_gost_hash_ctx(&hash_ctx);
    return 1;
}
예제 #5
0
/* Inserts a block in the hash table */
void insert_hash(block_node *b)
{
	int i;

	i = hash_block(b->block);
	
	//pthread_mutex_lock(&hash_mutex);
	ht[i].active = ht[i].active | (unsigned char)0xFF; /* Uuuu....deep magic...I wonder what this does... */
	insert_list(&(ht[i].list), b);
	//pthread_mutex_unlock(&hash_mutex);
}
예제 #6
0
void remove_hash(uint32_t block)
{
	int i;

	i = hash_block(block);
	
	//pthread_mutex_lock(&hash_mutex);
	remove_list(&(ht[i].list), block);
	if(ht[i].list == NULL)
		ht[i].active = ht[i].active & (unsigned char)0x00; /* Uuuu....deep magic...I wonder what this does... */
	//pthread_mutex_unlock(&hash_mutex);
}
예제 #7
0
파일: gost2001_keyx.c 프로젝트: 274914765/C
/* Implementation of CryptoPro VKO 34.10-2001 algorithm */
static int VKO_compute_key (unsigned char *shared_key, size_t shared_key_size, const EC_POINT * pub_key,
                            EC_KEY * priv_key, const unsigned char *ukm)
{
    unsigned char ukm_be[8], databuf[64], hashbuf[64];

    BIGNUM *UKM = NULL, *p = NULL, *order = NULL, *X = NULL, *Y = NULL;

    const BIGNUM *key = EC_KEY_get0_private_key (priv_key);

    EC_POINT *pnt = EC_POINT_new (EC_KEY_get0_group (priv_key));

    int i;

    gost_hash_ctx hash_ctx;

    BN_CTX *ctx = BN_CTX_new ();

    for (i = 0; i < 8; i++)
    {
        ukm_be[7 - i] = ukm[i];
    }
    BN_CTX_start (ctx);
    UKM = getbnfrombuf (ukm_be, 8);
    p = BN_CTX_get (ctx);
    order = BN_CTX_get (ctx);
    X = BN_CTX_get (ctx);
    Y = BN_CTX_get (ctx);
    EC_GROUP_get_order (EC_KEY_get0_group (priv_key), order, ctx);
    BN_mod_mul (p, key, UKM, order, ctx);
    EC_POINT_mul (EC_KEY_get0_group (priv_key), pnt, NULL, pub_key, p, ctx);
    EC_POINT_get_affine_coordinates_GFp (EC_KEY_get0_group (priv_key), pnt, X, Y, ctx);
    /*Serialize elliptic curve point same way as we do it when saving
     * key */
    store_bignum (Y, databuf, 32);
    store_bignum (X, databuf + 32, 32);
    /* And reverse byte order of whole buffer */
    for (i = 0; i < 64; i++)
    {
        hashbuf[63 - i] = databuf[i];
    }
    init_gost_hash_ctx (&hash_ctx, &GostR3411_94_CryptoProParamSet);
    start_hash (&hash_ctx);
    hash_block (&hash_ctx, hashbuf, 64);
    finish_hash (&hash_ctx, shared_key);
    done_gost_hash_ctx (&hash_ctx);
    BN_free (UKM);
    BN_CTX_end (ctx);
    BN_CTX_free (ctx);
    EC_POINT_free (pnt);
    return 32;
}
예제 #8
0
static int passwd_abort(uint64_t etime)
{
	const char *sha_env_str = getenv("bootstopkeysha256");
	u8 sha_env[SHA256_SUM_LEN];
	u8 sha[SHA256_SUM_LEN];
	char presskey[MAX_DELAY_STOP_STR];
	const char *algo_name = "sha256";
	u_int presskey_len = 0;
	int abort = 0;
	int size;
	int ret;

	if (sha_env_str == NULL)
		sha_env_str = CONFIG_AUTOBOOT_STOP_STR_SHA256;

	/*
	 * Generate the binary value from the environment hash value
	 * so that we can compare this value with the computed hash
	 * from the user input
	 */
	ret = hash_parse_string(algo_name, sha_env_str, sha_env);
	if (ret) {
		printf("Hash %s not supported!\n", algo_name);
		return 0;
	}

	/*
	 * We don't know how long the stop-string is, so we need to
	 * generate the sha256 hash upon each input character and
	 * compare the value with the one saved in the environment
	 */
	do {
		if (tstc()) {
			/* Check for input string overflow */
			if (presskey_len >= MAX_DELAY_STOP_STR)
				return 0;

			presskey[presskey_len++] = getc();

			/* Calculate sha256 upon each new char */
			hash_block(algo_name, (const void *)presskey,
				   presskey_len, sha, &size);

			/* And check if sha matches saved value in env */
			if (slow_equals(sha, sha_env, SHA256_SUM_LEN))
				abort = 1;
		}
	} while (!abort && get_ticks() <= etime);

	return abort;
}
예제 #9
0
std::string hash_rom(HashFunc * hf, boost::filesystem::path path)
{
	std::streampos size;
	boost::filesystem::path ext;
	std::ifstream file (path.string(), std::ios::binary | std::ios::ate);
	if (file.is_open())
	{
		size = file.tellg();
		ext = path.extension();
		switch (decoders[ext.string()])
		{
			case DEC_BINARY:
				return hash_file(hf, file, 0);
			case DEC_SNES:
				if (size % 1024 == 512)
					return hash_file(hf, file, 512);
				else
					return hash_file(hf, file, 0);
				break;
			case DEC_MGD:
				return hash_block(hf, file, (size_t)size, deinterleave);
			case DEC_SMD:
				return hash_block(hf, file, 16384, deinterleave);
			case DEC_LNX:
				return hash_file(hf, file, 64);
			case DEC_N64:
				return hash_n64(hf, file);
			case DEC_NES:
				return hash_nes(hf, file);
			case DEC_NOT_DEF:
				return "";
		}
		file.close();
	}
	return "";
}
예제 #10
0
int hash_blocks(const EVP_MD *md,
                const unsigned char *in, size_t in_size,
                unsigned char *out, size_t *out_size,
                const unsigned char *salt, size_t salt_size,
                size_t block_size)
{
    size_t s;
    *out_size = 0;
    for (size_t i = 0; i < in_size; i += block_size) {
        hash_block(md, in + i, block_size, salt, salt_size, out, &s);
        out += s;
        *out_size += s;
    }

    return 0;
}
예제 #11
0
int hash_stream(gost_hash_ctx * ctx, int fd, char *sum)
{
    unsigned char buffer[BUF_SIZE];
    ssize_t bytes;
    int i;
    start_hash(ctx);
    while ((bytes = read(fd, buffer, BUF_SIZE)) > 0) {
        hash_block(ctx, buffer, bytes);
    }
    if (bytes < 0) {
        return 0;
    }
    finish_hash(ctx, buffer);
    for (i = 0; i < 32; i++) {
        sprintf(sum + 2 * i, "%02x", buffer[31 - i]);
    }
    return 1;
}
예제 #12
0
std::string hash_n64(HashFunc * hf, std::ifstream& file)
{
	char * b = new char [4];
	void (*swap)(char*, unsigned int);
	file.seekg (0, std::ios::beg);
	file.read (b, 4);
	unsigned char* header = reinterpret_cast<unsigned char*>(b);
	if (header[0] == 0x80)
	{
		swap = &z_swap;
	}
	else if (header[3] == 0x80)
	{
		swap = &n_swap;
	}
	else
	{
		swap = NULL;
	}
	delete[] b;
	return hash_block(hf, file, 16384, swap);
}
예제 #13
0
void
pkg_sign_gpg(const char *name, const char *output)
{
	struct archive *pkg;
	struct archive_entry *entry, *hash_entry, *sign_entry;
	int fd;
	struct stat sb;
	char *hash_file, *signature_file, *tmp, *pkgname, hash[SHA512_DIGEST_STRING_LENGTH];
	unsigned char block[65536];
	off_t i, size;
	size_t block_len, signature_len;

	if ((fd = open(name, O_RDONLY)) == -1)
		err(EXIT_FAILURE, "Cannot open binary package %s", name);
	if (fstat(fd, &sb) == -1)
		err(EXIT_FAILURE, "Cannot stat %s", name);

	entry = archive_entry_new();
	archive_entry_copy_stat(entry, &sb);

	pkgname = extract_pkgname(fd);
	hash_file = xasprintf(hash_template, pkgname,
	    (long long)archive_entry_size(entry));
	free(pkgname);

	for (i = 0; i < archive_entry_size(entry); i += block_len) {
		if (i + (off_t)sizeof(block) < archive_entry_size(entry))
			block_len = sizeof(block);
		else
			block_len = archive_entry_size(entry) % sizeof(block);
		if (read(fd, block, block_len) != (ssize_t)block_len)
			err(2, "short read");
		hash_block(block, block_len, hash);
		tmp = xasprintf("%s%s\n", hash_file, hash);
		free(hash_file);
		hash_file = tmp;
	}
	tmp = xasprintf("%s%s", hash_file, hash_trailer);
	free(hash_file);
	hash_file = tmp;

	if (detached_gpg_sign(hash_file, strlen(hash_file), &signature_file,
	    &signature_len, gpg_keyring_sign, gpg_sign_as))
		err(EXIT_FAILURE, "Cannot sign hash file");

	lseek(fd, 0, SEEK_SET);

	sign_entry = archive_entry_clone(entry);
	hash_entry = archive_entry_clone(entry);
	pkgname = strrchr(name, '/');
	archive_entry_set_pathname(entry, pkgname != NULL ? pkgname + 1 : name);
	archive_entry_set_pathname(hash_entry, HASH_FNAME);
	archive_entry_set_pathname(sign_entry, GPG_SIGNATURE_FNAME);
	archive_entry_set_size(hash_entry, strlen(hash_file));
	archive_entry_set_size(sign_entry, signature_len);

	pkg = archive_write_new();
	archive_write_set_compression_none(pkg);
	archive_write_set_format_ar_bsd(pkg);
	archive_write_open_filename(pkg, output);

	archive_write_header(pkg, hash_entry);
	archive_write_data(pkg, hash_file, strlen(hash_file));
	archive_write_finish_entry(pkg);
	archive_entry_free(hash_entry);

	archive_write_header(pkg, sign_entry);
	archive_write_data(pkg, signature_file, signature_len);
	archive_write_finish_entry(pkg);
	archive_entry_free(sign_entry);

	size = archive_entry_size(entry);
	archive_write_header(pkg, entry);

	for (i = 0; i < size; i += block_len) {
		if (i + (off_t)sizeof(block) < size)
			block_len = sizeof(block);
		else
			block_len = size % sizeof(block);
		if (read(fd, block, block_len) != (ssize_t)block_len)
			err(2, "short read");
		archive_write_data(pkg, block, block_len);
	}
	archive_write_finish_entry(pkg);
	archive_entry_free(entry);

	archive_write_finish(pkg);

	close(fd);

	exit(0);
}
예제 #14
0
파일: nested.c 프로젝트: ags/uni_coursework
int main(int argc, char* argv[]) {
  Options* args = arg_parse(argc, argv);
  int matches = 0;
  float time = 0;

  if(args == NULL) {
    fprintf(stderr, "usage: %s [-d] buffers outer_r inner_r\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  /* we need two buffers for IO and at least one for blocks */
  if(args->buffers < 3) {
    fprintf(stderr, "error: need at least 3 buffers\n");
    exit(EXIT_FAILURE);
  }
  int block_size = args->buffers - 2;

  FILE *fp_inner, *fp_outer;
  /* get a file pointer to inner relation, exit if unable */
  if(!e_fopen(args->outer_file, &fp_outer, "r")) {
    fprintf(stderr, "failed to open %s\n", args->outer_file);
    exit(EXIT_FAILURE);
  }
  if(!e_fopen(args->inner_file, &fp_inner, "r")) {
    fprintf(stderr, "failed to open %s\n", args->inner_file);
    exit(EXIT_FAILURE);
  }
  
  /* determine which relation is the outer and setup variables accordingly */
  int is_outer_char = is_char_relation(fp_outer);
  int o_records_pp, i_records_pp;
  if(is_outer_char) {
    o_records_pp = CHAR_RECORDS_PP;
    i_records_pp = GUILD_RECORDS_PP;
  } else {
    o_records_pp = GUILD_RECORDS_PP;
    i_records_pp = CHAR_RECORDS_PP;
  }
  #ifdef DO_TIME
    hrtime_t start, end;
    start = gethrtime();
  #endif
  Hashtable* htable = hash_init(HASH_SIZE);
  /* for each block of outer relation, scan inner relation */
  while(!feof(fp_outer)) {
    /* read in a block from outer file, where  a block is the number 
     * of available buffers, each page is a buffer and each page can 
     * hold 2 records. */
    Page** block = read_block(block_size, fp_outer, is_outer_char);

    /* hash block for faster comparisions */
    hash_block(htable, block, block_size, o_records_pp, is_outer_char);

    /* scan inner relation */
    while(!feof(fp_inner)) {
      /* read one page into the input buffer */
      Page* p = read_page(i_records_pp, fp_inner, !is_outer_char);
      for(int i = 0; i < i_records_pp; i++) {
        Character* c = NULL;
        Guild* g = NULL;
        Entry* e = NULL;
        /* we have either a character or guild from outer, so get the 
           one we don't from the hashtable */
        if(is_outer_char) {
          if(!p->g[i])
            continue;
          g = p->g[i];
          e = hash_lookup(htable, g->guild_id);
        } else {
          if(!p->c[i])
            continue;
          c = p->c[i];
          e = hash_lookup(htable, c->guild_id);
        }

        /* check all possible matches */
        while(e != NULL) {
          if(is_outer_char)
            c = (Character*)e->value;
          else
            g = (Guild*)e->value;
          
          /* compare guild id's for match */
          if(g->guild_id == c->guild_id) {
            matches++;
            /* output the tuple if -d flag set */
            if(args->dflag) {
              if(is_outer_char) {
                printf("%d,%s,%d,%d,%d,%s\n", c->guild_id, c->name, c->race, 
                    c->class, c->id, g->g_name);
              } else {
                printf("%d,%s,%s,%d,%d,%d\n", g->guild_id, g->g_name, c->name, 
                    c->race, c->class, c->id);
              }
            }
          }
          /* using chaining, so get next possible match */
          e = e->next;
        }
      }
      /* deallocate page */
      free_page(p, i_records_pp, !is_outer_char);
    }
예제 #15
0
int
main(int argc, char **argv)
{
	byte *strings[] = {
		"",
		"a",
		"aa",
		"aaa",
		"aaaa",
		"aaaaa",
		"aaaaaa",
		"aaaaaaa",
		"aaaaaaaa",
		"aaaaaaaaa",
		"aaaaaaaaaa",
		"AHOJ",
		"\200aaaa",
		"\200",
		"\200\200",
		"\200\200\200",
		"\200\200\200\200",
		"\200\200\200\200\200",
		"kelapS treboR",
		"Robert Spalek",
		"uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu",
		"********************************",
		"****************************************************************",
		NULL
	};
	int lengths[] = {
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
		11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
		30, 40, 50, 60, 70, 80, 90, 100,
		200, 300, 400, 500, 600, 700, 800, 900, 1000,
		2000, 4000, 8000, 16000, 32000, 64000,
		-1
	};
	int i;
	if (argc > 1)
		alignment = atoi(argv[1]);
	printf("Alignment set to %d\n", alignment);
	for (i=0; strings[i]; i++)
		if (strlen(strings[i]) != str_len(strings[i]))
			die("Internal str_len() error on string %d", i);
	printf("%d strings tested OK\n", i);
	for (i=0; strings[i]; i++)
	{
		uns h1, h2;
		h1 = hash_string(strings[i]);
		h2 = hash_string_nocase(strings[i]);
		if (h1 != hash_block(strings[i], str_len(strings[i])))
			die("Internal hash_string() error on string %d", i);
		printf("hash %2d = %08x %08x", i, h1, h2);
		if (h1 == h2)
			printf(" upper case?");
		printf("\n");
	}
	for (i=0; lengths[i] >= 0; i++)
	{
		byte str[lengths[i] + 1 + alignment];
		uns count = TEST_TIME / (lengths[i] + 10);
		uns el1 = 0, el2 = 0, elh = 0, elhn = 0;
		uns tot1 = 0, tot2 = 0, hash = 0, hashn = 0;
		uns j;
		for (j=0; j<count; j++)
		{
			random_string(str + alignment, lengths[i]);
			elapsed_time();
			/* Avoid "optimizing" by gcc, since the functions are
			 * attributed PURE.  */
			tot1 += strlen(str + alignment);
			el1 += elapsed_time();
			tot2 += str_len(str + alignment);
			el2 += elapsed_time();
			hash ^= hash_string(str + alignment);
			elh += elapsed_time();
			hashn ^= hash_string_nocase(str + alignment);
			elhn += elapsed_time();
		}
		if (tot1 != tot2)
			die("Internal error during test %d", i);
		printf("Test %d: strlen = %d, passes = %d, classical = %d usec, speedup = %.4f\n",
			i, lengths[i], count, el1, (el1 + 0.) / el2);
		printf("\t\t total hash = %08x/%08x, hash time = %d/%d usec\n", hash, hashn, elh, elhn);
	}
/*
	printf("test1: %d\n", hash_modify(10000000, 10000000, 99777555));
	printf("test1: %d, %d\n", i, hash_modify(i, lengths[i-2], 99777333));
	printf("test1: %d, %d\n", i, hash_modify(lengths[i-2], i, 99777333));
	printf("test1: %d,%d,%d->%d\n", i, i*3-2, i*i, hash_modify(4587, i*3-2, i*i));
	printf("test1: %d\n", hash_modify(lengths[5], 345, i));
*/
	return 0;
}
예제 #16
0
static unsigned int dataset_hash_hash(const void*h)
{
    return hash_block(h, HASH_SIZE);
}
예제 #17
0
/**
 * Process an emulated EC command
 *
 * @param ec		Current emulated EC state
 * @param req_hdr	Pointer to request header
 * @param req_data	Pointer to body of request
 * @param resp_hdr	Pointer to place to put response header
 * @param resp_data	Pointer to place to put response data, if any
 * @return length of response data, or 0 for no response data, or -1 on error
 */
static int process_cmd(struct ec_state *ec,
		       struct ec_host_request *req_hdr, const void *req_data,
		       struct ec_host_response *resp_hdr, void *resp_data)
{
	int len;

	/* TODO([email protected]): Check checksums */
	debug("EC command %#0x\n", req_hdr->command);

	switch (req_hdr->command) {
	case EC_CMD_HELLO: {
		const struct ec_params_hello *req = req_data;
		struct ec_response_hello *resp = resp_data;

		resp->out_data = req->in_data + 0x01020304;
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_GET_VERSION: {
		struct ec_response_get_version *resp = resp_data;

		strcpy(resp->version_string_ro, "sandbox_ro");
		strcpy(resp->version_string_rw, "sandbox_rw");
		resp->current_image = ec->current_image;
		debug("Current image %d\n", resp->current_image);
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_VBNV_CONTEXT: {
		const struct ec_params_vbnvcontext *req = req_data;
		struct ec_response_vbnvcontext *resp = resp_data;

		switch (req->op) {
		case EC_VBNV_CONTEXT_OP_READ:
			memcpy(resp->block, ec->vbnv_context,
			       sizeof(resp->block));
			len = sizeof(*resp);
			break;
		case EC_VBNV_CONTEXT_OP_WRITE:
			memcpy(ec->vbnv_context, resp->block,
			       sizeof(resp->block));
			len = 0;
			break;
		default:
			printf("   ** Unknown vbnv_context command %#02x\n",
			       req->op);
			return -1;
		}
		break;
	}
	case EC_CMD_REBOOT_EC: {
		const struct ec_params_reboot_ec *req = req_data;

		printf("Request reboot type %d\n", req->cmd);
		switch (req->cmd) {
		case EC_REBOOT_DISABLE_JUMP:
			len = 0;
			break;
		case EC_REBOOT_JUMP_RW:
			ec->current_image = EC_IMAGE_RW;
			len = 0;
			break;
		default:
			puts("   ** Unknown type");
			return -1;
		}
		break;
	}
	case EC_CMD_HOST_EVENT_GET_B: {
		struct ec_response_host_event_mask *resp = resp_data;

		resp->mask = 0;
		if (ec->recovery_req) {
			resp->mask |= EC_HOST_EVENT_MASK(
					EC_HOST_EVENT_KEYBOARD_RECOVERY);
		}

		len = sizeof(*resp);
		break;
	}
	case EC_CMD_VBOOT_HASH: {
		const struct ec_params_vboot_hash *req = req_data;
		struct ec_response_vboot_hash *resp = resp_data;
		struct fmap_entry *entry;
		int ret, size;

		entry = &ec->ec_config.region[EC_FLASH_REGION_RW];

		switch (req->cmd) {
		case EC_VBOOT_HASH_RECALC:
		case EC_VBOOT_HASH_GET:
			size = SHA256_SUM_LEN;
			len = get_image_used(ec, entry);
			ret = hash_block("sha256",
					 ec->flash_data + entry->offset,
					 len, resp->hash_digest, &size);
			if (ret) {
				printf("   ** hash_block() failed\n");
				return -1;
			}
			resp->status = EC_VBOOT_HASH_STATUS_DONE;
			resp->hash_type = EC_VBOOT_HASH_TYPE_SHA256;
			resp->digest_size = size;
			resp->reserved0 = 0;
			resp->offset = entry->offset;
			resp->size = len;
			len = sizeof(*resp);
			break;
		default:
			printf("   ** EC_CMD_VBOOT_HASH: Unknown command %d\n",
			       req->cmd);
			return -1;
		}
		break;
	}
	case EC_CMD_FLASH_PROTECT: {
		const struct ec_params_flash_protect *req = req_data;
		struct ec_response_flash_protect *resp = resp_data;
		uint32_t expect = EC_FLASH_PROTECT_ALL_NOW |
				EC_FLASH_PROTECT_ALL_AT_BOOT;

		printf("mask=%#x, flags=%#x\n", req->mask, req->flags);
		if (req->flags == expect || req->flags == 0) {
			resp->flags = req->flags ? EC_FLASH_PROTECT_ALL_NOW :
								0;
			resp->valid_flags = EC_FLASH_PROTECT_ALL_NOW;
			resp->writable_flags = 0;
			len = sizeof(*resp);
		} else {
			puts("   ** unexpected flash protect request\n");
			return -1;
		}
		break;
	}
	case EC_CMD_FLASH_REGION_INFO: {
		const struct ec_params_flash_region_info *req = req_data;
		struct ec_response_flash_region_info *resp = resp_data;
		struct fmap_entry *entry;

		switch (req->region) {
		case EC_FLASH_REGION_RO:
		case EC_FLASH_REGION_RW:
		case EC_FLASH_REGION_WP_RO:
			entry = &ec->ec_config.region[req->region];
			resp->offset = entry->offset;
			resp->size = entry->length;
			len = sizeof(*resp);
			printf("EC flash region %d: offset=%#x, size=%#x\n",
			       req->region, resp->offset, resp->size);
			break;
		default:
			printf("** Unknown flash region %d\n", req->region);
			return -1;
		}
		break;
	}
	case EC_CMD_FLASH_ERASE: {
		const struct ec_params_flash_erase *req = req_data;

		memset(ec->flash_data + req->offset,
		       ec->ec_config.flash_erase_value,
		       req->size);
		len = 0;
		break;
	}
	case EC_CMD_FLASH_WRITE: {
		const struct ec_params_flash_write *req = req_data;

		memcpy(ec->flash_data + req->offset, req + 1, req->size);
		len = 0;
		break;
	}
	case EC_CMD_MKBP_STATE:
		len = cros_ec_keyscan(ec, resp_data);
		break;
	case EC_CMD_ENTERING_MODE:
		len = 0;
		break;
	default:
		printf("   ** Unknown EC command %#02x\n", req_hdr->command);
		return -1;
	}

	return len;
}
예제 #18
0
int gost_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count) 
	{
	return hash_block((gost_hash_ctx *)ctx->md_data,data,count);	
	}
예제 #19
0
int main(int argc, char **argv)
{
    char *data_filename;
    char *verity_filename;
    unsigned char *salt = NULL;
    size_t salt_size = 0;
    bool sparse = false;
    size_t block_size = 4096;
    uint64_t calculate_size = 0;
    bool verbose = false;

    while (1) {
        const static struct option long_options[] = {
            {"salt-str", required_argument, 0, 'a'},
            {"salt-hex", required_argument, 0, 'A'},
            {"help", no_argument, 0, 'h'},
            {"sparse", no_argument, 0, 'S'},
            {"verity-size", required_argument, 0, 's'},
            {"verbose", no_argument, 0, 'v'},
            {NULL, 0, 0, 0}
        };
        int c = getopt_long(argc, argv, "a:A:hSs:v", long_options, NULL);
        if (c < 0) {
            break;
        }

        switch (c) {
        case 'a':
            salt_size = strlen(optarg);
            salt = new unsigned char[salt_size]();
            if (salt == NULL) {
                FATAL("failed to allocate memory for salt\n");
            }
            memcpy(salt, optarg, salt_size);
            break;
        case 'A': {
                BIGNUM *bn = NULL;
                if(!BN_hex2bn(&bn, optarg)) {
                    FATAL("failed to convert salt from hex\n");
                }
                salt_size = BN_num_bytes(bn);
                salt = new unsigned char[salt_size]();
                if (salt == NULL) {
                    FATAL("failed to allocate memory for salt\n");
                }
                if((size_t)BN_bn2bin(bn, salt) != salt_size) {
                    FATAL("failed to convert salt to bytes\n");
                }
            }
            break;
        case 'h':
            usage();
            return 1;
        case 'S':
            sparse = true;
            break;
        case 's': {
                char* endptr;
                errno = 0;
                unsigned long long int inSize = strtoull(optarg, &endptr, 0);
                if (optarg[0] == '\0' || *endptr != '\0' ||
                        (errno == ERANGE && inSize == ULLONG_MAX)) {
                    FATAL("invalid value of verity-size\n");
                }
                if (inSize > UINT64_MAX) {
                    FATAL("invalid value of verity-size\n");
                }
                calculate_size = (uint64_t)inSize;
            }
            break;
        case 'v':
            verbose = true;
            break;
        case '?':
            usage();
            return 1;
        default:
            abort();
        }
    }

    argc -= optind;
    argv += optind;

    const EVP_MD *md = EVP_sha256();
    if (!md) {
        FATAL("failed to get digest\n");
    }

    size_t hash_size = EVP_MD_size(md);
    assert(hash_size * 2 < block_size);

    if (!salt || !salt_size) {
        salt_size = hash_size;
        salt = new unsigned char[salt_size];
        if (salt == NULL) {
            FATAL("failed to allocate memory for salt\n");
        }

        int random_fd = open("/dev/urandom", O_RDONLY);
        if (random_fd < 0) {
            FATAL("failed to open /dev/urandom\n");
        }

        ssize_t ret = read(random_fd, salt, salt_size);
        if (ret != (ssize_t)salt_size) {
            FATAL("failed to read %zu bytes from /dev/urandom: %zd %d\n", salt_size, ret, errno);
        }
        close(random_fd);
    }

    if (calculate_size) {
        if (argc != 0) {
            usage();
            return 1;
        }
        size_t verity_blocks = 0;
        size_t level_blocks;
        int levels = 0;
        do {
            level_blocks = verity_tree_blocks(calculate_size, block_size, hash_size, levels);
            levels++;
            verity_blocks += level_blocks;
        } while (level_blocks > 1);

        printf("%" PRIu64 "\n", (uint64_t)verity_blocks * block_size);
        return 0;
    }

    if (argc != 2) {
        usage();
        return 1;
    }

    data_filename = argv[0];
    verity_filename = argv[1];

    int fd = open(data_filename, O_RDONLY);
    if (fd < 0) {
        FATAL("failed to open %s\n", data_filename);
    }

    struct sparse_file *file;
    if (sparse) {
        file = sparse_file_import(fd, false, false);
    } else {
        file = sparse_file_import_auto(fd, false, verbose);
    }

    if (!file) {
        FATAL("failed to read file %s\n", data_filename);
    }

    int64_t len = sparse_file_len(file, false, false);
    if (len % block_size != 0) {
        FATAL("file size %" PRIu64 " is not a multiple of %zu bytes\n",
                len, block_size);
    }

    int levels = 0;
    size_t verity_blocks = 0;
    size_t level_blocks;

    do {
        level_blocks = verity_tree_blocks(len, block_size, hash_size, levels);
        levels++;
        verity_blocks += level_blocks;
    } while (level_blocks > 1);

    unsigned char *verity_tree = new unsigned char[verity_blocks * block_size]();
    unsigned char **verity_tree_levels = new unsigned char *[levels + 1]();
    size_t *verity_tree_level_blocks = new size_t[levels]();
    if (verity_tree == NULL || verity_tree_levels == NULL || verity_tree_level_blocks == NULL) {
        FATAL("failed to allocate memory for verity tree\n");
    }

    unsigned char *ptr = verity_tree;
    for (int i = levels - 1; i >= 0; i--) {
        verity_tree_levels[i] = ptr;
        verity_tree_level_blocks[i] = verity_tree_blocks(len, block_size, hash_size, i);
        ptr += verity_tree_level_blocks[i] * block_size;
    }
    assert(ptr == verity_tree + verity_blocks * block_size);
    assert(verity_tree_level_blocks[levels - 1] == 1);

    unsigned char zero_block_hash[hash_size];
    unsigned char zero_block[block_size];
    memset(zero_block, 0, block_size);
    hash_block(md, zero_block, block_size, salt, salt_size, zero_block_hash, NULL);

    unsigned char root_hash[hash_size];
    verity_tree_levels[levels] = root_hash;

    struct sparse_hash_ctx ctx;
    ctx.hashes = verity_tree_levels[0];
    ctx.salt = salt;
    ctx.salt_size = salt_size;
    ctx.hash_size = hash_size;
    ctx.block_size = block_size;
    ctx.zero_block_hash = zero_block_hash;
    ctx.md = md;

    sparse_file_callback(file, false, false, hash_chunk, &ctx);

    sparse_file_destroy(file);
    close(fd);

    for (int i = 0; i < levels; i++) {
        size_t out_size;
        hash_blocks(md,
                verity_tree_levels[i], verity_tree_level_blocks[i] * block_size,
                verity_tree_levels[i + 1], &out_size,
                salt, salt_size, block_size);
          if (i < levels - 1) {
              assert(div_round_up(out_size, block_size) == verity_tree_level_blocks[i + 1]);
          } else {
              assert(out_size == hash_size);
          }
    }

    for (size_t i = 0; i < hash_size; i++) {
        printf("%02x", root_hash[i]);
    }
    printf(" ");
    for (size_t i = 0; i < salt_size; i++) {
        printf("%02x", salt[i]);
    }
    printf("\n");

    fd = open(verity_filename, O_WRONLY|O_CREAT, 0666);
    if (fd < 0) {
        FATAL("failed to open output file '%s'\n", verity_filename);
    }
    write(fd, verity_tree, verity_blocks * block_size);
    close(fd);

    delete[] verity_tree_levels;
    delete[] verity_tree_level_blocks;
    delete[] verity_tree;
    delete[] salt;
}