ta/wallet_ta.c
/** Use a combination of cryptographic primitives to deterministically
  * generate a new 256 bit number.
  *
  * The generator uses the algorithm described in
  * https://en.bitcoin.it/wiki/BIP_0032, accessed 12-November-2012 under the
  * "Specification" header. The generator generates uncompressed keys.
  * This function is only used by the TA itself.
  * \param session_data A data pointer to a session context.
  * \param out The generated 256 bit number will be written here.
  * \param seed Should point to a byte array of length #SEED_LENGTH containing
  *             the seed for the pseudo-random number generator. While the
  *             seed can be considered as an arbitrary array of bytes, the
  *             bytes of the array also admit the following interpretation:
  *             the first 32 bytes are the parent private key in big-endian
  *             format, and the next 32 bytes are the chain code (endian
  *             independent).
  * \param num A counter which determines which number the pseudo-random
  *            number generator will output.
  * \param test A boolean to indicate if this function is called for testing
  *				purposes so it can copy the chain code.
  * \param test_chain_code Where the chain code will be copied in a testing case
  * \param test_chain_code_size Size of the test_chain_code.
  * \return false upon success, true if the specified seed is not valid (will
  *         produce degenerate private keys).
  */
Use a combination of cryptographic primitives to deterministically
generate a new 256 bit number.


Use a combination of cryptographic primitives to deterministically generate a new 256 bit number .
static bool generate_deterministic256_internal(Session_data * session_data, BigNum256 out, const uint8_t *seed, const uint32_t num, bool test, BigNum256 test_chain_code, uint32_t test_chain_code_size)
{
	TEE_Result result = TEE_SUCCESS;
    BigNum256 i_l;
    uint8_t k_par[32];
    uint8_t hash[SHA512_HASH_LENGTH];
    uint8_t hmac_message[69]; 
    set_field_to_n_internal(session_data);
    TEE_MemMove((uint8_t*)k_par, (uint8_t*)seed, (uint32_t)32);
    swap_endian256_internal(k_par); 
    big_modulo_internal(session_data, k_par, k_par); 
    if (big_is_zero_internal(k_par))
        return true; 
    if (!(session_data->is_cached_parent_public_key_valid))
        set_parent_public_key_from_private_key_internal(session_data, k_par);
    hmac_message[0] = 0x04;
    TEE_MemMove((uint8_t*)&(hmac_message[1]),
    			(uint8_t*)(session_data->cached_parent_public_key.x),
    			(uint32_t)32);
    swap_endian256_internal(&(hmac_message[1]));
    TEE_MemMove((uint8_t*)&(hmac_message[33]),
    			(uint8_t*)(session_data->cached_parent_public_key.y),
    			(uint32_t)32);
    swap_endian256_internal(&(hmac_message[33]));
    write_u32_big_endian_internal(&(hmac_message[65]), num);
    result = set_hmac_sha512_key_internal(session_data, &(seed[32]), 32);
    if (result != TEE_SUCCESS)
    {
    	#ifdef OP_TEE_TA
    	DMSG("Failed to set the HMAC-SHA-512 operation key: 0x%x", result);
    	#endif
    	return true;
    }
    result = hmac_sha512_internal(session_data,
    							hash,
    							hmac_message,
    							sizeof(hmac_message));
    if (result != TEE_SUCCESS)
    {
    	#ifdef OP_TEE_TA
    	DMSG("Failed to set do HMAC-SHA-512 operation : 0x%x", result);
    	#endif
    	return true;
    }
    set_field_to_n_internal(session_data);
    i_l = (BigNum256)hash;
    swap_endian256_internal(i_l);     
    big_modulo_internal(session_data, i_l, i_l);    
    big_multiply_internal(session_data, out, i_l, k_par);
    if (test)
        TEE_MemMove((BigNum256)test_chain_code,
        			(uint8_t*)&(hash[32]),
        			(uint32_t)test_chain_code_size);
    return false;   
}
static bool generate_deterministic256_internal ( Session_data * session_data , BigNum256 out , const uint8_t * seed , const uint32_t num , bool test , BigNum256 test_chain_code , uint32_t test_chain_code_size ) { TEE_Result result = TEE_SUCCESS ; BigNum256 i_l ; uint8_t k_par [ 32 ] ; uint8_t hash [ SHA512_HASH_LENGTH ] ; uint8_t hmac_message [ 69 ] ; set_field_to_n_internal ( session_data ) ; TEE_MemMove ( ( uint8_t * ) k_par , ( uint8_t * ) seed , ( uint32_t ) 32 ) ; swap_endian256_internal ( k_par ) ; big_modulo_internal ( session_data , k_par , k_par ) ; if ( big_is_zero_internal ( k_par ) ) return true ; if ( ! ( session_data -> is_cached_parent_public_key_valid ) ) set_parent_public_key_from_private_key_internal ( session_data , k_par ) ; hmac_message [ 0 ] = 0x04 ; TEE_MemMove ( ( uint8_t * ) & ( hmac_message [ 1 ] ) , ( uint8_t * ) ( session_data -> cached_parent_public_key . x ) , ( uint32_t ) 32 ) ; swap_endian256_internal ( & ( hmac_message [ 1 ] ) ) ; TEE_MemMove ( ( uint8_t * ) & ( hmac_message [ 33 ] ) , ( uint8_t * ) ( session_data -> cached_parent_public_key . y ) , ( uint32_t ) 32 ) ; swap_endian256_internal ( & ( hmac_message [ 33 ] ) ) ; write_u32_big_endian_internal ( & ( hmac_message [ 65 ] ) , num ) ; result = set_hmac_sha512_key_internal ( session_data , & ( seed [ 32 ] ) , 32 ) ; if ( result != TEE_SUCCESS ) { #ifdef OP_TEE_TA DMSG ( " " , result ) ; #endif return true ; } result = hmac_sha512_internal ( session_data , hash , hmac_message , sizeof ( hmac_message ) ) ; if ( result != TEE_SUCCESS ) { #ifdef OP_TEE_TA DMSG ( " " , result ) ; #endif return true ; } set_field_to_n_internal ( session_data ) ; i_l = ( BigNum256 ) hash ; swap_endian256_internal ( i_l ) ; big_modulo_internal ( session_data , i_l , i_l ) ; big_multiply_internal ( session_data , out , i_l , k_par ) ; if ( test ) TEE_MemMove ( ( BigNum256 ) test_chain_code , ( uint8_t * ) & ( hash [ 32 ] ) , ( uint32_t ) test_chain_code_size ) ; return false ; }
Use a combination of cryptographic primitives to deterministically
 generate a new 256 bit number.
Use a combination of cryptographic primitives to deterministically generate a new 256 bit number .
/* 04 (1 byte) + x (32 bytes) + y (32 bytes) + num (4 bytes) */ /* Since seed is big-endian */ /* Just in case */ /*
     * k_par cannot be 0. If it is zero, then the output of this generator
     * will always be 0.
     */ /* Invalid seed */ /*
     * BIP 0032 specifies that the public key should be represented in a way
     * that is compatible with "SEC 1: Elliptic Curve Cryptography" by
     * Certicom research, obtained 15-August-2011 from:
     * http://www.secg.org/collateral/sec1_final.pdf section 2.3 ("Data Types
     * and Conversions"). The gist of it is: 0x04, followed by x, then y in
     * big-endian format.
     * TODO: Remove this all and implement updated BIP 32
     */ /* Since hash is big-endian */ /* Just in case */ /* Success */