Skip to content

Commit 419ef79

Browse files
Merge pull request #1015 from LedgerHQ/fix/signed_integer_formatting
Fix signed integer formatting
2 parents af9cb39 + 050fbf0 commit 419ef79

10 files changed

Lines changed: 293 additions & 239 deletions

File tree

src/features/generic_tx_parser/gtp_param_raw.c

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include "gtp_param_raw.h"
44
#include "gtp_field.h"
55
#include "uint256.h"
6-
#include "read.h"
76
#include "gtp_field_table.h"
87
#include "utils.h"
98
#include "shared_context.h"
@@ -111,47 +110,7 @@ bool format_uint(const s_field *field,
111110
}
112111

113112
bool format_int(const s_value *def, const s_parsed_value *value, char *buf, size_t buf_size) {
114-
uint8_t tmp[INT256_LENGTH];
115-
bool ret;
116-
union {
117-
uint256_t value256;
118-
uint128_t value128;
119-
int64_t value64;
120-
int32_t value32;
121-
int16_t value16;
122-
int8_t value8;
123-
} uv;
124-
125-
buf_shrink_expand(value->ptr, value->length, tmp, def->type_size);
126-
switch (def->type_size * 8) {
127-
case 256:
128-
convertUint256BE(tmp, def->type_size, &uv.value256);
129-
ret = tostring256_signed(&uv.value256, 10, buf, buf_size);
130-
break;
131-
case 128:
132-
convertUint128BE(tmp, def->type_size, &uv.value128);
133-
ret = tostring128_signed(&uv.value128, 10, buf, buf_size);
134-
break;
135-
case 64:
136-
uv.value64 = read_u64_be(tmp, 0);
137-
ret = format_i64(buf, buf_size, uv.value64);
138-
break;
139-
case 32:
140-
uv.value32 = read_u32_be(tmp, 0);
141-
ret = format_i64(buf, buf_size, (int64_t) uv.value32);
142-
break;
143-
case 16:
144-
uv.value16 = read_u16_be(tmp, 0);
145-
ret = format_i64(buf, buf_size, (int64_t) uv.value16);
146-
break;
147-
case 8:
148-
uv.value8 = value->ptr[0];
149-
ret = format_i64(buf, buf_size, (int64_t) uv.value8);
150-
break;
151-
default:
152-
ret = false;
153-
}
154-
return ret;
113+
return format_signed_int_be(value->ptr, value->length, def->type_size, buf, buf_size);
155114
}
156115

157116
/**

src/features/sign_message_eip712/ui_logic.c

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "app_mem_utils.h"
33
#include "mem_utils.h"
44
#include "os_io.h"
5+
#include "format.h"
56
#include "common_utils.h" // uint256_to_decimal
67
#include "common_712.h"
78
#include "context_712.h" // eip712_context_deinit
@@ -468,62 +469,18 @@ static bool ui_712_format_int(const uint8_t *data,
468469
uint8_t length,
469470
bool first,
470471
const s_struct_712_field *field_ptr) {
471-
uint256_t value256;
472-
uint128_t value128;
473-
int32_t value32;
474-
int16_t value16;
475-
int8_t value8;
476-
uint8_t tmp[sizeof(int32_t)] = {0};
477-
478472
// no reason for an integer to be received over multiple chunks
479473
if (!first) {
480474
return false;
481475
}
482-
if (length < 1) {
476+
if (!format_signed_int_be(data,
477+
length,
478+
field_ptr->type_size,
479+
strings.tmp.tmp,
480+
sizeof(strings.tmp.tmp))) {
483481
apdu_response_code = SWO_INCORRECT_DATA;
484482
return false;
485483
}
486-
if (length > field_ptr->type_size) {
487-
apdu_response_code = SWO_INCORRECT_DATA;
488-
return false;
489-
}
490-
491-
switch (field_ptr->type_size * 8) {
492-
case 256:
493-
convertUint256BE(data, length, &value256);
494-
tostring256_signed(&value256, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp));
495-
break;
496-
case 128:
497-
convertUint128BE(data, length, &value128);
498-
tostring128_signed(&value128, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp));
499-
break;
500-
case 64:
501-
convertUint64BEto128(data, length, &value128);
502-
tostring128_signed(&value128, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp));
503-
break;
504-
case 32:
505-
buf_shrink_expand(data, length, tmp, sizeof(int32_t));
506-
value32 = (int32_t) read_u32_be(tmp, 0);
507-
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "%d", value32);
508-
break;
509-
case 16:
510-
buf_shrink_expand(data, length, tmp, sizeof(int16_t));
511-
value16 = (int16_t) read_u16_be(tmp, 0);
512-
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "%d", value16);
513-
break;
514-
case 8:
515-
if (length != sizeof(int8_t)) {
516-
apdu_response_code = SWO_INCORRECT_DATA;
517-
return false;
518-
}
519-
value8 = (int8_t) data[0];
520-
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "%d", value8);
521-
break;
522-
default:
523-
PRINTF("Unhandled field typesize\n");
524-
apdu_response_code = SWO_INCORRECT_DATA;
525-
return false;
526-
}
527484
return true;
528485
}
529486

src/uint128.c

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,26 @@
2525
#include "common_utils.h" // HEXDIGITS
2626
#include "utils.h"
2727

28-
void readu128BE(const uint8_t *const buffer, uint128_t *const target) {
28+
void readu128BE(const uint8_t *buffer, uint128_t *target) {
2929
UPPER_P(target) = read_u64_be(buffer, 0);
3030
LOWER_P(target) = read_u64_be(buffer + 8, 0);
3131
}
3232

33-
bool zero128(const uint128_t *const number) {
33+
bool zero128(const uint128_t *number) {
3434
return ((LOWER_P(number) == 0) && (UPPER_P(number) == 0));
3535
}
3636

37-
void copy128(uint128_t *const target, const uint128_t *const number) {
37+
void copy128(uint128_t *target, const uint128_t *number) {
3838
UPPER_P(target) = UPPER_P(number);
3939
LOWER_P(target) = LOWER_P(number);
4040
}
4141

42-
void clear128(uint128_t *const target) {
42+
void clear128(uint128_t *target) {
4343
UPPER_P(target) = 0;
4444
LOWER_P(target) = 0;
4545
}
4646

47-
void shiftl128(const uint128_t *const number, uint32_t value, uint128_t *const target) {
47+
void shiftl128(const uint128_t *number, uint32_t value, uint128_t *target) {
4848
if (value >= 128) {
4949
clear128(target);
5050
} else if (value == 64) {
@@ -61,7 +61,7 @@ void shiftl128(const uint128_t *const number, uint32_t value, uint128_t *const t
6161
}
6262
}
6363

64-
void shiftr128(const uint128_t *const number, uint32_t value, uint128_t *const target) {
64+
void shiftr128(const uint128_t *number, uint32_t value, uint128_t *target) {
6565
if (value >= 128) {
6666
clear128(target);
6767
} else if (value == 64) {
@@ -80,7 +80,7 @@ void shiftr128(const uint128_t *const number, uint32_t value, uint128_t *const t
8080
}
8181
}
8282

83-
uint32_t bits128(const uint128_t *const number) {
83+
uint32_t bits128(const uint128_t *number) {
8484
uint32_t result = 0;
8585
if (UPPER_P(number)) {
8686
result = 64;
@@ -99,47 +99,39 @@ uint32_t bits128(const uint128_t *const number) {
9999
return result;
100100
}
101101

102-
bool equal128(const uint128_t *const number1, const uint128_t *const number2) {
102+
bool equal128(const uint128_t *number1, const uint128_t *number2) {
103103
return (UPPER_P(number1) == UPPER_P(number2)) && (LOWER_P(number1) == LOWER_P(number2));
104104
}
105105

106-
bool gt128(const uint128_t *const number1, const uint128_t *const number2) {
106+
bool gt128(const uint128_t *number1, const uint128_t *number2) {
107107
if (UPPER_P(number1) == UPPER_P(number2)) {
108108
return (LOWER_P(number1) > LOWER_P(number2));
109109
}
110110
return (UPPER_P(number1) > UPPER_P(number2));
111111
}
112112

113-
bool gte128(const uint128_t *const number1, const uint128_t *const number2) {
113+
bool gte128(const uint128_t *number1, const uint128_t *number2) {
114114
return gt128(number1, number2) || equal128(number1, number2);
115115
}
116116

117-
void add128(const uint128_t *const number1,
118-
const uint128_t *const number2,
119-
uint128_t *const target) {
117+
void add128(const uint128_t *number1, const uint128_t *number2, uint128_t *target) {
120118
UPPER_P(target) = UPPER_P(number1) + UPPER_P(number2) +
121119
((LOWER_P(number1) + LOWER_P(number2)) < LOWER_P(number1));
122120
LOWER_P(target) = LOWER_P(number1) + LOWER_P(number2);
123121
}
124122

125-
void sub128(const uint128_t *const number1,
126-
const uint128_t *const number2,
127-
uint128_t *const target) {
123+
void sub128(const uint128_t *number1, const uint128_t *number2, uint128_t *target) {
128124
UPPER_P(target) = UPPER_P(number1) - UPPER_P(number2) -
129125
((LOWER_P(number1) - LOWER_P(number2)) > LOWER_P(number1));
130126
LOWER_P(target) = LOWER_P(number1) - LOWER_P(number2);
131127
}
132128

133-
void or128(const uint128_t *const number1,
134-
const uint128_t *const number2,
135-
uint128_t *const target) {
129+
void or128(const uint128_t *number1, const uint128_t *number2, uint128_t *target) {
136130
UPPER_P(target) = UPPER_P(number1) | UPPER_P(number2);
137131
LOWER_P(target) = LOWER_P(number1) | LOWER_P(number2);
138132
}
139133

140-
void mul128(const uint128_t *const number1,
141-
const uint128_t *const number2,
142-
uint128_t *const target) {
134+
void mul128(const uint128_t *number1, const uint128_t *number2, uint128_t *target) {
143135
uint64_t top[4] = {UPPER_P(number1) >> 32,
144136
UPPER_P(number1) & 0xffffffff,
145137
LOWER_P(number1) >> 32,
@@ -184,10 +176,7 @@ void mul128(const uint128_t *const number1,
184176
add128(&tmp, &tmp2, target);
185177
}
186178

187-
void divmod128(const uint128_t *const l,
188-
const uint128_t *const r,
189-
uint128_t *const retDiv,
190-
uint128_t *const retMod) {
179+
void divmod128(const uint128_t *l, const uint128_t *r, uint128_t *retDiv, uint128_t *retMod) {
191180
uint128_t copyd, adder, resDiv, resMod;
192181
uint128_t one;
193182
UPPER(one) = 0;
@@ -218,10 +207,7 @@ void divmod128(const uint128_t *const l,
218207
}
219208
}
220209

221-
bool tostring128(const uint128_t *const number,
222-
uint32_t baseParam,
223-
char *const out,
224-
uint32_t outLength) {
210+
bool tostring128(const uint128_t *number, uint32_t baseParam, char *out, uint32_t outLength) {
225211
uint128_t rDiv;
226212
uint128_t rMod;
227213
uint128_t base;
@@ -259,10 +245,7 @@ bool tostring128(const uint128_t *const number,
259245
* @param[in] out_length the length of the output buffer
260246
* @return whether the formatting was successful or not
261247
*/
262-
bool tostring128_signed(const uint128_t *const number,
263-
uint32_t base,
264-
char *const out,
265-
uint32_t out_length) {
248+
bool tostring128_signed(const uint128_t *number, uint32_t base, char *out, uint32_t out_length) {
266249
uint128_t max_unsigned_val;
267250
uint128_t max_signed_val;
268251
uint128_t one_val;
@@ -289,7 +272,7 @@ bool tostring128_signed(const uint128_t *const number,
289272
return tostring128(number, base, out, out_length); // positive value
290273
}
291274

292-
void convertUint64BEto128(const uint8_t *const data, uint32_t length, uint128_t *const target) {
275+
void convertUint64BEto128(const uint8_t *data, uint32_t length, uint128_t *target) {
293276
uint8_t tmp[INT128_LENGTH];
294277
int64_t value;
295278

@@ -303,7 +286,7 @@ void convertUint64BEto128(const uint8_t *const data, uint32_t length, uint128_t
303286
readu128BE(tmp, target);
304287
}
305288

306-
void convertUint128BE(const uint8_t *const data, uint32_t length, uint128_t *const target) {
289+
void convertUint128BE(const uint8_t *data, uint32_t length, uint128_t *target) {
307290
uint8_t tmp[INT128_LENGTH];
308291

309292
if (data == NULL || target == NULL || length == 0) {

src/uint128.h

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,22 @@ typedef struct uint128_t {
2626
uint64_t elements[2];
2727
} uint128_t;
2828

29-
void readu128BE(const uint8_t *const buffer, uint128_t *const target);
30-
bool zero128(const uint128_t *const number);
31-
void copy128(uint128_t *const target, const uint128_t *const number);
32-
void clear128(uint128_t *const target);
33-
void shiftl128(const uint128_t *const number, uint32_t value, uint128_t *const target);
34-
void shiftr128(const uint128_t *const number, uint32_t value, uint128_t *const target);
35-
uint32_t bits128(const uint128_t *const number);
36-
bool equal128(const uint128_t *const number1, const uint128_t *const number2);
37-
bool gt128(const uint128_t *const number1, const uint128_t *const number2);
38-
bool gte128(const uint128_t *const number1, const uint128_t *const number2);
39-
void add128(const uint128_t *const number1,
40-
const uint128_t *const number2,
41-
uint128_t *const target);
42-
void sub128(const uint128_t *const number1,
43-
const uint128_t *const number2,
44-
uint128_t *const target);
45-
void or128(const uint128_t *const number1, const uint128_t *const number2, uint128_t *const target);
46-
void mul128(const uint128_t *const number1,
47-
const uint128_t *const number2,
48-
uint128_t *const target);
49-
void divmod128(const uint128_t *const l,
50-
const uint128_t *const r,
51-
uint128_t *const div,
52-
uint128_t *const mod);
53-
bool tostring128(const uint128_t *const number, uint32_t base, char *const out, uint32_t outLength);
54-
bool tostring128_signed(const uint128_t *const number,
55-
uint32_t base,
56-
char *const out,
57-
uint32_t out_length);
58-
void convertUint64BEto128(const uint8_t *const data, uint32_t length, uint128_t *const target);
59-
void convertUint128BE(const uint8_t *const data, uint32_t length, uint128_t *const target);
29+
void readu128BE(const uint8_t *buffer, uint128_t *target);
30+
bool zero128(const uint128_t *number);
31+
void copy128(uint128_t *target, const uint128_t *number);
32+
void clear128(uint128_t *target);
33+
void shiftl128(const uint128_t *number, uint32_t value, uint128_t *target);
34+
void shiftr128(const uint128_t *number, uint32_t value, uint128_t *target);
35+
uint32_t bits128(const uint128_t *number);
36+
bool equal128(const uint128_t *number1, const uint128_t *number2);
37+
bool gt128(const uint128_t *number1, const uint128_t *number2);
38+
bool gte128(const uint128_t *number1, const uint128_t *number2);
39+
void add128(const uint128_t *number1, const uint128_t *number2, uint128_t *target);
40+
void sub128(const uint128_t *number1, const uint128_t *number2, uint128_t *target);
41+
void or128(const uint128_t *number1, const uint128_t *number2, uint128_t *target);
42+
void mul128(const uint128_t *number1, const uint128_t *number2, uint128_t *target);
43+
void divmod128(const uint128_t *l, const uint128_t *r, uint128_t *div, uint128_t *mod);
44+
bool tostring128(const uint128_t *number, uint32_t base, char *out, uint32_t outLength);
45+
bool tostring128_signed(const uint128_t *number, uint32_t base, char *out, uint32_t out_length);
46+
void convertUint64BEto128(const uint8_t *data, uint32_t length, uint128_t *target);
47+
void convertUint128BE(const uint8_t *data, uint32_t length, uint128_t *target);

0 commit comments

Comments
 (0)