1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-28 08:11:02 +00:00

refactor(core): unify arg parsing in syscall dispatch

[no changelog]
This commit is contained in:
cepetr 2024-09-24 11:29:36 +02:00 committed by cepetr
parent da7ddd5c8c
commit 305f16c86b

View File

@ -70,18 +70,26 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
switch (syscall) {
case SYSCALL_SYSTEM_EXIT: {
systask_t *task = systask_active();
systask_exit(task, (int)args[0]);
int exit_code = (int)args[0];
systask_exit(task, exit_code);
} break;
case SYSCALL_SYSTEM_EXIT_ERROR: {
systask_t *task = systask_active();
systask_exit_error(task, (const char *)args[0], (const char *)args[1],
(const char *)args[2]);
const char *title = (const char *)args[0];
const char *message = (const char *)args[1];
const char *footer = (const char *)args[2];
systask_exit_error(task, title, message, footer);
} break;
case SYSCALL_SYSTEM_EXIT_FATAL: {
systask_t *task = systask_active();
systask_exit_fatal(task, (const char *)args[0], (const char *)args[1],
(int)args[2]);
const char *message = (const char *)args[0];
const char *file = (const char *)args[1];
int line = (int)args[2];
systask_exit_fatal(task, message, file, line);
} break;
case SYSCALL_SYSTICK_CYCLES: {
uint64_t cycles = systick_cycles();
args[0] = cycles & 0xFFFFFFFF;
@ -94,9 +102,9 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
args[1] = cycles >> 32;
} break;
case SYSCALL_SYSTICK_MS:
case SYSCALL_SYSTICK_MS: {
args[0] = systick_ms();
break;
} break;
case SYSCALL_SYSTICK_US_TO_CYCLES: {
uint64_t us = args[0] + ((uint64_t)args[1] << 32);
@ -105,35 +113,42 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
args[1] = cycles >> 32;
} break;
case SYSCALL_SECURE_SHUTDOWN:
case SYSCALL_SECURE_SHUTDOWN: {
secure_shutdown();
break;
case SYSCALL_REBOOT_DEVICE:
reboot_device();
break;
case SYSCALL_REBOOT_TO_BOOTLOADER:
} break;
case SYSCALL_REBOOT_DEVICE: {
reboot();
} break;
case SYSCALL_REBOOT_TO_BOOTLOADER: {
reboot_to_bootloader();
break;
case SYSCALL_REBOOT_AND_UPGRADE:
reboot_and_upgrade((uint8_t *)args[0]);
break;
} break;
case SYSCALL_REBOOT_AND_UPGRADE: {
const uint8_t *hash = (const uint8_t *)args[0];
reboot_and_upgrade(hash);
} break;
#ifdef STM32U5
case SYSCALL_SHA256_INIT: {
hash_sha256_context_t *ctx = (hash_sha256_context_t *)args[0];
hash_processor_sha256_init(ctx);
} break;
case SYSCALL_SHA256_UPDATE: {
hash_sha256_context_t *ctx = (hash_sha256_context_t *)args[0];
const uint8_t *data = (const uint8_t *)args[1];
uint32_t len = args[2];
hash_processor_sha256_update(ctx, data, len);
} break;
case SYSCALL_SHA256_FINAL: {
hash_sha256_context_t *ctx = (hash_sha256_context_t *)args[0];
uint8_t *output = (uint8_t *)args[1];
hash_processor_sha256_final(ctx, output);
} break;
case SYSCALL_SHA256_CALC: {
const uint8_t *data = (const uint8_t *)args[0];
uint32_t len = args[1];
@ -143,18 +158,23 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
#endif // STM32U5
case SYSCALL_DISPLAY_SET_BACKLIGHT: {
args[0] = display_set_backlight((int)args[0]);
int level = (int)args[0];
args[0] = display_set_backlight(level);
} break;
case SYSCALL_DISPLAY_GET_BACKLIGHT: {
args[0] = display_get_backlight();
} break;
case SYSCALL_DISPLAY_SET_ORIENTATION: {
args[0] = display_set_orientation((int)args[0]);
int angle = (int)args[0];
args[0] = display_set_orientation(angle);
} break;
case SYSCALL_DISPLAY_GET_ORIENTATION: {
args[0] = display_get_orientation();
} break;
#if XFRAMEBUFFER
case SYSCALL_DISPLAY_GET_FB_INFO: {
display_fb_info_t *info = (display_fb_info_t *)args[0];
@ -165,192 +185,291 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
display_wait_for_sync();
} break;
#endif
case SYSCALL_DISPLAY_FILL: {
const gfx_bitblt_t *bb = (const gfx_bitblt_t *)args[0];
display_fill(bb);
} break;
#ifdef USE_RGB_COLORS
case SYSCALL_DISPLAY_COPY_RGB565: {
const gfx_bitblt_t *bb = (const gfx_bitblt_t *)args[0];
display_copy_rgb565(bb);
} break;
#endif
case SYSCALL_DISPLAY_REFRESH: {
display_refresh();
} break;
case SYSCALL_USB_INIT: {
const usb_dev_info_t *dev_info = (const usb_dev_info_t *)args[0];
args[0] = usb_init(dev_info);
} break;
case SYSCALL_USB_DEINIT: {
usb_deinit();
} break;
case SYSCALL_USB_START: {
args[0] = usb_start();
} break;
case SYSCALL_USB_STOP: {
usb_stop();
} break;
case SYSCALL_USB_CONFIGURED: {
args[0] = usb_configured();
} break;
case SYSCALL_USB_HID_ADD: {
args[0] = usb_hid_add((const usb_hid_info_t *)args[0]);
const usb_hid_info_t *hid_info = (const usb_hid_info_t *)args[0];
args[0] = usb_hid_add(hid_info);
} break;
case SYSCALL_USB_HID_CAN_READ: {
args[0] = usb_hid_can_read((uint8_t)args[0]);
uint8_t iface_num = (uint8_t)args[0];
args[0] = usb_hid_can_read(iface_num);
} break;
case SYSCALL_USB_HID_CAN_WRITE: {
args[0] = usb_hid_can_write((uint8_t)args[0]);
uint8_t iface_num = (uint8_t)args[0];
args[0] = usb_hid_can_write(iface_num);
} break;
case SYSCALL_USB_HID_READ: {
args[0] = usb_hid_read((uint8_t)args[0], (uint8_t *)args[1], args[2]);
uint8_t iface_num = (uint8_t)args[0];
uint8_t *buf = (uint8_t *)args[1];
uint32_t len = args[2];
args[0] = usb_hid_read(iface_num, buf, len);
} break;
case SYSCALL_USB_HID_WRITE: {
args[0] =
usb_hid_write((uint8_t)args[0], (const uint8_t *)args[1], args[2]);
uint8_t iface_num = (uint8_t)args[0];
const uint8_t *buf = (const uint8_t *)args[1];
uint32_t len = args[2];
args[0] = usb_hid_write(iface_num, buf, len);
} break;
case SYSCALL_USB_HID_READ_SELECT: {
args[0] = usb_hid_read_select((uint32_t)args[0]);
uint32_t timeout = args[0];
args[0] = usb_hid_read_select(timeout);
} break;
case SYSCALL_USB_HID_READ_BLOCKING: {
args[0] = usb_hid_read_blocking((uint8_t)args[0], (uint8_t *)args[1],
args[2], (int)args[3]);
uint8_t iface_num = (uint8_t)args[0];
uint8_t *buf = (uint8_t *)args[1];
uint32_t len = args[2];
int timeout = (int)args[3];
args[0] = usb_hid_read_blocking(iface_num, buf, len, timeout);
} break;
case SYSCALL_USB_HID_WRITE_BLOCKING: {
args[0] = usb_hid_write_blocking(
(uint8_t)args[0], (const uint8_t *)args[1], args[2], (int)args[3]);
uint8_t iface_num = (uint8_t)args[0];
const uint8_t *buf = (const uint8_t *)args[1];
uint32_t len = args[2];
int timeout = (int)args[3];
args[0] = usb_hid_write_blocking(iface_num, buf, len, timeout);
} break;
case SYSCALL_USB_VCP_ADD: {
args[0] = usb_vcp_add((const usb_vcp_info_t *)args[0]);
const usb_vcp_info_t *vcp_info = (const usb_vcp_info_t *)args[0];
args[0] = usb_vcp_add(vcp_info);
} break;
case SYSCALL_USB_VCP_CAN_READ: {
args[0] = usb_vcp_can_read((uint8_t)args[0]);
uint8_t iface_num = (uint8_t)args[0];
args[0] = usb_vcp_can_read(iface_num);
} break;
case SYSCALL_USB_VCP_CAN_WRITE: {
args[0] = usb_vcp_can_write((uint8_t)args[0]);
uint8_t iface_num = (uint8_t)args[0];
args[0] = usb_vcp_can_write(iface_num);
} break;
case SYSCALL_USB_VCP_READ: {
args[0] = usb_vcp_read((uint8_t)args[0], (uint8_t *)args[1], args[2]);
uint8_t iface_num = (uint8_t)args[0];
uint8_t *buf = (uint8_t *)args[1];
uint32_t len = args[2];
args[0] = usb_vcp_read(iface_num, buf, len);
} break;
case SYSCALL_USB_VCP_WRITE: {
args[0] =
usb_vcp_write((uint8_t)args[0], (const uint8_t *)args[1], args[2]);
uint8_t iface_num = (uint8_t)args[0];
const uint8_t *buf = (const uint8_t *)args[1];
uint32_t len = args[2];
args[0] = usb_vcp_write(iface_num, buf, len);
} break;
case SYSCALL_USB_VCP_READ_BLOCKING: {
args[0] = usb_vcp_read_blocking((uint8_t)args[0], (uint8_t *)args[1],
args[2], (int)args[3]);
uint8_t iface_num = (uint8_t)args[0];
uint8_t *buf = (uint8_t *)args[1];
uint32_t len = args[2];
int timeout = (int)args[3];
args[0] = usb_vcp_read_blocking(iface_num, buf, len, timeout);
} break;
case SYSCALL_USB_VCP_WRITE_BLOCKING: {
args[0] = usb_vcp_write_blocking(
(uint8_t)args[0], (const uint8_t *)args[1], args[2], (int)args[3]);
uint8_t iface_num = (uint8_t)args[0];
const uint8_t *buf = (const uint8_t *)args[1];
uint32_t len = args[2];
int timeout = (int)args[3];
args[0] = usb_vcp_write_blocking(iface_num, buf, len, timeout);
} break;
case SYSCALL_USB_WEBUSB_ADD: {
args[0] = usb_webusb_add((const usb_webusb_info_t *)args[0]);
const usb_webusb_info_t *webusb_info = (const usb_webusb_info_t *)args[0];
args[0] = usb_webusb_add(webusb_info);
} break;
case SYSCALL_USB_WEBUSB_CAN_READ: {
args[0] = usb_webusb_can_read((uint8_t)args[0]);
uint8_t iface_num = (uint8_t)args[0];
args[0] = usb_webusb_can_read(iface_num);
} break;
case SYSCALL_USB_WEBUSB_CAN_WRITE: {
args[0] = usb_webusb_can_write((uint8_t)args[0]);
uint8_t iface_num = (uint8_t)args[0];
args[0] = usb_webusb_can_write(iface_num);
} break;
case SYSCALL_USB_WEBUSB_READ: {
args[0] = usb_webusb_read((uint8_t)args[0], (uint8_t *)args[1], args[2]);
uint8_t iface_num = (uint8_t)args[0];
uint8_t *buf = (uint8_t *)args[1];
uint32_t len = args[2];
args[0] = usb_webusb_read(iface_num, buf, len);
} break;
case SYSCALL_USB_WEBUSB_WRITE: {
args[0] =
usb_webusb_write((uint8_t)args[0], (const uint8_t *)args[1], args[2]);
uint8_t iface_num = (uint8_t)args[0];
const uint8_t *buf = (const uint8_t *)args[1];
uint32_t len = args[2];
args[0] = usb_webusb_write(iface_num, buf, len);
} break;
case SYSCALL_USB_WEBUSB_READ_SELECT: {
args[0] = usb_webusb_read_select((uint32_t)args[0]);
uint32_t timeout = args[0];
args[0] = usb_webusb_read_select(timeout);
} break;
case SYSCALL_USB_WEBUSB_READ_BLOCKING: {
args[0] = usb_webusb_read_blocking((uint8_t)args[0], (uint8_t *)args[1],
args[2], (int)args[3]);
uint8_t iface_num = (uint8_t)args[0];
uint8_t *buf = (uint8_t *)args[1];
uint32_t len = args[2];
int timeout = (int)args[3];
args[0] = usb_webusb_read_blocking(iface_num, buf, len, timeout);
} break;
case SYSCALL_USB_WEBUSB_WRITE_BLOCKING: {
args[0] = usb_webusb_write_blocking(
(uint8_t)args[0], (const uint8_t *)args[1], args[2], (int)args[3]);
uint8_t iface_num = (uint8_t)args[0];
const uint8_t *buf = (const uint8_t *)args[1];
uint32_t len = args[2];
int timeout = (int)args[3];
args[0] = usb_webusb_write_blocking(iface_num, buf, len, timeout);
} break;
#ifdef USE_SD_CARD
case SYSCALL_SDCARD_POWER_ON: {
args[0] = sdcard_power_on();
} break;
case SYSCALL_SDCARD_POWER_OFF: {
sdcard_power_off();
} break;
case SYSCALL_SDCARD_IS_PRESENT: {
args[0] = sdcard_is_present();
} break;
case SYSCALL_SDCARD_GET_CAPACITY: {
args[0] = sdcard_get_capacity_in_bytes();
} break;
case SYSCALL_SDCARD_READ_BLOCKS: {
args[0] = sdcard_read_blocks((uint32_t *)args[0], args[1], args[2]);
uint32_t *dest = (uint32_t *)args[0];
uint32_t block_num = args[1];
uint32_t num_blocks = args[2];
args[0] = sdcard_read_blocks(dest, block_num, num_blocks);
} break;
case SYSCALL_SDCARD_WRITE_BLOCKS: {
args[0] =
sdcard_write_blocks((const uint32_t *)args[0], args[1], args[2]);
const uint32_t *src = (const uint32_t *)args[0];
uint32_t block_num = args[1];
uint32_t num_blocks = args[2];
args[0] = sdcard_write_blocks(src, block_num, num_blocks);
} break;
#endif
case SYSCALL_UNIT_VARIANT_PRESENT: {
args[0] = unit_variant_present();
} break;
case SYSCALL_UNIT_VARIANT_GET_COLOR: {
args[0] = unit_variant_get_color();
} break;
case SYSCALL_UNIT_VARIANT_GET_PACKAGING: {
args[0] = unit_variant_get_packaging();
} break;
case SYSCALL_UNIT_VARIANT_GET_BTCONLY: {
args[0] = unit_variant_get_btconly();
} break;
case SYSCALL_UNIT_VARIANT_IS_SD_HOTSWAP_ENABLED: {
args[0] = unit_variant_is_sd_hotswap_enabled();
} break;
case SYSCALL_SECRET_BOOTLOADER_LOCKED: {
args[0] = secret_bootloader_locked();
} break;
#ifdef USE_BUTTON
case SYSCALL_BUTTON_READ: {
args[0] = button_read();
} break;
#endif
#ifdef USE_TOUCH
case SYSCALL_TOUCH_GET_EVENT: {
args[0] = touch_get_event();
} break;
#endif
#ifdef USE_HAPTIC
case SYSCALL_HAPTIC_SET_ENABLED: {
haptic_set_enabled(args[0]);
bool enabled = (args[0] != 0);
haptic_set_enabled(enabled);
} break;
case SYSCALL_HAPTIC_GET_ENABLED: {
args[0] = haptic_get_enabled();
} break;
case SYSCALL_HAPTIC_TEST: {
args[0] = haptic_test(args[0]);
uint16_t duration_ms = (uint16_t)args[0];
args[0] = haptic_test(duration_ms);
} break;
case SYSCALL_HAPTIC_PLAY: {
args[0] = haptic_play(args[0]);
haptic_effect_t effect = (haptic_effect_t)args[0];
args[0] = haptic_play(effect);
} break;
case SYSCALL_HAPTIC_PLAY_CUSTOM: {
args[0] = haptic_play_custom(args[0], args[1]);
int8_t amplitude_pct = (int8_t)args[1];
uint16_t duration_ms = (uint16_t)args[2];
args[0] = haptic_play_custom(amplitude_pct, duration_ms);
} break;
#endif
#ifdef USE_OPTIGA
/*optiga_sign_result optiga_sign(uint8_t index, const uint8_t *digest,
size_t digest_size, uint8_t
*signature, size_t max_sig_size, size_t *sig_size);
*/
case SYSCALL_OPTIGA_CERT_SIZE: {
uint8_t index = args[0];
size_t *cert_size = (size_t *)args[1];
args[0] = optiga_cert_size(index, cert_size);
} break;
case SYSCALL_OPTIGA_READ_CERT: {
uint8_t index = args[0];
uint8_t *cert = (uint8_t *)args[1];
@ -358,21 +477,25 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
size_t *cert_size = (size_t *)args[3];
args[0] = optiga_read_cert(index, cert, max_cert_size, cert_size);
} break;
case SYSCALL_OPTIGA_READ_SEC: {
uint8_t *sec = (uint8_t *)args[0];
args[0] = optiga_read_sec(sec);
} break;
case SYSCALL_OPTIGA_RANDOM_BUFFER: {
uint8_t *dest = (uint8_t *)args[0];
size_t size = args[1];
args[0] = optiga_random_buffer(dest, size);
} break;
#if PYOPT == 0
case SYSCALL_OPTIGA_SET_SEC_MAX: {
optiga_set_sec_max();
} break;
#endif
#endif
case SYSCALL_STORAGE_INIT: {
storage_init_callback = (PIN_UI_WAIT_CALLBACK)args[0];
const uint8_t *salt = (const uint8_t *)args[1];
@ -380,18 +503,22 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
mpu_reconfig(MPU_MODE_STORAGE);
storage_init(storage_init_callback_wrapper, salt, salt_len);
} break;
case SYSCALL_STORAGE_WIPE: {
mpu_reconfig(MPU_MODE_STORAGE);
storage_wipe();
} break;
case SYSCALL_STORAGE_IS_UNLOCKED: {
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_is_unlocked();
} break;
case SYSCALL_STORAGE_LOCK: {
mpu_reconfig(MPU_MODE_STORAGE);
storage_lock();
} break;
case SYSCALL_STORAGE_UNLOCK: {
const uint8_t *pin = (const uint8_t *)args[0];
size_t pin_len = args[1];
@ -399,18 +526,22 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_unlock(pin, pin_len, ext_salt);
} break;
case SYSCALL_STORAGE_HAS_PIN: {
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_has_pin();
} break;
case SYSCALL_STORAGE_PIN_FAILS_INCREASE: {
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_pin_fails_increase();
} break;
case SYSCALL_STORAGE_GET_PIN_REM: {
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_get_pin_rem();
} break;
case SYSCALL_STORAGE_CHANGE_PIN: {
const uint8_t *oldpin = (const uint8_t *)args[0];
size_t oldpin_len = args[1];
@ -422,16 +553,19 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
args[0] = storage_change_pin(oldpin, oldpin_len, newpin, newpin_len,
old_ext_salt, new_ext_salt);
} break;
case SYSCALL_STORAGE_ENSURE_NOT_WIPE_CODE: {
const uint8_t *pin = (const uint8_t *)args[0];
size_t pin_len = args[1];
mpu_reconfig(MPU_MODE_STORAGE);
storage_ensure_not_wipe_code(pin, pin_len);
} break;
case SYSCALL_STORAGE_HAS_WIPE_CODE: {
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_has_wipe_code();
} break;
case SYSCALL_STORAGE_CHANGE_WIPE_CODE: {
const uint8_t *pin = (const uint8_t *)args[0];
size_t pin_len = args[1];
@ -442,9 +576,11 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
args[0] = storage_change_wipe_code(pin, pin_len, ext_salt, wipe_code,
wipe_code_len);
} break;
case SYSCALL_STORAGE_HAS: {
uint16_t key = (uint16_t)args[0];
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_has((uint16_t)args[0]);
args[0] = storage_has(key);
} break;
case SYSCALL_STORAGE_GET: {
@ -455,6 +591,7 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_get(key, val, max_len, len);
} break;
case SYSCALL_STORAGE_SET: {
uint16_t key = (uint16_t)args[0];
const void *val = (const void *)args[1];
@ -462,45 +599,63 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_set(key, val, len);
} break;
case SYSCALL_STORAGE_DELETE: {
uint16_t key = (uint16_t)args[0];
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_delete((uint16_t)args[0]);
args[0] = storage_delete(key);
} break;
case SYSCALL_STORAGE_SET_COUNTER: {
uint16_t key = (uint16_t)args[0];
uint32_t count = args[1];
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_set_counter((uint16_t)args[0], args[1]);
args[0] = storage_set_counter(key, count);
} break;
case SYSCALL_STORAGE_NEXT_COUNTER: {
uint16_t key = (uint16_t)args[0];
uint32_t *count = (uint32_t *)args[1];
mpu_reconfig(MPU_MODE_STORAGE);
args[0] = storage_next_counter((uint16_t)args[0], (uint32_t *)args[1]);
args[0] = storage_next_counter(key, count);
} break;
case SYSCALL_ENTROPY_GET: {
uint8_t *buf = (uint8_t *)args[0];
entropy_get(buf);
} break;
case SYSCALL_TRANSLATIONS_WRITE: {
const uint8_t *data = (const uint8_t *)args[0];
uint32_t offset = args[1];
uint32_t len = args[2];
args[0] = translations_write(data, offset, len);
} break;
case SYSCALL_TRANSLATIONS_READ: {
uint32_t *len = (uint32_t *)args[0];
uint32_t offset = args[1];
args[0] = (uint32_t)translations_read(len, offset);
} break;
case SYSCALL_TRANSLATIONS_ERASE: {
translations_erase();
} break;
case SYSCALL_TRANSLATIONS_AREA_BYTESIZE: {
args[0] = translations_area_bytesize();
} break;
case SYSCALL_RNG_GET: {
args[0] = rng_get();
} break;
case SYSCALL_FIRMWARE_GET_VENDOR: {
args[0] = firmware_get_vendor((char *)args[0], args[1]);
char *buff = (char *)args[0];
size_t buff_size = args[1];
args[0] = firmware_get_vendor(buff, buff_size);
} break;
case SYSCALL_FIRMWARE_CALC_HASH: {
const uint8_t *challenge = (const uint8_t *)args[0];
size_t challenge_len = args[1];
@ -513,6 +668,7 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
firmware_calc_hash(challenge, challenge_len, hash, hash_len,
firmware_hash_callback_wrapper, callback_context);
} break;
default:
args[0] = 0xffffffff;
break;