mirror of
https://github.com/polhenarejos/pico-keys-sdk
synced 2026-05-29 01:21:21 +02:00
Compare commits
64 Commits
eb75ad4efa
...
v8.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
711a4df490 | ||
|
|
66f31c15b6 | ||
|
|
fa119d0c6e | ||
|
|
b67e9ac143 | ||
|
|
5d3d10b62b | ||
|
|
27938f0d9b | ||
|
|
20117d1609 | ||
|
|
8f4f5373cf | ||
|
|
d4971bba19 | ||
|
|
2001006a16 | ||
|
|
7c5f729b69 | ||
|
|
07bbadf34c | ||
|
|
ed848d005f | ||
|
|
e6c0227996 | ||
|
|
84f7952817 | ||
|
|
116aca7697 | ||
|
|
d410a4cfc2 | ||
|
|
9b6d6f6736 | ||
|
|
8f907b25ba | ||
|
|
233e6594c6 | ||
|
|
eca6807f8e | ||
|
|
14d5a75571 | ||
|
|
e56624948b | ||
|
|
200d59f91b | ||
|
|
c165ae4838 | ||
|
|
0ddfdf8134 | ||
|
|
031d76737b | ||
|
|
df94d10f8f | ||
|
|
b3b2b67034 | ||
|
|
3eff2442c6 | ||
|
|
a7e1cf028b | ||
|
|
e14a12b002 | ||
|
|
d39732c613 | ||
|
|
56c2ef0cc1 | ||
|
|
9b294b9685 | ||
|
|
5048e07f81 | ||
|
|
d63ed56e0e | ||
|
|
afe2b28fab | ||
|
|
838f342877 | ||
|
|
1a1d03ab2f | ||
|
|
809dc3d16d | ||
|
|
70c0c1bf81 | ||
|
|
cff3f8f677 | ||
|
|
6f6004c57b | ||
|
|
0b49fe4e1b | ||
|
|
4edc506759 | ||
|
|
e55014cfb3 | ||
|
|
2211fafe32 | ||
|
|
276f1b2ae8 | ||
|
|
202d32d13d | ||
|
|
95f02b6ea7 | ||
|
|
2e2b78445c | ||
|
|
da44fd21d4 | ||
|
|
365567d12b | ||
|
|
a3406572cd | ||
|
|
8321db1f67 | ||
|
|
5984d1f72d | ||
|
|
685e660ec0 | ||
|
|
3863842536 | ||
|
|
113e720fca | ||
|
|
c45c97ee1f | ||
|
|
d66d1c85b9 | ||
|
|
f01aca5518 | ||
|
|
da3a7f25d0 |
141
LICENSE
141
LICENSE
@@ -1,5 +1,5 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
@@ -7,17 +7,15 @@
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
@@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
@@ -72,7 +60,7 @@ modification follow.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
@@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
@@ -635,40 +633,29 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
||||
@@ -41,7 +41,7 @@ macro(SET_VERSION MAJOR MINOR FILE)
|
||||
HEX2DEC(ver_major ${ver_major})
|
||||
HEX2DEC(ver_minor ${ver_minor})
|
||||
message(STATUS "Found version:\t\t ${ver_major}.${ver_minor}")
|
||||
if(NOT ENABLE_EMULATION AND NOT ESP_PLATFORM)
|
||||
if(PICO_PLATFORM)
|
||||
pico_set_binary_version(${CMAKE_PROJECT_NAME} MAJOR ${ver_major} MINOR ${ver_minor})
|
||||
endif()
|
||||
SET(${MAJOR} ${ver_major})
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SHA256_ALT_H_
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
{
|
||||
"name": "Pico Keys Data",
|
||||
"id": 1,
|
||||
"start": "2048K",
|
||||
"size": "2048K",
|
||||
"start": "1024K",
|
||||
"size": "3072K",
|
||||
"families": ["data"],
|
||||
"permissions": {
|
||||
"secure": "rw",
|
||||
"nonsecure": "rw",
|
||||
"bootloader": "rw"
|
||||
"nonsecure": "",
|
||||
"bootloader": "r"
|
||||
},
|
||||
"link": ["owner", 0],
|
||||
"ignored_during_arm_boot": true,
|
||||
|
||||
@@ -124,7 +124,7 @@ if(NOT ESP_PLATFORM)
|
||||
add_definitions(-DMBEDTLS_ECP_DP_ED25519_ENABLED=1 -DMBEDTLS_ECP_DP_ED448_ENABLED=1 -DMBEDTLS_EDDSA_C=1 -DMBEDTLS_SHA3_C=1)
|
||||
else()
|
||||
set(MBEDTLS_ORIGIN "https://github.com/Mbed-TLS/mbedtls.git")
|
||||
set(MBEDTLS_REF "v3.6.3")
|
||||
set(MBEDTLS_REF "v3.6.5")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
@@ -237,7 +237,7 @@ if (ENABLE_EDDSA)
|
||||
)
|
||||
endif()
|
||||
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/file.c
|
||||
@@ -253,14 +253,19 @@ set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/apdu.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/rescue.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_cyw43.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pico.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pimoroni.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_ws2812.c
|
||||
)
|
||||
|
||||
if(ESP_PLATFORM)
|
||||
set(SOURCES ${SOURCES} ${CMAKE_CURRENT_LIST_DIR}/src/led/led_neopixel.c)
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/src/led/led_neopixel.c)
|
||||
else()
|
||||
if (NOT ENABLE_EMULATION)
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_cyw43.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pico.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_pimoroni.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led_ws2812.c
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
## mbedTLS reports an stringop overflow for cmac.c
|
||||
@@ -314,7 +319,7 @@ set(LIBRARIES
|
||||
)
|
||||
|
||||
set(IS_CYW43 0)
|
||||
if (NOT ENABLE_EMULATION AND NOT ESP_PLATFORM)
|
||||
if (PICO_PLATFORM)
|
||||
file(READ ${PICO_SDK_PATH}/src/boards/include/boards/${PICO_BOARD}.h content)
|
||||
string(REGEX MATCHALL "CYW43_WL_GPIO_LED_PIN" _ ${content})
|
||||
if (CMAKE_MATCH_0)
|
||||
@@ -331,7 +336,7 @@ function(add_impl_library target)
|
||||
endfunction()
|
||||
|
||||
if(USB_ITF_HID)
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/hid/hid.c
|
||||
)
|
||||
set(INCLUDES ${INCLUDES}
|
||||
@@ -340,7 +345,7 @@ if(USB_ITF_HID)
|
||||
endif()
|
||||
|
||||
if(USB_ITF_CCID)
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid/ccid.c
|
||||
)
|
||||
set(INCLUDES ${INCLUDES}
|
||||
@@ -348,18 +353,20 @@ if(USB_ITF_CCID)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT MSVC)
|
||||
add_definitions("-fmacro-prefix-map=${CMAKE_CURRENT_LIST_DIR}/=")
|
||||
|
||||
endif()
|
||||
if(MSVC)
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/mman.c
|
||||
)
|
||||
endif()
|
||||
if(ENABLE_EMULATION)
|
||||
if(APPLE)
|
||||
add_definitions("-Wno-deprecated-declarations")
|
||||
elseif(MSVC)
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/mman.c
|
||||
)
|
||||
endif()
|
||||
add_definitions(-DENABLE_EMULATION)
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation/emulation.c
|
||||
)
|
||||
set(MBEDTLS_SOURCES ${MBEDTLS_SOURCES}
|
||||
@@ -369,7 +376,7 @@ if(ENABLE_EMULATION)
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation
|
||||
)
|
||||
else()
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/usb/usb_descriptors.c
|
||||
)
|
||||
endif()
|
||||
@@ -380,7 +387,7 @@ endif()
|
||||
if(MSVC)
|
||||
set(
|
||||
CMAKE_C_FLAGS
|
||||
"${CMAKE_C_FLAGS} -wd4820 -wd4255 -wd5045 -wd4706 -wd4061 -wd5105"
|
||||
"${CMAKE_C_FLAGS} -wd4820 -wd4255 -wd5045 -wd4706 -wd4061 -wd5105 -wd4141 -wd4200"
|
||||
)
|
||||
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS
|
||||
@@ -392,13 +399,18 @@ if(MSVC)
|
||||
_WIN32_WINNT_WIN10_RS4=0
|
||||
_WIN32_WINNT_WIN10_RS5=0
|
||||
_STRALIGN_USE_SECURE_CRT=0
|
||||
NTDDI_WIN10_CU=0)
|
||||
NTDDI_WIN11_DT=0)
|
||||
set_source_files_properties(
|
||||
${EXTERNAL_SOURCES}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS " -W3 -wd4242 -wd4065"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(PICO_PLATFORM)
|
||||
pico_sdk_init()
|
||||
endif()
|
||||
|
||||
if(PICO_RP2350)
|
||||
pico_set_uf2_family(${CMAKE_PROJECT_NAME} "rp2350-arm-s")
|
||||
pico_embed_pt_in_binary(${CMAKE_PROJECT_NAME} "${CMAKE_CURRENT_LIST_DIR}/config/rp2350/pt.json")
|
||||
@@ -415,22 +427,23 @@ if(PICO_RP2350)
|
||||
set(INCLUDES ${INCLUDES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/config/rp2350/alt
|
||||
)
|
||||
set(SOURCES ${SOURCES}
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/config/rp2350/alt/sha256_alt.c
|
||||
)
|
||||
set(LIBRARIES ${LIBRARIES} pico_sha256)
|
||||
endif()
|
||||
set(INTERNAL_SOURCES ${SOURCES})
|
||||
set(SOURCES ${SOURCES} ${EXTERNAL_SOURCES})
|
||||
set(INTERNAL_SOURCES ${PICO_KEYS_SOURCES})
|
||||
set(PICO_KEYS_SOURCES ${PICO_KEYS_SOURCES} ${EXTERNAL_SOURCES})
|
||||
|
||||
if(NOT TARGET pico_keys_sdk)
|
||||
if(ENABLE_EMULATION OR ESP_PLATFORM)
|
||||
add_impl_library(pico_keys_sdk)
|
||||
else()
|
||||
if(PICO_PLATFORM)
|
||||
pico_add_library(pico_keys_sdk)
|
||||
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${LIBRARIES})
|
||||
else()
|
||||
add_impl_library(pico_keys_sdk)
|
||||
endif()
|
||||
target_sources(pico_keys_sdk INTERFACE ${SOURCES})
|
||||
target_sources(pico_keys_sdk INTERFACE ${PICO_KEYS_SOURCES})
|
||||
target_include_directories(pico_keys_sdk INTERFACE ${INCLUDES})
|
||||
target_link_libraries(pico_keys_sdk INTERFACE ${LIBRARIES})
|
||||
endif()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
idf_component_register(
|
||||
SRCS ${INTERNAL_SOURCES}
|
||||
INCLUDE_DIRS . fs rng usb led ../mbedtls/include ../tinycbor/src
|
||||
REQUIRES bootloader_support esp_partition esp_tinyusb efuse
|
||||
SRCS ${PICO_KEYS_SOURCES}
|
||||
INCLUDE_DIRS . fs rng usb led ../tinycbor/src
|
||||
REQUIRES bootloader_support esp_partition esp_tinyusb efuse mbedtls
|
||||
)
|
||||
|
||||
32
src/apdu.c
32
src/apdu.c
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "apdu.h"
|
||||
@@ -113,21 +113,22 @@ uint16_t apdu_process(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size)
|
||||
}
|
||||
}
|
||||
}
|
||||
//printf("apdu.nc %ld, apdu.ne %ld\n",apdu.nc,apdu.ne);
|
||||
//printf("apdu.nc %u, apdu.ne %u\n",apdu.nc,apdu.ne);
|
||||
if (apdu.header[1] == 0xc0) {
|
||||
//printf("apdu.ne %u, apdu.rlen %d, bk %x\n",apdu.ne,apdu.rlen,rdata_bk);
|
||||
timeout_stop();
|
||||
*(uint16_t *) rdata_gr = rdata_bk;
|
||||
rdata_gr[0] = rdata_bk >> 8;
|
||||
rdata_gr[1] = rdata_bk & 0xff;
|
||||
if (apdu.rlen <= apdu.ne) {
|
||||
#ifndef ENABLE_EMULATION
|
||||
#ifdef USB_ITF_HID
|
||||
if (itf == ITF_HID_CTAP) {
|
||||
driver_exec_finished_cont_hid(itf, apdu.rlen + 2, rdata_gr - apdu.rdata);
|
||||
driver_exec_finished_cont_hid(itf, apdu.rlen + 2, (uint16_t)(rdata_gr - apdu.rdata));
|
||||
}
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
if (itf == ITF_SC_CCID || itf == ITF_SC_WCID) {
|
||||
driver_exec_finished_cont_ccid(itf, apdu.rlen + 2, rdata_gr - apdu.rdata);
|
||||
driver_exec_finished_cont_ccid(itf, apdu.rlen + 2, (uint16_t)(rdata_gr - apdu.rdata));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
@@ -140,7 +141,7 @@ uint16_t apdu_process(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size)
|
||||
}
|
||||
else {
|
||||
rdata_gr += apdu.ne;
|
||||
rdata_bk = *(uint16_t *) rdata_gr;
|
||||
rdata_bk = (rdata_gr[0] << 8) | rdata_gr[1];
|
||||
rdata_gr[0] = 0x61;
|
||||
if (apdu.rlen - apdu.ne >= 256) {
|
||||
rdata_gr[1] = 0;
|
||||
@@ -151,12 +152,12 @@ uint16_t apdu_process(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size)
|
||||
#ifndef ENABLE_EMULATION
|
||||
#ifdef USB_ITF_HID
|
||||
if (itf == ITF_HID_CTAP) {
|
||||
driver_exec_finished_cont_hid(itf, apdu.ne + 2, rdata_gr - apdu.ne - apdu.rdata);
|
||||
driver_exec_finished_cont_hid(itf, (uint16_t)(apdu.ne + 2), (uint16_t)(rdata_gr - apdu.ne - apdu.rdata));
|
||||
}
|
||||
#endif
|
||||
#ifdef USB_ITF_CCID
|
||||
if (itf == ITF_SC_CCID || itf == ITF_SC_WCID) {
|
||||
driver_exec_finished_cont_ccid(itf, apdu.ne + 2, rdata_gr - apdu.ne - apdu.rdata);
|
||||
driver_exec_finished_cont_ccid(itf, (uint16_t)(apdu.ne + 2), (uint16_t)(rdata_gr - apdu.ne - apdu.rdata));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
@@ -182,7 +183,8 @@ uint16_t set_res_sw(uint8_t sw1, uint8_t sw2) {
|
||||
return make_uint16_t_be(sw1, sw2);
|
||||
}
|
||||
|
||||
void apdu_thread(void) {
|
||||
void *apdu_thread(void *arg) {
|
||||
(void)arg;
|
||||
card_init_core1();
|
||||
while (1) {
|
||||
uint32_t m = 0;
|
||||
@@ -215,9 +217,7 @@ done: ;
|
||||
current_app->unload();
|
||||
current_app = NULL;
|
||||
}
|
||||
#ifdef ESP_PLATFORM
|
||||
vTaskDelete(NULL);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void apdu_finish() {
|
||||
@@ -238,7 +238,7 @@ uint16_t apdu_next() {
|
||||
}
|
||||
else {
|
||||
rdata_gr = apdu.rdata + apdu.ne;
|
||||
rdata_bk = *(uint16_t *) rdata_gr;
|
||||
rdata_bk = (rdata_gr[0] << 8) | rdata_gr[1];
|
||||
rdata_gr[0] = 0x61;
|
||||
if (apdu.rlen - apdu.ne >= 256) {
|
||||
rdata_gr[1] = 0;
|
||||
|
||||
15
src/apdu.h
15
src/apdu.h
@@ -3,28 +3,29 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _APDU_H_
|
||||
#define _APDU_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
||||
#if defined(PICO_PLATFORM)
|
||||
#include "pico/stdlib.h"
|
||||
#endif
|
||||
#include "compat.h"
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct app {
|
||||
const uint8_t *aid;
|
||||
@@ -43,7 +44,7 @@ typedef struct cmd {
|
||||
} cmd_t;
|
||||
|
||||
extern uint8_t num_apps;
|
||||
extern app_t apps[8];
|
||||
extern app_t apps[16];
|
||||
extern app_t *current_app;
|
||||
|
||||
PACK(struct apdu {
|
||||
@@ -72,6 +73,6 @@ extern int process_apdu();
|
||||
extern uint16_t apdu_process(uint8_t, const uint8_t *buffer, uint16_t buffer_size);
|
||||
extern void apdu_finish();
|
||||
extern uint16_t apdu_next();
|
||||
extern void apdu_thread();
|
||||
extern void *apdu_thread(void *);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
|
||||
10
src/asn1.h
10
src/asn1.h
@@ -3,23 +3,23 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ASN1_H_
|
||||
#define _ASN1_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
||||
#if defined(PICO_PLATFORM)
|
||||
#include "pico/stdlib.h"
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
||||
35
src/board.h
Normal file
35
src/board.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
struct timezone;
|
||||
extern int gettimeofday(struct timeval *tp, struct timezone *tzp);
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
static inline uint32_t board_millis() {
|
||||
struct timeval start;
|
||||
gettimeofday(&start, NULL);
|
||||
return start.tv_sec * 1000 + start.tv_usec / 1000;
|
||||
}
|
||||
|
||||
#endif // _BOARD_H_
|
||||
27
src/compat.h
27
src/compat.h
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _COMPAT_H_
|
||||
@@ -47,4 +47,23 @@
|
||||
static void f(void)
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef HAVE_STRLCPY
|
||||
static inline size_t strlcpy(char *dst, const char *src, size_t size)
|
||||
{
|
||||
size_t srclen = strlen(src);
|
||||
|
||||
if (size != 0) {
|
||||
size_t copylen = (srclen >= size) ? size - 1 : srclen;
|
||||
memcpy(dst, src, copylen);
|
||||
dst[copylen] = '\0';
|
||||
}
|
||||
|
||||
return srclen;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // _COMPAT_H
|
||||
|
||||
@@ -3,39 +3,145 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(ENABLE_EMULATION)
|
||||
#elif defined(ESP_PLATFORM)
|
||||
#if defined(ESP_PLATFORM)
|
||||
#include "esp_compat.h"
|
||||
#else
|
||||
#elif defined(PICO_PLATFORM)
|
||||
#include <pico/unique_id.h>
|
||||
#endif
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/hkdf.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "crypto_utils.h"
|
||||
#include "pico_keys.h"
|
||||
#include "otp.h"
|
||||
#include "random.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int ct_memcmp(const void *a, const void *b, size_t n) {
|
||||
const volatile uint8_t *x = (const volatile uint8_t *)a;
|
||||
const volatile uint8_t *y = (const volatile uint8_t *)b;
|
||||
uint8_t r = 0;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
r |= x[i] ^ y[i];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static const mbedtls_md_info_t *SHA256(void) {
|
||||
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||
}
|
||||
|
||||
void derive_kbase(uint8_t kbase[32]) {
|
||||
const uint8_t nootp_salt[] = "NO-OTP";
|
||||
if (otp_key_1) {
|
||||
mbedtls_hkdf(SHA256(), pico_serial_hash, sizeof(pico_serial_hash), otp_key_1, 32, (const uint8_t *)"DEVICE/ROOT", 12, kbase, 32);
|
||||
}
|
||||
else {
|
||||
mbedtls_hkdf(SHA256(), nootp_salt, sizeof(nootp_salt)-1, pico_serial_hash, sizeof(pico_serial_hash), (const uint8_t *)"DEVICE/ROOT", 12, kbase, 32);
|
||||
}
|
||||
}
|
||||
|
||||
void derive_kver(const uint8_t *pin, size_t pin_len, uint8_t kver[32]) {
|
||||
uint8_t kbase[32];
|
||||
derive_kbase(kbase);
|
||||
mbedtls_md_hmac(SHA256(), kbase, 32, pin, pin_len, kver);
|
||||
mbedtls_platform_zeroize(kbase, sizeof(kbase));
|
||||
}
|
||||
|
||||
void pin_derive_verifier(const uint8_t *pin, size_t pin_len, uint8_t verifier[32]) {
|
||||
uint8_t kver[32];
|
||||
derive_kver(pin, pin_len, kver);
|
||||
mbedtls_hkdf(SHA256(), pico_serial_hash, sizeof(pico_serial_hash), kver, 32, (const uint8_t *)"PIN/VERIFY", 10, verifier, 32);
|
||||
mbedtls_platform_zeroize(kver, sizeof(kver));
|
||||
}
|
||||
|
||||
void pin_derive_session(const uint8_t *pin, size_t pin_len, uint8_t pin_token[32]) {
|
||||
uint8_t kver[32];
|
||||
derive_kver(pin, pin_len, kver);
|
||||
mbedtls_hkdf(SHA256(), pico_serial_hash, sizeof(pico_serial_hash), kver, 32, (const uint8_t *)"PIN/TOKEN", 9, pin_token, 32);
|
||||
mbedtls_platform_zeroize(kver, sizeof(kver));
|
||||
}
|
||||
|
||||
void pin_derive_kenc(const uint8_t pin_token[32], uint8_t kenc[32]) {
|
||||
mbedtls_hkdf(SHA256(), pico_serial_hash, sizeof(pico_serial_hash), pin_token, 32, (const uint8_t *)"PIN/ENC", 7, kenc, 32);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Encrypt 32-byte device key using AES-256-GCM
|
||||
// Output: [nonce|ciphertext|tag] = 12 + in_len + 16 = 60 bytes
|
||||
// ------------------------------------------------------------------
|
||||
int encrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t *out_buf) {
|
||||
uint8_t *nonce = out_buf;
|
||||
uint8_t *ct = out_buf + 12;
|
||||
uint8_t *tag = out_buf + 12 + in_len;
|
||||
|
||||
random_gen(NULL, nonce, 12);
|
||||
|
||||
mbedtls_gcm_context gcm;
|
||||
mbedtls_gcm_init(&gcm);
|
||||
uint8_t kenc[32];
|
||||
pin_derive_kenc(key, kenc);
|
||||
int rc = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, kenc, 256);
|
||||
mbedtls_platform_zeroize(kenc, sizeof(kenc));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, in_len, nonce, 12, pico_serial_hash, sizeof(pico_serial_hash), in_buf, ct, 16, tag);
|
||||
mbedtls_gcm_free(&gcm);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Decrypt & verify 32-byte device key using AES-256-GCM
|
||||
// Input: [nonce|ciphertext|tag] = in_len bytes
|
||||
// Output: decrypted = in_len - 12 - 16 bytes
|
||||
// ------------------------------------------------------------------
|
||||
int decrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t *out_buf) {
|
||||
const uint8_t *nonce = in_buf;
|
||||
const uint8_t *ct = in_buf + 12;
|
||||
const uint8_t *tag = in_buf + in_len - 16;
|
||||
|
||||
mbedtls_gcm_context gcm;
|
||||
mbedtls_gcm_init(&gcm);
|
||||
uint8_t kenc[32];
|
||||
pin_derive_kenc(key, kenc);
|
||||
int rc = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, kenc, 256);
|
||||
mbedtls_platform_zeroize(kenc, sizeof(kenc));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = mbedtls_gcm_auth_decrypt(&gcm, in_len - 16 - 12, nonce, 12, pico_serial_hash, sizeof(pico_serial_hash), tag, 16, ct, out_buf);
|
||||
mbedtls_gcm_free(&gcm);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Old functions, kept for compatibility. NOT SECURE, use the new ones above.
|
||||
void double_hash_pin(const uint8_t *pin, uint16_t len, uint8_t output[32]) {
|
||||
uint8_t o1[32];
|
||||
hash_multi(pin, len, o1);
|
||||
for (int i = 0; i < sizeof(o1); i++) {
|
||||
for (size_t i = 0; i < sizeof(o1); i++) {
|
||||
o1[i] ^= pin[i % len];
|
||||
}
|
||||
hash_multi(o1, sizeof(o1), output);
|
||||
}
|
||||
|
||||
|
||||
void hash_multi(const uint8_t *input, uint16_t len, uint8_t output[32]) {
|
||||
mbedtls_sha256_context ctx;
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_UTILS_H_
|
||||
@@ -38,6 +38,15 @@
|
||||
|
||||
#define IV_SIZE 16
|
||||
|
||||
extern int ct_memcmp(const void *a, const void *b, size_t n);
|
||||
// Newer and safe functions
|
||||
extern void derive_kbase(uint8_t kbase[32]);
|
||||
extern void derive_kver(const uint8_t *pin, size_t pin_len, uint8_t kver[32]);
|
||||
extern void pin_derive_kenc(const uint8_t pin_token[32], uint8_t kenc[32]);
|
||||
extern void pin_derive_session(const uint8_t *pin, size_t pin_len, uint8_t pin_token[32]);
|
||||
extern void pin_derive_verifier(const uint8_t *pin, size_t pin_len, uint8_t verifier[32]);
|
||||
extern int encrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t *out_buf);
|
||||
extern int decrypt_with_aad(const uint8_t key[32], const uint8_t *in_buf, size_t in_len, uint8_t *out_buf);
|
||||
extern void double_hash_pin(const uint8_t *pin, uint16_t len, uint8_t output[32]);
|
||||
extern void hash_multi(const uint8_t *input, uint16_t len, uint8_t output[32]);
|
||||
extern void hash256(const uint8_t *input, size_t len, uint8_t output[32]);
|
||||
|
||||
26
src/debug.h
26
src/debug.h
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DEBUG_H_
|
||||
@@ -20,16 +20,16 @@
|
||||
|
||||
#if defined(DEBUG_APDU) && DEBUG_APDU == 1
|
||||
#define DEBUG_PAYLOAD(_p, _s) { \
|
||||
printf("Payload %s (%d bytes) [%s:%d]:\n", #_p, (int) (_s), __FILE__, __LINE__); \
|
||||
for (int _i = 0; _i < _s; _i += 16) { \
|
||||
printf("Payload %s (%zu bytes) [%s:%d]:\n", #_p, (size_t)(_s), __FILE__, __LINE__); \
|
||||
for (size_t _i = 0; _i < (size_t)(_s); _i += 16) { \
|
||||
printf("%" PRIxPTR "h : ", (uintptr_t) (_i + _p)); \
|
||||
for (int _j = 0; _j < 16; _j++) { \
|
||||
if (_j < _s - _i) printf("%02X ", (_p)[_i + _j]); \
|
||||
for (size_t _j = 0; _j < 16; _j++) { \
|
||||
if (_j < (size_t)(_s) - _i) printf("%02X ", (_p)[_i + _j]); \
|
||||
else printf(" "); \
|
||||
if (_j == 7) printf(" "); \
|
||||
} printf(": "); \
|
||||
for (int _j = 0; _j < 16; _j++) { \
|
||||
if (_j < _s - _i && (_p)[_i + _j] > 32 && (_p)[_i + _j] != 127 && (_p)[_i + _j] < 176) printf("%c", (_p)[_i + _j]); \
|
||||
for (size_t _j = 0; _j < 16; _j++) { \
|
||||
if (_j < (size_t)(_s) - _i && (_p)[_i + _j] > 32 && (_p)[_i + _j] != 127 && (_p)[_i + _j] < 176) printf("%c", (_p)[_i + _j]); \
|
||||
else printf(" "); \
|
||||
if (_j == 7) printf(" "); \
|
||||
} \
|
||||
@@ -37,9 +37,9 @@
|
||||
} printf("\n"); \
|
||||
}
|
||||
#define DEBUG_DATA(_p, _s) { \
|
||||
printf("Data %s (%d bytes) [%s:%d]:\n", #_p, (int) (_s), __FILE__, __LINE__); \
|
||||
char *_tmp = (char *) calloc(1, 2 * _s + 1); \
|
||||
for (int _i = 0; _i < _s; _i++) { \
|
||||
printf("Data %s (%zu bytes) [%s:%d]:\n", #_p, (size_t)(_s), __FILE__, __LINE__); \
|
||||
char *_tmp = (char *) calloc(2 * (_s) + 1, sizeof(char)); \
|
||||
for (size_t _i = 0; _i < (size_t)(_s); _i++) { \
|
||||
sprintf(&_tmp[2 * _i], "%02X", (_p)[_i]); \
|
||||
} \
|
||||
printf("%s\n", _tmp); \
|
||||
|
||||
10
src/eac.c
10
src/eac.c
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "eac.h"
|
||||
@@ -237,7 +237,7 @@ int sm_verify() {
|
||||
uint16_t input_len = 0;
|
||||
int r = 0;
|
||||
bool add_header = (CLA(apdu) & 0xC) == 0xC;
|
||||
int data_len = (int) (apdu.nc / sm_blocksize) * sm_blocksize;
|
||||
size_t data_len = (size_t)(apdu.nc / sm_blocksize) * sm_blocksize;
|
||||
if (data_len % sm_blocksize) {
|
||||
data_len += sm_blocksize;
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _EAC_H_
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ESP_COMPAT_H_
|
||||
@@ -37,7 +37,12 @@ extern TaskHandle_t hcore0, hcore1;
|
||||
#define ESP32_CORE0 tskNO_AFFINITY
|
||||
#define ESP32_CORE1 tskNO_AFFINITY
|
||||
#endif
|
||||
#define multicore_launch_core1(a) xTaskCreatePinnedToCore((void(*)(void *))a, "core1", 4096*ITF_TOTAL*2, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 2, &hcore1, ESP32_CORE1)
|
||||
static inline void task_wrapper(void *arg) {
|
||||
void* (*func)(void*) = (void* (*)(void*))arg;
|
||||
func(NULL);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
#define multicore_launch_func_core1(func) xTaskCreatePinnedToCore(task_wrapper, "core1", 4096*ITF_TOTAL*2, (void *)func, CONFIG_TINYUSB_TASK_PRIORITY - 2, &hcore1, ESP32_CORE1)
|
||||
#define multicore_reset_core1() do { if (hcore1) { eTaskState e = eTaskGetState(hcore1); if (e <= eSuspended) { vTaskDelete(hcore1); }} }while(0)
|
||||
#define sleep_ms(a) vTaskDelay(a / portTICK_PERIOD_MS)
|
||||
static inline uint32_t board_millis(void) {
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "file.h"
|
||||
@@ -282,7 +282,7 @@ void scan_region(bool persistent)
|
||||
void wait_flash_finish();
|
||||
void scan_flash() {
|
||||
initialize_flash(false); //soft initialization
|
||||
uint32_t r1 = *(uintptr_t *) flash_read(end_rom_pool), r2 = *(uintptr_t *) flash_read(end_rom_pool + sizeof(uintptr_t));
|
||||
uint32_t r1 = (uint32_t)(*(uintptr_t *) flash_read(end_rom_pool)), r2 = (uint32_t)(*(uintptr_t *) flash_read(end_rom_pool + sizeof(uintptr_t)));
|
||||
if ((r1 == 0xffffffff || r1 == 0xefefefef) && (r2 == 0xffffffff || r2 == 0xefefefef)) {
|
||||
printf("First initialization (or corrupted!)\n");
|
||||
uint8_t empty[sizeof(uintptr_t) * 2 + sizeof(uint32_t)];
|
||||
|
||||
@@ -3,23 +3,23 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _FILE_H_
|
||||
#define _FILE_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
||||
#if defined(PICO_PLATFORM)
|
||||
#include "pico/stdlib.h"
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
@@ -71,6 +71,9 @@
|
||||
|
||||
#define MAX_DYNAMIC_FILES 256
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__pragma( pack(push, 1) )
|
||||
#endif
|
||||
typedef struct file {
|
||||
const uint8_t *name;
|
||||
uint8_t *data; //should include 2 bytes len at begining
|
||||
@@ -82,7 +85,13 @@ typedef struct file {
|
||||
#ifdef ENABLE_EMULATION
|
||||
uint32_t _padding;
|
||||
#endif
|
||||
} __attribute__ ((packed)) file_t;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
__pragma( pack(pop) )
|
||||
#else
|
||||
__attribute__ ((packed))
|
||||
#endif
|
||||
file_t;
|
||||
|
||||
extern bool file_has_data(file_t *);
|
||||
|
||||
|
||||
@@ -3,35 +3,36 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "pico_keys.h"
|
||||
|
||||
#if defined(ENABLE_EMULATION) || defined(ESP_PLATFORM)
|
||||
#if !defined(PICO_PLATFORM)
|
||||
#define XIP_BASE 0
|
||||
#define FLASH_SECTOR_SIZE 4096
|
||||
#ifdef ESP_PLATFORM
|
||||
uint32_t PICO_FLASH_SIZE_BYTES = (1 * 1024 * 1024);
|
||||
uint32_t FLASH_SIZE_BYTES = (1 * 1024 * 1024);
|
||||
#else
|
||||
#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024)
|
||||
#define FLASH_SIZE_BYTES (8 * 1024 * 1024)
|
||||
#endif
|
||||
#else
|
||||
uint32_t FLASH_SIZE_BYTES = (2 * 1024 * 1024);
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/flash.h"
|
||||
#endif
|
||||
#include "pico_keys.h"
|
||||
#include "file.h"
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -194,15 +195,15 @@ int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len) {
|
||||
}
|
||||
|
||||
uint32_t flash_free_space() {
|
||||
return last_base - start_data_pool;
|
||||
return (uint32_t)(last_base - start_data_pool);
|
||||
}
|
||||
|
||||
uint32_t flash_used_space() {
|
||||
return end_data_pool - last_base;
|
||||
return (uint32_t)(end_data_pool - last_base);
|
||||
}
|
||||
|
||||
uint32_t flash_total_space() {
|
||||
return end_data_pool - start_data_pool;
|
||||
return (uint32_t)(end_data_pool - start_data_pool);
|
||||
}
|
||||
|
||||
uint32_t flash_num_files() {
|
||||
@@ -210,5 +211,5 @@ uint32_t flash_num_files() {
|
||||
}
|
||||
|
||||
uint32_t flash_size() {
|
||||
return PICO_FLASH_SIZE_BYTES;
|
||||
return FLASH_SIZE_BYTES;
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -32,44 +32,45 @@
|
||||
#include "pico/bootrom.h"
|
||||
#include "boot/picobin.h"
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#define O_RDWR _O_RDWR
|
||||
#define O_CREAT _O_CREAT
|
||||
#define open _open
|
||||
#define write _write
|
||||
#define mode_t unsigned short
|
||||
#define lseek _lseek
|
||||
#include "mman.h"
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "esp_compat.h"
|
||||
#include "esp_partition.h"
|
||||
const esp_partition_t *part0;
|
||||
#define save_and_disable_interrupts() 1
|
||||
#define flash_range_erase(a,b) esp_partition_erase_range(part0, a, b)
|
||||
#define flash_range_program(a,b,c) esp_partition_write(part0, a, b, c);
|
||||
#define restore_interrupts(a) (void)a
|
||||
#else
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "esp_compat.h"
|
||||
#include "esp_partition.h"
|
||||
const esp_partition_t *part0;
|
||||
#define save_and_disable_interrupts() 1
|
||||
#define flash_range_erase(a,b) esp_partition_erase_range(part0, a, b)
|
||||
#define flash_range_program(a,b,c) esp_partition_write(part0, a, b, c);
|
||||
#define restore_interrupts(a) (void)a
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#define O_RDWR _O_RDWR
|
||||
#define O_CREAT _O_CREAT
|
||||
#define open _open
|
||||
#define write _write
|
||||
#define mode_t unsigned short
|
||||
#define lseek _lseek
|
||||
#include "mman.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include "emulation.h"
|
||||
#endif
|
||||
#include "queue.h"
|
||||
#endif
|
||||
#define FLASH_SECTOR_SIZE 4096
|
||||
#ifdef ESP_PLATFORM
|
||||
extern uint32_t PICO_FLASH_SIZE_BYTES;
|
||||
#else
|
||||
#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024)
|
||||
#endif
|
||||
#define XIP_BASE 0
|
||||
int fd_map = 0;
|
||||
uint8_t *map = NULL;
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
extern uint32_t FLASH_SIZE_BYTES;
|
||||
#else
|
||||
#define FLASH_SIZE_BYTES (8 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
#define TOTAL_FLASH_PAGES 6
|
||||
#define FLASH_LOCKOUT_RETRIES 5
|
||||
|
||||
extern void flash_set_bounds(uintptr_t start, uintptr_t end);
|
||||
|
||||
@@ -107,18 +108,16 @@ void do_flash() {
|
||||
//printf(" DO_FLASH AVAILABLE\n");
|
||||
for (int r = 0; r < TOTAL_FLASH_PAGES; r++) {
|
||||
if (flash_pages[r].ready == true) {
|
||||
#ifndef ENABLE_EMULATION
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
//printf("WRITTING %X\n",flash_pages[r].address-XIP_BASE);
|
||||
while (multicore_lockout_start_timeout_us(1000) == false) {
|
||||
;
|
||||
for (int retries = 0; retries < FLASH_LOCKOUT_RETRIES && multicore_lockout_start_timeout_us(1000) == false; retries++) {
|
||||
}
|
||||
//printf("WRITTING %X\n",flash_pages[r].address-XIP_BASE);
|
||||
uint32_t ints = save_and_disable_interrupts();
|
||||
flash_range_erase(flash_pages[r].address - XIP_BASE, FLASH_SECTOR_SIZE);
|
||||
flash_range_program(flash_pages[r].address - XIP_BASE, flash_pages[r].page, FLASH_SECTOR_SIZE);
|
||||
restore_interrupts(ints);
|
||||
while (multicore_lockout_end_timeout_us(1000) == false) {
|
||||
;
|
||||
for (int retries = 0; retries < FLASH_LOCKOUT_RETRIES && multicore_lockout_end_timeout_us(1000) == false; retries++) {
|
||||
}
|
||||
//printf("WRITEN %X !\n",flash_pages[r].address);
|
||||
#else
|
||||
@@ -128,14 +127,12 @@ void do_flash() {
|
||||
ready_pages--;
|
||||
}
|
||||
else if (flash_pages[r].erase == true) {
|
||||
#ifndef ENABLE_EMULATION
|
||||
while (multicore_lockout_start_timeout_us(1000) == false) {
|
||||
;
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
for (int retries = 0; retries < FLASH_LOCKOUT_RETRIES && multicore_lockout_start_timeout_us(1000) == false; retries++) {
|
||||
}
|
||||
//printf("WRITTING\n");
|
||||
flash_range_erase(flash_pages[r].address - XIP_BASE, flash_pages[r].page_size ? ((int) (flash_pages[r].page_size / FLASH_SECTOR_SIZE)) * FLASH_SECTOR_SIZE : FLASH_SECTOR_SIZE);
|
||||
while (multicore_lockout_end_timeout_us(1000) == false) {
|
||||
;
|
||||
for (int retries = 0; retries < FLASH_LOCKOUT_RETRIES && multicore_lockout_end_timeout_us(1000) == false; retries++) {
|
||||
}
|
||||
#else
|
||||
memset(map + flash_pages[r].address, 0, FLASH_SECTOR_SIZE);
|
||||
@@ -144,8 +141,8 @@ void do_flash() {
|
||||
ready_pages--;
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_EMULATION
|
||||
msync(map, PICO_FLASH_SIZE_BYTES, MS_SYNC);
|
||||
#if !defined(PICO_PLATFORM) && !defined(ESP_PLATFORM)
|
||||
msync(map, FLASH_SIZE_BYTES, MS_SYNC);
|
||||
#endif
|
||||
if (ready_pages != 0) {
|
||||
printf("ERROR: DO FLASH DOES NOT HAVE ZERO PAGES\n");
|
||||
@@ -169,20 +166,18 @@ void low_flash_init() {
|
||||
|
||||
uint32_t data_start_addr;
|
||||
uint32_t data_end_addr;
|
||||
#if defined(ENABLE_EMULATION)
|
||||
fd_map = open("memory.flash", O_RDWR | O_CREAT, (mode_t) 0600);
|
||||
lseek(fd_map, PICO_FLASH_SIZE_BYTES - 1, SEEK_SET);
|
||||
write(fd_map, "", 1);
|
||||
map = mmap(0, PICO_FLASH_SIZE_BYTES, PROT_READ | PROT_WRITE, MAP_SHARED, fd_map, 0);
|
||||
data_start_addr = 0;
|
||||
data_end_addr = PICO_FLASH_SIZE_BYTES;
|
||||
#elif defined(ESP_PLATFORM)
|
||||
#if defined(ESP_PLATFORM)
|
||||
part0 = esp_partition_find_first(0x40, 0x1, "part0");
|
||||
esp_partition_mmap(part0, 0, part0->size, ESP_PARTITION_MMAP_DATA, (const void **)&map, (esp_partition_mmap_handle_t *)&fd_map);
|
||||
data_start_addr = 0;
|
||||
data_end_addr = part0->size;
|
||||
PICO_FLASH_SIZE_BYTES = part0->size;
|
||||
FLASH_SIZE_BYTES = part0->size;
|
||||
#elif defined(PICO_PLATFORM)
|
||||
uint8_t txbuf[6] = {0x9f};
|
||||
uint8_t rxbuf[6] = {0};
|
||||
flash_do_cmd(txbuf, rxbuf, 4);
|
||||
|
||||
FLASH_SIZE_BYTES = (1 << rxbuf[3]);
|
||||
#ifdef PICO_RP2350
|
||||
__attribute__((aligned(4))) uint8_t workarea[4 * 1024];
|
||||
int rc = rom_load_partition_table(workarea, sizeof(workarea), false);
|
||||
@@ -194,22 +189,32 @@ void low_flash_init() {
|
||||
rc = rom_get_partition_table_info((uint32_t*)workarea, 0x8, PT_INFO_PARTITION_LOCATION_AND_FLAGS | PT_INFO_SINGLE_PARTITION | (boot_partition << 24));
|
||||
|
||||
if (rc != 3) {
|
||||
data_start_addr = (PICO_FLASH_SIZE_BYTES >> 1);
|
||||
data_end_addr = PICO_FLASH_SIZE_BYTES;
|
||||
data_start_addr = (FLASH_SIZE_BYTES >> 1);
|
||||
data_end_addr = FLASH_SIZE_BYTES;
|
||||
} else {
|
||||
uint16_t first_sector_number = (((uint32_t*)workarea)[1] & PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB;
|
||||
uint16_t last_sector_number = (((uint32_t*)workarea)[1] & PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB;
|
||||
data_start_addr = first_sector_number * FLASH_SECTOR_SIZE;
|
||||
data_end_addr = (last_sector_number + 1) * FLASH_SECTOR_SIZE;
|
||||
if (data_end_addr > FLASH_SIZE_BYTES) {
|
||||
data_end_addr = FLASH_SIZE_BYTES;
|
||||
}
|
||||
}
|
||||
data_end_addr -= 2 * FLASH_SECTOR_SIZE;
|
||||
#else
|
||||
data_start_addr = (PICO_FLASH_SIZE_BYTES >> 1);
|
||||
data_end_addr = PICO_FLASH_SIZE_BYTES;
|
||||
data_start_addr = (FLASH_SIZE_BYTES >> 1);
|
||||
data_end_addr = FLASH_SIZE_BYTES;
|
||||
#endif
|
||||
|
||||
data_start_addr += XIP_BASE;
|
||||
data_end_addr += XIP_BASE;
|
||||
#else
|
||||
fd_map = open("memory.flash", O_RDWR | O_CREAT, (mode_t) 0600);
|
||||
lseek(fd_map, FLASH_SIZE_BYTES - 1, SEEK_SET);
|
||||
write(fd_map, "", 1);
|
||||
map = mmap(0, FLASH_SIZE_BYTES, PROT_READ | PROT_WRITE, MAP_SHARED, fd_map, 0);
|
||||
data_start_addr = 0;
|
||||
data_end_addr = FLASH_SIZE_BYTES;
|
||||
#endif
|
||||
flash_set_bounds(data_start_addr, data_end_addr);
|
||||
}
|
||||
@@ -306,7 +311,7 @@ uint8_t *flash_read(uintptr_t addr) {
|
||||
}
|
||||
uint8_t *v = (uint8_t *) addr;
|
||||
mutex_exit(&mtx_flash);
|
||||
#if defined(ENABLE_EMULATION) || defined(ESP_PLATFORM)
|
||||
#if !defined(PICO_PLATFORM)
|
||||
if (addr >= start_data_pool && addr <= end_rom_pool + sizeof(uintptr_t)) {
|
||||
v += (uintptr_t) map;
|
||||
}
|
||||
@@ -317,7 +322,7 @@ uint8_t *flash_read(uintptr_t addr) {
|
||||
uintptr_t flash_read_uintptr(uintptr_t addr) {
|
||||
uint8_t *p = flash_read(addr);
|
||||
uintptr_t v = 0x0;
|
||||
for (int i = 0; i < sizeof(uintptr_t); i++) {
|
||||
for (size_t i = 0; i < sizeof(uintptr_t); i++) {
|
||||
v |= (uintptr_t) p[i] << (8 * i);
|
||||
}
|
||||
return v;
|
||||
@@ -325,7 +330,7 @@ uintptr_t flash_read_uintptr(uintptr_t addr) {
|
||||
uint16_t flash_read_uint16(uintptr_t addr) {
|
||||
uint8_t *p = flash_read(addr);
|
||||
uint16_t v = 0x0;
|
||||
for (int i = 0; i < sizeof(uint16_t); i++) {
|
||||
for (size_t i = 0; i < sizeof(uint16_t); i++) {
|
||||
v |= p[i] << (8 * i);
|
||||
}
|
||||
return v;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
/*
|
||||
* sys/mman.h
|
||||
* mman-win32
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _SYS_MMAN_H_
|
||||
#define _SYS_MMAN_H_
|
||||
|
||||
|
||||
171
src/fs/otp.c
171
src/fs/otp.c
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "file.h"
|
||||
@@ -27,6 +27,7 @@
|
||||
#endif
|
||||
#include "random.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include <stdalign.h>
|
||||
|
||||
#ifdef PICO_RP2350
|
||||
|
||||
@@ -39,35 +40,35 @@ static bool is_empty_buffer(const uint8_t *buffer, uint16_t buffer_len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int otp_write_data_mode(uint16_t row, uint8_t *data, uint16_t len, bool is_ecc) {
|
||||
static int otp_write_data_mode(uint16_t row, const uint8_t *data, uint16_t len, bool is_ecc) {
|
||||
otp_cmd_t cmd = { .flags = row | (is_ecc ? OTP_CMD_ECC_BITS : 0) | OTP_CMD_WRITE_BITS };
|
||||
uint32_t ret = rom_func_otp_access(data, len, cmd);
|
||||
uint32_t ret = rom_func_otp_access((uint8_t *)data, len, cmd);
|
||||
if (ret) {
|
||||
printf("OTP Write failed with error: %ld\n", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int otp_write_data(uint16_t row, uint8_t *data, uint16_t len) {
|
||||
int otp_write_data(uint16_t row, const uint8_t *data, uint16_t len) {
|
||||
return otp_write_data_mode(row, data, len, true);
|
||||
}
|
||||
|
||||
int otp_write_data_raw(uint16_t row, uint8_t *data, uint16_t len) {
|
||||
int otp_write_data_raw(uint16_t row, const uint8_t *data, uint16_t len) {
|
||||
return otp_write_data_mode(row, data, len, false);
|
||||
}
|
||||
|
||||
uint8_t* otp_buffer(uint16_t row) {
|
||||
const uint8_t* otp_buffer(uint16_t row) {
|
||||
volatile uint32_t *p = ((uint32_t *)(OTP_DATA_BASE + (row*2)));
|
||||
return (uint8_t *)p;
|
||||
return (const uint8_t *)p;
|
||||
}
|
||||
|
||||
uint8_t* otp_buffer_raw(uint16_t row) {
|
||||
const uint8_t* otp_buffer_raw(uint16_t row) {
|
||||
volatile uint32_t *p = ((uint32_t *)(OTP_DATA_RAW_BASE + (row*4)));
|
||||
return (uint8_t *)p;
|
||||
return (const uint8_t *)p;
|
||||
}
|
||||
|
||||
bool is_empty_otp_buffer(uint16_t row, uint16_t len) {
|
||||
return is_empty_buffer(otp_buffer(row), len);
|
||||
return is_empty_buffer(otp_buffer_raw(row), len * 2);
|
||||
}
|
||||
|
||||
static bool is_otp_locked_page(uint8_t page) {
|
||||
@@ -77,7 +78,7 @@ static bool is_otp_locked_page(uint8_t page) {
|
||||
|
||||
static void otp_lock_page(uint8_t page) {
|
||||
if (!is_otp_locked_page(page)) {
|
||||
uint32_t value = 0x3c3c3c;
|
||||
alignas(4) uint32_t value = 0x3c3c3c;
|
||||
otp_write_data_raw(OTP_DATA_PAGE0_LOCK0_ROW + page*2 + 1, (uint8_t *)&value, sizeof(value));
|
||||
}
|
||||
|
||||
@@ -112,7 +113,7 @@ typedef int otp_ret_t;
|
||||
#define OTP_EMTPY(ROW, LEN) is_empty_otp_buffer(ROW, LEN)
|
||||
#elif defined(ESP_PLATFORM)
|
||||
typedef esp_err_t otp_ret_t;
|
||||
#define OTP_WRITE(ROW, DATA, LEN) esp_efuse_write_key(ROW, ESP_EFUSE_KEY_PURPOSE_USER, DATA, LEN);
|
||||
#define OTP_WRITE(ROW, DATA, LEN) esp_efuse_write_key(ROW, ESP_EFUSE_KEY_PURPOSE_USER, DATA, LEN)
|
||||
#define OTP_READ(ROW, PTR) do { \
|
||||
esp_err_t ret = read_key_from_efuse(ROW, _##PTR, sizeof(_##PTR)); \
|
||||
if (ret != ESP_OK) { printf("Error reading OTP key 1 [%d]\n", ret); } \
|
||||
@@ -124,16 +125,70 @@ typedef esp_err_t otp_ret_t;
|
||||
#define SECURE_BOOT_BOOTKEY_INDEX 0
|
||||
#endif
|
||||
|
||||
bool otp_is_secure_boot_enabled(uint8_t *bootkey) {
|
||||
#ifdef PICO_RP2350
|
||||
const uint8_t *crit1 = otp_buffer(OTP_DATA_CRIT1_ROW);
|
||||
if ((crit1[0] & (1 << OTP_DATA_CRIT1_SECURE_BOOT_ENABLE_LSB)) == 0) {
|
||||
return false;
|
||||
}
|
||||
alignas(2) uint8_t BOOTKEY[] = "\xe1\xd1\x6b\xa7\x64\xab\xd7\x12\xd4\xef\x6e\x3e\xdd\x74\x4e\xd5\x63\x8c\x26\xb\x77\x1c\xf9\x81\x51\x11\xb\xaf\xac\x9b\xc8\x71";
|
||||
uint8_t bootkey_idx = 0;
|
||||
for (; bootkey_idx < 6; bootkey_idx++) {
|
||||
const uint8_t *bootkey_row = otp_buffer(OTP_DATA_BOOTKEY0_0_ROW + 0x10 * bootkey_idx);
|
||||
if (memcmp(bootkey_row, BOOTKEY, sizeof(BOOTKEY)) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bootkey_idx == 6) {
|
||||
return false;
|
||||
}
|
||||
const uint8_t *boot_flags1 = otp_buffer(OTP_DATA_BOOT_FLAGS1_ROW);
|
||||
if ((boot_flags1[0] & (1 << (bootkey_idx + OTP_DATA_BOOT_FLAGS1_KEY_VALID_LSB))) == 0) {
|
||||
return false;
|
||||
}
|
||||
if (bootkey) {
|
||||
*bootkey = bootkey_idx;
|
||||
}
|
||||
return true;
|
||||
#elif defined(ESP_PLATFORM)
|
||||
// TODO: Implement secure boot check for ESP32-S3
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool otp_is_secure_boot_locked() {
|
||||
uint8_t bootkey_idx = 0xFF;
|
||||
if (otp_is_secure_boot_enabled(&bootkey_idx) == false) {
|
||||
return false;
|
||||
}
|
||||
#ifdef PICO_RP2350
|
||||
const uint8_t *boot_flags1 = otp_buffer_raw(OTP_DATA_BOOT_FLAGS1_ROW);
|
||||
if ((boot_flags1[1] & ((OTP_DATA_BOOT_FLAGS1_KEY_INVALID_BITS >> OTP_DATA_BOOT_FLAGS1_KEY_INVALID_LSB) & (~(1 << bootkey_idx)))) != ((OTP_DATA_BOOT_FLAGS1_KEY_INVALID_BITS >> OTP_DATA_BOOT_FLAGS1_KEY_INVALID_LSB) & (~(1 << bootkey_idx)))) {
|
||||
return false;
|
||||
}
|
||||
const uint8_t *crit1 = otp_buffer_raw(OTP_DATA_CRIT1_ROW);
|
||||
if ((crit1[0] & (1 << OTP_DATA_CRIT1_DEBUG_DISABLE_LSB)) == 0
|
||||
|| (crit1[0] & (1 << OTP_DATA_CRIT1_GLITCH_DETECTOR_ENABLE_LSB)) == 0
|
||||
|| ((crit1[0] & (3 << OTP_DATA_CRIT1_GLITCH_DETECTOR_SENS_LSB)) != (3 << OTP_DATA_CRIT1_GLITCH_DETECTOR_SENS_LSB))) {
|
||||
return false;
|
||||
}
|
||||
return bootkey_idx != 0xFF;
|
||||
#elif defined(ESP_PLATFORM)
|
||||
// TODO: Implement secure boot lock check for ESP32-S3
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
int otp_enable_secure_boot(uint8_t bootkey, bool secure_lock) {
|
||||
int ret = 0;
|
||||
#ifdef PICO_RP2350
|
||||
uint8_t BOOTKEY[] = "\xe1\xd1\x6b\xa7\x64\xab\xd7\x12\xd4\xef\x6e\x3e\xdd\x74\x4e\xd5\x63\x8c\x26\xb\x77\x1c\xf9\x81\x51\x11\xb\xaf\xac\x9b\xc8\x71";
|
||||
alignas(2) uint8_t BOOTKEY[] = "\xe1\xd1\x6b\xa7\x64\xab\xd7\x12\xd4\xef\x6e\x3e\xdd\x74\x4e\xd5\x63\x8c\x26\xb\x77\x1c\xf9\x81\x51\x11\xb\xaf\xac\x9b\xc8\x71";
|
||||
if (is_empty_otp_buffer(OTP_DATA_BOOTKEY0_0_ROW + 0x10*bootkey, 32)) {
|
||||
PICOKEY_CHECK(otp_write_data(OTP_DATA_BOOTKEY0_0_ROW + 0x10*bootkey, BOOTKEY, sizeof(BOOTKEY)));
|
||||
}
|
||||
|
||||
uint8_t *boot_flags1 = otp_buffer_raw(OTP_DATA_BOOT_FLAGS1_ROW);
|
||||
uint8_t flagsb1[] = { boot_flags1[0] | (1 << (bootkey + OTP_DATA_BOOT_FLAGS1_KEY_VALID_LSB)), boot_flags1[1], boot_flags1[2], 0x00 };
|
||||
const uint8_t *boot_flags1 = otp_buffer_raw(OTP_DATA_BOOT_FLAGS1_ROW);
|
||||
alignas(4) uint8_t flagsb1[] = { boot_flags1[0] | (1 << (bootkey + OTP_DATA_BOOT_FLAGS1_KEY_VALID_LSB)), boot_flags1[1], boot_flags1[2], 0x00 };
|
||||
if (secure_lock) {
|
||||
flagsb1[1] |= ((OTP_DATA_BOOT_FLAGS1_KEY_INVALID_BITS >> OTP_DATA_BOOT_FLAGS1_KEY_INVALID_LSB) & (~(1 << bootkey)));
|
||||
}
|
||||
@@ -142,8 +197,8 @@ int otp_enable_secure_boot(uint8_t bootkey, bool secure_lock) {
|
||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_BOOT_FLAGS1_R1_ROW, flagsb1, sizeof(flagsb1)));
|
||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_BOOT_FLAGS1_R2_ROW, flagsb1, sizeof(flagsb1)));
|
||||
|
||||
uint8_t *crit1 = otp_buffer_raw(OTP_DATA_CRIT1_ROW);
|
||||
uint8_t flagsc1[] = { crit1[0] | (1 << OTP_DATA_CRIT1_SECURE_BOOT_ENABLE_LSB), crit1[1], crit1[2], 0x00 };
|
||||
const uint8_t *crit1 = otp_buffer_raw(OTP_DATA_CRIT1_ROW);
|
||||
alignas(4) uint8_t flagsc1[] = { crit1[0] | (1 << OTP_DATA_CRIT1_SECURE_BOOT_ENABLE_LSB), crit1[1], crit1[2], 0x00 };
|
||||
if (secure_lock) {
|
||||
flagsc1[0] |= (1 << OTP_DATA_CRIT1_DEBUG_DISABLE_LSB);
|
||||
flagsc1[0] |= (1 << OTP_DATA_CRIT1_GLITCH_DETECTOR_ENABLE_LSB);
|
||||
@@ -159,17 +214,20 @@ int otp_enable_secure_boot(uint8_t bootkey, bool secure_lock) {
|
||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_CRIT1_R7_ROW, flagsc1, sizeof(flagsc1)));
|
||||
|
||||
if (secure_lock) {
|
||||
uint8_t *page1 = otp_buffer_raw(OTP_DATA_PAGE1_LOCK1_ROW);
|
||||
const uint8_t *page1 = otp_buffer_raw(OTP_DATA_PAGE1_LOCK1_ROW);
|
||||
uint8_t page1v = page1[0] | (OTP_DATA_PAGE1_LOCK1_LOCK_BL_VALUE_READ_ONLY << OTP_DATA_PAGE1_LOCK1_LOCK_BL_LSB);
|
||||
uint8_t flagsp1[] = { page1v, page1v, page1v, 0x00 };
|
||||
alignas(4) uint8_t flagsp1[] = { page1v, page1v, page1v, 0x00 };
|
||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_PAGE1_LOCK1_ROW, flagsp1, sizeof(flagsp1)));
|
||||
uint8_t *page2 = otp_buffer_raw(OTP_DATA_PAGE2_LOCK1_ROW);
|
||||
const uint8_t *page2 = otp_buffer_raw(OTP_DATA_PAGE2_LOCK1_ROW);
|
||||
uint8_t page2v = page2[0] | (OTP_DATA_PAGE2_LOCK1_LOCK_BL_VALUE_READ_ONLY << OTP_DATA_PAGE2_LOCK1_LOCK_BL_LSB);
|
||||
uint8_t flagsp2[] = { page2v, page2v, page2v, 0x00 };
|
||||
alignas(4) uint8_t flagsp2[] = { page2v, page2v, page2v, 0x00 };
|
||||
PICOKEY_CHECK(otp_write_data_raw(OTP_DATA_PAGE2_LOCK1_ROW, flagsp2, sizeof(flagsp2)));
|
||||
}
|
||||
#elif defined(ESP_PLATFORM)
|
||||
// TODO: Implement secure boot for ESP32-S3
|
||||
#else
|
||||
(void)bootkey;
|
||||
(void)secure_lock;
|
||||
#endif // PICO_RP2350
|
||||
goto err;
|
||||
err:
|
||||
@@ -179,8 +237,64 @@ int otp_enable_secure_boot(uint8_t bootkey, bool secure_lock) {
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
#ifdef PICO_RP2350
|
||||
static void otp_invalidate_key(uint16_t row, uint16_t len) {
|
||||
if (!is_empty_otp_buffer(row, len)) {
|
||||
uint8_t *inval = (uint8_t *)calloc(len * 2, sizeof(uint8_t));
|
||||
if (inval) {
|
||||
memset(inval, 0xFF, len * 2);
|
||||
otp_write_data_raw(row, inval, len * 2);
|
||||
free(inval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static otp_ret_t otp_chaff(uint16_t row, uint16_t len) {
|
||||
const uint8_t *raw = otp_buffer_raw(row);
|
||||
uint8_t *chaff = (uint8_t *)calloc(len * 2, sizeof(uint8_t));
|
||||
if (chaff) {
|
||||
memcpy(chaff, raw, len * 2);
|
||||
for (int i = 0; i < len * 2; i++) {
|
||||
chaff[i] ^= 0xFF;
|
||||
}
|
||||
otp_ret_t ret = otp_write_data_raw(row + 32, chaff, len * 2);
|
||||
free(chaff);
|
||||
return ret;
|
||||
}
|
||||
return BOOTROM_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
static otp_ret_t otp_migrate_key(uint16_t new_row, uint16_t old_row, uint16_t len) {
|
||||
if (is_empty_otp_buffer(new_row, len) && !is_empty_otp_buffer(old_row, len)) {
|
||||
const uint8_t *key = otp_buffer(old_row);
|
||||
uint8_t *new_key = (uint8_t *)calloc(len, sizeof(uint8_t));
|
||||
if (new_key) {
|
||||
memcpy(new_key, key, len);
|
||||
otp_ret_t ret = otp_write_data(new_row, new_key, len);
|
||||
if (ret == BOOTROM_OK) {
|
||||
otp_chaff(new_row, len);
|
||||
otp_invalidate_key(old_row, 32);
|
||||
}
|
||||
free(new_key);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return BOOTROM_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
void otp_migrate_chaff() {
|
||||
otp_migrate_key(OTP_MKEK_ROW, OTP_OLD_MKEK_ROW, 32);
|
||||
otp_migrate_key(OTP_DEVK_ROW, OTP_OLD_DEVK_ROW, 32);
|
||||
otp_lock_page(OTP_MKEK_ROW >> 6);
|
||||
}
|
||||
#endif
|
||||
|
||||
void init_otp_files() {
|
||||
|
||||
#ifdef PICO_RP2350
|
||||
otp_migrate_chaff();
|
||||
#endif
|
||||
|
||||
#if defined(PICO_RP2350) || defined(ESP_PLATFORM)
|
||||
otp_ret_t ret = 0;
|
||||
uint16_t write_otp[2] = {0xFFFF, 0xFFFF};
|
||||
@@ -191,6 +305,9 @@ void init_otp_files() {
|
||||
if (ret != 0) {
|
||||
printf("Error writing OTP key 1 [%d]\n", ret);
|
||||
}
|
||||
#ifdef PICO_RP2350
|
||||
otp_chaff(OTP_KEY_1, 32);
|
||||
#endif
|
||||
write_otp[0] = OTP_KEY_1;
|
||||
}
|
||||
OTP_READ(OTP_KEY_1, otp_key_1);
|
||||
@@ -210,6 +327,9 @@ void init_otp_files() {
|
||||
if (ret != 0) {
|
||||
printf("Error writing OTP key 2 [%d]\n", ret);
|
||||
}
|
||||
#ifdef PICO_RP2350
|
||||
otp_chaff(OTP_KEY_2, 32);
|
||||
#endif
|
||||
write_otp[1] = OTP_KEY_2;
|
||||
}
|
||||
OTP_READ(OTP_KEY_2, otp_key_2);
|
||||
@@ -230,8 +350,7 @@ void init_otp_files() {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // PICO_RP2350 || ESP_PLATFORM
|
||||
#ifdef ENABLE_EMULATION
|
||||
#elif defined(ENABLE_EMULATION)
|
||||
static uint8_t _otp1[32] = {0}, _otp2[32] = {0};
|
||||
memset(_otp1, 0xAC, sizeof(_otp1));
|
||||
memset(_otp2, 0xBE, sizeof(_otp2));
|
||||
|
||||
25
src/fs/otp.h
25
src/fs/otp.h
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
@@ -21,17 +21,19 @@
|
||||
|
||||
#ifdef PICO_RP2350
|
||||
|
||||
#define OTP_MKEK_ROW 0xEF0
|
||||
#define OTP_DEVK_ROW 0xED0
|
||||
#define OTP_OLD_MKEK_ROW 0xEF0
|
||||
#define OTP_OLD_DEVK_ROW 0xED0
|
||||
#define OTP_MKEK_ROW 0xE90
|
||||
#define OTP_DEVK_ROW 0xE80
|
||||
|
||||
#define OTP_KEY_1 OTP_MKEK_ROW
|
||||
#define OTP_KEY_2 OTP_DEVK_ROW
|
||||
|
||||
extern uint8_t* otp_buffer(uint16_t row);
|
||||
extern uint8_t* otp_buffer_raw(uint16_t row);
|
||||
extern const uint8_t* otp_buffer(uint16_t row);
|
||||
extern const uint8_t* otp_buffer_raw(uint16_t row);
|
||||
extern bool is_empty_otp_buffer(uint16_t row, uint16_t len);
|
||||
extern int otp_write_data(uint16_t row, uint8_t *data, uint16_t len);
|
||||
extern int otp_write_data_raw(uint16_t row, uint8_t *data, uint16_t len);
|
||||
extern int otp_write_data(uint16_t row, const uint8_t *data, uint16_t len);
|
||||
extern int otp_write_data_raw(uint16_t row, const uint8_t *data, uint16_t len);
|
||||
|
||||
#elif defined(ESP_PLATFORM)
|
||||
|
||||
@@ -48,4 +50,7 @@ extern void init_otp_files();
|
||||
extern const uint8_t *otp_key_1;
|
||||
extern const uint8_t *otp_key_2;
|
||||
|
||||
extern bool otp_is_secure_boot_enabled(uint8_t *bootkey);
|
||||
extern bool otp_is_secure_boot_locked();
|
||||
|
||||
#endif // _OTP_H_
|
||||
|
||||
24
src/fs/phy.c
24
src/fs/phy.c
@@ -3,20 +3,21 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
#include "file.h"
|
||||
#include "otp.h"
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
|
||||
@@ -55,7 +56,7 @@ int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
|
||||
}
|
||||
if (phy->usb_product_present) {
|
||||
*p++ = PHY_USB_PRODUCT;
|
||||
*p++ = strlen(phy->usb_product) + 1;
|
||||
*p++ = (uint8_t)strlen(phy->usb_product) + 1;
|
||||
strcpy((char *)p, phy->usb_product);
|
||||
p += strlen(phy->usb_product);
|
||||
*p++ = '\0';
|
||||
@@ -70,8 +71,13 @@ int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
|
||||
*p++ = 1;
|
||||
*p++ = phy->enabled_usb_itf;
|
||||
}
|
||||
if (phy->led_driver_present) {
|
||||
*p++ = PHY_LED_DRIVER;
|
||||
*p++ = 1;
|
||||
*p++ = phy->led_driver;
|
||||
}
|
||||
|
||||
*len = p - data;
|
||||
*len = (uint8_t)(p - data);
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
|
||||
@@ -141,6 +147,12 @@ int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy) {
|
||||
phy->enabled_usb_itf_present = true;
|
||||
}
|
||||
break;
|
||||
case PHY_LED_DRIVER:
|
||||
if (tlen == 1) {
|
||||
phy->led_driver = *p++;
|
||||
phy->led_driver_present = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
p += tlen;
|
||||
break;
|
||||
|
||||
25
src/fs/phy.h
25
src/fs/phy.h
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _PHY_H_
|
||||
@@ -28,6 +28,7 @@
|
||||
#define PHY_USB_PRODUCT 0x9
|
||||
#define PHY_ENABLED_CURVES 0xA
|
||||
#define PHY_ENABLED_USB_ITF 0xB
|
||||
#define PHY_LED_DRIVER 0xC
|
||||
|
||||
#define PHY_OPT_WCID 0x1
|
||||
#define PHY_OPT_DIMM 0x2
|
||||
@@ -51,6 +52,18 @@
|
||||
#define PHY_USB_ITF_HID 0x4
|
||||
#define PHY_USB_ITF_KB 0x8
|
||||
|
||||
#define PHY_LED_DRIVER_PICO 0x1
|
||||
#define PHY_LED_DRIVER_PIMORONI 0x2
|
||||
#define PHY_LED_DRIVER_WS2812 0x3
|
||||
#ifdef CYW43_WL_GPIO_LED_PIN
|
||||
#define PHY_LED_DRIVER_CYW43 0x4
|
||||
#endif
|
||||
#ifdef ESP_PLATFORM
|
||||
#define PHY_LED_DRIVER_NEOPIXEL 0x5
|
||||
#endif
|
||||
|
||||
#define PHY_LED_DRIVER_NONE 0xFF
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -73,6 +86,7 @@ typedef struct phy_data {
|
||||
uint8_t led_brightness;
|
||||
uint8_t up_btn;
|
||||
uint8_t enabled_usb_itf;
|
||||
uint8_t led_driver;
|
||||
|
||||
bool vidpid_present;
|
||||
bool led_gpio_present;
|
||||
@@ -81,10 +95,11 @@ typedef struct phy_data {
|
||||
bool usb_product_present;
|
||||
bool enabled_curves_present;
|
||||
bool enabled_usb_itf_present;
|
||||
bool led_driver_present;
|
||||
|
||||
} phy_data_t;
|
||||
|
||||
#define PHY_MAX_SIZE ((2+4)+(2+4)+(2+32)+(2+2)+(2+1)+(2+1)+(2+1)+(2+1))
|
||||
#define PHY_MAX_SIZE ((2+4)+(2+4)+(2+32)+(2+2)+(2+1)+(2+1)+(2+1)+(2+1)+(2+1))
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
extern int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len);
|
||||
|
||||
129
src/led/led.c
129
src/led/led.c
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -21,13 +21,13 @@
|
||||
#ifdef PICO_PLATFORM
|
||||
#include "bsp/board.h"
|
||||
#elif defined(ESP_PLATFORM)
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_compat.h"
|
||||
#elif defined(ENABLE_EMULATION)
|
||||
#include "emulation.h"
|
||||
#endif
|
||||
|
||||
extern void led_driver_init();
|
||||
extern void led_driver_color(uint8_t, uint32_t, float);
|
||||
led_driver_t *led_driver = NULL;
|
||||
|
||||
static uint32_t led_mode = MODE_NOT_MOUNTED;
|
||||
|
||||
@@ -40,7 +40,7 @@ uint32_t led_get_mode() {
|
||||
}
|
||||
|
||||
void led_blinking_task() {
|
||||
#ifndef ENABLE_EMULATION
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
static uint32_t start_ms = 0;
|
||||
static uint32_t stop_ms = 0;
|
||||
static uint32_t last_led_update_ms = 0;
|
||||
@@ -69,7 +69,7 @@ void led_blinking_task() {
|
||||
|
||||
// limit the frequency of LED status updates
|
||||
if (board_millis() - last_led_update_ms > 2) {
|
||||
led_driver_color(led_color, led_brightness, progress);
|
||||
led_driver->set_color(led_color, led_brightness, progress);
|
||||
last_led_update_ms = board_millis();
|
||||
}
|
||||
|
||||
@@ -82,14 +82,95 @@ void led_blinking_task() {
|
||||
}
|
||||
|
||||
void led_off_all() {
|
||||
#ifndef ENABLE_EMULATION
|
||||
led_driver_color(LED_COLOR_OFF, 0, 0);
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
led_driver->set_color(LED_COLOR_OFF, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern led_driver_t led_driver_pico;
|
||||
extern led_driver_t led_driver_cyw43;
|
||||
extern led_driver_t led_driver_ws2812;
|
||||
extern led_driver_t led_driver_neopixel;
|
||||
extern led_driver_t led_driver_pimoroni;
|
||||
|
||||
void led_driver_init_dummy() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void led_driver_color_dummy(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
(void)color;
|
||||
(void)led_brightness;
|
||||
(void)progress;
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
led_driver_t led_driver_dummy = {
|
||||
.init = led_driver_init_dummy,
|
||||
.set_color = led_driver_color_dummy,
|
||||
};
|
||||
|
||||
void led_init() {
|
||||
#ifndef ENABLE_EMULATION
|
||||
led_driver_init();
|
||||
led_driver = &led_driver_dummy;
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
// Guess default driver
|
||||
#if defined(PIMORONI_TINY2040) || defined(PIMORONI_TINY2350)
|
||||
led_driver = &led_driver_pimoroni;
|
||||
phy_data.led_driver = phy_data.led_driver_present ? phy_data.led_driver : PHY_LED_DRIVER_PIMORONI;
|
||||
#elif defined(CYW43_WL_GPIO_LED_PIN)
|
||||
led_driver = &led_driver_cyw43;
|
||||
phy_data.led_driver = phy_data.led_driver_present ? phy_data.led_driver : PHY_LED_DRIVER_CYW43;
|
||||
phy_data.led_gpio = phy_data.led_gpio_present ? phy_data.led_gpio : CYW43_WL_GPIO_LED_PIN;
|
||||
#elif defined(PICO_DEFAULT_WS2812_PIN)
|
||||
led_driver = &led_driver_ws2812;
|
||||
phy_data.led_driver = phy_data.led_driver_present ? phy_data.led_driver : PHY_LED_DRIVER_WS2812;
|
||||
phy_data.led_gpio = phy_data.led_gpio_present ? phy_data.led_gpio : PICO_DEFAULT_WS2812_PIN;
|
||||
#elif defined(ESP_PLATFORM)
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
#define NEOPIXEL_PIN GPIO_NUM_48
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define NEOPIXEL_PIN GPIO_NUM_15
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
#define NEOPIXEL_PIN GPIO_NUM_8
|
||||
#else
|
||||
#define NEOPIXEL_PIN GPIO_NUM_27
|
||||
#endif
|
||||
led_driver = &led_driver_neopixel;
|
||||
phy_data.led_driver = phy_data.led_driver_present ? phy_data.led_driver : PHY_LED_DRIVER_NEOPIXEL;
|
||||
phy_data.led_gpio = phy_data.led_gpio_present ? phy_data.led_gpio : NEOPIXEL_PIN;
|
||||
#elif defined(PICO_DEFAULT_LED_PIN)
|
||||
led_driver = &led_driver_pico;
|
||||
phy_data.led_driver = phy_data.led_driver_present ? phy_data.led_driver : PHY_LED_DRIVER_PICO;
|
||||
phy_data.led_gpio = phy_data.led_gpio_present ? phy_data.led_gpio : PICO_DEFAULT_LED_PIN;
|
||||
#endif
|
||||
if (phy_data.led_driver_present) {
|
||||
switch (phy_data.led_driver) {
|
||||
#ifdef ESP_PLATFORM
|
||||
case PHY_LED_DRIVER_NEOPIXEL:
|
||||
led_driver = &led_driver_neopixel;
|
||||
break;
|
||||
#else
|
||||
case PHY_LED_DRIVER_PICO:
|
||||
led_driver = &led_driver_pico;
|
||||
break;
|
||||
#ifdef CYW43_WL_GPIO_LED_PIN
|
||||
case PHY_LED_DRIVER_CYW43:
|
||||
led_driver = &led_driver_cyw43;
|
||||
break;
|
||||
#endif
|
||||
case PHY_LED_DRIVER_WS2812:
|
||||
led_driver = &led_driver_ws2812;
|
||||
break;
|
||||
case PHY_LED_DRIVER_PIMORONI:
|
||||
led_driver = &led_driver_pimoroni;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
phy_data.led_driver_present = true;
|
||||
phy_data.led_gpio_present = true;
|
||||
led_driver->init();
|
||||
led_set_mode(MODE_NOT_MOUNTED);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _LED_H_
|
||||
@@ -67,4 +67,11 @@ extern void led_blinking_task();
|
||||
extern void led_off_all();
|
||||
extern void led_init();
|
||||
|
||||
typedef struct {
|
||||
void (*init)();
|
||||
void (*set_color)(uint8_t color, uint32_t led_brightness, float progress);
|
||||
} led_driver_t;
|
||||
|
||||
extern led_driver_t *led_driver;
|
||||
|
||||
#endif // _LED_H_
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
@@ -21,11 +21,11 @@
|
||||
|
||||
#include "pico/cyw43_arch.h"
|
||||
|
||||
void led_driver_init() {
|
||||
void led_driver_init_cyw43() {
|
||||
cyw43_arch_init();
|
||||
}
|
||||
|
||||
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
void led_driver_color_cyw43(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
(void)led_brightness;
|
||||
uint8_t gpio = CYW43_WL_GPIO_LED_PIN;
|
||||
if (phy_data.led_gpio_present) {
|
||||
@@ -34,4 +34,9 @@ void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
cyw43_arch_gpio_put(gpio, progress >= 0.5);
|
||||
}
|
||||
|
||||
led_driver_t led_driver_cyw43 = {
|
||||
.init = led_driver_init_cyw43,
|
||||
.set_color = led_driver_color_cyw43,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
@@ -45,7 +45,7 @@ tNeopixel pixel[] = {
|
||||
#define NEOPIXEL_PIN GPIO_NUM_27
|
||||
#endif
|
||||
|
||||
void led_driver_init() {
|
||||
void led_driver_init_neopixel() {
|
||||
uint8_t gpio = NEOPIXEL_PIN;
|
||||
if (phy_data.led_gpio_present) {
|
||||
gpio = phy_data.led_gpio;
|
||||
@@ -53,7 +53,7 @@ void led_driver_init() {
|
||||
neopixel = neopixel_Init(1, gpio);
|
||||
}
|
||||
|
||||
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
void led_driver_color_neopixel(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
static tNeopixel spx = {.index = 0, .rgb = 0};
|
||||
if (!(phy_data.opts & PHY_OPT_DIMM)) {
|
||||
progress = progress >= 0.5 ? 1 : 0;
|
||||
@@ -72,4 +72,9 @@ void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
neopixel_SetPixel(neopixel, &spx, 1);
|
||||
}
|
||||
|
||||
led_driver_t led_driver_neopixel = {
|
||||
.init = led_driver_init_neopixel,
|
||||
.set_color = led_driver_color_neopixel,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,25 +3,28 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
|
||||
#if defined(PICO_DEFAULT_LED_PIN) && !defined(PICO_DEFAULT_WS2812_PIN) && !defined(PIMORONI_TINY2040) && !defined(PIMORONI_TINY2350)
|
||||
|
||||
#ifdef PICO_DEFAULT_LED_PIN
|
||||
uint8_t gpio = PICO_DEFAULT_LED_PIN;
|
||||
#else
|
||||
uint8_t gpio = 0;
|
||||
#endif
|
||||
|
||||
void led_driver_init() {
|
||||
#ifdef PICO_PLATFORM
|
||||
void led_driver_init_pico() {
|
||||
if (phy_data.led_gpio_present) {
|
||||
gpio = phy_data.led_gpio;
|
||||
}
|
||||
@@ -29,9 +32,14 @@ void led_driver_init() {
|
||||
gpio_set_dir(gpio, GPIO_OUT);
|
||||
}
|
||||
|
||||
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
void led_driver_color_pico(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
(void)led_brightness;
|
||||
gpio_put(gpio, progress >= 0.5);
|
||||
}
|
||||
|
||||
led_driver_t led_driver_pico = {
|
||||
.init = led_driver_init_pico,
|
||||
.set_color = led_driver_color_pico,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,22 +3,21 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
|
||||
#if defined(PIMORONI_TINY2040) || defined(PIMORONI_TINY2350)
|
||||
|
||||
#ifdef PICO_PLATFORM
|
||||
#ifdef PIMORONI_TINY2040
|
||||
#define LED_R_PIN TINY2040_LED_R_PIN
|
||||
#define LED_G_PIN TINY2040_LED_G_PIN
|
||||
@@ -27,6 +26,10 @@
|
||||
#define LED_R_PIN TINY2350_LED_R_PIN
|
||||
#define LED_G_PIN TINY2350_LED_G_PIN
|
||||
#define LED_B_PIN TINY2350_LED_B_PIN
|
||||
#else
|
||||
#define LED_R_PIN 0
|
||||
#define LED_G_PIN 0
|
||||
#define LED_B_PIN 0
|
||||
#endif
|
||||
|
||||
uint8_t pixel[][3] = {
|
||||
@@ -40,7 +43,7 @@ uint8_t pixel[][3] = {
|
||||
{0, 0, 0} // 7: white
|
||||
};
|
||||
|
||||
void led_driver_init() {
|
||||
void led_driver_init_pimoroni() {
|
||||
gpio_init(LED_R_PIN);
|
||||
gpio_set_dir(LED_R_PIN, GPIO_OUT);
|
||||
gpio_init(LED_G_PIN);
|
||||
@@ -49,7 +52,7 @@ void led_driver_init() {
|
||||
gpio_set_dir(LED_B_PIN, GPIO_OUT);
|
||||
}
|
||||
|
||||
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
void led_driver_color_pimoroni(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
if (progress < 0.5) {
|
||||
color = LED_COLOR_OFF;
|
||||
}
|
||||
@@ -58,4 +61,9 @@ void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
gpio_put(LED_B_PIN, pixel[color][2]);
|
||||
}
|
||||
|
||||
led_driver_t led_driver_pimoroni = {
|
||||
.init = led_driver_init_pimoroni,
|
||||
.set_color = led_driver_color_pimoroni,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,22 +3,21 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
|
||||
#ifdef PICO_DEFAULT_WS2812_PIN
|
||||
|
||||
#ifdef PICO_PLATFORM
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/clocks.h"
|
||||
|
||||
@@ -70,11 +69,14 @@ static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin,
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
|
||||
void led_driver_init() {
|
||||
void led_driver_init_ws2812() {
|
||||
PIO pio = pio0;
|
||||
int sm = 0;
|
||||
uint offset = pio_add_program(pio, &ws2812_program);
|
||||
uint8_t gpio = PICO_DEFAULT_WS2812_PIN;
|
||||
uint8_t gpio = 0;
|
||||
#ifdef PICO_DEFAULT_WS2812_PIN
|
||||
gpio = PICO_DEFAULT_WS2812_PIN;
|
||||
#endif
|
||||
if (phy_data.led_gpio_present) {
|
||||
gpio = phy_data.led_gpio;
|
||||
}
|
||||
@@ -113,7 +115,7 @@ static inline void ws2812_put_pixel(uint32_t u32_pixel) {
|
||||
pio_sm_put_blocking(pio0, 0, u32_pixel << 8u);
|
||||
}
|
||||
|
||||
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
void led_driver_color_ws2812(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
if (!(phy_data.opts & PHY_OPT_DIMM)) {
|
||||
progress = progress >= 0.5 ? 1 : 0;
|
||||
}
|
||||
@@ -128,4 +130,9 @@ void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
|
||||
ws2812_put_pixel(urgb_u32(pixel_color.r, pixel_color.g, pixel_color.b));
|
||||
}
|
||||
|
||||
led_driver_t led_driver_ws2812 = {
|
||||
.init = led_driver_init_ws2812,
|
||||
.set_color = led_driver_color_ws2812,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
53
src/main.c
53
src/main.c
@@ -3,33 +3,34 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "pico_keys.h"
|
||||
|
||||
// Pico
|
||||
|
||||
#if !defined(ENABLE_EMULATION)
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
#if defined(ENABLE_EMULATION)
|
||||
#include "emulation.h"
|
||||
#elif defined(ESP_PLATFORM)
|
||||
#include "tusb.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "tinyusb.h"
|
||||
#include "esp_efuse.h"
|
||||
#define BOOT_PIN GPIO_NUM_0
|
||||
#else
|
||||
#elif defined(PICO_PLATFORM)
|
||||
#include "pico/stdlib.h"
|
||||
#include "bsp/board.h"
|
||||
#include "pico/aon_timer.h"
|
||||
@@ -40,14 +41,15 @@
|
||||
#endif
|
||||
|
||||
#include "random.h"
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "usb.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
extern void do_flash();
|
||||
extern void low_flash_init();
|
||||
extern void init_otp_files();
|
||||
|
||||
app_t apps[8];
|
||||
app_t apps[16];
|
||||
uint8_t num_apps = 0;
|
||||
|
||||
app_t *current_app = NULL;
|
||||
@@ -55,11 +57,8 @@ app_t *current_app = NULL;
|
||||
const uint8_t *ccid_atr = NULL;
|
||||
|
||||
bool app_exists(const uint8_t *aid, size_t aid_len) {
|
||||
if (current_app && current_app->aid && (current_app->aid + 1 == aid || !memcmp(current_app->aid + 1, aid, aid_len))) {
|
||||
return true;
|
||||
}
|
||||
for (int a = 0; a < num_apps; a++) {
|
||||
if (!memcmp(apps[a].aid + 1, aid, MIN(aid_len, apps[a].aid[0]))) {
|
||||
if (apps[a].aid[0] == aid_len && !memcmp(apps[a].aid + 1, aid, MIN(aid_len, apps[a].aid[0]))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -80,14 +79,14 @@ int register_app(int (*select_aid)(app_t *, uint8_t), const uint8_t *aid) {
|
||||
}
|
||||
|
||||
int select_app(const uint8_t *aid, size_t aid_len) {
|
||||
if (current_app && current_app->aid && (current_app->aid + 1 == aid || !memcmp(current_app->aid + 1, aid, aid_len))) {
|
||||
if (current_app && current_app->aid && current_app->aid[0] == aid_len && (current_app->aid + 1 == aid || !memcmp(current_app->aid + 1, aid, MIN(current_app->aid[0], aid_len)))) {
|
||||
current_app->select_aid(current_app, 0);
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
for (int a = 0; a < num_apps; a++) {
|
||||
if (!memcmp(apps[a].aid + 1, aid, MIN(aid_len, apps[a].aid[0]))) {
|
||||
if (apps[a].aid[0] == aid_len && !memcmp(apps[a].aid + 1, aid, MIN(aid_len, apps[a].aid[0]))) {
|
||||
if (current_app) {
|
||||
if (current_app->aid && !memcmp(current_app->aid + 1, aid, aid_len)) {
|
||||
if (current_app->aid && !memcmp(current_app->aid + 1, aid, MIN(current_app->aid[0], aid_len))) {
|
||||
current_app->select_aid(current_app, 1);
|
||||
return PICOKEY_OK;
|
||||
}
|
||||
@@ -116,7 +115,6 @@ bool is_req_button_pending() {
|
||||
|
||||
bool cancel_button = false;
|
||||
|
||||
#ifdef ENABLE_EMULATION
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
struct timezone
|
||||
@@ -146,13 +144,13 @@ int gettimeofday(struct timeval* tp, struct timezone* tzp)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if !defined(ENABLE_EMULATION)
|
||||
#ifdef ESP_PLATFORM
|
||||
bool picok_board_button_read() {
|
||||
int boot_state = gpio_get_level(BOOT_PIN);
|
||||
return boot_state == 0;
|
||||
}
|
||||
#else
|
||||
#elif defined(PICO_PLATFORM)
|
||||
bool __no_inline_not_in_flash_func(picok_get_bootsel_button)() {
|
||||
const uint CS_PIN_INDEX = 1;
|
||||
|
||||
@@ -187,10 +185,13 @@ bool __no_inline_not_in_flash_func(picok_get_bootsel_button)() {
|
||||
|
||||
return button_state;
|
||||
}
|
||||
uint32_t picok_board_button_read(void)
|
||||
{
|
||||
bool picok_board_button_read(void) {
|
||||
return picok_get_bootsel_button();
|
||||
}
|
||||
#else
|
||||
bool picok_board_button_read(void) {
|
||||
return true; // always unpressed
|
||||
}
|
||||
#endif
|
||||
bool button_pressed_state = false;
|
||||
uint32_t button_pressed_time = 0;
|
||||
@@ -286,6 +287,7 @@ void core0_loop() {
|
||||
}
|
||||
|
||||
char pico_serial_str[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1];
|
||||
uint8_t pico_serial_hash[32];
|
||||
pico_unique_board_id_t pico_serial;
|
||||
#ifdef ESP_PLATFORM
|
||||
#define pico_get_unique_board_id(a) do { uint32_t value; esp_efuse_read_block(EFUSE_BLK1, &value, 0, 32); memcpy((uint8_t *)(a), &value, sizeof(uint32_t)); esp_efuse_read_block(EFUSE_BLK1, &value, 32, 32); memcpy((uint8_t *)(a)+4, &value, sizeof(uint32_t)); } while(0)
|
||||
@@ -294,19 +296,20 @@ extern const uint8_t desc_config[];
|
||||
TaskHandle_t hcore0 = NULL, hcore1 = NULL;
|
||||
int app_main() {
|
||||
#else
|
||||
#ifdef ENABLE_EMULATION
|
||||
#ifndef PICO_PLATFORM
|
||||
#define pico_get_unique_board_id(a) memset(a, 0, sizeof(*(a)))
|
||||
#endif
|
||||
int main(void) {
|
||||
#endif
|
||||
pico_get_unique_board_id(&pico_serial);
|
||||
memset(pico_serial_str, 0, sizeof(pico_serial_str));
|
||||
for (int i = 0; i < sizeof(pico_serial); i++) {
|
||||
for (size_t i = 0; i < sizeof(pico_serial); i++) {
|
||||
snprintf(&pico_serial_str[2 * i], 3, "%02X", pico_serial.id[i]);
|
||||
}
|
||||
mbedtls_sha256(pico_serial.id, sizeof(pico_serial.id), pico_serial_hash, false);
|
||||
|
||||
#ifndef ENABLE_EMULATION
|
||||
#ifndef ESP_PLATFORM
|
||||
#ifdef PICO_PLATFORM
|
||||
board_init();
|
||||
stdio_init_all();
|
||||
#endif
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _PICO_KEYS_H_
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "file.h"
|
||||
#include "led/led.h"
|
||||
#if defined(ENABLE_EMULATION) || defined(ESP_PLATFORM)
|
||||
#include <stdint.h>
|
||||
#if !defined(MIN)
|
||||
#if defined(_MSC_VER)
|
||||
@@ -46,7 +45,7 @@
|
||||
_a > _b ? _a : _b; })
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#if defined(PICO_PLATFORM)
|
||||
#include "pico/unique_id.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
@@ -56,7 +55,7 @@
|
||||
#include <stdbool.h>
|
||||
#elif defined(ESP_PLATFORM)
|
||||
#include "esp_compat.h"
|
||||
#else
|
||||
#elif defined(PICO_PLATFORM)
|
||||
#include "pico/util/queue.h"
|
||||
#endif
|
||||
|
||||
@@ -76,12 +75,12 @@ static inline uint16_t get_uint16_t_be(const uint8_t *b) {
|
||||
static inline uint16_t get_uint16_t_le(const uint8_t *b) {
|
||||
return make_uint16_t_le(b[0], b[1]);
|
||||
}
|
||||
static inline uint32_t put_uint16_t_be(uint16_t n, uint8_t *b) {
|
||||
static inline uint8_t put_uint16_t_be(uint16_t n, uint8_t *b) {
|
||||
*b++ = (n >> 8) & 0xff;
|
||||
*b = n & 0xff;
|
||||
return 2;
|
||||
}
|
||||
static inline uint32_t put_uint16_t_le(uint16_t n, uint8_t *b) {
|
||||
static inline uint8_t put_uint16_t_le(uint16_t n, uint8_t *b) {
|
||||
*b++ = n & 0xff;
|
||||
*b = (n >> 8) & 0xff;
|
||||
return 2;
|
||||
@@ -155,7 +154,6 @@ extern int flash_clear_file(file_t *file);
|
||||
extern int (*button_pressed_cb)(uint8_t);
|
||||
|
||||
extern bool is_req_button_pending();
|
||||
extern uint32_t button_timeout;
|
||||
|
||||
#define SW_BYTES_REMAINING_00() set_res_sw(0x61, 0x00)
|
||||
#define SW_WARNING_STATE_UNCHANGED() set_res_sw(0x62, 0x00)
|
||||
@@ -230,11 +228,16 @@ extern uint32_t button_timeout;
|
||||
|
||||
#define PICOKEY_CHECK(x) do { ret = (x); if (ret != PICOKEY_OK) goto err; } while (0)
|
||||
|
||||
#if defined(ENABLE_EMULATION) || defined(ESP_PLATFORM)
|
||||
#if !defined (PICO_PLATFORM)
|
||||
#define PICO_UNIQUE_BOARD_ID_SIZE_BYTES 8
|
||||
typedef struct { uint8_t id[PICO_UNIQUE_BOARD_ID_SIZE_BYTES]; } pico_unique_board_id_t;
|
||||
#endif
|
||||
extern pico_unique_board_id_t pico_serial;
|
||||
extern char pico_serial_str[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1];
|
||||
extern uint8_t pico_serial_hash[32];
|
||||
|
||||
#if defined(PICO_PLATFORM)
|
||||
#define multicore_launch_func_core1(a) multicore_launch_core1((void (*) (void))a)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __VERSION_H_
|
||||
#define __VERSION_H_
|
||||
|
||||
#define PICO_KEYS_SDK_VERSION 0x0700
|
||||
#define PICO_KEYS_SDK_VERSION 0x0800
|
||||
|
||||
#define PICO_KEYS_SDK_VERSION_MAJOR ((PICO_KEYS_SDK_VERSION >> 8) & 0xff)
|
||||
#define PICO_KEYS_SDK_VERSION_MINOR (PICO_KEYS_SDK_VERSION & 0xff)
|
||||
|
||||
113
src/pthread_win32.h
Normal file
113
src/pthread_win32.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef _PTHREAD_H_
|
||||
#define _PTHREAD_H_
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef HANDLE pthread_t;
|
||||
typedef CRITICAL_SECTION pthread_mutex_t;
|
||||
|
||||
typedef struct {
|
||||
CONDITION_VARIABLE cond;
|
||||
} pthread_cond_t;
|
||||
|
||||
// Mutex
|
||||
static inline int pthread_mutex_init(pthread_mutex_t *m, void *a) {
|
||||
(void)a;
|
||||
InitializeCriticalSection(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_mutex_lock(pthread_mutex_t *m) {
|
||||
EnterCriticalSection(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_mutex_unlock(pthread_mutex_t *m) {
|
||||
LeaveCriticalSection(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_mutex_destroy(pthread_mutex_t *m) {
|
||||
DeleteCriticalSection(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Thread
|
||||
static DWORD WINAPI thread_entry(LPVOID param) {
|
||||
void **args = (void **)param;
|
||||
void *(*fn)(void *) = (void *(*)(void *))(uintptr_t)args[0];
|
||||
void *arg = args[1];
|
||||
fn(arg);
|
||||
free(param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_create(pthread_t *t, void *a, void *(*fn)(void *), void *arg) {
|
||||
(void)a;
|
||||
void **params = malloc(2 * sizeof(void *));
|
||||
if (!params) return -1;
|
||||
params[0] = (void *)(uintptr_t)fn;
|
||||
params[1] = arg;
|
||||
*t = CreateThread(NULL, 0, thread_entry, params, 0, NULL);
|
||||
return *t ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int pthread_join(pthread_t t, void **ret) {
|
||||
WaitForSingleObject(t, INFINITE);
|
||||
CloseHandle(t);
|
||||
if (ret) *ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Condition variable
|
||||
static inline int pthread_cond_init(pthread_cond_t *c, void *a) {
|
||||
(void)a;
|
||||
InitializeConditionVariable(&c->cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_destroy(pthread_cond_t *c) {
|
||||
(void)c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m) {
|
||||
SleepConditionVariableCS(&c->cond, m, INFINITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_signal(pthread_cond_t *c) {
|
||||
WakeConditionVariable(&c->cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_broadcast(pthread_cond_t *c) {
|
||||
WakeAllConditionVariable(&c->cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_mutex_trylock(pthread_mutex_t *m){
|
||||
return TryEnterCriticalSection(m) ? 0 : EBUSY;
|
||||
}
|
||||
|
||||
#endif // _PTHREAD_H_
|
||||
#endif // _MSC_VER
|
||||
132
src/queue.h
Normal file
132
src/queue.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QUEUE_H
|
||||
#define QUEUE_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "pthread_win32.h"
|
||||
#include "semaphore_win32.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
typedef struct {
|
||||
pthread_mutex_t mtx;
|
||||
pthread_cond_t cnd;
|
||||
size_t size_elem;
|
||||
size_t num_elem;
|
||||
size_t max_elem;
|
||||
uint8_t buf[1024];
|
||||
bool is_init;
|
||||
} queue_t;
|
||||
|
||||
static inline void queue_free(queue_t *a) {
|
||||
pthread_mutex_destroy(&a->mtx);
|
||||
pthread_cond_destroy(&a->cnd);
|
||||
a->is_init = false;
|
||||
}
|
||||
static inline void queue_init(queue_t *a, size_t size_elem, size_t max_elem) {
|
||||
if (a->is_init) {
|
||||
queue_free(a);
|
||||
}
|
||||
pthread_mutex_init(&a->mtx, NULL);
|
||||
pthread_cond_init(&a->cnd, NULL);
|
||||
a->size_elem = size_elem;
|
||||
a->max_elem = max_elem;
|
||||
a->num_elem = 0;
|
||||
a->is_init = true;
|
||||
}
|
||||
static inline void queue_add_blocking(queue_t *a, const void *b) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
while (a->num_elem == a->max_elem) {
|
||||
pthread_cond_wait(&a->cnd, &a->mtx);
|
||||
}
|
||||
memcpy(a->buf + a->num_elem * a->size_elem, b, a->size_elem);
|
||||
a->num_elem++;
|
||||
pthread_cond_signal(&a->cnd);
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
}
|
||||
static inline void queue_remove_blocking(queue_t *a, void *b) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
while (a->num_elem == 0) {
|
||||
pthread_cond_wait(&a->cnd, &a->mtx);
|
||||
}
|
||||
memcpy(b, a->buf, a->size_elem);
|
||||
memmove(a->buf, a->buf + a->size_elem, a->size_elem * (a->num_elem - 1));
|
||||
a->num_elem--;
|
||||
pthread_cond_signal(&a->cnd);
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
}
|
||||
static inline int queue_try_add(queue_t *a, const void *b) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
if (a->num_elem == a->max_elem) {
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return 0;
|
||||
}
|
||||
memcpy(a->buf + a->num_elem * a->size_elem, b, a->size_elem);
|
||||
a->num_elem++;
|
||||
pthread_cond_signal(&a->cnd);
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return 1;
|
||||
}
|
||||
static inline int queue_try_remove(queue_t *a, void *b) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
if (a->num_elem == 0) {
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return 0;
|
||||
}
|
||||
memcpy(b, a->buf, a->size_elem);
|
||||
memmove(a->buf, a->buf + a->size_elem, a->size_elem * (a->num_elem - 1));
|
||||
a->num_elem--;
|
||||
pthread_cond_signal(&a->cnd);
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return 1;
|
||||
}
|
||||
static inline int queue_is_empty(queue_t *a) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
bool ret = a->num_elem == 0;
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return ret;
|
||||
}
|
||||
static inline int queue_is_full(queue_t *a) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
bool ret = a->num_elem == a->max_elem;
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return ret;
|
||||
}
|
||||
static inline void queue_clear(queue_t *a) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
a->num_elem = 0;
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
}
|
||||
extern pthread_t hcore0, hcore1;
|
||||
#define multicore_launch_func_core1(a) pthread_create(&hcore1, NULL, (void *(*) (void *))a, NULL)
|
||||
#define multicore_reset_core1()
|
||||
|
||||
typedef pthread_mutex_t mutex_t;
|
||||
typedef sem_t semaphore_t;
|
||||
#define mutex_init(a) pthread_mutex_init(a, NULL)
|
||||
#define mutex_try_enter(a,b) (pthread_mutex_trylock(a) == 0)
|
||||
#define mutex_enter_blocking(a) pthread_mutex_lock(a)
|
||||
#define mutex_exit(a) pthread_mutex_unlock(a)
|
||||
#define sem_release(a) sem_post(a)
|
||||
#define sem_acquire_blocking(a) sem_wait(a)
|
||||
#define multicore_lockout_victim_init() (void)0
|
||||
|
||||
#endif // QUEUE_H
|
||||
85
src/rescue.c
85
src/rescue.c
@@ -3,22 +3,26 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "pico_keys_version.h"
|
||||
#include "otp.h"
|
||||
#ifdef PICO_PLATFORM
|
||||
#include "pico/bootrom.h"
|
||||
#include "hardware/watchdog.h"
|
||||
#endif
|
||||
|
||||
int rescue_process_apdu();
|
||||
int rescue_unload();
|
||||
@@ -39,6 +43,8 @@ const uint8_t rescue_aid[] = {
|
||||
#endif
|
||||
|
||||
extern uint8_t PICO_PRODUCT;
|
||||
extern uint8_t PICO_VERSION_MAJOR;
|
||||
extern uint8_t PICO_VERSION_MINOR;
|
||||
|
||||
int rescue_select(app_t *a, uint8_t force) {
|
||||
a->process_apdu = rescue_process_apdu;
|
||||
@@ -46,8 +52,8 @@ int rescue_select(app_t *a, uint8_t force) {
|
||||
res_APDU_size = 0;
|
||||
res_APDU[res_APDU_size++] = PICO_MCU;
|
||||
res_APDU[res_APDU_size++] = PICO_PRODUCT;
|
||||
res_APDU[res_APDU_size++] = PICO_KEYS_SDK_VERSION_MAJOR;
|
||||
res_APDU[res_APDU_size++] = PICO_KEYS_SDK_VERSION_MINOR;
|
||||
res_APDU[res_APDU_size++] = PICO_VERSION_MAJOR;
|
||||
res_APDU[res_APDU_size++] = PICO_VERSION_MINOR;
|
||||
apdu.ne = res_APDU_size;
|
||||
if (force) {
|
||||
scan_flash();
|
||||
@@ -70,7 +76,7 @@ int cmd_write() {
|
||||
|
||||
if (P1(apdu) == 0x1) { // PHY
|
||||
#ifndef ENABLE_EMULATION
|
||||
int ret = phy_unserialize_data(apdu.data, apdu.nc, &phy_data);
|
||||
int ret = phy_unserialize_data(apdu.data, (uint16_t)apdu.nc, &phy_data);
|
||||
if (ret == PICOKEY_OK) {
|
||||
if (phy_save() != PICOKEY_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
@@ -81,6 +87,43 @@ int cmd_write() {
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
int cmd_read() {
|
||||
if (apdu.nc != 0) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
|
||||
uint8_t p1 = P1(apdu);
|
||||
if (p1 == 0x1) { // PHY
|
||||
#ifndef ENABLE_EMULATION
|
||||
uint16_t len = 0;
|
||||
int ret = phy_serialize_data(&phy_data, apdu.rdata, &len);
|
||||
if (ret != PICOKEY_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
res_APDU_size = len;
|
||||
#endif
|
||||
}
|
||||
else if (p1 == 0x2) { // FLASH INFO
|
||||
res_APDU_size = 0;
|
||||
uint32_t free = flash_free_space(), total = flash_total_space(), used = flash_used_space(), nfiles = flash_num_files(), size = flash_size();
|
||||
res_APDU_size += put_uint32_t_be(free, res_APDU + res_APDU_size);
|
||||
res_APDU_size += put_uint32_t_be(used, res_APDU + res_APDU_size);
|
||||
res_APDU_size += put_uint32_t_be(total, res_APDU + res_APDU_size);
|
||||
res_APDU_size += put_uint32_t_be(nfiles, res_APDU + res_APDU_size);
|
||||
res_APDU_size += put_uint32_t_be(size, res_APDU + res_APDU_size);
|
||||
}
|
||||
else if (p1 == 0x3) { // OTP SECURE BOOT STATUS
|
||||
res_APDU_size = 0;
|
||||
uint8_t bootkey = 0xFF;
|
||||
bool enabled = otp_is_secure_boot_enabled(&bootkey);
|
||||
bool locked = otp_is_secure_boot_locked();
|
||||
res_APDU[res_APDU_size++] = enabled ? 0x1 : 0x0;
|
||||
res_APDU[res_APDU_size++] = locked ? 0x1 : 0x0;
|
||||
res_APDU[res_APDU_size++] = bootkey;
|
||||
}
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
#if defined(PICO_RP2350) || defined(ESP_PLATFORM)
|
||||
int cmd_secure() {
|
||||
if (apdu.nc != 0) {
|
||||
@@ -98,13 +141,41 @@ int cmd_secure() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PICO_PLATFORM
|
||||
int cmd_reboot_bootsel() {
|
||||
if (apdu.nc != 0) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
|
||||
if (P1(apdu) == 0x1) {
|
||||
// Reboot to BOOTSEL
|
||||
reset_usb_boot(0, 0);
|
||||
}
|
||||
else if (P1(apdu) == 0x0) {
|
||||
// Reboot to normal mode
|
||||
watchdog_reboot(0, 0, 100);
|
||||
}
|
||||
else {
|
||||
return SW_INCORRECT_P1P2();
|
||||
}
|
||||
|
||||
return SW_OK();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define INS_WRITE 0x1C
|
||||
#define INS_SECURE 0x1D
|
||||
#define INS_READ 0x1E
|
||||
#define INS_REBOOT_BOOTSEL 0x1F
|
||||
|
||||
static const cmd_t cmds[] = {
|
||||
{ INS_WRITE, cmd_write },
|
||||
#if defined(PICO_RP2350) || defined(ESP_PLATFORM)
|
||||
{ INS_SECURE, cmd_secure },
|
||||
#endif
|
||||
{ INS_READ, cmd_read },
|
||||
#ifdef PICO_PLATFORM
|
||||
{ INS_REBOOT_BOOTSEL, cmd_reboot_bootsel },
|
||||
#endif
|
||||
{ 0x00, 0x0 }
|
||||
};
|
||||
|
||||
@@ -3,35 +3,36 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#if defined(ENABLE_EMULATION)
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "emulation.h"
|
||||
#elif (ESP_PLATFORM)
|
||||
#include "bootloader_random.h"
|
||||
#include "esp_random.h"
|
||||
#include "esp_compat.h"
|
||||
#else
|
||||
|
||||
#if defined(PICO_PLATFORM)
|
||||
#include "pico/stdlib.h"
|
||||
#include "hwrng.h"
|
||||
#include "bsp/board.h"
|
||||
#include "pico/rand.h"
|
||||
#elif defined(ESP_PLATFORM)
|
||||
#include "bootloader_random.h"
|
||||
#include "esp_random.h"
|
||||
#include "esp_compat.h"
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "board.h"
|
||||
#endif
|
||||
|
||||
void hwrng_start() {
|
||||
@@ -57,14 +58,14 @@ static int ep_process() {
|
||||
}
|
||||
uint64_t word = 0x0;
|
||||
|
||||
#if defined(ENABLE_EMULATION)
|
||||
word = rand();
|
||||
word <<= 32;
|
||||
word |= rand();
|
||||
#if defined(PICO_PLATFORM)
|
||||
word = get_rand_64();
|
||||
#elif defined(ESP_PLATFORM)
|
||||
esp_fill_random((uint8_t *)&word, sizeof(word));
|
||||
#else
|
||||
word = get_rand_64();
|
||||
word = rand();
|
||||
word <<= 32;
|
||||
word |= rand();
|
||||
#endif
|
||||
random_word ^= word ^ board_millis();
|
||||
random_word *= 0x00000100000001B3;
|
||||
@@ -169,15 +170,13 @@ uint32_t neug_get() {
|
||||
|
||||
void neug_wait_full() {
|
||||
struct rng_rb *rb = &the_ring_buffer;
|
||||
#ifndef ENABLE_EMULATION
|
||||
#ifdef ESP_PLATFORM
|
||||
uint8_t core = xTaskGetCurrentTaskHandle() == hcore1 ? 1 : 0;
|
||||
#else
|
||||
#elif defined(PICO_PLATFORM)
|
||||
uint core = get_core_num();
|
||||
#endif
|
||||
#endif
|
||||
while (!rb->full) {
|
||||
#ifndef ENABLE_EMULATION
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
if (core == 1) {
|
||||
sleep_ms(1);
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _NEUG_H_
|
||||
@@ -21,7 +21,7 @@
|
||||
#define NEUG_PRE_LOOP 32
|
||||
|
||||
#include <stdlib.h>
|
||||
#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
||||
#if defined(PICO_PLATFORM)
|
||||
#include "pico/stdlib.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
47
src/semaphore_win32.h
Normal file
47
src/semaphore_win32.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef _SEMAPHORE_H_
|
||||
#define _SEMAPHORE_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct {
|
||||
HANDLE handle;
|
||||
} sem_t;
|
||||
|
||||
static inline int sem_init(sem_t *sem, int pshared, unsigned int value) {
|
||||
(void)pshared;
|
||||
sem->handle = CreateSemaphore(NULL, value, 0x7FFFFFFF, NULL);
|
||||
return sem->handle ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int sem_wait(sem_t *sem) {
|
||||
return WaitForSingleObject(sem->handle, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int sem_post(sem_t *sem) {
|
||||
return ReleaseSemaphore(sem->handle, 1, NULL) ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int sem_destroy(sem_t *sem) {
|
||||
return CloseHandle(sem->handle) ? 0 : -1;
|
||||
}
|
||||
|
||||
#endif // _SEMAPHORE_H_
|
||||
#endif // _MSC_VER
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "random.h"
|
||||
@@ -378,7 +378,11 @@ static uint16_t ccid_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc,
|
||||
tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *)((uint8_t *)itf_desc + drv_len - sizeof(tusb_desc_endpoint_t));
|
||||
TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0);
|
||||
uint8_t msg[] = { 0x50, 0x03 };
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
usbd_edpt_xfer(rhport, desc_ep->bEndpointAddress, msg, sizeof(msg));
|
||||
#else
|
||||
usbd_edpt_xfer(rhport, desc_ep->bEndpointAddress, msg, sizeof(msg), sizeof(msg));
|
||||
#endif
|
||||
#else
|
||||
vendord_open(rhport, (tusb_desc_interface_t *)itf_vendor, max_len);
|
||||
#endif
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CCID_H_
|
||||
|
||||
@@ -3,18 +3,19 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
#include "emulation.h"
|
||||
#include <stdio.h>
|
||||
#ifndef _MSC_VER
|
||||
@@ -41,7 +42,6 @@ typedef int socklen_t;
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "pico_keys.h"
|
||||
#include "apdu.h"
|
||||
#include "usb.h"
|
||||
#include "ccid/ccid.h"
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _EMULATION_H_
|
||||
@@ -20,11 +20,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include "queue.h"
|
||||
#include "board.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#define USB_BUFFER_SIZE 2048
|
||||
@@ -34,12 +31,6 @@ extern uint16_t emul_rx_size, emul_tx_size;
|
||||
extern uint16_t driver_write_emul(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size);
|
||||
extern uint16_t emul_read(uint8_t itf);
|
||||
|
||||
static inline uint32_t board_millis() {
|
||||
struct timeval start;
|
||||
gettimeofday(&start, NULL);
|
||||
return start.tv_sec * 1000 + start.tv_usec / 1000;
|
||||
}
|
||||
|
||||
#ifdef USB_ITF_HID
|
||||
typedef uint8_t hid_report_type_t;
|
||||
#endif
|
||||
@@ -71,109 +62,4 @@ extern void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report,
|
||||
extern bool tud_hid_n_report(uint8_t itf, uint8_t report_id, const uint8_t *buffer, uint32_t n);
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
typedef struct {
|
||||
pthread_mutex_t mtx;
|
||||
pthread_cond_t cnd;
|
||||
size_t size_elem;
|
||||
size_t num_elem;
|
||||
size_t max_elem;
|
||||
uint8_t buf[1024];
|
||||
bool is_init;
|
||||
} queue_t;
|
||||
|
||||
static inline void queue_free(queue_t *a) {
|
||||
pthread_mutex_destroy(&a->mtx);
|
||||
pthread_cond_destroy(&a->cnd);
|
||||
a->is_init = false;
|
||||
}
|
||||
static inline void queue_init(queue_t *a, size_t size_elem, size_t max_elem) {
|
||||
if (a->is_init) {
|
||||
queue_free(a);
|
||||
}
|
||||
pthread_mutex_init(&a->mtx, NULL);
|
||||
pthread_cond_init(&a->cnd, NULL);
|
||||
a->size_elem = size_elem;
|
||||
a->max_elem = max_elem;
|
||||
a->num_elem = 0;
|
||||
a->is_init = true;
|
||||
}
|
||||
static inline void queue_add_blocking(queue_t *a, const void *b) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
while (a->num_elem == a->max_elem) {
|
||||
pthread_cond_wait(&a->cnd, &a->mtx);
|
||||
}
|
||||
memcpy(a->buf + a->num_elem * a->size_elem, b, a->size_elem);
|
||||
a->num_elem++;
|
||||
pthread_cond_signal(&a->cnd);
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
}
|
||||
static inline void queue_remove_blocking(queue_t *a, void *b) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
while (a->num_elem == 0) {
|
||||
pthread_cond_wait(&a->cnd, &a->mtx);
|
||||
}
|
||||
memcpy(b, a->buf, a->size_elem);
|
||||
memmove(a->buf, a->buf + a->size_elem, a->size_elem * (a->num_elem - 1));
|
||||
a->num_elem--;
|
||||
pthread_cond_signal(&a->cnd);
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
}
|
||||
static inline int queue_try_add(queue_t *a, const void *b) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
if (a->num_elem == a->max_elem) {
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return 0;
|
||||
}
|
||||
memcpy(a->buf + a->num_elem * a->size_elem, b, a->size_elem);
|
||||
a->num_elem++;
|
||||
pthread_cond_signal(&a->cnd);
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return 1;
|
||||
}
|
||||
static inline int queue_try_remove(queue_t *a, void *b) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
if (a->num_elem == 0) {
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return 0;
|
||||
}
|
||||
memcpy(b, a->buf, a->size_elem);
|
||||
memmove(a->buf, a->buf + a->size_elem, a->size_elem * (a->num_elem - 1));
|
||||
a->num_elem--;
|
||||
pthread_cond_signal(&a->cnd);
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return 1;
|
||||
}
|
||||
static inline int queue_is_empty(queue_t *a) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
bool ret = a->num_elem == 0;
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return ret;
|
||||
}
|
||||
static inline int queue_is_full(queue_t *a) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
bool ret = a->num_elem == a->max_elem;
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
return ret;
|
||||
}
|
||||
static inline void queue_clear(queue_t *a) {
|
||||
pthread_mutex_lock(&a->mtx);
|
||||
a->num_elem = 0;
|
||||
pthread_mutex_unlock(&a->mtx);
|
||||
}
|
||||
extern pthread_t hcore0, hcore1;
|
||||
#define multicore_launch_core1(a) pthread_create(&hcore1, NULL, (void *(*) (void *))a, NULL)
|
||||
#define multicore_reset_core1()
|
||||
|
||||
typedef pthread_mutex_t mutex_t;
|
||||
typedef sem_t semaphore_t;
|
||||
#define mutex_init(a) pthread_mutex_init(a, NULL)
|
||||
#define mutex_try_enter(a,b) (pthread_mutex_trylock(a) == 0)
|
||||
#define mutex_enter_blocking(a) pthread_mutex_lock(a)
|
||||
#define mutex_exit(a) pthread_mutex_unlock(a)
|
||||
#define sem_release(a) sem_post(a)
|
||||
#define sem_acquire_blocking(a) sem_wait(a)
|
||||
#define multicore_lockout_victim_init() (void)0
|
||||
|
||||
#endif // _EMULATION_H_
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CTAP_HID_H_
|
||||
@@ -159,7 +159,7 @@ typedef struct {
|
||||
extern void add_keyboard_buffer(const uint8_t *, size_t, bool);
|
||||
extern void append_keyboard_buffer(const uint8_t *data, size_t data_len);
|
||||
|
||||
extern bool is_nitrokey;
|
||||
extern bool is_nk;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -3,37 +3,36 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
#ifndef ENABLE_EMULATION
|
||||
#include "tusb.h"
|
||||
#ifndef ESP_PLATFORM
|
||||
#if defined(PICO_PLATFORM)
|
||||
#include "bsp/board.h"
|
||||
#else
|
||||
#elif defined(ESP_PLATFORM)
|
||||
static portMUX_TYPE mutex = portMUX_INITIALIZER_UNLOCKED;
|
||||
#endif
|
||||
#else
|
||||
#include "emulation.h"
|
||||
#endif
|
||||
#include "ctap_hid.h"
|
||||
#include "pico_keys.h"
|
||||
#include "pico_keys_version.h"
|
||||
#include "apdu.h"
|
||||
#include "usb.h"
|
||||
|
||||
static bool mounted = false;
|
||||
extern void init_fido();
|
||||
bool is_nitrokey = false;
|
||||
bool is_nk = false;
|
||||
uint8_t (*get_version_major)() = NULL;
|
||||
uint8_t (*get_version_minor)() = NULL;
|
||||
|
||||
@@ -48,14 +47,6 @@ typedef struct msg_packet {
|
||||
|
||||
msg_packet_t msg_packet = { 0 };
|
||||
|
||||
void tud_mount_cb() {
|
||||
mounted = true;
|
||||
}
|
||||
|
||||
bool driver_mounted_hid() {
|
||||
return mounted;
|
||||
}
|
||||
|
||||
static uint16_t *send_buffer_size = NULL;
|
||||
static write_status_t *last_write_result = NULL;
|
||||
|
||||
@@ -100,7 +91,7 @@ int driver_init_hid() {
|
||||
|
||||
usb_set_timeout_counter(ITF_HID, 200);
|
||||
|
||||
is_nitrokey = false;
|
||||
is_nk = false;
|
||||
|
||||
hid_tx[ITF_HID_CTAP].w_ptr = hid_tx[ITF_HID_CTAP].r_ptr = 0;
|
||||
send_buffer_size[ITF_HID_CTAP] = 0;
|
||||
@@ -158,7 +149,7 @@ static bool sent_key = false;
|
||||
static bool keyboard_encode = false;
|
||||
|
||||
void add_keyboard_buffer(const uint8_t *data, size_t data_len, bool encode) {
|
||||
keyboard_buffer_len = MIN(sizeof(keyboard_buffer), data_len);
|
||||
keyboard_buffer_len = (uint8_t)MIN(sizeof(keyboard_buffer), data_len);
|
||||
memcpy(keyboard_buffer, data, keyboard_buffer_len);
|
||||
keyboard_encode = encode;
|
||||
}
|
||||
@@ -166,7 +157,7 @@ void add_keyboard_buffer(const uint8_t *data, size_t data_len, bool encode) {
|
||||
void append_keyboard_buffer(const uint8_t *data, size_t data_len) {
|
||||
if (keyboard_buffer_len + data_len < sizeof(keyboard_buffer)) {
|
||||
memcpy(keyboard_buffer + keyboard_buffer_len, data, MIN(sizeof(keyboard_buffer) - keyboard_buffer_len, data_len));
|
||||
keyboard_buffer_len += MIN(sizeof(keyboard_buffer) - keyboard_buffer_len, data_len);
|
||||
keyboard_buffer_len += (uint8_t)MIN(sizeof(keyboard_buffer) - keyboard_buffer_len, data_len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,11 +277,13 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
|
||||
printf("set_report %d %d %d\n", itf, report_id, report_type);
|
||||
if (!hid_set_report_cb || hid_set_report_cb(itf, report_id, report_type, buffer, bufsize) == 0) {
|
||||
//usb_rx(itf, buffer, bufsize);
|
||||
memcpy(hid_rx[itf].buffer + hid_rx[itf].w_ptr, buffer, bufsize);
|
||||
hid_rx[itf].w_ptr += bufsize;
|
||||
int proc_pkt = driver_process_usb_packet_hid(64);
|
||||
if (proc_pkt == 0) {
|
||||
driver_process_usb_nopacket_hid();
|
||||
if (itf == ITF_HID_CTAP) {
|
||||
memcpy(hid_rx[itf].buffer + hid_rx[itf].w_ptr, buffer, bufsize);
|
||||
hid_rx[itf].w_ptr += bufsize;
|
||||
int proc_pkt = driver_process_usb_packet_hid(64);
|
||||
if (proc_pkt == 0) {
|
||||
driver_process_usb_nopacket_hid();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,8 +318,8 @@ int driver_process_usb_nopacket_hid() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern const uint8_t fido_aid[], u2f_aid[];
|
||||
extern void apdu_thread(void), cbor_thread(void);
|
||||
extern const uint8_t fido_aid[], u2f_aid[], oath_aid[];
|
||||
extern void *cbor_thread(void *);
|
||||
|
||||
int driver_process_usb_packet_hid(uint16_t read) {
|
||||
int apdu_sent = 0;
|
||||
@@ -418,7 +411,7 @@ int driver_process_usb_packet_hid(uint16_t read) {
|
||||
}
|
||||
last_packet_time = 0;
|
||||
memcpy(ctap_resp, ctap_req, sizeof(CTAPHID_FRAME));
|
||||
#ifndef ENABLE_EMULATION
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
sleep_ms(1000); //For blinking the device during 1 seg
|
||||
#endif
|
||||
driver_write_hid(ITF_HID_CTAP, (const uint8_t *)ctap_resp, 64);
|
||||
@@ -490,8 +483,10 @@ int driver_process_usb_packet_hid(uint16_t read) {
|
||||
(msg_packet.len == 0 ||
|
||||
(msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) {
|
||||
if (last_cmd == CTAPHID_OTP) {
|
||||
is_nitrokey = true;
|
||||
select_app(fido_aid + 1, fido_aid[0]);
|
||||
is_nk = true;
|
||||
#ifdef ENABLE_OATH_APP
|
||||
select_app(oath_aid + 1, oath_aid[0]);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
select_app(u2f_aid + 1, u2f_aid[0]);
|
||||
@@ -574,7 +569,7 @@ void driver_exec_finished_hid(uint16_t size_next) {
|
||||
ctap_error(apdu.sw & 0xff);
|
||||
}
|
||||
else {
|
||||
if (is_nitrokey) {
|
||||
if (is_nk) {
|
||||
memmove(apdu.rdata + 2, apdu.rdata, size_next - 2);
|
||||
put_uint16_t_be(apdu.sw, apdu.rdata);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,9 @@ extern "C" {
|
||||
#define CFG_TUSB_OS OPT_OS_PICO
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
|
||||
#define CFG_TUSB_OS OPT_OS_FREERTOS
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_NONE
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define TUP_DCD_ENDPOINT_MAX 16
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -87,8 +90,12 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#ifdef _MSC_VER
|
||||
#define CFG_TUSB_MEM_ALIGN __declspec(align(4))
|
||||
#else
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// DEVICE CONFIGURATION
|
||||
|
||||
@@ -3,27 +3,25 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// Pico
|
||||
#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
||||
#include "pico_keys.h"
|
||||
#if defined(PICO_PLATFORM)
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "bsp/board.h"
|
||||
#endif
|
||||
#include "pico_keys.h"
|
||||
#include "usb.h"
|
||||
#include "apdu.h"
|
||||
#ifndef ENABLE_EMULATION
|
||||
@@ -39,11 +37,17 @@
|
||||
// Device specific functions
|
||||
static uint32_t *timeout_counter = NULL;
|
||||
static uint8_t card_locked_itf = 0; // no locked
|
||||
static void (*card_locked_func)(void) = NULL;
|
||||
static void *(*card_locked_func)(void *) = NULL;
|
||||
#ifndef ENABLE_EMULATION
|
||||
static mutex_t mutex;
|
||||
extern void usb_desc_setup();
|
||||
#endif
|
||||
#if !defined(PICO_PLATFORM) && !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
||||
#ifdef _MSC_VER
|
||||
#include "pthread_win32.h"
|
||||
#endif
|
||||
pthread_t hcore0, hcore1;
|
||||
#endif
|
||||
|
||||
#ifdef USB_ITF_HID
|
||||
uint8_t ITF_HID_CTAP = ITF_INVALID, ITF_HID_KB = ITF_INVALID;
|
||||
@@ -76,6 +80,11 @@ void usb_init() {
|
||||
desc_device.idVendor = phy_data.vid;
|
||||
desc_device.idProduct = phy_data.pid;
|
||||
}
|
||||
else {
|
||||
phy_data.vid = desc_device.idVendor;
|
||||
phy_data.pid = desc_device.idProduct;
|
||||
phy_data.vidpid_present = true;
|
||||
}
|
||||
mutex_init(&mutex);
|
||||
#endif
|
||||
queue_init(&card_to_usb_q, sizeof(uint32_t), 64);
|
||||
@@ -169,7 +178,7 @@ void card_init_core1() {
|
||||
|
||||
uint16_t finished_data_size = 0;
|
||||
|
||||
void card_start(uint8_t itf, void (*func)(void)) {
|
||||
void card_start(uint8_t itf, void *(*func)(void *)) {
|
||||
timeout_start();
|
||||
if (card_locked_itf != itf || card_locked_func != func) {
|
||||
if (card_locked_itf != ITF_TOTAL || card_locked_func != NULL) {
|
||||
@@ -177,7 +186,7 @@ void card_start(uint8_t itf, void (*func)(void)) {
|
||||
}
|
||||
if (func) {
|
||||
multicore_reset_core1();
|
||||
multicore_launch_core1(func);
|
||||
multicore_launch_func_core1(func);
|
||||
}
|
||||
led_set_mode(MODE_MOUNTED);
|
||||
card_locked_itf = itf;
|
||||
@@ -266,3 +275,11 @@ int card_status(uint8_t itf) {
|
||||
}
|
||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
#ifndef USB_ITF_CCID
|
||||
#include "device/usbd_pvt.h"
|
||||
usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
|
||||
*driver_count = 0;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _USB_H_
|
||||
@@ -22,8 +22,11 @@
|
||||
#include "emulation.h"
|
||||
#elif defined(ESP_PLATFORM)
|
||||
#include "esp_compat.h"
|
||||
#else
|
||||
#elif defined(PICO_PLATFORM)
|
||||
#include "pico/util/queue.h"
|
||||
#else
|
||||
#include "queue.h"
|
||||
#include "board.h"
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
@@ -44,7 +47,7 @@
|
||||
#define EV_BUTTON_TIMEOUT 16
|
||||
#define EV_BUTTON_PRESSED 32
|
||||
|
||||
static const uint8_t ITF_INVALID = 0xFF;
|
||||
enum { ITF_INVALID = 0xFF };
|
||||
|
||||
#ifdef USB_ITF_HID
|
||||
extern uint8_t ITF_HID_CTAP, ITF_HID_KB;
|
||||
@@ -74,7 +77,7 @@ extern void usb_task();
|
||||
extern queue_t usb_to_card_q;
|
||||
extern queue_t card_to_usb_q;
|
||||
|
||||
extern void card_start(uint8_t, void (*func)(void));
|
||||
extern void card_start(uint8_t, void *(*func)(void *));
|
||||
extern void card_exit();
|
||||
extern int card_status(uint8_t itf);
|
||||
extern void usb_init();
|
||||
|
||||
@@ -3,21 +3,22 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
#include "tusb.h"
|
||||
#include "usb_descriptors.h"
|
||||
#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM)
|
||||
#if defined(PICO_PLATFORM)
|
||||
#include "pico/unique_id.h"
|
||||
#endif
|
||||
#ifdef ESP_PLATFORM
|
||||
@@ -25,7 +26,6 @@
|
||||
#endif
|
||||
#include "pico_keys_version.h"
|
||||
#include "usb.h"
|
||||
#include "pico_keys.h"
|
||||
|
||||
#ifndef USB_VID
|
||||
#define USB_VID 0xFEFF
|
||||
@@ -34,7 +34,11 @@
|
||||
#define USB_PID 0xFCFD
|
||||
#endif
|
||||
|
||||
#if defined(PICO_PLATFORM) || defined(ESP_PLATFORM)
|
||||
#define USB_BCD 0x0200
|
||||
#else
|
||||
#define USB_BCD 0x0110
|
||||
#endif
|
||||
|
||||
#define USB_CONFIG_ATT_ONE TU_BIT(7)
|
||||
|
||||
@@ -103,8 +107,9 @@ uint8_t const desc_hid_report_kb[] = {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
EPNUM_DUMMY = 1,
|
||||
#ifdef USB_ITF_CCID
|
||||
EPNUM_CCID = 1,
|
||||
EPNUM_CCID,
|
||||
#if TUSB_SMARTCARD_CCID_EPS == 3
|
||||
EPNUM_CCID_INT,
|
||||
#endif
|
||||
@@ -162,13 +167,13 @@ void usb_desc_setup() {
|
||||
#ifdef USB_ITF_HID
|
||||
if (ITF_HID != ITF_INVALID) {
|
||||
TUSB_DESC_TOTAL_LEN += TUD_HID_INOUT_DESC_LEN;
|
||||
const uint8_t desc[] = { TUD_HID_INOUT_DESCRIPTOR(ITF_HID, ITF_HID + 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, TUSB_DIR_IN_MASK | EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10) };
|
||||
const uint8_t desc[] = { TUD_HID_INOUT_DESCRIPTOR(ITF_HID, ITF_HID + 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, (uint8_t)TUSB_DIR_IN_MASK | EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10) };
|
||||
memcpy(p, desc, sizeof(desc));
|
||||
p += sizeof(desc);
|
||||
}
|
||||
if (ITF_KEYBOARD != ITF_INVALID) {
|
||||
TUSB_DESC_TOTAL_LEN += TUD_HID_DESC_LEN;
|
||||
const uint8_t desc_kb[] = { TUD_HID_DESCRIPTOR(ITF_KEYBOARD, ITF_KEYBOARD + 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report_kb), TUSB_DIR_IN_MASK | EPNUM_HID_KB, 16, 5) };
|
||||
const uint8_t desc_kb[] = { TUD_HID_DESCRIPTOR(ITF_KEYBOARD, ITF_KEYBOARD + 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report_kb), (uint8_t)TUSB_DIR_IN_MASK | EPNUM_HID_KB, 16, 5) };
|
||||
memcpy(p, desc_kb, sizeof(desc_kb));
|
||||
p += sizeof(desc_kb);
|
||||
}
|
||||
@@ -199,6 +204,8 @@ uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USB_ITF_WCID
|
||||
|
||||
#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_WEBUSB_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN)
|
||||
#define MS_OS_20_DESC_LEN 0xB2
|
||||
|
||||
@@ -302,6 +309,8 @@ uint8_t const *tud_descriptor_bos_cb(void) {
|
||||
return desc_bos;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// String Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -364,8 +373,8 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
uint8_t buff_avail = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1;
|
||||
if (index >= 4) {
|
||||
const char *product = phy_data.usb_product_present ? phy_data.usb_product : string_desc_arr[2];
|
||||
uint8_t len = MIN(strlen(product), buff_avail);
|
||||
for (int ix = 0; ix < len; chr_count++, ix++) {
|
||||
uint8_t len = (uint8_t)MIN(strlen(product), buff_avail);
|
||||
for (size_t ix = 0; ix < len; chr_count++, ix++) {
|
||||
_desc_str[1 + chr_count] = product[ix];
|
||||
}
|
||||
buff_avail -= len;
|
||||
@@ -374,7 +383,7 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
buff_avail--;
|
||||
}
|
||||
}
|
||||
for (int ix = 0; ix < MIN(strlen(str), buff_avail); chr_count++, ix++) {
|
||||
for (size_t ix = 0; ix < MIN(strlen(str), buff_avail); chr_count++, ix++) {
|
||||
_desc_str[1 + chr_count] = str[ix];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef USB_DESCRIPTORS_H_
|
||||
|
||||
2
tinycbor
2
tinycbor
Submodule tinycbor updated: e27261ed5e...c0aad2fb21
Reference in New Issue
Block a user