diff --git a/src_features/signMessageEIP712/encode_field.c b/src_features/signMessageEIP712/encode_field.c index 4702fa4..ce78a89 100644 --- a/src_features/signMessageEIP712/encode_field.c +++ b/src_features/signMessageEIP712/encode_field.c @@ -14,28 +14,32 @@ typedef enum } e_padding_type; /** - * Encode a field value to 32 bytes (0 padded) + * Encode a field value to 32 bytes (padded) * * @param[in] value field value to encode * @param[in] length field length before encoding + * @param[in] ptype padding direction (LSB vs MSB) + * @param[in] pval value used for padding * @return encoded field value */ -static void *field_encode(const uint8_t *const value, uint8_t length, e_padding_type ptype) +static void *field_encode(const uint8_t *const value, + uint8_t length, + e_padding_type ptype, + uint8_t pval) { uint8_t *padded_value; uint8_t start_idx; - if (length > 32) // sanity check + if (length > EIP_712_ENCODED_FIELD_LENGTH) // sanity check { return NULL; } - // 0-pad the value to 32 bytes if ((padded_value = mem_alloc(EIP_712_ENCODED_FIELD_LENGTH)) != NULL) { switch (ptype) { case MSB: - explicit_bzero(padded_value, EIP_712_ENCODED_FIELD_LENGTH - length); + memset(padded_value, pval, EIP_712_ENCODED_FIELD_LENGTH - length); start_idx = EIP_712_ENCODED_FIELD_LENGTH - length; break; case LSB: @@ -45,25 +49,46 @@ static void *field_encode(const uint8_t *const value, uint8_t length, e_padding_ default: return NULL; // should not be here } - for (uint8_t idx = 0; idx < length; ++idx) - { - padded_value[start_idx + idx] = value[idx]; - } + memcpy(&padded_value[start_idx], value, length); } return padded_value; } /** - * Encode an integer + * Encode an unsigned integer * * @param[in] value pointer to the "packed" integer received * @param[in] length its byte-length * @return the encoded value */ -void *encode_integer(const uint8_t *const value, uint8_t length) +void *encode_uint(const uint8_t *const value, uint8_t length) { // no length check here since it will be checked by field_encode - return field_encode(value, length, MSB); + return field_encode(value, length, MSB, 0x00); +} + +/** + * Encode a signed integer + * + * @param[in] value pointer to the "packed" integer received + * @param[in] length its byte-length + * @param[in] typesize the type size in bytes + * @return the encoded value + */ +void *encode_int(const uint8_t *const value, uint8_t length, uint8_t typesize) +{ + uint8_t padding_value; + + if ((length == typesize) && (value[0] & (1 << 7))) // negative number + { + padding_value = 0xFF; + } + else + { + padding_value = 0x00; + } + // no length check here since it will be checked by field_encode + return field_encode(value, length, MSB, padding_value); } /** @@ -76,7 +101,7 @@ void *encode_integer(const uint8_t *const value, uint8_t length) void *encode_bytes(const uint8_t *const value, uint8_t length) { // no length check here since it will be checked by field_encode - return field_encode(value, length, LSB); + return field_encode(value, length, LSB, 0x00); } /** @@ -92,7 +117,7 @@ void *encode_boolean(const bool *const value, uint8_t length) { return NULL; } - return encode_integer((uint8_t*)value, length); + return encode_uint((uint8_t*)value, length); } /** @@ -108,7 +133,7 @@ void *encode_address(const uint8_t *const value, uint8_t length) { return NULL; } - return encode_integer(value, length); + return encode_uint(value, length); } #endif // HAVE_EIP712_FULL_SUPPORT diff --git a/src_features/signMessageEIP712/encode_field.h b/src_features/signMessageEIP712/encode_field.h index 6bb58e4..a8e99f9 100644 --- a/src_features/signMessageEIP712/encode_field.h +++ b/src_features/signMessageEIP712/encode_field.h @@ -8,7 +8,8 @@ #define EIP_712_ENCODED_FIELD_LENGTH 32 -void *encode_integer(const uint8_t *const value, uint8_t length); +void *encode_uint(const uint8_t *const value, uint8_t length); +void *encode_int(const uint8_t *const value, uint8_t length, uint8_t typesize); void *encode_boolean(const bool *const value, uint8_t length); void *encode_address(const uint8_t *const value, uint8_t length); void *encode_bytes(const uint8_t *const value, uint8_t length); diff --git a/src_features/signMessageEIP712/field_hash.c b/src_features/signMessageEIP712/field_hash.c index da1a997..8e47d4b 100644 --- a/src_features/signMessageEIP712/field_hash.c +++ b/src_features/signMessageEIP712/field_hash.c @@ -115,8 +115,10 @@ bool field_hash(const uint8_t *data, switch (field_type) { case TYPE_SOL_INT: + value = encode_int(data, data_length, get_struct_field_typesize(field_ptr)); + break; case TYPE_SOL_UINT: - value = encode_integer(data, data_length); + value = encode_uint(data, data_length); break; case TYPE_SOL_BYTES_FIX: value = encode_bytes(data, data_length);