Skip to content

Commit da25e74

Browse files
committed
Vulnerability fixes
Fixed: - Missing input value validation - Potential missing secret wiping from stack after use - String manipulation - Pointer arithmetic on void pointer - Trivial swich-case statements were removed - Replaced certain other memset calls
1 parent ab29900 commit da25e74

5 files changed

Lines changed: 30 additions & 74 deletions

File tree

src/diffieHellman.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ __noinline_due_to_stack__ size_t dh_decode(bip44_path_t* pathSpec,
370370
END_TRY;
371371

372372
TRACE("Finishing decription, written:%d, lastCharacter:%d", written, buffer[written - 1]);
373-
// Calculate redulting length based on the last decoded value
373+
// Calculate resulting length based on the last decoded value
374+
ASSERT(written != 0);
375+
ASSERT(written >= buffer[written - 1]);
374376
return written - buffer[written - 1];
375377
}

src/eos_utils.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ bool b58enc(uint8_t *bin, uint32_t binsz, char *b58, uint32_t *b58sz) {
179179
size = (binsz - zcount) * 138 / 100 + 1;
180180
uint8_t buf[MAX_B58ENC_LENGTH];
181181
ASSERT(size <= MAX_B58ENC_LENGTH);
182-
memset(buf, 0, sizeof(buf));
182+
explicit_bzero(buf, sizeof(buf));
183183

184184
for (i = zcount, high = size - 1; i < binsz; ++i, high = j) {
185185
for (carry = bin[i], j = size - 1; (j > high) || carry; --j) {
@@ -223,7 +223,7 @@ uint32_t compressed_public_key_to_wif(const uint8_t *publicKey,
223223
ASSERT(outLength >= 40);
224224

225225
uint8_t temp[37];
226-
memset(temp, 0, sizeof(temp));
226+
explicit_bzero(temp, sizeof(temp));
227227
memcpy(temp, publicKey, 33);
228228

229229
uint8_t check[20];
@@ -232,7 +232,7 @@ uint32_t compressed_public_key_to_wif(const uint8_t *publicKey,
232232
cx_hash(&riprip.header, CX_LAST, temp, 33, check, sizeof(check));
233233
memcpy(temp + 33, check, 4);
234234

235-
memset(out, 0, outLength);
235+
explicit_bzero(out, outLength);
236236
out[0] = 'F';
237237
out[1] = 'I';
238238
out[2] = 'O';

src/getPublicKey.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,6 @@ static ins_get_key_context_t* ctx = &(instructionState.getKeyContext);
1414
// it should be set to this value at the beginning and after a UI state machine is finished
1515
static int UI_STEP_NONE = 0;
1616

17-
static inline void CHECK_STAGE(get_key_stage_t expected) {
18-
VALIDATE(ctx->stage == expected, ERR_INVALID_STATE);
19-
}
20-
21-
static void advanceStage() {
22-
TRACE("Advancing from stage: %d", ctx->stage);
23-
24-
switch (ctx->stage) {
25-
case GET_KEY_STAGE_INIT:
26-
ctx->stage = GET_KEY_STAGE_NONE;
27-
ui_idle(); // we are done with this key export
28-
break;
29-
30-
default:
31-
ASSERT(false);
32-
}
33-
}
34-
3517
// ============================== Derivation and UI state machine ==============================
3618

3719
enum {
@@ -74,10 +56,10 @@ static void getPublicKey_ui_runStep() {
7456

7557
ctx->responseReadyMagic = 0; // just for safety
7658
ui_displayBusy(); // needs to happen after I/O
77-
59+
7860
TRACE("Export done.");
7961

80-
advanceStage();
62+
ui_idle(); // we are done with this key export
8163
}
8264
UI_STEP_END(GET_KEY_UI_STEP_INVALID);
8365
}
@@ -128,10 +110,8 @@ void getPublicKey_handleAPDU(uint8_t p1,
128110
VALIDATE(p2 == P2_UNUSED, ERR_INVALID_REQUEST_PARAMETERS);
129111

130112
explicit_bzero(ctx, SIZEOF(*ctx));
131-
ctx->stage = GET_KEY_STAGE_INIT;
132113
ctx->ui_step = UI_STEP_NONE;
133114

134-
CHECK_STAGE(GET_KEY_STAGE_INIT);
135115
ASSERT(wireDataSize < BUFFER_SIZE_PARANOIA);
136116

137117
{

src/getPublicKey.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,12 @@
88

99
#define MAX_PUBLIC_KEYS 1000
1010

11-
typedef enum {
12-
GET_KEY_STAGE_NONE = 0,
13-
GET_KEY_STAGE_INIT = 20,
14-
} get_key_stage_t;
15-
1611
typedef enum {
1712
P1_SHOW_PUBKEY = 1,
1813
P1_DO_NOT_SHOW_PUBKEY = 2,
1914
} get_key_p1_t;
2015

2116
typedef struct {
22-
get_key_stage_t stage;
2317
get_key_p1_t show_or_not;
2418

2519
bip44_path_t pathSpec;

src/signTransaction.c

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ __noinline_due_to_stack__ void signTx_handleInitAPDU(uint8_t p2,
175175
switch (network) {
176176
#define CASE(NETWORK, CHAIN_STRING) \
177177
case NETWORK: { \
178-
snprintf(ctx->value, MAX_DISPLAY_KEY_LENGTH, CHAIN_STRING); \
178+
snprintf(ctx->value, MAX_DISPLAY_VALUE_LENGTH, CHAIN_STRING); \
179179
break; \
180180
}
181181
CASE(NETWORK_MAINNET, "Mainnet");
@@ -204,19 +204,13 @@ __noinline_due_to_stack__ void signTx_handleInitAPDU(uint8_t p2,
204204
policy = policyForSignTxInit(&ctx->wittnessPath);
205205
TRACE("Policy: %d", (int) policy);
206206
ENSURE_NOT_DENIED(policy);
207-
{
208-
// select UI steps
209-
switch (policy) {
210-
#define CASE(POLICY, UI_STEP) \
211-
case POLICY: { \
212-
ctx->ui_step = UI_STEP; \
213-
break; \
214-
}
215-
CASE(POLICY_SHOW_BEFORE_RESPONSE, HANDLE_SIMPLE_STEP_DISPLAY_DETAILS);
216-
default:
217-
THROW(ERR_NOT_IMPLEMENTED);
218-
#undef CASE
219-
}
207+
// select UI step
208+
if (policy == POLICY_SHOW_BEFORE_RESPONSE) {
209+
ctx->ui_step = HANDLE_SIMPLE_STEP_DISPLAY_DETAILS;
210+
}
211+
else {
212+
THROW(ERR_NOT_IMPLEMENTED);
213+
220214
}
221215
}
222216

@@ -296,7 +290,7 @@ __noinline_due_to_stack__ void signTx_handleShowMessageAPDU(
296290
struct {
297291
uint8_t displayValueLen;
298292
uint8_t displayValue[MAX_DISPLAY_VALUE_LENGTH];
299-
}* constData2 = (void*) constDataBuffer + 1 + constData->displayKeyLen;
293+
}* constData2 = (void*) (constDataBuffer + 1 + constData->displayKeyLen);
300294
VALIDATE(constData2->displayValueLen < MAX_DISPLAY_VALUE_LENGTH - 1, ERR_INVALID_DATA);
301295
VALIDATE(constSize == 2 + constData->displayKeyLen + constData2->displayValueLen,
302296
ERR_INVALID_DATA);
@@ -848,19 +842,12 @@ __noinline_due_to_stack__ void signTx_handleEndDHEncodingAPDU(
848842
policy = policyForSignTxDHEnd();
849843
TRACE("Policy: %d", (int) policy);
850844
ENSURE_NOT_DENIED(policy);
851-
{
852-
// select UI steps
853-
switch (policy) {
854-
#define CASE(POLICY, UI_STEP) \
855-
case POLICY: { \
856-
ctx->ui_step = UI_STEP; \
857-
break; \
858-
}
859-
CASE(POLICY_PROMPT_BEFORE_RESPONSE, HANDLE_DH_END_STEP_CONFIRM);
860-
default:
861-
THROW(ERR_NOT_IMPLEMENTED);
862-
#undef CASE
863-
}
845+
// select UI step
846+
if (policy == POLICY_PROMPT_BEFORE_RESPONSE) {
847+
ctx->ui_step = HANDLE_DH_END_STEP_CONFIRM;
848+
}
849+
else {
850+
THROW(ERR_NOT_IMPLEMENTED);
864851
}
865852
}
866853
}
@@ -952,19 +939,12 @@ __noinline_due_to_stack__ void signTx_handleFinishAPDU(
952939
policy = policyForSignTxFinish();
953940
TRACE("Policy: %d", (int) policy);
954941
ENSURE_NOT_DENIED(policy);
955-
{
956-
// select UI steps
957-
switch (policy) {
958-
#define CASE(POLICY, UI_STEP) \
959-
case POLICY: { \
960-
ctx->ui_step = UI_STEP; \
961-
break; \
962-
}
963-
CASE(POLICY_PROMPT_BEFORE_RESPONSE, HANDLE_FINISH_STEP_DISPLAY_DETAILS);
964-
default:
965-
THROW(ERR_NOT_IMPLEMENTED);
966-
#undef CASE
967-
}
942+
// select UI step
943+
if (policy == POLICY_PROMPT_BEFORE_RESPONSE) {
944+
ctx->ui_step = HANDLE_FINISH_STEP_DISPLAY_DETAILS;
945+
}
946+
else {
947+
THROW(ERR_NOT_IMPLEMENTED);
968948
}
969949
}
970950

@@ -1032,7 +1012,7 @@ __noinline_due_to_stack__ void signTx_handleFinishAPDU(
10321012
}
10331013
}
10341014
FINALLY {
1035-
memset(&privateKey, 0, sizeof(privateKey));
1015+
explicit_bzero(&privateKey, sizeof(privateKey));
10361016
}
10371017
}
10381018
END_TRY;

0 commit comments

Comments
 (0)