2018-09-06 16:28:56 +00:00
/*
* This file is part of the TREZOR project , https : //trezor.io/
*
* Copyright ( C ) 2018 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/>.
*/
2018-09-14 12:40:29 +00:00
void fsm_msgInitialize ( const Initialize * msg )
2018-05-03 14:47:37 +00:00
{
recovery_abort ( ) ;
signing_abort ( ) ;
if ( msg & & msg - > has_state & & msg - > state . size = = 64 ) {
uint8_t i_state [ 64 ] ;
if ( ! session_getState ( msg - > state . bytes , i_state , NULL ) ) {
session_clear ( false ) ; // do not clear PIN
} else {
if ( 0 ! = memcmp ( msg - > state . bytes , i_state , 64 ) ) {
session_clear ( false ) ; // do not clear PIN
}
}
} else {
session_clear ( false ) ; // do not clear PIN
}
layoutHome ( ) ;
fsm_msgGetFeatures ( 0 ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgGetFeatures ( const GetFeatures * msg )
2018-05-03 14:47:37 +00:00
{
( void ) msg ;
RESP_INIT ( Features ) ;
2019-01-27 14:06:05 +00:00
resp - > has_vendor = true ; strlcpy ( resp - > vendor , " trezor.io " , sizeof ( resp - > vendor ) ) ;
2018-05-03 14:47:37 +00:00
resp - > has_major_version = true ; resp - > major_version = VERSION_MAJOR ;
resp - > has_minor_version = true ; resp - > minor_version = VERSION_MINOR ;
resp - > has_patch_version = true ; resp - > patch_version = VERSION_PATCH ;
2019-01-25 10:58:23 +00:00
resp - > has_device_id = true ; strlcpy ( resp - > device_id , config_uuid_str , sizeof ( resp - > device_id ) ) ;
resp - > has_pin_protection = true ; resp - > pin_protection = config_hasPin ( ) ;
2019-02-14 17:59:31 +00:00
resp - > has_passphrase_protection = true ; config_getPassphraseProtection ( & ( resp - > passphrase_protection ) ) ;
2018-05-03 14:47:37 +00:00
# ifdef SCM_REVISION
int len = sizeof ( SCM_REVISION ) - 1 ;
resp - > has_revision = true ; memcpy ( resp - > revision . bytes , SCM_REVISION , len ) ; resp - > revision . size = len ;
# endif
resp - > has_bootloader_hash = true ; resp - > bootloader_hash . size = memory_bootloader_hash ( resp - > bootloader_hash . bytes ) ;
2019-01-25 10:58:23 +00:00
2019-02-07 15:06:07 +00:00
resp - > has_language = config_getLanguage ( resp - > language , sizeof ( resp - > language ) ) ;
2019-02-19 17:01:10 +00:00
resp - > has_label = config_getLabel ( resp - > label , sizeof ( resp - > label ) ) ;
2019-01-25 10:58:23 +00:00
resp - > has_initialized = true ; resp - > initialized = config_isInitialized ( ) ;
2019-02-07 15:06:07 +00:00
resp - > has_imported = config_getImported ( & ( resp - > imported ) ) ;
2019-02-08 15:08:55 +00:00
resp - > has_pin_cached = true ; resp - > pin_cached = session_isUnlocked ( ) & & config_hasPin ( ) ;
2018-05-03 14:47:37 +00:00
resp - > has_passphrase_cached = true ; resp - > passphrase_cached = session_isPassphraseCached ( ) ;
2019-02-14 17:59:31 +00:00
resp - > has_needs_backup = true ; config_getNeedsBackup ( & ( resp - > needs_backup ) ) ;
resp - > has_unfinished_backup = true ; config_getUnfinishedBackup ( & ( resp - > unfinished_backup ) ) ;
resp - > has_no_backup = true ; config_getNoBackup ( & ( resp - > no_backup ) ) ;
2019-02-07 15:06:07 +00:00
resp - > has_flags = config_getFlags ( & ( resp - > flags ) ) ;
2018-05-03 14:47:37 +00:00
resp - > has_model = true ; strlcpy ( resp - > model , " 1 " , sizeof ( resp - > model ) ) ;
msg_write ( MessageType_MessageType_Features , resp ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgPing ( const Ping * msg )
2018-05-03 14:47:37 +00:00
{
RESP_INIT ( Success ) ;
if ( msg - > has_button_protection & & msg - > button_protection ) {
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " answer to ping? " ) , NULL , NULL , NULL , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
}
if ( msg - > has_pin_protection & & msg - > pin_protection ) {
CHECK_PIN
}
if ( msg - > has_passphrase_protection & & msg - > passphrase_protection ) {
if ( ! protectPassphrase ( ) ) {
2018-08-27 17:06:11 +00:00
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
return ;
}
}
if ( msg - > has_message ) {
resp - > has_message = true ;
memcpy ( & ( resp - > message ) , & ( msg - > message ) , sizeof ( resp - > message ) ) ;
}
msg_write ( MessageType_MessageType_Success , resp ) ;
layoutHome ( ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgChangePin ( const ChangePin * msg )
2018-05-03 14:47:37 +00:00
{
bool removal = msg - > has_remove & & msg - > remove ;
if ( removal ) {
2019-01-25 10:58:23 +00:00
if ( config_hasPin ( ) ) {
2018-05-03 14:47:37 +00:00
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " remove current PIN? " ) , NULL , NULL , NULL , NULL ) ;
} else {
fsm_sendSuccess ( _ ( " PIN removed " ) ) ;
return ;
}
} else {
2019-01-25 10:58:23 +00:00
if ( config_hasPin ( ) ) {
2018-05-03 14:47:37 +00:00
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " change current PIN? " ) , NULL , NULL , NULL , NULL ) ;
} else {
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " set new PIN? " ) , NULL , NULL , NULL , NULL ) ;
}
}
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
2019-02-19 17:01:10 +00:00
if ( protectChangePin ( removal ) ) {
if ( removal ) {
fsm_sendSuccess ( _ ( " PIN removed " ) ) ;
} else {
fsm_sendSuccess ( _ ( " PIN changed " ) ) ;
}
}
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgWipeDevice ( const WipeDevice * msg )
2018-05-03 14:47:37 +00:00
{
( void ) msg ;
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " wipe the device? " ) , NULL , _ ( " All data will be lost. " ) , NULL , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_WipeDevice , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
2019-01-25 10:58:23 +00:00
config_wipe ( ) ;
2018-05-03 14:47:37 +00:00
// the following does not work on Mac anyway :-/ Linux/Windows are fine, so it is not needed
// usbReconnect(); // force re-enumeration because of the serial number change
fsm_sendSuccess ( _ ( " Device wiped " ) ) ;
layoutHome ( ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgGetEntropy ( const GetEntropy * msg )
2018-05-03 14:47:37 +00:00
{
# if !DEBUG_RNG
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " send entropy? " ) , NULL , NULL , NULL , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
# endif
RESP_INIT ( Entropy ) ;
uint32_t len = msg - > size ;
if ( len > 1024 ) {
len = 1024 ;
}
resp - > entropy . size = len ;
random_buffer ( resp - > entropy . bytes , len ) ;
msg_write ( MessageType_MessageType_Entropy , resp ) ;
layoutHome ( ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgLoadDevice ( const LoadDevice * msg )
2018-05-03 14:47:37 +00:00
{
2019-02-19 17:01:10 +00:00
CHECK_PIN
2019-02-05 19:40:58 +00:00
2018-05-03 14:47:37 +00:00
CHECK_NOT_INITIALIZED
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " I take the risk " ) , NULL , _ ( " Loading private seed " ) , _ ( " is not recommended. " ) , _ ( " Continue only if you " ) , _ ( " know what you are " ) , _ ( " doing! " ) , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
if ( msg - > has_mnemonic & & ! ( msg - > has_skip_checksum & & msg - > skip_checksum ) ) {
if ( ! mnemonic_check ( msg - > mnemonic ) ) {
2018-08-27 17:06:11 +00:00
fsm_sendFailure ( FailureType_Failure_DataError , _ ( " Mnemonic with wrong checksum provided " ) ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
}
2019-01-25 10:58:23 +00:00
config_loadDevice ( msg ) ;
2018-05-03 14:47:37 +00:00
fsm_sendSuccess ( _ ( " Device loaded " ) ) ;
layoutHome ( ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgResetDevice ( const ResetDevice * msg )
2018-05-03 14:47:37 +00:00
{
2019-02-19 17:01:10 +00:00
CHECK_PIN
2019-02-05 19:40:58 +00:00
2018-05-03 14:47:37 +00:00
CHECK_NOT_INITIALIZED
CHECK_PARAM ( ! msg - > has_strength | | msg - > strength = = 128 | | msg - > strength = = 192 | | msg - > strength = = 256 , _ ( " Invalid seed strength " ) ) ;
reset_init (
msg - > has_display_random & & msg - > display_random ,
msg - > has_strength ? msg - > strength : 128 ,
msg - > has_passphrase_protection & & msg - > passphrase_protection ,
msg - > has_pin_protection & & msg - > pin_protection ,
msg - > has_language ? msg - > language : 0 ,
msg - > has_label ? msg - > label : 0 ,
msg - > has_u2f_counter ? msg - > u2f_counter : 0 ,
2018-10-04 15:19:37 +00:00
msg - > has_skip_backup ? msg - > skip_backup : false ,
msg - > has_no_backup ? msg - > no_backup : false
2018-05-03 14:47:37 +00:00
) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgEntropyAck ( const EntropyAck * msg )
2018-05-03 14:47:37 +00:00
{
if ( msg - > has_entropy ) {
reset_entropy ( msg - > entropy . bytes , msg - > entropy . size ) ;
} else {
reset_entropy ( 0 , 0 ) ;
}
}
2018-09-14 12:40:29 +00:00
void fsm_msgBackupDevice ( const BackupDevice * msg )
2018-05-03 14:47:37 +00:00
{
CHECK_INITIALIZED
CHECK_PIN_UNCACHED
( void ) msg ;
2019-02-19 17:01:10 +00:00
char mnemonic [ MAX_MNEMONIC_LEN + 1 ] ;
if ( config_getMnemonic ( mnemonic , sizeof ( mnemonic ) ) ) {
reset_backup ( true , mnemonic ) ;
}
memzero ( mnemonic , sizeof ( mnemonic ) ) ;
2018-05-03 14:47:37 +00:00
}
2018-09-14 12:40:29 +00:00
void fsm_msgCancel ( const Cancel * msg )
2018-05-03 14:47:37 +00:00
{
( void ) msg ;
recovery_abort ( ) ;
signing_abort ( ) ;
ethereum_signing_abort ( ) ;
2018-08-27 17:06:11 +00:00
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
}
2018-09-14 12:40:29 +00:00
void fsm_msgClearSession ( const ClearSession * msg )
2018-05-03 14:47:37 +00:00
{
( void ) msg ;
session_clear ( true ) ; // clear PIN as well
layoutScreensaver ( ) ;
fsm_sendSuccess ( _ ( " Session cleared " ) ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgApplySettings ( const ApplySettings * msg )
2018-05-03 14:47:37 +00:00
{
CHECK_PARAM ( msg - > has_label | | msg - > has_language | | msg - > has_use_passphrase | | msg - > has_homescreen | | msg - > has_auto_lock_delay_ms ,
_ ( " No setting provided " ) ) ;
CHECK_PIN
if ( msg - > has_label ) {
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " change name to " ) , msg - > label , " ? " , NULL , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
}
if ( msg - > has_language ) {
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " change language to " ) , msg - > language , " ? " , NULL , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
}
if ( msg - > has_use_passphrase ) {
2018-05-21 13:50:53 +00:00
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , msg - > use_passphrase ? _ ( " enable passphrase " ) : _ ( " disable passphrase " ) , _ ( " protection? " ) , NULL , NULL , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
}
if ( msg - > has_homescreen ) {
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " change the home " ) , _ ( " screen? " ) , NULL , NULL , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
}
if ( msg - > has_auto_lock_delay_ms ) {
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you really want to " ) , _ ( " change auto-lock " ) , _ ( " delay? " ) , NULL , NULL , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
}
if ( msg - > has_label ) {
2019-01-25 10:58:23 +00:00
config_setLabel ( msg - > label ) ;
2018-05-03 14:47:37 +00:00
}
if ( msg - > has_language ) {
2019-01-25 10:58:23 +00:00
config_setLanguage ( msg - > language ) ;
2018-05-03 14:47:37 +00:00
}
if ( msg - > has_use_passphrase ) {
2019-01-25 10:58:23 +00:00
config_setPassphraseProtection ( msg - > use_passphrase ) ;
2018-05-03 14:47:37 +00:00
}
if ( msg - > has_homescreen ) {
2019-01-25 10:58:23 +00:00
config_setHomescreen ( msg - > homescreen . bytes , msg - > homescreen . size ) ;
2018-05-03 14:47:37 +00:00
}
if ( msg - > has_auto_lock_delay_ms ) {
2019-01-25 10:58:23 +00:00
config_setAutoLockDelayMs ( msg - > auto_lock_delay_ms ) ;
2018-05-03 14:47:37 +00:00
}
fsm_sendSuccess ( _ ( " Settings applied " ) ) ;
layoutHome ( ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgApplyFlags ( const ApplyFlags * msg )
2018-05-03 14:47:37 +00:00
{
2019-02-19 17:01:10 +00:00
CHECK_PIN
2019-02-05 19:40:58 +00:00
2018-05-03 14:47:37 +00:00
if ( msg - > has_flags ) {
2019-01-25 10:58:23 +00:00
config_applyFlags ( msg - > flags ) ;
2018-05-03 14:47:37 +00:00
}
fsm_sendSuccess ( _ ( " Flags applied " ) ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgRecoveryDevice ( const RecoveryDevice * msg )
2018-05-03 14:47:37 +00:00
{
2019-02-18 17:12:04 +00:00
CHECK_PIN_UNCACHED
2019-02-05 19:40:58 +00:00
2018-05-03 14:47:37 +00:00
const bool dry_run = msg - > has_dry_run ? msg - > dry_run : false ;
2019-02-05 19:40:58 +00:00
if ( ! dry_run ) {
2018-05-03 14:47:37 +00:00
CHECK_NOT_INITIALIZED
}
CHECK_PARAM ( ! msg - > has_word_count | | msg - > word_count = = 12 | | msg - > word_count = = 18 | | msg - > word_count = = 24 , _ ( " Invalid word count " ) ) ;
recovery_init (
msg - > has_word_count ? msg - > word_count : 12 ,
msg - > has_passphrase_protection & & msg - > passphrase_protection ,
msg - > has_pin_protection & & msg - > pin_protection ,
msg - > has_language ? msg - > language : 0 ,
msg - > has_label ? msg - > label : 0 ,
msg - > has_enforce_wordlist & & msg - > enforce_wordlist ,
msg - > has_type ? msg - > type : 0 ,
msg - > has_u2f_counter ? msg - > u2f_counter : 0 ,
dry_run
) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgWordAck ( const WordAck * msg )
2018-05-03 14:47:37 +00:00
{
recovery_word ( msg - > word ) ;
}
2018-09-14 12:40:29 +00:00
void fsm_msgSetU2FCounter ( const SetU2FCounter * msg )
2018-05-03 14:47:37 +00:00
{
layoutDialogSwipe ( & bmp_icon_question , _ ( " Cancel " ) , _ ( " Confirm " ) , NULL , _ ( " Do you want to set " ) , _ ( " the U2F counter? " ) , NULL , NULL , NULL , NULL ) ;
2018-08-27 17:06:11 +00:00
if ( ! protectButton ( ButtonRequestType_ButtonRequest_ProtectCall , false ) ) {
fsm_sendFailure ( FailureType_Failure_ActionCancelled , NULL ) ;
2018-05-03 14:47:37 +00:00
layoutHome ( ) ;
return ;
}
2019-01-25 10:58:23 +00:00
config_setU2FCounter ( msg - > u2f_counter ) ;
2018-05-03 14:47:37 +00:00
fsm_sendSuccess ( _ ( " U2F counter set " ) ) ;
layoutHome ( ) ;
2018-05-11 12:03:28 +00:00
}