From 0493f229be451b1d216a40decf9673a1935c843f Mon Sep 17 00:00:00 2001 From: ftheirs Date: Mon, 20 Jun 2022 09:33:26 -0300 Subject: [PATCH 1/4] update docs --- README.md | 5 +++-- docs/img/clion_debugging.png | Bin 107484 -> 0 bytes docs/img/cosmos_app1.png | Bin 15105 -> 0 bytes docs/img/cosmos_app2.png | Bin 20554 -> 0 bytes docs/img/cosmos_app3.png | Bin 13197 -> 0 bytes docs/img/tendermint_app.png | Bin 11365 -> 0 bytes docs/zondax_dark.png | Bin 0 -> 83636 bytes docs/zondax_light.png | Bin 0 -> 83657 bytes 8 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 docs/img/clion_debugging.png delete mode 100644 docs/img/cosmos_app1.png delete mode 100644 docs/img/cosmos_app2.png delete mode 100644 docs/img/cosmos_app3.png delete mode 100644 docs/img/tendermint_app.png create mode 100644 docs/zondax_dark.png create mode 100644 docs/zondax_light.png diff --git a/README.md b/README.md index 23a9108..ac5c625 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,10 @@ --- -![zondax](docs/zondax.jpg) +![zondax_light](docs/zondax_light.png#gh-light-mode-only) +![zondax_dark](docs/zondax_dark.png#gh-dark-mode-only) -_Please visit our website at [zondax.ch](zondax.ch)_ +_Please visit our website at [zondax.ch](https://www.zondax.ch)_ --- diff --git a/docs/img/clion_debugging.png b/docs/img/clion_debugging.png deleted file mode 100644 index f26ff75908db78149134ed0b2ebd9ad6fcd5fdee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107484 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∨;${%nGo zxA(ochcak+xyB~b3p%KlUtsf;Mqj%*ABcE_go!Ed>pTOqXEI=LXaR)%>QC+mIC9)~ zZ*7hDnx4=dZ6R~N?t~`cy(~c^ga$iHA1z_eywGgZeT2BQX5&NKz3WvM{yu0@S1$5_ zwmxQ67*f}&%*6_2Y0z2#=y!*gOZR{|=dpd4g0U`Bht`NdQN`;E>{S?ONE)>oksCx-UzMydU03FRbaX;;dQRVE7g)!7C6C=cC${KdAWv!P_FrMl<>U?iuGUB(Y3XAg=@FC{9@ym^`p1XdxcBJ|r|2XINQbtPi z?d z-*&}&1-v{$u2J#ap#vEeqUI4suO+JS8iDS*LzDX(mGtL(zo-$3zc9M1AI_!)VZ>km eU%U5IGTl$__Q3se<$nf!4OWrg}U*x}*%{C*rW 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

%u>jH7fM>JM| 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 diff --git a/docs/img/cosmos_app3.png b/docs/img/cosmos_app3.png deleted file mode 100644 index 4011eeacf6688d28dc7e4dcc020fedc315e067b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13197 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 LC8?sPhJODGX_>4h diff --git a/docs/img/tendermint_app.png b/docs/img/tendermint_app.png deleted file mode 100644 index a21a37b0625ad497d07f502d06e8fef4a52a3a03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11365 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 diff --git a/docs/zondax_dark.png b/docs/zondax_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a6c22dfbf40721b0408f296f61647e370c5a2a34 GIT binary patch literal 83636 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⪻5COyX7 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 literal 0 HcmV?d00001 From 7aec9712579dc34f4587683ca65141bffdae5eeb Mon Sep 17 00:00:00 2001 From: ftheirs Date: Tue, 5 Jul 2022 08:32:25 -0300 Subject: [PATCH 2/4] remove zxlib source files --- deps/ledger-zxlib/.editorconfig | 16 - deps/ledger-zxlib/.github/workflows/main.yml | 29 - deps/ledger-zxlib/.gitignore | 4 - deps/ledger-zxlib/CMakeLists.txt | 57 - deps/ledger-zxlib/LICENSE | 201 -- deps/ledger-zxlib/README.md | 5 - deps/ledger-zxlib/app/common/view.c | 323 ---- deps/ledger-zxlib/app/common/view.h | 62 - deps/ledger-zxlib/app/common/view_internal.h | 135 -- deps/ledger-zxlib/app/common/view_s.c | 336 ---- deps/ledger-zxlib/app/common/view_x.c | 292 --- deps/ledger-zxlib/cmake/gtest/CMakeLists.txt | 31 - .../cmake/gtest/CMakeLists.txt.gtest.in | 16 - deps/ledger-zxlib/dockerized_build.mk | 326 ---- deps/ledger-zxlib/include/apdu_codes.h | 50 - deps/ledger-zxlib/include/app_mode.h | 37 - deps/ledger-zxlib/include/base58.h | 38 - deps/ledger-zxlib/include/base64.h | 29 - deps/ledger-zxlib/include/bech32.h | 39 - deps/ledger-zxlib/include/bignum.h | 35 - deps/ledger-zxlib/include/bittools.h | 37 - deps/ledger-zxlib/include/buffering.h | 67 - deps/ledger-zxlib/include/hexutils.h | 30 - deps/ledger-zxlib/include/segwit_addr.h | 101 - deps/ledger-zxlib/include/sigutils.h | 41 - deps/ledger-zxlib/include/timeutils.h | 62 - deps/ledger-zxlib/include/utf8.h | 1682 ----------------- deps/ledger-zxlib/include/view_templates.h | 168 -- deps/ledger-zxlib/include/zxerror.h | 107 -- deps/ledger-zxlib/include/zxformat.h | 367 ---- deps/ledger-zxlib/include/zxmacros.h | 117 -- deps/ledger-zxlib/include/zxmacros_ledger.h | 57 - deps/ledger-zxlib/include/zxmacros_x64.h | 40 - deps/ledger-zxlib/include/zxtypes.h | 30 - deps/ledger-zxlib/include/zxutils_ledger.h | 12 - deps/ledger-zxlib/include/zxversion.h | 20 - deps/ledger-zxlib/scripts/install_deps.sh | 34 - deps/ledger-zxlib/scripts/template.sh | 60 - deps/ledger-zxlib/src/app_mode.c | 85 - deps/ledger-zxlib/src/base58.c | 153 -- deps/ledger-zxlib/src/base64.c | 71 - deps/ledger-zxlib/src/bech32.c | 58 - deps/ledger-zxlib/src/bignum.c | 148 -- deps/ledger-zxlib/src/buffering.c | 95 - deps/ledger-zxlib/src/hexutils.c | 57 - deps/ledger-zxlib/src/segwit_addr.c | 191 -- deps/ledger-zxlib/src/sigutils.c | 115 -- deps/ledger-zxlib/src/timeutils.c | 508 ----- deps/ledger-zxlib/src/zxformat.c | 144 -- deps/ledger-zxlib/src/zxmacros.c | 68 - deps/ledger-zxlib/src/zxutils_ledger.c | 154 -- deps/ledger-zxlib/templates/Makefile.root | 29 - deps/ledger-zxlib/tests/asciify.cpp | 119 -- deps/ledger-zxlib/tests/base64.cpp | 57 - deps/ledger-zxlib/tests/bech32.cpp | 83 - deps/ledger-zxlib/tests/bip44path.cpp | 89 - deps/ledger-zxlib/tests/buffering_tests.cpp | 229 --- deps/ledger-zxlib/tests/doubledabble.cpp | 164 -- deps/ledger-zxlib/tests/hexutils.cpp | 51 - deps/ledger-zxlib/tests/macros.cpp | 502 ----- deps/ledger-zxlib/tests/sigutils.cpp | 133 -- deps/ledger-zxlib/tests/zxformat.cpp | 97 - 62 files changed, 8493 deletions(-) delete mode 100644 deps/ledger-zxlib/.editorconfig delete mode 100644 deps/ledger-zxlib/.github/workflows/main.yml delete mode 100644 deps/ledger-zxlib/.gitignore delete mode 100644 deps/ledger-zxlib/CMakeLists.txt delete mode 100644 deps/ledger-zxlib/LICENSE delete mode 100644 deps/ledger-zxlib/README.md delete mode 100644 deps/ledger-zxlib/app/common/view.c delete mode 100644 deps/ledger-zxlib/app/common/view.h delete mode 100644 deps/ledger-zxlib/app/common/view_internal.h delete mode 100644 deps/ledger-zxlib/app/common/view_s.c delete mode 100644 deps/ledger-zxlib/app/common/view_x.c delete mode 100644 deps/ledger-zxlib/cmake/gtest/CMakeLists.txt delete mode 100644 deps/ledger-zxlib/cmake/gtest/CMakeLists.txt.gtest.in delete mode 100644 deps/ledger-zxlib/dockerized_build.mk delete mode 100644 deps/ledger-zxlib/include/apdu_codes.h delete mode 100644 deps/ledger-zxlib/include/app_mode.h delete mode 100644 deps/ledger-zxlib/include/base58.h delete mode 100644 deps/ledger-zxlib/include/base64.h delete mode 100644 deps/ledger-zxlib/include/bech32.h delete mode 100644 deps/ledger-zxlib/include/bignum.h delete mode 100644 deps/ledger-zxlib/include/bittools.h delete mode 100644 deps/ledger-zxlib/include/buffering.h delete mode 100644 deps/ledger-zxlib/include/hexutils.h delete mode 100644 deps/ledger-zxlib/include/segwit_addr.h delete mode 100644 deps/ledger-zxlib/include/sigutils.h delete mode 100644 deps/ledger-zxlib/include/timeutils.h delete mode 100644 deps/ledger-zxlib/include/utf8.h delete mode 100644 deps/ledger-zxlib/include/view_templates.h delete mode 100644 deps/ledger-zxlib/include/zxerror.h delete mode 100644 deps/ledger-zxlib/include/zxformat.h delete mode 100644 deps/ledger-zxlib/include/zxmacros.h delete mode 100644 deps/ledger-zxlib/include/zxmacros_ledger.h delete mode 100644 deps/ledger-zxlib/include/zxmacros_x64.h delete mode 100644 deps/ledger-zxlib/include/zxtypes.h delete mode 100644 deps/ledger-zxlib/include/zxutils_ledger.h delete mode 100644 deps/ledger-zxlib/include/zxversion.h delete mode 100755 deps/ledger-zxlib/scripts/install_deps.sh delete mode 100755 deps/ledger-zxlib/scripts/template.sh delete mode 100644 deps/ledger-zxlib/src/app_mode.c delete mode 100644 deps/ledger-zxlib/src/base58.c delete mode 100644 deps/ledger-zxlib/src/base64.c delete mode 100644 deps/ledger-zxlib/src/bech32.c delete mode 100644 deps/ledger-zxlib/src/bignum.c delete mode 100644 deps/ledger-zxlib/src/buffering.c delete mode 100644 deps/ledger-zxlib/src/hexutils.c delete mode 100644 deps/ledger-zxlib/src/segwit_addr.c delete mode 100644 deps/ledger-zxlib/src/sigutils.c delete mode 100644 deps/ledger-zxlib/src/timeutils.c delete mode 100644 deps/ledger-zxlib/src/zxformat.c delete mode 100644 deps/ledger-zxlib/src/zxmacros.c delete mode 100644 deps/ledger-zxlib/src/zxutils_ledger.c delete mode 100644 deps/ledger-zxlib/templates/Makefile.root delete mode 100644 deps/ledger-zxlib/tests/asciify.cpp delete mode 100644 deps/ledger-zxlib/tests/base64.cpp delete mode 100644 deps/ledger-zxlib/tests/bech32.cpp delete mode 100644 deps/ledger-zxlib/tests/bip44path.cpp delete mode 100644 deps/ledger-zxlib/tests/buffering_tests.cpp delete mode 100644 deps/ledger-zxlib/tests/doubledabble.cpp delete mode 100644 deps/ledger-zxlib/tests/hexutils.cpp delete mode 100644 deps/ledger-zxlib/tests/macros.cpp delete mode 100644 deps/ledger-zxlib/tests/sigutils.cpp delete mode 100644 deps/ledger-zxlib/tests/zxformat.cpp diff --git a/deps/ledger-zxlib/.editorconfig b/deps/ledger-zxlib/.editorconfig deleted file mode 100644 index 2d7db14..0000000 --- a/deps/ledger-zxlib/.editorconfig +++ /dev/null @@ -1,16 +0,0 @@ -# top-most EditorConfig file -root = true - -[*] -charset = utf-8 -trim_trailing_whitespace = true -end_of_line = lf -insert_final_newline = true - -[*.{c,h,cpp,hpp}] -indent_style = space -indent_size = 4 - -[*.{yml,sh}] -indent_style = space -indent_size = 2 diff --git a/deps/ledger-zxlib/.github/workflows/main.yml b/deps/ledger-zxlib/.github/workflows/main.yml deleted file mode 100644 index 485c5c5..0000000 --- a/deps/ledger-zxlib/.github/workflows/main.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: "Test/Build" -on: - workflow_dispatch: - push: - pull_request: - branches: [ main ] - -jobs: - configure: - runs-on: ubuntu-latest - outputs: - uid_gid: ${{ steps.get-user.outputs.uid_gid }} - steps: - - id: get-user - run: echo "::set-output name=uid_gid::$(id -u):$(id -g)" - - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - submodules: true - - name: Install deps - run: | - sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10 - brew install conan - conan config install https://github.com/conan-io/conanclientcert.git - - run: cmake -DCMAKE_BUILD_TYPE=Debug . && make diff --git a/deps/ledger-zxlib/.gitignore b/deps/ledger-zxlib/.gitignore deleted file mode 100644 index d3d05a3..0000000 --- a/deps/ledger-zxlib/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ - -\.idea/ - -cmake-build-debug/ diff --git a/deps/ledger-zxlib/CMakeLists.txt b/deps/ledger-zxlib/CMakeLists.txt deleted file mode 100644 index a8937e7..0000000 --- a/deps/ledger-zxlib/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -#******************************************************************************* -#* (c) 2018 Zondax GmbH -#* -#* Licensed under the Apache License, Version 2.0 (the "License"); -#* you may not use this file except in compliance with the License. -#* You may obtain a copy of the License at -#* -#* http://www.apache.org/licenses/LICENSE-2.0 -#* -#* Unless required by applicable law or agreed to in writing, software -#* distributed under the License is distributed on an "AS IS" BASIS, -#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -#* See the License for the specific language governing permissions and -#* limitations under the License. -#******************************************************************************** -cmake_minimum_required(VERSION 3.0) -project(ledger-zxlib) - -set(CMAKE_CXX_STANDARD 11) - -add_subdirectory(cmake/gtest) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/include -) - -############### - -file(GLOB_RECURSE ZXLIB_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c - ) - -file(GLOB_RECURSE TESTS_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp - ) - -############### -set(BUILD_TESTS OFF CACHE BOOL "Enables tests") - -add_library(zxlib STATIC ${ZXLIB_SRC}) -target_include_directories(zxlib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) - -enable_testing() - -add_executable(zxlib_tests - ${TESTS_SRC} - ) - -target_include_directories(zxlib_tests PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${gtest_SOURCE_DIR}/include - ${gmock_SOURCE_DIR}/include - ) - -target_link_libraries(zxlib_tests gtest_main zxlib) - -add_test(ZXLIB_TESTS zxlib_tests) diff --git a/deps/ledger-zxlib/LICENSE b/deps/ledger-zxlib/LICENSE deleted file mode 100644 index 0fa613e..0000000 --- a/deps/ledger-zxlib/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018-2020 Zondax GmbH - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/deps/ledger-zxlib/README.md b/deps/ledger-zxlib/README.md deleted file mode 100644 index d75ac57..0000000 --- a/deps/ledger-zxlib/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# ledger-zxlib - -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -[![GithubActions](https://github.com/zondax/ledger-zxlib/actions/workflows/main.yml/badge.svg)](https://github.com/Zondax/ledger-zxlib/blob/main/.github/workflows/main.yaml) -[![CodeFactor](https://www.codefactor.io/repository/github/zondax/ledger-zxlib/badge)](https://www.codefactor.io/repository/github/zondax/ledger-zxlib) diff --git a/deps/ledger-zxlib/app/common/view.c b/deps/ledger-zxlib/app/common/view.c deleted file mode 100644 index 0a5fc19..0000000 --- a/deps/ledger-zxlib/app/common/view.c +++ /dev/null @@ -1,323 +0,0 @@ -/******************************************************************************* -* (c) 2018, 2019 Zondax GmbH -* (c) 2016 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "view.h" -#include "coin.h" -#include "view_internal.h" -#include "crypto.h" - -#include "actions.h" -#include "apdu_codes.h" -#include "ux.h" -#include "bagl.h" -#include "zxmacros.h" -#include "view_templates.h" -#include "tx.h" -#include "addr.h" -#include "app_mode.h" -#include "zxerror.h" - -#include -#include -#include - -view_t viewdata; - -void h_approve(__Z_UNUSED unsigned int _) { - zemu_log_stack("h_approve"); - - view_idle_show(0, NULL); - UX_WAIT(); - if (viewdata.viewfuncAccept != NULL) { - viewdata.viewfuncAccept(); - } -} - -void h_reject(__Z_UNUSED unsigned int _) { - zemu_log_stack("h_reject"); - - view_idle_show(0, NULL); - UX_WAIT(); - app_reject(); -} - -void h_error_accept(__Z_UNUSED unsigned int _) { - view_idle_show(0, NULL); - UX_WAIT(); - app_reply_error(); -} - -void h_initialize(__Z_UNUSED unsigned int _) { - view_idle_show(0, NULL); - UX_WAIT(); -} - -/////////////////////////////////// -// Paging related - -void h_paging_init() { - zemu_log_stack("h_paging_init"); - - viewdata.itemIdx = 0; - viewdata.pageIdx = 0; - viewdata.pageCount = 1; - viewdata.itemCount = 0xFF; -} - -bool h_paging_can_increase() { - if (viewdata.pageIdx + 1 < viewdata.pageCount) { - zemu_log_stack("h_paging_can_increase"); - return true; - } - - // passed page count, go to next index - if (viewdata.itemCount > 0 && viewdata.itemIdx < (viewdata.itemCount - 1 + INCLUDE_ACTIONS_COUNT)) { - zemu_log_stack("h_paging_can_increase"); - return true; - } - - zemu_log_stack("h_paging_can_increase NO"); - return false; -} - -void h_paging_increase() { - zemu_log_stack("h_paging_increase"); - - if (viewdata.pageIdx + 1 < viewdata.pageCount) { - // increase page - viewdata.pageIdx++; - return; - } - - // passed page count, go to next index - if (viewdata.itemCount > 0 && viewdata.itemIdx < (viewdata.itemCount - 1 + INCLUDE_ACTIONS_COUNT)) { - viewdata.itemIdx++; - viewdata.pageIdx = 0; - } -} - -bool h_paging_can_decrease() { - if (viewdata.pageIdx != 0) { - zemu_log_stack("h_paging_can_decrease"); - return true; - } - - if (viewdata.itemIdx > 0) { - zemu_log_stack("h_paging_can_decrease"); - return true; - } - - zemu_log_stack("h_paging_can_decrease NO"); - return false; -} - -void h_paging_decrease() { - char buffer[50]; - snprintf(buffer, sizeof(buffer), "h_paging_decrease Idx %d", viewdata.itemIdx); - zemu_log_stack(buffer); - - if (viewdata.pageIdx != 0) { - viewdata.pageIdx--; - zemu_log_stack("page--"); - return; - } - - if (viewdata.itemIdx > 0) { - viewdata.itemIdx--; - zemu_log_stack("item--"); - // jump to last page. update will cap this value - viewdata.pageIdx = 255; - } -} - -/////////////////////////////////// -// Paging related - -#ifdef INCLUDE_ACTIONS_AS_ITEMS -bool is_accept_item(){ - return viewdata.itemIdx == viewdata.itemCount - 1; -} - -void set_accept_item(){ - viewdata.itemIdx = viewdata.itemCount - 1; - viewdata.pageIdx = 0; -} - -bool is_reject_item(){ - return viewdata.itemIdx == viewdata.itemCount; -} -#endif - -void h_review_action() { -#ifdef INCLUDE_ACTIONS_AS_ITEMS - if( is_accept_item() ){ - zemu_log_stack("action_accept"); - h_approve(1); - return; - } - - if( is_reject_item() ){ - zemu_log_stack("action_reject"); - h_reject(1); - return; - } - - zemu_log_stack("quick accept"); - if (app_mode_expert()) { - set_accept_item(); - h_review_update(); - return; - } -#endif -} - -zxerr_t h_review_update_data() { - if (viewdata.viewfuncGetNumItems == NULL) { - zemu_log_stack("h_review_update_data - GetNumItems==NULL"); - return zxerr_no_data; - } - if (viewdata.viewfuncGetItem == NULL) { - zemu_log_stack("h_review_update_data - GetItem==NULL"); - return zxerr_no_data; - } - - if (viewdata.viewfuncGetItem == NULL) { - zemu_log_stack("h_review_update_data - GetItem==NULL"); - return zxerr_no_data; - } - - if (viewdata.viewfuncGetItem == NULL) { - zemu_log_stack("h_review_update_data - GetItem==NULL"); - return zxerr_no_data; - } - - char buffer[20]; - snprintf(buffer, sizeof(buffer), "update Idx %d/%d", viewdata.itemIdx, viewdata.pageIdx); - zemu_log_stack(buffer); - -#ifdef INCLUDE_ACTIONS_AS_ITEMS - viewdata.pageCount = 1; - - if( is_accept_item() ){ - snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s",""); - snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "%s", APPROVE_LABEL); - splitValueField(); - zemu_log_stack("show_accept_action - accept item"); - viewdata.pageIdx = 0; - return zxerr_ok; - } - - if( is_reject_item() ){ - snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s", ""); - snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "%s", REJECT_LABEL); - splitValueField(); - zemu_log_stack("show_reject_action - reject item"); - viewdata.pageIdx = 0; - return zxerr_ok; - } -#endif - - do { - CHECK_ZXERR(viewdata.viewfuncGetNumItems(&viewdata.itemCount)) - - //Verify how many chars fit in display (nanos) - CHECK_ZXERR(viewdata.viewfuncGetItem( - viewdata.itemIdx, - viewdata.key, MAX_CHARS_PER_KEY_LINE, - viewdata.value, MAX_CHARS_PER_VALUE1_LINE, - 0, &viewdata.pageCount)) - viewdata.pageCount = 1; - const max_char_display dyn_max_char_per_line1 = get_max_char_per_line(); - - // be sure we are not out of bounds - CHECK_ZXERR(viewdata.viewfuncGetItem( - viewdata.itemIdx, - viewdata.key, MAX_CHARS_PER_KEY_LINE, - viewdata.value, dyn_max_char_per_line1, - 0, &viewdata.pageCount)) - if (viewdata.pageCount != 0 && viewdata.pageIdx > viewdata.pageCount) { - // try again and get last page - viewdata.pageIdx = viewdata.pageCount - 1; - } - CHECK_ZXERR(viewdata.viewfuncGetItem( - viewdata.itemIdx, - viewdata.key, MAX_CHARS_PER_KEY_LINE, - viewdata.value, dyn_max_char_per_line1, - viewdata.pageIdx, &viewdata.pageCount)) - - viewdata.itemCount++; - - if (viewdata.pageCount > 1) { - uint8_t keyLen = strlen(viewdata.key); - if (keyLen < MAX_CHARS_PER_KEY_LINE) { - snprintf(viewdata.key + keyLen, - MAX_CHARS_PER_KEY_LINE - keyLen, - " [%d/%d]", - viewdata.pageIdx + 1, - viewdata.pageCount); - } - } - - if (viewdata.pageCount == 0) { - h_paging_increase(); - } - } while (viewdata.pageCount == 0); - - splitValueAddress(); - return zxerr_ok; -} - -/////////////////////////////////// -// General - -void io_seproxyhal_display(const bagl_element_t *element) { - io_seproxyhal_display_default((bagl_element_t *) element); -} - -void view_init(void) { - UX_INIT(); -#ifdef APP_SECRET_MODE_ENABLED - viewdata.secret_click_count = 0; -#endif -} - -void view_idle_show(uint8_t item_idx, char *statusString) { - view_idle_show_impl(item_idx, statusString); -} - -void view_message_show(char *title, char *message) { - view_message_impl(title, message); -} - -void view_review_init(viewfunc_getItem_t viewfuncGetItem, - viewfunc_getNumItems_t viewfuncGetNumItems, - viewfunc_accept_t viewfuncAccept) { - viewdata.viewfuncGetItem = viewfuncGetItem; - viewdata.viewfuncGetNumItems = viewfuncGetNumItems; - viewdata.viewfuncAccept = viewfuncAccept; -} - -void view_review_show() { - view_review_show_impl(); -} - -void view_error_show() { - snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "ERROR"); - snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "SHOWING DATA"); - splitValueField(); - view_error_show_impl(); -} diff --git a/deps/ledger-zxlib/app/common/view.h b/deps/ledger-zxlib/app/common/view.h deleted file mode 100644 index 6c9e777..0000000 --- a/deps/ledger-zxlib/app/common/view.h +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* -* (c) 2018-2020 Zondax GmbH -* (c) 2016 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#include -#include "coin.h" -#include "zxerror.h" - -#if defined(LEDGER_SPECIFIC) -#include "bolos_target.h" -#if defined(BOLOS_SDK) -#include "os.h" -#include "cx.h" -#endif -#endif - -typedef zxerr_t (*viewfunc_getNumItems_t)(uint8_t *num_items); - -typedef zxerr_t (*viewfunc_getItem_t)(int8_t displayIdx, - char *outKey, uint16_t outKeyLen, - char *outVal, uint16_t outValLen, - uint8_t pageIdx, uint8_t *pageCount); - -typedef void (*viewfunc_accept_t)(); - -#ifdef APP_SECRET_MODE_ENABLED -zxerr_t secret_enabled(); -#endif - -/// view_init (initializes UI) -void view_init(); - -/// view_initialize_show (idle view - main menu + status) -void view_initialize_show(uint8_t item_idx, char *statusString); - -/// view_idle_show (idle view - main menu + status) -void view_idle_show(uint8_t item_idx, char *statusString); - -void view_message_show(char *title, char *message); - -/// view_error (error view) -void view_error_show(); - -void view_review_init(viewfunc_getItem_t viewfuncGetItem, - viewfunc_getNumItems_t viewfuncGetNumItems, - viewfunc_accept_t viewfuncAccept); - -void view_review_show(); diff --git a/deps/ledger-zxlib/app/common/view_internal.h b/deps/ledger-zxlib/app/common/view_internal.h deleted file mode 100644 index 4f08a73..0000000 --- a/deps/ledger-zxlib/app/common/view_internal.h +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* -* (c) 2019 Zondax GmbH -* (c) 2016 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#include -#include -#include "coin.h" -#include "zxerror.h" -#include "view.h" - -#define CUR_FLOW G_ux.flow_stack[G_ux.stack_count-1] - -#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) -#define MAX_CHARS_PER_KEY_LINE 64 -#define MAX_CHARS_PER_VALUE1_LINE 4096 -#define MAX_CHARS_HEXMESSAGE 160 -#else -#ifndef MAX_CHARS_PER_VALUE_LINE -#define MAX_CHARS_PER_VALUE_LINE (17) -#endif -#define MAX_CHARS_PER_KEY_LINE (MAX_CHARS_PER_VALUE_LINE+1) -#define MAX_CHARS_PER_VALUE1_LINE (2*MAX_CHARS_PER_VALUE_LINE+1) -#define MAX_CHARS_PER_VALUE2_LINE (MAX_CHARS_PER_VALUE_LINE+1) -#define MAX_CHARS_HEXMESSAGE 40 -#endif - -// This takes data from G_io_apdu_buffer that is prefilled with the address - -#define APPROVE_LABEL "APPROVE" -#define REJECT_LABEL "REJECT" - -#if defined(TARGET_NANOS) -#define INCLUDE_ACTIONS_AS_ITEMS 2 -#define INCLUDE_ACTIONS_COUNT (INCLUDE_ACTIONS_AS_ITEMS-1) -typedef uint8_t max_char_display; -#else -#define INCLUDE_ACTIONS_COUNT 0 -typedef int max_char_display; -#endif - -typedef struct { - struct { - char key[MAX_CHARS_PER_KEY_LINE]; - char value[MAX_CHARS_PER_VALUE1_LINE]; -#if defined(TARGET_NANOS) - char value2[MAX_CHARS_PER_VALUE2_LINE]; -#endif - }; - viewfunc_getItem_t viewfuncGetItem; - viewfunc_getNumItems_t viewfuncGetNumItems; - viewfunc_accept_t viewfuncAccept; - -#ifdef APP_SECRET_MODE_ENABLED - uint8_t secret_click_count; -#endif - uint8_t itemIdx; - uint8_t itemCount; - uint8_t pageIdx; - uint8_t pageCount; -} view_t; - -typedef enum { - view_action_unknown, - view_action_accept, - view_action_reject, -} view_action_t; - -extern view_t viewdata; - -#define print_title(...) snprintf(viewdata.title, sizeof(viewdata.title), __VA_ARGS__) -#define print_key(...) snprintf(viewdata.key, sizeof(viewdata.key), __VA_ARGS__); -#define print_value(...) snprintf(viewdata.value, sizeof(viewdata.value), __VA_ARGS__); - -#if defined(TARGET_NANOS) -#define print_value2(...) snprintf(viewdata.value2, sizeof(viewdata.value2), __VA_ARGS__); -#endif - -void splitValueField(); -void splitValueAddress(); -max_char_display get_max_char_per_line(); - -/////////////////////////////////////////////// -/////////////////////////////////////////////// -/////////////////////////////////////////////// -/////////////////////////////////////////////// -/////////////////////////////////////////////// -/////////////////////////////////////////////// -/////////////////////////////////////////////// -/////////////////////////////////////////////// - -void view_initialize_show_impl(uint8_t item_idx, char *statusString); - -void view_idle_show_impl(uint8_t item_idx, char *statusString); - -void view_message_impl(char *title, char *message); - -void view_error_show_impl(); - -void h_paging_init(); - -bool h_paging_can_increase(); - -void h_paging_increase(); - -bool h_paging_can_decrease(); - -void h_paging_decrease(); - -void view_review_show_impl(); - -void h_approve(unsigned int _); - -void h_reject(unsigned int _); - -void h_review_action(); - -void h_review_update(); - -void h_error_accept(unsigned int _); - -zxerr_t h_review_update_data(); diff --git a/deps/ledger-zxlib/app/common/view_s.c b/deps/ledger-zxlib/app/common/view_s.c deleted file mode 100644 index d323b5c..0000000 --- a/deps/ledger-zxlib/app/common/view_s.c +++ /dev/null @@ -1,336 +0,0 @@ -/******************************************************************************* -* (c) 2018, 2019 Zondax GmbH -* (c) 2016 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "app_mode.h" -#include "view.h" -#include "view_internal.h" -#include "apdu_codes.h" -#include "ux.h" -#include "bagl.h" -#include "zxmacros.h" -#include "view_templates.h" -#include "zxutils_ledger.h" - -#include -#include - -#if defined(TARGET_NANOS) - -void h_initialize(); - -#define BAGL_WIDTH 128 -#define BAGL_HEIGHT 32 -#define BAGL_WIDTH_MARGIN 10 - -void h_expert_toggle(); -void h_expert_update(); -void h_review_button_left(); -void h_review_button_right(); -void h_review_button_both(); - -bool exceed_pixel_in_display(const uint8_t length); - -#ifdef APP_SECRET_MODE_ENABLED -void h_secret_click(); -#endif - -ux_state_t ux; - -void os_exit(uint32_t id) { - (void)id; - os_sched_exit(0); -} - -const ux_menu_entry_t menu_main[] = { - {NULL, NULL, 0, &C_icon_app, MENU_MAIN_APP_LINE1, viewdata.key, 33, 12}, - {NULL, h_expert_toggle, 0, &C_icon_app, "Expert mode:", viewdata.value, 33, 12}, - {NULL, NULL, 0, &C_icon_app, APPVERSION_LINE1, APPVERSION_LINE2, 33, 12}, - - {NULL, -#ifdef APP_SECRET_MODE_ENABLED - h_secret_click, -#else - NULL, -#endif - 0, &C_icon_app, "Developed by:", "Zondax.ch", 33, 12}, - - {NULL, NULL, 0, &C_icon_app, "License: ", "Apache 2.0", 33, 12}, - {NULL, os_exit, 0, &C_icon_dashboard, "Quit", NULL, 50, 29}, - UX_MENU_END -}; - -const ux_menu_entry_t menu_initialize[] = { - {NULL, NULL, 0, &C_icon_app, MENU_MAIN_APP_LINE1, viewdata.key, 33, 12}, - {NULL, h_initialize, 0, &C_icon_app, "Click to", "Initialize", 33, 12}, - {NULL, h_expert_toggle, 0, &C_icon_app, "Expert mode:", viewdata.value, 33, 12}, - {NULL, NULL, 0, &C_icon_app, APPVERSION_LINE1, APPVERSION_LINE2, 33, 12}, - {NULL, NULL, 0, &C_icon_app, "Developed by:", "Zondax.ch", 33, 12}, - {NULL, NULL, 0, &C_icon_app, "License: ", "Apache 2.0", 33, 12}, - {NULL, os_exit, 0, &C_icon_dashboard, "Quit", NULL, 50, 29}, - UX_MENU_END -}; - -static const bagl_element_t view_message[] = { - UI_BACKGROUND, - UI_LabelLine(UIID_LABEL + 0, 0, 8, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.key), - UI_LabelLine(UIID_LABEL + 1, 0, 19, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value), -}; - -static const bagl_element_t view_review[] = { - UI_BACKGROUND_LEFT_RIGHT_ICONS, - UI_LabelLine(UIID_LABEL + 0, 0, 8, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.key), - UI_LabelLine(UIID_LABEL + 1, 0, 19, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value), - UI_LabelLine(UIID_LABEL + 2, 0, 30, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value2), -}; - -static const bagl_element_t view_error[] = { - UI_FillRectangle(0, 0, 0, UI_SCREEN_WIDTH, UI_SCREEN_HEIGHT, 0x000000, 0xFFFFFF), - UI_Icon(0, 128 - 7, 0, 7, 7, BAGL_GLYPH_ICON_CHECK), - UI_LabelLine(UIID_LABEL + 0, 0, 8, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.key), - UI_LabelLine(UIID_LABEL + 0, 0, 19, UI_SCREEN_WIDTH, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value), - UI_LabelLineScrolling(UIID_LABELSCROLL, 0, 30, 128, UI_11PX, UI_WHITE, UI_BLACK, viewdata.value2), -}; - -static unsigned int view_error_button(unsigned int button_mask, __Z_UNUSED unsigned int button_mask_counter) { - switch (button_mask) { - case BUTTON_EVT_RELEASED | BUTTON_LEFT | BUTTON_RIGHT: - case BUTTON_EVT_RELEASED | BUTTON_LEFT: - break; - case BUTTON_EVT_RELEASED | BUTTON_RIGHT: - h_error_accept(0); - break; - } - return 0; -} - -static unsigned int view_message_button(unsigned int button_mask, __Z_UNUSED unsigned int button_mask_counter) { - switch (button_mask) { - case BUTTON_EVT_RELEASED | BUTTON_LEFT | BUTTON_RIGHT: - case BUTTON_EVT_RELEASED | BUTTON_LEFT: - case BUTTON_EVT_RELEASED | BUTTON_RIGHT: - break; - } - return 0; -} - -static unsigned int view_review_button(unsigned int button_mask, __Z_UNUSED unsigned int button_mask_counter) { - switch (button_mask) { - case BUTTON_EVT_RELEASED | BUTTON_LEFT | BUTTON_RIGHT: - h_review_button_both(); - break; - case BUTTON_EVT_RELEASED | BUTTON_LEFT: - // Press left to progress to the previous element - h_review_button_left(); - break; - - case BUTTON_EVT_RELEASED | BUTTON_RIGHT: - // Press right to progress to the next element - h_review_button_right(); - break; - } - return 0; -} - -const bagl_element_t *view_prepro(const bagl_element_t *element) { - switch (element->component.userid) { - case UIID_ICONLEFT: - if (!h_paging_can_decrease()){ - return NULL; - } - UX_CALLBACK_SET_INTERVAL(2000); - break; - case UIID_ICONRIGHT: - if (!h_paging_can_increase()){ - return NULL; - } - UX_CALLBACK_SET_INTERVAL(2000); - break; - case UIID_LABELSCROLL: - UX_CALLBACK_SET_INTERVAL( - MAX(3000, 1000 + bagl_label_roundtrip_duration_ms(element, 7)) - ); - break; - } - return element; -} - -const bagl_element_t *view_prepro_idle(const bagl_element_t *element) { - switch (element->component.userid) { - case UIID_ICONLEFT: - case UIID_ICONRIGHT: - return NULL; - } - return element; -} - -void h_review_update() { - zxerr_t err = h_review_update_data(); - switch(err) { - case zxerr_ok: - UX_DISPLAY(view_review, view_prepro); - break; - default: - view_error_show(); - UX_WAIT(); - break; - } -} - -void h_review_button_left() { - zemu_log_stack("h_review_button_left"); - h_paging_decrease(); - h_review_update(); -} - -void h_review_button_right() { - zemu_log_stack("h_review_button_right"); - h_paging_increase(); - h_review_update(); -} - -void h_review_button_both() { - zemu_log_stack("h_review_button_left"); - h_review_action(); -} - -void splitValueField() { - print_value2(""); - const uint16_t vlen = strlen(viewdata.value); - if (vlen > MAX_CHARS_PER_VALUE2_LINE - 1) { - snprintf(viewdata.value2, MAX_CHARS_PER_VALUE2_LINE, "%s", viewdata.value + MAX_CHARS_PER_VALUE_LINE); - viewdata.value[MAX_CHARS_PER_VALUE_LINE] = 0; - } -} -void splitValueAddress() { - uint8_t len = MAX_CHARS_PER_VALUE_LINE; - bool exceeding_max = exceed_pixel_in_display(len); - while(exceeding_max && len--) { - exceeding_max = exceed_pixel_in_display(len); - } - print_value2(""); - const uint16_t vlen = strlen(viewdata.value); - //if viewdata.value == NULL --> len = 0 - if (vlen > len && len > 0) { - snprintf(viewdata.value2, MAX_CHARS_PER_VALUE2_LINE, "%s", viewdata.value + len); - viewdata.value[len] = 0; - } -} - -max_char_display get_max_char_per_line() { - uint8_t len = MAX_CHARS_PER_VALUE_LINE; - bool exceeding_max = exceed_pixel_in_display(len); - while(exceeding_max && len--) { - exceeding_max = exceed_pixel_in_display(len); - } - //MAX_CHARS_PER_VALUE1_LINE is defined this way - return (len > 0) ? (2 * len + 1) : len; -} - -bool exceed_pixel_in_display(const uint8_t length) { - const unsigned short strWidth = zx_compute_line_width_light(viewdata.value, length); - return (strWidth >= (BAGL_WIDTH - BAGL_WIDTH_MARGIN)); -} - -////////////////////////// -////////////////////////// -////////////////////////// -////////////////////////// -////////////////////////// - -void view_initialize_show_impl(uint8_t item_idx, char *statusString) { - if (statusString == NULL ) { - snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", MENU_MAIN_APP_LINE2); - } else { - snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", statusString); - } - h_expert_update(); - UX_MENU_DISPLAY(item_idx, menu_initialize, NULL); -} - -void view_idle_show_impl(uint8_t item_idx, char *statusString) { - if (statusString == NULL ) { - snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", MENU_MAIN_APP_LINE2); -#ifdef APP_SECRET_MODE_ENABLED - if (app_mode_secret()) { - snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", MENU_MAIN_APP_LINE2_SECRET); - } -#endif - } else { - snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", statusString); - } - h_expert_update(); - UX_MENU_DISPLAY(item_idx, menu_main, NULL); -} - -void view_message_impl(char *title, char *message) { - snprintf(viewdata.key, MAX_CHARS_PER_VALUE_LINE, "%s", title); - snprintf(viewdata.value, MAX_CHARS_PER_VALUE_LINE, "%s", message); - UX_DISPLAY(view_message, view_prepro_idle); -} - -void view_error_show_impl() { - UX_DISPLAY(view_error, view_prepro); -} - -void h_expert_toggle() { - app_mode_set_expert(!app_mode_expert()); - view_idle_show(1, NULL); -} - -#ifdef APP_SECRET_MODE_ENABLED -void h_secret_click() { - if (COIN_SECRET_REQUIRED_CLICKS == 0) { - // There is no secret mode - return; - } - - viewdata.secret_click_count++; - - char buffer[50]; - snprintf(buffer, sizeof(buffer), "secret click %d\n", viewdata.secret_click_count); - zemu_log(buffer); - - if (viewdata.secret_click_count >= COIN_SECRET_REQUIRED_CLICKS) { - secret_enabled(); - viewdata.secret_click_count = 0; - } -} -#endif - -void h_expert_update() { - snprintf(viewdata.value, MAX_CHARS_PER_VALUE_LINE, "disabled"); - if (app_mode_expert()) { - snprintf(viewdata.value, MAX_CHARS_PER_VALUE_LINE, "enabled"); - } -} - -void view_review_show_impl() { - zemu_log_stack("view_review_show_impl"); - - h_paging_init(); - - zxerr_t err = h_review_update_data(); - switch(err) { - case zxerr_ok: - UX_DISPLAY(view_review, view_prepro); - break; - default: - view_error_show(); - break; - } -} -#endif diff --git a/deps/ledger-zxlib/app/common/view_x.c b/deps/ledger-zxlib/app/common/view_x.c deleted file mode 100644 index f8dd8bc..0000000 --- a/deps/ledger-zxlib/app/common/view_x.c +++ /dev/null @@ -1,292 +0,0 @@ -/******************************************************************************* -* (c) 2018, 2019 Zondax GmbH -* (c) 2016 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "app_mode.h" -#include "view.h" -#include "view_internal.h" -#include "actions.h" -#include "apdu_codes.h" -#include "glyphs.h" -#include "bagl.h" -#include "zxmacros.h" -#include "view_templates.h" -#include "tx.h" - -#ifdef APP_SECRET_MODE_ENABLED -#include "secret.h" -#endif - -#include -#include - -#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) - -void h_expert_toggle(); -void h_expert_update(); -void h_review_loop_start(); -void h_review_loop_inside(); -void h_review_loop_end(); - -#ifdef APP_SECRET_MODE_ENABLED -void h_secret_click(); -#endif - -#include "ux.h" -ux_state_t G_ux; -bolos_ux_params_t G_ux_params; -uint8_t flow_inside_loop; - - -UX_STEP_NOCB(ux_idle_flow_1_step, pbb, { &C_icon_app, MENU_MAIN_APP_LINE1, viewdata.key,}); -UX_STEP_CB_INIT(ux_idle_flow_2_step, bn, h_expert_update(), h_expert_toggle(), { "Expert mode:", viewdata.value, }); -UX_STEP_NOCB(ux_idle_flow_3_step, bn, { APPVERSION_LINE1, APPVERSION_LINE2, }); - -#ifdef APP_SECRET_MODE_ENABLED -UX_STEP_CB(ux_idle_flow_4_step, bn, h_secret_click(), { "Developed by:", "Zondax.ch", }); -#else -UX_STEP_NOCB(ux_idle_flow_4_step, bn, { "Developed by:", "Zondax.ch", }); -#endif - -UX_STEP_NOCB(ux_idle_flow_5_step, bn, { "License:", "Apache 2.0", }); -UX_STEP_CB(ux_idle_flow_6_step, pb, os_sched_exit(-1), { &C_icon_dashboard, "Quit",}); - -const ux_flow_step_t *const ux_idle_flow [] = { - &ux_idle_flow_1_step, - &ux_idle_flow_2_step, - &ux_idle_flow_3_step, - &ux_idle_flow_4_step, - &ux_idle_flow_5_step, - &ux_idle_flow_6_step, - FLOW_END_STEP, -}; - -/////////// - -UX_STEP_NOCB(ux_message_flow_1_step, pbb, { &C_icon_app, viewdata.key, viewdata.value,}); - -UX_FLOW( - ux_message_flow, - &ux_message_flow_1_step -); - -/////////// - -UX_STEP_NOCB(ux_error_flow_1_step, bnnn_paging, { .title = viewdata.key, .text = viewdata.value, }); -UX_STEP_VALID(ux_error_flow_2_step, pb, h_error_accept(0), { &C_icon_validate_14, "Ok"}); - -UX_FLOW( - ux_error_flow, - &ux_error_flow_1_step, - &ux_error_flow_2_step -); - -/////////// - -UX_FLOW_DEF_NOCB(ux_review_flow_1_review_title, pbb, { &C_icon_app, "Please", "review",}); -UX_STEP_INIT(ux_review_flow_2_start_step, NULL, NULL, { h_review_loop_start(); }); -UX_STEP_NOCB_INIT(ux_review_flow_2_step, bnnn_paging, { h_review_loop_inside(); }, { .title = viewdata.key, .text = viewdata.value, }); -UX_STEP_INIT(ux_review_flow_2_end_step, NULL, NULL, { h_review_loop_end(); }); -UX_STEP_VALID(ux_review_flow_3_step, pb, h_approve(0), { &C_icon_validate_14, APPROVE_LABEL }); -UX_STEP_VALID(ux_review_flow_4_step, pb, h_reject(0), { &C_icon_crossmark, REJECT_LABEL }); - -const ux_flow_step_t *const ux_review_flow[] = { - &ux_review_flow_1_review_title, - &ux_review_flow_2_start_step, - &ux_review_flow_2_step, - &ux_review_flow_2_end_step, - &ux_review_flow_3_step, - &ux_review_flow_4_step, - FLOW_END_STEP, -}; - -////////////////////////// -////////////////////////// -////////////////////////// -////////////////////////// -////////////////////////// - -void h_review_update() { - zxerr_t err = h_review_update_data(); - switch(err) { - case zxerr_ok: - case zxerr_no_data: - break; - default: - view_error_show(); - break; - } -} - -void h_review_loop_start() { - if (flow_inside_loop) { - // coming from right - - if (!h_paging_can_decrease()) { - // exit to the left - flow_inside_loop = 0; - ux_flow_prev(); - return; - } - - h_paging_decrease(); - } else { - // coming from left - h_paging_init(); - } - - h_review_update(); - - ux_flow_next(); -} - -void h_review_loop_inside() { - flow_inside_loop = 1; -} - -void h_review_loop_end() { - if (flow_inside_loop) { - // coming from left - h_paging_increase(); - zxerr_t err = h_review_update_data(); - - switch(err) { - case zxerr_ok: - ux_layout_bnnn_paging_reset(); - break; - case zxerr_no_data: { - flow_inside_loop = 0; - ux_flow_next(); - return; - } - default: - view_error_show(); - break; - } - } else { - // coming from right - h_paging_decrease(); - h_review_update(); - } - - // move to prev flow but trick paging to show first page - CUR_FLOW.prev_index = CUR_FLOW.index-2; - CUR_FLOW.index--; - ux_flow_relayout(); -} - -void splitValueField() { - uint16_t vlen = strlen(viewdata.value); - if (vlen == 0 ) { - snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, " "); - } -} - -void splitValueAddress() { - splitValueField(); -} - -max_char_display get_max_char_per_line() { - return MAX_CHARS_PER_VALUE1_LINE; -} - -void h_expert_toggle() { - app_mode_set_expert(!app_mode_expert()); - ux_flow_init(0, ux_idle_flow, &ux_idle_flow_2_step); -} - -void h_expert_update() { - snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "disabled"); - if (app_mode_expert()) { - snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "enabled"); - } -} - -#ifdef APP_SECRET_MODE_ENABLED -void h_secret_click() { - if (COIN_SECRET_REQUIRED_CLICKS == 0) { - // There is no secret mode - return; - } - - viewdata.secret_click_count++; - - char buffer[50]; - snprintf(buffer, sizeof(buffer), "secret click %d\n", viewdata.secret_click_count); - zemu_log(buffer); - - if (viewdata.secret_click_count >= COIN_SECRET_REQUIRED_CLICKS) { - secret_enabled(); - viewdata.secret_click_count = 0; - return; - } - - ux_flow_init(0, ux_idle_flow, &ux_idle_flow_4_step); -} -#endif - -////////////////////////// -////////////////////////// -////////////////////////// -////////////////////////// -////////////////////////// - -void view_idle_show_impl(__Z_UNUSED uint8_t item_idx, char *statusString) { - if (statusString == NULL ) { - if (app_mode_secret()) { - snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s", MENU_MAIN_APP_LINE2_SECRET); - } else { - snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s", MENU_MAIN_APP_LINE2); - } - } else { - snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s", statusString); - } - - if(G_ux.stack_count == 0) { - ux_stack_push(); - } - ux_flow_init(0, ux_idle_flow, NULL); -} - -void view_review_show_impl(){ - h_paging_init(); - h_paging_decrease(); - //// - flow_inside_loop = 0; - if(G_ux.stack_count == 0) { - ux_stack_push(); - } - ux_flow_init(0, ux_review_flow, NULL); -} - -void view_message_impl(char *title, char *message) { - snprintf(viewdata.key, MAX_CHARS_PER_KEY_LINE, "%s", title); - snprintf(viewdata.value, MAX_CHARS_PER_VALUE1_LINE, "%s", message); - ux_layout_bnnn_paging_reset(); - if(G_ux.stack_count == 0) { - ux_stack_push(); - } - ux_flow_init(0, ux_message_flow, NULL); -} - -void view_error_show_impl() { - ux_layout_bnnn_paging_reset(); - if(G_ux.stack_count == 0) { - ux_stack_push(); - } - ux_flow_init(0, ux_error_flow, NULL); -} -#endif diff --git a/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt b/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt deleted file mode 100644 index c64d5d8..0000000 --- a/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -############################## -# Google Test -# Based on instructions in https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project -# Download and unpack googletest at configure time -configure_file(CMakeLists.txt.gtest.in ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt) - -execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) -if (result) - message(FATAL_ERROR "CMake step for googletest failed: ${result}") -endif () - -execute_process(COMMAND ${CMAKE_COMMAND} --build . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) -if (result) - message(FATAL_ERROR "Build step for googletest failed: ${result}") -endif () - -# Prevent overriding the parent project's compiler/linker settings on Windows -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - -add_subdirectory( - ${CMAKE_BINARY_DIR}/googletest-src - ${CMAKE_BINARY_DIR}/googletest-build -) - -if (CMAKE_VERSION VERSION_LESS 3.0.0) - include_directories("${gtest_SOURCE_DIR}/include") -endif () diff --git a/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt.gtest.in b/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt.gtest.in deleted file mode 100644 index b30f8be..0000000 --- a/deps/ledger-zxlib/cmake/gtest/CMakeLists.txt.gtest.in +++ /dev/null @@ -1,16 +0,0 @@ -# Based on https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project -cmake_minimum_required(VERSION 3.0.0) - -project(googletest-download NONE) - -include(ExternalProject) -ExternalProject_Add(googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.11.0 - SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" - ) diff --git a/deps/ledger-zxlib/dockerized_build.mk b/deps/ledger-zxlib/dockerized_build.mk deleted file mode 100644 index 50d9c37..0000000 --- a/deps/ledger-zxlib/dockerized_build.mk +++ /dev/null @@ -1,326 +0,0 @@ -#******************************************************************************* -#* (c) 2019-2021 Zondax GmbH -#* -#* Licensed under the Apache License, Version 2.0 (the "License"); -#* you may not use this file except in compliance with the License. -#* You may obtain a copy of the License at -#* -#* http://www.apache.org/licenses/LICENSE-2.0 -#* -#* Unless required by applicable law or agreed to in writing, software -#* distributed under the License is distributed on an "AS IS" BASIS, -#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -#* See the License for the specific language governing permissions and -#* limitations under the License. -#******************************************************************************** - -.PHONY: all deps build clean load delete check_python show_info_recovery_mode - -TESTS_ZEMU_DIR?=$(CURDIR)/tests_zemu -EXAMPLE_VUE_DIR?=$(CURDIR)/example_vue -TESTS_JS_PACKAGE?= -TESTS_JS_DIR?= - -LEDGER_SRC=$(CURDIR)/app -DOCKER_APP_SRC=/project -DOCKER_APP_BIN=$(DOCKER_APP_SRC)/app/bin/app.elf - -DOCKER_BOLOS_SDKS=/project/deps/nanos-secure-sdk -DOCKER_BOLOS_SDKX=/project/deps/nanox-secure-sdk -DOCKER_BOLOS_SDKS2=/project/deps/nanosplus-secure-sdk - -# Note: This is not an SSH key, and being public represents no risk -SCP_PUBKEY=049bc79d139c70c83a4b19e8922e5ee3e0080bb14a2e8b0752aa42cda90a1463f689b0fa68c1c0246845c2074787b649d0d8a6c0b97d4607065eee3057bdf16b83 -SCP_PRIVKEY=ff701d781f43ce106f72dc26a46b6a83e053b5d07bb3d4ceab79c91ca822a66b - -INTERACTIVE:=$(shell [ -t 0 ] && echo 1) -USERID:=$(shell id -u) -$(info USERID : $(USERID)) -$(info TESTS_ZEMU_DIR : $(TESTS_ZEMU_DIR)) -$(info EXAMPLE_VUE_DIR : $(EXAMPLE_VUE_DIR)) -$(info TESTS_JS_DIR : $(TESTS_JS_DIR)) -$(info TESTS_JS_PACKAGE : $(TESTS_JS_PACKAGE)) - -DOCKER_IMAGE_ZONDAX=zondax/builder-bolos:latest -DOCKER_IMAGE_LEDGER=ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest - -ifdef INTERACTIVE -INTERACTIVE_SETTING:="-i" -TTY_SETTING:="-t" -else -INTERACTIVE_SETTING:= -TTY_SETTING:= -endif - -UNAME_S := $(shell uname -s) -ifeq ($(UNAME_S),Linux) - NPROC=$(shell nproc) -endif -ifeq ($(UNAME_S),Darwin) - NPROC=$(shell sysctl -n hw.physicalcpu) -endif - -define run_docker - docker run $(TTY_SETTING) $(INTERACTIVE_SETTING) --rm \ - -e SCP_PRIVKEY=$(SCP_PRIVKEY) \ - -e BOLOS_SDK=$(1) \ - -e BOLOS_ENV=/opt/bolos \ - -u $(USERID) \ - -v $(shell pwd):/project \ - -e SUPPORT_SR25519=$(SUPPORT_SR25519) \ - -e SUBSTRATE_PARSER_FULL=$(SUBSTRATE_PARSER_FULL) \ - -e COIN=$(COIN) \ - -e APP_TESTING=$(APP_TESTING) \ - $(DOCKER_IMAGE_ZONDAX) "$(2)" -endef - -define run_docker_ledger - docker run $(TTY_SETTING) $(INTERACTIVE_SETTING) --rm \ - -v $(shell pwd):/app \ - $(DOCKER_IMAGE_LEDGER) "$(1)" -endef - -all: - @$(MAKE) clean_output - @$(MAKE) clean_build - @$(MAKE) buildS - @$(MAKE) clean_build - @$(MAKE) buildX - @$(MAKE) clean_build - @$(MAKE) buildS2 - -.PHONY: check_python -check_python: - @python -c 'import sys; sys.exit(3-sys.version_info.major)' || (echo "The python command does not point to Python 3"; exit 1) - -.PHONY: deps -deps: check_python - @echo "Install dependencies" - $(CURDIR)/deps/ledger-zxlib/scripts/install_deps.sh - -.PHONY: pull -pull: - docker pull $(DOCKER_IMAGE_ZONDAX) - docker pull $(DOCKER_IMAGE_LEDGER) - -.PHONY: ledger_lint -ledger_lint: - $(call run_docker_ledger,"scan-build --use-cc=clang -analyze-headers -enable-checker security -enable-checker unix -enable-checker valist -o scan-build --status-bugs make default") - -.PHONY: build_rustS -build_rustS: - $(call run_docker,$(DOCKER_BOLOS_SDKS),make -C $(DOCKER_APP_SRC) rust) - -.PHONY: build_rustX -build_rustX: - $(call run_docker,$(DOCKER_BOLOS_SDKX),make -C $(DOCKER_APP_SRC) rust) - -.PHONY: build_rustS2 -build_rustS2: - $(call run_docker,$(DOCKER_BOLOS_SDKS2),make -C $(DOCKER_APP_SRC) rust) - -.PHONY: convert_icon -convert_icon: - @convert $(LEDGER_SRC)/tmp.gif -monochrome -size 16x16 -depth 1 $(LEDGER_SRC)/nanos_icon.gif - @convert $(LEDGER_SRC)/nanos_icon.gif -crop 14x14+1+1 +repage -negate $(LEDGER_SRC)/nanox_icon.gif - -.PHONY: buildS -buildS: build_rustS - $(call run_docker,$(DOCKER_BOLOS_SDKS),make -j $(NPROC) -C $(DOCKER_APP_SRC)) - -.PHONY: buildX -buildX: build_rustX - $(call run_docker,$(DOCKER_BOLOS_SDKX),make -j $(NPROC) -C $(DOCKER_APP_SRC)) - -.PHONY: buildS2 -buildS2: build_rustS2 - $(call run_docker,$(DOCKER_BOLOS_SDKS2),make -j $(NPROC) -C $(DOCKER_APP_SRC)) - -.PHONY: clean_output -clean_output: - @echo "Removing output files" - @rm -f app/output/app* || true - -.PHONY: clean -clean_build: - $(call run_docker,$(DOCKER_BOLOS_SDKS),make -C $(DOCKER_APP_SRC) clean) - -.PHONY: clean -clean: clean_output clean_build - -.PHONY: listvariants -listvariants: - $(call run_docker,$(DOCKER_BOLOS_SDKS),make -C $(DOCKER_APP_SRC) listvariants) - -.PHONY: shellS -shellS: - $(call run_docker,$(DOCKER_BOLOS_SDKS) -t,bash) - -.PHONY: shellX -shellX: - $(call run_docker,$(DOCKER_BOLOS_SDKX) -t,bash) - -.PHONY: shellS2 -shellS2: - $(call run_docker,$(DOCKER_BOLOS_SDKS2) -t,bash) - -.PHONY: load -load: - ${LEDGER_SRC}/pkg/installer_s.sh load - -.PHONY: delete -delete: - ${LEDGER_SRC}/pkg/installer_s.sh delete - -.PHONY: loadX -loadX: - ${LEDGER_SRC}/pkg/installer_x.sh load - -.PHONY: deleteX -deleteX: - ${LEDGER_SRC}/pkg/installer_x.sh delete - -.PHONY: loadS2 -loadS2: - ${LEDGER_SRC}/pkg/installer_s2.sh load - -.PHONY: deleteS2 -deleteS2: - ${LEDGER_SRC}/pkg/installer_s2.sh delete - -.PHONY: show_info_recovery_mode -show_info_recovery_mode: - @echo "This command requires a Ledger Nano S in recovery mode. To go into recovery mode, follow:" - @echo " 1. Settings -> Device -> Reset all and confirm" - @echo " 2. Unplug device, press and hold the right button, plug-in again" - @echo " 3. Navigate to the main menu" - @echo "If everything was correct, no PIN needs to be entered." - -# This target will initialize the device with the integration testing mnemonic -.PHONY: dev_init -dev_init: show_info_recovery_mode - @echo "Initializing device with test mnemonic! WARNING TAKES 2 MINUTES AND REQUIRES RECOVERY MODE" - @python -m ledgerblue.hostOnboard --apdu --id 0 --prefix "" --passphrase "" --pin 5555 --words "equip will roof matter pink blind book anxiety banner elbow sun young" - -# This target will initialize the device with the secondary integration testing mnemonic (Bob) -.PHONY: dev_init_secondary -dev_init_secondary: check_python show_info_recovery_mode - @echo "Initializing device with secondary test mnemonic! WARNING TAKES 2 MINUTES AND REQUIRES RECOVERY MODE" - @python -m ledgerblue.hostOnboard --apdu --id 0 --prefix "" --passphrase "" --pin 5555 --words "elite vote proof agree february step sibling sand grocery axis false cup" - -# This target will setup a custom developer certificate -.PHONY: dev_ca -dev_ca: check_python - @python -m ledgerblue.setupCustomCA --targetId 0x31100004 --public $(SCP_PUBKEY) --name zondax - -# This target will setup a custom developer certificate -.PHONY: dev_caX -dev_caX: check_python - @python -m ledgerblue.setupCustomCA --targetId 0x33000004 --public $(SCP_PUBKEY) --name zondax - -.PHONY: dev_ca_delete -dev_ca_delete: check_python - @python -m ledgerblue.resetCustomCA --targetId 0x31100004 - -# This target will setup a custom developer certificate -.PHONY: dev_ca2 -dev_ca2: check_python - @python -m ledgerblue.setupCustomCA --targetId 0x33000004 --public $(SCP_PUBKEY) --name zondax - -.PHONY: dev_ca_delete2 -dev_ca_delete2: check_python - @python -m ledgerblue.resetCustomCA --targetId 0x33000004 - -########################## VUE Section ############################### - -.PHONY: vue_install_js_link -ifeq ($(TESTS_JS_DIR),) -vue_install_js_link: - @echo "No local package defined" -else -vue_install_js_link: - # First unlink everything - cd $(TESTS_JS_DIR) && yarn unlink || true - cd $(EXAMPLE_VUE_DIR) && yarn unlink $(TESTS_JS_PACKAGE) || true -# # Now build and link - cd $(TESTS_JS_DIR) && yarn install && yarn build && yarn link || true - cd $(EXAMPLE_VUE_DIR) && yarn link $(TESTS_JS_PACKAGE) && yarn install || true - @echo - # List linked packages - @echo - @cd $(EXAMPLE_VUE_DIR) && ( ls -l node_modules ; ls -l node_modules/@* ) | grep ^l || true - @echo -endif - -.PHONY: vue -vue: vue_install_js_link - cd $(EXAMPLE_VUE_DIR) && yarn install && yarn serve - -########################## VUE Section ############################### - -.PHONY: zemu_install_js_link -ifeq ($(TESTS_JS_DIR),) -zemu_install_js_link: - @echo "No local package defined" -else -zemu_install_js_link: - # First unlink everything - cd $(TESTS_JS_DIR) && yarn unlink || true - cd $(TESTS_ZEMU_DIR) && yarn unlink $(TESTS_JS_PACKAGE) || true - # Now build and link - cd $(TESTS_JS_DIR) && yarn install && yarn build && yarn link || true - cd $(TESTS_ZEMU_DIR) && yarn link $(TESTS_JS_PACKAGE) && yarn install || true - @echo - # List linked packages - @echo - @cd $(TESTS_ZEMU_DIR) && ( ls -l node_modules ; ls -l node_modules/@* ) | grep ^l || true - @echo -endif - -.PHONY: zemu_install -zemu_install: zemu_install_js_link - # and now install everything - cd $(TESTS_ZEMU_DIR) && yarn install - -.PHONY: zemu -zemu: - cd $(TESTS_ZEMU_DIR)/tools && node debug.mjs $(COIN) - -.PHONY: zemu_val -zemu_val: - cd $(TESTS_ZEMU_DIR)/tools && node debug_val.mjs - -.PHONY: zemu_debug -zemu_debug: - cd $(TESTS_ZEMU_DIR)/tools && node debug.mjs $(COIN) debug - -########################## TEST Section ############################### - -.PHONY: zemu_test -zemu_test: - cd $(TESTS_ZEMU_DIR) && yarn test$(COIN) - -.PHONY: rust_test -rust_test: - cd app/rust && cargo test - -.PHONY: cpp_test -cpp_test: - mkdir -p build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. && make - cd build && GTEST_COLOR=1 ASAN_OPTIONS=detect_leaks=0 ctest -VV - -########################## FUZZING Section ############################### - -.PHONY: fuzz_build -fuzz_build: - cmake -B build -DCMAKE_C_COMPILER=clang-11 -DCMAKE_CXX_COMPILER=clang++-11 -DCMAKE_BUILD_TYPE=Debug -DENABLE_FUZZING=1 -DENABLE_SANITIZERS=1 . - make -C build - -.PHONY: fuzz -fuzz: fuzz_build - ./fuzz/run-fuzzers.py - -.PHONY: fuzz_crash -fuzz_crash: FUZZ_LOGGING=1 -fuzz_crash: fuzz_build - ./fuzz/run-fuzz-crashes.py diff --git a/deps/ledger-zxlib/include/apdu_codes.h b/deps/ledger-zxlib/include/apdu_codes.h deleted file mode 100644 index 5f55265..0000000 --- a/deps/ledger-zxlib/include/apdu_codes.h +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#pragma once - -#include "inttypes.h" -#include "zxmacros.h" - -// Based on ISO7816 - -#define APDU_CODE_OK 0x9000 -#define APDU_CODE_BUSY 0x9001 - -#define APDU_CODE_EXECUTION_ERROR 0x6400 - -#define APDU_CODE_WRONG_LENGTH 0x6700 - -#define APDU_CODE_EMPTY_BUFFER 0x6982 -#define APDU_CODE_OUTPUT_BUFFER_TOO_SMALL 0x6983 -#define APDU_CODE_DATA_INVALID 0x6984 -#define APDU_CODE_CONDITIONS_NOT_SATISFIED 0x6985 -#define APDU_CODE_COMMAND_NOT_ALLOWED 0x6986 -#define APDU_CODE_TX_NOT_INITIALIZED 0x6987 - -#define APDU_CODE_BAD_KEY_HANDLE 0x6A80 -#define APDU_CODE_INVALIDP1P2 0x6B00 -#define APDU_CODE_INS_NOT_SUPPORTED 0x6D00 -#define APDU_CODE_CLA_NOT_SUPPORTED 0x6E00 - -#define APDU_CODE_UNKNOWN 0x6F00 -#define APDU_CODE_SIGN_VERIFY_ERROR 0x6F01 - - -__Z_INLINE void set_code(uint8_t *buffer, uint8_t offset, uint16_t value) { - *(buffer + offset) = (uint8_t) (value >> 8); - *(buffer + offset + 1) = (uint8_t) (value & 0xFF); -} diff --git a/deps/ledger-zxlib/include/app_mode.h b/deps/ledger-zxlib/include/app_mode.h deleted file mode 100644 index 11c72e8..0000000 --- a/deps/ledger-zxlib/include/app_mode.h +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* -* (c) 2016 Ledger -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once -#include "zxmacros.h" -#include "stdbool.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void app_mode_reset(); - -bool app_mode_expert(); - -void app_mode_set_expert(uint8_t val); - -bool app_mode_secret(); - -void app_mode_set_secret(uint8_t val); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/base58.h b/deps/ledger-zxlib/include/base58.h deleted file mode 100644 index b76412d..0000000 --- a/deps/ledger-zxlib/include/base58.h +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* -* Ledger App - Bitcoin Wallet -* (c) 2019 Zondax GmbH -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int decode_base58(const char *in, size_t length, - unsigned char *out, size_t *outlen); - -int encode_base58(const unsigned char *in, size_t length, - unsigned char *out, size_t *outlen); - -char encode_base58_clip(unsigned char v); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/base64.h b/deps/ledger-zxlib/include/base64.h deleted file mode 100644 index 99bc7c0..0000000 --- a/deps/ledger-zxlib/include/base64.h +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* -* (c) 2020 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -uint16_t base64_encode(char *out, uint16_t outlen, const uint8_t *in, uint16_t inlen); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/bech32.h b/deps/ledger-zxlib/include/bech32.h deleted file mode 100644 index bd9fd14..0000000 --- a/deps/ledger-zxlib/include/bech32.h +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* -* (c) 2019 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "zxerror.h" - -#define MAX_INPUT_SIZE 64 - -// the following function encodes directly from bytes -// it will internally convert from 8 to 5 bits and return a -// zero-terminated string in output - -zxerr_t bech32EncodeFromBytes(char *out, - size_t out_len, - const char *hrp, - const uint8_t *in, - size_t in_len, - uint8_t pad); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/bignum.h b/deps/ledger-zxlib/include/bignum.h deleted file mode 100644 index 9bf31f8..0000000 --- a/deps/ledger-zxlib/include/bignum.h +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* -* (c) 2019 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -bool_t bignumLittleEndian_bcdprint(char *outBuffer, uint16_t outBufferLen, const uint8_t *inBCD, uint16_t inBCDLen); -void bignumLittleEndian_to_bcd(uint8_t *bcdOut, uint16_t bcdOutLen, const uint8_t *binValue, uint16_t binValueLen); - -bool_t bignumBigEndian_bcdprint(char *outBuffer, uint16_t outBufferLen, const uint8_t *bcdIn, uint16_t bcdInLen); -void bignumBigEndian_to_bcd(uint8_t *bcdOut, uint16_t bcdOutLen, const uint8_t *binValue, uint16_t binValueLen); - - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/bittools.h b/deps/ledger-zxlib/include/bittools.h deleted file mode 100644 index 1903878..0000000 --- a/deps/ledger-zxlib/include/bittools.h +++ /dev/null @@ -1,37 +0,0 @@ -// This code has been adapted from: -/* Copyright (c) 2017 Pieter Wuille - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -int convert_bits(uint8_t *out, - size_t *outlen, - int outBits, - const uint8_t *in, - size_t inLen, - int inBits, int pad); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/buffering.h b/deps/ledger-zxlib/include/buffering.h deleted file mode 100644 index ec6e80c..0000000 --- a/deps/ledger-zxlib/include/buffering.h +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* -* (c) 2016 Ledger -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -typedef struct { - uint8_t *data; - uint16_t size; - uint16_t pos; - uint8_t in_use: 1; -} buffer_state_t; - -/// Initialize buffer -/// \param ram_buffer -/// \param ram_buffer_size -/// \param flash_buffer -/// \param flash_buffer_size -void buffering_init(uint8_t *ram_buffer, - uint16_t ram_buffer_size, - uint8_t *flash_buffer, - uint16_t flash_buffer_size); - -/// Reset buffer -void buffering_reset(); - -/// Append data to the buffer -/// \param data -/// \param length -/// \return the number of appended bytes -int buffering_append(uint8_t *data, int length); - -/// buffering_get_ram_buffer -/// \return -buffer_state_t *buffering_get_ram_buffer(); - -/// buffering_get_flash_buffer -/// \return -buffer_state_t *buffering_get_flash_buffer(); - -/// buffering_get_buffer -/// \return -buffer_state_t *buffering_get_buffer(); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/hexutils.h b/deps/ledger-zxlib/include/hexutils.h deleted file mode 100644 index 3cbaad8..0000000 --- a/deps/ledger-zxlib/include/hexutils.h +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -size_t parseHexString(uint8_t *out, uint16_t outLen, const char *input); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/segwit_addr.h b/deps/ledger-zxlib/include/segwit_addr.h deleted file mode 100644 index f97bcfa..0000000 --- a/deps/ledger-zxlib/include/segwit_addr.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (c) 2017 Pieter Wuille - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef _SEGWIT_ADDR_H_ -#define _SEGWIT_ADDR_H_ 1 - -#include - -/** Encode a SegWit address - * - * Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be - * updated to contain the null-terminated address. - * In: hrp: Pointer to the null-terminated human readable part to use - * (chain/network specific). - * ver: Version of the witness program (between 0 and 16 inclusive). - * prog: Data bytes for the witness program (between 2 and 40 bytes). - * prog_len: Number of data bytes in prog. - * Returns 1 if successful. - */ -int segwit_addr_encode( - char *output, - const char *hrp, - int ver, - const uint8_t *prog, - size_t prog_len -); - -/** Decode a SegWit address - * - * Out: ver: Pointer to an int that will be updated to contain the witness - * program version (between 0 and 16 inclusive). - * prog: Pointer to a buffer of size 40 that will be updated to - * contain the witness program bytes. - * prog_len: Pointer to a size_t that will be updated to contain the length - * of bytes in prog. - * hrp: Pointer to the null-terminated human readable part that is - * expected (chain/network specific). - * addr: Pointer to the null-terminated address. - * Returns 1 if successful. - */ -int segwit_addr_decode( - int *ver, - uint8_t *prog, - size_t *prog_len, - const char *hrp, - const char *addr -); - -/** Encode a Bech32 string - * - * Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that - * will be updated to contain the null-terminated Bech32 string. - * In: hrp : Pointer to the null-terminated human readable part. - * data : Pointer to an array of 5-bit values. - * data_len: Length of the data array. - * Returns 1 if successful. - */ -int bech32_encode( - char *output, - const char *hrp, - const uint8_t *data, - size_t data_len -); - -/** Decode a Bech32 string - * - * Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be - * updated to contain the null-terminated human readable part. - * data: Pointer to a buffer of size strlen(input) - 8 that will - * hold the encoded 5-bit data values. - * data_len: Pointer to a size_t that will be updated to be the number - * of entries in data. - * In: input: Pointer to a null-terminated Bech32 string. - * Returns 1 if successful. - */ -int bech32_decode( - char *hrp, - uint8_t *data, - size_t *data_len, - const char *input -); - -#endif diff --git a/deps/ledger-zxlib/include/sigutils.h b/deps/ledger-zxlib/include/sigutils.h deleted file mode 100644 index 862f809..0000000 --- a/deps/ledger-zxlib/include/sigutils.h +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* -* (c) 2020 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - no_error = 0, - invalid_derPrefix, - invalid_payloadLen, - invalid_rmaker, - invalid_rLen, - invalid_smarker, - invalid_sLen, -} err_convert_e; - -err_convert_e convertDERtoRSV(const uint8_t *inSignatureDER, - unsigned int inInfo, - uint8_t *outR, - uint8_t *outS, - uint8_t *outV); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/timeutils.h b/deps/ledger-zxlib/include/timeutils.h deleted file mode 100644 index d291477..0000000 --- a/deps/ledger-zxlib/include/timeutils.h +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include "zxmacros.h" -#include "zxerror.h" - -__Z_INLINE const char *getMonth(uint8_t tm_mon) { - switch (tm_mon) { - case 1: - return "Jan"; - case 2: - return "Feb"; - case 3: - return "Mar"; - case 4: - return "Apr"; - case 5: - return "May"; - case 6: - return "Jun"; - case 7: - return "Jul"; - case 8: - return "Aug"; - case 9: - return "Sep"; - case 10: - return "Oct"; - case 11: - return "Nov"; - case 12: - return "Dec"; - default: - return "ERR"; - } -} - -zxerr_t printTime(char *out, uint16_t outLen, uint64_t t); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/utf8.h b/deps/ledger-zxlib/include/utf8.h deleted file mode 100644 index fe2e8d9..0000000 --- a/deps/ledger-zxlib/include/utf8.h +++ /dev/null @@ -1,1682 +0,0 @@ -/* The latest version of this library is available on GitHub; - * https://github.com/sheredom/utf8.h */ - -/* This is free and unencumbered software released into the public domain. - * - * Anyone is free to copy, modify, publish, use, compile, sell, or - * distribute this software, either in source code form or as a compiled - * binary, for any purpose, commercial or non-commercial, and by any - * means. - * - * In jurisdictions that recognize copyright laws, the author or authors - * of this software dedicate any and all copyright interest in the - * software to the public domain. We make this dedication for the benefit - * of the public at large and to the detriment of our heirs and - * successors. We intend this dedication to be an overt act of - * relinquishment in perpetuity of all present and future rights to this - * software under copyright law. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * For more information, please refer to */ - -#ifndef SHEREDOM_UTF8_H_INCLUDED -#define SHEREDOM_UTF8_H_INCLUDED - -#if defined(_MSC_VER) -#pragma warning(push) - -/* disable warning: no function prototype given: converting '()' to '(void)' */ -#pragma warning(disable : 4255) - -/* disable warning: '__cplusplus' is not defined as a preprocessor macro, - * replacing with '0' for '#if/#elif' */ -#pragma warning(disable : 4668) - -/* disable warning: bytes padding added after construct */ -#pragma warning(disable : 4820) -#endif - -#include -#include - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -#if defined(_MSC_VER) && (_MSC_VER < 1920) -typedef __int32 utf8_int32_t; -#else -#include -typedef int32_t utf8_int32_t; -#endif - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wold-style-cast" -#pragma clang diagnostic ignored "-Wcast-qual" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_MSC_VER) -#define utf8_nonnull -#define utf8_pure -#define utf8_restrict __restrict -#define utf8_weak __inline -#elif defined(__clang__) || defined(__GNUC__) -#define utf8_nonnull __attribute__((nonnull)) -#define utf8_pure __attribute__((pure)) -#define utf8_restrict __restrict__ -#define utf8_weak __attribute__((weak)) -#else -#error Non clang, non gcc, non MSVC compiler found! -#endif - -#ifdef __cplusplus -#define utf8_null NULL -#else -#define utf8_null 0 -#endif - -#if (defined(__cplusplus) && __cplusplus >= 201402L) -#define utf8_constexpr14 constexpr -#define utf8_constexpr14_impl constexpr -#else -/* constexpr and weak are incompatible. so only enable one of them */ -#define utf8_constexpr14 utf8_weak -#define utf8_constexpr14_impl -#endif - -#if defined(__cplusplus) && __cplusplus >= 202002L -using utf8_int8_t = char8_t; /* Introduced in C++20 */ -#else -typedef char utf8_int8_t; -#endif - -/* Return less than 0, 0, greater than 0 if src1 < src2, src1 == src2, src1 > - * src2 respectively, case insensitive. */ -utf8_constexpr14 utf8_nonnull utf8_pure int -utf8casecmp(const utf8_int8_t *src1, const utf8_int8_t *src2); - -/* Append the utf8 string src onto the utf8 string dst. */ -utf8_nonnull utf8_weak utf8_int8_t * -utf8cat(utf8_int8_t *utf8_restrict dst, const utf8_int8_t *utf8_restrict src); - -/* Find the first match of the utf8 codepoint chr in the utf8 string src. */ -utf8_constexpr14 utf8_nonnull utf8_pure utf8_int8_t * -utf8chr(const utf8_int8_t *src, utf8_int32_t chr); - -/* Return less than 0, 0, greater than 0 if src1 < src2, - * src1 == src2, src1 > src2 respectively. */ -utf8_constexpr14 utf8_nonnull utf8_pure int utf8cmp(const utf8_int8_t *src1, - const utf8_int8_t *src2); - -/* Copy the utf8 string src onto the memory allocated in dst. */ -utf8_nonnull utf8_weak utf8_int8_t * - utf8cpy(utf8_int8_t *utf8_restrict dst, const utf8_int8_t *utf8_restrict src); - -/* Number of utf8 codepoints in the utf8 string src that consists entirely - * of utf8 codepoints not from the utf8 string reject. */ -utf8_constexpr14 utf8_nonnull utf8_pure size_t -utf8cspn(const utf8_int8_t *src, const utf8_int8_t *reject); - -/* Duplicate the utf8 string src by getting its size, malloc'ing a new buffer - * copying over the data, and returning that. Or 0 if malloc failed. */ -utf8_weak utf8_int8_t *utf8dup(const utf8_int8_t *src); - -/* Number of utf8 codepoints in the utf8 string str, - * excluding the null terminating byte. */ -utf8_constexpr14 utf8_nonnull utf8_pure size_t utf8len(const utf8_int8_t *str); - -/* Similar to utf8len, except that only at most n bytes of src are looked. */ -utf8_constexpr14 utf8_nonnull utf8_pure size_t utf8nlen(const utf8_int8_t *str, - size_t n); - -/* Return less than 0, 0, greater than 0 if src1 < src2, src1 == src2, src1 > - * src2 respectively, case insensitive. Checking at most n bytes of each utf8 - * string. */ -utf8_constexpr14 utf8_nonnull utf8_pure int -utf8ncasecmp(const utf8_int8_t *src1, const utf8_int8_t *src2, size_t n); - -/* Append the utf8 string src onto the utf8 string dst, - * writing at most n+1 bytes. Can produce an invalid utf8 - * string if n falls partway through a utf8 codepoint. */ -utf8_nonnull utf8_weak utf8_int8_t * - utf8ncat(utf8_int8_t *utf8_restrict dst, const utf8_int8_t *utf8_restrict src, -size_t n); - -/* Return less than 0, 0, greater than 0 if src1 < src2, - * src1 == src2, src1 > src2 respectively. Checking at most n - * bytes of each utf8 string. */ -utf8_constexpr14 utf8_nonnull utf8_pure int -utf8ncmp(const utf8_int8_t *src1, const utf8_int8_t *src2, size_t n); - -/* Copy the utf8 string src onto the memory allocated in dst. - * Copies at most n bytes. If n falls partway through a utf8 - * codepoint, or if dst doesn't have enough room for a null - * terminator, the final string will be cut short to preserve - * utf8 validity. */ - -utf8_nonnull utf8_weak utf8_int8_t * - utf8ncpy(utf8_int8_t *utf8_restrict dst, const utf8_int8_t *utf8_restrict src, -size_t n); - -/* Similar to utf8dup, except that at most n bytes of src are copied. If src is - * longer than n, only n bytes are copied and a null byte is added. - * - * Returns a new string if successful, 0 otherwise */ -utf8_weak utf8_int8_t *utf8ndup(const utf8_int8_t *src, size_t n); - -/* Locates the first occurrence in the utf8 string str of any byte in the - * utf8 string accept, or 0 if no match was found. */ -utf8_constexpr14 utf8_nonnull utf8_pure utf8_int8_t * -utf8pbrk(const utf8_int8_t *str, const utf8_int8_t *accept); - -/* Find the last match of the utf8 codepoint chr in the utf8 string src. */ -utf8_constexpr14 utf8_nonnull utf8_pure utf8_int8_t * -utf8rchr(const utf8_int8_t *src, int chr); - -/* Number of bytes in the utf8 string str, - * including the null terminating byte. */ -utf8_constexpr14 utf8_nonnull utf8_pure size_t utf8size(const utf8_int8_t *str); - -/* Similar to utf8size, except that the null terminating byte is excluded. */ -utf8_constexpr14 utf8_nonnull utf8_pure size_t -utf8size_lazy(const utf8_int8_t *str); - -/* Similar to utf8size, except that only at most n bytes of src are looked and - * the null terminating byte is excluded. */ -utf8_constexpr14 utf8_nonnull utf8_pure size_t -utf8nsize_lazy(const utf8_int8_t *str, size_t n); - -/* Number of utf8 codepoints in the utf8 string src that consists entirely - * of utf8 codepoints from the utf8 string accept. */ -utf8_constexpr14 utf8_nonnull utf8_pure size_t -utf8spn(const utf8_int8_t *src, const utf8_int8_t *accept); - -/* The position of the utf8 string needle in the utf8 string haystack. */ -utf8_constexpr14 utf8_nonnull utf8_pure utf8_int8_t * -utf8str(const utf8_int8_t *haystack, const utf8_int8_t *needle); - -/* The position of the utf8 string needle in the utf8 string haystack, case - * insensitive. */ -utf8_constexpr14 utf8_nonnull utf8_pure utf8_int8_t * -utf8casestr(const utf8_int8_t *haystack, const utf8_int8_t *needle); - -/* Return 0 on success, or the position of the invalid - * utf8 codepoint on failure. */ -utf8_constexpr14 utf8_nonnull utf8_pure utf8_int8_t * -utf8valid(const utf8_int8_t *str); - -/* Similar to utf8valid, except that only at most n bytes of src are looked. */ -utf8_constexpr14 utf8_nonnull utf8_pure utf8_int8_t * -utf8nvalid(const utf8_int8_t *str, size_t n); - -/* Given a null-terminated string, makes the string valid by replacing invalid - * codepoints with a 1-byte replacement. Returns 0 on success. */ -utf8_nonnull utf8_weak int utf8makevalid(utf8_int8_t *str, -const utf8_int32_t replacement); - -/* Sets out_codepoint to the current utf8 codepoint in str, and returns the - * address of the next utf8 codepoint after the current one in str. */ -utf8_constexpr14 utf8_nonnull utf8_int8_t * -utf8codepoint(const utf8_int8_t *utf8_restrict str, - utf8_int32_t *utf8_restrict out_codepoint); - -/* Calculates the size of the next utf8 codepoint in str. */ -utf8_constexpr14 utf8_nonnull size_t -utf8codepointcalcsize(const utf8_int8_t *str); - -/* Returns the size of the given codepoint in bytes. */ -utf8_constexpr14 size_t utf8codepointsize(utf8_int32_t chr); - -/* Write a codepoint to the given string, and return the address to the next - * place after the written codepoint. Pass how many bytes left in the buffer to - * n. If there is not enough space for the codepoint, this function returns - * null. */ -utf8_nonnull utf8_weak utf8_int8_t * - utf8catcodepoint(utf8_int8_t *str, utf8_int32_t chr, size_t n); - -/* Returns 1 if the given character is lowercase, or 0 if it is not. */ -utf8_constexpr14 int utf8islower(utf8_int32_t chr); - -/* Returns 1 if the given character is uppercase, or 0 if it is not. */ -utf8_constexpr14 int utf8isupper(utf8_int32_t chr); - -/* Transform the given string into all lowercase codepoints. */ -utf8_nonnull utf8_weak void utf8lwr(utf8_int8_t *utf8_restrict str); - -/* Transform the given string into all uppercase codepoints. */ -utf8_nonnull utf8_weak void utf8upr(utf8_int8_t *utf8_restrict str); - -/* Make a codepoint lower case if possible. */ -utf8_constexpr14 utf8_int32_t utf8lwrcodepoint(utf8_int32_t cp); - -/* Make a codepoint upper case if possible. */ -utf8_constexpr14 utf8_int32_t utf8uprcodepoint(utf8_int32_t cp); - -/* Sets out_codepoint to the current utf8 codepoint in str, and returns the - * address of the previous utf8 codepoint before the current one in str. */ -utf8_constexpr14 utf8_nonnull utf8_int8_t * -utf8rcodepoint(const utf8_int8_t *utf8_restrict str, - utf8_int32_t *utf8_restrict out_codepoint); - -/* Duplicate the utf8 string src by getting its size, calling alloc_func_ptr to - * copy over data to a new buffer, and returning that. Or 0 if alloc_func_ptr - * returned null. */ -utf8_weak utf8_int8_t *utf8dup_ex(const utf8_int8_t *src, - utf8_int8_t *(*alloc_func_ptr)(utf8_int8_t *, - size_t), - utf8_int8_t *user_data); - -/* Similar to utf8dup, except that at most n bytes of src are copied. If src is - * longer than n, only n bytes are copied and a null byte is added. - * - * Returns a new string if successful, 0 otherwise. */ -utf8_weak utf8_int8_t *utf8ndup_ex(const utf8_int8_t *src, size_t n, - utf8_int8_t *(*alloc_func_ptr)(utf8_int8_t *, - size_t), - utf8_int8_t *user_data); - -#undef utf8_weak -#undef utf8_pure -#undef utf8_nonnull - -utf8_constexpr14_impl int utf8casecmp(const utf8_int8_t *src1, - const utf8_int8_t *src2) { - utf8_int32_t src1_lwr_cp = 0, src2_lwr_cp = 0, src1_upr_cp = 0, - src2_upr_cp = 0, src1_orig_cp = 0, src2_orig_cp = 0; - - for (;;) { - src1 = utf8codepoint(src1, &src1_orig_cp); - src2 = utf8codepoint(src2, &src2_orig_cp); - - /* lower the srcs if required */ - src1_lwr_cp = utf8lwrcodepoint(src1_orig_cp); - src2_lwr_cp = utf8lwrcodepoint(src2_orig_cp); - - /* lower the srcs if required */ - src1_upr_cp = utf8uprcodepoint(src1_orig_cp); - src2_upr_cp = utf8uprcodepoint(src2_orig_cp); - - /* check if the lowered codepoints match */ - if ((0 == src1_orig_cp) && (0 == src2_orig_cp)) { - return 0; - } else if ((src1_lwr_cp == src2_lwr_cp) || (src1_upr_cp == src2_upr_cp)) { - continue; - } - - /* if they don't match, then we return the difference between the characters - */ - return src1_lwr_cp - src2_lwr_cp; - } -} - -utf8_int8_t *utf8cat(utf8_int8_t *utf8_restrict dst, -const utf8_int8_t *utf8_restrict src) { -utf8_int8_t *d = dst; -/* find the null terminating byte in dst */ -while ('\0' != *d) { -d++; -} - -/* overwriting the null terminating byte in dst, append src byte-by-byte */ -while ('\0' != *src) { -*d++ = *src++; -} - -/* write out a new null terminating byte into dst */ -*d = '\0'; - -return dst; -} - -utf8_constexpr14_impl utf8_int8_t *utf8chr(const utf8_int8_t *src, - utf8_int32_t chr) { - utf8_int8_t c[5] = {'\0', '\0', '\0', '\0', '\0'}; - - if (0 == chr) { - /* being asked to return position of null terminating byte, so - * just run s to the end, and return! */ - while ('\0' != *src) { - src++; - } - return (utf8_int8_t *)src; - } else if (0 == ((utf8_int32_t)0xffffff80 & chr)) { - /* 1-byte/7-bit ascii - * (0b0xxxxxxx) */ - c[0] = (utf8_int8_t)chr; - } else if (0 == ((utf8_int32_t)0xfffff800 & chr)) { - /* 2-byte/11-bit utf8 code point - * (0b110xxxxx 0b10xxxxxx) */ - c[0] = (utf8_int8_t)(0xc0 | (utf8_int8_t)(chr >> 6)); - c[1] = (utf8_int8_t)(0x80 | (utf8_int8_t)(chr & 0x3f)); - } else if (0 == ((utf8_int32_t)0xffff0000 & chr)) { - /* 3-byte/16-bit utf8 code point - * (0b1110xxxx 0b10xxxxxx 0b10xxxxxx) */ - c[0] = (utf8_int8_t)(0xe0 | (utf8_int8_t)(chr >> 12)); - c[1] = (utf8_int8_t)(0x80 | (utf8_int8_t)((chr >> 6) & 0x3f)); - c[2] = (utf8_int8_t)(0x80 | (utf8_int8_t)(chr & 0x3f)); - } else { /* if (0 == ((int)0xffe00000 & chr)) { */ - /* 4-byte/21-bit utf8 code point - * (0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx) */ - c[0] = (utf8_int8_t)(0xf0 | (utf8_int8_t)(chr >> 18)); - c[1] = (utf8_int8_t)(0x80 | (utf8_int8_t)((chr >> 12) & 0x3f)); - c[2] = (utf8_int8_t)(0x80 | (utf8_int8_t)((chr >> 6) & 0x3f)); - c[3] = (utf8_int8_t)(0x80 | (utf8_int8_t)(chr & 0x3f)); - } - - /* we've made c into a 2 utf8 codepoint string, one for the chr we are - * seeking, another for the null terminating byte. Now use utf8str to - * search */ - return utf8str(src, c); -} - -utf8_constexpr14_impl int utf8cmp(const utf8_int8_t *src1, - const utf8_int8_t *src2) { - while (('\0' != *src1) || ('\0' != *src2)) { - if (*src1 < *src2) { - return -1; - } else if (*src1 > *src2) { - return 1; - } - - src1++; - src2++; - } - - /* both utf8 strings matched */ - return 0; -} - -utf8_constexpr14_impl int utf8coll(const utf8_int8_t *src1, - const utf8_int8_t *src2); - -utf8_int8_t *utf8cpy(utf8_int8_t *utf8_restrict dst, -const utf8_int8_t *utf8_restrict src) { -utf8_int8_t *d = dst; - -/* overwriting anything previously in dst, write byte-by-byte - * from src */ -while ('\0' != *src) { -*d++ = *src++; -} - -/* append null terminating byte */ -*d = '\0'; - -return dst; -} - -utf8_constexpr14_impl size_t utf8cspn(const utf8_int8_t *src, - const utf8_int8_t *reject) { - size_t chars = 0; - - while ('\0' != *src) { - const utf8_int8_t *r = reject; - size_t offset = 0; - - while ('\0' != *r) { - /* checking that if *r is the start of a utf8 codepoint - * (it is not 0b10xxxxxx) and we have successfully matched - * a previous character (0 < offset) - we found a match */ - if ((0x80 != (0xc0 & *r)) && (0 < offset)) { - return chars; - } else { - if (*r == src[offset]) { - /* part of a utf8 codepoint matched, so move our checking - * onwards to the next byte */ - offset++; - r++; - } else { - /* r could be in the middle of an unmatching utf8 code point, - * so we need to march it on to the next character beginning, */ - - do { - r++; - } while (0x80 == (0xc0 & *r)); - - /* reset offset too as we found a mismatch */ - offset = 0; - } - } - } - - /* found a match at the end of *r, so didn't get a chance to test it */ - if (0 < offset) { - return chars; - } - - /* the current utf8 codepoint in src did not match reject, but src - * could have been partway through a utf8 codepoint, so we need to - * march it onto the next utf8 codepoint starting byte */ - do { - src++; - } while ((0x80 == (0xc0 & *src))); - chars++; - } - - return chars; -} - -utf8_int8_t *utf8dup(const utf8_int8_t *src) { - return utf8dup_ex(src, utf8_null, utf8_null); -} - -utf8_int8_t *utf8dup_ex(const utf8_int8_t *src, - utf8_int8_t *(*alloc_func_ptr)(utf8_int8_t *, size_t), - utf8_int8_t *user_data) { -utf8_int8_t *n = utf8_null; - -/* figure out how many bytes (including the terminator) we need to copy first - */ -size_t bytes = utf8size(src); - -if (alloc_func_ptr) { -n = alloc_func_ptr(user_data, bytes); -} else { -n = (utf8_int8_t *)malloc(bytes); -} - -if (utf8_null == n) { -/* out of memory so we bail */ -return utf8_null; -} else { -bytes = 0; - -/* copy src byte-by-byte into our new utf8 string */ -while ('\0' != src[bytes]) { -n[bytes] = src[bytes]; -bytes++; -} - -/* append null terminating byte */ -n[bytes] = '\0'; -return n; -} -} - -utf8_constexpr14_impl utf8_int8_t *utf8fry(const utf8_int8_t *str); - -utf8_constexpr14_impl size_t utf8len(const utf8_int8_t *str) { - return utf8nlen(str, SIZE_MAX); -} - -utf8_constexpr14_impl size_t utf8nlen(const utf8_int8_t *str, size_t n) { - const utf8_int8_t *t = str; - size_t length = 0; - - while ((size_t)(str - t) < n && '\0' != *str) { - if (0xf0 == (0xf8 & *str)) { - /* 4-byte utf8 code point (began with 0b11110xxx) */ - str += 4; - } else if (0xe0 == (0xf0 & *str)) { - /* 3-byte utf8 code point (began with 0b1110xxxx) */ - str += 3; - } else if (0xc0 == (0xe0 & *str)) { - /* 2-byte utf8 code point (began with 0b110xxxxx) */ - str += 2; - } else { /* if (0x00 == (0x80 & *s)) { */ - /* 1-byte ascii (began with 0b0xxxxxxx) */ - str += 1; - } - - /* no matter the bytes we marched s forward by, it was - * only 1 utf8 codepoint */ - length++; - } - - if ((size_t)(str - t) > n) { - length--; - } - return length; -} - -utf8_constexpr14_impl int utf8ncasecmp(const utf8_int8_t *src1, - const utf8_int8_t *src2, size_t n) { - utf8_int32_t src1_lwr_cp = 0, src2_lwr_cp = 0, src1_upr_cp = 0, - src2_upr_cp = 0, src1_orig_cp = 0, src2_orig_cp = 0; - - do { - const utf8_int8_t *const s1 = src1; - const utf8_int8_t *const s2 = src2; - - /* first check that we have enough bytes left in n to contain an entire - * codepoint */ - if (0 == n) { - return 0; - } - - if ((1 == n) && ((0xc0 == (0xe0 & *s1)) || (0xc0 == (0xe0 & *s2)))) { - const utf8_int32_t c1 = (0xe0 & *s1); - const utf8_int32_t c2 = (0xe0 & *s2); - - if (c1 < c2) { - return c1 - c2; - } else { - return 0; - } - } - - if ((2 >= n) && ((0xe0 == (0xf0 & *s1)) || (0xe0 == (0xf0 & *s2)))) { - const utf8_int32_t c1 = (0xf0 & *s1); - const utf8_int32_t c2 = (0xf0 & *s2); - - if (c1 < c2) { - return c1 - c2; - } else { - return 0; - } - } - - if ((3 >= n) && ((0xf0 == (0xf8 & *s1)) || (0xf0 == (0xf8 & *s2)))) { - const utf8_int32_t c1 = (0xf8 & *s1); - const utf8_int32_t c2 = (0xf8 & *s2); - - if (c1 < c2) { - return c1 - c2; - } else { - return 0; - } - } - - src1 = utf8codepoint(src1, &src1_orig_cp); - src2 = utf8codepoint(src2, &src2_orig_cp); - n -= utf8codepointsize(src1_orig_cp); - - src1_lwr_cp = utf8lwrcodepoint(src1_orig_cp); - src2_lwr_cp = utf8lwrcodepoint(src2_orig_cp); - - src1_upr_cp = utf8uprcodepoint(src1_orig_cp); - src2_upr_cp = utf8uprcodepoint(src2_orig_cp); - - /* check if the lowered codepoints match */ - if ((0 == src1_orig_cp) && (0 == src2_orig_cp)) { - return 0; - } else if ((src1_lwr_cp == src2_lwr_cp) || (src1_upr_cp == src2_upr_cp)) { - continue; - } - - /* if they don't match, then we return the difference between the characters - */ - return src1_lwr_cp - src2_lwr_cp; - } while (0 < n); - - /* both utf8 strings matched */ - return 0; -} - -utf8_int8_t *utf8ncat(utf8_int8_t *utf8_restrict dst, -const utf8_int8_t *utf8_restrict src, size_t n) { -utf8_int8_t *d = dst; - -/* find the null terminating byte in dst */ -while ('\0' != *d) { -d++; -} - -/* overwriting the null terminating byte in dst, append src byte-by-byte - * stopping if we run out of space */ -do { -*d++ = *src++; -} while (('\0' != *src) && (0 != --n)); - -/* write out a new null terminating byte into dst */ -*d = '\0'; - -return dst; -} - -utf8_constexpr14_impl int utf8ncmp(const utf8_int8_t *src1, - const utf8_int8_t *src2, size_t n) { - while ((0 != n--) && (('\0' != *src1) || ('\0' != *src2))) { - if (*src1 < *src2) { - return -1; - } else if (*src1 > *src2) { - return 1; - } - - src1++; - src2++; - } - - /* both utf8 strings matched */ - return 0; -} - -utf8_int8_t *utf8ncpy(utf8_int8_t *utf8_restrict dst, -const utf8_int8_t *utf8_restrict src, size_t n) { -utf8_int8_t *d = dst; -size_t index = 0, check_index = 0; - -if (n == 0) { -return dst; -} - -/* overwriting anything previously in dst, write byte-by-byte - * from src */ -for (index = 0; index < n; index++) { -d[index] = src[index]; -if ('\0' == src[index]) { -break; -} -} - -for (check_index = index - 1; -check_index > 0 && 0x80 == (0xc0 & d[check_index]); check_index--) { -/* just moving the index */ -} - -if (check_index < index && -(index - check_index) < utf8codepointsize(d[check_index])) { -index = check_index; -} - -/* append null terminating byte */ -for (; index < n; index++) { -d[index] = 0; -} - -return dst; -} - -utf8_int8_t *utf8ndup(const utf8_int8_t *src, size_t n) { - return utf8ndup_ex(src, n, utf8_null, utf8_null); -} - -utf8_int8_t *utf8ndup_ex(const utf8_int8_t *src, size_t n, - utf8_int8_t *(*alloc_func_ptr)(utf8_int8_t *, size_t), - utf8_int8_t *user_data) { -utf8_int8_t *c = utf8_null; -size_t bytes = 0; - -/* Find the end of the string or stop when n is reached */ -while ('\0' != src[bytes] && bytes < n) { -bytes++; -} - -/* In case bytes is actually less than n, we need to set it - * to be used later in the copy byte by byte. */ -n = bytes; - -if (alloc_func_ptr) { -c = alloc_func_ptr(user_data, bytes + 1); -} else { -c = (utf8_int8_t *)malloc(bytes + 1); -} - -if (utf8_null == c) { -/* out of memory so we bail */ -return utf8_null; -} - -bytes = 0; - -/* copy src byte-by-byte into our new utf8 string */ -while ('\0' != src[bytes] && bytes < n) { -c[bytes] = src[bytes]; -bytes++; -} - -/* append null terminating byte */ -c[bytes] = '\0'; -return c; -} - -utf8_constexpr14_impl utf8_int8_t *utf8rchr(const utf8_int8_t *src, int chr) { - - utf8_int8_t *match = utf8_null; - utf8_int8_t c[5] = {'\0', '\0', '\0', '\0', '\0'}; - - if (0 == chr) { - /* being asked to return position of null terminating byte, so - * just run s to the end, and return! */ - while ('\0' != *src) { - src++; - } - return (utf8_int8_t *)src; - } else if (0 == ((int)0xffffff80 & chr)) { - /* 1-byte/7-bit ascii - * (0b0xxxxxxx) */ - c[0] = (utf8_int8_t)chr; - } else if (0 == ((int)0xfffff800 & chr)) { - /* 2-byte/11-bit utf8 code point - * (0b110xxxxx 0b10xxxxxx) */ - c[0] = (utf8_int8_t)(0xc0 | (utf8_int8_t)(chr >> 6)); - c[1] = (utf8_int8_t)(0x80 | (utf8_int8_t)(chr & 0x3f)); - } else if (0 == ((int)0xffff0000 & chr)) { - /* 3-byte/16-bit utf8 code point - * (0b1110xxxx 0b10xxxxxx 0b10xxxxxx) */ - c[0] = (utf8_int8_t)(0xe0 | (utf8_int8_t)(chr >> 12)); - c[1] = (utf8_int8_t)(0x80 | (utf8_int8_t)((chr >> 6) & 0x3f)); - c[2] = (utf8_int8_t)(0x80 | (utf8_int8_t)(chr & 0x3f)); - } else { /* if (0 == ((int)0xffe00000 & chr)) { */ - /* 4-byte/21-bit utf8 code point - * (0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx) */ - c[0] = (utf8_int8_t)(0xf0 | (utf8_int8_t)(chr >> 18)); - c[1] = (utf8_int8_t)(0x80 | (utf8_int8_t)((chr >> 12) & 0x3f)); - c[2] = (utf8_int8_t)(0x80 | (utf8_int8_t)((chr >> 6) & 0x3f)); - c[3] = (utf8_int8_t)(0x80 | (utf8_int8_t)(chr & 0x3f)); - } - - /* we've created a 2 utf8 codepoint string in c that is - * the utf8 character asked for by chr, and a null - * terminating byte */ - - while ('\0' != *src) { - size_t offset = 0; - - while (src[offset] == c[offset]) { - offset++; - } - - if ('\0' == c[offset]) { - /* we found a matching utf8 code point */ - match = (utf8_int8_t *)src; - src += offset; - } else { - src += offset; - - /* need to march s along to next utf8 codepoint start - * (the next byte that doesn't match 0b10xxxxxx) */ - if ('\0' != *src) { - do { - src++; - } while (0x80 == (0xc0 & *src)); - } - } - } - - /* return the last match we found (or 0 if no match was found) */ - return match; -} - -utf8_constexpr14_impl utf8_int8_t *utf8pbrk(const utf8_int8_t *str, - const utf8_int8_t *accept) { - while ('\0' != *str) { - const utf8_int8_t *a = accept; - size_t offset = 0; - - while ('\0' != *a) { - /* checking that if *a is the start of a utf8 codepoint - * (it is not 0b10xxxxxx) and we have successfully matched - * a previous character (0 < offset) - we found a match */ - if ((0x80 != (0xc0 & *a)) && (0 < offset)) { - return (utf8_int8_t *)str; - } else { - if (*a == str[offset]) { - /* part of a utf8 codepoint matched, so move our checking - * onwards to the next byte */ - offset++; - a++; - } else { - /* r could be in the middle of an unmatching utf8 code point, - * so we need to march it on to the next character beginning, */ - - do { - a++; - } while (0x80 == (0xc0 & *a)); - - /* reset offset too as we found a mismatch */ - offset = 0; - } - } - } - - /* we found a match on the last utf8 codepoint */ - if (0 < offset) { - return (utf8_int8_t *)str; - } - - /* the current utf8 codepoint in src did not match accept, but src - * could have been partway through a utf8 codepoint, so we need to - * march it onto the next utf8 codepoint starting byte */ - do { - str++; - } while ((0x80 == (0xc0 & *str))); - } - - return utf8_null; -} - -utf8_constexpr14_impl size_t utf8size(const utf8_int8_t *str) { - return utf8size_lazy(str) + 1; -} - -utf8_constexpr14_impl size_t utf8size_lazy(const utf8_int8_t *str) { - return utf8nsize_lazy(str, SIZE_MAX); -} - -utf8_constexpr14_impl size_t utf8nsize_lazy(const utf8_int8_t *str, size_t n) { - size_t size = 0; - while (size < n && '\0' != str[size]) { - size++; - } - return size; -} - -utf8_constexpr14_impl size_t utf8spn(const utf8_int8_t *src, - const utf8_int8_t *accept) { - size_t chars = 0; - - while ('\0' != *src) { - const utf8_int8_t *a = accept; - size_t offset = 0; - - while ('\0' != *a) { - /* checking that if *r is the start of a utf8 codepoint - * (it is not 0b10xxxxxx) and we have successfully matched - * a previous character (0 < offset) - we found a match */ - if ((0x80 != (0xc0 & *a)) && (0 < offset)) { - /* found a match, so increment the number of utf8 codepoints - * that have matched and stop checking whether any other utf8 - * codepoints in a match */ - chars++; - src += offset; - offset = 0; - break; - } else { - if (*a == src[offset]) { - offset++; - a++; - } else { - /* a could be in the middle of an unmatching utf8 codepoint, - * so we need to march it on to the next character beginning, */ - do { - a++; - } while (0x80 == (0xc0 & *a)); - - /* reset offset too as we found a mismatch */ - offset = 0; - } - } - } - - /* found a match at the end of *a, so didn't get a chance to test it */ - if (0 < offset) { - chars++; - src += offset; - continue; - } - - /* if a got to its terminating null byte, then we didn't find a match. - * Return the current number of matched utf8 codepoints */ - if ('\0' == *a) { - return chars; - } - } - - return chars; -} - -utf8_constexpr14_impl utf8_int8_t *utf8str(const utf8_int8_t *haystack, - const utf8_int8_t *needle) { - utf8_int32_t throwaway_codepoint = 0; - - /* if needle has no utf8 codepoints before the null terminating - * byte then return haystack */ - if ('\0' == *needle) { - return (utf8_int8_t *)haystack; - } - - while ('\0' != *haystack) { - const utf8_int8_t *maybeMatch = haystack; - const utf8_int8_t *n = needle; - - while (*haystack == *n && (*haystack != '\0' && *n != '\0')) { - n++; - haystack++; - } - - if ('\0' == *n) { - /* we found the whole utf8 string for needle in haystack at - * maybeMatch, so return it */ - return (utf8_int8_t *)maybeMatch; - } else { - /* h could be in the middle of an unmatching utf8 codepoint, - * so we need to march it on to the next character beginning - * starting from the current character */ - haystack = utf8codepoint(maybeMatch, &throwaway_codepoint); - } - } - - /* no match */ - return utf8_null; -} - -utf8_constexpr14_impl utf8_int8_t *utf8casestr(const utf8_int8_t *haystack, - const utf8_int8_t *needle) { - /* if needle has no utf8 codepoints before the null terminating - * byte then return haystack */ - if ('\0' == *needle) { - return (utf8_int8_t *)haystack; - } - - for (;;) { - const utf8_int8_t *maybeMatch = haystack; - const utf8_int8_t *n = needle; - utf8_int32_t h_cp = 0, n_cp = 0; - - /* Get the next code point and track it */ - const utf8_int8_t *nextH = haystack = utf8codepoint(haystack, &h_cp); - n = utf8codepoint(n, &n_cp); - - while ((0 != h_cp) && (0 != n_cp)) { - h_cp = utf8lwrcodepoint(h_cp); - n_cp = utf8lwrcodepoint(n_cp); - - /* if we find a mismatch, bail out! */ - if (h_cp != n_cp) { - break; - } - - haystack = utf8codepoint(haystack, &h_cp); - n = utf8codepoint(n, &n_cp); - } - - if (0 == n_cp) { - /* we found the whole utf8 string for needle in haystack at - * maybeMatch, so return it */ - return (utf8_int8_t *)maybeMatch; - } - - if (0 == h_cp) { - /* no match */ - return utf8_null; - } - - /* Roll back to the next code point in the haystack to test */ - haystack = nextH; - } -} - -utf8_constexpr14_impl utf8_int8_t *utf8valid(const utf8_int8_t *str) { - return utf8nvalid(str, SIZE_MAX); -} - -utf8_constexpr14_impl utf8_int8_t *utf8nvalid(const utf8_int8_t *str, - size_t n) { - const utf8_int8_t *t = str; - size_t consumed = 0, remained = 0; - - while ((void)(consumed = (size_t)(str - t)), consumed < n && '\0' != *str) { - remained = n - consumed; - - if (0xf0 == (0xf8 & *str)) { - /* ensure that there's 4 bytes or more remained */ - if (remained < 4) { - return (utf8_int8_t *)str; - } - - /* ensure each of the 3 following bytes in this 4-byte - * utf8 codepoint began with 0b10xxxxxx */ - if ((0x80 != (0xc0 & str[1])) || (0x80 != (0xc0 & str[2])) || - (0x80 != (0xc0 & str[3]))) { - return (utf8_int8_t *)str; - } - - /* ensure that our utf8 codepoint ended after 4 bytes */ - if (0x80 == (0xc0 & str[4])) { - return (utf8_int8_t *)str; - } - - /* ensure that the top 5 bits of this 4-byte utf8 - * codepoint were not 0, as then we could have used - * one of the smaller encodings */ - if ((0 == (0x07 & str[0])) && (0 == (0x30 & str[1]))) { - return (utf8_int8_t *)str; - } - - /* 4-byte utf8 code point (began with 0b11110xxx) */ - str += 4; - } else if (0xe0 == (0xf0 & *str)) { - /* ensure that there's 3 bytes or more remained */ - if (remained < 3) { - return (utf8_int8_t *)str; - } - - /* ensure each of the 2 following bytes in this 3-byte - * utf8 codepoint began with 0b10xxxxxx */ - if ((0x80 != (0xc0 & str[1])) || (0x80 != (0xc0 & str[2]))) { - return (utf8_int8_t *)str; - } - - /* ensure that our utf8 codepoint ended after 3 bytes */ - if (0x80 == (0xc0 & str[3])) { - return (utf8_int8_t *)str; - } - - /* ensure that the top 5 bits of this 3-byte utf8 - * codepoint were not 0, as then we could have used - * one of the smaller encodings */ - if ((0 == (0x0f & str[0])) && (0 == (0x20 & str[1]))) { - return (utf8_int8_t *)str; - } - - /* 3-byte utf8 code point (began with 0b1110xxxx) */ - str += 3; - } else if (0xc0 == (0xe0 & *str)) { - /* ensure that there's 2 bytes or more remained */ - if (remained < 2) { - return (utf8_int8_t *)str; - } - - /* ensure the 1 following byte in this 2-byte - * utf8 codepoint began with 0b10xxxxxx */ - if (0x80 != (0xc0 & str[1])) { - return (utf8_int8_t *)str; - } - - /* ensure that our utf8 codepoint ended after 2 bytes */ - if (0x80 == (0xc0 & str[2])) { - return (utf8_int8_t *)str; - } - - /* ensure that the top 4 bits of this 2-byte utf8 - * codepoint were not 0, as then we could have used - * one of the smaller encodings */ - if (0 == (0x1e & str[0])) { - return (utf8_int8_t *)str; - } - - /* 2-byte utf8 code point (began with 0b110xxxxx) */ - str += 2; - } else if (0x00 == (0x80 & *str)) { - /* 1-byte ascii (began with 0b0xxxxxxx) */ - str += 1; - } else { - /* we have an invalid 0b1xxxxxxx utf8 code point entry */ - return (utf8_int8_t *)str; - } - } - - return utf8_null; -} - -int utf8makevalid(utf8_int8_t *str, const utf8_int32_t replacement) { -utf8_int8_t *read = str; -utf8_int8_t *write = read; -const utf8_int8_t r = (utf8_int8_t)replacement; -utf8_int32_t codepoint = 0; - -if (replacement > 0x7f) { -return -1; -} - -while ('\0' != *read) { -if (0xf0 == (0xf8 & *read)) { -/* ensure each of the 3 following bytes in this 4-byte - * utf8 codepoint began with 0b10xxxxxx */ -if ((0x80 != (0xc0 & read[1])) || (0x80 != (0xc0 & read[2])) || -(0x80 != (0xc0 & read[3]))) { -*write++ = r; -read++; -continue; -} - -/* 4-byte utf8 code point (began with 0b11110xxx) */ -read = utf8codepoint(read, &codepoint); -write = utf8catcodepoint(write, codepoint, 4); -} else if (0xe0 == (0xf0 & *read)) { -/* ensure each of the 2 following bytes in this 3-byte - * utf8 codepoint began with 0b10xxxxxx */ -if ((0x80 != (0xc0 & read[1])) || (0x80 != (0xc0 & read[2]))) { -*write++ = r; -read++; -continue; -} - -/* 3-byte utf8 code point (began with 0b1110xxxx) */ -read = utf8codepoint(read, &codepoint); -write = utf8catcodepoint(write, codepoint, 3); -} else if (0xc0 == (0xe0 & *read)) { -/* ensure the 1 following byte in this 2-byte - * utf8 codepoint began with 0b10xxxxxx */ -if (0x80 != (0xc0 & read[1])) { -*write++ = r; -read++; -continue; -} - -/* 2-byte utf8 code point (began with 0b110xxxxx) */ -read = utf8codepoint(read, &codepoint); -write = utf8catcodepoint(write, codepoint, 2); -} else if (0x00 == (0x80 & *read)) { -/* 1-byte ascii (began with 0b0xxxxxxx) */ -read = utf8codepoint(read, &codepoint); -write = utf8catcodepoint(write, codepoint, 1); -} else { -/* if we got here then we've got a dangling continuation (0b10xxxxxx) */ -*write++ = r; -read++; -continue; -} -} - -*write = '\0'; - -return 0; -} - -utf8_constexpr14_impl utf8_int8_t * -utf8codepoint(const utf8_int8_t *utf8_restrict str, - utf8_int32_t *utf8_restrict out_codepoint) { - if (0xf0 == (0xf8 & str[0])) { - /* 4 byte utf8 codepoint */ - *out_codepoint = ((0x07 & str[0]) << 18) | ((0x3f & str[1]) << 12) | - ((0x3f & str[2]) << 6) | (0x3f & str[3]); - str += 4; - } else if (0xe0 == (0xf0 & str[0])) { - /* 3 byte utf8 codepoint */ - *out_codepoint = - ((0x0f & str[0]) << 12) | ((0x3f & str[1]) << 6) | (0x3f & str[2]); - str += 3; - } else if (0xc0 == (0xe0 & str[0])) { - /* 2 byte utf8 codepoint */ - *out_codepoint = ((0x1f & str[0]) << 6) | (0x3f & str[1]); - str += 2; - } else { - /* 1 byte utf8 codepoint otherwise */ - *out_codepoint = str[0]; - str += 1; - } - - return (utf8_int8_t *)str; -} - -utf8_constexpr14_impl size_t utf8codepointcalcsize(const utf8_int8_t *str) { - if (0xf0 == (0xf8 & str[0])) { - /* 4 byte utf8 codepoint */ - return 4; - } else if (0xe0 == (0xf0 & str[0])) { - /* 3 byte utf8 codepoint */ - return 3; - } else if (0xc0 == (0xe0 & str[0])) { - /* 2 byte utf8 codepoint */ - return 2; - } - - /* 1 byte utf8 codepoint otherwise */ - return 1; -} - -utf8_constexpr14_impl size_t utf8codepointsize(utf8_int32_t chr) { - if (0 == ((utf8_int32_t)0xffffff80 & chr)) { - return 1; - } else if (0 == ((utf8_int32_t)0xfffff800 & chr)) { - return 2; - } else if (0 == ((utf8_int32_t)0xffff0000 & chr)) { - return 3; - } else { /* if (0 == ((int)0xffe00000 & chr)) { */ - return 4; - } -} - -utf8_int8_t *utf8catcodepoint(utf8_int8_t *str, utf8_int32_t chr, size_t n) { -if (0 == ((utf8_int32_t)0xffffff80 & chr)) { -/* 1-byte/7-bit ascii - * (0b0xxxxxxx) */ -if (n < 1) { -return utf8_null; -} -str[0] = (utf8_int8_t)chr; -str += 1; -} else if (0 == ((utf8_int32_t)0xfffff800 & chr)) { -/* 2-byte/11-bit utf8 code point - * (0b110xxxxx 0b10xxxxxx) */ -if (n < 2) { -return utf8_null; -} -str[0] = (utf8_int8_t)(0xc0 | (utf8_int8_t)((chr >> 6) & 0x1f)); -str[1] = (utf8_int8_t)(0x80 | (utf8_int8_t)(chr & 0x3f)); -str += 2; -} else if (0 == ((utf8_int32_t)0xffff0000 & chr)) { -/* 3-byte/16-bit utf8 code point - * (0b1110xxxx 0b10xxxxxx 0b10xxxxxx) */ -if (n < 3) { -return utf8_null; -} -str[0] = (utf8_int8_t)(0xe0 | (utf8_int8_t)((chr >> 12) & 0x0f)); -str[1] = (utf8_int8_t)(0x80 | (utf8_int8_t)((chr >> 6) & 0x3f)); -str[2] = (utf8_int8_t)(0x80 | (utf8_int8_t)(chr & 0x3f)); -str += 3; -} else { /* if (0 == ((int)0xffe00000 & chr)) { */ -/* 4-byte/21-bit utf8 code point - * (0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx) */ -if (n < 4) { -return utf8_null; -} -str[0] = (utf8_int8_t)(0xf0 | (utf8_int8_t)((chr >> 18) & 0x07)); -str[1] = (utf8_int8_t)(0x80 | (utf8_int8_t)((chr >> 12) & 0x3f)); -str[2] = (utf8_int8_t)(0x80 | (utf8_int8_t)((chr >> 6) & 0x3f)); -str[3] = (utf8_int8_t)(0x80 | (utf8_int8_t)(chr & 0x3f)); -str += 4; -} - -return str; -} - -utf8_constexpr14_impl int utf8islower(utf8_int32_t chr) { - return chr != utf8uprcodepoint(chr); -} - -utf8_constexpr14_impl int utf8isupper(utf8_int32_t chr) { - return chr != utf8lwrcodepoint(chr); -} - -void utf8lwr(utf8_int8_t *utf8_restrict str) { -utf8_int32_t cp = 0; -utf8_int8_t *pn = utf8codepoint(str, &cp); - -while (cp != 0) { -const utf8_int32_t lwr_cp = utf8lwrcodepoint(cp); -const size_t size = utf8codepointsize(lwr_cp); - -if (lwr_cp != cp) { -utf8catcodepoint(str, lwr_cp, size); -} - -str = pn; -pn = utf8codepoint(str, &cp); -} -} - -void utf8upr(utf8_int8_t *utf8_restrict str) { -utf8_int32_t cp = 0; -utf8_int8_t *pn = utf8codepoint(str, &cp); - -while (cp != 0) { -const utf8_int32_t lwr_cp = utf8uprcodepoint(cp); -const size_t size = utf8codepointsize(lwr_cp); - -if (lwr_cp != cp) { -utf8catcodepoint(str, lwr_cp, size); -} - -str = pn; -pn = utf8codepoint(str, &cp); -} -} - -utf8_constexpr14_impl utf8_int32_t utf8lwrcodepoint(utf8_int32_t cp) { - if (((0x0041 <= cp) && (0x005a >= cp)) || - ((0x00c0 <= cp) && (0x00d6 >= cp)) || - ((0x00d8 <= cp) && (0x00de >= cp)) || - ((0x0391 <= cp) && (0x03a1 >= cp)) || - ((0x03a3 <= cp) && (0x03ab >= cp)) || - ((0x0410 <= cp) && (0x042f >= cp))) { - cp += 32; - } else if ((0x0400 <= cp) && (0x040f >= cp)) { - cp += 80; - } else if (((0x0100 <= cp) && (0x012f >= cp)) || - ((0x0132 <= cp) && (0x0137 >= cp)) || - ((0x014a <= cp) && (0x0177 >= cp)) || - ((0x0182 <= cp) && (0x0185 >= cp)) || - ((0x01a0 <= cp) && (0x01a5 >= cp)) || - ((0x01de <= cp) && (0x01ef >= cp)) || - ((0x01f8 <= cp) && (0x021f >= cp)) || - ((0x0222 <= cp) && (0x0233 >= cp)) || - ((0x0246 <= cp) && (0x024f >= cp)) || - ((0x03d8 <= cp) && (0x03ef >= cp)) || - ((0x0460 <= cp) && (0x0481 >= cp)) || - ((0x048a <= cp) && (0x04ff >= cp))) { - cp |= 0x1; - } else if (((0x0139 <= cp) && (0x0148 >= cp)) || - ((0x0179 <= cp) && (0x017e >= cp)) || - ((0x01af <= cp) && (0x01b0 >= cp)) || - ((0x01b3 <= cp) && (0x01b6 >= cp)) || - ((0x01cd <= cp) && (0x01dc >= cp))) { - cp += 1; - cp &= ~0x1; - } else { - switch (cp) { - default: - break; - case 0x0178: - cp = 0x00ff; - break; - case 0x0243: - cp = 0x0180; - break; - case 0x018e: - cp = 0x01dd; - break; - case 0x023d: - cp = 0x019a; - break; - case 0x0220: - cp = 0x019e; - break; - case 0x01b7: - cp = 0x0292; - break; - case 0x01c4: - cp = 0x01c6; - break; - case 0x01c7: - cp = 0x01c9; - break; - case 0x01ca: - cp = 0x01cc; - break; - case 0x01f1: - cp = 0x01f3; - break; - case 0x01f7: - cp = 0x01bf; - break; - case 0x0187: - cp = 0x0188; - break; - case 0x018b: - cp = 0x018c; - break; - case 0x0191: - cp = 0x0192; - break; - case 0x0198: - cp = 0x0199; - break; - case 0x01a7: - cp = 0x01a8; - break; - case 0x01ac: - cp = 0x01ad; - break; - case 0x01af: - cp = 0x01b0; - break; - case 0x01b8: - cp = 0x01b9; - break; - case 0x01bc: - cp = 0x01bd; - break; - case 0x01f4: - cp = 0x01f5; - break; - case 0x023b: - cp = 0x023c; - break; - case 0x0241: - cp = 0x0242; - break; - case 0x03fd: - cp = 0x037b; - break; - case 0x03fe: - cp = 0x037c; - break; - case 0x03ff: - cp = 0x037d; - break; - case 0x037f: - cp = 0x03f3; - break; - case 0x0386: - cp = 0x03ac; - break; - case 0x0388: - cp = 0x03ad; - break; - case 0x0389: - cp = 0x03ae; - break; - case 0x038a: - cp = 0x03af; - break; - case 0x038c: - cp = 0x03cc; - break; - case 0x038e: - cp = 0x03cd; - break; - case 0x038f: - cp = 0x03ce; - break; - case 0x0370: - cp = 0x0371; - break; - case 0x0372: - cp = 0x0373; - break; - case 0x0376: - cp = 0x0377; - break; - case 0x03f4: - cp = 0x03b8; - break; - case 0x03cf: - cp = 0x03d7; - break; - case 0x03f9: - cp = 0x03f2; - break; - case 0x03f7: - cp = 0x03f8; - break; - case 0x03fa: - cp = 0x03fb; - break; - } - } - - return cp; -} - -utf8_constexpr14_impl utf8_int32_t utf8uprcodepoint(utf8_int32_t cp) { - if (((0x0061 <= cp) && (0x007a >= cp)) || - ((0x00e0 <= cp) && (0x00f6 >= cp)) || - ((0x00f8 <= cp) && (0x00fe >= cp)) || - ((0x03b1 <= cp) && (0x03c1 >= cp)) || - ((0x03c3 <= cp) && (0x03cb >= cp)) || - ((0x0430 <= cp) && (0x044f >= cp))) { - cp -= 32; - } else if ((0x0450 <= cp) && (0x045f >= cp)) { - cp -= 80; - } else if (((0x0100 <= cp) && (0x012f >= cp)) || - ((0x0132 <= cp) && (0x0137 >= cp)) || - ((0x014a <= cp) && (0x0177 >= cp)) || - ((0x0182 <= cp) && (0x0185 >= cp)) || - ((0x01a0 <= cp) && (0x01a5 >= cp)) || - ((0x01de <= cp) && (0x01ef >= cp)) || - ((0x01f8 <= cp) && (0x021f >= cp)) || - ((0x0222 <= cp) && (0x0233 >= cp)) || - ((0x0246 <= cp) && (0x024f >= cp)) || - ((0x03d8 <= cp) && (0x03ef >= cp)) || - ((0x0460 <= cp) && (0x0481 >= cp)) || - ((0x048a <= cp) && (0x04ff >= cp))) { - cp &= ~0x1; - } else if (((0x0139 <= cp) && (0x0148 >= cp)) || - ((0x0179 <= cp) && (0x017e >= cp)) || - ((0x01af <= cp) && (0x01b0 >= cp)) || - ((0x01b3 <= cp) && (0x01b6 >= cp)) || - ((0x01cd <= cp) && (0x01dc >= cp))) { - cp -= 1; - cp |= 0x1; - } else { - switch (cp) { - default: - break; - case 0x00ff: - cp = 0x0178; - break; - case 0x0180: - cp = 0x0243; - break; - case 0x01dd: - cp = 0x018e; - break; - case 0x019a: - cp = 0x023d; - break; - case 0x019e: - cp = 0x0220; - break; - case 0x0292: - cp = 0x01b7; - break; - case 0x01c6: - cp = 0x01c4; - break; - case 0x01c9: - cp = 0x01c7; - break; - case 0x01cc: - cp = 0x01ca; - break; - case 0x01f3: - cp = 0x01f1; - break; - case 0x01bf: - cp = 0x01f7; - break; - case 0x0188: - cp = 0x0187; - break; - case 0x018c: - cp = 0x018b; - break; - case 0x0192: - cp = 0x0191; - break; - case 0x0199: - cp = 0x0198; - break; - case 0x01a8: - cp = 0x01a7; - break; - case 0x01ad: - cp = 0x01ac; - break; - case 0x01b0: - cp = 0x01af; - break; - case 0x01b9: - cp = 0x01b8; - break; - case 0x01bd: - cp = 0x01bc; - break; - case 0x01f5: - cp = 0x01f4; - break; - case 0x023c: - cp = 0x023b; - break; - case 0x0242: - cp = 0x0241; - break; - case 0x037b: - cp = 0x03fd; - break; - case 0x037c: - cp = 0x03fe; - break; - case 0x037d: - cp = 0x03ff; - break; - case 0x03f3: - cp = 0x037f; - break; - case 0x03ac: - cp = 0x0386; - break; - case 0x03ad: - cp = 0x0388; - break; - case 0x03ae: - cp = 0x0389; - break; - case 0x03af: - cp = 0x038a; - break; - case 0x03cc: - cp = 0x038c; - break; - case 0x03cd: - cp = 0x038e; - break; - case 0x03ce: - cp = 0x038f; - break; - case 0x0371: - cp = 0x0370; - break; - case 0x0373: - cp = 0x0372; - break; - case 0x0377: - cp = 0x0376; - break; - case 0x03d1: - cp = 0x0398; - break; - case 0x03d7: - cp = 0x03cf; - break; - case 0x03f2: - cp = 0x03f9; - break; - case 0x03f8: - cp = 0x03f7; - break; - case 0x03fb: - cp = 0x03fa; - break; - } - } - - return cp; -} - -utf8_constexpr14_impl utf8_int8_t * -utf8rcodepoint(const utf8_int8_t *utf8_restrict str, - utf8_int32_t *utf8_restrict out_codepoint) { - const utf8_int8_t *s = (const utf8_int8_t *)str; - - if (0xf0 == (0xf8 & s[0])) { - /* 4 byte utf8 codepoint */ - *out_codepoint = ((0x07 & s[0]) << 18) | ((0x3f & s[1]) << 12) | - ((0x3f & s[2]) << 6) | (0x3f & s[3]); - } else if (0xe0 == (0xf0 & s[0])) { - /* 3 byte utf8 codepoint */ - *out_codepoint = - ((0x0f & s[0]) << 12) | ((0x3f & s[1]) << 6) | (0x3f & s[2]); - } else if (0xc0 == (0xe0 & s[0])) { - /* 2 byte utf8 codepoint */ - *out_codepoint = ((0x1f & s[0]) << 6) | (0x3f & s[1]); - } else { - /* 1 byte utf8 codepoint otherwise */ - *out_codepoint = s[0]; - } - - do { - s--; - } while ((0 != (0x80 & s[0])) && (0x80 == (0xc0 & s[0]))); - - return (utf8_int8_t *)s; -} - -#undef utf8_restrict -#undef utf8_constexpr14 -#undef utf8_null - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -#endif /* SHEREDOM_UTF8_H_INCLUDED */ diff --git a/deps/ledger-zxlib/include/view_templates.h b/deps/ledger-zxlib/include/view_templates.h deleted file mode 100644 index a301b60..0000000 --- a/deps/ledger-zxlib/include/view_templates.h +++ /dev/null @@ -1,168 +0,0 @@ -/******************************************************************************* -* (c) 2016 Ledger -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#include - -#define UI_CENTER11PX BAGL_FONT_OPEN_SANS_REGULAR_11px | BAGL_FONT_ALIGNMENT_CENTER -#define UI_CENTER11PX_BOLD BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER -#define UI_11PX 11 - -#define DEFAULT_FONT BAGL_FONT_OPEN_SANS_LIGHT_16px | BAGL_FONT_ALIGNMENT_LEFT -#define UI_WHITE 0xFFFFFF -#define UI_BLACK 0x000000 - -#define UIID_ICONLEFT 0x10 -#define UIID_ICONRIGHT 0x11 -#define UIID_LABEL 0x20 -#define UIID_LABELSCROLL 0x71 - -#define UI_FillRectangle(id, x, y, w, h, fgcolor, bgcolor) \ -{ \ - { \ - BAGL_RECTANGLE, /* type */ \ - id, /* usedid */ \ - x, /* x */ \ - y, /* y */ \ - w, /* width */ \ - h, /* height */ \ - 0, /* stroke */ \ - 0, /* radius */ \ - BAGL_FILL, /* fill */ \ - fgcolor, /* fgcolor */ \ - bgcolor, /* bgcolor */ \ - 0, /* font_id */ \ - 0 /* icon_id */ \ - }, \ - NULL, /* text */ \ -} - -#define UI_LabelLine(id, x, y, w, h, fgcolor, bgcolor, text) \ -{ \ - { \ - BAGL_LABELINE, /* type */ \ - id, /* usedid */ \ - x, /* x */ \ - y, /* y */ \ - w, /* width */ \ - h, /* height */ \ - 0, /* stroke */ \ - 0, /* radius */ \ - 0, /* fill */ \ - fgcolor, /* fgcolor */ \ - bgcolor, /* bgcolor */ \ - UI_CENTER11PX, /* font_id */ \ - 0 /* icon_id */ \ - }, \ - text, /* text */ \ -} - -#define UI_LabelLineScrolling(id, x, y, w, h, fgcolor, bgcolor, text) \ -{ \ - { \ - BAGL_LABELINE, /* type */ \ - id, /* usedid */ \ - x, /* x */ \ - y, /* y */ \ - w, /* width */ \ - h, /* height */ \ - 5 | BAGL_STROKE_FLAG_ONESHOT, /* stroke | scr pause */ \ - 0, /* radius */ \ - 0, /* fill */ \ - fgcolor, /* fgcolor */ \ - bgcolor, /* bgcolor */ \ - UI_CENTER11PX, /* font_id */ \ - 50 /* icon_id / scroll speed */ \ - }, \ - text, /* text */ \ -} - -#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) -#define UI_SCREEN_WIDTH 128 -#define UI_SCREEN_HEIGHT 64 - -#define BAGL_GLYPH_ICON_LEFT ((const char*)&C_icon_left) -#define BAGL_GLYPH_ICON_RIGHT ((const char*)&C_icon_right) -#define BAGL_GLYPH_ICON_CROSS ((const char*)&C_icon_crossmark) -#define BAGL_GLYPH_ICON_CHECK ((const char*)&C_icon_validate) - -#define UI_Icon(id, x, y, w, h, icon) \ -{ \ - { \ - BAGL_ICON, /* type */ \ - id, /* usedid */ \ - x, /* x */ \ - y, /* y */ \ - w, /* width */ \ - h, /* height */ \ - 0, /* stroke */ \ - 0, /* radius */ \ - 0, /* fill */ \ - UI_WHITE, /* fgcolor */ \ - UI_BLACK, /* bgcolor */ \ - 0, /* font_id */ \ - 0 /* icon_id */ \ - }, \ - icon, /* text */ \ - 0, /* touch_area_brim */ \ - 0, /* overfgcolor */ \ - 0, /* overbgcolor */ \ - NULL, /* tap */ \ - NULL, /* out */ \ - NULL, /* over */ \ -} - -#define UI_BACKGROUND \ - UI_FillRectangle(0, 0, 0, UI_SCREEN_WIDTH, UI_SCREEN_HEIGHT, 0x000000, 0xFFFFFF) - -#define UI_BACKGROUND_LEFT_RIGHT_ICONS \ - UI_BACKGROUND, \ - UI_Icon(UIID_ICONLEFT, 2, 28, 4, 7, BAGL_GLYPH_ICON_LEFT), \ - UI_Icon(UIID_ICONRIGHT, 122, 28, 4, 7, BAGL_GLYPH_ICON_RIGHT) - -#else -#define UI_SCREEN_WIDTH 128 -#define UI_SCREEN_HEIGHT 32 - -#define UI_Icon(id, x, y, w, h, icon) \ -{ \ - { \ - BAGL_ICON, /* type */ \ - id, /* usedid */ \ - x, /* x */ \ - y, /* y */ \ - w, /* width */ \ - h, /* height */ \ - 0, /* stroke */ \ - 0, /* radius */ \ - 0, /* fill */ \ - UI_WHITE, /* fgcolor */ \ - UI_BLACK, /* bgcolor */ \ - 0, /* font_id */ \ - icon /* icon_id */ \ - }, \ - NULL, /* text */ \ -} - -#define UI_BACKGROUND \ - UI_FillRectangle(0, 0, 0, UI_SCREEN_WIDTH, UI_SCREEN_HEIGHT, 0x000000, 0xFFFFFF) - -#define UI_BACKGROUND_LEFT_RIGHT_ICONS \ - UI_BACKGROUND, \ - UI_Icon(UIID_ICONLEFT, 0, 0, 7, 7, BAGL_GLYPH_ICON_LEFT), \ - UI_Icon(UIID_ICONRIGHT, 128 - 7, 0, 7, 7, BAGL_GLYPH_ICON_RIGHT) -#endif diff --git a/deps/ledger-zxlib/include/zxerror.h b/deps/ledger-zxlib/include/zxerror.h deleted file mode 100644 index 3a245c5..0000000 --- a/deps/ledger-zxlib/include/zxerror.h +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#pragma once - -#include "zxmacros.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define CHECK_ZXERR(CALL) { \ - zxerr_t err = CALL; \ - if (err!=zxerr_ok) return err;} - -typedef enum { - zxerr_unknown = 0b00000000, - zxerr_ok = 0b00000011, - zxerr_no_data = 0b00000101, - zxerr_buffer_too_small = 0b00000110, - zxerr_out_of_bounds = 0b00001001, - zxerr_encoding_failed = 0b00001010, - zxerr_invalid_crypto_settings = 0b00001100, - zxerr_ledger_api_error = 0b00001111, -} zxerr_t; - -__Z_INLINE uint8_t getErrorMessage(char *buffer, uint16_t bufferLen, zxerr_t err) { - MEMZERO(buffer, bufferLen); - - switch (err) { - case zxerr_unknown: - snprintf(buffer, bufferLen, "zxerr_unknown"); - break; - case zxerr_ok: - snprintf(buffer, bufferLen, "zxerr_ok"); - break; - case zxerr_no_data: - snprintf(buffer, bufferLen, "zxerr_no_data"); - break; - case zxerr_out_of_bounds: - snprintf(buffer, bufferLen, "zxerr_out_of_bounds"); - break; - case zxerr_encoding_failed: - snprintf(buffer, bufferLen, "zxerr_encoding_failed"); - break; - case zxerr_invalid_crypto_settings: - snprintf(buffer, bufferLen, "zxerr_invalid_crypto_settings"); - break; - case zxerr_ledger_api_error: - snprintf(buffer, bufferLen, "zxerr_ledger_api_error"); - break; - default: - snprintf(buffer, bufferLen, "err N/A"); - } - - return strlen(buffer); -} - -//0b00000000 -//0b00000011 -//0b00000101 -//0b00000110 -//0b00001001 -//0b00001010 -//0b00001100 -//0b00001111 -//0b00010001 -//0b00010010 -//0b00010100 -//0b00010111 -//0b00011000 -//0b00011011 -//0b00011101 -//0b00011110 -//0b00100001 -//0b00100010 -//0b00100100 -//0b00100111 -//0b00101000 -//0b00101011 -//0b00101101 -//0b00101110 -//0b00110000 -//0b00110011 -//0b00110101 -//0b00110110 -//0b00111001 -//0b00111010 -//0b00111100 -//0b00111111 - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/zxformat.h b/deps/ledger-zxlib/include/zxformat.h deleted file mode 100644 index d7e54db..0000000 --- a/deps/ledger-zxlib/include/zxformat.h +++ /dev/null @@ -1,367 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "zxmacros.h" -#include "zxerror.h" - -#define NUM_TO_STR(TYPE) __Z_INLINE const char * TYPE##_to_str(char *data, int dataLen, TYPE##_t number) { \ - if (dataLen < 2) return "Buffer too small"; \ - MEMZERO(data, dataLen); \ - char *p = data; \ - if (number < 0) { *(p++) = '-'; data++; } \ - else if (number == 0) { *(p++) = '0'; } \ - TYPE##_t tmp; \ - while (number != 0) { \ - if (p - data >= (dataLen - 1)) { return "Buffer too small"; } \ - tmp = number % 10; \ - tmp = tmp < 0 ? -tmp : tmp; \ - *(p++) = (char) ('0' + tmp); \ - number /= 10u; \ - } \ - while (p > data) { \ - p--; \ - char z = *data; *data = *p; *p = z; \ - data++; \ - } \ - return NULL; \ -} - -NUM_TO_STR(int32) - -NUM_TO_STR(int64) - -NUM_TO_STR(uint64) - -size_t z_strlen(const char *buffer, size_t maxSize); - -zxerr_t z_str3join(char *buffer, size_t bufferSize, const char *prefix, const char *suffix); - -__Z_INLINE void bip32_to_str(char *s, uint32_t max, const uint32_t *path, uint8_t pathLen) { - MEMZERO(s, max); - - if (pathLen == 0) { - snprintf(s, max, "EMPTY PATH"); - return; - } - - if (pathLen > 5) { - snprintf(s, max, "ERROR"); - return; - } - - uint32_t offset = 0; - for (uint16_t i = 0; i < pathLen; i++) { - size_t written; - - // Warning: overcomplicated because Ledger's snprintf does not return number of written bytes - - snprintf(s + offset, max - offset, "%d", path[i] & 0x7FFFFFFFu); - written = strlen(s + offset); - if (written == 0 || written >= max - offset) { - snprintf(s, max, "ERROR"); - return; - } - offset += written; - - if ((path[i] & 0x80000000u) != 0) { - snprintf(s + offset, max - offset, "'"); - written = strlen(s + offset); - if (written == 0 || written >= max - offset) { - snprintf(s, max, "ERROR"); - return; - } - offset += written; - } - - if (i != pathLen - 1) { - snprintf(s + offset, max - offset, "/"); - written = strlen(s + offset); - if (written == 0 || written >= max - offset) { - snprintf(s, max, "ERROR"); - return; - } - offset += written; - } - } -} - -__Z_INLINE void bip44_to_str(char *s, uint32_t max, const uint32_t path[5]) { - bip32_to_str(s, max, path, 5); -} - -__Z_INLINE int8_t str_to_int8(const char *start, const char *end, char *error) { - int sign = 1; - if (*start == '-') { - sign = -1; - start++; - } - - int64_t value = 0; - int multiplier = 1; - for (const char *s = end - 1; s >= start; s--) { - int delta = (*s - '0'); - if (delta >= 0 && delta <= 9) { - value += (delta * multiplier); - multiplier *= 10; - } else { - if (error != NULL) { - *error = 1; - return 0; - } - } - } - - value *= sign; - if (value >= INT8_MIN && value <= INT8_MAX) { - return (int8_t) value; - } - if (error != NULL) { - *error = 1; - } - return 0; -} - -__Z_INLINE int64_t str_to_int64(const char *start, const char *end, char *error) { - int sign = 1; - if (*start == '-') { - sign = -1; - start++; - } - - int64_t value = 0; - int64_t multiplier = 1; - for (const char *s = end - 1; s >= start; s--) { - int64_t delta = (*s - '0'); - if (delta >= 0 && delta <= 9) { - value += delta * multiplier; - multiplier *= 10; - } else { - if (error != NULL) { - *error = 1; - return 0; - } - } - } - - return value * sign; -} - -uint8_t intstr_to_fpstr_inplace(char *number, size_t number_max_size, uint8_t decimalPlaces); - -__Z_INLINE uint8_t fpstr_to_str(char *out, uint16_t outLen, const char *number, uint8_t decimals) { - MEMZERO(out, outLen); - size_t digits = strlen(number); - - if (decimals == 0) { - if (digits == 0) { - snprintf(out, outLen, "0"); - return 0; - } - - if (outLen < digits) { - snprintf(out, outLen, "ERR"); - return 1; - } - - // No need for formatting - snprintf(out, outLen, "%s", number); - return 0; - } - - if ((outLen < decimals + 2)) { - snprintf(out, outLen, "ERR"); - return 1; - } - - if (outLen < digits + 2) { - snprintf(out, outLen, "ERR"); - return 1; - } - - if (digits <= decimals) { - if (outLen <= decimals + 2) { - snprintf(out, outLen, "ERR"); - return 1; - } - - // First part - snprintf(out, outLen, "0."); - out += 2; - outLen -= 2; - - MEMSET(out, '0', decimals - digits); - out += decimals - digits; - outLen -= decimals - digits; - - snprintf(out, outLen, "%s", number); - return 0; - } - - const size_t shift = digits - decimals; - snprintf(out, outLen, "%s", number); - number += shift; - - out += shift; - outLen -= shift; - - *out++ = '.'; - outLen--; - snprintf(out, outLen, "%s", number); - return 0; -} - -__Z_INLINE uint16_t fpuint64_to_str(char *out, uint16_t outLen, const uint64_t value, uint8_t decimals) { - char buffer[30]; - MEMZERO(buffer, sizeof(buffer)); - uint64_to_str(buffer, sizeof(buffer), value); - fpstr_to_str(out, outLen, buffer, decimals); - return (uint16_t) strlen(out); -} - -__Z_INLINE void number_inplace_trimming(char *s, uint8_t non_trimmed) { - const size_t len = strlen(s); - if (len == 0 || len == 1 || len > 1024) { - return; - } - - int16_t dec_point = -1; - for (int16_t i = 0; i < (int16_t) len && dec_point < 0; i++) { - if (s[i] == '.') { - dec_point = i; - } - } - if (dec_point < 0) { - return; - } - - const size_t limit = (size_t) dec_point + non_trimmed; - for (size_t i = (len - 1); i > limit && s[i] == '0'; i--) { - s[i] = 0; - } -} - -__Z_INLINE uint64_t uint64_from_BEarray(const uint8_t data[8]) { - uint64_t result = 0; - for (uint8_t i = 0; i < 8u; i++) { - result <<= 8u; - result += data[i]; - } - return result; -} - -__Z_INLINE uint32_t array_to_hexstr(char *dst, uint16_t dstLen, const uint8_t *src, uint8_t count) { - MEMZERO(dst, dstLen); - if (dstLen < (count * 2 + 1)) { - return 0; - } - - const char hexchars[] = "0123456789abcdef"; - for (uint8_t i = 0; i < count; i++, src++) { - *dst++ = hexchars[*src >> 4u]; - *dst++ = hexchars[*src & 0x0Fu]; - } - *dst = 0; // terminate string - - return (uint32_t) (count * 2); -} - -__Z_INLINE void pageStringExt(char *outValue, uint16_t outValueLen, - const char *inValue, uint16_t inValueLen, - uint8_t pageIdx, uint8_t *pageCount) { - MEMZERO(outValue, outValueLen); - *pageCount = 0; - - outValueLen--; // leave space for NULL termination - if (outValueLen == 0) { - return; - } - - if (inValueLen == 0) { - return; - } - - *pageCount = (uint8_t) (inValueLen / outValueLen); - const uint16_t lastChunkLen = (inValueLen % outValueLen); - - if (lastChunkLen > 0) { - (*pageCount)++; - } - - if (pageIdx < *pageCount) { - if (lastChunkLen > 0 && pageIdx == *pageCount - 1) { - MEMCPY(outValue, inValue + (pageIdx * outValueLen), lastChunkLen); - } else { - MEMCPY(outValue, inValue + (pageIdx * outValueLen), outValueLen); - } - } -} - -__Z_INLINE void pageString(char *outValue, uint16_t outValueLen, - const char *inValue, - uint8_t pageIdx, uint8_t *pageCount) { - pageStringExt(outValue, outValueLen, inValue, (uint16_t) strlen(inValue), pageIdx, pageCount); -} - -__Z_INLINE zxerr_t formatBufferData( - const uint8_t *ptr, - uint64_t len, - char *outValue, - uint16_t outValueLen, - uint8_t pageIdx, - uint8_t *pageCount) { - char bufferUI[500 + 1]; - MEMZERO(bufferUI, sizeof(bufferUI)); - MEMZERO(outValue, 0); - CHECK_APP_CANARY() - - if (len >= sizeof(bufferUI)) { - return zxerr_buffer_too_small; - } - memcpy(bufferUI, ptr, len); - - // Check we have all ascii - uint8_t allAscii = 1; - for (size_t i = 0; i < len && allAscii; i++) { - if (bufferUI[i] < 32 || bufferUI[i] > 127) { - allAscii = 0; - } - } - - if (!allAscii) { - bufferUI[0] = '0'; - bufferUI[1] = 'x'; - if (array_to_hexstr(bufferUI + 2, sizeof(bufferUI) - 2, ptr, len) == 0) { - return zxerr_buffer_too_small; - } - } - - pageString(outValue, outValueLen, bufferUI, pageIdx, pageCount); - - return zxerr_ok; -} - -size_t asciify(char *utf8_in); - -size_t asciify_ext(const char *utf8_in, char *ascii_only_out); - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/zxmacros.h b/deps/ledger-zxlib/include/zxmacros.h deleted file mode 100644 index b5bf7e8..0000000 --- a/deps/ledger-zxlib/include/zxmacros.h +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#pragma clang diagnostic push -#pragma ide diagnostic ignored "modernize-use-nullptr" -#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection" -#pragma ide diagnostic ignored "OCUnusedMacroInspection" -#pragma ide diagnostic ignored "modernize-deprecated-headers" - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include "string.h" - -#ifndef __APPLE__ - -extern void explicit_bzero(void *s, size_t n) __THROW __nonnull ((1)); - -#endif - -#define __Z_INLINE inline __attribute__((always_inline)) static -#define __Z_UNUSED __attribute__((unused)) -#define NV_ALIGN __attribute__ ((aligned(64))) - -#if defined(LEDGER_SPECIFIC) -#include "bolos_target.h" -#endif - -#if defined (TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) -#include "zxmacros_ledger.h" -#else - -#include "zxmacros_x64.h" - -#endif - -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -#define ZX_SWAP(v) (((v) & 0x000000FFu) << 24u | ((v) & 0x0000FF00u) << 8u | ((v) & 0x00FF0000u) >> 8u | ((v) & 0xFF000000u) >> 24u) -#define HtoNL(v) ZX_SWAP( v ) -#define NtoHL(v) ZX_SWAP( v ) -#else -#define HtoNL(x) (x) -#define NtoHL(x) (x) -#endif - -#define SET_NV(DST, TYPE, VAL) { \ - TYPE nvset_tmp=(VAL); \ - MEMCPY_NV((void*) PIC(DST), (void *) PIC(&nvset_tmp), sizeof(TYPE)); \ -} - -__Z_INLINE void strncpy_s(char *dst, const char *src, size_t dstSize) { - MEMZERO(dst, dstSize); - strncpy(dst, src, dstSize - 1); -} - -#define sizeof_field(type, member) sizeof(((type *)0)->member) -#define array_length(array) (sizeof(array) / sizeof((array)[0])) - -void zemu_trace(const char *file, uint32_t line); - -#define ZEMU_TRACE() zemu_trace( __func__, __LINE__ ); - -__attribute__((unused)) void check_app_canary(); - -void handle_stack_overflow(); - -void zemu_log_stack(const char *ctx); - -#if (defined (TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2)) -#if defined(ZEMU_LOGGING) -__Z_INLINE void zemu_log(const char *buf) -{ - asm volatile ( - "movs r0, #0x04\n" - "movs r1, %0\n" - "svc 0xab\n" - :: "r"(buf) : "r0", "r1" - ); -} -#else -__Z_INLINE void zemu_log(__Z_UNUSED const char *_) {} -#endif -#else -__Z_INLINE void zemu_log(__Z_UNUSED const char *msg) { - printf("%s\n", msg); -} -#endif - -#if APP_TESTING -#define ZEMU_LOGF(SIZE, ...) { char tmp[(SIZE)]; snprintf(tmp, (SIZE), __VA_ARGS__); zemu_log(tmp); } -#else -#define ZEMU_LOGF(SIZE, ...) {} -#endif - -#ifdef __cplusplus -} -#endif - -#pragma clang diagnostic pop diff --git a/deps/ledger-zxlib/include/zxmacros_ledger.h b/deps/ledger-zxlib/include/zxmacros_ledger.h deleted file mode 100644 index 7604b82..0000000 --- a/deps/ledger-zxlib/include/zxmacros_ledger.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#if defined (TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) - -#include "os.h" -#include "cx.h" - -#define MEMCPY_NV nvm_write - -// This macros are kept for backwards compatibility -// the most recent SDK has unified implementations and deprecated the original os_*** -#define MEMCPY memmove -#define MEMMOVE memmove -#define MEMSET memset -#define MEMCMP memcmp -#define MEMZERO explicit_bzero - -#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) -#include "ux.h" -#define NV_CONST const -#define NV_VOLATILE volatile -#define IS_UX_ALLOWED (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE) -#else -#include "ux.h" -#include "os_io_seproxyhal.h" -#define NV_CONST -#define NV_VOLATILE -#define IS_UX_ALLOWED (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE) -#endif - -#define CHECK_APP_CANARY() check_app_canary(); -#define APP_STACK_CANARY_MAGIC 0xDEAD0031 -extern unsigned int app_stack_canary; - -#define WAIT_EVENT() io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0) - -#define UX_WAIT() \ - while (!UX_DISPLAYED()) { WAIT_EVENT(); UX_DISPLAY_NEXT_ELEMENT(); } \ - WAIT_EVENT(); \ - io_seproxyhal_general_status(); \ - WAIT_EVENT() -#endif diff --git a/deps/ledger-zxlib/include/zxmacros_x64.h b/deps/ledger-zxlib/include/zxmacros_x64.h deleted file mode 100644 index 22d27dc..0000000 --- a/deps/ledger-zxlib/include/zxmacros_x64.h +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#if !defined (TARGET_NANOS) && !defined(TARGET_NANOX) && !defined(TARGET_NANOS2) - -// This macros are kept for backwards compatibility -// the most recent SDK has unified implementations and deprecated the original os_*** -#define MEMMOVE memmove -#define MEMSET memset -#define MEMCPY memcpy -#define MEMCMP memcmp -#define MEMCPY_NV memcpy - -#define PIC(x) (x) -#define CHECK_APP_CANARY() {} -#define CX_ECCINFO_PARITY_ODD 1u -#define CX_ECCINFO_xGTn 2u - -#ifndef __APPLE__ -#define MEMZERO explicit_bzero -#else -__Z_INLINE void __memzero(void *buffer, size_t s) { memset(buffer, 0, s); } -#define MEMZERO __memzero -#endif - -#endif diff --git a/deps/ledger-zxlib/include/zxtypes.h b/deps/ledger-zxlib/include/zxtypes.h deleted file mode 100644 index 9aae677..0000000 --- a/deps/ledger-zxlib/include/zxtypes.h +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - bool_false = 0, - bool_true = 1, -} bool_t; - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/include/zxutils_ledger.h b/deps/ledger-zxlib/include/zxutils_ledger.h deleted file mode 100644 index 7d3fc05..0000000 --- a/deps/ledger-zxlib/include/zxutils_ledger.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -unsigned short zx_compute_line_width_light(const char* text, unsigned char text_length); - - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/deps/ledger-zxlib/include/zxversion.h b/deps/ledger-zxlib/include/zxversion.h deleted file mode 100644 index d3db356..0000000 --- a/deps/ledger-zxlib/include/zxversion.h +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************* -* (c) 2018 - 2022 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#pragma once - -#define ZXLIB_MAJOR 12 -#define ZXLIB_MINOR 0 -#define ZXLIB_PATCH 1 diff --git a/deps/ledger-zxlib/scripts/install_deps.sh b/deps/ledger-zxlib/scripts/install_deps.sh deleted file mode 100755 index 46b3765..0000000 --- a/deps/ledger-zxlib/scripts/install_deps.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash -#******************************************************************************* -#* (c) 2018 Zondax GmbH -#* -#* Licensed under the Apache License, Version 2.0 (the "License"); -#* you may not use this file except in compliance with the License. -#* You may obtain a copy of the License at -#* -#* http://www.apache.org/licenses/LICENSE-2.0 -#* -#* Unless required by applicable law or agreed to in writing, software -#* distributed under the License is distributed on an "AS IS" BASIS, -#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -#* See the License for the specific language governing permissions and -#* limitations under the License. -#******************************************************************************** - -os_string="$(uname -s)" -case "${os_string}" in - Linux*) - sudo apt-get install libusb-1.0.0 libudev-dev - pip install -U setuptools - pip install -U --no-cache ledgerblue ecpy - pip install -U conan - ;; - Darwin*) - brew install libusb - pip install -U ledgerblue ecpy - pip install -U conan - ;; - *) - echo "OS not recognized" - ;; -esac diff --git a/deps/ledger-zxlib/scripts/template.sh b/deps/ledger-zxlib/scripts/template.sh deleted file mode 100755 index 8f0e720..0000000 --- a/deps/ledger-zxlib/scripts/template.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash -#******************************************************************************* -# (c) 2018 Zondax GmbH -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#******************************************************************************* - -if [ -z "$APPNAME" ] -then - echo "This script has not been configured correctly" - exit 1 -fi - -# check python 3 has been installed -if ! command -v python3 &>/dev/null; then - echo Python 3 is not installed - exit -fi - -python3 -m ledgerblue.loadApp -h &>/dev/null; -if [ $? -ne 0 ]; then - echo - echo "ERR: ledgerblue pip package not found." - echo "please install using 'pip install ledgerblue'" - echo - exit -fi - -TMP_HEX_DIR=$(mktemp -d -t ci-XXXXXXXXXX) -mkdir -p ${TMP_HEX_DIR}/bin -BIN_HEX_FILE=${TMP_HEX_DIR}/bin/app.hex -echo -e "${APPHEX}" > ${BIN_HEX_FILE} - -case "$1" in - 'load') - cd "$TMP_HEX_DIR" || exit - python3 -m ledgerblue.loadApp --appFlags 0x200 --delete ${LOAD_PARAMS} --path ${APPPATH} --path "44'/1'" - ;; - 'delete') - python3 -m ledgerblue.deleteApp ${DELETE_PARAMS} - ;; - 'version') - echo "v${APPVERSION}" - ;; - *) - echo "Zondax Installer [$APPNAME-$APPVERSION] [Warning: use only for test/demo apps]" - echo " load - Load $APPNAME app" - echo " delete - Delete $APPNAME app" - echo " version - Show $APPNAME app version" -esac diff --git a/deps/ledger-zxlib/src/app_mode.c b/deps/ledger-zxlib/src/app_mode.c deleted file mode 100644 index 9d80d02..0000000 --- a/deps/ledger-zxlib/src/app_mode.c +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* -* (c) 2020 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "app_mode.h" - -typedef struct { - uint8_t expert; -} app_mode_persistent_t; - -typedef struct { - uint8_t secret; -} app_mode_temporary_t; - -app_mode_temporary_t app_mode_temporary; - -#if defined(TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) -////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// -app_mode_persistent_t NV_CONST N_appmode_impl __attribute__ ((aligned(64))); -#define N_appmode (*(NV_VOLATILE app_mode_persistent_t *)PIC(&N_appmode_impl)) - -void app_mode_reset(){ - app_mode_temporary.secret = 0; -} - -bool app_mode_expert() { - return N_appmode.expert; -} - -void app_mode_set_expert(uint8_t val) { - app_mode_persistent_t mode; - mode.expert = val; - MEMCPY_NV( (void*) PIC(&N_appmode_impl), (void*) &mode, sizeof(app_mode_persistent_t)); -} - -#else -////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// - -app_mode_persistent_t app_mode; - -void app_mode_reset() { - app_mode.expert = 0; - app_mode_temporary.secret = 0; -} - -bool app_mode_expert() { - return app_mode.expert; -} - -void app_mode_set_expert(uint8_t val) { - app_mode.expert = val; -} - -////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// - -#endif - -bool app_mode_secret() { - return app_mode_temporary.secret; -} - -void app_mode_set_secret(uint8_t val) { - app_mode_temporary.secret = val; -} diff --git a/deps/ledger-zxlib/src/base58.c b/deps/ledger-zxlib/src/base58.c deleted file mode 100644 index e6fce41..0000000 --- a/deps/ledger-zxlib/src/base58.c +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* -* Adapted from Ledger App - Bitcoin Wallet -* (c) 2019 Zondax GmbH -* -* Ledger App - Bitcoin Wallet -* (c) 2016-2019 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "base58.h" -#include "zxmacros.h" - -#define MAX_DEC_INPUT_SIZE 164 -#define MAX_ENC_INPUT_SIZE 120 - -unsigned char const BASE58TABLE[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, - 0x10, 0xff, 0x11, 0x12, 0x13, 0x14, 0x15, 0xff, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0xff, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff}; - -unsigned char const BASE58ALPHABET[] = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; - -int decode_base58(const char *in, size_t length, - unsigned char *out, size_t *outlen) { - unsigned char tmp[MAX_DEC_INPUT_SIZE]; - unsigned char buffer[MAX_DEC_INPUT_SIZE] = {0}; - unsigned char i; - unsigned char j; - unsigned char startAt; - unsigned char zeroCount = 0; - if (length > MAX_DEC_INPUT_SIZE) { - return -1; - } - MEMMOVE(tmp, in, length); - for (i = 0; i < length; i++) { - if (in[i] >= sizeof(BASE58TABLE)) { - return -1; - } - tmp[i] = BASE58TABLE[(int) in[i]]; - if (tmp[i] == 0xff) { - return -1; - } - } - while ((zeroCount < length) && (tmp[zeroCount] == 0)) { - ++zeroCount; - } - j = length; - startAt = zeroCount; - while (startAt < length) { - unsigned short remainder = 0; - unsigned char divLoop; - for (divLoop = startAt; divLoop < length; divLoop++) { - unsigned short digit256 = (unsigned short) (tmp[divLoop] & 0xff); - unsigned short tmpDiv = remainder * 58 + digit256; - tmp[divLoop] = (unsigned char) (tmpDiv / 256); - remainder = (tmpDiv % 256); - } - if (tmp[startAt] == 0) { - ++startAt; - } - buffer[--j] = (unsigned char) remainder; - } - while ((j < length) && (buffer[j] == 0)) { - ++j; - } - length = length - (j - zeroCount); - if (*outlen < length) { - return -1; - } - - MEMMOVE(out, buffer + j - zeroCount, length); - *outlen = length; - return 0; -} - -int encode_base58(const unsigned char *in, size_t length, - unsigned char *out, size_t *outlen) { - unsigned char buffer[MAX_ENC_INPUT_SIZE * 138 / 100 + 1] = {0}; - size_t i, j; - size_t startAt, stopAt; - size_t zeroCount = 0; - size_t outputSize; - - if (length > MAX_ENC_INPUT_SIZE) { - return -1; - } - - while ((zeroCount < length) && (in[zeroCount] == 0)) { - ++zeroCount; - } - - outputSize = (length - zeroCount) * 138 / 100 + 1; - stopAt = outputSize - 1; - for (startAt = zeroCount; startAt < length; startAt++) { - int carry = in[startAt]; - for (j = outputSize - 1; (int) j >= 0; j--) { - carry += 256 * buffer[j]; - buffer[j] = carry % 58; - carry /= 58; - - if (j <= stopAt - 1 && carry == 0) { - break; - } - } - stopAt = j; - } - - j = 0; - while (j < outputSize && buffer[j] == 0) { - j += 1; - } - - if (*outlen < zeroCount + outputSize - j) { - *outlen = zeroCount + outputSize - j; - return -1; - } - - MEMSET(out, BASE58ALPHABET[0], zeroCount); - - i = zeroCount; - while (j < outputSize) { - out[i++] = BASE58ALPHABET[buffer[j++]]; - } - *outlen = i; - return 0; -} - -char encode_base58_clip(const unsigned char v) { - return BASE58ALPHABET[v % 58]; -} diff --git a/deps/ledger-zxlib/src/base64.c b/deps/ledger-zxlib/src/base64.c deleted file mode 100644 index ad601f8..0000000 --- a/deps/ledger-zxlib/src/base64.c +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* -* (c) 2020 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include -#include "base64.h" - -#define BASE64_PADDING_CHAR '=' - -const char base64_charset[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', -}; - -uint16_t base64_encode(char *out, uint16_t outlen, const uint8_t *in, uint16_t inlen) { - MEMZERO(out, outlen); - - // Check uppeer bound or bailout - uint16_t minspace = inlen / 6; - if (inlen % 6 != 0) minspace++; - minspace++; // zero termination - if (outlen < minspace) { - return 0; - } - - int8_t carry_count = 0; - uint8_t carry_value = 0; - uint16_t out_idx = 0; - - for (uint16_t i = 0; i < inlen; i++) { - const uint8_t c = in[i]; - - const uint8_t shift = (6 - carry_count); - const uint8_t idx = (carry_value << shift) | (c >> (carry_count + 2)); - carry_value = c & (0xFFu >> shift); - carry_count += 2; - - out[out_idx++] = base64_charset[idx]; - - // Check if we have another complete byte ready - if (carry_count == 6) { - out[out_idx++] = base64_charset[carry_value]; - carry_value = 0; - carry_count = 0; - } - } - - // If there is any left over add and pad - if (carry_count > 0) { - out[out_idx++] = base64_charset[carry_value << (6 - carry_count)]; - while (carry_count < 6) { - out[out_idx++] = BASE64_PADDING_CHAR; - carry_count += 2; - } - } - - return out_idx; -} diff --git a/deps/ledger-zxlib/src/bech32.c b/deps/ledger-zxlib/src/bech32.c deleted file mode 100644 index 21fc639..0000000 --- a/deps/ledger-zxlib/src/bech32.c +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* -* (c) 2019 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include -#include -#include -#include "bech32.h" -#include "segwit_addr.h" -#include "bittools.h" - -zxerr_t bech32EncodeFromBytes(char *out, - size_t out_len, - const char *hrp, - const uint8_t *in, - size_t in_len, - uint8_t pad) { - MEMZERO(out, out_len); - - if (in_len > MAX_INPUT_SIZE) { - return zxerr_out_of_bounds; - } - - size_t hrplen = strlen(hrp); - // We set a lower bound to ensure this is safe - if (out_len < hrplen + (in_len * 2) + 7) { - return zxerr_buffer_too_small; - } - - // Overestimate required size *2==(8/4) instead of *(8/5) - uint8_t tmp_data[MAX_INPUT_SIZE * 2]; - size_t tmp_size = 0; - MEMZERO(tmp_data, sizeof(tmp_data)); - - convert_bits(tmp_data, &tmp_size, 5, in, in_len, 8, pad); - if (tmp_size >= out_len) { - return zxerr_out_of_bounds; - } - - int err = bech32_encode(out, hrp, tmp_data, tmp_size); - if (err == 0) { - return zxerr_encoding_failed; - } - - return zxerr_ok; -} diff --git a/deps/ledger-zxlib/src/bignum.c b/deps/ledger-zxlib/src/bignum.c deleted file mode 100644 index 442ef70..0000000 --- a/deps/ledger-zxlib/src/bignum.c +++ /dev/null @@ -1,148 +0,0 @@ -/******************************************************************************* -* (c) 2019 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include "zxtypes.h" -#include "bignum.h" - -bool_t bignumLittleEndian_bcdprint(char *outBuffer, uint16_t outBufferLen, - const uint8_t *inBCD, uint16_t inBCDLen) { - static const char hexchars[] = "0123456789ABCDEF"; - uint8_t started = 0; - MEMZERO(outBuffer, outBufferLen); - - if (outBufferLen < 4) { - return bool_false; - } - - if (inBCDLen * 2 > outBufferLen) { - snprintf(outBuffer, outBufferLen, "ERR"); - return bool_false; - } - - for (uint8_t i = 0; i < inBCDLen; i++, inBCD++) { - if (started || *inBCD != 0) { - if (started || (*inBCD >> 4u) != 0) { - *outBuffer = hexchars[*inBCD >> 4u]; - outBuffer++; - } - *outBuffer = hexchars[*inBCD & 0x0Fu]; - outBuffer++; - started = 1; - } - } - - if (!started) { - snprintf(outBuffer, outBufferLen, "0"); - } - - return bool_true; -} - -void bignumLittleEndian_to_bcd(uint8_t *bcdOut, uint16_t bcdOutLen, - const uint8_t *binValue, uint16_t binValueLen) { - MEMZERO(bcdOut, bcdOutLen); - - uint8_t carry = 0; - for (uint16_t bitIdx = 0; bitIdx < binValueLen * 8; bitIdx++) { - // Fix bcd - for (uint16_t j = 0; j < bcdOutLen; j++) { - if ((bcdOut[j] & 0x0Fu) > 0x04u) { - bcdOut[j] += 0x03u; - } - if ((bcdOut[j] & 0xF0u) > 0x40u) { - bcdOut[j] += 0x30u; - } - } - - // get bit - const uint16_t byteIdx = bitIdx >> 3u; - const uint8_t mask = 0x80u >> (bitIdx & 0x7u); - carry = (uint8_t) ((binValue[binValueLen - byteIdx - 1] & mask) > 0); - - // Shift bcd - for (uint16_t j = 0; j < bcdOutLen; j++) { - uint8_t carry2 = (uint8_t) (bcdOut[bcdOutLen - j - 1] > 127u); - bcdOut[bcdOutLen - j - 1] <<= 1u; - bcdOut[bcdOutLen - j - 1] += carry; - carry = carry2; - } - } -} - -bool_t bignumBigEndian_bcdprint(char *outBuffer, uint16_t outBufferLen, - const uint8_t *bcdIn, uint16_t bcdInLen) { - static const char hexchars[] = "0123456789ABCDEF"; - uint8_t started = 0; - MEMZERO(outBuffer, outBufferLen); - - if (outBufferLen < 4) { - return bool_false; - } - - if (bcdInLen * 2 > outBufferLen) { - snprintf(outBuffer, outBufferLen, "ERR"); - return bool_false; - } - - for (uint16_t i = 0; i < bcdInLen; i++) { - uint8_t v = bcdIn[bcdInLen - i - 1]; - if (started || v != 0) { - if (started || (v >> 4u) != 0) { - *outBuffer = hexchars[v >> 4u]; - outBuffer++; - } - *outBuffer = hexchars[v & 0x0Fu]; - outBuffer++; - started = 1; - } - } - - if (!started) { - snprintf(outBuffer, outBufferLen, "0"); - } - - return bool_true; -} - -void bignumBigEndian_to_bcd(uint8_t *bcdOut, uint16_t bcdOutLen, - const uint8_t *binValue, uint16_t binValueLen) { - MEMZERO(bcdOut, bcdOutLen); - - uint8_t carry = 0; - for (uint16_t bitIdx = 0; bitIdx < binValueLen * 8; bitIdx++) { - // Fix bcd - for (uint16_t j = 0; j < bcdOutLen; j++) { - if ((bcdOut[j] & 0x0Fu) > 0x04u) { - bcdOut[j] += 0x03u; - } - if ((bcdOut[j] & 0xF0u) > 0x40u) { - bcdOut[j] += 0x30u; - } - } - - // get bit - const uint16_t byteIdx = bitIdx >> 3u; - const uint8_t mask = 0x80u >> (bitIdx & 0x7u); - carry = (uint8_t) ((binValue[byteIdx] & mask) > 0); - - // Shift bcd - for (uint16_t j = 0; j < bcdOutLen; j++) { - uint8_t carry2 = (uint8_t) (bcdOut[j] > 127u); - bcdOut[j] <<= 1u; - bcdOut[j] += carry; - carry = carry2; - } - } -} diff --git a/deps/ledger-zxlib/src/buffering.c b/deps/ledger-zxlib/src/buffering.c deleted file mode 100644 index e956782..0000000 --- a/deps/ledger-zxlib/src/buffering.c +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "buffering.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -buffer_state_t ram; // Ram -buffer_state_t flash; // Flash - -void buffering_init(uint8_t *ram_buffer, - uint16_t ram_buffer_size, - uint8_t *flash_buffer, - uint16_t flash_buffer_size) { - ram.data = ram_buffer; - ram.size = ram_buffer_size; - ram.pos = 0; - ram.in_use = 1; - - flash.data = flash_buffer; - flash.size = flash_buffer_size; - flash.pos = 0; - flash.in_use = 0; -} - -void buffering_reset() { - ram.pos = 0; - ram.in_use = 1; - flash.pos = 0; - flash.in_use = 0; -} - -int buffering_append(uint8_t *data, int length) { - if (ram.in_use) { - if (ram.size - ram.pos >= length) { - // RAM in use, append to ram if there is enough space - MEMCPY(ram.data + ram.pos, data, (size_t) length); - ram.pos += length; - } else { - // If RAM is not big enough copy memory to flash - ram.in_use = 0; - flash.in_use = 1; - if (ram.pos > 0) { - buffering_append(ram.data, ram.pos); - } - int num_bytes = buffering_append(data, length); - ram.pos = 0; - return num_bytes; - } - } else { - // Flash in use, append to flash - if (flash.size - flash.pos >= length) { - MEMCPY_NV(flash.data + flash.pos, data, (size_t) length); - flash.pos += length; - } else { - return 0; - } - } - return length; -} - -buffer_state_t *buffering_get_ram_buffer() { - return &ram; -} - -buffer_state_t *buffering_get_flash_buffer() { - return &flash; -} - -buffer_state_t *buffering_get_buffer() { - if (ram.in_use) { - return &ram; - } - return &flash; -} - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/src/hexutils.c b/deps/ledger-zxlib/src/hexutils.c deleted file mode 100644 index 66b8089..0000000 --- a/deps/ledger-zxlib/src/hexutils.c +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include -#include -#include "hexutils.h" - -uint8_t hex2dec(char c, char *out) { - c = (char) tolower((int) c); - - if (!isxdigit((int) c)) { - return 1; - } - - if (isdigit((int) c)) { - *out = (char) (c - '0'); - return 0; - } - - *out = (char) (c - 'a' + 10); - return 0; -} - -size_t parseHexString(uint8_t *out, uint16_t outLen, const char *input) { - size_t len = strnlen(input, outLen * 2u + 1u); - if ( (len / 2) > outLen) { - return 0; - } - if (len % 2 == 1) { - return 0; - } - - for (size_t i = 0; i < len; i += 2) { - char tmp1, tmp2; - if (hex2dec(input[i], &tmp1)) - return 0; - if (hex2dec(input[i + 1], &tmp2)) - return 0; - - out[i >> 1u] = (tmp1 << 4u) + tmp2; - } - - return (len / 2); -} diff --git a/deps/ledger-zxlib/src/segwit_addr.c b/deps/ledger-zxlib/src/segwit_addr.c deleted file mode 100644 index 23ee214..0000000 --- a/deps/ledger-zxlib/src/segwit_addr.c +++ /dev/null @@ -1,191 +0,0 @@ -/* Copyright (c) 2017 Pieter Wuille - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include -#include -#include - -#include "segwit_addr.h" - -uint32_t bech32_polymod_step(uint32_t pre) { - uint8_t b = pre >> 25u; - return ((pre & 0x1FFFFFFu) << 5u) ^ - (-((b >> 0u) & 1u) & 0x3b6a57b2UL) ^ - (-((b >> 1u) & 1u) & 0x26508e6dUL) ^ - (-((b >> 2u) & 1u) & 0x1ea119faUL) ^ - (-((b >> 3u) & 1u) & 0x3d4233ddUL) ^ - (-((b >> 4u) & 1u) & 0x2a1462b3UL); -} - -static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; - -static const int8_t charset_rev[128] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, - -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, - 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, - -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, - 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1 -}; - -int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len) { - uint32_t chk = 1; - size_t i = 0; - while (hrp[i] != 0) { - char ch = hrp[i]; - if (ch < 33 || ch > 126) { - return 0; - } - - if (ch >= 'A' && ch <= 'Z') return 0; - chk = bech32_polymod_step(chk) ^ (ch >> 5u); - ++i; - } - if (i + 7 + data_len > 90) return 0; - chk = bech32_polymod_step(chk); - while (*hrp != 0) { - chk = bech32_polymod_step(chk) ^ (*hrp & 0x1fu); - *(output++) = *(hrp++); - } - *(output++) = '1'; - for (i = 0; i < data_len; ++i) { - if (*data >> 5u) return 0; - chk = bech32_polymod_step(chk) ^ (*data); - *(output++) = charset[*(data++)]; - } - for (i = 0; i < 6; ++i) { - chk = bech32_polymod_step(chk); - } - chk ^= 1; - for (i = 0; i < 6; ++i) { - *(output++) = charset[(chk >> ((5u - i) * 5u)) & 0x1fu]; - } - *output = 0; - return 1; -} - -int bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) { - uint32_t chk = 1; - size_t i; - size_t input_len = strlen(input); - size_t hrp_len; - int have_lower = 0, have_upper = 0; - if (input_len < 8 || input_len > 90) { - return 0; - } - *data_len = 0; - while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') { - ++(*data_len); - } - hrp_len = input_len - (1 + *data_len); - if (1 + *data_len >= input_len || *data_len < 6) { - return 0; - } - *(data_len) -= 6; - for (i = 0; i < hrp_len; ++i) { - char ch = input[i]; - if (ch < 33 || ch > 126) { - return 0; - } - if (ch >= 'a' && ch <= 'z') { - have_lower = 1; - } else if (ch >= 'A' && ch <= 'Z') { - have_upper = 1; - ch = (ch - 'A') + 'a'; - } - hrp[i] = ch; - chk = bech32_polymod_step(chk) ^ (ch >> 5u); - } - hrp[i] = 0; - chk = bech32_polymod_step(chk); - for (i = 0; i < hrp_len; ++i) { - chk = bech32_polymod_step(chk) ^ (input[i] & 0x1fu); - } - ++i; - while (i < input_len) { - int v = (input[i] & 0x80u) ? -1 : charset_rev[(int)input[i]]; - if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1; - if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1; - if (v == -1) { - return 0; - } - chk = bech32_polymod_step(chk) ^ v; - if (i + 6 < input_len) { - data[i - (1 + hrp_len)] = v; - } - ++i; - } - if (have_lower && have_upper) { - return 0; - } - return chk == 1; -} - -int convert_bits(uint8_t* out, size_t* outlen, int outBits, const uint8_t* in, size_t inLen, int inBits, int pad) { - uint32_t val = 0; - int bits = 0; - uint32_t maxv = (((uint32_t)1u) << outBits) - 1u; - while (inLen--) { - val = (val << inBits) | *(in++); - bits += inBits; - while (bits >= outBits) { - bits -= outBits; - out[(*outlen)++] = (val >> bits) & maxv; - } - } - if (pad) { - if (bits) { - out[(*outlen)++] = (val << (outBits - bits)) & maxv; - } - } else if (((val << (outBits - bits)) & maxv) || bits >= inBits) { - return 0; - } - return 1; -} - -int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) { - uint8_t data[65]; - size_t datalen = 0; - if (witver > 16) return 0; - if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0; - if (witprog_len < 2 || witprog_len > 40) return 0; - data[0] = witver; - convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1); - ++datalen; - return bech32_encode(output, hrp, data, datalen); -} - -int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) { - uint8_t data[84]; - char hrp_actual[84]; - size_t data_len; - if (!bech32_decode(hrp_actual, data, &data_len, addr)) return 0; - if (data_len == 0 || data_len > 65) return 0; - if (strncmp(hrp, hrp_actual, 84) != 0) return 0; - if (data[0] > 16) return 0; - *witdata_len = 0; - if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0; - if (*witdata_len < 2 || *witdata_len > 40) return 0; - if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0; - *witver = data[0]; - return 1; -} diff --git a/deps/ledger-zxlib/src/sigutils.c b/deps/ledger-zxlib/src/sigutils.c deleted file mode 100644 index 107088f..0000000 --- a/deps/ledger-zxlib/src/sigutils.c +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************* -* (c) 2020 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include -#include - -#define MINPAYLOADLEN 1 -#define PAYLOADLEN 32 -#define MAXPAYLOADLEN 33 - -err_convert_e convertDERtoRSV(const uint8_t *inSignatureDER, - unsigned int inInfo, - uint8_t *outR, - uint8_t *outS, - uint8_t *outV) { - - // https://github.com/libbitcoin/libbitcoin-system/wiki/ECDSA-and-DER-Signatures#serialised-der-signature-sequence - // 0 [1 byte] - DER Prefix - // 1 [1 byte] - Payload len - // 2 [1 byte] - R Marker. Always 02 - // 3 [1 byte] - R Len RLEN - // ROFFSET ... [.?. byte] - R ROFFSET - // ROFFSET+RLEN [1 byte] - S Marker. Always 02 - // ROFFSET+RLEN+1 [1 byte] - S Length SLEN - // ROFFSET+RLEN+2 [.?. byte] - S SOFFSET - // Prepare response - // R [32] - // S [32] - // V [1] - - MEMZERO(outR, 32); - MEMZERO(outS, 32); - MEMZERO(outV, 1); - - const uint8_t derPrefix = *(inSignatureDER); - if (derPrefix != 0x30) { - return invalid_derPrefix; - } - - const uint8_t payloadLen = *(inSignatureDER + 1); - const uint8_t minPayloadLen = 2 + MINPAYLOADLEN + 2 + MINPAYLOADLEN; - const uint8_t maxPayloadLen = 2 + MAXPAYLOADLEN + 2 + MAXPAYLOADLEN; - if (payloadLen < minPayloadLen || payloadLen > maxPayloadLen) { - return invalid_payloadLen; - } - - const uint8_t rMarker = *(inSignatureDER + 2); - if (rMarker != 0x02) { - return invalid_rmaker; - } - - uint8_t rLen = *(inSignatureDER + 3); - if (rLen > MAXPAYLOADLEN || rLen < MINPAYLOADLEN) { - return invalid_rLen; - } - - const uint8_t sMarker = *(inSignatureDER + 4 + rLen); - if (sMarker != 0x02) { - return invalid_smarker; - } - - uint8_t sLen = *(inSignatureDER + 4 + rLen + 1); - if (sLen > MAXPAYLOADLEN || sLen < MINPAYLOADLEN) { - return invalid_sLen; - } - - // Get data fields - const uint8_t *rPtr = inSignatureDER + 4; - const uint8_t *sPtr = inSignatureDER + 4 + rLen + 2; - - // Correct field pointers - if (rLen < PAYLOADLEN) { - outR += PAYLOADLEN - rLen; - } - if (rLen > PAYLOADLEN) { - rPtr += rLen - PAYLOADLEN; // move forward get only 32 bytes - rLen = PAYLOADLEN; - } - - if (sLen < PAYLOADLEN) { - outS += PAYLOADLEN - sLen; - } - if (sLen > PAYLOADLEN) { - sPtr += sLen - PAYLOADLEN; // move forward get only 32 bytes - sLen = PAYLOADLEN; - } - - // Prepare V - *outV = 0; - if (inInfo & CX_ECCINFO_PARITY_ODD) { - *outV += 1; - } - if (inInfo & CX_ECCINFO_xGTn) { - *outV += 2; - } - - // Copy things - MEMCPY(outR, rPtr, rLen); - MEMCPY(outS, sPtr, sLen); - - return no_error; -} diff --git a/deps/ledger-zxlib/src/timeutils.c b/deps/ledger-zxlib/src/timeutils.c deleted file mode 100644 index 0efa919..0000000 --- a/deps/ledger-zxlib/src/timeutils.c +++ /dev/null @@ -1,508 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include "zxmacros.h" -#include "timeutils.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -const uint8_t monthDays[] = { - 31, - 28, - 31, - 30, - 31, - 30, - 31, - 31, - 30, - 31, - 30, - 31 -}; - -const uint32_t yearLookup[] = { - 0, - 365, - 730, - 1096, - 1461, - 1826, - 2191, - 2557, - 2922, - 3287, - 3652, - 4018, - 4383, - 4748, - 5113, - 5479, - 5844, - 6209, - 6574, - 6940, - 7305, - 7670, - 8035, - 8401, - 8766, - 9131, - 9496, - 9862, - 10227, - 10592, - 10957, - 11323, - 11688, - 12053, - 12418, - 12784, - 13149, - 13514, - 13879, - 14245, - 14610, - 14975, - 15340, - 15706, - 16071, - 16436, - 16801, - 17167, - 17532, - 17897, - 18262, - 18628, - 18993, - 19358, - 19723, - 20089, - 20454, - 20819, - 21184, - 21550, - 21915, - 22280, - 22645, - 23011, - 23376, - 23741, - 24106, - 24472, - 24837, - 25202, - 25567, - 25933, - 26298, - 26663, - 27028, - 27394, - 27759, - 28124, - 28489, - 28855, - 29220, - 29585, - 29950, - 30316, - 30681, - 31046, - 31411, - 31777, - 32142, - 32507, - 32872, - 33238, - 33603, - 33968, - 34333, - 34699, - 35064, - 35429, - 35794, - 36160, - 36525, - 36890, - 37255, - 37621, - 37986, - 38351, - 38716, - 39082, - 39447, - 39812, - 40177, - 40543, - 40908, - 41273, - 41638, - 42004, - 42369, - 42734, - 43099, - 43465, - 43830, - 44195, - 44560, - 44926, - 45291, - 45656, - 46021, - 46387, - 46752, - 47117, - 47482, - 47847, - 48212, - 48577, - 48942, - 49308, - 49673, - 50038, - 50403, - 50769, - 51134, - 51499, - 51864, - 52230, - 52595, - 52960, - 53325, - 53691, - 54056, - 54421, - 54786, - 55152, - 55517, - 55882, - 56247, - 56613, - 56978, - 57343, - 57708, - 58074, - 58439, - 58804, - 59169, - 59535, - 59900, - 60265, - 60630, - 60996, - 61361, - 61726, - 62091, - 62457, - 62822, - 63187, - 63552, - 63918, - 64283, - 64648, - 65013, - 65379, - 65744, - 66109, - 66474, - 66840, - 67205, - 67570, - 67935, - 68301, - 68666, - 69031, - 69396, - 69762, - 70127, - 70492, - 70857, - 71223, - 71588, - 71953, - 72318, - 72684, - 73049, - 73414, - 73779, - 74145, - 74510, - 74875, - 75240, - 75606, - 75971, - 76336, - 76701, - 77067, - 77432, - 77797, - 78162, - 78528, - 78893, - 79258, - 79623, - 79989, - 80354, - 80719, - 81084, - 81450, - 81815, - 82180, - 82545, - 82911, - 83276, - 83641, - 84006, - 84371, - 84736, - 85101, - 85466, - 85832, - 86197, - 86562, - 86927, - 87293, - 87658, - 88023, - 88388, - 88754, - 89119, - 89484, - 89849, - 90215, - 90580, - 90945, - 91310, - 91676, - 92041, - 92406, - 92771, - 93137, - 93502, - 93867, - 94232, - 94598, - 94963, - 95328, - 95693, - 96059, - 96424, - 96789, - 97154, - 97520, - 97885, - 98250, - 98615, - 98981, - 99346, - 99711, - 100076, - 100442, - 100807, - 101172, - 101537, - 101903, - 102268, - 102633, - 102998, - 103364, - 103729, - 104094, - 104459, - 104825, - 105190, - 105555, - 105920, - 106286, - 106651, - 107016, - 107381, - 107747, - 108112, - 108477, - 108842, - 109208, - 109573, - 109938, - 110303, - 110669, - 111034, - 111399, - 111764, - 112130, - 112495, - 112860, - 113225, - 113591, - 113956, - 114321, - 114686, - 115052, - 115417, - 115782, - 116147, - 116513, - 116878, - 117243, - 117608, - 117974, - 118339, - 118704, - 119069, - 119435, - 119800, - 120165, - 120530, - 120895, - 121260, - 121625, - 121990, - 122356, - 122721, - 123086, - 123451, - 123817, - 124182, - 124547, - 124912, - 125278, - 125643, - 126008, - 126373, - 126739, - 127104, - 127469, - 127834, - 128200, - 128565, - 128930, - 129295, - 129661, - 130026, - 130391, - 130756, - 131122, - 131487, - 131852, - 132217, - 132583, - 132948, - 133313, - 133678, - 134044, - 134409, - 134774, - 135139, - 135505, - 135870, - 136235, - 136600, - 136966, - 137331, - 137696, - 138061, - 138427, - 138792, - 139157, - 139522, - 139888, - 140253, - 140618, - 140983, - 141349, - 141714, - 142079, - 142444, - 142810, - 143175, - 143540, - 143905, - 144271, - 144636, - 145001, - 145366, - 145732, -}; - -// ARM does not implement gmtime. This is a simple alternative implementation -// based on section 4.16 -// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html -zxerr_t printTime(char *out, uint16_t outLen, uint64_t t) { - uint8_t tm_sec; - uint8_t tm_min; - uint8_t tm_hour; - uint16_t tm_day; - uint8_t tm_mon; - uint16_t tm_year; - - tm_sec = (uint8_t) (t % 60); - t -= tm_sec; - t /= 60; - - tm_min = (uint8_t) (t % 60); - t -= tm_min; - t /= 60; - - tm_hour = (uint8_t) (t % 24); - t -= tm_hour; - t /= 24; - - // Look up tm_year - tm_year = 0; - const uint16_t yearLookupSize = sizeof(yearLookup)/sizeof(yearLookup[0]); - while (tm_year < yearLookupSize && yearLookup[tm_year] <= t) tm_year++; - - if (tm_year == 0 || tm_year == yearLookupSize) { - return zxerr_out_of_bounds; - } - tm_year--; - - tm_day = (uint16_t) (t - yearLookup[tm_year] + 1); - tm_year = (uint16_t) (1970 + tm_year); - - // Get day/month - uint8_t leap = (uint8_t) (tm_year % 4 == 0 && (tm_year % 100 != 0 || tm_year % 400 == 0) ? 1 : 0); - - for (tm_mon = 0; tm_mon < 12; tm_mon++) { - uint8_t tmp = monthDays[tm_mon]; - tmp += (tm_mon == 1 ? leap : 0); - if (tm_day <= tmp) { - break; - } - tm_day -= tmp; - } - tm_mon++; - - const char *monthName = getMonth(tm_mon); - - // YYYYmmdd HH:MM:SS - snprintf(out, outLen, "%02d%s%04d %02d:%02d:%02dUTC", - tm_day, - monthName, - tm_year, - tm_hour, tm_min, tm_sec - ); - - return zxerr_ok; -} - -#ifdef __cplusplus -} -#endif diff --git a/deps/ledger-zxlib/src/zxformat.c b/deps/ledger-zxlib/src/zxformat.c deleted file mode 100644 index ee6d5ce..0000000 --- a/deps/ledger-zxlib/src/zxformat.c +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* -* (c) 2020 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include "zxformat.h" -#include -#include -#include "utf8.h" - -size_t asciify(char *utf8_in_ascii_out) { - return asciify_ext(utf8_in_ascii_out, utf8_in_ascii_out); -} - -size_t asciify_ext(const char *utf8_in, char *ascii_only_out) { - void *p = (void *) utf8_in; - char *q = ascii_only_out; - - // utf8valid returns zero on success - while (*((char *) p) && utf8valid(p) == 0) { - utf8_int32_t tmp_codepoint = 0; - p = utf8codepoint(p, &tmp_codepoint); - *q = (char) ((tmp_codepoint >= 32 && tmp_codepoint <= (int32_t) 0x7F) ? tmp_codepoint : '.'); - q++; - } - - // Terminate string - *q = 0; - return q - ascii_only_out; -} - -uint8_t intstr_to_fpstr_inplace(char *number, size_t number_max_size, uint8_t decimalPlaces) { - uint16_t numChars = strnlen(number, number_max_size); - MEMZERO(number + numChars, number_max_size - numChars); - - if (number_max_size < 1) { - // No space to do anything - return 0; - } - - if (number_max_size <= numChars) { - // No space to do anything - return 0; - } - - if (numChars == 0) { - // Empty number, make a zero - snprintf(number, number_max_size, "0"); - numChars = 1; - } - - // Check all are numbers - uint16_t firstDigit = numChars; - for (int i = 0; i < numChars; i++) { - if (number[i] < '0' || number[i] > '9') { - snprintf(number, number_max_size, "ERR"); - return 0; - } - if (number[i] != '0' && firstDigit > i) { - firstDigit = i; - } - } - - // Trim any incorrect leading zeros - if (firstDigit == numChars) { - snprintf(number, number_max_size, "0"); - numChars = 1; - } else { - // Trim leading zeros - MEMMOVE(number, number + firstDigit, numChars - firstDigit); - MEMZERO(number + numChars - firstDigit, firstDigit); - } - - // If there are no decimal places return - if (decimalPlaces == 0) { - return numChars; - } - - // Now insert decimal point - -// 0123456789012 <-decimal places -// abcd < numChars = 4 -// abcd < shift -// 000000000abcd < fill -// 0.00000000abcd < add decimal point - - if (numChars < decimalPlaces + 1) { - // Move to end - const uint16_t padSize = decimalPlaces - numChars + 1; - MEMMOVE(number + padSize, number, numChars); - MEMSET(number, '0', padSize); - numChars = strlen(number); - } - - // add decimal point - const uint16_t pointPosition = numChars - decimalPlaces; - MEMMOVE(number + pointPosition + 1, number + pointPosition, decimalPlaces); // shift content - number[pointPosition] = '.'; - - numChars = strlen(number); - return numChars; -} - -size_t z_strlen(const char *buffer, size_t maxSize) { - if (buffer == NULL) return 0; - const size_t tmp = strlen(buffer); - return tmp < maxSize ? tmp : maxSize; -} - -zxerr_t z_str3join(char *buffer, size_t bufferSize, const char *prefix, const char *suffix) { - size_t messageSize = z_strlen(buffer, bufferSize); - const size_t prefixSize = z_strlen(prefix, bufferSize); - const size_t suffixSize = z_strlen(suffix, bufferSize); - - size_t requiredSize = 1 /* termination */ + messageSize + prefixSize + suffixSize; - - if (bufferSize < requiredSize) { - snprintf(buffer, bufferSize, "ERR???"); - return zxerr_buffer_too_small; - } - - if (suffixSize > 0) { - memmove(buffer + messageSize, suffix, suffixSize); - buffer[messageSize + suffixSize] = 0; - } - - // shift and add prefix - if (prefixSize > 0) { - memmove(buffer + prefixSize, buffer, messageSize + suffixSize + 1); - memmove(buffer, prefix, prefixSize); - } - - return zxerr_ok; -} diff --git a/deps/ledger-zxlib/src/zxmacros.c b/deps/ledger-zxlib/src/zxmacros.c deleted file mode 100644 index 5dd172b..0000000 --- a/deps/ledger-zxlib/src/zxmacros.c +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include "zxmacros.h" - -#pragma clang diagnostic push -#pragma ide diagnostic ignored "EndlessLoop" - -void handle_stack_overflow() { - zemu_log("!!!!!!!!!!!!!!!!!!!!!! CANARY TRIGGERED!!! STACK OVERFLOW DETECTED\n"); -#if defined (TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) - io_seproxyhal_se_reset(); -#else - while (1); -#endif -} - -#pragma clang diagnostic pop - -__Z_UNUSED void check_app_canary() { -#if defined (TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) - if (app_stack_canary != APP_STACK_CANARY_MAGIC) handle_stack_overflow(); -#endif -} - -#if defined(ZEMU_LOGGING) && (defined (TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2)) -void zemu_log_stack(const char *ctx) { - #define STACK_SHIFT 20 - void* p = NULL; - char buf[70]; - snprintf(buf, sizeof(buf), "|SP| %p %p (%d) : %s\n", - &app_stack_canary, - ((void*)&p)+STACK_SHIFT, - (uint32_t)((void*)&p)+STACK_SHIFT - (uint32_t)&app_stack_canary, - ctx); - zemu_log(buf); - (void) ctx; -} -#else - -void zemu_log_stack(__Z_UNUSED const char *ctx) {} - -#endif - - -#if defined(ZEMU_LOGGING) && (defined (TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2)) -void zemu_trace(const char *file, uint32_t line) { - char buf[200]; - snprintf(buf, sizeof(buf), "|TRACE| %s:%d\n", file, line); - zemu_log(buf); -} -#else - -void zemu_trace(__Z_UNUSED const char *file, __Z_UNUSED uint32_t line) {} - -#endif diff --git a/deps/ledger-zxlib/src/zxutils_ledger.c b/deps/ledger-zxlib/src/zxutils_ledger.c deleted file mode 100644 index 4800665..0000000 --- a/deps/ledger-zxlib/src/zxutils_ledger.c +++ /dev/null @@ -1,154 +0,0 @@ -//#******************************************************************************* -//#* (c) 2021 Zondax GmbH -//#* (c) 2020 Ledger SAS -//#* -//#* Licensed under the Apache License, Version 2.0 (the "License"); -//#* you may not use this file except in compliance with the License. -//#* You may obtain a copy of the License at -//#* -//#* http://www.apache.org/licenses/LICENSE-2.0 -//#* -//#* Unless required by applicable law or agreed to in writing, software -//#* distributed under the License is distributed on an "AS IS" BASIS, -//#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//#* See the License for the specific language governing permissions and -//#* limitations under the License. -//#******************************************************************************** -#include "zxutils_ledger.h" - -#ifndef NULL -#define NULL ((void *)0) -#endif - -// We implement a light mechanism in order to be able to retrieve the width of -// nano S characters, in the two possible fonts: -// - BAGL_FONT_OPEN_SANS_EXTRABOLD_11px, -// - BAGL_FONT_OPEN_SANS_REGULAR_11px. -#define NANOS_FIRST_CHAR 0x20 -#define NANOS_LAST_CHAR 0x7F - -// OPEN_SANS_REGULAR_11PX << 4 | OPEN_SANS_EXTRABOLD_11PX -const char nanos_characters_width[96] = { - 3 << 4 | 3, /* code 0020 */ - 3 << 4 | 3, /* code 0021 */ - 4 << 4 | 6, /* code 0022 */ - 7 << 4 | 7, /* code 0023 */ - 6 << 4 | 6, /* code 0024 */ - 9 << 4 | 10, /* code 0025 */ - 8 << 4 | 9, /* code 0026 */ - 2 << 4 | 3, /* code 0027 */ - 3 << 4 | 4, /* code 0028 */ - 3 << 4 | 4, /* code 0029 */ - 6 << 4 | 6, /* code 002A */ - 6 << 4 | 6, /* code 002B */ - 3 << 4 | 3, /* code 002C */ - 4 << 4 | 4, /* code 002D */ - 3 << 4 | 3, /* code 002E */ - 4 << 4 | 5, /* code 002F */ - 6 << 4 | 8, /* code 0030 */ - 6 << 4 | 6, /* code 0031 */ - 6 << 4 | 7, /* code 0032 */ - 6 << 4 | 7, /* code 0033 */ - 8 << 4 | 8, /* code 0034 */ - 6 << 4 | 6, /* code 0035 */ - 6 << 4 | 8, /* code 0036 */ - 6 << 4 | 7, /* code 0037 */ - 6 << 4 | 8, /* code 0038 */ - 6 << 4 | 8, /* code 0039 */ - 3 << 4 | 3, /* code 003A */ - 3 << 4 | 3, /* code 003B */ - 6 << 4 | 5, /* code 003C */ - 6 << 4 | 6, /* code 003D */ - 6 << 4 | 5, /* code 003E */ - 5 << 4 | 6, /* code 003F */ - 10 << 4 | 10, /* code 0040 */ - 7 << 4 | 8, /* code 0041 */ - 7 << 4 | 7, /* code 0042 */ - 7 << 4 | 7, /* code 0043 */ - 8 << 4 | 8, /* code 0044 */ - 6 << 4 | 6, /* code 0045 */ - 6 << 4 | 6, /* code 0046 */ - 8 << 4 | 8, /* code 0047 */ - 8 << 4 | 8, /* code 0048 */ - 3 << 4 | 4, /* code 0049 */ - 4 << 4 | 5, /* code 004A */ - 7 << 4 | 8, /* code 004B */ - 6 << 4 | 6, /* code 004C */ - 10 << 4 | 11, /* code 004D */ - 8 << 4 | 9, /* code 004E */ - 9 << 4 | 9, /* code 004F */ - 7 << 4 | 7, /* code 0050 */ - 9 << 4 | 9, /* code 0051 */ - 7 << 4 | 8, /* code 0052 */ - 6 << 4 | 6, /* code 0053 */ - 7 << 4 | 6, /* code 0054 */ - 8 << 4 | 8, /* code 0055 */ - 7 << 4 | 6, /* code 0056 */ - 10 << 4 | 11, /* code 0057 */ - 6 << 4 | 8, /* code 0058 */ - 6 << 4 | 7, /* code 0059 */ - 6 << 4 | 7, /* code 005A */ - 4 << 4 | 5, /* code 005B */ - 4 << 4 | 5, /* code 005C */ - 4 << 4 | 5, /* code 005D */ - 6 << 4 | 7, /* code 005E */ - 5 << 4 | 6, /* code 005F */ - 6 << 4 | 7, /* code 0060 */ - 6 << 4 | 7, /* code 0061 */ - 7 << 4 | 7, /* code 0062 */ - 5 << 4 | 6, /* code 0063 */ - 7 << 4 | 7, /* code 0064 */ - 6 << 4 | 7, /* code 0065 */ - 5 << 4 | 6, /* code 0066 */ - 6 << 4 | 7, /* code 0067 */ - 7 << 4 | 7, /* code 0068 */ - 3 << 4 | 4, /* code 0069 */ - 4 << 4 | 5, /* code 006A */ - 6 << 4 | 7, /* code 006B */ - 3 << 4 | 4, /* code 006C */ - 10 << 4 | 10, /* code 006D */ - 7 << 4 | 7, /* code 006E */ - 7 << 4 | 7, /* code 006F */ - 7 << 4 | 7, /* code 0070 */ - 7 << 4 | 7, /* code 0071 */ - 4 << 4 | 5, /* code 0072 */ - 5 << 4 | 6, /* code 0073 */ - 4 << 4 | 5, /* code 0074 */ - 7 << 4 | 7, /* code 0075 */ - 6 << 4 | 7, /* code 0076 */ - 9 << 4 | 10, /* code 0077 */ - 6 << 4 | 7, /* code 0078 */ - 6 << 4 | 7, /* code 0079 */ - 5 << 4 | 6, /* code 007A */ - 4 << 4 | 5, /* code 007B */ - 6 << 4 | 6, /* code 007C */ - 4 << 4 | 5, /* code 007D */ - 6 << 4 | 6, /* code 007E */ - 7 << 4 | 6, /* code 007F */ -}; - -unsigned short zx_compute_line_width_light(const char* text, unsigned char text_length) { - char current_char; - unsigned short line_width = 0; - - if(text == NULL) { - return 0xFFFF; - } - - // We parse the characters of the input text on all the input length. - while (text_length--) { - current_char = *text; - - if (current_char < NANOS_FIRST_CHAR || current_char > NANOS_LAST_CHAR) { - if (current_char == '\n' || current_char == '\r') { - break; - } - } - else { - // Regular. - line_width += (nanos_characters_width[current_char - NANOS_FIRST_CHAR] >> 0x04) & 0x0F; - } - text++; - } - return line_width; -} diff --git a/deps/ledger-zxlib/templates/Makefile.root b/deps/ledger-zxlib/templates/Makefile.root deleted file mode 100644 index 566f607..0000000 --- a/deps/ledger-zxlib/templates/Makefile.root +++ /dev/null @@ -1,29 +0,0 @@ -#******************************************************************************* -#* (c) 2019 Zondax GmbH -#* -#* Licensed under the Apache License, Version 2.0 (the "License"); -#* you may not use this file except in compliance with the License. -#* You may obtain a copy of the License at -#* -#* http://www.apache.org/licenses/LICENSE-2.0 -#* -#* Unless required by applicable law or agreed to in writing, software -#* distributed under the License is distributed on an "AS IS" BASIS, -#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -#* See the License for the specific language governing permissions and -#* limitations under the License. -#******************************************************************************** - -# We use BOLOS_SDK to determine the development environment that is being used -# BOLOS_SDK IS DEFINED We use the plain Makefile for Ledger -# BOLOS_SDK NOT DEFINED We use a containerized build approach - -ifeq ($(BOLOS_SDK),) -include $(CURDIR)/deps/ledger-zxlib/cmake/dockerized_build.mk -else -default: - $(MAKE) -C app -%: - $(info "Calling app Makefile for target $@") - COIN=$(COIN) $(MAKE) -C app $@ -endif diff --git a/deps/ledger-zxlib/tests/asciify.cpp b/deps/ledger-zxlib/tests/asciify.cpp deleted file mode 100644 index f54e0a0..0000000 --- a/deps/ledger-zxlib/tests/asciify.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include -#include -#include - -namespace { - TEST(ASCIIFY, pure) { - char input[] = "This is only ascii"; - char have[50]; - - asciify_ext(input, have); - - EXPECT_STREQ(input, have); - } - - TEST(ASCIIFY, ascii_below_32) { - char input[] = "\05test"; - char want[] = ".test"; - char have[50]; - - EXPECT_EQ(5, strlen(input)); - - size_t ascii_len = asciify_ext(input, have); - std::cout << have << std::endl; - - EXPECT_EQ(strlen(want), ascii_len); - EXPECT_STREQ(want, have); - } - - TEST(ASCIIFY, extended) { - char input[] = "cumpleaños"; - char want[] = "cumplea.os"; - char have[50]; - - EXPECT_EQ(11, strlen(input)); - - size_t ascii_len = asciify_ext(input, have); - std::cout << have << std::endl; - - EXPECT_EQ(strlen(want), ascii_len); - EXPECT_STREQ(want, have); - } - - TEST(ASCIIFY, utf8) { - char input[] = "哈Something哈"; - char want[] = ".Something."; - char have[50]; - - EXPECT_EQ(15, strlen(input)); - - size_t ascii_len = asciify_ext(input, have); - std::cout << have << std::endl; - - EXPECT_EQ(strlen(want), ascii_len); - EXPECT_STREQ(want, have); - } - - TEST(ASCIIFY, inplace_pure) { - char data[] = "This is only ascii"; - char want[] = "This is only ascii"; - - asciify(data); - EXPECT_STREQ(want, data); - } - - TEST(ASCIIFY, inplace_ascii_below_32) { - char data[] = "\05test"; - char want[] = ".test"; - - EXPECT_EQ(5, strlen(data)); - - size_t ascii_len = asciify(data); - std::cout << data << std::endl; - - EXPECT_EQ(strlen(want), ascii_len); - EXPECT_STREQ(want, data); - } - - TEST(ASCIIFY, inplace_extended) { - char data[] = "cumpleaños"; - char want[] = "cumplea.os"; - - EXPECT_EQ(11, strlen(data)); - - size_t ascii_len = asciify(data); - std::cout << data << std::endl; - - EXPECT_EQ(strlen(want), ascii_len); - EXPECT_STREQ(want, data); - } - - TEST(ASCIIFY, inplace_utf8) { - char data[] = "哈Something哈"; - char want[] = ".Something."; - - EXPECT_EQ(15, strlen(data)); - - size_t ascii_len = asciify(data); - std::cout << data << std::endl; - - EXPECT_EQ(strlen(want), ascii_len); - EXPECT_STREQ(want, data); - } - -} diff --git a/deps/ledger-zxlib/tests/base64.cpp b/deps/ledger-zxlib/tests/base64.cpp deleted file mode 100644 index af9a8e5..0000000 --- a/deps/ledger-zxlib/tests/base64.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* -* (c) 2019 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include -#include "base64.h" - -namespace { - TEST(BASE64, basic_case) { - char out[100]; - uint8_t data[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; - - base64_encode(out, sizeof(out), data, 0); - EXPECT_STREQ(out, ""); - - base64_encode(out, sizeof(out), data, 1); - EXPECT_STREQ(out, "AQ=="); - - base64_encode(out, sizeof(out), data, 2); - EXPECT_STREQ(out, "AQM="); - - base64_encode(out, sizeof(out), data, 3); - EXPECT_STREQ(out, "AQMF"); - - base64_encode(out, sizeof(out), data, 4); - EXPECT_STREQ(out, "AQMFBw=="); - - base64_encode(out, sizeof(out), data, 5); - EXPECT_STREQ(out, "AQMFBwk="); - - base64_encode(out, sizeof(out), data, 6); - EXPECT_STREQ(out, "AQMFBwkL"); - - base64_encode(out, sizeof(out), data, 7); - EXPECT_STREQ(out, "AQMFBwkLDQ=="); - - base64_encode(out, sizeof(out), data, 8); - EXPECT_STREQ(out, "AQMFBwkLDQ8="); - - base64_encode(out, sizeof(out), data, 9); - EXPECT_STREQ(out, "AQMFBwkLDQ8R"); - - base64_encode(out, sizeof(out), data, 10); - EXPECT_STREQ(out, "AQMFBwkLDQ8REw=="); - } -} diff --git a/deps/ledger-zxlib/tests/bech32.cpp b/deps/ledger-zxlib/tests/bech32.cpp deleted file mode 100644 index 4e79141..0000000 --- a/deps/ledger-zxlib/tests/bech32.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* -* (c) 2019 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include -#include -#include -#include - -namespace { - TEST(BECH32, hex_to_address) { - char addr_out[100]; - const char *hrp = "zx"; - - uint8_t data1[] = {1, 3, 5}; - uint8_t data2[] = {1, 3, 5, 7, 9, 11, 13}; - - auto err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data1, sizeof(data1), 0); - ASSERT_EQ(err, zxerr_ok); - std::cout << addr_out << std::endl; - ASSERT_STREQ("zx1qypse825ac", addr_out); - - err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data2, sizeof(data2), 0); - ASSERT_EQ(err, zxerr_ok); - std::cout << addr_out << std::endl; - ASSERT_STREQ("zx1qyps2pcfpvx20dk22", addr_out); - - /// - err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data1, sizeof(data1), 1); - ASSERT_EQ(err, zxerr_ok); - std::cout << addr_out << std::endl; - ASSERT_STREQ("zx1qyps2ucfnzd", addr_out); - - err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data2, sizeof(data2), 1); - ASSERT_EQ(err, zxerr_ok); - std::cout << addr_out << std::endl; - ASSERT_STREQ("zx1qyps2pcfpvxshamanz", addr_out); - } - - TEST(BECH32, huge_input) { - char addr_out[200]; - const char *hrp = "zx"; - - auto data = std::vector(1000, 0x55); - - auto err = bech32EncodeFromBytes(addr_out, sizeof(addr_out), hrp, data.data(), data.size(),0); - ASSERT_EQ(err, zxerr_out_of_bounds); - - std::cout << addr_out << std::endl; - } - - TEST(BECH32, small_output) { - char addr_out[1000]; - const char *hrp = "zx"; - - auto data = std::vector(32, 0x55); - - MEMZERO(addr_out, sizeof(addr_out)); - - // declare size to be smaller - const size_t declared_size = 52; - - auto err = bech32EncodeFromBytes(addr_out, declared_size, hrp, data.data(), data.size(), 0); - ASSERT_EQ(err, zxerr_buffer_too_small); - - for (int i = declared_size; i < sizeof(addr_out); i++) { - ASSERT_EQ(addr_out[i], 0); - } - - std::cout << addr_out << std::endl; - } -} diff --git a/deps/ledger-zxlib/tests/bip44path.cpp b/deps/ledger-zxlib/tests/bip44path.cpp deleted file mode 100644 index 807d5a6..0000000 --- a/deps/ledger-zxlib/tests/bip44path.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include -#include -#include - -namespace { - TEST(MACROS, bip32empty) { - char buffer[100]; - uint32_t path[] = {44, 60, 0, 0, 1}; - bip32_to_str(buffer, sizeof(buffer), path, 0); - EXPECT_EQ("EMPTY PATH", std::string(buffer)); - } - - TEST(MACROS, bip32tooManyChildren) { - char buffer[100]; - uint32_t path[] = {44, 60, 0, 0, 1}; - bip32_to_str(buffer, sizeof(buffer), path, 200); - EXPECT_EQ("ERROR", std::string(buffer)); - } - - TEST(MACROS, bip32notEnoughSpaceInBuffer1) { - char buffer[6]; - uint32_t path[] = {1234, 60, 0, 0, 1}; - bip32_to_str(buffer, sizeof(buffer), path, 5); - EXPECT_EQ("ERROR", std::string(buffer)); - } - - TEST(MACROS, bip32notEnoughSpaceInBuffer2) { - char buffer[9]; - uint32_t path[] = {1, 1, 1, 1, 1}; - bip32_to_str(buffer, sizeof(buffer), path, 5); - EXPECT_EQ("ERROR", std::string(buffer)); - } - - TEST(MACROS, bip32notEnoughSpaceInBuffer3) { - char buffer[10]; - uint32_t path[] = {1, 1, 1, 1, 0x80000001 }; - bip32_to_str(buffer, sizeof(buffer), path, 5); - EXPECT_EQ("ERROR", std::string(buffer)); - } - - TEST(MACROS, bip32justEnoughSpaceInBuffer3) { - char buffer[10]; - uint32_t path[] = {1, 1, 1, 1, 1}; - bip32_to_str(buffer, sizeof(buffer), path, 5); - EXPECT_EQ("1/1/1/1/1", std::string(buffer)); - } - - TEST(MACROS, bip44path1) { - uint32_t path[] = {44, 60, 0, 0, 1}; - - char buffer[100]; - bip44_to_str(buffer, sizeof(buffer), path); - - EXPECT_EQ("44/60/0/0/1", std::string(buffer)); - } - - TEST(MACROS, bip44path2) { - uint32_t path[] = {0x8000002c, 60, 0, 0, 1}; - - char buffer[100]; - bip44_to_str(buffer, sizeof(buffer), path); - - EXPECT_EQ("44'/60/0/0/1", std::string(buffer)); - } - - TEST(MACROS, bip44path3) { - uint32_t path[] = {0x8000002c, 60, 0, 0, 0x80000001}; - - char buffer[100]; - bip44_to_str(buffer, sizeof(buffer), path); - - EXPECT_EQ("44'/60/0/0/1'", std::string(buffer)); - } -} diff --git a/deps/ledger-zxlib/tests/buffering_tests.cpp b/deps/ledger-zxlib/tests/buffering_tests.cpp deleted file mode 100644 index c7292d1..0000000 --- a/deps/ledger-zxlib/tests/buffering_tests.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "gtest/gtest.h" -#include "buffering.h" - -namespace { - - TEST(Buffering, SmallBuffer) { - uint8_t ram_buffer[100]; - uint8_t flash_buffer[1000]; - - buffering_init(ram_buffer, - sizeof(ram_buffer), - flash_buffer, - sizeof(flash_buffer)); - - // Data is small enough to fit into ram buffer - uint8_t small[50]; - auto num_bytes = buffering_append(small, sizeof(small)); - EXPECT_EQ(sizeof(small), num_bytes) << "Append should not return error"; - - EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "Writing small buffer should only write to RAM"; - EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH"; - EXPECT_EQ(50, buffering_get_ram_buffer()->pos) << "Wrong position of the written data in the ram buffer"; - EXPECT_EQ(100, buffering_get_ram_buffer()->size) << "Wrong size of the ram buffer"; - EXPECT_EQ(0, buffering_get_flash_buffer()->pos) << "Wrong position of the written data in the flash buffer"; - EXPECT_EQ(1000, buffering_get_flash_buffer()->size) << "Wrong size of the flash buffer"; - } - - TEST(Buffering, BigBuffer) { - uint8_t ram_buffer[100]; - uint8_t flash_buffer[1000]; - - buffering_init(ram_buffer, - sizeof(ram_buffer), - flash_buffer, - sizeof(flash_buffer)); - - // Data is too big to fit into ram buffer, it will be written directly to flash - uint8_t big[500]; - auto num_bytes = buffering_append(big, sizeof(big)); - EXPECT_EQ(sizeof(big), num_bytes) << "Append should not return error"; - - EXPECT_FALSE(buffering_get_ram_buffer()->in_use) << "Writing big buffer should write data to FLASH"; - EXPECT_TRUE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH"; - EXPECT_EQ(0, buffering_get_ram_buffer()->pos) << "Wrong position of the written data in the ram buffer"; - EXPECT_EQ(100, buffering_get_ram_buffer()->size) << "Wrong size of the ram buffer"; - EXPECT_EQ(500, buffering_get_flash_buffer()->pos) << "Wrong position of the written data in the flash buffer"; - EXPECT_EQ(1000, buffering_get_flash_buffer()->size) << "Wrong size of the flash buffer"; - } - - TEST(Buffering, SmallBufferMultipleTimesWithinRam) { - uint8_t ram_buffer[100]; - uint8_t flash_buffer[1000]; - - buffering_init(ram_buffer, - sizeof(ram_buffer), - flash_buffer, - sizeof(flash_buffer)); - - uint8_t small[40]; - auto num_bytes = buffering_append(small, sizeof(small)); - EXPECT_EQ(sizeof(small), num_bytes) << "Append should not return error"; - EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "Writing small buffer should only write to RAM"; - EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH"; - - // Here we write another chunk which should not top over the ram buffer - buffering_append(small, sizeof(small)); - EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "Writing small buffer should only write to RAM"; - EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH"; - - EXPECT_EQ(sizeof(small) * 2, buffering_get_ram_buffer()->pos) << "Data should be written to RAM"; - EXPECT_EQ(100, buffering_get_ram_buffer()->size) << "Wrong size of the ram buffer"; - EXPECT_EQ(0, buffering_get_flash_buffer()->pos) << "Data should be written to RAM"; - EXPECT_EQ(1000, buffering_get_flash_buffer()->size) << "Wrong size of the flash buffer"; - } - - TEST(Buffering, SmallBufferMultipleTimesToFlash) { - uint8_t ram_buffer[100]; - uint8_t flash_buffer[1000]; - - buffering_init(ram_buffer, - sizeof(ram_buffer), - flash_buffer, - sizeof(flash_buffer)); - - uint8_t small[100]; - buffering_append(small, sizeof(small)); - EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "Writing small buffer should only write to RAM"; - EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should write data to FLASH"; - - // Here we append another small buffer, this time we're going to exceed ram's size - // data will be copied to nvram - buffering_append(small, sizeof(small)); - EXPECT_FALSE(buffering_get_ram_buffer()->in_use) << "Data should be now in FLASH"; - EXPECT_TRUE(buffering_get_flash_buffer()->in_use) << "Data should be now in FLASH"; - - EXPECT_EQ(0, buffering_get_ram_buffer()->pos) << "RAM buffer should be reset"; - EXPECT_EQ(100, buffering_get_ram_buffer()->size) << "Wrong size of the ram buffer"; - EXPECT_EQ(200, buffering_get_flash_buffer()->pos) << "Wrong position of the written data in the flash buffer"; - EXPECT_EQ(1000, buffering_get_flash_buffer()->size) << "Wrong size of the flash buffer"; - } - - TEST(Buffering, SmallBufferMultipleTimes_CheckData) { - uint8_t ram_buffer[100]; - uint8_t flash_buffer[1000]; - - buffering_init(ram_buffer, - sizeof(ram_buffer), - flash_buffer, - sizeof(flash_buffer)); - - uint8_t small1[100]; - for (int i = 0; i < sizeof(small1); i++) { - small1[i] = i; - } - buffering_append(small1, sizeof(small1)); - - uint8_t small2[200]; - for (int i = 0; i < sizeof(small2); i++) { - small2[i] = 100 - i; - } - auto num_bytes = buffering_append(small2, sizeof(small2)); - EXPECT_EQ(sizeof(small2), num_bytes) << "Append should not return error"; - - // In this test we want to make sure that data is not compromised. - uint8_t *dst = buffering_get_flash_buffer()->data; - for (int i = 0; i < sizeof(small1) + sizeof(small2); i++) { - if (i < sizeof(small1)) { - EXPECT_EQ(dst[i], small1[i]) << "Wrong data written to FLASH"; - } else { - EXPECT_EQ(dst[i], small2[i - sizeof(small1)]) << "Wrong data written to FLASH"; - } - } - } - - TEST(Buffering, Reset) { - uint8_t ram_buffer[100]; - uint8_t flash_buffer[1000]; - - buffering_init(ram_buffer, - sizeof(ram_buffer), - flash_buffer, - sizeof(flash_buffer)); - - uint8_t big[1000]; - auto num_bytes = buffering_append(big, sizeof(big)); - EXPECT_EQ(sizeof(big), num_bytes) << "Append should not return error"; - - EXPECT_FALSE(buffering_get_ram_buffer()->in_use) << "Writing big buffer should only write to FLASH"; - EXPECT_TRUE(buffering_get_flash_buffer()->in_use) << "Writing big buffer should only write to FLASH"; - - buffering_reset(); - - EXPECT_TRUE(buffering_get_ram_buffer()->in_use) << "After reset RAM should be enabled by default"; - EXPECT_FALSE(buffering_get_flash_buffer()->in_use) << "After reset RAM should be enabled by default"; - } - - TEST(Buffering, NotEnoughRoomInFlash) { - uint8_t ram_buffer[100]; - uint8_t flash_buffer[1000]; - - buffering_init(ram_buffer, - sizeof(ram_buffer), - flash_buffer, - sizeof(flash_buffer)); - - uint8_t big[1101]; - auto num_bytes = buffering_append(big, sizeof(big)); - EXPECT_EQ(0, num_bytes) << "Appending outside the bounds of the buffer should return error"; - } - - TEST(Buffering, NoFlashOnlyRAM) { - uint8_t ram_buffer[100]; - - buffering_init(ram_buffer, - sizeof(ram_buffer), - nullptr, 0); - - uint8_t small[10]; - auto num_bytes = buffering_append(small, sizeof(small)); - EXPECT_EQ(10, num_bytes) << "Could not add to RAM"; - - num_bytes = buffering_append(small, sizeof(small)); - EXPECT_EQ(10, num_bytes) << "Could not add to RAM"; - - num_bytes = buffering_append(small, sizeof(small)); - EXPECT_EQ(10, num_bytes) << "Could not add to RAM"; - - auto state = buffering_get_buffer(); - EXPECT_EQ(30, state->pos) << "Invalid buffer size"; - - uint8_t small2[70]; - num_bytes = buffering_append(small2, sizeof(small2)); - EXPECT_EQ(70, num_bytes); - - state = buffering_get_buffer(); - EXPECT_EQ(100, state->pos) << "Invalid buffer size"; - - num_bytes = buffering_append(small, sizeof(small)); - EXPECT_EQ(0, num_bytes) << "Could add to RAM when it should have been impossible"; - } - - TEST(Buffering, NoFlash) { - uint8_t ram_buffer[100]; - - buffering_init(ram_buffer, - sizeof(ram_buffer), - nullptr, 0); - - uint8_t big[1101]; - auto num_bytes = buffering_append(big, sizeof(big)); - EXPECT_EQ(0, num_bytes) << "Appending outside the bounds of the buffer should return error"; - } -} diff --git a/deps/ledger-zxlib/tests/doubledabble.cpp b/deps/ledger-zxlib/tests/doubledabble.cpp deleted file mode 100644 index 4b7b048..0000000 --- a/deps/ledger-zxlib/tests/doubledabble.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/******************************************************************************* -* (c) 2019 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "gmock/gmock.h" - -#include -#include "bignum.h" - -using ::testing::TestWithParam; -using ::testing::Values; - -typedef struct { - std::string hex; - std::string expectedOutput; -} bignum_testcase_t; - -class BignumLittleEndianTests : public ::testing::TestWithParam { -}; - -class BignumBigEndianTests : public ::testing::TestWithParam { -}; - -INSTANTIATE_TEST_SUITE_P - -( - BignumTestCases, BignumLittleEndianTests, testing::Values( - bignum_testcase_t{"00", "0"}, - bignum_testcase_t{"01", "1"}, - bignum_testcase_t{"0001", "256"}, - bignum_testcase_t{"03E8", "59395"}, - bignum_testcase_t{"E803", "1000"}, - bignum_testcase_t{"10", "16"}, - bignum_testcase_t{"FF01", "511"}, - bignum_testcase_t{"0102", "513"}, - bignum_testcase_t{"FFFF01", "131071"}, - bignum_testcase_t{"a08601", "100000"}, - bignum_testcase_t{"40420f", "1000000"}, - bignum_testcase_t{"809698", "10000000"}, - bignum_testcase_t{"002d3101", "20000000"}, - bignum_testcase_t{"00e1f505", "100000000"}, - bignum_testcase_t{"00407a10f35a", "100000000000000"}, - bignum_testcase_t{"d2029649", "1234567890"}, - bignum_testcase_t{"d20a3fce96f1cf8c9cb4378c37a4873f17621ebce404f5aa13", - "123456789012345678901234567890123456789012345678901234567890"} -)); - -// Check that bignums are printed properly (parametric tests) -TEST_P(BignumLittleEndianTests, print) { - auto testcase = GetParam(); - - uint8_t inBuffer[100]; - auto inBufferLen = parseHexString(inBuffer, sizeof(inBuffer), testcase.hex.c_str()); - - uint8_t bcdOut[100]; - uint16_t bcdOutLen = sizeof(bcdOut); - - bignumLittleEndian_to_bcd(bcdOut, bcdOutLen, inBuffer, static_cast(inBufferLen)); - - char bufferUI[300]; - bignumLittleEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen); - EXPECT_THAT(std::string(bufferUI), testing::Eq(testcase.expectedOutput)); -} - -// Check that bignums are printed properly (range tests) -TEST(BignumLittleEndianTests, range) { - uint8_t inBuffer[100]; - - for (uint64_t i = 0; i < 10000; i++) { - std::stringstream s; - uint64_t tmp = i; - while (tmp != 0) { - s << std::setfill('0') << std::setw(2) << std::hex << tmp % 256; - tmp /= 256; - } - auto inBufferLen = parseHexString(inBuffer, sizeof(inBuffer), s.str().c_str()); - - uint8_t bcdOut[100]; - uint16_t bcdOutLen = sizeof(bcdOut); - bignumLittleEndian_to_bcd(bcdOut, bcdOutLen, inBuffer, static_cast(inBufferLen)); - char bufferUI[300]; - bignumLittleEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen); - - std::stringstream expected; - expected << i; - EXPECT_THAT(std::string(bufferUI), testing::Eq(expected.str())) << s.str(); - } -} - -INSTANTIATE_TEST_SUITE_P - -( - BignumTestCases, BignumBigEndianTests, testing::Values( - bignum_testcase_t{"00", "0"}, - bignum_testcase_t{"01", "1"}, - bignum_testcase_t{"0001", "1"}, - bignum_testcase_t{"000001", "1"}, - bignum_testcase_t{"03E8", "1000"}, - bignum_testcase_t{"E803", "59395"}, - bignum_testcase_t{"10", "16"}, - bignum_testcase_t{"FF01", "65281"}, - bignum_testcase_t{"01FF", "511"}, - bignum_testcase_t{"0102", "258"}, - bignum_testcase_t{"FFFF01", "16776961"}, - bignum_testcase_t{"a08601", "10520065"}, - bignum_testcase_t{"40420f", "4211215"}, - bignum_testcase_t{"809698", "8427160"}, - bignum_testcase_t{"002d3101", "2961665"}, - bignum_testcase_t{"00e1f505", "14808325"}, - bignum_testcase_t{"00407a10f35a", "276925838170"}, - bignum_testcase_t{"d2029649", "3523384905"}, - bignum_testcase_t{"d20a3fce96f1cf8c9cb4378c37a4873f17621ebce404f5aa13", - "1318442675213289749221432902819395197389189473307425559128595"} -)); - -// Check that bignums are printed properly (parametric tests) -TEST_P(BignumBigEndianTests, print) { - auto testcase = GetParam(); - - uint8_t inBuffer[100]; - auto inBufferLen = parseHexString(inBuffer, sizeof(inBuffer), testcase.hex.c_str()); - - uint8_t bcdOut[100]; - uint16_t bcdOutLen = sizeof(bcdOut); - bignumBigEndian_to_bcd(bcdOut, bcdOutLen, inBuffer, static_cast(inBufferLen)); - - char bufferUI[300]; - bignumBigEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen); - EXPECT_THAT(std::string(bufferUI), testing::Eq(testcase.expectedOutput)); -} - -// Check that bignums are printed properly (range tests) -TEST(BignumBigEndianTests, range) { - uint8_t inBuffer[100]; - - for (uint64_t i = 0; i < 2500; i += 7) { - std::stringstream s; - s << std::setfill('0') << std::setw(10) << std::hex << i; - std::cout << s.str() << std::endl; - auto inBufferLen = parseHexString(inBuffer, sizeof(inBuffer), s.str().c_str()); - - uint8_t bcdOut[100]; - uint16_t bcdOutLen = sizeof(bcdOut); - bignumBigEndian_to_bcd(bcdOut, bcdOutLen, inBuffer, static_cast(inBufferLen)); - char bufferUI[300]; - bignumBigEndian_bcdprint(bufferUI, sizeof(bufferUI), bcdOut, bcdOutLen); - - std::stringstream expected; - expected << i; - EXPECT_THAT(std::string(bufferUI), testing::Eq(expected.str())) << s.str(); - } -} diff --git a/deps/ledger-zxlib/tests/hexutils.cpp b/deps/ledger-zxlib/tests/hexutils.cpp deleted file mode 100644 index e9d3ae4..0000000 --- a/deps/ledger-zxlib/tests/hexutils.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "gmock/gmock.h" - -#include - -#include "hexutils.h" - -TEST(HEXUTILS, parseHexString) { - char s[] = "1234567890"; - uint8_t data[100]; - - auto length = parseHexString(data, sizeof(data), s); - - ASSERT_THAT(length, testing::Eq(5)); - - ASSERT_THAT(data[0], testing::Eq(0x12)); - ASSERT_THAT(data[1], testing::Eq(0x34)); - ASSERT_THAT(data[2], testing::Eq(0x56)); - ASSERT_THAT(data[3], testing::Eq(0x78)); - ASSERT_THAT(data[4], testing::Eq(0x90)); -} - -TEST(HEXUTILS, parseHexString2) { - char s[] = "be333be7ee"; - uint8_t data[100]; - - auto length = parseHexString(data, sizeof(data), s); - - ASSERT_THAT(length, testing::Eq(5)); - - ASSERT_THAT(data[0], testing::Eq(0xbe)); - ASSERT_THAT(data[1], testing::Eq(0x33)); - ASSERT_THAT(data[2], testing::Eq(0x3b)); - ASSERT_THAT(data[3], testing::Eq(0xe7)); - ASSERT_THAT(data[4], testing::Eq(0xee)); -} diff --git a/deps/ledger-zxlib/tests/macros.cpp b/deps/ledger-zxlib/tests/macros.cpp deleted file mode 100644 index a4a2e86..0000000 --- a/deps/ledger-zxlib/tests/macros.cpp +++ /dev/null @@ -1,502 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include -#include -#include - -namespace { - TEST(FORMAT, array_to_hexstr) { - uint8_t array1[] = {1, 3, 5}; - - char output[20]; - memset(output, 1, 20); - - array_to_hexstr(output, sizeof(output), array1, sizeof(array1)); - EXPECT_EQ(memcmp(output, "010305", 2 * sizeof(array1)), 0); - EXPECT_EQ(output[2 * sizeof(array1)], 0); - } - - TEST(FORMAT, fpuint64_to_str) { - char output[100]; - printf("\n"); - - fpuint64_to_str(output, sizeof(output), 123, 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.00123"); - - fpuint64_to_str(output, sizeof(output), 1234, 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.01234"); - - fpuint64_to_str(output, sizeof(output), 12345, 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.12345"); - - fpuint64_to_str(output, sizeof(output), 123456, 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "1.23456"); - - fpuint64_to_str(output, sizeof(output), 1234567, 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "12.34567"); - } - - TEST(FORMAT, fpstr_to_str) { - char output[100]; - printf("\n"); - - fpstr_to_str(output, sizeof(output), "", 0); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0"); - - fpstr_to_str(output, sizeof(output), "1", 0); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "1"); - - fpstr_to_str(output, sizeof(output), "123", 0); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "123"); - - fpstr_to_str(output, sizeof(output), "", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.00000"); - - fpstr_to_str(output, sizeof(output), "0", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.00000"); - - fpstr_to_str(output, sizeof(output), "123", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.00123"); - - fpstr_to_str(output, sizeof(output), "1234", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.01234"); - - fpstr_to_str(output, sizeof(output), "12345", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.12345"); - - fpstr_to_str(output, sizeof(output), "123456", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "1.23456"); - - fpstr_to_str(output, sizeof(output), "1234567", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "12.34567"); - } - - TEST(FORMAT, fpstr_to_str_BAD_zeros) { - char output[8]; - printf("\n"); - - fpstr_to_str(output, sizeof(output), "", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.00000"); - - fpstr_to_str(output, sizeof(output), "", 6); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "", 7); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "", 8); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - } - - TEST(FORMAT, fpstr_to_str_BAD_short) { - char output[8]; - printf("\n"); - - fpstr_to_str(output, sizeof(output), "123", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "0.00123"); - - fpstr_to_str(output, sizeof(output), "123", 6); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "123", 7); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "123", 8); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - } - - TEST(FORMAT, fpstr_to_str_BAD_long) { - char output[8]; - printf("\n"); - - fpstr_to_str(output, sizeof(output), "123456", 5); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "1.23456"); - - fpstr_to_str(output, sizeof(output), "123456", 6); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "123456", 7); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "12345", 7); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "12345", 2); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "123.45"); - - fpstr_to_str(output, sizeof(output), "123456", 2); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "1234.56"); - - fpstr_to_str(output, sizeof(output), "1234567", 2); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "12345678", 2); - printf("%10s\n", output); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "1234567890", 0); - EXPECT_EQ(std::string(output), "ERR"); - - fpstr_to_str(output, sizeof(output), "123456", 0); - EXPECT_EQ(std::string(output), "123456"); - } - - TEST(FORMAT, fpuint64_to_str_zeros) { - char output[100]; - printf("\n"); - - fpuint64_to_str(output, sizeof(output), 0, 9); - printf("%11s\n", output); - EXPECT_EQ(std::string(output), "0.000000000"); - - fpuint64_to_str(output, sizeof(output), 0, 1); - printf("%11s\n", output); - EXPECT_EQ(std::string(output), "0.0"); - - fpuint64_to_str(output, sizeof(output), 1, 1); - printf("%11s\n", output); - EXPECT_EQ(std::string(output), "0.1"); - - fpuint64_to_str(output, sizeof(output), 10, 1); - printf("%11s\n", output); - EXPECT_EQ(std::string(output), "1.0"); - } - - TEST(FORMAT, number_trimming) { - char output[100]; - - snprintf(output, sizeof(output), "0"); - number_inplace_trimming(output, 1); - EXPECT_EQ(std::string(output), "0"); - - snprintf(output, sizeof(output), "10"); - number_inplace_trimming(output, 1); - EXPECT_EQ(std::string(output), "10"); - - snprintf(output, sizeof(output), "10.10"); - number_inplace_trimming(output, 1); - EXPECT_EQ(std::string(output), "10.1"); - - snprintf(output, sizeof(output), "0.0"); - number_inplace_trimming(output, 1); - EXPECT_EQ(std::string(output), "0.0"); - - snprintf(output, sizeof(output), "0.00"); - number_inplace_trimming(output, 1); - EXPECT_EQ(std::string(output), "0.0"); - - snprintf(output, sizeof(output), "0.01"); - number_inplace_trimming(output, 1); - EXPECT_EQ(std::string(output), "0.01"); - - snprintf(output, sizeof(output), "0.010"); - number_inplace_trimming(output, 1); - EXPECT_EQ(std::string(output), "0.01"); - - snprintf(output, sizeof(output), "0.010000"); - number_inplace_trimming(output, 1); - EXPECT_EQ(std::string(output), "0.01"); - } - - TEST(FORMAT, intstr_to_fpstr_inplace_trimming_leading) { - char number[100]; - printf("\n"); - - snprintf(number, sizeof(number), "0"); - intstr_to_fpstr_inplace(number, sizeof(number), 0); - EXPECT_EQ(std::string(number), "0"); - - snprintf(number, sizeof(number), "00"); - intstr_to_fpstr_inplace(number, sizeof(number), 0); - EXPECT_EQ(std::string(number), "0"); - - snprintf(number, sizeof(number), "0000"); - intstr_to_fpstr_inplace(number, sizeof(number), 0); - EXPECT_EQ(std::string(number), "0"); - - snprintf(number, sizeof(number), "00001"); - intstr_to_fpstr_inplace(number, sizeof(number), 0); - EXPECT_EQ(std::string(number), "1"); - - snprintf(number, sizeof(number), "000011"); - intstr_to_fpstr_inplace(number, sizeof(number), 0); - EXPECT_EQ(std::string(number), "11"); - - snprintf(number, sizeof(number), "10000"); - intstr_to_fpstr_inplace(number, sizeof(number), 0); - EXPECT_EQ(std::string(number), "10000"); - } - - TEST(FORMAT, intstr_to_fpstr_inplace_empty) { - char number[100]; - printf("\n"); - - MEMZERO(number, sizeof(number)); - intstr_to_fpstr_inplace(number, sizeof(number), 0); - EXPECT_EQ(std::string(number), "0"); - - MEMZERO(number, sizeof(number)); - intstr_to_fpstr_inplace(number, sizeof(number), 5); - EXPECT_EQ(std::string(number), "0.00000"); - - MEMZERO(number, sizeof(number)); - intstr_to_fpstr_inplace(number, sizeof(number), 10); - EXPECT_EQ(std::string(number), "0.0000000000"); - } - - TEST(FORMAT, intstr_to_fpstr_inplace) { - char number[100]; - printf("\n"); - - snprintf(number, sizeof(number), "1"); - intstr_to_fpstr_inplace(number, sizeof(number), 0); - EXPECT_EQ(std::string(number), "1"); - - snprintf(number, sizeof(number), "123"); - intstr_to_fpstr_inplace(number, sizeof(number), 0); - EXPECT_EQ(std::string(number), "123"); - - snprintf(number, sizeof(number), "0"); - intstr_to_fpstr_inplace(number, sizeof(number), 5); - EXPECT_EQ(std::string(number), "0.00000"); - - snprintf(number, sizeof(number), "123"); - intstr_to_fpstr_inplace(number, sizeof(number), 5); - EXPECT_EQ(std::string(number), "0.00123"); - - snprintf(number, sizeof(number), "1234"); - intstr_to_fpstr_inplace(number, sizeof(number), 5); - EXPECT_EQ(std::string(number), "0.01234"); - - snprintf(number, sizeof(number), "12345"); - intstr_to_fpstr_inplace(number, sizeof(number), 5); - EXPECT_EQ(std::string(number), "0.12345"); - - snprintf(number, sizeof(number), "123456"); - intstr_to_fpstr_inplace(number, sizeof(number), 5); - EXPECT_EQ(std::string(number), "1.23456"); - - snprintf(number, sizeof(number), "1234567"); - intstr_to_fpstr_inplace(number, sizeof(number), 5); - EXPECT_EQ(std::string(number), "12.34567"); - } - - TEST(INT64_TO_STR, Zero) { - char temp[10]; - const char *error = int64_to_str(temp, sizeof(temp), int64_t(0)); - EXPECT_STREQ(temp, "0"); - EXPECT_TRUE(error == nullptr); - } - - TEST(INT64_TO_STR, Positive_1234) { - char temp[10]; - const char *error = int64_to_str(temp, sizeof(temp), int64_t(1234)); - EXPECT_STREQ(temp, "1234"); - EXPECT_TRUE(error == nullptr); - } - - TEST(INT64_TO_STR, Negative_1234) { - char temp[10]; - const char *error = int64_to_str(temp, sizeof(temp), int64_t(-1234)); - EXPECT_STREQ(temp, "-1234"); - EXPECT_TRUE(error == nullptr); - } - - TEST(INT64_TO_STR, TooSmall_0) { - char temp[1]; - const char *error = int64_to_str(temp, sizeof(temp), int64_t(0)); - EXPECT_STREQ("Buffer too small", error); - } - - TEST(INT64_TO_STR, FitsJust) { - char temp[4]; - const char *error = int64_to_str(temp, sizeof(temp), int64_t(999)); - EXPECT_STREQ(temp, "999"); - EXPECT_TRUE(error == nullptr); - } - - TEST(INT64_TO_STR, TooSmall_10) { - char temp[2]; - const char *error = int64_to_str(temp, sizeof(temp), int64_t(10)); - EXPECT_STREQ("Buffer too small", error); - } - - TEST(INT64_TO_STR, Max) { - char temp[20]; - const char *error = int64_to_str(temp, sizeof(temp), std::numeric_limits::max()); - EXPECT_STREQ(temp, "9223372036854775807"); - EXPECT_TRUE(error == nullptr); - } - - TEST(INT64_TO_STR, Min) { - char temp[21]; - const char *error = int64_to_str(temp, sizeof(temp), std::numeric_limits::min()); - EXPECT_STREQ(temp, "-9223372036854775808"); - EXPECT_TRUE(error == nullptr); - } - - TEST(STR_TO_INT8, Min) { - char numberStr[] = "-128"; - char error = 0; - int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(-128, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT8, Max) { - char numberStr[] = "127"; - char error = 0; - int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(127, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT8, Zero) { - char numberStr[] = "0"; - char error = 0; - int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(0, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT8, Hundred) { - char numberStr[] = "100"; - char error = 0; - int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(100, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT8, NegHundred) { - char numberStr[] = "-100"; - char error = 0; - int8_t number = str_to_int8(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(-100, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT8, OutsideBoundsPositive) { - char numberStr[] = "128"; - char error = 0; - str_to_int8(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(1, error); - } - - TEST(STR_TO_INT8, OutsideBoundsNegative) { - char numberStr[] = "-129"; - char error = 0; - str_to_int8(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(1, error); - } - - TEST(STR_TO_INT8, DummyData_Positive) { - char numberStr[] = "100b0"; - char error = 0; - str_to_int8(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(1, error); - } - - TEST(STR_TO_INT8, DummyData_Negative) { - char numberStr[] = "-1002xx"; - char error = 0; - str_to_int8(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(1, error); - } - - TEST(STR_TO_INT64, Min) { - char numberStr[] = "-9223372036854775807"; - char error = 0; - int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(-9223372036854775807, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT64, Max) { - char numberStr[] = "9223372036854775807"; - char error = 0; - int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(9223372036854775807, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT64, Zero) { - char numberStr[] = "0"; - char error = 0; - int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(0, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT64, Hundred) { - char numberStr[] = "100"; - char error = 0; - int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(100, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT64, NegHundred) { - char numberStr[] = "-100"; - char error = 0; - int64_t number = str_to_int64(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(-100, number); - EXPECT_EQ(0, error); - } - - TEST(STR_TO_INT64, DummyData_Positive) { - char numberStr[] = "100b0"; - char error = 0; - str_to_int64(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(1, error); - } - - TEST(STR_TO_INT64, DummyData_Negative) { - char numberStr[] = "-1002xx"; - char error = 0; - str_to_int64(numberStr, numberStr + strlen(numberStr), &error); - EXPECT_EQ(1, error); - } -} diff --git a/deps/ledger-zxlib/tests/sigutils.cpp b/deps/ledger-zxlib/tests/sigutils.cpp deleted file mode 100644 index 21fde60..0000000 --- a/deps/ledger-zxlib/tests/sigutils.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* -* (c) 2020 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -#include "gmock/gmock.h" -#include -#include -#include -#include - -#include "sigutils.h" - -TEST(SIGUTILS, convertBasic) { - char inSignatureDERStr[] = "304402206878b5690514437a2342405029426cc2b25b4a03fc396fef845d656cf62bad2c022018610a8d37e3384245176ab49ddbdbe8da4133f661bf5ea7ad4e3d2b912d856f01"; - auto inSignatureDER = std::vector(71); - - auto length = parseHexString(inSignatureDER.data(), inSignatureDER.size(), inSignatureDERStr); - EXPECT_EQ(length, sizeof(inSignatureDERStr) / 2); - - uint8_t R[32]; - uint8_t S[32]; - uint8_t V; - - auto ret = convertDERtoRSV(inSignatureDER.data(), 0, R, S, &V); - EXPECT_EQ(ret, 0); - - char inSignatureDERStr_R[] = "6878b5690514437a2342405029426cc2b25b4a03fc396fef845d656cf62bad2c"; - char inSignatureDERStr_S[] = "18610a8d37e3384245176ab49ddbdbe8da4133f661bf5ea7ad4e3d2b912d856f"; - auto inSignatureDER_R = std::vector(32); - auto inSignatureDER_S = std::vector(32); - parseHexString(inSignatureDER_R.data(), inSignatureDER_R.size(), inSignatureDERStr_R); - parseHexString(inSignatureDER_S.data(), inSignatureDER_S.size(), inSignatureDERStr_S); - - EXPECT_THAT(R, ::testing::ElementsAreArray(inSignatureDER_R)); - EXPECT_THAT(S, ::testing::ElementsAreArray(inSignatureDER_S)); -} - -TEST(SIGUTILS, convertBasic2) { - char inSignatureDERStr[] = "30430220035942178e9e8d447cf9e6886f99c41bf942fb2880fd79aa2d4626489ec7821b021f6b3277dea0355c161d20a120ec9165500b5c9a2cd0fce1c4b8a5260bf6831f"; - auto inSignatureDER = std::vector(71); - - auto length = parseHexString(inSignatureDER.data(), inSignatureDER.size(), inSignatureDERStr); - EXPECT_EQ(length, sizeof(inSignatureDERStr) / 2); - - uint8_t R[32]; - uint8_t S[32]; - uint8_t V; - - auto ret = convertDERtoRSV(inSignatureDER.data(), 0, R, S, &V); - EXPECT_EQ(ret, 0); - - char inSignatureDERStr_R[] = "035942178e9e8d447cf9e6886f99c41bf942fb2880fd79aa2d4626489ec7821b"; - char inSignatureDERStr_S[] = "006b3277dea0355c161d20a120ec9165500b5c9a2cd0fce1c4b8a5260bf6831f"; - auto inSignatureDER_R = std::vector(32); - auto inSignatureDER_S = std::vector(32); - parseHexString(inSignatureDER_R.data(), inSignatureDER_R.size(), inSignatureDERStr_R); - parseHexString(inSignatureDER_S.data(), inSignatureDER_S.size(), inSignatureDERStr_S); - - char buffer[100]; - array_to_hexstr(buffer, sizeof(buffer), R, (int16_t) sizeof(R)); - std::cout << buffer << std::endl; - array_to_hexstr(buffer, sizeof(buffer), S, (int16_t) sizeof(S)); - std::cout << buffer << std::endl; - - EXPECT_THAT(R, ::testing::ElementsAreArray(inSignatureDER_R)); - EXPECT_THAT(S, ::testing::ElementsAreArray(inSignatureDER_S)); -} - -TEST(SIGUTILS, convertBasic3) { - char inSignatureDERStr[] = "3045022100e9b508a9cd66410b43992c01622cf9e1a6aa1353d836d7f428a6d1317f96f27d02200ca01cee5480388bad3802c08e0bcf357c091f3a5921e1e5d1e0e115dd14ff23"; - auto inSignatureDER = std::vector(71); - - auto length = parseHexString(inSignatureDER.data(), inSignatureDER.size(), inSignatureDERStr); - EXPECT_EQ(length, sizeof(inSignatureDERStr) / 2); - - uint8_t R[32]; - uint8_t S[32]; - uint8_t V; - - auto ret = convertDERtoRSV(inSignatureDER.data(), 0, R, S, &V); - EXPECT_EQ(ret, 0); - - char inSignatureDERStr_R[] = "e9b508a9cd66410b43992c01622cf9e1a6aa1353d836d7f428a6d1317f96f27d"; - char inSignatureDERStr_S[] = "0ca01cee5480388bad3802c08e0bcf357c091f3a5921e1e5d1e0e115dd14ff23"; - auto inSignatureDER_R = std::vector(32); - auto inSignatureDER_S = std::vector(32); - parseHexString(inSignatureDER_R.data(), inSignatureDER_R.size(), inSignatureDERStr_R); - parseHexString(inSignatureDER_S.data(), inSignatureDER_S.size(), inSignatureDERStr_S); - - EXPECT_THAT(R, ::testing::ElementsAreArray(inSignatureDER_R)); - EXPECT_THAT(S, ::testing::ElementsAreArray(inSignatureDER_S)); -} - -TEST(SIGUTILS, convertShort1) { - char inSignatureDERStr[] = "3041021e544670fe5627f2d483484582284f627d9cfd1e0ab123984e81611a8da4fc021f6d99f9afd3c4fa62cee8dff21786f9c23c8d2f524d8fd363acc6c6567dc380"; - char inSignatureDERStr_R[] = "0000544670fe5627f2d483484582284f627d9cfd1e0ab123984e81611a8da4fc"; - char inSignatureDERStr_S[] = "006d99f9afd3c4fa62cee8dff21786f9c23c8d2f524d8fd363acc6c6567dc380"; - - auto inSignatureDER = std::vector(sizeof(inSignatureDERStr)); - - auto length = parseHexString(inSignatureDER.data(), inSignatureDER.size(), inSignatureDERStr); - EXPECT_EQ(length, sizeof(inSignatureDERStr) / 2); - - uint8_t R[32]; - uint8_t S[32]; - uint8_t V; - - auto ret = convertDERtoRSV(inSignatureDER.data(), 0, R, S, &V); - EXPECT_EQ(ret, 0); - - - char R_str[200]; - char S_str[200]; - array_to_hexstr(R_str, sizeof(R_str), R, 32); - std::cout << R_str << std::endl; - array_to_hexstr(S_str, sizeof(S_str), S, 32); - std::cout << S_str << std::endl; - - EXPECT_STREQ(R_str, inSignatureDERStr_R); - EXPECT_STREQ(S_str, inSignatureDERStr_S); -} diff --git a/deps/ledger-zxlib/tests/zxformat.cpp b/deps/ledger-zxlib/tests/zxformat.cpp deleted file mode 100644 index 3ad7b24..0000000 --- a/deps/ledger-zxlib/tests/zxformat.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* -* (c) 2018 Zondax GmbH -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -#include -#include -#include - -namespace { - TEST(FORMAT, nothingAdded) { - char buffer[10]; - - snprintf(buffer, sizeof(buffer), "TEST"); - auto prefix = std::string(""); - - EXPECT_EQ(zxerr_ok, z_str3join(buffer, sizeof(buffer), prefix.c_str(), "")); - EXPECT_STREQ(buffer, "TEST"); - } - - TEST(FORMAT, noPrefix) { - char buffer[10]; - - snprintf(buffer, sizeof(buffer), "TEST"); - auto prefix = std::string(""); - auto suffix = std::string("1"); - - EXPECT_EQ(zxerr_ok, z_str3join(buffer, sizeof(buffer), prefix.c_str(), suffix.c_str())); - EXPECT_STREQ(buffer, "TEST1"); - } - - TEST(FORMAT, prefixSimple) { - char buffer[10]; - - snprintf(buffer, sizeof(buffer), "TEST"); - auto prefix = std::string("xyz "); - auto suffix = std::string("1"); - - EXPECT_EQ(zxerr_ok, z_str3join(buffer, sizeof(buffer), prefix.c_str(), suffix.c_str())); - EXPECT_STREQ(buffer, "xyz TEST1"); - } - - TEST(FORMAT, limitBuffer0) { - char buffer[10]; - - snprintf(buffer, sizeof(buffer), "TEST"); - auto prefix = std::string("xyz"); - auto suffix = std::string("4"); - - EXPECT_EQ(zxerr_ok, z_str3join(buffer, sizeof(buffer), prefix.c_str(), suffix.c_str())); - EXPECT_STREQ(buffer, "xyzTEST4"); - } - - TEST(FORMAT, limitBuffer1) { - char buffer[9]; - - snprintf(buffer, sizeof(buffer), "TEST"); - auto prefix = std::string("xyz"); - auto suffix = std::string("4"); - - EXPECT_EQ(zxerr_ok, z_str3join(buffer, sizeof(buffer), prefix.c_str(), suffix.c_str())); - EXPECT_STREQ(buffer, "xyzTEST4"); - } - - TEST(FORMAT, limitBuffer2) { - char buffer[8]; - - snprintf(buffer, sizeof(buffer), "TEST"); - auto prefix = std::string("xyz"); - auto suffix = std::string("4"); - - EXPECT_EQ(zxerr_buffer_too_small, z_str3join(buffer, sizeof(buffer), prefix.c_str(), suffix.c_str())); - EXPECT_STREQ(buffer, "ERR???"); - } - - TEST(FORMAT, smallBuffer) { - char buffer[7]; - - snprintf(buffer, sizeof(buffer), "TEST"); - auto prefix = std::string("xyz"); - auto suffix = std::string("4"); - - EXPECT_EQ(zxerr_buffer_too_small, z_str3join(buffer, sizeof(buffer), prefix.c_str(), suffix.c_str())); - EXPECT_STREQ(buffer, "ERR???"); - } - -} From 48efbc034c3b88e33addbdb9a35dec1b3fafa847 Mon Sep 17 00:00:00 2001 From: ftheirs Date: Tue, 5 Jul 2022 08:33:02 -0300 Subject: [PATCH 3/4] update submodules --- .gitmodules | 3 +++ deps/ledger-zxlib | 1 + deps/nanos-secure-sdk | 2 +- deps/nanosplus-secure-sdk | 2 +- deps/nanox-secure-sdk | 2 +- 5 files changed, 7 insertions(+), 3 deletions(-) create mode 160000 deps/ledger-zxlib diff --git a/.gitmodules b/.gitmodules index 27e9369..721a322 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "deps/nanosplus-secure-sdk"] path = deps/nanosplus-secure-sdk url = https://github.com/LedgerHQ/nanosplus-secure-sdk +[submodule "deps/ledger-zxlib"] + path = deps/ledger-zxlib + url = https://github.com/Zondax/ledger-zxlib.git diff --git a/deps/ledger-zxlib b/deps/ledger-zxlib new file mode 160000 index 0000000..ccf9cf8 --- /dev/null +++ b/deps/ledger-zxlib @@ -0,0 +1 @@ +Subproject commit ccf9cf81b8d4d83a58ccd5948d8f80ef582e2efe diff --git a/deps/nanos-secure-sdk b/deps/nanos-secure-sdk index 1c16f9a..026a1f5 160000 --- a/deps/nanos-secure-sdk +++ b/deps/nanos-secure-sdk @@ -1 +1 @@ -Subproject commit 1c16f9ad50f792c62a948aacb650258660f262cb +Subproject commit 026a1f5cf55e68f74062cb2795804f9b4554ea15 diff --git a/deps/nanosplus-secure-sdk b/deps/nanosplus-secure-sdk index dd4684c..c2a17eb 160000 --- a/deps/nanosplus-secure-sdk +++ b/deps/nanosplus-secure-sdk @@ -1 +1 @@ -Subproject commit dd4684c36592ddbdfc1df78e045d93376beaba96 +Subproject commit c2a17ebe62395d7a7a36658bf4bec952c08d0df3 diff --git a/deps/nanox-secure-sdk b/deps/nanox-secure-sdk index ba45af7..86324f6 160000 --- a/deps/nanox-secure-sdk +++ b/deps/nanox-secure-sdk @@ -1 +1 @@ -Subproject commit ba45af7f4208b6c02ac35fb0d43a914228febd56 +Subproject commit 86324f6a73e269c04f6a3e3cf41f6569a8cc6c6b From f283a60ed30f9af8e62cb181208a456c55e5ea56 Mon Sep 17 00:00:00 2001 From: ftheirs Date: Tue, 5 Jul 2022 09:15:33 -0300 Subject: [PATCH 4/4] update version & snapshots --- .github/workflows/ledger.yml | 10 ++++++++-- .github/workflows/main.yml | 2 +- app/Makefile | 4 ++-- app/Makefile.version | 2 +- app/src/apdu_handler.c | 4 ++-- tests_zemu/package.json | 2 +- tests_zemu/snapshots/s-mainmenu/00004.png | Bin 442 -> 447 bytes tests_zemu/snapshots/s-mainmenu/00010.png | Bin 442 -> 447 bytes tests_zemu/snapshots/sp-mainmenu/00004.png | Bin 367 -> 370 bytes tests_zemu/snapshots/sp-mainmenu/00010.png | Bin 367 -> 370 bytes tests_zemu/snapshots/x-mainmenu/00004.png | Bin 367 -> 370 bytes tests_zemu/snapshots/x-mainmenu/00010.png | Bin 367 -> 370 bytes 12 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ledger.yml b/.github/workflows/ledger.yml index bedf8b8..f73ca36 100644 --- a/.github/workflows/ledger.yml +++ b/.github/workflows/ledger.yml @@ -3,9 +3,13 @@ name: CI on: # Triggers the workflow on push or pull request events but only for the main branch push: - branches: [ main ] + branches: + - main + - develop pull_request: - branches: [ main ] + branches: + - main + - develop # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -20,6 +24,8 @@ jobs: steps: - uses: actions/checkout@v2 + with: + submodules: true - name: Build with Clang Static Analyzer run: | diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 401ad16..a046122 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: push: pull_request: - branches: [ main ] + branches: [ main, develop ] jobs: configure: diff --git a/app/Makefile b/app/Makefile index b0fd8ee..27455da 100755 --- a/app/Makefile +++ b/app/Makefile @@ -27,8 +27,8 @@ all: bin/app.elf @echo "APPNAME=\"${APPNAME}\"" >> $(OUTPUT_INSTALLER) @echo "APPVERSION=\"${APPVERSION}\"" >> $(OUTPUT_INSTALLER) @echo "APPPATH=\""${APPPATH}"\"" >> $(OUTPUT_INSTALLER) - @echo "LOAD_PARAMS=\"${COMMON_LOAD_PARAMS}\"" >> $(OUTPUT_INSTALLER) - @echo "DELETE_PARAMS=\"${COMMON_DELETE_PARAMS}\"" >> $(OUTPUT_INSTALLER) + @echo "LOAD_PARAMS=($$(echo "${APP_LOAD_PARAMS}" | sed -e "s|"${APPNAME}"|\""${APPNAME}"\"|"))" >> $(OUTPUT_INSTALLER) + @echo "DELETE_PARAMS=($$(echo "${COMMON_DELETE_PARAMS}" | sed -e "s|"${APPNAME}"|\""${APPNAME}"\"|"))" >> $(OUTPUT_INSTALLER) @echo "APPHEX=\"" >> $(OUTPUT_INSTALLER) @cat $(CURDIR)/bin/app.hex >> $(OUTPUT_INSTALLER) @echo "\"" >> $(OUTPUT_INSTALLER) diff --git a/app/Makefile.version b/app/Makefile.version index 1869e56..468d502 100644 --- a/app/Makefile.version +++ b/app/Makefile.version @@ -3,4 +3,4 @@ APPVERSION_M=2 # This is the `spec_version` field of `Runtime` APPVERSION_N=0 # This is the patch version of this release -APPVERSION_P=1 +APPVERSION_P=2 diff --git a/app/src/apdu_handler.c b/app/src/apdu_handler.c index efd6e45..f78b7dd 100644 --- a/app/src/apdu_handler.c +++ b/app/src/apdu_handler.c @@ -47,7 +47,7 @@ __Z_INLINE void handleGetAddrSecp256K1(volatile uint32_t *flags, volatile uint32 if (requireConfirmation) { view_review_init(addr_getItem, addr_getNumItems, app_reply_address); - view_review_show(); + view_review_show(0x03); *flags |= IO_ASYNCH_REPLY; return; } @@ -80,7 +80,7 @@ __Z_INLINE void handleSignSecp256K1(volatile uint32_t *flags, volatile uint32_t CHECK_APP_CANARY() view_review_init(tx_getItem, tx_getNumItems, app_sign); - view_review_show(); + view_review_show(0x03); *flags |= IO_ASYNCH_REPLY; } diff --git a/tests_zemu/package.json b/tests_zemu/package.json index 7dbade6..fd49ee9 100644 --- a/tests_zemu/package.json +++ b/tests_zemu/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@zondax/ledger-axelar": "^0.0.1", - "@zondax/zemu": "^0.29.0" + "@zondax/zemu": "^0.32.0" }, "devDependencies": { "@types/jest": "^27.4.0", diff --git a/tests_zemu/snapshots/s-mainmenu/00004.png b/tests_zemu/snapshots/s-mainmenu/00004.png index 131ba7b5ba4dc47aa7f9317ceb0c5b89adca8e25..c475aa12b69e20ec522cfc1a5772ab07c0bde368 100644 GIT binary patch delta 421 zcmV;W0b2gL1HS{1B!7lUL_t(|ob8!G62dSDMX96rKX4ay5oHhvC8V0f;jKCiLCdEE z5g5- zlWO8PhVhl4S`i4-q>ySXZyG))?wx!B(0UzH0(Y^C5}I0c=xQzE6Cbc1HkXxrNIRjH z4ae_k>4Icam~^8FU}U#Z6M72Nf1@^RZ-fBshm7r1R`yxXx{+ogae>Eb_JFQ;!B%DSr_Ct*nzS2Xkn&|L1M)5)@> zABi5qu>rL`RzuIWb7`<_`h&Lwed!6=-!gKx!T!c++8&-HNs=T@>0000#ZH%SqW|r|t2&pD#oJF&lCKzrz<6 zSIxw2*k8_~aE*ux9VW-rGKf{lgGKnuHz1WHuS!F1Ql(m~Uw^&O(0yV*d zM+&PZ)-jB)1=X5Bm?npc!TP3=bK=>_X8`ZlF(>jWagn5{sl%Vv6rXs5^{~03^oO(y zYFRn{PscfCKeylAfwXw@g7gV=czN6X?U7)|`uvq34|i1th2)=7^`YfZENa zh#J8AzFoy4hQI8bn$}mJf(B^SY!7$|pV%=jG4=MHhKjoGNwU6_F+$$}Udx?aqK)(r z-2-9=)b_Dj&TJ>2_-HeLuLb?6KZu`Y^x1}IhX()v02u%P3-Sc{JInLW4UXpk0000< KMNUMnLSTY*pv5- zlWO8PhVhl4S`i4-q>ySXZyG))?wx!B(0UzH0(Y^C5}I0c=xQzE6Cbc1HkXxrNIRjH z4ae_k>4Icam~^8FU}U#Z6M72Nf1@^RZ-fBshm7r1R`yxXx{+ogae>Eb_JFQ;!B%DSr_Ct*nzS2Xkn&|L1M)5)@> zABi5qu>rL`RzuIWb7`<_`h&Lwed!6=-!gKx!T!c++8&-HNs=T@>0000#ZH%SqW|r|t2&pD#oJF&lCKzrz<6 zSIxw2*k8_~aE*ux9VW-rGKf{lgGKnuHz1WHuS!F1Ql(m~Uw^&O(0yV*d zM+&PZ)-jB)1=X5Bm?npc!TP3=bK=>_X8`ZlF(>jWagn5{sl%Vv6rXs5^{~03^oO(y zYFRn{PscfCKeylAfwXw@g7gV=czN6X?U7)|`uvq34|i1th2)=7^`YfZENa zh#J8AzFoy4hQI8bn$}mJf(B^SY!7$|pV%=jG4=MHhKjoGNwU6_F+$$}Udx?aqK)(r z-2-9=)b_Dj&TJ>2_-HeLuLb?6KZu`Y^x1}IhX()v02u%P3-Sc{JInLW4UXpk0000< KMNUMnLSTY*pvgTiNn>5@so?c#U1Kez?$*B$TQ5P=-kta+!E%X;5MrTwwL^5 z&RN~N`?{Iebc)&HFL6^B_062SaCT_chuNX}MgQvArs&>$=cW8^$+lMo|6g^wy?ghS zql(ij`eMn_qVt83JG?La(@4KAUwgq~`S1MY`xuU|U$*SB>6288)o4#YWB$X z@%tB-XSVtLYL|5J{l&hRZQc&9%13r@JdalwM;>STo8$idm0q=27|(o@GrM{s9b0~@ z&k2c0-2A(%gEe5snc{i2N@52#g!P{YwFzciH@z<7?&KY|<`Iwo$%Nhc&N!=Xc7)X1 l)u*g3RhV-kLV)4lLE&|KAFg;*w|5~()YH|^Wt~$(69D1PqkjMZ delta 340 zcmeyw^qy&gO1+toz21C7pmt;+_pHQ z{zq7ui2(u1maJNpbz9tj>xB0240dWupV+oYI&ue`e>!K)s%29?eY=#wH(?de(}pVV zyBlx6uDc&+Zxi6O(s)Pfbf$cL^-kQ6A+hc|D z?^P^&Sx>Icm=(11xrOc>-4``e+`r53E-di-UcP)A!}tDWOD>yyS$TW)z3M4DeluUI z5`5qF{^Ds%o|#|rFL%!RlJCZAQz-uFNb!xyz28r#$_T&NF1!2t-Pjoy|6Ve} z-*^8ApSbWx-S!`SmBkWfzqd(u(K&FS?rX$KhTlu|6YbrvcgI(rp7!!|QMkkAj``B5 ip~u&`Bl*6e{x$pFBR7RFp7%Bc1&ODtpUXO@geCxvOQMhf diff --git a/tests_zemu/snapshots/sp-mainmenu/00010.png b/tests_zemu/snapshots/sp-mainmenu/00010.png index 63db780f609cabff100fc14cdfc8d0b36af4b214..308172da5eb884ad21422b6cfb0f582372db4cf5 100644 GIT binary patch delta 343 zcmaFQ^oePLO1-70i(^Q|oVPa<`3@=Yv?ZF{Yxym|viu|aM1|Ho$JpIJ?e?E&@Z9%k zS+o}e0zBw)ad9d6eK>gTiNn>5@so?c#U1Kez?$*B$TQ5P=-kta+!E%X;5MrTwwL^5 z&RN~N`?{Iebc)&HFL6^B_062SaCT_chuNX}MgQvArs&>$=cW8^$+lMo|6g^wy?ghS zql(ij`eMn_qVt83JG?La(@4KAUwgq~`S1MY`xuU|U$*SB>6288)o4#YWB$X z@%tB-XSVtLYL|5J{l&hRZQc&9%13r@JdalwM;>STo8$idm0q=27|(o@GrM{s9b0~@ z&k2c0-2A(%gEe5snc{i2N@52#g!P{YwFzciH@z<7?&KY|<`Iwo$%Nhc&N!=Xc7)X1 l)u*g3RhV-kLV)4lLE&|KAFg;*w|5~()YH|^Wt~$(69D1PqkjMZ delta 340 zcmeyw^qy&gO1+toz21C7pmt;+_pHQ z{zq7ui2(u1maJNpbz9tj>xB0240dWupV+oYI&ue`e>!K)s%29?eY=#wH(?de(}pVV zyBlx6uDc&+Zxi6O(s)Pfbf$cL^-kQ6A+hc|D z?^P^&Sx>Icm=(11xrOc>-4``e+`r53E-di-UcP)A!}tDWOD>yyS$TW)z3M4DeluUI z5`5qF{^Ds%o|#|rFL%!RlJCZAQz-uFNb!xyz28r#$_T&NF1!2t-Pjoy|6Ve} z-*^8ApSbWx-S!`SmBkWfzqd(u(K&FS?rX$KhTlu|6YbrvcgI(rp7!!|QMkkAj``B5 ip~u&`Bl*6e{x$pFBR7RFp7%Bc1&ODtpUXO@geCxvOQMhf diff --git a/tests_zemu/snapshots/x-mainmenu/00004.png b/tests_zemu/snapshots/x-mainmenu/00004.png index 63db780f609cabff100fc14cdfc8d0b36af4b214..308172da5eb884ad21422b6cfb0f582372db4cf5 100644 GIT binary patch delta 343 zcmaFQ^oePLO1-70i(^Q|oVPa<`3@=Yv?ZF{Yxym|viu|aM1|Ho$JpIJ?e?E&@Z9%k zS+o}e0zBw)ad9d6eK>gTiNn>5@so?c#U1Kez?$*B$TQ5P=-kta+!E%X;5MrTwwL^5 z&RN~N`?{Iebc)&HFL6^B_062SaCT_chuNX}MgQvArs&>$=cW8^$+lMo|6g^wy?ghS zql(ij`eMn_qVt83JG?La(@4KAUwgq~`S1MY`xuU|U$*SB>6288)o4#YWB$X z@%tB-XSVtLYL|5J{l&hRZQc&9%13r@JdalwM;>STo8$idm0q=27|(o@GrM{s9b0~@ z&k2c0-2A(%gEe5snc{i2N@52#g!P{YwFzciH@z<7?&KY|<`Iwo$%Nhc&N!=Xc7)X1 l)u*g3RhV-kLV)4lLE&|KAFg;*w|5~()YH|^Wt~$(69D1PqkjMZ delta 340 zcmeyw^qy&gO1+toz21C7pmt;+_pHQ z{zq7ui2(u1maJNpbz9tj>xB0240dWupV+oYI&ue`e>!K)s%29?eY=#wH(?de(}pVV zyBlx6uDc&+Zxi6O(s)Pfbf$cL^-kQ6A+hc|D z?^P^&Sx>Icm=(11xrOc>-4``e+`r53E-di-UcP)A!}tDWOD>yyS$TW)z3M4DeluUI z5`5qF{^Ds%o|#|rFL%!RlJCZAQz-uFNb!xyz28r#$_T&NF1!2t-Pjoy|6Ve} z-*^8ApSbWx-S!`SmBkWfzqd(u(K&FS?rX$KhTlu|6YbrvcgI(rp7!!|QMkkAj``B5 ip~u&`Bl*6e{x$pFBR7RFp7%Bc1&ODtpUXO@geCxvOQMhf diff --git a/tests_zemu/snapshots/x-mainmenu/00010.png b/tests_zemu/snapshots/x-mainmenu/00010.png index 63db780f609cabff100fc14cdfc8d0b36af4b214..308172da5eb884ad21422b6cfb0f582372db4cf5 100644 GIT binary patch delta 343 zcmaFQ^oePLO1-70i(^Q|oVPa<`3@=Yv?ZF{Yxym|viu|aM1|Ho$JpIJ?e?E&@Z9%k zS+o}e0zBw)ad9d6eK>gTiNn>5@so?c#U1Kez?$*B$TQ5P=-kta+!E%X;5MrTwwL^5 z&RN~N`?{Iebc)&HFL6^B_062SaCT_chuNX}MgQvArs&>$=cW8^$+lMo|6g^wy?ghS zql(ij`eMn_qVt83JG?La(@4KAUwgq~`S1MY`xuU|U$*SB>6288)o4#YWB$X z@%tB-XSVtLYL|5J{l&hRZQc&9%13r@JdalwM;>STo8$idm0q=27|(o@GrM{s9b0~@ z&k2c0-2A(%gEe5snc{i2N@52#g!P{YwFzciH@z<7?&KY|<`Iwo$%Nhc&N!=Xc7)X1 l)u*g3RhV-kLV)4lLE&|KAFg;*w|5~()YH|^Wt~$(69D1PqkjMZ delta 340 zcmeyw^qy&gO1+toz21C7pmt;+_pHQ z{zq7ui2(u1maJNpbz9tj>xB0240dWupV+oYI&ue`e>!K)s%29?eY=#wH(?de(}pVV zyBlx6uDc&+Zxi6O(s)Pfbf$cL^-kQ6A+hc|D z?^P^&Sx>Icm=(11xrOc>-4``e+`r53E-di-UcP)A!}tDWOD>yyS$TW)z3M4DeluUI z5`5qF{^Ds%o|#|rFL%!RlJCZAQz-uFNb!xyz28r#$_T&NF1!2t-Pjoy|6Ve} z-*^8ApSbWx-S!`SmBkWfzqd(u(K&FS?rX$KhTlu|6YbrvcgI(rp7!!|QMkkAj``B5 ip~u&`Bl*6e{x$pFBR7RFp7%Bc1&ODtpUXO@geCxvOQMhf