2014-04-29 12:26:51 +00:00
/*
2017-11-05 16:46:34 +00:00
* This file is part of the TREZOR project , https : //trezor.io/
2014-04-29 12:26:51 +00:00
*
* Copyright ( C ) 2014 Pavol Rusnak < stick @ satoshilabs . com >
*
* This library is free software : you can redistribute it and / or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "reset.h"
2019-01-25 10:58:23 +00:00
# include "config.h"
2014-04-29 12:26:51 +00:00
# include "rng.h"
# include "sha2.h"
# include "messages.h"
# include "fsm.h"
# include "layout2.h"
# include "protect.h"
# include "bip39.h"
# include "util.h"
2017-06-18 20:22:33 +00:00
# include "gettext.h"
2018-07-10 14:58:00 +00:00
# include "messages.pb.h"
2019-01-23 16:00:01 +00:00
# include "memzero.h"
2014-04-29 12:26:51 +00:00
static uint32_t strength ;
static uint8_t int_entropy [ 32 ] ;
static bool awaiting_entropy = false ;
2017-06-26 17:17:40 +00:00
static bool skip_backup = false ;
2018-10-04 15:19:37 +00:00
static bool no_backup = false ;
2014-04-29 12:26:51 +00:00
2018-10-04 15:19:37 +00:00
void reset_init ( bool display_random , uint32_t _strength , bool passphrase_protection , bool pin_protection , const char * language , const char * label , uint32_t u2f_counter , bool _skip_backup , bool _no_backup )
2014-04-29 12:26:51 +00:00
{
2016-11-22 20:39:33 +00:00
if ( _strength ! = 128 & & _strength ! = 192 & & _strength ! = 256 ) return ;
2014-04-29 12:26:51 +00:00
strength = _strength ;
2017-06-26 17:17:40 +00:00
skip_backup = _skip_backup ;
2018-10-04 15:19:37 +00:00
no_backup = _no_backup ;
2014-04-29 12:26:51 +00:00
2018-10-11 13:24:40 +00:00
if ( display_random & & ( skip_backup | | no_backup ) ) {
2018-10-11 13:27:03 +00:00
fsm_sendFailure ( FailureType_Failure_ProcessError , " Can't show internal entropy when backup is skipped " ) ;
2018-10-08 13:37:53 +00:00
layoutHome ( ) ;
return ;
}
2018-12-10 17:46:05 +00:00
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " create a new wallet? " ) , NULL , _ ( " By continuing you " ) , _ ( " agree to trezor.io/tos " ) , NULL ) ;
2018-10-22 12:39:49 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
layoutHome ( ) ;
return ;
}
2014-04-29 12:26:51 +00:00
random_buffer ( int_entropy , 32 ) ;
char ent_str [ 4 ] [ 17 ] ;
data2hex ( int_entropy , 8 , ent_str [ 0 ] ) ;
data2hex ( int_entropy + 8 , 8 , ent_str [ 1 ] ) ;
data2hex ( int_entropy + 16 , 8 , ent_str [ 2 ] ) ;
data2hex ( int_entropy + 24 , 8 , ent_str [ 3 ] ) ;
if ( display_random ) {
2017-06-18 20:22:33 +00:00
layoutDialogSwipe ( & bmp_icon_info , _ ( " Cancel " ) , _ ( " Continue " ) , NULL , _ ( " Internal entropy: " ) , ent_str [ 0 ] , ent_str [ 1 ] , ent_str [ 2 ] , ent_str [ 3 ] , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ResetDevice , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2014-04-29 12:26:51 +00:00
layoutHome ( ) ;
return ;
}
}
2019-01-25 10:58:23 +00:00
if ( pin_protection & & ! protectChangePin ( false ) ) {
2014-04-29 12:26:51 +00:00
layoutHome ( ) ;
return ;
}
2019-01-25 10:58:23 +00:00
config_setPassphraseProtection ( passphrase_protection ) ;
config_setLanguage ( language ) ;
config_setLabel ( label ) ;
config_setU2FCounter ( u2f_counter ) ;
2014-04-29 12:26:51 +00:00
EntropyRequest resp ;
2019-01-23 16:00:01 +00:00
memzero ( & resp , sizeof ( EntropyRequest ) ) ;
2014-04-29 12:26:51 +00:00
msg_write ( MessageType_MessageType_EntropyRequest , & resp ) ;
awaiting_entropy = true ;
}
void reset_entropy ( const uint8_t * ext_entropy , uint32_t len )
{
if ( ! awaiting_entropy ) {
2018-08-27 17:06:11 +00:00
fsm_sendFailure ( FailureType_Failure_UnexpectedMessage , _ ( " Not in Reset mode " ) ) ;
2014-04-29 12:26:51 +00:00
return ;
}
2019-02-12 14:46:28 +00:00
awaiting_entropy = false ;
2019-02-05 19:40:58 +00:00
2014-04-29 12:26:51 +00:00
SHA256_CTX ctx ;
sha256_Init ( & ctx ) ;
sha256_Update ( & ctx , int_entropy , 32 ) ;
sha256_Update ( & ctx , ext_entropy , len ) ;
2016-04-26 09:53:58 +00:00
sha256_Final ( & ctx , int_entropy ) ;
2019-01-25 10:58:23 +00:00
const char * mnemonic = mnemonic_from_data ( int_entropy , strength / 8 ) ;
2019-01-23 16:00:01 +00:00
memzero ( int_entropy , 32 ) ;
2014-04-29 12:26:51 +00:00
2018-10-04 15:19:37 +00:00
if ( skip_backup | | no_backup ) {
2019-02-12 14:46:28 +00:00
if ( no_backup ) {
config_setNoBackup ( ) ;
} else {
config_setNeedsBackup ( true ) ;
}
if ( config_setMnemonic ( mnemonic ) ) {
fsm_sendSuccess ( _ ( " Device successfully initialized " ) ) ;
} else {
fsm_sendFailure ( FailureType_Failure_ProcessError , _ ( " Failed to store mnemonic " ) ) ;
}
2017-06-26 17:17:40 +00:00
layoutHome ( ) ;
} else {
2019-01-25 10:58:23 +00:00
reset_backup ( false , mnemonic ) ;
2017-06-26 17:17:40 +00:00
}
2019-02-12 14:46:28 +00:00
mnemonic_clear ( ) ;
2017-06-26 17:17:40 +00:00
}
2017-09-04 06:12:33 +00:00
static char current_word [ 10 ] ;
2017-06-26 17:17:40 +00:00
2017-06-28 09:25:47 +00:00
// separated == true if called as a separate workflow via BackupMessage
2019-01-25 10:58:23 +00:00
void reset_backup ( bool separated , const char * mnemonic )
2017-06-26 17:17:40 +00:00
{
2017-11-03 19:48:28 +00:00
if ( separated ) {
2019-02-12 14:46:28 +00:00
bool needs_backup = false ;
config_getNeedsBackup ( & needs_backup ) ;
if ( ! needs_backup ) {
fsm_sendFailure ( FailureType_Failure_UnexpectedMessage , _ ( " Seed already backed up " ) ) ;
return ;
}
config_setUnfinishedBackup ( true ) ;
config_setNeedsBackup ( false ) ;
2017-11-03 19:48:28 +00:00
}
2017-07-05 10:17:46 +00:00
2017-07-23 20:20:51 +00:00
for ( int pass = 0 ; pass < 2 ; pass + + ) {
2017-08-07 14:34:07 +00:00
int i = 0 , word_pos = 1 ;
2017-08-22 07:17:05 +00:00
while ( mnemonic [ i ] ! = 0 ) {
2014-04-29 12:26:51 +00:00
// copy current_word
2017-07-23 20:20:51 +00:00
int j = 0 ;
2017-08-22 07:17:05 +00:00
while ( mnemonic [ i ] ! = ' ' & & mnemonic [ i ] ! = 0 & & j + 1 < ( int ) sizeof ( current_word ) ) {
current_word [ j ] = mnemonic [ i ] ;
2014-04-29 12:26:51 +00:00
i + + ; j + + ;
}
2017-08-07 14:34:07 +00:00
current_word [ j ] = 0 ;
2017-08-22 07:17:05 +00:00
if ( mnemonic [ i ] ! = 0 ) {
2017-08-07 14:34:07 +00:00
i + + ;
}
2017-08-22 07:17:05 +00:00
layoutResetWord ( current_word , pass , word_pos , mnemonic [ i ] = = 0 ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ConfirmWord , true ) ) {
2017-06-28 09:25:47 +00:00
if ( ! separated ) {
2017-08-22 17:00:25 +00:00
session_clear ( true ) ;
2017-06-28 09:25:47 +00:00
}
2014-04-29 12:26:51 +00:00
layoutHome ( ) ;
2018-08-27 17:06:11 +00:00
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2014-04-29 12:26:51 +00:00
return ;
}
2017-08-07 14:34:07 +00:00
word_pos + + ;
2014-04-29 12:26:51 +00:00
}
}
2017-06-28 09:25:47 +00:00
2019-01-25 10:58:23 +00:00
config_setUnfinishedBackup ( false ) ;
2018-04-04 10:42:52 +00:00
2017-06-28 09:25:47 +00:00
if ( separated ) {
fsm_sendSuccess ( _ ( " Seed successfully backed up " ) ) ;
} else {
2019-02-12 14:46:28 +00:00
config_setNeedsBackup ( false ) ;
if ( config_setMnemonic ( mnemonic ) ) {
fsm_sendSuccess ( _ ( " Device successfully initialized " ) ) ;
} else {
fsm_sendFailure ( FailureType_Failure_ProcessError , _ ( " Failed to store mnemonic " ) ) ;
}
2017-06-28 09:25:47 +00:00
}
2014-04-29 12:26:51 +00:00
layoutHome ( ) ;
}
2015-08-24 12:42:11 +00:00
# if DEBUG_LINK
2014-04-29 12:26:51 +00:00
uint32_t reset_get_int_entropy ( uint8_t * entropy ) {
memcpy ( entropy , int_entropy , 32 ) ;
return 32 ;
}
const char * reset_get_word ( void ) {
return current_word ;
}
2015-08-24 12:42:11 +00:00
# endif