ledger-app-monero/src/monero_open_tx.c

146 lines
4.8 KiB
C

/*****************************************************************************
* Ledger Monero App.
* (c) 2017-2020 Cedric Mesnil <cslashm@gmail.com>, Ledger SAS.
* (c) 2020 Ledger SAS.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/
#include "os.h"
#include "cx.h"
#include "monero_types.h"
#include "monero_api.h"
#include "monero_vars.h"
/* ----------------------------------------------------------------------- */
/* --- --- */
/* ----------------------------------------------------------------------- */
int monero_reset_tx(int reset_tx_cnt) {
int error;
explicit_bzero(G_monero_vstate.r, sizeof(G_monero_vstate.r));
explicit_bzero(G_monero_vstate.R, sizeof(G_monero_vstate.R));
cx_rng(G_monero_vstate.hmac_key, KEY_SIZE);
error = monero_keccak_init_H();
if (error) {
return error;
}
monero_sha256_commitment_init();
monero_sha256_outkeys_init();
G_monero_vstate.tx_in_progress = 0;
G_monero_vstate.tx_output_cnt = 0;
if (reset_tx_cnt) {
G_monero_vstate.tx_cnt = 0;
}
return 0;
}
/* ----------------------------------------------------------------------- */
/* --- --- */
/* ----------------------------------------------------------------------- */
/*
* HD wallet not yet supported : account is assumed to be zero
*/
int monero_apdu_open_tx() {
int error;
monero_io_fetch_u32(); // skip account
monero_io_discard(1);
error = monero_reset_tx(0);
if (error) {
return error;
}
G_monero_vstate.tx_cnt++;
ui_menu_opentx_display(0);
return monero_apdu_open_tx_cont();
}
int monero_apdu_open_tx_cont() {
int error;
G_monero_vstate.tx_in_progress = 1;
#ifdef DEBUG_HWDEVICE
memset(G_monero_vstate.hmac_key, 0xab, sizeof(G_monero_vstate.hmac_key));
#else
cx_rng(G_monero_vstate.hmac_key, KEY_SIZE);
#endif
error = monero_rng_mod_order(G_monero_vstate.r, sizeof(G_monero_vstate.r));
if (error) {
return error;
}
error = monero_ecmul_G(G_monero_vstate.R, G_monero_vstate.r, sizeof(G_monero_vstate.R),
sizeof(G_monero_vstate.r));
if (error) {
return error;
}
monero_io_insert(G_monero_vstate.R, KEY_SIZE);
monero_io_insert_encrypt(G_monero_vstate.r, KEY_SIZE, TYPE_SCALAR);
monero_io_insert(C_FAKE_SEC_VIEW_KEY, KEY_SIZE);
monero_io_insert_hmac_for((void*)C_FAKE_SEC_VIEW_KEY, KEY_SIZE, TYPE_SCALAR);
monero_io_insert(C_FAKE_SEC_SPEND_KEY, KEY_SIZE);
monero_io_insert_hmac_for((void*)C_FAKE_SEC_SPEND_KEY, KEY_SIZE, TYPE_SCALAR);
return SW_OK;
}
/* ----------------------------------------------------------------------- */
/* --- --- */
/* ----------------------------------------------------------------------- */
int monero_apdu_close_tx() {
int error;
monero_io_discard(1);
error = monero_reset_tx(G_monero_vstate.tx_sig_mode == TRANSACTION_CREATE_REAL);
if (error) {
return error;
}
#ifdef HAVE_BAGL
ui_menu_main_display();
#endif
return SW_OK;
}
/* ----------------------------------------------------------------------- */
/* --- --- */
/* ----------------------------------------------------------------------- */
int monero_abort_tx() {
monero_reset_tx(1);
ui_menu_show_tx_aborted();
return 0;
}
/* ----------------------------------------------------------------------- */
/* --- --- */
/* ----------------------------------------------------------------------- */
int monero_apdu_set_signature_mode() {
unsigned int sig_mode;
G_monero_vstate.tx_sig_mode = TRANSACTION_CREATE_FAKE;
sig_mode = monero_io_fetch_u8();
monero_io_discard(0);
switch (sig_mode) {
case TRANSACTION_CREATE_REAL:
case TRANSACTION_CREATE_FAKE:
break;
default:
return SW_WRONG_DATA;
}
G_monero_vstate.tx_sig_mode = sig_mode;
monero_io_insert_u32(G_monero_vstate.tx_sig_mode);
return SW_OK;
}