aes_rval aes_decrypt_key(const void *in_key, int key_len, aes_decrypt_ctx cx[1])
{
    switch(key_len)
    {
#ifdef AES_ERR_CHK
    case 16: case 128: return aes_decrypt_key128(in_key, cx);
    case 24: case 192: return aes_decrypt_key192(in_key, cx);
    case 32: case 256: return aes_decrypt_key256(in_key, cx);
    default: return aes_error;
#else
    case 16: case 128: aes_decrypt_key128(in_key, cx); return;
    case 24: case 192: aes_decrypt_key192(in_key, cx); return;
    case 32: case 256: aes_decrypt_key256(in_key, cx); return;
#endif
    }
}
Пример #2
0
aes_rval aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
{
    switch(key_len)
    {
#if defined( AES_ERR_CHK )
    case 16: case 128: return aes_decrypt_key128(key, cx);
    case 24: case 192: return aes_decrypt_key192(key, cx);
    case 32: case 256: return aes_decrypt_key256(key, cx);
    default: return aes_error;
#else
    case 16: case 128: aes_decrypt_key128(key, cx); return;
    case 24: case 192: aes_decrypt_key192(key, cx); return;
    case 32: case 256: aes_decrypt_key256(key, cx); return;
#endif
    }
}
Пример #3
0
/* Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal) */
int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
{
	int retVal = ERR_SUCCESS;

	switch (cipher)
	{
	case AES:
#ifndef TC_WINDOWS_BOOT
		if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
			return ERR_CIPHER_INIT_FAILURE;

		if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx))) != EXIT_SUCCESS)
			return ERR_CIPHER_INIT_FAILURE;
#else
		if (aes_set_key (key, (length_type) CipherGetKeySize(AES), (aes_context *) ks) != 0)
			return ERR_CIPHER_INIT_FAILURE;
#endif
		break;

	case SERPENT:
		serpent_set_key (key, CipherGetKeySize(SERPENT) * 8, ks);
		break;
		
	case TWOFISH:
		twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, CipherGetKeySize(TWOFISH) * 8);
		break;

#ifndef TC_WINDOWS_BOOT
		
	case BLOWFISH:
		/* Deprecated/legacy */
		BlowfishSetKey ((BF_KEY *)ks, CipherGetKeySize(BLOWFISH), key);
		break;

	case CAST:
		/* Deprecated/legacy */
		Cast5SetKey ((CAST_KEY *) ks, CipherGetKeySize(CAST), key);
		break;

	case TRIPLEDES:
		/* Deprecated/legacy */
		TripleDesSetKey (key, CipherGetKeySize (TRIPLEDES), (TDES_KEY *) ks);

		// Verify whether all three DES keys are mutually different
		if (((*((__int64 *) key) ^ *((__int64 *) key+1)) & 0xFEFEFEFEFEFEFEFEULL) == 0
		|| ((*((__int64 *) key+1) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0
		|| ((*((__int64 *) key) ^ *((__int64 *) key+2)) & 0xFEFEFEFEFEFEFEFEULL) == 0)
			retVal = ERR_CIPHER_INIT_WEAK_KEY;		// Non-fatal error

		break;

#endif	// TC_WINDOWS_BOOT

	default:
		// Unknown/wrong cipher ID
		return ERR_CIPHER_INIT_FAILURE;
	}

	return retVal;
}
Пример #4
0
/* Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal) */
int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
{
	int retVal = ERR_SUCCESS;

	switch (cipher)
	{
	case AES:
#ifndef TC_WINDOWS_BOOT
		if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
			return ERR_CIPHER_INIT_FAILURE;

		if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx))) != EXIT_SUCCESS)
			return ERR_CIPHER_INIT_FAILURE;
#else
		if (aes_set_key (key, (length_type) CipherGetKeySize(AES), (aes_context *) ks) != 0)
			return ERR_CIPHER_INIT_FAILURE;
#endif
		break;

	case SERPENT:
		serpent_set_key (key, ks);
		break;
		
	case TWOFISH:
		twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key);
		break;

	default:
		// Unknown/wrong cipher ID
		return ERR_CIPHER_INIT_FAILURE;
	}

	return retVal;
}
Пример #5
0
	void CipherAES::SetCipherKey (const byte *key)
	{
		if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ScheduledKey.Ptr()) != EXIT_SUCCESS)
			throw CipherInitError (SRC_POS);

		if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
			throw CipherInitError (SRC_POS);
	}
Пример #6
0
void fsm_msgCipherKeyValue(CipherKeyValue *msg)
{
	if (!msg->has_key) {
		fsm_sendFailure(FailureType_Failure_SyntaxError, "No key provided");
		return;
	}
	if (!msg->has_value) {
		fsm_sendFailure(FailureType_Failure_SyntaxError, "No value provided");
		return;
	}
	if (msg->value.size % 16) {
		fsm_sendFailure(FailureType_Failure_SyntaxError, "Value length must be a multiple of 16");
		return;
	}
	if (!protectPin(true)) {
		layoutHome();
		return;
	}
	HDNode *node = fsm_getRootNode();
	if (!node) return;
	fsm_deriveKey(node, msg->address_n, msg->address_n_count);

	bool encrypt = msg->has_encrypt && msg->encrypt;
	bool ask_on_encrypt = msg->has_ask_on_encrypt && msg->ask_on_encrypt;
	bool ask_on_decrypt = msg->has_ask_on_decrypt && msg->ask_on_decrypt;
	if ((encrypt && ask_on_encrypt) || (!encrypt && ask_on_decrypt)) {
		layoutCipherKeyValue(encrypt, msg->key);
		if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
			fsm_sendFailure(FailureType_Failure_ActionCancelled, "CipherKeyValue cancelled");
			layoutHome();
			return;
		}
	}

	uint8_t data[256 + 4];
	strlcpy((char *)data, msg->key, sizeof(data));
	strlcat((char *)data, ask_on_encrypt ? "E1" : "E0", sizeof(data));
	strlcat((char *)data, ask_on_decrypt ? "D1" : "D0", sizeof(data));

	hmac_sha512(node->private_key, 32, data, strlen((char *)data), data);

	RESP_INIT(Success);
	if (encrypt) {
		aes_encrypt_ctx ctx;
		aes_encrypt_key256(data, &ctx);
		aes_cbc_encrypt(msg->value.bytes, resp->payload.bytes, msg->value.size, data + 32, &ctx);
	} else {
		aes_decrypt_ctx ctx;
		aes_decrypt_key256(data, &ctx);
		aes_cbc_decrypt(msg->value.bytes, resp->payload.bytes, msg->value.size, data + 32, &ctx);
	}
	resp->has_payload = true;
	resp->payload.size = msg->value.size;
	msg_write(MessageType_MessageType_Success, resp);
	layoutHome();
}
Пример #7
0
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
{
	switch(key_len)
	{
	case 16: case 128: return aes_decrypt_key128(key, cx);
	case 24: case 192: return aes_decrypt_key192(key, cx);
	case 32: case 256: return aes_decrypt_key256(key, cx);
	default: return EXIT_FAILURE;
	}
}
Пример #8
0
int EAInit (unsigned char *key, unsigned __int8 *ks)
{
	aes_init();

	if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
		return ERR_CIPHER_INIT_FAILURE;
	if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
		return ERR_CIPHER_INIT_FAILURE;

	return ERR_SUCCESS;
}
Пример #9
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;
}
Пример #10
0
int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
{
#ifdef GST_WINDOWS_BOOT_AES

	aes_init();

	if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
		return ERR_CIPHER_INIT_FAILURE;
	if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
		return ERR_CIPHER_INIT_FAILURE;

#elif defined (GST_WINDOWS_BOOT_SERPENT)
	serpent_set_key (key, 32 * 8, ks);
#elif defined (GST_WINDOWS_BOOT_TWOFISH)
	twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, 32 * 8);
#endif
	return ERR_SUCCESS;
}
Пример #11
0
/*
 * Expand the cipher key into the decryption key schedule.
 *
 * Return the number of rounds for the given cipher key size.
 * The size of the key schedule depends on the number of rounds
 * (which can be computed from the size of the key), i.e. 4 * (Nr + 1).
 *
 * Parameters:
 * rk		AES key schedule 32-bit array to be initialized
 * cipherKey	User key
 * keyBits	AES key size (128, 192, or 256 bits)
 */
int
rijndael_key_setup_dec_amd64(uint32_t rk[], const uint32_t cipherKey[],
	int keyBits)
{
	switch (keyBits) {
	case 128:
		aes_decrypt_key128((unsigned char *)&cipherKey[0], rk);
		return (10);
	case 192:
		aes_decrypt_key192((unsigned char *)&cipherKey[0], rk);
		return (12);
	case 256:
		aes_decrypt_key256((unsigned char *)&cipherKey[0], rk);
		return (14);
	default: /* should never get here */
		break;
	}

	return (0);
}
Пример #12
0
static bool 
aes_operation(bool encrypt, const uint8_t *kek, size_t kek_len, uint8_t *block)
{
    uint64_t iv[2] = { 0 };

    if (encrypt) {
        aes_encrypt_ctx encrypt_ctx[1];
        switch(kek_len) {
#if AES128_KEK
            case 16: aes_encrypt_key128(kek, encrypt_ctx); break;
#endif
#if AES192_KEK
            case 24: aes_encrypt_key192(kek, encrypt_ctx); break;
#endif
#if AES256_KEK
            case 32: aes_encrypt_key256(kek, encrypt_ctx); break;
#endif
            default: return false;
        }
        aes_encrypt_cbc(block, (uint8_t*)iv, 1, block, encrypt_ctx);
    } else {
        aes_decrypt_ctx decrypt_ctx[1];
        switch(kek_len) {
#if AES128_KEK
            case 16: aes_decrypt_key128(kek, decrypt_ctx); break;
#endif
#if AES192_KEK
            case 24: aes_decrypt_key192(kek, decrypt_ctx); break;
#endif
#if AES256_KEK
            case 32: aes_decrypt_key256(kek, decrypt_ctx); break;
#endif
            default: return false;
        }
        aes_decrypt_cbc(block, (uint8_t*)iv, 1, block, decrypt_ctx);
    }

    return true;
}
Пример #13
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;
}
Пример #14
0
void fsm_msgCipherKeyValue(CipherKeyValue *msg)
{

	if (!storage_is_initialized()) 
    {
		fsm_sendFailure(FailureType_Failure_NotInitialized, "Device not initialized");
		return;
	}

    if(!msg->has_key)
    {
        fsm_sendFailure(FailureType_Failure_SyntaxError, "No key provided");
        return;
    }

    if(!msg->has_value)
    {
        fsm_sendFailure(FailureType_Failure_SyntaxError, "No value provided");
        return;
    }

    if(msg->value.size % 16)
    {
        fsm_sendFailure(FailureType_Failure_SyntaxError,
                        "Value length must be a multiple of 16");
        return;
    }

    if(!pin_protect_cached())
    {
        go_home();
        return;
    }

    const HDNode *node = fsm_getDerivedNode(msg->address_n, msg->address_n_count);

    if(!node) { return; }

    bool encrypt = msg->has_encrypt && msg->encrypt;
    bool ask_on_encrypt = msg->has_ask_on_encrypt && msg->ask_on_encrypt;
    bool ask_on_decrypt = msg->has_ask_on_decrypt && msg->ask_on_decrypt;

    if((encrypt && ask_on_encrypt) || (!encrypt && ask_on_decrypt))
    {
        if(!confirm_cipher(encrypt, msg->key))
        {
            fsm_sendFailure(FailureType_Failure_ActionCancelled,
                            "CipherKeyValue cancelled");
            go_home();
            return;
        }
    }

    uint8_t data[256 + 4];
    strlcpy((char *)data, msg->key, sizeof(data));
    strlcat((char *)data, ask_on_encrypt ? "E1" : "E0", sizeof(data));
    strlcat((char *)data, ask_on_decrypt ? "D1" : "D0", sizeof(data));

    hmac_sha512(node->private_key, 32, data, strlen((char *)data), data);

    RESP_INIT(CipheredKeyValue);

    if(encrypt)
    {
        aes_encrypt_ctx ctx;
        aes_encrypt_key256(data, &ctx);
        aes_cbc_encrypt(msg->value.bytes, resp->value.bytes, msg->value.size,
                        ((msg->iv.size == 16) ? (msg->iv.bytes) : (data + 32)), &ctx);
    }
    else
    {
        aes_decrypt_ctx ctx;
        aes_decrypt_key256(data, &ctx);
        aes_cbc_decrypt(msg->value.bytes, resp->value.bytes, msg->value.size,
                        ((msg->iv.size == 16) ? (msg->iv.bytes) : (data + 32)), &ctx);
    }

    resp->has_value = true;
    resp->value.size = msg->value.size;
    msg_write(MessageType_MessageType_CipheredKeyValue, resp);
    go_home();
}