49 Commits

Author SHA1 Message Date
Pol Henarejos
41ae81067c Merge remote-tracking branch 'origin/main' 2025-07-09 09:39:05 +02:00
Pol Henarejos
9c878cc5b6 Fix PIV default keys indication.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-07-08 14:13:23 +02:00
Pol Henarejos
31ac28c7de Fix touch policy on mgmt key change.
Fixes #38.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-07-08 13:51:24 +02:00
Pol Henarejos
33ce1c50aa Add autobuild for RP2350.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-07-05 00:52:30 +02:00
Pol Henarejos
edfcd087c1 Fix cross build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-06-22 20:26:53 +02:00
Pol Henarejos
a713eb4e03 Fix ESP32 build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-06-22 20:22:38 +02:00
Pol Henarejos
f2fe6dd5c2 Update README.md
Add Pico Fido2 link.
2025-05-30 11:22:59 +02:00
Pol Henarejos
1a24a9ed1b Revert "Add card personalize 2 tests"
This reverts commit 0c46c1d25ce3c109bb8014914bd812a2a000f0ac.
2025-05-24 14:55:23 +02:00
Pol Henarejos
b62573a6bd Fix data checks.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:55:23 +02:00
Pol Henarejos
58a9d9cf97 Fix reset retry when OTP is enabled.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:55:23 +02:00
Pol Henarejos
bc9681e7b0 Add support for EdDSA with Ed448 curve.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:55:23 +02:00
Pol Henarejos
c39b87019e Add card personalize 2 tests
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:55:23 +02:00
Pol Henarejos
f34cdac00b Rename cmd_version to cmd_version_openpgp
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:50:17 +02:00
Pol Henarejos
f9c1178f4d Move PRODUCT def to a separate file.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:49:48 +02:00
Pol Henarejos
68ac692de6 Rename scan_files to scan_files_openpgp
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:25:21 +02:00
Pol Henarejos
4480e29ecc Rename wait_button_pressed to wait_button_pressed_fid.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-24 14:22:37 +02:00
Pol Henarejos
fccc48de43 Fix change PIN when no PIN was introduced before.
Fixes #32

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-05-12 11:16:18 +02:00
Pol Henarejos
d5a0d85b71 Fix eddsa output folder.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-04-10 19:56:40 +02:00
Pol Henarejos
6dbc8f8f56 Upgrade to v3.6
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-04-10 18:48:27 +02:00
Pol Henarejos
11840f1471 Update build script to automatize EdDSA builds.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-04-10 18:47:35 +02:00
Pol Henarejos
fc4391b433 Upgrade pico keys sdk.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-04-08 18:58:19 +02:00
Pol Henarejos
b8a3969fad Build and sign firmware.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-04-08 18:58:06 +02:00
Pol Henarejos
0cf673ac6d Fix build name.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-23 00:56:07 +01:00
Pol Henarejos
142511c494 Fix commissioned values for LED.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-23 00:54:09 +01:00
Pol Henarejos
6de499e435 Add EdDSA support as a conditional build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 20:29:42 +01:00
Pol Henarejos
ddb6b4b936 Add EDDSA as a conditional build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 20:27:28 +01:00
Pol Henarejos
5ec7402e81 Merge branch 'eddsa' 2025-02-21 20:22:44 +01:00
Pol Henarejos
153c60fb47 Fix cyw43 build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 17:34:41 +01:00
Pol Henarejos
3e5f882071 Fix cyw43 build.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-21 17:34:09 +01:00
Pol Henarejos
34c35ed36f Upgrade to v3.4
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-02-19 20:24:39 +01:00
Pol Henarejos
7050e6b19f Upgrade to version 3.2
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-15 11:24:15 +01:00
Pol Henarejos
b1161c4614 Update Pico Keys SDK EdDSA pointer.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-08 10:21:35 +01:00
Pol Henarejos
64a2d240d4 Merge branch 'main' into eddsa
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2025-01-05 20:01:42 +01:00
Pol Henarejos
7f24b9f6b8 Upgrade to version 3.0
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-11-10 21:35:30 +01:00
Pol Henarejos
1d508f254d Not used
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 20:10:00 +02:00
Pol Henarejos
09af4625a9 Fix indentation.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 20:02:06 +02:00
Pol Henarejos
befe99576c Merge branch 'main' into eddsa
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 20:01:54 +02:00
Pol Henarejos
77299f7047 Add esp32 cmake.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 19:23:19 +02:00
Pol Henarejos
2fd07a7dc3 Add EDDSA algo.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 19:22:30 +02:00
Pol Henarejos
6e11171416 Merge branch 'main' into eddsa
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 19:22:18 +02:00
Pol Henarejos
631ffbe4a7 Update cmake
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 17:46:04 +02:00
Pol Henarejos
88e19bae35 Update sdk
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 17:44:08 +02:00
Pol Henarejos
90af0da7a0 Rename
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 17:43:41 +02:00
Pol Henarejos
cb2d784522 Update modules
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2024-09-30 17:38:01 +02:00
Pol Henarejos
08a40e757a Merge branch 'main' into eddsa 2023-09-05 01:14:02 +02:00
Pol Henarejos
939c7fa7ab Add workflow to eddsa branch.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2023-09-05 01:10:52 +02:00
Pol Henarejos
91bcd9f9cd Fix EdDSA signature return format.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2023-09-05 01:04:44 +02:00
Pol Henarejos
88f5bbfd58 Added support for Ed25519.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2023-09-05 00:18:06 +02:00
Pol Henarejos
e480d57881 Update HSM SDK pointer.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2023-09-04 17:26:53 +02:00
25 changed files with 282 additions and 167 deletions

View File

@@ -35,7 +35,7 @@ jobs:
language: [ 'cpp', 'python' ] language: [ 'cpp', 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
mode: [ 'pico', 'esp32', 'local' ] mode: [ 'pico', 'local' ]
steps: steps:
- name: Checkout repository - name: Checkout repository

View File

@@ -19,13 +19,20 @@ jobs:
with: with:
ref: ${{ matrix.refs }} ref: ${{ matrix.refs }}
submodules: 'recursive' submodules: 'recursive'
- name: Restore private key
run: |
echo "${{ secrets.PRIVATE_KEY_B64 }}" | base64 -d > private.pem
chmod 600 private.pem
- name : Build - name : Build
env: env:
PICO_SDK_PATH: ../pico-sdk PICO_SDK_PATH: ../pico-sdk
SECURE_BOOT_PKEY: ../private.pem
run: | run: |
./workflows/autobuild.sh pico ./workflows/autobuild.sh pico
./build_pico_openpgp.sh ./build_pico_openpgp.sh --no-eddsa
./workflows/autobuild.sh esp32 ./workflows/autobuild.sh esp32
- name: Delete private key
run: rm private.pem
- name: Update nightly release - name: Update nightly release
uses: pyTooling/Actions/releaser@main uses: pyTooling/Actions/releaser@main
with: with:

View File

@@ -14,10 +14,10 @@ name: "Emulation and test"
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: [ "main", "piv" ] branches: [ "main", "piv", "eddsa" ]
pull_request: pull_request:
# The branches below must be a subset of the branches above # The branches below must be a subset of the branches above
branches: [ "main", "piv" ] branches: [ "main", "piv", "eddsa" ]
schedule: schedule:
- cron: '23 5 * * 4' - cron: '23 5 * * 4'

View File

@@ -45,6 +45,13 @@ else()
add_executable(pico_openpgp) add_executable(pico_openpgp)
endif() endif()
set(USB_ITF_CCID 1)
set(USB_ITF_WCID 1)
include(pico-keys-sdk/pico_keys_sdk_import.cmake)
if(NOT ESP_PLATFORM)
set(SOURCES ${PICO_KEYS_SOURCES})
endif()
set(SOURCES ${SOURCES} set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/openpgp.c ${CMAKE_CURRENT_LIST_DIR}/src/openpgp/openpgp.c
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/files.c ${CMAKE_CURRENT_LIST_DIR}/src/openpgp/files.c
@@ -67,12 +74,9 @@ set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/cmd_keypair_gen.c ${CMAKE_CURRENT_LIST_DIR}/src/openpgp/cmd_keypair_gen.c
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/cmd_reset_retry.c ${CMAKE_CURRENT_LIST_DIR}/src/openpgp/cmd_reset_retry.c
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/do.c ${CMAKE_CURRENT_LIST_DIR}/src/openpgp/do.c
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/defs.c
) )
set(USB_ITF_CCID 1)
set(USB_ITF_WCID 1)
include(pico-keys-sdk/pico_keys_sdk_import.cmake)
SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/openpgp/version.h" 1) SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/openpgp/version.h" 1)
if(ESP_PLATFORM) if(ESP_PLATFORM)

View File

@@ -3,6 +3,8 @@ This project aims at transforming your Raspberry Pico or ESP32 microcontroller i
OpenPGP cards are used to manage PGP keys and do cryptographic operations, such as keypair generation, signing and asymmetric deciphering. Pico OpenPGP follows the [**OpenPGP 3.4.1** specifications](https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.pdf "**OpenPGP 3.4.1** specifications"), available at [GnuPG](http://gnupg.org "GnuPG"). OpenPGP cards are used to manage PGP keys and do cryptographic operations, such as keypair generation, signing and asymmetric deciphering. Pico OpenPGP follows the [**OpenPGP 3.4.1** specifications](https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.pdf "**OpenPGP 3.4.1** specifications"), available at [GnuPG](http://gnupg.org "GnuPG").
If you are looking for a OpenPGP + Fido, see: https://github.com/polhenarejos/pico-fido2
## Features ## Features
Pico OpenPGP has implemented the following features: Pico OpenPGP has implemented the following features:

View File

@@ -1 +1 @@
Version=3.4 Version=3.6

View File

@@ -1,23 +1,48 @@
#!/bin/bash #!/bin/bash
VERSION_MAJOR="3" VERSION_MAJOR="3"
VERSION_MINOR="4" VERSION_MINOR="6"
NO_EDDSA=0
SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}" SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}"
#if ! [[ -z "${GITHUB_SHA}" ]]; then #if ! [[ -z "${GITHUB_SHA}" ]]; then
# SUFFIX="${SUFFIX}.${GITHUB_SHA}" # SUFFIX="${SUFFIX}.${GITHUB_SHA}"
#fi #fi
rm -rf release/* if [[ $1 == "--no-eddsa" ]]; then
NO_EDDSA=1
echo "Skipping EDDSA build"
fi
mkdir -p build_release mkdir -p build_release
mkdir -p release mkdir -p release
mkdir -p release_eddsa
rm -rf -- release/*
if [[ $NO_EDDSA -eq 0 ]]; then
rm -rf -- release_eddsa/*
fi
cd build_release cd build_release
PICO_SDK_PATH="${PICO_SDK_PATH:-../../pico-sdk}" PICO_SDK_PATH="${PICO_SDK_PATH:-../../pico-sdk}"
SECURE_BOOT_PKEY="${SECURE_BOOT_PKEY:-../../ec_private_key.pem}"
board_dir=${PICO_SDK_PATH}/src/boards/include/boards board_dir=${PICO_SDK_PATH}/src/boards/include/boards
for board in "$board_dir"/* for board in "$board_dir"/*
do do
board_name="$(basename -- $board .h)" board_name="$(basename -- "$board" .h)"
rm -rf * rm -rf -- ./*
PICO_SDK_PATH="${PICO_SDK_PATH}" cmake .. -DPICO_BOARD=$board_name PICO_SDK_PATH="${PICO_SDK_PATH}" cmake .. -DPICO_BOARD=$board_name -DSECURE_BOOT_PKEY=${SECURE_BOOT_PKEY}
make -j`nproc` make -j`nproc`
mv pico_openpgp.uf2 ../release/pico_openpgp_$board_name-$SUFFIX.uf2 mv pico_openpgp.uf2 ../release/pico_openpgp_$board_name-$SUFFIX.uf2
done done
# Build with EDDSA
if [[ $NO_EDDSA -eq 0 ]]; then
for board in "$board_dir"/*
do
board_name="$(basename -- "$board" .h)"
rm -rf -- ./*
PICO_SDK_PATH="${PICO_SDK_PATH}" cmake .. -DPICO_BOARD=$board_name -DSECURE_BOOT_PKEY=${SECURE_BOOT_PKEY} -DENABLE_EDDSA=1
make -j`nproc`
mv pico_openpgp.uf2 ../release_eddsa/pico_openpgp_$board_name-$SUFFIX-eddsa1.uf2
done
fi

View File

@@ -1,6 +1,6 @@
idf_component_register( idf_component_register(
SRCS ${SOURCES} SRCS ${SOURCES}
INCLUDE_DIRS . ../../pico-keys-sdk/src ../../pico-keys-sdk/src/fs ../../pico-keys-sdk/src/rng ../../pico-keys-sdk/src/usb INCLUDE_DIRS . ../../pico-keys-sdk/src ../../pico-keys-sdk/src/fs ../../pico-keys-sdk/src/rng ../../pico-keys-sdk/src/usb ../../pico-keys-sdk/tinycbor/src
REQUIRES bootloader_support esp_partition esp_tinyusb zorxx__neopixel mbedtls efuse REQUIRES mbedtls efuse
) )
idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON) idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON)

View File

@@ -29,6 +29,10 @@ int cmd_change_pin() {
} }
uint8_t pin_len = file_get_data(pw)[0]; uint8_t pin_len = file_get_data(pw)[0];
uint16_t r = 0; uint16_t r = 0;
r = check_pin(pw, apdu.data, pin_len);
if (r != 0x9000) {
return r;
}
if ((r = load_dek()) != PICOKEY_OK) { if ((r = load_dek()) != PICOKEY_OK) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
@@ -38,10 +42,6 @@ int cmd_change_pin() {
dek[IV_SIZE + i] ^= otp_key_1[i]; dek[IV_SIZE + i] ^= otp_key_1[i];
} }
} }
r = check_pin(pw, apdu.data, pin_len);
if (r != 0x9000) {
return r;
}
uint8_t dhash[33]; uint8_t dhash[33];
dhash[0] = apdu.nc - pin_len; dhash[0] = apdu.nc - pin_len;
double_hash_pin(apdu.data + pin_len, apdu.nc - pin_len, dhash + 1); double_hash_pin(apdu.data + pin_len, apdu.nc - pin_len, dhash + 1);

View File

@@ -156,8 +156,8 @@ int cmd_import_data() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
} }
else if (algo[0] == ALGO_ECDSA || algo[0] == ALGO_ECDH) { else if (algo[0] == ALGO_ECDSA || algo[0] == ALGO_ECDH || algo[0] == ALGO_EDDSA) {
mbedtls_ecdsa_context ecdsa; mbedtls_ecp_keypair ecdsa;
if (p[1] == NULL || len[1] == 0) { if (p[1] == NULL || len[1] == 0) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
@@ -165,7 +165,7 @@ int cmd_import_data() {
if (gid == MBEDTLS_ECP_DP_NONE) { if (gid == MBEDTLS_ECP_DP_NONE) {
return SW_FUNC_NOT_SUPPORTED(); return SW_FUNC_NOT_SUPPORTED();
} }
mbedtls_ecdsa_init(&ecdsa); mbedtls_ecp_keypair_init(&ecdsa);
if (gid == MBEDTLS_ECP_DP_CURVE25519) { if (gid == MBEDTLS_ECP_DP_CURVE25519) {
mbedtls_ecp_group_load(&ecdsa.grp, gid); mbedtls_ecp_group_load(&ecdsa.grp, gid);
r = mbedtls_mpi_read_binary(&ecdsa.d, p[1], len[1]); r = mbedtls_mpi_read_binary(&ecdsa.d, p[1], len[1]);
@@ -174,17 +174,25 @@ int cmd_import_data() {
r = mbedtls_ecp_read_key(gid, &ecdsa, p[1], len[1]); r = mbedtls_ecp_read_key(gid, &ecdsa, p[1], len[1]);
} }
if (r != 0) { if (r != 0) {
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecp_keypair_free(&ecdsa);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
#ifdef MBEDTLS_EDDSA_C
if (ecdsa.grp.id == MBEDTLS_ECP_DP_ED25519) {
r = mbedtls_ecp_point_edwards(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, random_gen, NULL);
}
else
#endif
{
r = mbedtls_ecp_mul(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, &ecdsa.grp.G, random_gen, NULL); r = mbedtls_ecp_mul(&ecdsa.grp, &ecdsa.Q, &ecdsa.d, &ecdsa.grp.G, random_gen, NULL);
}
if (r != 0) { if (r != 0) {
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecp_keypair_free(&ecdsa);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
r = store_keys(&ecdsa, ALGO_ECDSA, fid, true); r = store_keys(&ecdsa, ALGO_ECDSA, fid, true);
make_ecdsa_response(&ecdsa); make_ecdsa_response(&ecdsa);
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecp_keypair_free(&ecdsa);
if (r != PICOKEY_OK) { if (r != PICOKEY_OK) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }

View File

@@ -37,7 +37,7 @@ int cmd_internal_aut() {
if (!ef) { if (!ef) {
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
if (wait_button_pressed(EF_UIF_AUT) == true) { if (wait_button_pressed_fid(EF_UIF_AUT) == true) {
return SW_SECURE_MESSAGE_EXEC_ERROR(); return SW_SECURE_MESSAGE_EXEC_ERROR();
} }
int r = PICOKEY_OK; int r = PICOKEY_OK;
@@ -57,17 +57,17 @@ int cmd_internal_aut() {
} }
res_APDU_size = olen; res_APDU_size = olen;
} }
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) { else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA || algo[0] == ALGO_EDDSA) {
mbedtls_ecdsa_context ctx; mbedtls_ecp_keypair ctx;
mbedtls_ecdsa_init(&ctx); mbedtls_ecp_keypair_init(&ctx);
r = load_private_key_ecdsa(&ctx, ef, true); r = load_private_key_ecdsa(&ctx, ef, true);
if (r != PICOKEY_OK) { if (r != PICOKEY_OK) {
mbedtls_ecdsa_free(&ctx); mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
size_t olen = 0; size_t olen = 0;
r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen); r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen);
mbedtls_ecdsa_free(&ctx); mbedtls_ecp_keypair_free(&ctx);
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }

View File

@@ -76,23 +76,23 @@ int cmd_keypair_gen() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
} }
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) { else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA || algo[0] == ALGO_EDDSA) {
printf("KEYPAIR ECDSA\r\n"); printf("KEYPAIR ECDSA\r\n");
mbedtls_ecp_group_id gid = get_ec_group_id_from_attr(algo + 1, algo_len - 1); mbedtls_ecp_group_id gid = get_ec_group_id_from_attr(algo + 1, algo_len - 1);
if (gid == MBEDTLS_ECP_DP_NONE) { if (gid == MBEDTLS_ECP_DP_NONE) {
return SW_FUNC_NOT_SUPPORTED(); return SW_FUNC_NOT_SUPPORTED();
} }
mbedtls_ecdsa_context ecdsa; mbedtls_ecp_keypair ecdsa;
mbedtls_ecdsa_init(&ecdsa); mbedtls_ecp_keypair_init(&ecdsa);
uint8_t index = 0; uint8_t index = 0;
r = mbedtls_ecdsa_genkey(&ecdsa, gid, random_gen, &index); r = mbedtls_ecdsa_genkey(&ecdsa, gid, random_gen, &index);
if (r != 0) { if (r != 0) {
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecp_keypair_free(&ecdsa);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
r = store_keys(&ecdsa, algo[0], fid, true); r = store_keys(&ecdsa, algo[0], fid, true);
make_ecdsa_response(&ecdsa); make_ecdsa_response(&ecdsa);
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecp_keypair_free(&ecdsa);
if (r != PICOKEY_OK) { if (r != PICOKEY_OK) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
@@ -127,7 +127,7 @@ int cmd_keypair_gen() {
} }
else if (P1(apdu) == 0x81) { //read else if (P1(apdu) == 0x81) { //read
file_t *ef = search_by_fid(fid + 3, NULL, SPECIFY_EF); file_t *ef = search_by_fid(fid + 3, NULL, SPECIFY_EF);
if (!ef || !ef->data) { if (!file_has_data(ef)) {
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
res_APDU_size = file_get_size(ef); res_APDU_size = file_get_size(ef);

View File

@@ -66,7 +66,7 @@ int cmd_pso() {
if (!ef) { if (!ef) {
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
if (wait_button_pressed(pk_fid == EF_PK_SIG ? EF_UIF_SIG : EF_UIF_DEC) == true) { if (wait_button_pressed_fid(pk_fid == EF_PK_SIG ? EF_UIF_SIG : EF_UIF_DEC) == true) {
return SW_SECURE_MESSAGE_EXEC_ERROR(); return SW_SECURE_MESSAGE_EXEC_ERROR();
} }
int r = PICOKEY_OK; int r = PICOKEY_OK;
@@ -137,18 +137,18 @@ int cmd_pso() {
res_APDU_size = olen; res_APDU_size = olen;
} }
} }
else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) { else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA || algo[0] == ALGO_EDDSA) {
if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) { if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) {
mbedtls_ecdsa_context ctx; mbedtls_ecp_keypair ctx;
mbedtls_ecdsa_init(&ctx); mbedtls_ecp_keypair_init(&ctx);
r = load_private_key_ecdsa(&ctx, ef, true); r = load_private_key_ecdsa(&ctx, ef, true);
if (r != PICOKEY_OK) { if (r != PICOKEY_OK) {
mbedtls_ecdsa_free(&ctx); mbedtls_ecp_keypair_free(&ctx);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
size_t olen = 0; size_t olen = 0;
r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen); r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen);
mbedtls_ecdsa_free(&ctx); mbedtls_ecp_keypair_free(&ctx);
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }

View File

@@ -16,6 +16,7 @@
*/ */
#include "openpgp.h" #include "openpgp.h"
#include "otp.h"
int cmd_reset_retry() { int cmd_reset_retry() {
if (P2(apdu) != 0x81) { if (P2(apdu) != 0x81) {
@@ -44,6 +45,8 @@ int cmd_reset_retry() {
newpin_len = apdu.nc - pin_len; newpin_len = apdu.nc - pin_len;
has_rc = true; has_rc = true;
hash_multi(apdu.data, pin_len, session_rc); hash_multi(apdu.data, pin_len, session_rc);
has_pw1 = has_pw3 = false;
isUserAuthenticated = false;
} }
else if (P1(apdu) == 0x2) { else if (P1(apdu) == 0x2) {
if (!has_pw3) { if (!has_pw3) {
@@ -59,6 +62,11 @@ int cmd_reset_retry() {
if (!tf) { if (!tf) {
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
if (otp_key_1) {
for (int i = 0; i < 32; i++) {
dek[IV_SIZE + i] ^= otp_key_1[i];
}
}
uint8_t def[IV_SIZE + 32 + 32 + 32 + 32]; uint8_t def[IV_SIZE + 32 + 32 + 32 + 32];
memcpy(def, file_get_data(tf), file_get_size(tf)); memcpy(def, file_get_data(tf), file_get_size(tf));
hash_multi(apdu.data + (apdu.nc - newpin_len), newpin_len, session_pw1); hash_multi(apdu.data + (apdu.nc - newpin_len), newpin_len, session_pw1);
@@ -74,6 +82,9 @@ int cmd_reset_retry() {
return SW_MEMORY_FAILURE(); return SW_MEMORY_FAILURE();
} }
low_flash_available(); low_flash_available();
if ((r = load_dek()) != PICOKEY_OK) {
return SW_EXEC_ERROR();
}
return SW_OK(); return SW_OK();
} }
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();

View File

@@ -32,6 +32,6 @@ int cmd_terminate_df() {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
initialize_flash(true); initialize_flash(true);
scan_files(); scan_files_openpgp();
return SW_OK(); return SW_OK();
} }

View File

@@ -18,7 +18,7 @@
#include "openpgp.h" #include "openpgp.h"
#include "version.h" #include "version.h"
int cmd_version() { int cmd_version_openpgp() {
res_APDU[res_APDU_size++] = PIPGP_VERSION_MAJOR; res_APDU[res_APDU_size++] = PIPGP_VERSION_MAJOR;
res_APDU[res_APDU_size++] = PIPGP_VERSION_MINOR; res_APDU[res_APDU_size++] = PIPGP_VERSION_MINOR;
res_APDU[res_APDU_size++] = 0x0; res_APDU[res_APDU_size++] = 0x0;

20
src/openpgp/defs.c Normal file
View File

@@ -0,0 +1,20 @@
/*
* This file is part of the Pico OpenPGP distribution (https://github.com/polhenarejos/pico-openpgp).
* 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/>.
*/
#include "openpgp.h"
uint8_t PICO_PRODUCT = 3;

View File

@@ -28,12 +28,7 @@ int parse_do(uint16_t *fids, int mode) {
data_len = ((int (*)(const file_t *, int))(ef->data))((const file_t *) ef, mode); data_len = ((int (*)(const file_t *, int))(ef->data))((const file_t *) ef, mode);
} }
else { else {
if (ef->data) {
data_len = file_get_size(ef); data_len = file_get_size(ef);
}
else {
data_len = 0;
}
if (mode == 1) { if (mode == 1) {
if (fids[0] > 1 && res_APDU_size > 0) { if (fids[0] > 1 && res_APDU_size > 0) {
if (fids[i + 1] < 0x0100) { if (fids[i + 1] < 0x0100) {
@@ -45,7 +40,7 @@ int parse_do(uint16_t *fids, int mode) {
} }
res_APDU_size += format_tlv_len(data_len, res_APDU + res_APDU_size); res_APDU_size += format_tlv_len(data_len, res_APDU + res_APDU_size);
} }
if (ef->data) { if (file_has_data(ef)) {
memcpy(res_APDU + res_APDU_size, file_get_data(ef), data_len); memcpy(res_APDU + res_APDU_size, file_get_data(ef), data_len);
} }
res_APDU_size += data_len; res_APDU_size += data_len;
@@ -174,20 +169,6 @@ int parse_pw_status(const file_t *f, int mode) {
return res_APDU_size - init_len; return res_APDU_size - init_len;
} }
#define ALGO_RSA_1K 0
#define ALGO_RSA_2k 1
#define ALGO_RSA_3K 2
#define ALGO_RSA_4K 3
#define ALGO_X448 4
#define ALGO_P256K1 5
#define ALGO_P256R1 6
#define ALGO_P384R1 7
#define ALGO_P521R1 8
#define ALGO_BP256R1 9
#define ALGO_BP384R1 10
#define ALGO_BP512R1 11
#define ALGO_CV22519 12
const uint8_t algorithm_attr_x448[] = { const uint8_t algorithm_attr_x448[] = {
4, 4,
ALGO_ECDH, ALGO_ECDH,
@@ -275,6 +256,20 @@ const uint8_t algorithm_attr_cv25519[] = {
0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01
}; };
#ifdef MBEDTLS_EDDSA_C
const uint8_t algorithm_attr_ed25519[] = {
10,
ALGO_EDDSA,
0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01
};
const uint8_t algorithm_attr_ed448[] = {
4,
ALGO_EDDSA,
0x2b, 0x65, 0x71
};
#endif
int parse_algo(const uint8_t *algo, uint16_t tag) { int parse_algo(const uint8_t *algo, uint16_t tag) {
res_APDU[res_APDU_size++] = tag & 0xff; res_APDU[res_APDU_size++] = tag & 0xff;
memcpy(res_APDU + res_APDU_size, algo, algo[0] + 1); memcpy(res_APDU + res_APDU_size, algo, algo[0] + 1);
@@ -300,6 +295,10 @@ int parse_algoinfo(const file_t *f, int mode) {
datalen += parse_algo(algorithm_attr_bp256r1, EF_ALGO_SIG); datalen += parse_algo(algorithm_attr_bp256r1, EF_ALGO_SIG);
datalen += parse_algo(algorithm_attr_bp384r1, EF_ALGO_SIG); datalen += parse_algo(algorithm_attr_bp384r1, EF_ALGO_SIG);
datalen += parse_algo(algorithm_attr_bp512r1, EF_ALGO_SIG); datalen += parse_algo(algorithm_attr_bp512r1, EF_ALGO_SIG);
#ifdef MBEDTLS_EDDSA_C
datalen += parse_algo(algorithm_attr_ed25519, EF_ALGO_SIG);
datalen += parse_algo(algorithm_attr_ed448, EF_ALGO_SIG);
#endif
datalen += parse_algo(algorithm_attr_rsa1k, EF_ALGO_DEC); datalen += parse_algo(algorithm_attr_rsa1k, EF_ALGO_DEC);
datalen += parse_algo(algorithm_attr_rsa2k, EF_ALGO_DEC); datalen += parse_algo(algorithm_attr_rsa2k, EF_ALGO_DEC);
@@ -326,6 +325,10 @@ int parse_algoinfo(const file_t *f, int mode) {
datalen += parse_algo(algorithm_attr_bp256r1, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_bp256r1, EF_ALGO_AUT);
datalen += parse_algo(algorithm_attr_bp384r1, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_bp384r1, EF_ALGO_AUT);
datalen += parse_algo(algorithm_attr_bp512r1, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_bp512r1, EF_ALGO_AUT);
#ifdef MBEDTLS_EDDSA_C
datalen += parse_algo(algorithm_attr_ed25519, EF_ALGO_AUT);
datalen += parse_algo(algorithm_attr_ed448, EF_ALGO_AUT);
#endif
uint16_t lpdif = res_APDU + res_APDU_size - lp - 2; uint16_t lpdif = res_APDU + res_APDU_size - lp - 2;
*lp++ = lpdif >> 8; *lp++ = lpdif >> 8;
*lp++ = lpdif & 0xff; *lp++ = lpdif & 0xff;

View File

@@ -26,3 +26,7 @@ extern const uint8_t algorithm_attr_cv25519[];
extern const uint8_t algorithm_attr_x448[]; extern const uint8_t algorithm_attr_x448[];
extern const uint8_t algorithm_attr_rsa2k[]; extern const uint8_t algorithm_attr_rsa2k[];
extern const uint8_t algorithm_attr_rsa4096[]; extern const uint8_t algorithm_attr_rsa4096[];
#ifdef MBEDTLS_EDDSA_C
extern const uint8_t algorithm_attr_ed25519[];
extern const uint8_t algorithm_attr_ed448[];
#endif

View File

@@ -30,8 +30,9 @@
#include "ccid/ccid.h" #include "ccid/ccid.h"
#include "otp.h" #include "otp.h"
#include "do.h" #include "do.h"
#ifdef MBEDTLS_EDDSA_C
uint8_t PICO_PRODUCT = 3; #include "mbedtls/eddsa.h"
#endif
bool has_pw1 = false; bool has_pw1 = false;
bool has_pw2 = false; bool has_pw2 = false;
@@ -64,7 +65,7 @@ int openpgp_process_apdu();
extern uint32_t board_button_read(void); extern uint32_t board_button_read(void);
bool wait_button_pressed(uint16_t fid) { bool wait_button_pressed_fid(uint16_t fid) {
uint32_t val = EV_PRESS_BUTTON; uint32_t val = EV_PRESS_BUTTON;
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
file_t *ef = search_by_fid(fid, NULL, SPECIFY_ANY); file_t *ef = search_by_fid(fid, NULL, SPECIFY_ANY);
@@ -96,7 +97,7 @@ void select_file(file_t *pe) {
} }
} }
void scan_files() { void scan_files_openpgp() {
scan_flash(); scan_flash();
file_t *ef; file_t *ef;
if ((ef = search_by_fid(EF_FULL_AID, NULL, SPECIFY_ANY))) { if ((ef = search_by_fid(EF_FULL_AID, NULL, SPECIFY_ANY))) {
@@ -285,7 +286,7 @@ void init_openpgp() {
algo_aut = EF_ALGO_PRIV3; algo_aut = EF_ALGO_PRIV3;
pk_dec = EF_PK_DEC; pk_dec = EF_PK_DEC;
pk_aut = EF_PK_AUT; pk_aut = EF_PK_AUT;
scan_files(); scan_files_openpgp();
//cmd_select(); //cmd_select();
} }
@@ -488,8 +489,8 @@ int store_keys(void *key_ctx, int type, uint16_t key_id, bool use_kek) {
mbedtls_mpi_write_binary(&rsa->P, kdata, key_size / 2); mbedtls_mpi_write_binary(&rsa->P, kdata, key_size / 2);
mbedtls_mpi_write_binary(&rsa->Q, kdata + key_size / 2, key_size / 2); mbedtls_mpi_write_binary(&rsa->Q, kdata + key_size / 2, key_size / 2);
} }
else if (type == ALGO_ECDSA || type == ALGO_ECDH) { else if (type == ALGO_ECDSA || type == ALGO_ECDH || type == ALGO_EDDSA) {
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; mbedtls_ecp_keypair *ecdsa = (mbedtls_ecp_keypair *) key_ctx;
size_t olen = 0; size_t olen = 0;
kdata[0] = ecdsa->grp.id & 0xff; kdata[0] = ecdsa->grp.id & 0xff;
mbedtls_ecp_write_key_ext(ecdsa, &olen, kdata + 1, sizeof(kdata) - 1); mbedtls_ecp_write_key_ext(ecdsa, &olen, kdata + 1, sizeof(kdata) - 1);
@@ -558,7 +559,7 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey, bool use_dek) {
return PICOKEY_OK; return PICOKEY_OK;
} }
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey, bool use_dek) { int load_private_key_ecdsa(mbedtls_ecp_keypair *ctx, file_t *fkey, bool use_dek) {
int key_size = file_get_size(fkey); int key_size = file_get_size(fkey);
uint8_t kdata[67]; //Worst case, 521 bit + 1byte uint8_t kdata[67]; //Worst case, 521 bit + 1byte
memcpy(kdata, file_get_data(fkey), key_size); memcpy(kdata, file_get_data(fkey), key_size);
@@ -568,11 +569,19 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey, bool use_de
mbedtls_ecp_group_id gid = kdata[0]; mbedtls_ecp_group_id gid = kdata[0];
int r = mbedtls_ecp_read_key(gid, ctx, kdata + 1, key_size - 1); int r = mbedtls_ecp_read_key(gid, ctx, kdata + 1, key_size - 1);
if (r != 0) { if (r != 0) {
mbedtls_ecdsa_free(ctx); mbedtls_ecp_keypair_free(ctx);
return PICOKEY_EXEC_ERROR; return PICOKEY_EXEC_ERROR;
} }
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
#ifdef MBEDTLS_EDDSA_C
if (ctx->grp.id == MBEDTLS_ECP_DP_ED25519 || ctx->grp.id == MBEDTLS_ECP_DP_ED448) {
r = mbedtls_ecp_point_edwards(&ctx->grp, &ctx->Q, &ctx->d, random_gen, NULL);
}
else
#endif
{
r = mbedtls_ecp_mul(&ctx->grp, &ctx->Q, &ctx->d, &ctx->grp.G, random_gen, NULL); r = mbedtls_ecp_mul(&ctx->grp, &ctx->Q, &ctx->d, &ctx->grp.G, random_gen, NULL);
}
if (r != 0) { if (r != 0) {
mbedtls_ecdsa_free(ctx); mbedtls_ecdsa_free(ctx);
return PICOKEY_EXEC_ERROR; return PICOKEY_EXEC_ERROR;
@@ -617,6 +626,14 @@ mbedtls_ecp_group_id get_ec_group_id_from_attr(const uint8_t *algo, size_t algo_
else if (memcmp(algorithm_attr_x448 + 2, algo, algo_len) == 0) { else if (memcmp(algorithm_attr_x448 + 2, algo, algo_len) == 0) {
return MBEDTLS_ECP_DP_CURVE448; return MBEDTLS_ECP_DP_CURVE448;
} }
#ifdef MBEDTLS_EDDSA_C
else if (memcmp(algorithm_attr_ed25519 + 2, algo, algo_len) == 0) {
return MBEDTLS_ECP_DP_ED25519;
}
else if (memcmp(algorithm_attr_ed448 + 2, algo, algo_len) == 0) {
return MBEDTLS_ECP_DP_ED448;
}
#endif
return MBEDTLS_ECP_DP_NONE; return MBEDTLS_ECP_DP_NONE;
} }
@@ -635,7 +652,7 @@ void make_rsa_response(mbedtls_rsa_context *rsa) {
put_uint16_t_be(res_APDU_size - 5, res_APDU + 3); put_uint16_t_be(res_APDU_size - 5, res_APDU + 3);
} }
void make_ecdsa_response(mbedtls_ecdsa_context *ecdsa) { void make_ecdsa_response(mbedtls_ecp_keypair *ecdsa) {
uint8_t pt[MBEDTLS_ECP_MAX_PT_LEN]; uint8_t pt[MBEDTLS_ECP_MAX_PT_LEN];
size_t plen = 0; size_t plen = 0;
mbedtls_ecp_point_write_binary(&ecdsa->grp, mbedtls_ecp_point_write_binary(&ecdsa->grp,
@@ -728,15 +745,24 @@ int rsa_sign(mbedtls_rsa_context *ctx,
return r; return r;
} }
int ecdsa_sign(mbedtls_ecdsa_context *ctx, int ecdsa_sign(mbedtls_ecp_keypair *ctx,
const uint8_t *data, const uint8_t *data,
size_t data_len, size_t data_len,
uint8_t *out, uint8_t *out,
size_t *out_len) { size_t *out_len) {
int r = 0;
#ifdef MBEDTLS_EDDSA_C
if (ctx->grp.id == MBEDTLS_ECP_DP_ED25519 || ctx->grp.id == MBEDTLS_ECP_DP_ED448) {
r = mbedtls_eddsa_write_signature(ctx, data, data_len, out, 114, out_len, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
}
else
#endif
{
mbedtls_mpi ri, si; mbedtls_mpi ri, si;
mbedtls_mpi_init(&ri); mbedtls_mpi_init(&ri);
mbedtls_mpi_init(&si); mbedtls_mpi_init(&si);
int r = mbedtls_ecdsa_sign(&ctx->grp, &ri, &si, &ctx->d, data, data_len, random_gen, NULL); r = mbedtls_ecdsa_sign(&ctx->grp, &ri, &si, &ctx->d, data, data_len, random_gen, NULL);
if (r == 0) { if (r == 0) {
size_t plen = (ctx->grp.nbits + 7) / 8; size_t plen = (ctx->grp.nbits + 7) / 8;
mbedtls_mpi_write_binary(&ri, out, plen); mbedtls_mpi_write_binary(&ri, out, plen);
@@ -745,6 +771,7 @@ int ecdsa_sign(mbedtls_ecdsa_context *ctx,
} }
mbedtls_mpi_free(&ri); mbedtls_mpi_free(&ri);
mbedtls_mpi_free(&si); mbedtls_mpi_free(&si);
}
return r; return r;
} }
@@ -754,7 +781,7 @@ extern int cmd_get_next_data();
extern int cmd_put_data(); extern int cmd_put_data();
extern int cmd_verify(); extern int cmd_verify();
extern int cmd_select_data(); extern int cmd_select_data();
extern int cmd_version(); extern int cmd_version_openpgp();
extern int cmd_import_data(); extern int cmd_import_data();
extern int cmd_change_pin(); extern int cmd_change_pin();
extern int cmd_mse(); extern int cmd_mse();
@@ -799,7 +826,7 @@ static const cmd_t cmds[] = {
{ INS_INTERNAL_AUT, cmd_internal_aut }, { INS_INTERNAL_AUT, cmd_internal_aut },
{ INS_MSE, cmd_mse }, { INS_MSE, cmd_mse },
{ INS_IMPORT_DATA, cmd_import_data }, { INS_IMPORT_DATA, cmd_import_data },
{ INS_VERSION, cmd_version }, { INS_VERSION, cmd_version_openpgp },
{ INS_SELECT_DATA, cmd_select_data }, { INS_SELECT_DATA, cmd_select_data },
{ INS_GET_NEXT_DATA, cmd_get_next_data }, { INS_GET_NEXT_DATA, cmd_get_next_data },
{ 0x00, 0x0 } { 0x00, 0x0 }

View File

@@ -59,6 +59,7 @@ extern int pin_reset_retries(const file_t *pin, bool force);
#define ALGO_RSA 0x01 #define ALGO_RSA 0x01
#define ALGO_ECDH 0x12 #define ALGO_ECDH 0x12
#define ALGO_ECDSA 0x13 #define ALGO_ECDSA 0x13
#define ALGO_EDDSA 0x16
#define ALGO_AES 0x70 #define ALGO_AES 0x70
#define ALGO_AES_128 0x71 #define ALGO_AES_128 0x71
#define ALGO_AES_192 0x72 #define ALGO_AES_192 0x72
@@ -71,8 +72,8 @@ extern int check_pin(const file_t *pin, const uint8_t *data, size_t len);
extern mbedtls_ecp_group_id get_ec_group_id_from_attr(const uint8_t *algo, size_t algo_len); extern mbedtls_ecp_group_id get_ec_group_id_from_attr(const uint8_t *algo, size_t algo_len);
extern int reset_sig_count(); extern int reset_sig_count();
extern uint16_t algo_dec, algo_aut, pk_dec, pk_aut; extern uint16_t algo_dec, algo_aut, pk_dec, pk_aut;
extern bool wait_button_pressed(uint16_t fid); extern bool wait_button_pressed_fid(uint16_t fid);
extern void scan_files(); extern void scan_files_openpgp();
extern int load_aes_key(uint8_t *aes_key, file_t *fkey); extern int load_aes_key(uint8_t *aes_key, file_t *fkey);
extern int inc_sig_count(); extern int inc_sig_count();
extern int dek_encrypt(uint8_t *data, size_t len); extern int dek_encrypt(uint8_t *data, size_t len);

View File

@@ -218,7 +218,7 @@ static void scan_files_piv() {
uint8_t *key = (uint8_t *)"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"; uint8_t *key = (uint8_t *)"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08";
file_t *ef = search_by_fid(EF_PIV_KEY_CARDMGM, NULL, SPECIFY_ANY); file_t *ef = search_by_fid(EF_PIV_KEY_CARDMGM, NULL, SPECIFY_ANY);
file_put_data(ef, key, 24); file_put_data(ef, key, 24);
uint8_t meta[] = { PIV_ALGO_AES192, PINPOLICY_ALWAYS, TOUCHPOLICY_ALWAYS, ORIGIN_GENERATED }; uint8_t meta[] = { PIV_ALGO_AES192, PINPOLICY_ALWAYS, TOUCHPOLICY_ALWAYS };
meta_add(EF_PIV_KEY_CARDMGM, meta, sizeof(meta)); meta_add(EF_PIV_KEY_CARDMGM, meta, sizeof(meta));
has_pwpiv = false; has_pwpiv = false;
memset(session_pwpiv, 0, sizeof(session_pwpiv)); memset(session_pwpiv, 0, sizeof(session_pwpiv));
@@ -458,6 +458,7 @@ static int cmd_get_metadata() {
res_APDU[res_APDU_size++] = 2; res_APDU[res_APDU_size++] = 2;
res_APDU[res_APDU_size++] = meta[1]; res_APDU[res_APDU_size++] = meta[1];
res_APDU[res_APDU_size++] = meta[2]; res_APDU[res_APDU_size++] = meta[2];
if (key_ref != EF_PIV_KEY_CARDMGM) {
res_APDU[res_APDU_size++] = 0x3; res_APDU[res_APDU_size++] = 0x3;
res_APDU[res_APDU_size++] = 1; res_APDU[res_APDU_size++] = 1;
res_APDU[res_APDU_size++] = meta[3]; res_APDU[res_APDU_size++] = meta[3];
@@ -523,9 +524,10 @@ static int cmd_get_metadata() {
} }
} }
} }
}
if (key_ref == EF_PIV_PIN || key_ref == EF_PIV_PUK || key_ref == EF_PIV_KEY_CARDMGM) { if (key_ref == EF_PIV_PIN || key_ref == EF_PIV_PUK || key_ref == EF_PIV_KEY_CARDMGM) {
uint8_t dhash[32]; uint8_t dhash[32];
int32_t eq = false; int32_t eq = 0;
if (key_ref == EF_PIV_PIN) { if (key_ref == EF_PIV_PIN) {
double_hash_pin((const uint8_t *)"\x31\x32\x33\x34\x35\x36\xFF\xFF", 8, dhash); double_hash_pin((const uint8_t *)"\x31\x32\x33\x34\x35\x36\xFF\xFF", 8, dhash);
eq = memcmp(dhash, file_get_data(ef_key) + 1, file_get_size(ef_key) - 1); eq = memcmp(dhash, file_get_data(ef_key) + 1, file_get_size(ef_key) - 1);
@@ -539,7 +541,7 @@ static int cmd_get_metadata() {
} }
res_APDU[res_APDU_size++] = 0x5; res_APDU[res_APDU_size++] = 0x5;
res_APDU[res_APDU_size++] = 1; res_APDU[res_APDU_size++] = 1;
res_APDU[res_APDU_size++] = eq; res_APDU[res_APDU_size++] = eq == 0;
if (key_ref == EF_PIV_PIN || key_ref == EF_PIV_PUK) { if (key_ref == EF_PIV_PIN || key_ref == EF_PIV_PUK) {
file_t *pw_status; file_t *pw_status;
if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF))) { if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF))) {
@@ -983,13 +985,14 @@ static int cmd_set_mgmkey() {
} }
uint8_t touch = P2(apdu); uint8_t touch = P2(apdu);
if (touch != 0xFF && touch != 0xFE) { if (touch != 0xFF && touch != 0xFE) {
return SW_INCORRECT_P1P2();
}
if (touch == 0xFF) { if (touch == 0xFF) {
touch = TOUCHPOLICY_NEVER; touch = TOUCHPOLICY_NEVER;
} }
else if (touch == 0xFE) { else if (touch == 0xFE) {
touch = TOUCHPOLICY_ALWAYS; touch = TOUCHPOLICY_ALWAYS;
} }
}
uint8_t algo = apdu.data[0], key_ref = apdu.data[1], pinlen = apdu.data[2]; uint8_t algo = apdu.data[0], key_ref = apdu.data[1], pinlen = apdu.data[2];
if ((key_ref != EF_PIV_KEY_CARDMGM) || (!(algo == PIV_ALGO_AES128 && pinlen == 16) && !(algo == PIV_ALGO_AES192 && pinlen == 24) && !(algo == PIV_ALGO_AES256 && pinlen == 32) && !(algo == PIV_ALGO_3DES && pinlen == 24))) { if ((key_ref != EF_PIV_KEY_CARDMGM) || (!(algo == PIV_ALGO_AES128 && pinlen == 16) && !(algo == PIV_ALGO_AES192 && pinlen == 24) && !(algo == PIV_ALGO_AES256 && pinlen == 32) && !(algo == PIV_ALGO_3DES && pinlen == 24))) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();

View File

@@ -29,7 +29,7 @@
#define PIV_VERSION_MINOR (PIV_VERSION & 0xff) #define PIV_VERSION_MINOR (PIV_VERSION & 0xff)
#define PIPGP_VERSION 0x0304 #define PIPGP_VERSION 0x0306
#define PIPGP_VERSION_MAJOR ((PIPGP_VERSION >> 8) & 0xff) #define PIPGP_VERSION_MAJOR ((PIPGP_VERSION >> 8) & 0xff)
#define PIPGP_VERSION_MINOR (PIPGP_VERSION & 0xff) #define PIPGP_VERSION_MINOR (PIPGP_VERSION & 0xff)

View File

@@ -3,5 +3,5 @@
source tests/docker_env.sh source tests/docker_env.sh
#run_in_docker rm -rf CMakeFiles #run_in_docker rm -rf CMakeFiles
run_in_docker mkdir -p build_in_docker run_in_docker mkdir -p build_in_docker
run_in_docker -w "$PWD/build_in_docker" cmake -DENABLE_EMULATION=1 .. run_in_docker -w "$PWD/build_in_docker" cmake -DENABLE_EMULATION=1 -DENABLE_EDDSA=1 ..
run_in_docker -w "$PWD/build_in_docker" make -j ${NUM_PROC} run_in_docker -w "$PWD/build_in_docker" make -j ${NUM_PROC}