int main(int argc, char *argv[]) {
    if (argc != 5) error(2,
                             "Usage: tweetnacl-encrypt send-key.sec recv-key.pub text.txt text.enc");

    // This will also erroneously fail if the file "-" exists
    if (file_exists(argv[4])) errorf(1, "File <%s> exists", argv[4]);

    // Alice is sending to Bob, not surprisingly
    unsigned char a_secret_key[crypto_box_SECRETKEYBYTES];
    unsigned char b_public_key[crypto_box_PUBLICKEYBYTES];

    read_key(argv[1], a_secret_key, crypto_box_SECRETKEYBYTES);
    read_key(argv[2], b_public_key, crypto_box_PUBLICKEYBYTES);

    unsigned char nonce[crypto_box_NONCEBYTES];
    randombytes(nonce, sizeof(nonce));

    FILE *out;
    if (strcmp(argv[4], "-") != 0) {
        out = create_file(argv[4]);
        fwrite(nonce, sizeof(nonce), 1, out);
    } else {
        out = stdout;
        fwrite(bytes_to_hex(nonce, sizeof(nonce)), sizeof(nonce) * 2, 1, out);
        fputs("\n", out);
    }

    // Input
    // unsigned char *message = read_file(argv[3]);
    Content c = read_file(argv[3]);
    long psize = crypto_box_ZEROBYTES + c.size;
    unsigned char *padded = malloc(psize);
    if (padded == NULL) error(1, "Malloc failed!");
    memset(padded, 0, crypto_box_ZEROBYTES);
    memcpy(padded + crypto_box_ZEROBYTES, c.bytes, c.size);
    free(c.bytes);

    // Output
    unsigned char *encrypted = calloc(psize, sizeof(unsigned char));
    if (encrypted == NULL) error(1, "Calloc failed!");

    // Encrypt
    crypto_box(encrypted, padded, psize, nonce, b_public_key, a_secret_key);
    free(padded);

    if (out != stdout) {
        fwrite(encrypted + crypto_box_BOXZEROBYTES,
               psize - crypto_box_BOXZEROBYTES, 1, out);
    } else {
        fwrite(bytes_to_hex(encrypted + crypto_box_BOXZEROBYTES,
                            psize - crypto_box_BOXZEROBYTES),
               (psize - crypto_box_BOXZEROBYTES) * 2, 1, out);
        fputs("\n", out);
    }
    free(encrypted);
    return 0;
}
Exemple #2
0
interval_db* node_mgr::init_interval_db(const string endid, const string my_vid, const string startid)
{
    string filename(filebase + bytes_to_hex(endid));
    // truncate filename to 255 characters
    if (filename.size() > 255)
        filename.resize(255);

    interval_db* i = new interval_db;
    if (startid != "") {
        cout << "[init_interval_db]  Interval is [" << bytes_to_hex(startid) << " , "  << bytes_to_hex(endid) << " ] " << endl;
        cout << "Creating file (init): " << filename << endl;
        i->h = fawn::FawnDS<FawnDS_Flash>::Create_FawnDS(filename.c_str(),
                                           NUM_RECORD_INIT,
                                           .9,
                                           .8,
                                           TEXT_KEYS);
        DBID d_endid(endid);
        DBID d_startid(startid);
        i->h->setStartID(d_startid);
        i->h->setEndID(d_endid);
      
      cout << "Creating db from xml file: " << xmlfile << endl;
      silt::Configuration* config = new silt::Configuration(xmlfile);
      i->siltds = silt::FawnDS_Factory::New(config);
      i->siltds->Create();
      
    } else {
        cout << "[init_interval_db] startid isnt set" << endl;
        cout << "Opening file: " << filename << endl;
        i->h = fawn::FawnDS<FawnDS_Flash>::Open_FawnDS(filename.c_str(), TEXT_KEYS);
      
      cout << "Opening db from xml file: " << xmlfile << endl;
      silt::Configuration* config = new silt::Configuration(xmlfile);
      i->siltds = silt::FawnDS_Factory::New(config);
      i->siltds->Open();
      
    }
    i->valid = true;
    i->tempDS = NULL;
    i->name = filename;
    i->splitPoint = "";
    i->largest_seq = 0;
    i->last_ack = 0;
    i->sequence = 1;

    // If vid specified, set, otherwise endid = owner vid
    if (my_vid == "")
        i->vid = endid;
    else
        i->vid = my_vid;

    pthread_rwlock_init(&(i->dbLock), NULL);
    return i;
}
std::string Authentication2Command::toString()

{
    std::stringstream builder;

    builder << "Authentication 2:" << std::endl;
    builder << "\tIDm: " << bytes_to_hex(idm, 8) << std::endl;
    builder << "\tChallenge 2 Response: " << bytes_to_hex(challenge_2_response, 8) << std::endl;

    return builder.str();
}
	std::string Authentication2ResponseCommand::toString()
		
	{
		std::stringstream builder;

		builder << "Authentication 2 Response:" << std::endl;
		builder << "\tIDm: " << bytes_to_hex(idm, 8) << std::endl;
		builder << "\tIDi: " << bytes_to_hex(idi, 8) << std::endl;
		builder << "\tPMi: " << bytes_to_hex(pmi, 8) << std::endl;

		return builder.str();
	}
Exemple #5
0
void node_mgr::create_interval_file(const string ps_endid, const string ps_startid, const string my_vid) {

    string filename(filebase + bytes_to_hex(ps_endid));
    cout << "Creating file: " << filename << endl;
    cout << "[create_interval_file]  Interval is [" << bytes_to_hex(ps_startid) << " , "  << bytes_to_hex(ps_endid) << " ] " << endl;
    struct stat fileInfo;
    // truncate filename to 255 characters
    if (filename.size() > 255)
        filename.resize(255);
    int statRet = stat(filename.c_str(), &fileInfo);
    if (statRet == 0) {
        // File exists
        cout << "File exists already" << endl;
        if (overwrite)
            cout << "Overwriting..." << endl;
        else {
            cout << "Opening existing file " << endl;
            interval_db* i = init_interval_db(ps_endid, my_vid);
            insertIntervalFile(i);
            return;
        }
    }

    bool b_create_done = false;

    // lock intervaldb (read mode)
    pthread_rwlock_rdlock(&interval_lock);

    // Don't create if name already exists in existing db.
    for (uint dbi = 0; dbi < dbs.size(); dbi++) {
        if (dbs[dbi] != NULL) {
            if (dbs[dbi]->name == filename) {
                b_create_done = true;
                break;
            }
        }
    }
    // Don't hold interval lock while creating fawnds file. Assumes no
    // one else will be creating a similarly named file during this short
    // period of filename collision vulnerability
    pthread_rwlock_unlock(&interval_lock);


    if (b_create_done)
        return;

    interval_db* i = init_interval_db(ps_endid, my_vid, ps_startid);
    insertIntervalFile(i);
}
Exemple #6
0
void lastpass_update_account(enum blobsync sync, unsigned const char key[KDF_HASH_LEN], const struct session *session, const struct account *account, struct blob *blob)
{
	_cleanup_free_ char *url = NULL;
	_cleanup_free_ char *fields = NULL;

	bytes_to_hex(account->url, &url, strlen(account->url));
	fields = stringify_fields(account->field_head);

	++blob->version;

	if (account->share)
		upload_queue_enqueue(sync, key, session, "show_website.php", "extjs", "1",
				"token", session->token, "aid", account->id,
				"name", account->name_encrypted, "grouping", account->group_encrypted,
				"url", url, "username", account->username_encrypted,
				"password", account->password_encrypted, /* "data", fields,     Removing until server-side catches up. */
				"pwprotect", account->pwprotect ? "on" : "off",
				"extra", account->note_encrypted, "sharedfolderid", account->share->id, NULL);
	else
		upload_queue_enqueue(sync, key, session, "show_website.php", "extjs", "1",
				"token", session->token, "aid", account->id,
				"name", account->name_encrypted, "grouping", account->group_encrypted,
				"url", url, "username", account->username_encrypted,
				"password", account->password_encrypted, /* "data", fields,     Removing until server-side catches up. */
				"pwprotect", account->pwprotect ? "on" : "off",
				"extra", account->note_encrypted, NULL);
}
	std::string ReadWithoutEncryptionCommand::toString()
		
	{
		std::stringstream builder;

		builder << "Read without Encryption:" << std::endl;
		builder << "\tIDm: " << bytes_to_hex(idm, 8) << std::endl;
		builder << "\tNumber of Services to read: " << (unsigned int)number_of_services << std::endl;
		if(number_of_services > 0)
		{
			builder << "\tServices to read:" << std::endl;
			for(int i = 0; i < number_of_services; i++)
			{
				builder << "\t\t"<< std::setw(2) << std::setfill('0') << i <<": ";
				builder << format_node_code(service_code_list[i]) << std::dec << std::setw(0) << std::setfill(' ') << std::endl;
			}
		}
		
		builder << "\tNumber of Blocks to read: " << (unsigned int)number_of_blocks << std::endl;
		if(number_of_blocks > 0)
		{
			builder << "\tBlocks to read: " << std::endl;
			for(int i = 0; i < number_of_blocks; i++)
			{
				unsigned int service_code_list_order = block_headers_list[i] & 0x0f;
				unsigned int access_mode = (block_headers_list[i] & 0x70) >> 4;

				builder << "\t\t" << std::setw(2) << std::setfill('0') << i <<": ";
				builder << "Service #" << service_code_list_order << ", Block #" << (unsigned int)block_list[i] << " (" << (access_mode == 1 ? "purse cashback access" : "r/w operation") << ")" << std::endl;
			}
		}
Exemple #8
0
int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, bool sops, bool localaudio) {
  uuid_t uuid;
  char uuid_str[37];

  RAND_bytes(config->remoteInputAesKey, 16);
  memset(config->remoteInputAesIv, 0, 16);

  srand(time(NULL));
  char url[4096];
  u_int32_t rikeyid = 1;
  char rikey_hex[33];
  bytes_to_hex(config->remoteInputAesKey, rikey_hex, 16);

  PHTTP_DATA data = http_create_data();
  if (data == NULL)
    return GS_OUT_OF_MEMORY;

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  if (server->currentGame == 0) {
    int channelCounnt = config->audioConfiguration == AUDIO_CONFIGURATION_STEREO ? CHANNEL_COUNT_STEREO : CHANNEL_COUNT_51_SURROUND;
    int mask = config->audioConfiguration == AUDIO_CONFIGURATION_STEREO ? CHANNEL_MASK_STEREO : CHANNEL_MASK_51_SURROUND;
    sprintf(url, "https://%s:47984/launch?uniqueid=%s&uuid=%s&appid=%d&mode=%dx%dx%d&additionalStates=1&sops=%d&rikey=%s&rikeyid=%d&localAudioPlayMode=%d&surroundAudioInfo=%d", server->address, unique_id, uuid_str, appId, config->width, config->height, config->fps, sops, rikey_hex, rikeyid, localaudio, (mask << 16) + channelCounnt);
  } else
    sprintf(url, "https://%s:47984/resume?uniqueid=%s&uuid=%s&rikey=%s&rikeyid=%d", server->address, unique_id, uuid_str, rikey_hex, rikeyid);

  int ret = http_request(url, data);
  if (ret == GS_OK)
    server->currentGame = appId;

  http_free_data(data);
  return ret;
}
	std::string SearchServiceCodeResponseCommand::toString()
		
	{
		std::stringstream builder;

		builder << "Search Service Code Response:" << std::endl;
		builder << "\tIDm: " << bytes_to_hex(idm, 8) << std::endl;
		builder << "\tService Code: " << format_node_code(service_code);
		if(is_area)
		{
			uint8_t area_end_code_bytes[] = {
				(area_end_code & 0xff00) >> 8,
				(area_end_code & 0x00ff)
			};
			builder << "\tArea End: "<< bytes_to_hex(area_end_code_bytes, 2) << std::endl;
		}

		return builder.str();
	}
void output_key(char filename[], unsigned char key[], int key_size) {
    // http://stackoverflow.com/a/8004250
    if (strcmp(filename, "-") != 0) {
        FILE *out = create_file(filename);
        fwrite(key, key_size, 1, out);
        fclose(out);
    } else {
        fwrite(bytes_to_hex(key, key_size), key_size * 2, 1, stdout);
        fputs("\n", stdout);
    }
}
Exemple #11
0
static int check_resource(struct resource_list *list, const char *file_resource_name, struct archive *a, struct archive_entry *ae)
{
    struct resource_list *item = rlist_find_by_name(list, file_resource_name);
    if (!item)
        ERR_RETURN("Can't find file-resource for %s", file_resource_name);

    if (item->processed)
        ERR_RETURN("Processing %s twice. Archive is corrupt.", file_resource_name);
    item->processed = true;

    struct sparse_file_map sfm;
    sparse_file_init(&sfm);
    OK_OR_RETURN(sparse_file_get_map_from_resource(item->resource, &sfm));

    size_t expected_length = sparse_file_data_size(&sfm);
    ssize_t archive_length = archive_entry_size(ae);
    if (archive_length < 0)
        ERR_RETURN("Missing file length in archive for %s", file_resource_name);
    if ((size_t) archive_length != expected_length)
        ERR_RETURN("Length mismatch for %s", file_resource_name);

    char *expected_hash = cfg_getstr(item->resource, "blake2b-256");
    if (!expected_hash || strlen(expected_hash) != crypto_generichash_BYTES * 2)
        ERR_RETURN("invalid blake2b-256 hash for '%s'", file_resource_name);

    crypto_generichash_state hash_state;
    crypto_generichash_init(&hash_state, NULL, 0, crypto_generichash_BYTES);
    size_t length_left = expected_length;
    while (length_left != 0) {
        char buffer[4096];

        size_t to_read = sizeof(buffer);
        if (to_read > length_left)
            to_read = length_left;

        ssize_t len = archive_read_data(a, buffer, to_read);
        if (len <= 0)
            ERR_RETURN("Error reading '%s' in archive", archive_entry_pathname(ae));

        crypto_generichash_update(&hash_state, (const unsigned char*) buffer, len);
        length_left -= len;
    }

    unsigned char hash[crypto_generichash_BYTES];
    crypto_generichash_final(&hash_state, hash, sizeof(hash));
    char hash_str[sizeof(hash) * 2 + 1];
    bytes_to_hex(hash, hash_str, sizeof(hash));
    if (memcmp(hash_str, expected_hash, sizeof(hash_str)) != 0)
        ERR_RETURN("Detected blake2b digest mismatch for %s", file_resource_name);

    return 0;
}
Exemple #12
0
int gs_start_app(PSERVER_DATA server, STREAM_CONFIGURATION *config, int appId, bool sops, bool localaudio) {
  int ret = GS_OK;
  uuid_t uuid;
  char* result = NULL;
  char uuid_str[37];

  if (config->height >= 2160 && !server->supports4K)
    return GS_NOT_SUPPORTED_4K;

  RAND_bytes(config->remoteInputAesKey, 16);
  memset(config->remoteInputAesIv, 0, 16);

  srand(time(NULL));
  char url[4096];
  u_int32_t rikeyid = 0;
  char rikey_hex[33];
  bytes_to_hex(config->remoteInputAesKey, rikey_hex, 16);

  PHTTP_DATA data = http_create_data();
  if (data == NULL)
    return GS_OUT_OF_MEMORY;

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  if (server->currentGame == 0) {
    int channelCounnt = config->audioConfiguration == AUDIO_CONFIGURATION_STEREO ? CHANNEL_COUNT_STEREO : CHANNEL_COUNT_51_SURROUND;
    int mask = config->audioConfiguration == AUDIO_CONFIGURATION_STEREO ? CHANNEL_MASK_STEREO : CHANNEL_MASK_51_SURROUND;
    sprintf(url, "https://%s:47984/launch?uniqueid=%s&uuid=%s&appid=%d&mode=%dx%dx%d&additionalStates=1&sops=%d&rikey=%s&rikeyid=%d&localAudioPlayMode=%d&surroundAudioInfo=%d", server->address, unique_id, uuid_str, appId, config->width, config->height, config->fps, sops, rikey_hex, rikeyid, localaudio, (mask << 16) + channelCounnt);
  } else
    sprintf(url, "https://%s:47984/resume?uniqueid=%s&uuid=%s&rikey=%s&rikeyid=%d", server->address, unique_id, uuid_str, rikey_hex, rikeyid);

  if ((ret = http_request(url, data)) == GS_OK)
    server->currentGame = appId;
  else
    goto cleanup;

  if ((ret = xml_search(data->memory, data->size, "gamesession", &result)) != GS_OK)
    goto cleanup;

  if (!strcmp(result, "0")) {
    ret = GS_FAILED;
    goto cleanup;
  }

  cleanup:
  if (result != NULL)
    free(result);

  http_free_data(data);
  return ret;
}
Exemple #13
0
void kdf_login_key(const char *username, const char *password, int iterations, char hex[KDF_HEX_LEN])
{
	unsigned char hash[KDF_HASH_LEN];
	size_t password_len;
	_cleanup_free_ char *user_lower = xstrlower(username);

	password_len = strlen(password);

	if (iterations < 1)
		iterations = 1;

	if (iterations == 1) {
		sha256_hash(user_lower, strlen(user_lower), password, password_len, hash);
		bytes_to_hex(hash, &hex, KDF_HASH_LEN);
		sha256_hash(hex, KDF_HEX_LEN - 1, password, password_len, hash);
	} else {
		pbkdf2_hash(user_lower, strlen(user_lower), password, password_len, iterations, hash);
		pbkdf2_hash(password, password_len, (char *)hash, KDF_HASH_LEN, 1, hash);
	}

	bytes_to_hex(hash, &hex, KDF_HASH_LEN);
	mlock(hex, KDF_HEX_LEN);
}
Exemple #14
0
/** @brief Print out the superblock struct to stdout
 *
 * @param sb Superblock
 */
void print_superblock(struct mint_superblock *sb){
	char *buf = (char*)(malloc(4096));
	const EVP_MD *md;
	md = EVP_get_digestbyname(sb->hash_algorithm);
	uint32_t hash_bytes = EVP_MD_size(md);
	printf("[ dm-mintegrity superblock ]\n");
	printf("Magic: %#0x\n", sb->magic);
	printf("Version: %u\n", sb->version);
	bytes_to_hex(sb->uuid, 16, buf);
	printf("UUID: %s\n", buf);
	printf("Hash_Type: %s\n", sb->hash_algorithm);
	printf("Hmac_Type: %s\n", sb->hmac_algorithm);
	printf("Block_Size: %u\n", sb->block_size);
	printf("Data_Blocks: %ju\n", sb->data_blocks);
	printf("Hash_Blocks: %u\n", sb->hash_blocks);
	printf("JB_Blocks: %u\n", sb->jb_blocks);
	printf("Salt_Size: %u\n", sb->salt_size);
	bytes_to_hex(sb->salt, sb->salt_size, buf);
	printf("Salt: %s\n", buf);
	bytes_to_hex(sb->root, hash_bytes, buf);
	printf("Root_Hash: %s\n", buf);
	free(buf);
}
Exemple #15
0
void hexdump(const char *prefix, const size_t column_len, const void *value, size_t len) {
    assert(prefix != NULL);
    assert(column_len > 0);
    int row_count = (len / column_len) + 1;
    int i;

    size_t slen = column_len*3;
    char* s = malloc(slen * sizeof(char));
    for (i = 0; i < row_count; ++i) {
        memset(s, 0, slen);
        bytes_to_hex(value, len, (char **)&s);
        printf("%s %s\n", prefix, s);
    }
    free(s);
}
Exemple #16
0
static char *stringify_fields(const struct field *field_head)
{
	char *field_str, *fields = NULL;

	for (const struct field *field = field_head; field; field = field->next) {
		field_str = stringify_field(field);
		xstrappend(&fields, field_str);
		free(field_str);
	}
	if (fields)
		xstrappend(&fields, "0\taction\t\taction\n0\tmethod\t\tmethod\n");
	else
		fields = xstrdup("");

	field_str = NULL;
	bytes_to_hex(fields, &field_str, strlen(fields));
	free(fields);

	return field_str;
}
Exemple #17
0
fawn::FawnDS<FawnDS_Flash>* node_mgr::createTempStore(const string& startid_str, const string& endid_str,
                                  const string& prefix_str)
{
    DBID p_endid(endid_str);
    DBID p_startid(startid_str);
    string filename(filebase + prefix_str + bytes_to_hex(endid_str));
    // truncate filename to 255 characters
    if (filename.size() > 255)
        filename.resize(255);
    cout << "Creating temporary file: " << filename << endl;
    fawn::FawnDS<FawnDS_Flash>* tempDS = fawn::FawnDS<FawnDS_Flash>::Create_FawnDS(filename.c_str(),
                                                 NUM_RECORD_INIT_TEMP,
                                                 0.9,
                                                 0.8,
                                                 TEXT_KEYS);

    tempDS->setStartID(p_startid);
    tempDS->setEndID(p_endid);

    return tempDS;
}
void load_recovery_id_prop() {
    char fstab_filename[PROP_VALUE_MAX + sizeof(FSTAB_PREFIX)];
    char propbuf[PROP_VALUE_MAX];
    int ret = property_get("ro.hardware", propbuf);
    if (!ret) {
        ERROR("ro.hardware not set - unable to load recovery id\n");
        return;
    }
    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX "%s", propbuf);

    std::unique_ptr<fstab, void(*)(fstab*)> tab(fs_mgr_read_fstab(fstab_filename),
            fs_mgr_free_fstab);
    if (!tab) {
        ERROR("unable to read fstab %s: %s\n", fstab_filename, strerror(errno));
        return;
    }

    fstab_rec* rec = fs_mgr_get_entry_for_mount_point(tab.get(), RECOVERY_MOUNT_POINT);
    if (rec == NULL) {
        ERROR("/recovery not specified in fstab\n");
        return;
    }

    int fd = open(rec->blk_device, O_RDONLY);
    if (fd == -1) {
        ERROR("error opening block device %s: %s\n", rec->blk_device, strerror(errno));
        return;
    }

    boot_img_hdr hdr;
    if (android::base::ReadFully(fd, &hdr, sizeof(hdr))) {
        std::string hex = bytes_to_hex(reinterpret_cast<uint8_t*>(hdr.id), sizeof(hdr.id));
        property_set("ro.recovery_id", hex.c_str());
    } else {
        ERROR("error reading /recovery: %s\n", strerror(errno));
    }

    close(fd);
}
void load_recovery_id_prop() {
    std::string ro_hardware = property_get("ro.hardware");
    if (ro_hardware.empty()) {
        LOG(ERROR) << "ro.hardware not set - unable to load recovery id";
        return;
    }
    std::string fstab_filename = FSTAB_PREFIX + ro_hardware;

    std::unique_ptr<fstab, void(*)(fstab*)> tab(fs_mgr_read_fstab(fstab_filename.c_str()),
                                                fs_mgr_free_fstab);
    if (!tab) {
        PLOG(ERROR) << "unable to read fstab " << fstab_filename;
        return;
    }

    fstab_rec* rec = fs_mgr_get_entry_for_mount_point(tab.get(), RECOVERY_MOUNT_POINT);
    if (rec == NULL) {
        LOG(ERROR) << "/recovery not specified in fstab";
        return;
    }

    int fd = open(rec->blk_device, O_RDONLY);
    if (fd == -1) {
        PLOG(ERROR) << "error opening block device " << rec->blk_device;
        return;
    }

    boot_img_hdr hdr;
    if (android::base::ReadFully(fd, &hdr, sizeof(hdr))) {
        std::string hex = bytes_to_hex(reinterpret_cast<uint8_t*>(hdr.id), sizeof(hdr.id));
        property_set("ro.recovery_id", hex.c_str());
    } else {
        PLOG(ERROR) << "error reading /recovery";
    }

    close(fd);
}
Exemple #20
0
int main()
{
    try
    {
        std::cout << "load:\t";
        {
            std::cout << "1, 12, 1.234, 5.678" << std::endl;

            boost::uint8_t n8(0);
            boost::uint32_t n32(0);
            boost::uint64_t n64(0);
            double ad64(0);
            double bd64(0);

            std::cout << "\tfrom little-endian:\t";
            {
                std::string const hex_little("010C0000005839B4C876BEF33F83C0CAA145B61640");
                std::cout << hex_little << std::endl;

                byte_array bytes;
                hex_to_bytes(hex_little, bytes);

                n8 = yatbinrw::load_little_endian<boost::uint8_t, sizeof(boost::uint8_t)>(bytes.begin());
                std::cout << "\t\tn8 = " << (int)n8 << std::endl;

                n32 = yatbinrw::load_little_endian<boost::uint32_t, sizeof(boost::uint32_t)>(bytes.begin() + 1);
                std::cout << "\t\tn32 = " << n32 << std::endl;

                n64 = yatbinrw::load_little_endian<boost::uint64_t, sizeof(boost::uint64_t)>(bytes.begin() + 1 + 4);
                std::memcpy(&ad64, &n64, sizeof(double));
                std::cout << "\t\tad64 = " << ad64 << " (" << n64 << " )" << std::endl;

                n64 = yatbinrw::load_little_endian<boost::uint64_t, sizeof(boost::uint64_t)>(bytes.begin() + 1 + 4 + 8);
                std::memcpy(&bd64, &n64, sizeof(double));
                std::cout << "\t\tbd64 = " << bd64 << " (" << n64 << " )" << std::endl;
            }

            std::cout << "\tfrom big-endian:\t";
            {
                std::string const hex_big("010000000C3FF3BE76C8B439584016B645A1CAC083");
                std::cout << hex_big << std::endl;

                byte_array bytes;
                hex_to_bytes(hex_big, bytes);        

                n8 = yatbinrw::load_big_endian<boost::uint8_t, sizeof(boost::uint8_t)>(bytes.begin());
                std::cout << "\t\tn8 = " << (int)n8 << std::endl;

                n32 = yatbinrw::load_big_endian<boost::uint32_t, sizeof(boost::uint32_t)>(bytes.begin() + 1);
                std::cout << "\t\tn32 = " << n32 << std::endl;

                n64 = yatbinrw::load_big_endian<boost::uint64_t, sizeof(boost::uint64_t)>(bytes.begin() + 1 + 4);
                std::memcpy(&ad64, &n64, sizeof(double));
                std::cout << "\t\tad64 = " << ad64 << " (" << n64 << " )" << std::endl;

                n64 = yatbinrw::load_big_endian<boost::uint64_t, sizeof(boost::uint64_t)>(bytes.begin() + 1 + 4 + 8);
                std::memcpy(&bd64, &n64, sizeof(double));
                std::cout << "\t\tbd64 = " << bd64 << " (" << n64 << " )" << std::endl;
            }
        } // load

        std::cout << "store:\t";
        {
            boost::uint8_t const n8(1);
            boost::uint32_t const n32(12);
            boost::uint64_t n64(0);
            double const ad64(1.234);
            double const bd64(5.678);

            std::cout << (int)n8 << ", " << n32 << ", " << ad64 << ", " << bd64 << std::endl;

            std::cout << "\tto little-endian:\t";
            {
                byte_array bytes; //empty
                std::back_insert_iterator<byte_array> it(std::back_inserter(bytes));

                yatbinrw::store_little_endian<boost::uint8_t, 1>(it, n8);
                yatbinrw::store_little_endian<boost::uint32_t, 4>(it, n32);

                std::memcpy(&n64, &ad64, sizeof(boost::uint64_t));
                yatbinrw::store_little_endian<boost::uint64_t, 8>(it, n64);

                std::memcpy(&n64, &bd64, sizeof(boost::uint64_t));
                yatbinrw::store_little_endian<boost::uint64_t, 8>(it, n64);

                std::string hex;
                bytes_to_hex(bytes, hex);
                std::cout << hex << std::endl;
            }

            std::cout << "\tto big-endian:";
            {
                byte_array bytes(1 + 4 + 8 + 8); // non-empty

                yatbinrw::store_big_endian<boost::uint8_t, 1>(bytes.begin(), n8);
                yatbinrw::store_big_endian<boost::uint32_t, 4>(bytes.begin() + 1, n32);

                std::memcpy(&n64, &ad64, sizeof(boost::uint64_t));
                yatbinrw::store_big_endian<boost::uint64_t, 8>(bytes.begin() + 1 + 4, n64);

                std::memcpy(&n64, &bd64, sizeof(boost::uint64_t));
                yatbinrw::store_big_endian<boost::uint64_t, 8>(bytes.begin() + 1 + 4 + 8, n64);

                std::string hex;
                bytes_to_hex(bytes, hex);
                std::cout << '\t' << hex << std::endl;
            }

        } // store
    }
    catch (std::exception const& e)
    {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}
Exemple #21
0
static void write_hex_string(struct buffer *buffer, char *bytes)
{
	_cleanup_free_ char *hex = NULL;
	bytes_to_hex(bytes, &hex, strlen(bytes));
	write_plain_string(buffer, hex);
}
Exemple #22
0
int gs_pair(const char* address, const char* pin) {
    int ret = GS_OK;
    char url[4096];
    
    unsigned char salt_data[16];
    char salt_hex[33];
    RAND_bytes(salt_data, 16);
    bytes_to_hex(salt_data, salt_hex, 16);
    
    sprintf(url, "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", address, g_UniqueId, salt_hex, g_CertHex);
    PHTTP_DATA data = http_create_data();
    if (data == NULL)
        return GS_OUT_OF_MEMORY;
    else if ((ret = http_request(url, data)) != GS_OK)
        goto cleanup;
    
    unsigned char salt_pin[20];
    unsigned char aes_key_hash[20];
    AES_KEY enc_key, dec_key;
    memcpy(salt_pin, salt_data, 16);
    memcpy(salt_pin+16, pin, 4);
    SHA1(salt_pin, 20, aes_key_hash);
    AES_set_encrypt_key((unsigned char *)aes_key_hash, 128, &enc_key);
    AES_set_decrypt_key((unsigned char *)aes_key_hash, 128, &dec_key);
    
    unsigned char challenge_data[16];
    unsigned char challenge_enc[16];
    char challenge_hex[33];
    RAND_bytes(challenge_data, 16);
    AES_encrypt(challenge_data, challenge_enc, &enc_key);
    bytes_to_hex(challenge_enc, challenge_hex, 16);
    
    sprintf(url, "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&clientchallenge=%s", address, g_UniqueId, challenge_hex);
    if ((ret = http_request(url, data)) != GS_OK)
        goto cleanup;
    
    char *result;
    if (xml_search(data->memory, data->size, "challengeresponse", &result) != GS_OK) {
        ret = GS_INVALID;
        goto cleanup;
    }
    
    unsigned char challenge_response_data_enc[48];
    unsigned char challenge_response_data[48];
    for (int count = 0; count < strlen(result); count += 2) {
        sscanf(&result[count], "%2hhx", &challenge_response_data_enc[count / 2]);
    }
    free(result);
    
    for (int i = 0; i < 48; i += 16) {
        AES_decrypt(&challenge_response_data_enc[i], &challenge_response_data[i], &dec_key);
    }
    
    unsigned char client_secret_data[16];
    RAND_bytes(client_secret_data, 16);
    
    unsigned char challenge_response[16 + 256 + 16];
    unsigned char challenge_response_hash[32];
    unsigned char challenge_response_hash_enc[32];
    char challenge_response_hex[65];
    memcpy(challenge_response, challenge_response_data + 20, 16);
    memcpy(challenge_response + 16, g_Cert->signature->data, 256);
    memcpy(challenge_response + 16 + 256, client_secret_data, 16);
    SHA1(challenge_response, 16 + 256 + 16, challenge_response_hash);
    
    for (int i = 0; i < 32; i += 16) {
        AES_encrypt(&challenge_response_hash[i], &challenge_response_hash_enc[i], &enc_key);
    }
    bytes_to_hex(challenge_response_hash_enc, challenge_response_hex, 32);
    
    sprintf(url, "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&serverchallengeresp=%s", address, g_UniqueId, challenge_response_hex);
    if ((ret = http_request(url, data)) != GS_OK)
        goto cleanup;
    
    if (xml_search(data->memory, data->size, "pairingsecret", &result) != GS_OK) {
        ret = GS_INVALID;
        goto cleanup;
    }
    
    unsigned char *signature = NULL;
    size_t s_len;
    if (sign_it(client_secret_data, 16, &signature, &s_len, g_PrivateKey) != GS_OK) {
        gs_error = "Failed to sign data";
        ret = GS_FAILED;
        goto cleanup;
    }
    
    unsigned char client_pairing_secret[16 + 256];
    char client_pairing_secret_hex[(16 + 256) * 2 + 1];
    memcpy(client_pairing_secret, client_secret_data, 16);
    memcpy(client_pairing_secret + 16, signature, 256);
    bytes_to_hex(client_pairing_secret, client_pairing_secret_hex, 16 + 256);
    
    sprintf(url, "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&clientpairingsecret=%s", address, g_UniqueId, client_pairing_secret_hex);
    if ((ret = http_request(url, data)) != GS_OK)
        goto cleanup;
    
    sprintf(url, "https://%s:47984/pair?uniqueid=%s&devicename=roth&updateState=1&phrase=pairchallenge", address, g_UniqueId);
    if ((ret = http_request(url, data)) != GS_OK)
        goto cleanup;
    
cleanup:
    http_free_data(data);
    
    return ret;
}
Exemple #23
0
char *str_id( const UCHAR id[], char buf[] ) {
	return bytes_to_hex( buf, id, SHA1_BIN_LENGTH );
}
static int rehash_verity(const int meta_version, const int dm_verity_version,
                         const char * data_device, const size_t block_size)
{
	#if 0
    int r = -1;
	char *table, *salt = NULL;

	salt = malloc(32); /* biggest length */
	if (NULL == salt) {
		fprintf(stderr, "Failed to malloc mem for salt\n");
		return -1;
	}
    #endif
    
    int ret = 0;
	  
	uint64_t part_size;
	if(ext4_part_size(TARGET_DEV, &part_size)) {
        printf("failed to get part size.\n");
        return -1;
    }

    const char * tmp_hash_file = TMP_HASH_FILE;
    const char * tmp_hash_table = TMP_HASH_TABLE;
    //unlink(tmp_hash_file);
    //unlink(tmp_hash_table);

    const char * hash_name = HASH_NAME;
    int i;
    char * table = NULL, *p;
    const long data_blocks = part_size / DMVERITY_BLOCK_SIZE;
#ifdef USE_SHA256
    const int digest_size = 32;//sha256
#elif USE_SHA1
    const int digest_size = 20;//sha1
#else
    const int digest_size = 16;//md5
#endif
    char salt[digest_size];
    char root_hash[digest_size];
    const loff_t hash_start = (part_size + DMVERITY_META_SIZE)/DMVERITY_BLOCK_SIZE;
    const loff_t hash_position = DMVERITY_META_SIZE/DMVERITY_BLOCK_SIZE;

    struct verity_meta_header meta_header;
    FILE * fp;

    //0.1 generate random salt
    /* generate_salt(salt); */
    if (generate_salt(salt, digest_size) != digest_size) {
        printf("Error generating random salt.\n");
        // how to handle it better? now it will use whatever compiler gives: all 0's
    }
    
    // 1. generate hash, table and write to a tmp hash file
    if(VERITY_create_hash(dm_verity_version,                  \
                      hash_name,                              \
                      TMP_HASH_FILE,                          \
                      data_device,                             \
                      block_size,                    \
                      block_size,                    \
                      data_blocks,                            \
                      hash_position,                          \
                      (unsigned char *)root_hash,             \
                      digest_size,                            \
                      (const unsigned char *)salt,            \
                      digest_size))
    {
        printf("failed to create hash tree\n");
        ret = -1;
        goto rehash_out;
    }  


    int table_size = nDigits(dm_verity_version) + 1 + strlen(TARGET_DEV) + 1
        + strlen(TARGET_DEV) + 1 + nDigits(DMVERITY_BLOCK_SIZE) + 1
        + nDigits(DMVERITY_BLOCK_SIZE) + 1 + nDigits(data_blocks) + 1
        + nDigits(hash_start) + 1 + strlen(hash_name) + 1 + digest_size * 2
        + 1 + digest_size * 2 + 1;
    table = malloc(table_size);
    if(NULL == table){
        printf("malloc failed\n");
        ret = -1;
        goto rehash_out;
    }
    table[table_size-1] = 0;
    i = sprintf(table, "%d %s %s %lld %lld %lld %lld %s ", dm_verity_version, TARGET_DEV,
                TARGET_DEV, (long long int) DMVERITY_BLOCK_SIZE,
                (long long int) DMVERITY_BLOCK_SIZE, (long long int) data_blocks,
                (long long int) hash_start, hash_name);
    if(i <= 0){
        printf("sprintf error");
        free(table);
        ret = -1;
        goto rehash_out;
    }
    //printf("Table: %s\n", table);
    p = table + i;
    bytes_to_hex(root_hash, p, digest_size);
    p += digest_size * 2;
    p += sprintf(p, " ");
    bytes_to_hex(salt, p, digest_size);
    printf("table: %s", table);
    
    // 2.1 generate meta_header
    meta_header.magic_number = VERITY_METADATA_MAGIC_NUMBER;
    meta_header.protocol_version = 0;
    meta_header.table_length = strlen(table);//not including trailing NULL
    memset(&meta_header.signature, 0, sizeof(meta_header.signature));
    //tmp_hash_file it should have been created by generate_dm_verity_hash already.
    
    // 2.2 write table and meta_header to tmp hash file
    fp = fopen(tmp_hash_file, "r+");
    if (NULL == fp) {
        printf("failed to open temp file\n");
        ret = -1;
        goto rehash_out;
    }
    if(1 != fwrite(&meta_header, sizeof(struct verity_meta_header), 1, fp)){
        printf("failed to write temp file\n");
        fclose(fp);
        ret = -1;
        goto rehash_out;
    }
    printf("write meta_header %d\n", sizeof(struct verity_meta_header));
    if(1 != fwrite(table, meta_header.table_length+1, 1, fp)){
        printf("failed to write temp file\n");
        fclose(fp);
        ret = -1;
        goto rehash_out;
    }
    printf("write table %d\n", meta_header.table_length+1);
    fflush(fp);
    fsync(fileno(fp));
    fclose(fp);

    // 2.3 write table  to tmp hash meta table file
    fp = fopen(tmp_hash_table, "w");
    if (NULL == fp) {
        printf("failed to open temp meta table file\n");
        ret = -1;
        goto rehash_out;
    }
    
    if(1 != fwrite(table, meta_header.table_length+1, 1, fp)){
        printf("failed to write temp meta table file\n");
        fclose(fp);
        ret = -1;
        goto rehash_out;
    }
    printf("write table %d\n", meta_header.table_length+1);
    fflush(fp);
    fsync(fileno(fp));
    fclose(fp);
    
    // 3. write tmp hash file to the /system (not signed)
    /*
    if(file_to_device(tmp_hash_file, TARGET_DEV, 1024*1024, part_size)){
        printf("failed to write hash 001\n");
        goto rehash_out;
    }
    */
rehash_out:
    //unlink(tmp_hash_file);
    if(table)
        free(table);
	return ret;
}
Exemple #25
0
int gs_pair(PSERVER_DATA server, char* pin) {
  int ret = GS_OK;
  char url[4096];
  uuid_t uuid;
  char uuid_str[37];

  if (server->paired) {
    gs_error = "Already paired";
    return GS_WRONG_STATE;
  }

  if (server->currentGame != 0) {
    gs_error = "The computer is currently in a game. You must close the game before pairing";
    return GS_WRONG_STATE;
  }

  unsigned char salt_data[16];
  char salt_hex[33];
  RAND_bytes(salt_data, 16);
  bytes_to_hex(salt_data, salt_hex, 16);

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", server->address, unique_id, uuid_str, salt_hex, cert_hex);
  PHTTP_DATA data = http_create_data();
  if (data == NULL)
    return GS_OUT_OF_MEMORY;
  else if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  unsigned char salt_pin[20];
  unsigned char aes_key_hash[20];
  AES_KEY aes_key;
  memcpy(salt_pin, salt_data, 16);
  memcpy(salt_pin+16, salt_pin, 4);
  SHA1(salt_pin, 20, aes_key_hash);
  AES_set_encrypt_key((unsigned char *)aes_key_hash, 128, &aes_key);

  unsigned char challenge_data[16];
  unsigned char challenge_enc[16];
  char challenge_hex[33];
  RAND_bytes(challenge_data, 16);
  AES_encrypt(challenge_data, challenge_enc, &aes_key);
  bytes_to_hex(challenge_enc, challenge_hex, 16);

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&clientchallenge=%s", server->address, unique_id, uuid_str, challenge_hex);
  if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  char *result;
  if (xml_search(data->memory, data->size, "challengeresponse", &result) != GS_OK) {
    ret = GS_INVALID;
    goto cleanup;
  }

  char challenge_response_data_enc[48];
  char challenge_response_data[48];
  for (int count = 0; count < strlen(result); count++) {
    sscanf(&result[count], "%2hhx", &challenge_response_data_enc[count / 2]);
  }
  free(result);

  for (int i = 0; i < 48; i += 16) {
    AES_decrypt(&challenge_response_data_enc[i], &challenge_response_data[i], &aes_key);
  }

  char client_secret_data[16];
  RAND_bytes(client_secret_data, 16);

  char challenge_response[16 + 256 + 16];
  char challenge_response_hash[32];
  char challenge_response_hash_enc[32];
  char challenge_response_hex[33];
  memcpy(challenge_response, challenge_response_data + 20, 16);
  memcpy(challenge_response + 16, cert->signature->data, 256);
  memcpy(challenge_response + 16 + 256, client_secret_data, 16);
  SHA1(challenge_response, 16 + 256 + 16, challenge_response_hash);

  for (int i = 0; i < 32; i += 16) {
    AES_encrypt(&challenge_response_hash[i], &challenge_response_hash_enc[i], &aes_key);
  }
  bytes_to_hex(challenge_response_hash_enc, challenge_response_hex, 32);

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&serverchallengeresp=%s", server->address, unique_id, uuid_str, challenge_response_hex);
  if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  if (xml_search(data->memory, data->size, "pairingsecret", &result) != GS_OK) {
    ret = GS_INVALID;
    goto cleanup;
  }

  unsigned char *signature = NULL;
  size_t s_len;
  if (sign_it(client_secret_data, 16, &signature, &s_len, privateKey) != GS_OK) {
      gs_error = "Failed to sign data";
      ret = GS_FAILED;
      goto cleanup;
  }

  char client_pairing_secret[16 + 256];
  char client_pairing_secret_hex[(16 + 256) * 2 + 1];
  memcpy(client_pairing_secret, client_secret_data, 16);
  memcpy(client_pairing_secret + 16, signature, 256);
  bytes_to_hex(client_pairing_secret, client_pairing_secret_hex, 16 + 256);

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&clientpairingsecret=%s", server->address, unique_id, uuid_str, client_pairing_secret_hex);
  if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "https://%s:47984/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&phrase=pairchallenge", server->address, unique_id, uuid_str);
  if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  server->paired = true;

  cleanup:
  http_free_data(data);

  return ret;
}
Exemple #26
0
int gs_pair(PSERVER_DATA server, char* pin) {
  int ret = GS_OK;
  char* result = NULL;
  char url[4096];
  uuid_t uuid;
  char uuid_str[37];

  if (server->paired) {
    gs_error = "Already paired";
    return GS_WRONG_STATE;
  }

  if (server->currentGame != 0) {
    gs_error = "The computer is currently in a game. You must close the game before pairing";
    return GS_WRONG_STATE;
  }

  unsigned char salt_data[16];
  char salt_hex[33];
  RAND_bytes(salt_data, 16);
  bytes_to_hex(salt_data, salt_hex, 16);

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", server->address, unique_id, uuid_str, salt_hex, cert_hex);
  PHTTP_DATA data = http_create_data();
  if (data == NULL)
    return GS_OUT_OF_MEMORY;
  else if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  if ((ret = xml_search(data->memory, data->size, "paired", &result)) != GS_OK)
    goto cleanup;

  if (strcmp(result, "1") != 0) {
    gs_error = "Pairing failed";
    ret = GS_FAILED;
    goto cleanup;
  }

  free(result);
  result = NULL;
  if ((ret = xml_search(data->memory, data->size, "plaincert", &result)) != GS_OK)
    goto cleanup;

  if (strlen(result)/2 > 8191) {
    gs_error = "Server certificate too big";
    ret = GS_FAILED;
    goto cleanup;
  }

  char plaincert[8192];
  for (int count = 0; count < strlen(result); count += 2) {
    sscanf(&result[count], "%2hhx", &plaincert[count / 2]);
  }
  plaincert[strlen(result)/2] = '\0';
  printf("%d / %d\n", strlen(result)/2, strlen(plaincert));

  unsigned char salt_pin[20];
  unsigned char aes_key_hash[32];
  AES_KEY enc_key, dec_key;
  memcpy(salt_pin, salt_data, 16);
  memcpy(salt_pin+16, pin, 4);

  int hash_length = server->serverMajorVersion >= 7 ? 32 : 20;
  if (server->serverMajorVersion >= 7)
    SHA256(salt_pin, 20, aes_key_hash);
  else
    SHA1(salt_pin, 20, aes_key_hash);

  AES_set_encrypt_key((unsigned char *)aes_key_hash, 128, &enc_key);
  AES_set_decrypt_key((unsigned char *)aes_key_hash, 128, &dec_key);

  unsigned char challenge_data[16];
  unsigned char challenge_enc[16];
  char challenge_hex[33];
  RAND_bytes(challenge_data, 16);
  AES_encrypt(challenge_data, challenge_enc, &enc_key);
  bytes_to_hex(challenge_enc, challenge_hex, 16);

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&clientchallenge=%s", server->address, unique_id, uuid_str, challenge_hex);
  if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  free(result);
  result = NULL;
  if ((ret = xml_search(data->memory, data->size, "paired", &result)) != GS_OK)
    goto cleanup;

  if (strcmp(result, "1") != 0) {
    gs_error = "Pairing failed";
    ret = GS_FAILED;
    goto cleanup;
  }

  free(result);
  result = NULL;
  if (xml_search(data->memory, data->size, "challengeresponse", &result) != GS_OK) {
    ret = GS_INVALID;
    goto cleanup;
  }

  char challenge_response_data_enc[48];
  char challenge_response_data[48];
  for (int count = 0; count < strlen(result); count += 2) {
    sscanf(&result[count], "%2hhx", &challenge_response_data_enc[count / 2]);
  }

  for (int i = 0; i < 48; i += 16) {
    AES_decrypt(&challenge_response_data_enc[i], &challenge_response_data[i], &dec_key);
  }

  char client_secret_data[16];
  RAND_bytes(client_secret_data, 16);

  char challenge_response[16 + 256 + 16];
  char challenge_response_hash[32];
  char challenge_response_hash_enc[32];
  char challenge_response_hex[65];
  memcpy(challenge_response, challenge_response_data + hash_length, 16);
  memcpy(challenge_response + 16, cert->signature->data, 256);
  memcpy(challenge_response + 16 + 256, client_secret_data, 16);
  if (server->serverMajorVersion >= 7)
    SHA256(challenge_response, 16 + 256 + 16, challenge_response_hash);
  else
    SHA1(challenge_response, 16 + 256 + 16, challenge_response_hash);

  for (int i = 0; i < 32; i += 16) {
    AES_encrypt(&challenge_response_hash[i], &challenge_response_hash_enc[i], &enc_key);
  }
  bytes_to_hex(challenge_response_hash_enc, challenge_response_hex, 32);

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&serverchallengeresp=%s", server->address, unique_id, uuid_str, challenge_response_hex);
  if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  free(result);
  result = NULL;
  if ((ret = xml_search(data->memory, data->size, "paired", &result)) != GS_OK)
    goto cleanup;

  if (strcmp(result, "1") != 0) {
    gs_error = "Pairing failed";
    ret = GS_FAILED;
    goto cleanup;
  }

  free(result);
  result = NULL;
  if (xml_search(data->memory, data->size, "pairingsecret", &result) != GS_OK) {
    ret = GS_INVALID;
    goto cleanup;
  }

  char pairing_secret[16 + 256];
  for (int count = 0; count < strlen(result); count += 2) {
    sscanf(&result[count], "%2hhx", &pairing_secret[count / 2]);
  }

  if (!verifySignature(pairing_secret, 16, pairing_secret+16, 256, plaincert)) {
    gs_error = "MITM attack detected";
    ret = GS_FAILED;
    goto cleanup;
  }

  unsigned char *signature = NULL;
  size_t s_len;
  if (sign_it(client_secret_data, 16, &signature, &s_len, privateKey) != GS_OK) {
      gs_error = "Failed to sign data";
      ret = GS_FAILED;
      goto cleanup;
  }

  char client_pairing_secret[16 + 256];
  char client_pairing_secret_hex[(16 + 256) * 2 + 1];
  memcpy(client_pairing_secret, client_secret_data, 16);
  memcpy(client_pairing_secret + 16, signature, 256);
  bytes_to_hex(client_pairing_secret, client_pairing_secret_hex, 16 + 256);

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "http://%s:47989/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&clientpairingsecret=%s", server->address, unique_id, uuid_str, client_pairing_secret_hex);
  if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  free(result);
  result = NULL;
  if ((ret = xml_search(data->memory, data->size, "paired", &result)) != GS_OK)
    goto cleanup;

  if (strcmp(result, "1") != 0) {
    gs_error = "Pairing failed";
    ret = GS_FAILED;
    goto cleanup;
  }

  uuid_generate_random(uuid);
  uuid_unparse(uuid, uuid_str);
  sprintf(url, "https://%s:47984/pair?uniqueid=%s&uuid=%s&devicename=roth&updateState=1&phrase=pairchallenge", server->address, unique_id, uuid_str);
  if ((ret = http_request(url, data)) != GS_OK)
    goto cleanup;

  free(result);
  result = NULL;
  if ((ret = xml_search(data->memory, data->size, "paired", &result)) != GS_OK)
    goto cleanup;

  if (strcmp(result, "1") != 0) {
    gs_error = "Pairing failed";
    ret = GS_FAILED;
    goto cleanup;
  }

  server->paired = true;

  cleanup:
  if (ret != GS_OK)
    gs_unpair(server);
  
  if (result != NULL)
    free(result);

  http_free_data(data);

  return ret;
}
Exemple #27
0
int main(int argc, char const *argv[]) {
	// Check for arguments
	if (argc < 8) {
		exit_error_f(
			"Usage:\n"
			"%s DEV BLOCK_SIZE JB_TRANSACTIONS HASH_TYPE SALT HMAC_TYPE SECRET lazy|nolazy\n"
			"%s MINT_DEV DATA_DEV BLOCK_SIZE JB_TRANSACTIONS HASH_TYPE SALT HMAC_TYPE SECRET lazy|nolazy\n",
			argv[0], argv[0]);
	}
	const char *dev, *dev2, *hash_type, *hmac_type, *salt_str, *secret_str;
	uint32_t block_size, journal_blocks;
	bool zero;

	if (!strcmp(argv[argc - 1], "lazy")) {
		zero = false;
	} else if (!strcmp(argv[argc - 1], "nolazy")) {
		zero = true;
	} else {
		exit_error_f("Unsupported optional argument: %s", argv[argc - 1]);
	}

	bool two_disks = (argc == 10);

	dev = argv[1];
	dev2 = argv[2];
	hash_type = argv[4 + two_disks];
	salt_str = argv[5 + two_disks];
	hmac_type = argv[6 + two_disks];
	secret_str = argv[7 + two_disks];

	// Open destination device
	int file, file2;
	if ((file = open(dev, O_RDWR)) < 0) {
		exit_error_f("Could not open: '%s' for writing, %s", dev, strerror(errno));
	}

	// Get size
	// TODO: size of file in 512 chunks?
	struct stat file_stats, file_stats2;
	if (fstat(file, &file_stats) != 0) {
		exit_error_f("Could not get file stats for: '%s', %s", dev, strerror(errno));
	}

	if (!(S_ISREG(file_stats.st_mode) || S_ISBLK(file_stats.st_mode))) {
		exit_error_f("File is neither a regular file nor block device");
	}

	if (two_disks) {
		if ((file2 = open(dev2, O_RDWR)) < 0) {
			exit_error_f("Could not open: '%s' for writing, %s", dev2, strerror(errno));
		}

		// Get size
		// TODO: size of file in 512 chunks?
		if (fstat(file2, &file_stats2) != 0) {
			exit_error_f("Could not get file stats for: '%s', %s", dev2, strerror(errno));
		}

		if (!(S_ISREG(file_stats2.st_mode) || S_ISBLK(file_stats2.st_mode))) {
			exit_error_f("File is neither a regular file nor block device");
		}
	}

	// Get block size
	if (sscanf(argv[2 + two_disks], "%u", &block_size) != 1) {
		exit_error_f("Invalid block size: '%s'", argv[2 + two_disks]);
	}
	if (block_size < 512) {
		exit_error_f("Invalid block size: '%u' < 512", block_size);
	}

	// Remainder check
	if (S_ISREG(file_stats.st_mode) && file_stats.st_size % block_size != 0) {
		warn("File is not a multiple of block_size: %d. %ju bytes left over",
			block_size, file_stats.st_size % block_size);
	}
	if (two_disks && S_ISREG(file_stats2.st_mode)
			&& file_stats2.st_size % block_size != 0) {
		warn("File is not a multiple of block_size: %d. %ju bytes left over",
			block_size, file_stats.st_size % block_size);
	}

	// Number of journal blocks
	if (sscanf(argv[3 + two_disks], "%u", &journal_blocks) != 1) {
		exit_error_f("Invalid journal blocks number: '%s'", argv[3 + two_disks]);
	}

	OpenSSL_add_all_digests();

	// Block hash algorithm
	EVP_MD_CTX *mdctx_hash = EVP_MD_CTX_create();
	const EVP_MD *md_hash;
	md_hash = EVP_get_digestbyname(hash_type);
	if (!md_hash) {
		exit_error_f("Unsupported hash type: %s", hash_type);
	}
	uint32_t hash_bytes = EVP_MD_size(md_hash);

	// Hmac algorithm
	const EVP_MD *md_hmac;
	md_hmac = EVP_get_digestbyname(hmac_type);
	if (!md_hmac) {
		exit_error_f("Unsupported hmac type: %s", hmac_type);
	}

	// Parse and check salt
	char salt[128];
	if (strlen(salt_str) % 2 != 0) {
		exit_error_f("Invalid hex salt: length not a multiple of 2");
	}
	if (strlen(salt_str) > 256) {
		exit_error_f("Salt is too long. %lu > %d", strlen(salt_str), 256);
	}
	if (hex_to_bytes(salt_str, strlen(salt_str), (char*)salt) != 0) {
		exit_error_f("Invalid hex salt: '%s'", salt_str);
	}

	// Parse and check secrets
	char secret[hash_bytes];
	if (strlen(secret_str) % 2 != 0) {
		exit_error_f("Invalid hex secret: length not a multiple of 2");
	}
	if (hex_to_bytes(secret_str, strlen(secret_str), (char*)secret) != 0) {
		exit_error_f("Invalid hex inner pad: '%s'", secret_str);
	}

	// Calculate data size, hash block size, journal size
	// TODO: uh...this is 64 bits...
	uint64_t data_blocks = 0;
	uint32_t hash_blocks = 0;
	uint32_t jb_blocks = 0;
	uint32_t pad_blocks = 0;
	uint32_t *blocks_per_level = malloc(sizeof(uint32_t) * DM_MINTEGRITY_MAX_LEVELS);
	uint32_t levels = 0;
	uint64_t blocks, blocks2;

	if (S_ISREG(file_stats.st_mode)) {
		blocks = file_stats.st_size / block_size;
	} else if (S_ISBLK(file_stats.st_mode)) {
		if(ioctl(file, BLKGETSIZE64, &blocks) != 0){
			exit_error_f("ioctl for block size failed: %s", strerror(errno));
		}
		blocks = blocks / block_size;
	}

	if (two_disks) {
		if (S_ISREG(file_stats2.st_mode)) {
			blocks2 = file_stats2.st_size / block_size;
		} else if (S_ISBLK(file_stats2.st_mode)) {
			if(ioctl(file2, BLKGETSIZE64, &blocks2) != 0){
				exit_error_f("ioctl for block size failed: %s", strerror(errno));
			}
			blocks2 = blocks2 / block_size;
		}
	}

	// Fanout
	uint8_t fls, pls = 0;
	uint32_t fanout = block_size / hash_bytes;
	while (fanout > 0) {
		if ((fanout & 1) == 1) {
			fls = pls;
		}
		pls ++;
		fanout = fanout >> 1;
	}
	fanout = 1 << fls;

	// Use up entire block device
	if (!two_disks) {
		compute_block_numbers(blocks, block_size, fanout, journal_blocks, &data_blocks,
			&hash_blocks, &jb_blocks, &pad_blocks, &levels, blocks_per_level, hash_bytes);
	} else {
		jb_blocks = journal_blocks;
		data_blocks = blocks2;
		compute_hash_blocks(blocks2, fanout, &levels, &hash_blocks, blocks_per_level);
		if (hash_blocks + journal_blocks > blocks2) {
			exit_error_f("Need: %u hash + journal blocks, but %s only has %ju",
				hash_blocks + journal_blocks, dev, blocks);
		}
	}
	
	// Result info
	info("Blocks: %ju = Superblock: 1, Data: %ju, Hash: %u, JB: %u, Pad: %u, Levels: %u",
			blocks, data_blocks, hash_blocks, jb_blocks, pad_blocks, levels);

	// Calculate each hash block level
	char **hash_levels = (char**)malloc(sizeof(char*) * levels);
	char hash_output[EVP_MAX_MD_SIZE];
	uint32_t hash_length;
	char *zero_block = (char*)malloc(block_size);
	char *temp_block = (char*)malloc(block_size);
	bzero(zero_block, block_size);

	char buf[128];
	// Data hash
	hash(md_hash, mdctx_hash, zero_block, block_size, salt,
		strlen(salt_str) / 2, hash_output, &hash_length);

	// Now loop through each level
	for (uint32_t i = 0; i < levels; i++) {
		hash_levels[i] = (char*)malloc(block_size);
		// Fill block with hashes - padding is zeros
		bzero(hash_levels[i], block_size);
		for (uint32_t f = 0; f < fanout; f++) {
			for (int b = 0; b < hash_bytes; b++) {
				hash_levels[i][f * (block_size / (1 << fls)) + b] = hash_output[b];
			}
		}
		// Compute hash of this level for next iteration/root
		hash(md_hash, mdctx_hash, hash_levels[i], block_size, salt,
			strlen(salt_str) / 2, hash_output, &hash_length);
	}

	// Write out hash superblock
	struct mint_superblock *msb = malloc(sizeof(struct mint_superblock));
	// Zero out everything
	bzero(msb, sizeof(struct mint_superblock));
	// Magic
	msb->magic = 0x796c694c;
	// Version
	msb->version = 1;
	// Make a new uuid!
	uuid_t uuid;
	uuid_generate(uuid);
	// TODO: is there a better way of doing this?
	memcpy(&msb->uuid, &uuid, 16);
	// Copy hash algorithm name
	strcpy(msb->hash_algorithm, hash_type);
	// Copy hmac algorithm name
	strcpy(msb->hmac_algorithm, hmac_type);
	// Block size!
	msb->block_size = block_size;
	// Set block numbers
	msb->data_blocks = data_blocks;
	msb->hash_blocks = hash_blocks;
	msb->jb_blocks = jb_blocks;
	// Set salt size
	msb->salt_size = strlen(salt_str) / 2;
	// Copy salt
	memcpy(msb->salt, salt, msb->salt_size);
	// Set root hash
	memcpy(msb->root, hash_output, hash_length);
	// Write it out!
	if (write(file, msb, sizeof(struct mint_superblock)) < 0) {
		exit_error_f("Failed to write MSB: %s", strerror(errno));
	}
	if (write(file, zero_block, block_size - 512) < 0) {
		exit_error_f("Failed to write MSB pad: %s", strerror(errno));
	}

	// Big block buffer
	uint32_t multiple = 1024;
	char *big_block = (char*)malloc(block_size * multiple);
	bzero(big_block, block_size * multiple);

	// Write out hash block levels
	uint8_t p = 0;
	info("Writing hash blocks...");
	uint32_t h_written = 1;
	for (int i = levels - 1; i >= 0; i--) {
		// Copy into big buffer
		for (uint32_t m = 0; m < multiple; m++) {
			memcpy(big_block + m * block_size, hash_levels[i], block_size);
		}
		// Write out big buffer
		for (uint32_t j = 0; j < blocks_per_level[i] / multiple; j++) {
			h_written += multiple;
			p = progress(h_written, hash_blocks, 79, p);
			if(write(file, big_block, block_size * multiple) < 0){
				exit_error_f("Failed to write hash block: %u, %s",
					h_written - 1, strerror(errno));
			}
		}
		for (uint32_t j = 0; j < blocks_per_level[i] % multiple; j++) {
			p = progress(h_written++, hash_blocks, 79, p);
			if(write(file, hash_levels[i], block_size) < 0){
				exit_error_f("Failed to write hash block: %u, %s",
					h_written - 1, strerror(errno));
			}
		}
	}
	fprintf(stderr, "\n");

	// Initialize journal
	struct mint_journal_superblock *mjsb = (struct mint_journal_superblock*)
		malloc(sizeof(struct mint_journal_superblock));
	bzero(mjsb, sizeof(struct mint_journal_superblock));
	// Magic
	mjsb->header.magic = MJ_MAGIC;
	// Superblock
	mjsb->header.type = TYPE_MJSB;
	// Number of blocks
	mjsb->blocks = jb_blocks;
	// Head, tail, and fill are 0
	mjsb->head = 0;
	mjsb->tail = 0;
	mjsb->fill = 0;
	mjsb->sequence = 0;
	// Clean
	mjsb->state = 0;

	info("Writing journal...");
	if (write(file, mjsb, sizeof(struct mint_journal_superblock)) < 0) {
		exit_error_f("Failed to write journal superblock:, %s",
		strerror(errno));
	}
	if (write(file, zero_block, block_size - 512) < 0) {
		exit_error_f("Failed to write journal superblock pad: %s", strerror(errno));
	}

	struct mint_journal_header *mjh = (struct mint_journal_header*)
		malloc(sizeof(struct mint_journal_header));
	bzero(mjh, sizeof(struct mint_journal_header));
	// Magic
	mjh->magic = MJ_MAGIC;
	// Nothing block
	mjh->type = TYPE_MJNB;

	// Copy headers into start of every block
	bzero(big_block, block_size * multiple);
	for (uint64_t i = 0; i < multiple; i++) {
		memcpy(big_block + i * block_size, mjh, sizeof(struct mint_journal_header));
	}
	p = 0;
	for (uint64_t i = 0; i < (jb_blocks - 1) / multiple; i++) {
		if(write(file, big_block, block_size * multiple) < 0){
			exit_error_f("Failed to write journal block: %ju, %s", i,
				strerror(errno));
		}
		p = progress(i * multiple + 1, jb_blocks, 79, p);
	}
	for (uint64_t i = 0; i < (jb_blocks - 1) % multiple; i++) {
		if(write(file, big_block, block_size) < 0){
			exit_error_f("Failed to write journal block: %ju, %s", i,
				strerror(errno));
		}
		p = progress(jb_blocks - ((jb_blocks - 1) % multiple) + i + 2, jb_blocks, 79, p);
	}
	fprintf(stderr, "\n");

	// Zero out data
	if (zero) {
		int f = two_disks ? file2 : file;
		bzero(big_block, block_size * multiple);
		info("Writing data blocks...");
		p = 0;
		for (uint64_t i = 0; i < data_blocks / multiple; i++) {
			if(write(f, big_block, block_size * multiple) < 0){
				exit_error_f("Failed to write data block: %ju, %s", i,
					strerror(errno));
			}
			p = progress(i * multiple, data_blocks, 79, p);
		}
		for (uint64_t i = 0; i < data_blocks % multiple; i++) {
			if(write(f, zero_block, block_size) < 0){
				exit_error_f("Failed to write data block: %ju, %s", i,
					strerror(errno));
			}
			p = progress(data_blocks - (data_blocks % multiple) + i + 1,
				data_blocks, 79, p);
		}
		fprintf(stderr, "\n");
	} else {
		info("Skipping disk zeroing...");
	}

	close(file);
	if (two_disks) {
		close(file2);
	}

	print_superblock(msb);
	bytes_to_hex(msb->root, hash_bytes, buf);
	printf("dmsetup create meow --table \"%u %ju mintegrity %s%s%s %u %u %u %ju "
		"%s %s %s %s %s%s\"\n",
		0,             // Start is 0
		data_blocks * (block_size / 512),   // Size of device given to device mapper
		// Mintegrity options
		dev,           // String of block device
		two_disks ? " " : "", two_disks ? dev2 : "",
		block_size,    // Block size
		hash_blocks,   // Number of hash blocks
		jb_blocks,     // Number of journaling blocks
		data_blocks,   // Number of data blocks
		hash_type,     // Hash type
		buf,           // Root digest to verity
		salt_str,      // Salt
		hmac_type,     // Hash type for hmac
		secret_str,    // Hmac secret
		zero ? "" : " lazy"
		);

	free(mjh);
	free(mjsb);
	free(msb);
	free(blocks_per_level);
	free(zero_block);
	free(big_block);
	free(temp_block);
	for (int i = 0; i < levels; i++) {
		free(hash_levels[i]);
	}
	free(hash_levels);
	EVP_MD_CTX_destroy(mdctx_hash);
	return 0;
}