Exemple #1
0
// passphrase must be at most 256 characters or code may crash
void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed[512 / 8], void (*progress_callback)(uint32_t current, uint32_t total))
{
	int passphraselen = strlen(passphrase);
#if USE_BIP39_CACHE
	int mnemoniclen = strlen(mnemonic);
	// check cache
	if (mnemoniclen < 256 && passphraselen < 64) {
		int i;
		for (i = 0; i < BIP39_CACHE_SIZE; i++) {
			if (!bip39_cache[i].set) continue;
			if (strcmp(bip39_cache[i].mnemonic, mnemonic) != 0) continue;
			if (strcmp(bip39_cache[i].passphrase, passphrase) != 0) continue;
			// found the correct entry
			memcpy(seed, bip39_cache[i].seed, 512 / 8);
			return;
		}
	}
#endif
	uint8_t salt[8 + 256 + 4];
	memcpy(salt, "mnemonic", 8);
	memcpy(salt + 8, passphrase, passphraselen);
	pbkdf2_hmac_sha512((const uint8_t *)mnemonic, strlen(mnemonic), salt, passphraselen + 8, BIP39_PBKDF2_ROUNDS, seed, 512 / 8, progress_callback);
#if USE_BIP39_CACHE
	// store to cache
	if (mnemoniclen < 256 && passphraselen < 64) {
		bip39_cache[bip39_cache_index].set = true;
		strcpy(bip39_cache[bip39_cache_index].mnemonic, mnemonic);
		strcpy(bip39_cache[bip39_cache_index].passphrase, passphrase);
		memcpy(bip39_cache[bip39_cache_index].seed, seed, 512 / 8);
		bip39_cache_index = (bip39_cache_index + 1) % BIP39_CACHE_SIZE;
	}
#endif
}
Exemple #2
0
bool storage_getRootNode(HDNode *node)
{
	// root node is properly cached
	if (sessionRootNodeCached) {
		memcpy(node, &sessionRootNode, sizeof(HDNode));
		return true;
	}

	// if storage has node, decrypt and use it
	if (storage.has_node) {
		if (!protectPassphrase()) {
			return false;
		}
		if (hdnode_from_xprv(storage.node.depth, storage.node.fingerprint, storage.node.child_num, storage.node.chain_code.bytes, storage.node.private_key.bytes, &sessionRootNode) == 0) {
			return false;
		}
		if (storage.has_passphrase_protection && storage.passphrase_protection && strlen(sessionPassphrase)) {
			// decrypt hd node
			uint8_t secret[64];
			uint8_t salt[12];
			memcpy(salt, "TREZORHD", 8);
			layoutProgressSwipe("Waking up", 0);
			pbkdf2_hmac_sha512((const uint8_t *)sessionPassphrase, strlen(sessionPassphrase), salt, 8, BIP39_PBKDF2_ROUNDS, secret, 64, get_root_node_callback);
			aes_decrypt_ctx ctx;
			aes_decrypt_key256(secret, &ctx);
			aes_cbc_decrypt(sessionRootNode.chain_code, sessionRootNode.chain_code, 32, secret + 32, &ctx);
			aes_cbc_decrypt(sessionRootNode.private_key, sessionRootNode.private_key, 32, secret + 32, &ctx);
		}
		memcpy(node, &sessionRootNode, sizeof(HDNode));
		sessionRootNodeCached = true;
		return true;
	}

	// if storage has mnemonic, convert it to node and use it
	if (storage.has_mnemonic) {
		if (!protectPassphrase()) {
			return false;
		}
		uint8_t seed[64];
		layoutProgressSwipe("Waking up", 0);
		mnemonic_to_seed(storage.mnemonic, sessionPassphrase, seed, get_root_node_callback); // BIP-0039
		if (hdnode_from_seed(seed, sizeof(seed), &sessionRootNode) == 0) {
			return false;
		}
		memcpy(node, &sessionRootNode, sizeof(HDNode));
		sessionRootNodeCached = true;
		return true;
	}

	return false;
}
Exemple #3
0
int main()
{
	uint8_t check[64];
	int i;

	/* test pbkdf2 */
	for (i = 0; i < tablenum; i++) {
		pbkdf2_hmac_sha512(check, 64,
				   (uint8_t*)table[i].passwd, strlen(table[i].passwd),
				   (uint8_t*)table[i].salt, strlen(table[i].salt),
				   table[i].c);

		if (memcmp(check, table[i].dk, 64) != 0) {
			printf("test nr. %d failed\n", i+1);
			printvec("is", check, 64);
			printvec("should", table[i].dk, 64);
			return 1;
		}
	}

	return 0;
}
Exemple #4
0
/*
 * storage_get_root_node() - Returns root node of device
 *
 * INPUT
 *     - node: where to put the node that is found
 * OUTPUT
 *     true/false whether root node was found
 */
bool storage_get_root_node(HDNode *node)
{
    // root node is properly cached
    if(sessionRootNodeCached)
    {
        memcpy(node, &sessionRootNode, sizeof(HDNode));
        return true;
    }

    // if storage has node, decrypt and use it
    if(shadow_config.storage.has_node)
    {
        if(!passphrase_protect())
        {
            return false;
        }

        layout_loading();

        if(hdnode_from_xprv(shadow_config.storage.node.depth,
                            shadow_config.storage.node.fingerprint,
                            shadow_config.storage.node.child_num,
                            shadow_config.storage.node.chain_code.bytes,
                            shadow_config.storage.node.private_key.bytes,
                            &sessionRootNode) == 0)
        {
            return false;
        }

        if(shadow_config.storage.has_passphrase_protection &&
                shadow_config.storage.passphrase_protection && strlen(sessionPassphrase))
        {
            // decrypt hd node
            uint8_t secret[64];

            /* Length of salt + 4 bytes are needed as workspace by pbkdf2_hmac_sha512 */
            uint8_t salt[strlen(PBKDF2_HMAC_SHA512_SALT) + 4];
            memcpy((char *)salt, PBKDF2_HMAC_SHA512_SALT, strlen(PBKDF2_HMAC_SHA512_SALT));

            animating_progress_handler();

            pbkdf2_hmac_sha512((const uint8_t *)sessionPassphrase,
                               strlen(sessionPassphrase),
                               salt, strlen(PBKDF2_HMAC_SHA512_SALT), BIP39_PBKDF2_ROUNDS, secret, 64,
                               get_root_node_callback);

            aes_decrypt_ctx ctx;
            aes_decrypt_key256(secret, &ctx);
            aes_cbc_decrypt(sessionRootNode.chain_code, sessionRootNode.chain_code, 32,
                            secret + 32,
                            &ctx);
            aes_cbc_decrypt(sessionRootNode.private_key, sessionRootNode.private_key, 32,
                            secret + 32,
                            &ctx);
        }

        memcpy(node, &sessionRootNode, sizeof(HDNode));
        sessionRootNodeCached = true;
        return true;
    }

    // if storage has mnemonic, convert it to node and use it
    if(shadow_config.storage.has_mnemonic)
    {
        if(!passphrase_protect())
        {
            return false;
        }

        if(storage_get_root_node_cache(node))
        {
            return true;
        }

        layout_loading();

        uint8_t seed[64];

        animating_progress_handler();

        mnemonic_to_seed(shadow_config.storage.mnemonic, sessionPassphrase, seed,
                         get_root_node_callback); // BIP-0039

        if(hdnode_from_seed(seed, sizeof(seed), &sessionRootNode) == 0)
        {
            return false;
        }

        storage_set_root_node_cache(&sessionRootNode);

        memcpy(node, &sessionRootNode, sizeof(HDNode));
        sessionRootNodeCached = true;
        return true;
    }

    return false;
}