2016-10-11 15:09:35 +00:00
|
|
|
/*
|
2018-02-26 13:06:10 +00:00
|
|
|
* This file is part of the TREZOR project, https://trezor.io/
|
2016-10-11 15:09:35 +00:00
|
|
|
*
|
2018-02-26 13:06:10 +00:00
|
|
|
* Copyright (c) SatoshiLabs
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2016-10-11 15:09:35 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "py/runtime.h"
|
|
|
|
|
2018-02-23 20:27:26 +00:00
|
|
|
#include "version.h"
|
|
|
|
|
2016-10-11 15:09:35 +00:00
|
|
|
#if MICROPY_PY_TREZORUTILS
|
|
|
|
|
2017-05-15 13:48:47 +00:00
|
|
|
#include <string.h>
|
2017-04-17 15:57:42 +00:00
|
|
|
#include "common.h"
|
|
|
|
|
2017-09-26 15:26:34 +00:00
|
|
|
/// def consteq(sec: bytes, pub: bytes) -> bool:
|
|
|
|
/// '''
|
|
|
|
/// Compares the private information in `sec` with public, user-provided
|
|
|
|
/// information in `pub`. Runs in constant time, corresponding to a length
|
|
|
|
/// of `pub`. Can access memory behind valid length of `sec`, caller is
|
|
|
|
/// expected to avoid any invalid memory access.
|
|
|
|
/// '''
|
|
|
|
STATIC mp_obj_t mod_trezorutils_consteq(mp_obj_t sec, mp_obj_t pub) {
|
|
|
|
mp_buffer_info_t secbuf;
|
|
|
|
mp_get_buffer_raise(sec, &secbuf, MP_BUFFER_READ);
|
|
|
|
mp_buffer_info_t pubbuf;
|
|
|
|
mp_get_buffer_raise(pub, &pubbuf, MP_BUFFER_READ);
|
|
|
|
|
|
|
|
size_t diff = secbuf.len - pubbuf.len;
|
|
|
|
for (size_t i = 0; i < pubbuf.len; i++) {
|
|
|
|
const uint8_t *s = (uint8_t *)secbuf.buf;
|
|
|
|
const uint8_t *p = (uint8_t *)pubbuf.buf;
|
|
|
|
diff |= s[i] - p[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (diff == 0) {
|
|
|
|
return mp_const_true;
|
|
|
|
} else {
|
|
|
|
return mp_const_false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorutils_consteq_obj, mod_trezorutils_consteq);
|
|
|
|
|
2017-06-14 15:40:50 +00:00
|
|
|
/// def memcpy(dst: bytearray, dst_ofs: int,
|
|
|
|
/// src: bytearray, src_ofs: int,
|
|
|
|
/// n: int) -> int:
|
2016-10-11 15:09:35 +00:00
|
|
|
/// '''
|
|
|
|
/// Copies at most `n` bytes from `src` at offset `src_ofs` to
|
|
|
|
/// `dst` at offset `dst_ofs`. Returns the number of actually
|
|
|
|
/// copied bytes.
|
|
|
|
/// '''
|
2017-06-14 16:47:38 +00:00
|
|
|
STATIC mp_obj_t mod_trezorutils_memcpy(size_t n_args, const mp_obj_t *args) {
|
2016-10-11 15:09:35 +00:00
|
|
|
mp_arg_check_num(n_args, 0, 5, 5, false);
|
|
|
|
|
|
|
|
mp_buffer_info_t dst;
|
|
|
|
mp_get_buffer_raise(args[0], &dst, MP_BUFFER_WRITE);
|
|
|
|
int dst_ofs = mp_obj_get_int(args[1]);
|
|
|
|
if (dst_ofs < 0) {
|
|
|
|
mp_raise_ValueError("Invalid dst offset (has to be >= 0)");
|
|
|
|
}
|
|
|
|
|
|
|
|
mp_buffer_info_t src;
|
|
|
|
mp_get_buffer_raise(args[2], &src, MP_BUFFER_READ);
|
|
|
|
int src_ofs = mp_obj_get_int(args[3]);
|
|
|
|
if (src_ofs < 0) {
|
|
|
|
mp_raise_ValueError("Invalid src offset (has to be >= 0)");
|
|
|
|
}
|
|
|
|
|
|
|
|
int n = mp_obj_get_int(args[4]);
|
|
|
|
if (n < 0) {
|
|
|
|
mp_raise_ValueError("Invalid byte count (has to be >= 0)");
|
|
|
|
}
|
|
|
|
size_t dst_rem = (dst_ofs < dst.len) ? dst.len - dst_ofs : 0;
|
|
|
|
size_t src_rem = (src_ofs < src.len) ? src.len - src_ofs : 0;
|
|
|
|
size_t ncpy = MIN(n, MIN(src_rem, dst_rem));
|
|
|
|
|
|
|
|
memmove(((char*)dst.buf) + dst_ofs, ((const char*)src.buf) + src_ofs, ncpy);
|
|
|
|
|
|
|
|
return mp_obj_new_int(ncpy);
|
|
|
|
}
|
2017-06-14 16:47:38 +00:00
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_memcpy_obj, 5, 5, mod_trezorutils_memcpy);
|
2016-10-11 15:09:35 +00:00
|
|
|
|
2017-06-14 15:40:50 +00:00
|
|
|
/// def halt(msg: str = None) -> None:
|
2016-11-19 14:21:39 +00:00
|
|
|
/// '''
|
2017-06-14 15:40:50 +00:00
|
|
|
/// Halts execution.
|
2016-11-19 14:21:39 +00:00
|
|
|
/// '''
|
2017-06-14 16:47:38 +00:00
|
|
|
STATIC mp_obj_t mod_trezorutils_halt(size_t n_args, const mp_obj_t *args) {
|
2016-11-19 14:30:46 +00:00
|
|
|
mp_buffer_info_t msg;
|
|
|
|
if (n_args > 0 && mp_get_buffer(args[0], &msg, MP_BUFFER_READ)) {
|
2017-10-26 21:51:39 +00:00
|
|
|
ensure(secfalse, msg.buf);
|
2016-11-19 14:30:46 +00:00
|
|
|
} else {
|
2017-10-26 21:51:39 +00:00
|
|
|
ensure(secfalse, "halt");
|
2016-11-19 14:30:46 +00:00
|
|
|
}
|
2016-11-19 14:21:39 +00:00
|
|
|
return mp_const_none;
|
|
|
|
}
|
2017-06-14 16:47:38 +00:00
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_halt_obj, 0, 1, mod_trezorutils_halt);
|
2016-11-19 14:21:39 +00:00
|
|
|
|
2018-02-23 18:08:34 +00:00
|
|
|
/// def set_mode_unprivileged() -> None:
|
|
|
|
/// '''
|
|
|
|
/// Set unprivileged mode.
|
|
|
|
/// '''
|
|
|
|
STATIC mp_obj_t mod_trezorutils_set_mode_unprivileged(void) {
|
|
|
|
#if defined TREZOR_STM32
|
|
|
|
__asm__ volatile("msr control, %0" :: "r" (0x1));
|
|
|
|
__asm__ volatile("isb");
|
|
|
|
#endif
|
|
|
|
return mp_const_none;
|
|
|
|
}
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_set_mode_unprivileged_obj, mod_trezorutils_set_mode_unprivileged);
|
|
|
|
|
2018-02-23 20:27:26 +00:00
|
|
|
/// def symbol(name: str) -> str/int/None:
|
|
|
|
/// '''
|
|
|
|
/// Retrieve internal symbol.
|
|
|
|
/// '''
|
|
|
|
STATIC mp_obj_t mod_trezorutils_symbol(mp_obj_t name) {
|
|
|
|
mp_buffer_info_t str;
|
|
|
|
mp_get_buffer_raise(name, &str, MP_BUFFER_READ);
|
|
|
|
if (0 == strncmp(str.buf, "GITREV", str.len)) {
|
|
|
|
#define XSTR(s) STR(s)
|
|
|
|
#define STR(s) #s
|
|
|
|
return mp_obj_new_str(XSTR(GITREV), strlen(XSTR(GITREV)), false);
|
|
|
|
}
|
|
|
|
if (0 == strncmp(str.buf, "VERSION_MAJOR", str.len)) {
|
|
|
|
return mp_obj_new_int(VERSION_MAJOR);
|
|
|
|
}
|
|
|
|
if (0 == strncmp(str.buf, "VERSION_MINOR", str.len)) {
|
|
|
|
return mp_obj_new_int(VERSION_MINOR);
|
|
|
|
}
|
|
|
|
if (0 == strncmp(str.buf, "VERSION_PATCH", str.len)) {
|
|
|
|
return mp_obj_new_int(VERSION_PATCH);
|
|
|
|
}
|
|
|
|
return mp_const_none;
|
|
|
|
}
|
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorutils_symbol_obj, mod_trezorutils_symbol);
|
|
|
|
|
2017-06-14 16:47:38 +00:00
|
|
|
STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = {
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorutils) },
|
2017-09-26 15:26:34 +00:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_consteq), MP_ROM_PTR(&mod_trezorutils_consteq_obj) },
|
2017-06-14 16:47:38 +00:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_memcpy), MP_ROM_PTR(&mod_trezorutils_memcpy_obj) },
|
|
|
|
{ MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&mod_trezorutils_halt_obj) },
|
2018-02-23 18:08:34 +00:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_set_mode_unprivileged), MP_ROM_PTR(&mod_trezorutils_set_mode_unprivileged_obj) },
|
2018-02-23 20:27:26 +00:00
|
|
|
{ MP_ROM_QSTR(MP_QSTR_symbol), MP_ROM_PTR(&mod_trezorutils_symbol_obj) },
|
2016-10-11 15:09:35 +00:00
|
|
|
};
|
|
|
|
|
2017-06-14 16:47:38 +00:00
|
|
|
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorutils_globals, mp_module_trezorutils_globals_table);
|
2016-10-11 15:09:35 +00:00
|
|
|
|
2017-06-14 16:47:38 +00:00
|
|
|
const mp_obj_module_t mp_module_trezorutils = {
|
2016-10-11 15:09:35 +00:00
|
|
|
.base = { &mp_type_module },
|
2017-06-14 16:47:38 +00:00
|
|
|
.globals = (mp_obj_dict_t*)&mp_module_trezorutils_globals,
|
2016-10-11 15:09:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // MICROPY_PY_TREZORUTILS
|