Пример #1
0
int inverse_hash_memory(const struct hash *hash, void *p, size_t n)
{
    const char *waitless_dir = getenv(WAITLESS_DIR);
    if (!waitless_dir)
        die("WAITLESS_DIR not set");
    int dn = strlen(waitless_dir), in = strlen(INVERSE);
    int total = dn + in + 3 + SHOW_HASH_SIZE;
    if (total > PATH_MAX)
        die("WAITLESS_DIR is too long: %d > %d", dn, PATH_MAX - total + dn);

    // path = "waitless_dir/inverse/hash[0:2]/hash"
    char path[total];
    memcpy(path, waitless_dir, dn);
    memcpy(path+dn, INVERSE, in);
    show_hash(path+dn+in+3, SHOW_HASH_SIZE, hash);
    memcpy(path+dn+in, path+dn+in+3, 2);
    path[dn+in+2] = '/';

    // Read path
    // TODO: do enough file locking to prevent reading a partially written file
    int fd = real_open(path, O_RDONLY, 0);
    if (fd < 0)
        die("inverse_hash_memory: failed to open %s: %s", path, strerror(errno));
    size_t r = read(fd, p, n);
    if (r < 0)
        die("inverse_hash_memory: read failed: %s", strerror(errno));
    real_close(fd);
    return r;
}
Пример #2
0
void remember_hash_memory(struct hash *hash, const void *p, size_t n)
{
    hash_memory(hash, p, n);

    const char *waitless_dir = getenv(WAITLESS_DIR);
    if (!waitless_dir)
        die("WAITLESS_DIR not set");
    int dn = strlen(waitless_dir), in = strlen(INVERSE);
    int total = dn + in + 3 + SHOW_HASH_SIZE;
    if (total > PATH_MAX)
        die("WAITLESS_DIR is too long: %d > %d", dn, PATH_MAX - total + dn);

    // path = "waitless_dir/inverse/hash[0:2]/hash"
    char path[total];
    memcpy(path, waitless_dir, dn);
    memcpy(path+dn, INVERSE, in);
    show_hash(path+dn+in+3, SHOW_HASH_SIZE, hash);
    memcpy(path+dn+in, path+dn+in+3, 2);
    path[dn+in+2] = '/';

retry:;

    // Try to open path for exclusive create
    int fd = real_open(path, O_WRONLY | O_CREAT | O_EXCL, 0644);
    if (fd < 0) {
        // Failed: either file exists (great!) or we need to make directories
        int errno_ = errno;
        if (errno_ == EEXIST) {
            // If the file exists, we assume it already has the desired contents
            // (go cryptographic hashing).
            return;
        }
        else if (errno_ == ENOENT) {
            // Create the necessary directory components
            path[dn+in-1] = 0;
            if (mkdir(path, 0755) < 0 && errno != EEXIST)
                die("mkdir(\"%s\") failed: %s", path, strerror(errno));
            path[dn+in-1] = '/';
            path[dn+in+2] = 0;
            if (mkdir(path, 0755) < 0 && errno != EEXIST)
                die("mkdir(\"%s\") failed: %s", path, strerror(errno));
            path[dn+in+2] = '/';

            // Try to open again.  Note that it's possible to hit EEXIST on
            // retry if another thread is trying to remember the same hash.
            goto retry;
        }
        die("failed to create %s: %s", path, strerror(errno_));
    }

    if (write(fd, p, n) != n)
        die("remember_hash_memory: write failed: %s", strerror(errno));
    if (real_close(fd) < 0)
        die("remember_hash_memory: close failed: %s", strerror(errno));
}
Пример #3
0
static void new_node(struct process *process, enum action_type type, const struct hash *data)
{
    struct parents *parents = &process->parents;

    // If there are no parents, skip node generation entirely.  This should
    // happen only from the initial action_execve call in waitless.c.
    if (!parents->n)
        return;

    char buffer[SHOW_HASH_SIZE*parents->n + 3 + SHOW_HASH_SIZE + 1 + SHOW_NODE_SIZE];
    char *p = buffer;
    if (is_verbose()) {
        p += snprintf(p, sizeof(buffer), "%d: ", getpid());
        int i;
        for (i = 0; i < parents->n; i++) {
            p = show_hash(p, 8, parents->p+i);
            *p++ = ' ';
        }
        p = stpcpy(p, "-> ");
    }

    // The new node's name is the hash of its parents' names.
    // We store the new node's name as parents[0] since it will be
    // the first parent of the following node.
    subgraph_node_name(parents->p, parents->p, parents->n);
    parents->n = 1;
    subgraph_new_node(parents->p, type, data);

    if (is_verbose()) {
        p = show_hash(p, 8, parents->p+0);
        p = stpcpy(p, ": ");
        p = show_subgraph_node(p, type, data);
        *p++ = '\n';
        *p = 0;
        write_str(STDERR_FILENO, buffer);
    }
}
Пример #4
0
int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
		 int argc, char * const argv[])
{
	ulong addr, len;

	if (argc < 2)
		return CMD_RET_USAGE;

	addr = simple_strtoul(*argv++, NULL, 16);
	len = simple_strtoul(*argv++, NULL, 16);

	if (multi_hash()) {
		struct hash_algo *algo;
		u8 output[HASH_MAX_DIGEST_SIZE];
		u8 vsum[HASH_MAX_DIGEST_SIZE];
		void *buf;

		if (hash_lookup_algo(algo_name, &algo)) {
			printf("Unknown hash algorithm '%s'\n", algo_name);
			return CMD_RET_USAGE;
		}
		argc -= 2;

		if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
			puts("HASH_MAX_DIGEST_SIZE exceeded\n");
			return 1;
		}

		buf = map_sysmem(addr, len);
		algo->hash_func_ws(buf, len, output, algo->chunk_size);
		unmap_sysmem(buf);

		/* Try to avoid code bloat when verify is not needed */
#ifdef CONFIG_HASH_VERIFY
		if (flags & HASH_FLAG_VERIFY) {
#else
		if (0) {
#endif
			if (!argc)
				return CMD_RET_USAGE;
			if (parse_verify_sum(algo, *argv, vsum,
					flags & HASH_FLAG_ENV)) {
				printf("ERROR: %s does not contain a valid "
					"%s sum\n", *argv, algo->name);
				return 1;
			}
			if (memcmp(output, vsum, algo->digest_size) != 0) {
				int i;

				show_hash(algo, addr, len, output);
				printf(" != ");
				for (i = 0; i < algo->digest_size; i++)
					printf("%02x", vsum[i]);
				puts(" ** ERROR **\n");
				return 1;
			}
		} else {
			show_hash(algo, addr, len, output);
			printf("\n");

			if (argc) {
				store_result(algo, output, *argv,
					flags & HASH_FLAG_ENV);
			}
		}

	/* Horrible code size hack for boards that just want crc32 */
	} else {
		ulong crc;
		ulong *ptr;

		crc = crc32_wd(0, (const uchar *)addr, len, CHUNKSZ_CRC32);

		printf("CRC32 for %08lx ... %08lx ==> %08lx\n",
				addr, addr + len - 1, crc);

		if (argc >= 3) {
			ptr = (ulong *)simple_strtoul(argv[0], NULL, 16);
			*ptr = crc;
		}
	}

	return 0;
}
Пример #5
0
static void
test_from_string(const char *data, size_t len) {
  char *buf, *mem;
  size_t n = s_times;
  int opt = s_options;
  size_t out_len, out_len0, len2 = len, work_len;

  if (s_show_hash) {
    show_hash(data, len);
    return;
  }

  out_len0 = out_len = bmz_pack_buflen(len);
  buf = malloc(len + out_len);
  work_len = bmz_bm_pack_worklen(len, s_fp_len);
  mem = malloc(work_len);
  LOG(1, "input length: %lu, out_len %lu, work_len: %lu\n",
      (Lu)len, (Lu)out_len, (Lu)work_len);

  /* memcpy/memmove for comparison */
  if (opt & O_MEMCPY) {
    BENCH("memcpy", memcpy(buf, data, len), len, n);
  }

  if (opt & O_CHECK_HASH) {

    if (opt & O_HASH_MOD)
      HT_CHECK(bmz_check_hash_mod(data, len, s_fp_len, s_b1, s_m) == BMZ_E_OK);

    if (opt & O_HASH_MOD16X2)
      HT_CHECK(bmz_check_hash_mod16x2(data, len, s_fp_len,
                                      s_b1, s_b2, s_m1, s_m2) == BMZ_E_OK);
    if (opt & O_HASH_MASK16X2)
      HT_CHECK(bmz_check_hash_mask16x2(data, len, s_fp_len, s_b1, s_b2)
               == BMZ_E_OK);

    if (opt & O_HASH_MASK)
      HT_CHECK(bmz_check_hash_mask(data, len, s_fp_len, s_b1) == BMZ_E_OK);

    if (opt & O_HASH_MASK32X2)
      HT_CHECK(bmz_check_hash_mask32x2(data, len, s_fp_len, s_b1, s_b2)
               == BMZ_E_OK);
  }

  if (opt & O_BENCH_HASH) {

    if (opt & O_HASH_MOD)
      BENCH("hash mod", bmz_bench_hash(data, len, BMZ_HASH_MOD), len, n);

    if (opt & O_HASH_MOD16X2)
      BENCH("hash mod16x2", bmz_bench_hash(data, len, BMZ_HASH_MOD16X2),
            len, n);

    if (opt & O_HASH_MASK16X2)
      BENCH("hash mask16x2", bmz_bench_hash(data, len, BMZ_HASH_MASK16X2),
            len, n);

    if (opt & O_HASH_MASK)
      BENCH("hash mask", bmz_bench_hash(data, len, BMZ_HASH_MASK), len, n);

    if (opt & O_HASH_MASK32X2)
      BENCH("hash mask32x2", bmz_bench_hash(data, len, BMZ_HASH_MASK32X2),
            len, n);
  }

  if (opt & O_BENCH_LUT) {

    if (opt & O_HASH_MOD)
      BENCH("lut mod", bmz_bench_lut_mod(data, len, s_fp_len, mem, s_b1, s_m),
            len, n);

    if (opt & O_HASH_MOD16X2)
      BENCH("lut mod16x2", bmz_bench_lut_mod16x2(data, len, s_fp_len, mem,
            s_b1, s_b2, s_m1, s_m2), len, n);

    if (opt & O_HASH_MASK16X2)
      BENCH("lut mask16x2", bmz_bench_lut_mask16x2(data, len, s_fp_len, mem,
            s_b1, s_b2), len, n);

    if (opt & O_HASH_MASK)
      BENCH("lut mask", bmz_bench_lut_mask(data, len, s_fp_len, mem, s_b1),
            len, n);

    if (opt & O_HASH_MASK32X2)
      BENCH("lut mask32x2", bmz_bench_lut_mask32x2(data, len, s_fp_len, mem,
            s_b1, s_b2), len, n);
  }

  if (opt != O_DEFAULT && (opt & 0xf)) return;

  if (opt & O_HASH_MOD) {
    BENCH("bm pack mod", test_bm_mod(data, len, buf, &out_len, mem), len, n);
    BENCH("bm unpack", test_bm_unpack(buf, out_len, buf + out_len, &len2),
          len, n);
    HT_CHECK(len == len2);
    HT_CHECK(memcmp(data, buf + out_len, len) == 0);
  }

  if (opt & O_HASH_MOD16X2) {
    memset(buf, 0, out_len); out_len = out_len0;
    BENCH("bm pack mod16x2", test_bm_mod16x2(data, len, buf, &out_len, mem),
          len, n);
    BENCH("bm unpack", test_bm_unpack(buf, out_len, buf + out_len, &len2),
          len, n);
    HT_CHECK(len == len2);
    HT_CHECK(memcmp(data, buf + out_len, len) == 0);
  }

  if (opt & O_HASH_MASK16X2) {
    memset(buf, 0, out_len); out_len = out_len0;
    BENCH("bm pack mask16x2", test_bm_mask16x2(data, len, buf, &out_len, mem),
          len, n);
    BENCH("bm unpack", test_bm_unpack(buf, out_len, buf + out_len, &len2),
          len, n);
    HT_CHECK(len == len2);
    HT_CHECK(memcmp(data, buf + out_len, len) == 0);
  }

  if (opt & O_HASH_MASK) {
    memset(buf, 0, out_len); out_len = out_len0;
    BENCH("bm pack mask", test_bm_mask(data, len, buf, &out_len, mem), len, n);
    BENCH("bm unpack", test_bm_unpack(buf, out_len, buf + out_len, &len2),
          len, n);
    HT_CHECK(len == len2);
    HT_CHECK(memcmp(data, buf + out_len, len) == 0);
  }

  if (opt & O_HASH_MASK32X2) {
    memset(buf, 0, out_len); out_len = out_len0;
    BENCH("bm pack mask32x2", test_bm_mask32x2(data, len, buf, &out_len, mem),
          len, n);
    BENCH("bm unpack", test_bm_unpack(buf, out_len, buf + out_len, &len2),
          len, n);
    HT_CHECK(len == len2);
    HT_CHECK(memcmp(data, buf + out_len, len) == 0);
  }
}
Пример #6
0
int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag,
		 int argc, char * const argv[])
{
	struct hash_algo *algo;
	ulong addr, len;
	u8 output[HASH_MAX_DIGEST_SIZE];
	u8 vsum[HASH_MAX_DIGEST_SIZE];

	if (argc < 2)
		return CMD_RET_USAGE;

	algo = find_hash_algo(algo_name);
	if (!algo) {
		printf("Unknown hash algorithm '%s'\n", algo_name);
		return CMD_RET_USAGE;
	}
	addr = simple_strtoul(*argv++, NULL, 16);
	len = simple_strtoul(*argv++, NULL, 16);
	argc -= 2;

	if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
		puts("HASH_MAX_DIGEST_SIZE exceeded\n");
		return 1;
	}

	algo->hash_func_ws((const unsigned char *)addr, len, output,
			   algo->chunk_size);

	/* Try to avoid code bloat when verify is not needed */
#ifdef CONFIG_HASH_VERIFY
	if (verify) {
#else
	if (0) {
#endif
		if (!argc)
			return CMD_RET_USAGE;
		if (parse_verify_sum(algo, *argv, vsum)) {
			printf("ERROR: %s does not contain a valid %s sum\n",
				*argv, algo->name);
			return 1;
		}
		if (memcmp(output, vsum, algo->digest_size) != 0) {
			int i;

			show_hash(algo, addr, len, output);
			printf(" != ");
			for (i = 0; i < algo->digest_size; i++)
				printf("%02x", vsum[i]);
			puts(" ** ERROR **\n");
			return 1;
		}
	} else {
		show_hash(algo, addr, len, output);
		printf("\n");

		if (argc)
			store_result(algo, output, *argv);
	}

	return 0;
}