diff --git a/core/embed/lib/display.h b/core/embed/lib/display.h
index bdad4717b..b4c3ed1a2 100644
--- a/core/embed/lib/display.h
+++ b/core/embed/lib/display.h
@@ -69,8 +69,4 @@ void display_qrcode(int x, int y, const char *data, uint8_t scale);
void display_offset(int set_xy[2], int *get_x, int *get_y);
void display_fade(int start, int end, int delay);
-// helper for locating a substring in buffer with utf-8 string
-void display_utf8_substr(const char *buf_start, size_t buf_len, int char_off,
- int char_len, const char **out_start, int *out_len);
-
#endif
diff --git a/core/embed/lib/utf8.c b/core/embed/lib/utf8.c
new file mode 100644
index 000000000..c01a6b60a
--- /dev/null
+++ b/core/embed/lib/utf8.c
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * 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 .
+ */
+
+#include "utf8.h"
+
+#define UTF8_IS_CONT(ch) (((ch)&0xC0) == 0x80)
+
+void utf8_substr(const char *buf_start, size_t buf_len, int char_off,
+ int char_len, const char **out_start, int *out_len) {
+ size_t i = 0;
+
+ for (; i < buf_len; i++) {
+ if (char_off == 0) {
+ break;
+ }
+ if (!UTF8_IS_CONT(buf_start[i])) {
+ char_off--;
+ }
+ }
+ size_t i_start = i;
+
+ for (; i < buf_len; i++) {
+ if (char_len == 0) {
+ break;
+ }
+ if (!UTF8_IS_CONT(buf_start[i])) {
+ char_len--;
+ }
+ }
+
+ for (; i < buf_len; i++) {
+ if (!UTF8_IS_CONT(buf_start[i])) {
+ break;
+ }
+ }
+
+ *out_start = buf_start + i_start;
+ *out_len = i - i_start;
+}
diff --git a/core/embed/lib/utf8.h b/core/embed/lib/utf8.h
new file mode 100644
index 000000000..91ab267d9
--- /dev/null
+++ b/core/embed/lib/utf8.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * 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 .
+ */
+
+#ifndef LIB_UTF8_H
+#define LIB_UTF8_H
+
+#include
+#include
+
+// helper for locating a substring in buffer with utf-8 string
+void utf8_substr(const char *buf_start, size_t buf_len, int char_off,
+ int char_len, const char **out_start, int *out_len);
+
+#endif // LIB_UTF8_H
\ No newline at end of file