blue-app-btc/include/btchip_context.h

237 lines
7.9 KiB
C

/*******************************************************************************
* Ledger Blue - Bitcoin Wallet
* (c) 2016 Ledger
*
* 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.
********************************************************************************/
#ifndef BTCHIP_CONTEXT_H
#define BTCHIP_CONTEXT_H
#include "os.h"
#include "btchip_secure_value.h"
#include "btchip_filesystem_tx.h"
#define MAX_OUTPUT_TO_CHECK 200
#define MAX_COIN_ID 10
#define MAX_SHORT_COIN_ID 5
#define MAGIC_TRUSTED_INPUT 0x32
#define MAGIC_DEV_KEY 0x01
enum btchip_modes_e {
BTCHIP_MODE_ISSUER = 0x00,
BTCHIP_MODE_SETUP_NEEDED = 0xff,
BTCHIP_MODE_WALLET = 0x01,
BTCHIP_MODE_RELAXED_WALLET = 0x02,
BTCHIP_MODE_SERVER = 0x04,
BTCHIP_MODE_DEVELOPER = 0x08,
};
enum btchip_options_e {
BTCHIP_OPTION_UNCOMPRESSED_KEYS = 0x01,
BTCHIP_OPTION_DETERMINISTIC_SIGNATURE = 0x02,
BTCHIP_OPTION_FREE_SIGHASHTYPE = 0x04,
BTCHIP_OPTION_SKIP_2FA_P2SH = 0x08,
BTCHIP_OPTION_ALLOW_ARBITRARY_CHANGE = 0x10
};
/**
* Current state of an untrusted transaction hashing
*/
enum btchip_transaction_state_e {
/** No transaction in progress */
BTCHIP_TRANSACTION_NONE = 0x00,
/** Transaction defined, waiting for an input to be hashed */
BTCHIP_TRANSACTION_DEFINED_WAIT_INPUT = 0x01,
/** Transaction defined, input hashing in progress, pending input script
data */
BTCHIP_TRANSACTION_INPUT_HASHING_IN_PROGRESS_INPUT_SCRIPT = 0x02,
/** Transaction defined, input hashing done, pending output hashing for this
input */
BTCHIP_TRANSACTION_INPUT_HASHING_DONE = 0x03,
/** Transaction defined, waiting for an output to be hashed */
BTCHIP_TRANSACTION_DEFINED_WAIT_OUTPUT = 0x04,
/** Transaction defined, output hashing in progress for a complex script,
pending output script data */
BTCHIP_TRANSACTION_OUTPUT_HASHING_IN_PROGRESS_OUTPUT_SCRIPT = 0x05,
/** Transaction defined, output hashing done, pending finalization */
BTCHIP_TRANSACTION_OUTPUT_HASHING_DONE = 0x06,
/** Extra data present */
BTCHIP_TRANSACTION_PROCESS_EXTRA = 0x07,
/** Transaction parsed */
BTCHIP_TRANSACTION_PARSED = 0x08,
/** Transaction parsed, ready to prepare for signature after validating the
user outputs */
BTCHIP_TRANSACTION_PRESIGN_READY = 0x09,
/** Transaction fully parsed, ready to be signed */
BTCHIP_TRANSACTION_SIGN_READY = 0x0a,
};
typedef enum btchip_transaction_state_e btchip_transaction_state_t;
enum btchip_output_parsing_state_e {
BTCHIP_OUTPUT_PARSING_NONE = 0x00,
BTCHIP_OUTPUT_PARSING_NUMBER_OUTPUTS = 0x01,
BTCHIP_OUTPUT_PARSING_OUTPUT = 0x02,
BTCHIP_OUTPUT_FINALIZE_TX = 0x03,
BTCHIP_OUTPUT_HANDLE_LEGACY = 0xFF
};
typedef enum btchip_output_parsing_state_e btchip_output_parsing_state_t;
struct segwit_hash_s {
cx_sha256_t hashPrevouts;
cx_sha256_t hashSequence;
};
struct segwit_cache_s {
unsigned char hashedPrevouts[32];
unsigned char hashedSequence[32];
unsigned char hashedOutputs[32];
};
/**
* Structure defining an operation on a transaction
*/
struct btchip_transaction_context_s {
/** Transient over signing components */
/** Remaining number of inputs/outputs to process for this transaction */
unsigned long int transactionRemainingInputsOutputs;
/** Index of the currently processed input/output for this transaction */
unsigned long int transactionCurrentInputOutput;
/** Remaining script bytes to process for the current input or output */
unsigned long int scriptRemaining;
/** Persistent over signing components */
/** State of the transaction, type btchip_transaction_state_t */
unsigned char transactionState;
/** Computed sum of transaction inputs or value of the output to convert to
* a trusted input */
unsigned char transactionAmount[8];
/** Flag indicating if this transaction has been processed before */
unsigned char firstSigned;
/** If the transaction is relaxed */
unsigned char relaxed;
/** If the transaction consumes a P2SH input */
unsigned char consumeP2SH;
};
typedef struct btchip_transaction_context_s btchip_transaction_context_t;
struct btchip_tmp_output_s {
/** Change address if initialized */
unsigned char changeAddress[21];
/** Flag set if the change address was initialized */
unsigned char changeInitialized;
/** Flag set if the change address was checked */
unsigned char changeChecked;
/** Flag set if the change address can be submitted */
unsigned char changeAccepted;
/** Flag set if the outputs have been fragmented */
unsigned char multipleOutput;
};
typedef struct btchip_tmp_output_s btchip_tmp_output_t;
struct btchip_context_s {
/** Flag if dongle has been halted */
secu8 halted;
/** Index of the output to convert into a trusted input in a transaction */
unsigned long int trustedInputIndex;
/** (Integrity protected) transaction context */
btchip_transaction_context_t transactionContext;
/** Current Pay To Address version */
unsigned short payToAddressVersion;
/** Current Pay To Script Hash version */
unsigned short payToScriptHashVersion;
/** Current coin family */
unsigned char coinFamily;
/** Current Coin ID */
unsigned char coinId[MAX_COIN_ID];
/** Current short Coin ID */
unsigned char shortCoinId[MAX_SHORT_COIN_ID];
/** Current Coin ID length */
unsigned char coinIdLength;
/** Current short Coin ID length */
unsigned char shortCoinIdLength;
/** Non protected transaction context */
/** Full transaction hash context */
cx_sha256_t transactionHashFull;
/** Authorization transaction hash context */
cx_sha256_t transactionHashAuthorization;
/** Current hash to perform (TRANSACTION_HASH_) */
unsigned char transactionHashOption;
/* Segregated Witness changes */
union {
struct segwit_hash_s hash;
struct segwit_cache_s cache;
} segwit;
unsigned char transactionVersion[4];
unsigned char inputValue[8];
unsigned char usingSegwit;
unsigned char segwitParsedOnce;
/* /Segregated Witness changes */
/** Size currently available to the transaction parser */
unsigned char transactionDataRemaining;
/** Current pointer to the transaction buffer for the transaction parser */
unsigned char *transactionBufferPointer;
/** Trusted Input index processed */
unsigned char trustedInputProcessed;
/** Transaction input to catch for a Trusted Input lookup */
unsigned long int transactionTargetInput;
/** Length of the incoming command */
unsigned short inLength;
/** Length of the outgoing command */
unsigned short outLength;
/** IO flags to reply with at the end of an APDU handler */
unsigned char io_flags;
/** Status Word of the response */
unsigned short sw;
/** Current scratch buffer */
unsigned char *tmp;
// was previously in NVRAM
btchip_transaction_summary_t transactionSummary;
unsigned short hashedMessageLength;
union {
btchip_tmp_output_t output;
} tmpCtx;
unsigned char currentOutput[MAX_OUTPUT_TO_CHECK];
unsigned short currentOutputOffset;
unsigned int remainingOutputs;
unsigned int totalOutputs;
unsigned int discardSize;
unsigned char outputParsingState;
unsigned char totalOutputAmount[8];
unsigned char changeOutputFound;
};
typedef struct btchip_context_s btchip_context_t;
void btchip_context_init(void);
#endif