Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcefdb3c84 | ||
|
|
685ee2bbd5 | ||
|
|
6ae2a91e55 | ||
|
|
2373f21994 | ||
|
|
25bddb7230 | ||
|
|
418fa9c143 | ||
|
|
ce9ef47bb2 | ||
|
|
603963123b | ||
|
|
79ce35e944 | ||
|
|
5ddfa6382b | ||
|
|
9a99baafca | ||
|
|
819fb99646 |
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
||||
[submodule "pico-ccid"]
|
||||
path = pico-ccid
|
||||
url = https://github.com/polhenarejos/pico-ccid.git
|
||||
[submodule "pico-hsm-sdk"]
|
||||
path = pico-hsm-sdk
|
||||
url = ../pico-hsm-sdk
|
||||
|
||||
@@ -28,65 +28,18 @@ pico_sdk_init()
|
||||
|
||||
add_executable(pico_openpgp)
|
||||
|
||||
if (NOT DEFINED USB_VID)
|
||||
set(USB_VID 0xFEFF)
|
||||
endif()
|
||||
add_definitions(-DUSB_VID=${USB_VID})
|
||||
if (NOT DEFINED USB_PID)
|
||||
set(USB_PID 0xFCFD)
|
||||
endif()
|
||||
add_definitions(-DUSB_PID=${USB_PID})
|
||||
|
||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/pico-ccid/config/mbedtls_config.h ${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/include/mbedtls COPYONLY)
|
||||
|
||||
target_sources(pico_openpgp PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/usb/usb.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/usb/usb_descriptors.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/ccid2040.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/asn1.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs/file.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs/flash.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs/low_flash.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/rng/random.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/rng/neug.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/crypto_utils.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid/eac.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/openpgp.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/files.c
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/aes.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/asn1parse.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/bignum.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/cmac.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/cipher.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/cipher_wrap.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/constant_time.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecdsa.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecdh.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecp.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ecp_curves.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/md.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/md5.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/oid.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/platform_util.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/ripemd160.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/rsa.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/rsa_alt_helpers.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/sha1.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/sha256.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library/sha512.c
|
||||
)
|
||||
|
||||
target_include_directories(pico_openpgp PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/fs
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/openpgp
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/ccid
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/rng
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/src/usb
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/include
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-ccid/mbedtls/library
|
||||
)
|
||||
|
||||
set(HSM_DRIVER "ccid")
|
||||
include(pico-hsm-sdk/pico_hsm_sdk_import.cmake)
|
||||
|
||||
target_compile_options(pico_openpgp PUBLIC
|
||||
-Wall
|
||||
-Werror
|
||||
@@ -96,4 +49,4 @@ pico_add_extra_outputs(pico_openpgp)
|
||||
|
||||
#target_compile_definitions(pico_openpgp PRIVATE MBEDTLS_ECDSA_DETERMINISTIC=1)
|
||||
|
||||
target_link_libraries(pico_openpgp PRIVATE pico_stdlib tinyusb_device tinyusb_board pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc)
|
||||
target_link_libraries(pico_openpgp PRIVATE pico_hsm_sdk pico_stdlib tinyusb_device tinyusb_board pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc)
|
||||
|
||||
12
README.md
12
README.md
@@ -26,9 +26,19 @@ Pico OpenPGP has implemented the following features:
|
||||
- Key Derivation Function (KDF) for PIN.
|
||||
- Manage Security Environment (MSE).
|
||||
- DEK for internal safe storage.
|
||||
- AES key generation.
|
||||
- AES ciphering and deciphering.
|
||||
- Cardholder certificates support.
|
||||
|
||||
All these features are compliant with the specification. Therefore, if you detect some behaviour that is not expected or it does not follow the rules of specs, please open an issue.
|
||||
|
||||
## AES support
|
||||
There is no known software that supports AES with OpenPGP. Nevertheless, it can be used with customized PKCS11 modules or interfacing with raw APDU packets.
|
||||
|
||||
During asymmetric key generation for DEC key, Pico OpenPGP also generates a 32 bits symmetric key for AES operations.
|
||||
|
||||
OpenPGP card 3.4 specifications describe the procedure to perform ciphering (encryption and decryption) with AES via PSO:ENCIPHER and PSO:DECIPHER. Both commands are supported by Pico OpenPGP.
|
||||
|
||||
### About Gnuk
|
||||
This project was inspired by [Gnuk](https://wiki.debian.org/GNUK "Gnuk"), a same project but focused on STM32 processor family. Despite the initial idea was to port Gnuk to the Raspberry Pico family, the underlaying architecture is widely different (although boh run on ARM). For instance, the Pico has two ARM cores, with an appropiate SDK able to leverage them. Also, Pico has an internal flash storage, which is farly larger compared to STM32 ROM storage. Finally, the Pico has a complete USB interface based on TinyUSB, which difficults to port Gnuk. These are only few examples of the difficulties of porting Gnuk to the Raspberry Pico.
|
||||
|
||||
@@ -122,6 +132,6 @@ OpenSC relies on PCSC driver, which reads a list (`Info.plist`) that contains a
|
||||
|
||||
## Credits
|
||||
Pico OpenPGP uses the following libraries or portion of code:
|
||||
- mbedTLS for cryptographic operations.
|
||||
- MbedTLS for cryptographic operations.
|
||||
- TinyUSB for low level USB procedures.
|
||||
|
||||
|
||||
@@ -1,21 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION_MAJOR="1"
|
||||
VERSION_MINOR="6"
|
||||
VERSION_MINOR="8"
|
||||
|
||||
rm -rf release/*
|
||||
cd build_release
|
||||
|
||||
for board in adafruit_feather_rp2040 adafruit_itsybitsy_rp2040 adafruit_qtpy_rp2040 adafruit_trinkey_qt2040 arduino_nano_rp2040_connect melopero_shake_rp2040 pimoroni_interstate75 pimoroni_keybow2040 pimoroni_pga2040 pimoroni_picolipo_4mb pimoroni_picolipo_16mb pimoroni_picosystem pimoroni_plasma2040 pimoroni_tiny2040 pybstick26_rp2040 sparkfun_micromod sparkfun_promicro sparkfun_thingplus vgaboard waveshare_rp2040_lcd_0.96 waveshare_rp2040_plus_4mb waveshare_rp2040_plus_16mb waveshare_rp2040_zero
|
||||
for board in adafruit_feather_rp2040 \
|
||||
adafruit_itsybitsy_rp2040 \
|
||||
adafruit_kb2040 \
|
||||
adafruit_macropad_rp2040 \
|
||||
adafruit_qtpy_rp2040 \
|
||||
adafruit_trinkey_qt2040 \
|
||||
arduino_nano_rp2040_connect \
|
||||
datanoisetv_rp2040_dsp \
|
||||
eetree_gamekit_rp2040 \
|
||||
garatronic_pybstick26_rp2040 \
|
||||
melopero_shake_rp2040 \
|
||||
pico \
|
||||
pico_w \
|
||||
pimoroni_badger2040 \
|
||||
pimoroni_interstate75 \
|
||||
pimoroni_keybow2040 \
|
||||
pimoroni_motor2040 \
|
||||
pimoroni_pga2040 \
|
||||
pimoroni_picolipo_4mb \
|
||||
pimoroni_picolipo_16mb \
|
||||
pimoroni_picosystem \
|
||||
pimoroni_plasma2040 \
|
||||
pimoroni_servo2040 \
|
||||
pimoroni_tiny2040 \
|
||||
pimoroni_tiny2040_2mb \
|
||||
seeed_xiao_rp2040 \
|
||||
solderparty_rp2040_stamp \
|
||||
solderparty_rp2040_stamp_carrier \
|
||||
solderparty_rp2040_stamp_round_carrier \
|
||||
sparkfun_micromod \
|
||||
sparkfun_promicro \
|
||||
sparkfun_thingplus \
|
||||
vgaboard \
|
||||
waveshare_rp2040_lcd_0.96 \
|
||||
waveshare_rp2040_plus_4mb \
|
||||
waveshare_rp2040_plus_16mb \
|
||||
waveshare_rp2040_zero \
|
||||
wiznet_w5100s_evb_pico
|
||||
do
|
||||
rm -rf *
|
||||
PICO_SDK_PATH=~/Devel/pico/pico-sdk cmake .. -DPICO_BOARD=$board
|
||||
PICO_SDK_PATH=../../pico-sdk cmake .. -DPICO_BOARD=$board
|
||||
make -kj20
|
||||
mv pico_openpgp.uf2 ../release/pico_openpgp_$board-$VERSION_MAJOR.$VERSION_MINOR.uf2
|
||||
|
||||
done
|
||||
|
||||
rm -rf *
|
||||
PICO_SDK_PATH=~/Devel/pico/pico-sdk cmake ..
|
||||
make -kj20
|
||||
mv pico_openpgp.uf2 ../release/pico_openpgp_pico_generic-$VERSION_MAJOR.$VERSION_MINOR.uf2
|
||||
@@ -17,8 +17,8 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
VERSION_MAJOR="2" #Version of Pico CCID Core
|
||||
VERSION_MINOR="0"
|
||||
VERSION_MAJOR="3" #Version of Pico CCID Core
|
||||
VERSION_MINOR="4"
|
||||
|
||||
echo "----------------------------"
|
||||
echo "VID/PID patcher for Pico OpenPGP"
|
||||
|
||||
Submodule pico-ccid deleted from fe53f9a729
1
pico-hsm-sdk
Submodule
1
pico-hsm-sdk
Submodule
Submodule pico-hsm-sdk added at c4178fda4b
@@ -27,6 +27,8 @@
|
||||
#include "mbedtls/ecdh.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "asn1.h"
|
||||
#include "usb.h"
|
||||
#include "ccid.h"
|
||||
|
||||
bool has_pw1 = false;
|
||||
bool has_pw2 = false;
|
||||
@@ -57,13 +59,13 @@ int openpgp_process_apdu();
|
||||
|
||||
extern uint32_t board_button_read(void);
|
||||
|
||||
static bool wait_button(uint16_t fid) {
|
||||
static bool wait_button_pressed(uint16_t fid) {
|
||||
file_t *ef = search_by_fid(fid, NULL, SPECIFY_ANY);
|
||||
uint32_t val = EV_PRESS_BUTTON;
|
||||
if (ef && ef->data && file_read_uint8(ef->data+2) > 0) {
|
||||
queue_try_add(&card_to_ccid_q, &val);
|
||||
if (ef && ef->data && file_get_data(ef)[0] > 0) {
|
||||
queue_try_add(&card_to_usb_q, &val);
|
||||
do {
|
||||
queue_remove_blocking(&ccid_to_card_q, &val);
|
||||
queue_remove_blocking(&usb_to_card_q, &val);
|
||||
}
|
||||
while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT);
|
||||
}
|
||||
@@ -265,12 +267,12 @@ int load_dek() {
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
int r = CCID_OK;
|
||||
if (has_pw1 || has_pw2) {
|
||||
memcpy(dek, file_read(tf->data+sizeof(uint16_t)), IV_SIZE+32);
|
||||
memcpy(dek, file_get_data(tf), IV_SIZE+32);
|
||||
r = aes_decrypt_cfb_256(session_pw1, dek, dek+IV_SIZE, 32);
|
||||
}
|
||||
else if (has_pw3) {
|
||||
memcpy(dek, file_read(tf->data+sizeof(uint16_t)), IV_SIZE);
|
||||
memcpy(dek+IV_SIZE, file_read(tf->data+sizeof(uint16_t)+IV_SIZE+32), 32);
|
||||
memcpy(dek, file_get_data(tf), IV_SIZE);
|
||||
memcpy(dek+IV_SIZE, file_get_data(tf)+IV_SIZE+32, 32);
|
||||
r = aes_decrypt_cfb_256(session_pw3, dek, dek+IV_SIZE, 32);
|
||||
}
|
||||
if (r != 0)
|
||||
@@ -365,7 +367,7 @@ int parse_do(uint16_t *fids, int mode) {
|
||||
}
|
||||
else {
|
||||
if (ef->data)
|
||||
data_len = file_read_uint16(ef->data);
|
||||
data_len = file_get_size(ef);
|
||||
else
|
||||
data_len = 0;
|
||||
if (mode == 1) {
|
||||
@@ -380,7 +382,7 @@ int parse_do(uint16_t *fids, int mode) {
|
||||
res_APDU_size += format_tlv_len(data_len, res_APDU+res_APDU_size);
|
||||
}
|
||||
if (ef->data)
|
||||
memcpy(res_APDU+res_APDU_size, file_read(ef->data+2), data_len);
|
||||
memcpy(res_APDU+res_APDU_size, file_get_data(ef), data_len);
|
||||
res_APDU_size += data_len;
|
||||
}
|
||||
}
|
||||
@@ -394,8 +396,8 @@ int parse_trium(uint16_t fid, uint8_t num, size_t size) {
|
||||
for (uint8_t i = 0; i < num; i++) {
|
||||
file_t *ef;
|
||||
if ((ef = search_by_fid(fid+i, NULL, SPECIFY_EF)) && ef->data) {
|
||||
uint16_t data_len = file_read_uint16(ef->data);
|
||||
memcpy(res_APDU+res_APDU_size, file_read(ef->data+2), data_len);
|
||||
uint16_t data_len = file_get_size(ef);
|
||||
memcpy(res_APDU+res_APDU_size, file_get_data(ef), data_len);
|
||||
res_APDU_size += data_len;
|
||||
}
|
||||
else {
|
||||
@@ -426,12 +428,12 @@ int inc_sig_count() {
|
||||
file_t *pw_status;
|
||||
if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF)) || !pw_status->data)
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
if (file_read_uint8(pw_status->data+2) == 1)
|
||||
if (file_get_data(pw_status)[0] == 1)
|
||||
has_pw1 = false;
|
||||
file_t *ef = search_by_fid(EF_SIG_COUNT, NULL, SPECIFY_ANY);
|
||||
if (!ef || !ef->data)
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
uint8_t *p = file_read(ef->data+2);
|
||||
uint8_t *p = file_get_data(ef);
|
||||
uint32_t counter = (p[0] << 16) | (p[1] << 8) | p[2];
|
||||
counter++;
|
||||
uint8_t q[3] = { (counter>>16) & 0xff, (counter>>8) & 0xff, counter&0xff };
|
||||
@@ -461,7 +463,7 @@ int parse_sec_tpl(const file_t *f, int mode) {
|
||||
if (ef && ef->data) {
|
||||
res_APDU[res_APDU_size++] = EF_SIG_COUNT & 0xff;
|
||||
res_APDU[res_APDU_size++] = 3;
|
||||
memcpy(res_APDU+res_APDU_size, file_read(ef->data+2), 3);
|
||||
memcpy(res_APDU+res_APDU_size, file_get_data(ef), 3);
|
||||
res_APDU_size += 3;
|
||||
}
|
||||
return 5+2;
|
||||
@@ -527,7 +529,7 @@ int parse_pw_status(const file_t *f, int mode) {
|
||||
}
|
||||
ef = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_ANY);
|
||||
if (ef && ef->data) {
|
||||
memcpy(res_APDU+res_APDU_size, file_read(ef->data+2), 7);
|
||||
memcpy(res_APDU+res_APDU_size, file_get_data(ef), 7);
|
||||
res_APDU_size += 7;
|
||||
}
|
||||
return res_APDU_size-init_len;
|
||||
@@ -701,13 +703,13 @@ int parse_algoinfo(const file_t *f, int mode) {
|
||||
if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF)) || !ef->data)
|
||||
datalen += parse_algo(algorithm_attr_rsa2k, f->fid);
|
||||
else {
|
||||
uint16_t len = file_read_uint16(ef->data);
|
||||
uint16_t len = file_get_size(ef);
|
||||
if (res_APDU_size > 0) {
|
||||
res_APDU[res_APDU_size++] = f->fid & 0xff;
|
||||
res_APDU[res_APDU_size++] = len & 0xff;
|
||||
datalen += 2;
|
||||
}
|
||||
memcpy(res_APDU+res_APDU_size, file_read(ef->data+2), len);
|
||||
memcpy(res_APDU+res_APDU_size, file_get_data(ef), len);
|
||||
res_APDU_size += len;
|
||||
datalen += len;
|
||||
}
|
||||
@@ -778,12 +780,12 @@ int pin_reset_retries(const file_t *pin, bool force) {
|
||||
if (!pw_status)
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
uint8_t p[7];
|
||||
memcpy(p, file_read(pw_status->data+2), 7);
|
||||
memcpy(p, file_get_data(pw_status), 7);
|
||||
uint8_t retries = p[3+(pin->fid&0x3)];
|
||||
if (retries == 0 && force == false) //blocked
|
||||
return CCID_ERR_BLOCKED;
|
||||
p[3+(pin->fid&0x3)] = 3;
|
||||
int r = flash_write_data_to_file(pw_status, p, file_read_uint16(pw_status->data));
|
||||
int r = flash_write_data_to_file(pw_status, p, file_get_size(pw_status));
|
||||
low_flash_available();
|
||||
return r;
|
||||
}
|
||||
@@ -795,10 +797,10 @@ int pin_wrong_retry(const file_t *pin) {
|
||||
if (!pw_status)
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
uint8_t p[7];
|
||||
memcpy(p, file_read(pw_status->data+2), 7);
|
||||
memcpy(p, file_get_data(pw_status), 7);
|
||||
if (p[3+(pin->fid&0x3)] > 0) {
|
||||
p[3+(pin->fid&0x3)] -= 1;
|
||||
int r = flash_write_data_to_file(pw_status, p, file_read_uint16(pw_status->data));
|
||||
int r = flash_write_data_to_file(pw_status, p, file_get_size(pw_status));
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
low_flash_available();
|
||||
@@ -820,9 +822,9 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
|
||||
|
||||
uint8_t dhash[32];
|
||||
double_hash_pin(data, len, dhash);
|
||||
if (sizeof(dhash) != file_read_uint16(pin->data)-1) //1 byte for pin len
|
||||
if (sizeof(dhash) != file_get_size(pin)-1) //1 byte for pin len
|
||||
return SW_CONDITIONS_NOT_SATISFIED();
|
||||
if (memcmp(file_read(pin->data+3), dhash, sizeof(dhash)) != 0) {
|
||||
if (memcmp(file_get_data(pin)+1, dhash, sizeof(dhash)) != 0) {
|
||||
int retries;
|
||||
if ((retries = pin_wrong_retry(pin)) < CCID_OK)
|
||||
return SW_PIN_BLOCKED();
|
||||
@@ -874,12 +876,12 @@ static int cmd_verify() {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF)))
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
if (file_read_uint8(pw->data+2) == 0) //not initialized
|
||||
if (file_get_data(pw)[0] == 0) //not initialized
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
if (apdu.nc > 0) {
|
||||
return check_pin(pw, apdu.data, apdu.nc);
|
||||
}
|
||||
uint8_t retries = file_read_uint8(pw_status->data+2+3+(fid&0x3));
|
||||
uint8_t retries = *(file_get_data(pw_status)+3+(fid&0x3));
|
||||
if (retries == 0)
|
||||
return SW_PIN_BLOCKED();
|
||||
if ((p2 == 0x81 && has_pw1) || (p2 == 0x82 && has_pw2) || (p2 == 0x83 && has_pw3))
|
||||
@@ -922,7 +924,7 @@ static int cmd_change_pin() {
|
||||
file_t *pw;
|
||||
if (!(pw = search_by_fid(fid, NULL, SPECIFY_EF)))
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
uint8_t pin_len = file_read_uint8(pw->data+2);
|
||||
uint8_t pin_len = file_get_data(pw)[0];
|
||||
uint16_t r = check_pin(pw, apdu.data, pin_len);
|
||||
if (r != 0x9000)
|
||||
return r;
|
||||
@@ -946,7 +948,7 @@ static int cmd_reset_retry() {
|
||||
file_t *rc;
|
||||
if (!(rc = search_by_fid(EF_RC, NULL, SPECIFY_EF)))
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
uint8_t pin_len = file_read_uint8(rc->data+2);
|
||||
uint8_t pin_len = file_get_data(rc)[0];
|
||||
if (apdu.nc <= pin_len)
|
||||
return SW_WRONG_LENGTH();
|
||||
uint16_t r = check_pin(rc, apdu.data, pin_len);
|
||||
@@ -1020,9 +1022,9 @@ int store_keys(void *key_ctx, int type, uint16_t key_id) {
|
||||
}
|
||||
|
||||
int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
|
||||
int key_size = file_read_uint16(fkey->data);
|
||||
int key_size = file_get_size(fkey);
|
||||
uint8_t kdata[4096/8];
|
||||
memcpy(kdata, file_read(fkey->data+2), key_size);
|
||||
memcpy(kdata, file_get_data(fkey), key_size);
|
||||
if (dek_decrypt(kdata, key_size) != 0) {
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
@@ -1054,9 +1056,9 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
|
||||
}
|
||||
|
||||
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
||||
int key_size = file_read_uint16(fkey->data);
|
||||
int key_size = file_get_size(fkey);
|
||||
uint8_t kdata[67]; //Worst case, 521 bit + 1byte
|
||||
memcpy(kdata, file_read(fkey->data+2), key_size);
|
||||
memcpy(kdata, file_get_data(fkey), key_size);
|
||||
if (dek_decrypt(kdata, key_size) != 0) {
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
@@ -1070,8 +1072,8 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
||||
}
|
||||
|
||||
int load_aes_key(uint8_t *aes_key, file_t *fkey) {
|
||||
int key_size = file_read_uint16(fkey->data);
|
||||
memcpy(aes_key, file_read(fkey->data+2), key_size);
|
||||
int key_size = file_get_size(fkey);
|
||||
memcpy(aes_key, file_get_data(fkey), key_size);
|
||||
if (dek_decrypt(aes_key, key_size) != 0) {
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
@@ -1151,8 +1153,8 @@ static int cmd_keypair_gen() {
|
||||
const uint8_t *algo = algorithm_attr_rsa2k+1;
|
||||
uint16_t algo_len = algorithm_attr_rsa2k[0];
|
||||
if (algo_ef && algo_ef->data) {
|
||||
algo = file_read(algo_ef->data+2);
|
||||
algo_len = file_read_uint16(algo_ef->data);
|
||||
algo = file_get_data(algo_ef);
|
||||
algo_len = file_get_size(algo_ef);
|
||||
}
|
||||
if (P1(apdu) == 0x80) { //generate
|
||||
if (algo[0] == ALGO_RSA) {
|
||||
@@ -1221,8 +1223,8 @@ static int cmd_keypair_gen() {
|
||||
file_t *ef = search_by_fid(fid+3, NULL, SPECIFY_EF);
|
||||
if (!ef || !ef->data)
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
res_APDU_size = file_read_uint16(ef->data);
|
||||
memcpy(res_APDU, file_read(ef->data+2), res_APDU_size);
|
||||
res_APDU_size = file_get_size(ef);
|
||||
memcpy(res_APDU, file_get_data(ef), res_APDU_size);
|
||||
return SW_OK();
|
||||
}
|
||||
return SW_INCORRECT_P1P2();
|
||||
@@ -1321,7 +1323,7 @@ static int cmd_pso() {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
const uint8_t *algo = algorithm_attr_rsa2k+1;
|
||||
if (algo_ef && algo_ef->data) {
|
||||
algo = file_read(algo_ef->data+2);
|
||||
algo = file_get_data(algo_ef);
|
||||
}
|
||||
if (apdu.data[0] == 0x2) { //AES PSO?
|
||||
if (((apdu.nc - 1)%16 == 0 && P1(apdu) == 0x80 && P2(apdu) == 0x86) || (apdu.nc%16 == 0 && P1(apdu) == 0x86 && P2(apdu) == 0x80)) {
|
||||
@@ -1332,10 +1334,10 @@ static int cmd_pso() {
|
||||
file_t *ef = search_by_fid(pk_fid, NULL, SPECIFY_EF);
|
||||
if (!ef)
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
if (wait_button(pk_fid == EF_PK_SIG ? EF_UIF_SIG : EF_UIF_DEC) == true)
|
||||
if (wait_button_pressed(pk_fid == EF_PK_SIG ? EF_UIF_SIG : EF_UIF_DEC) == true)
|
||||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||
int r = CCID_OK;
|
||||
int key_size = file_read_uint16(ef->data);
|
||||
int key_size = file_get_size(ef);
|
||||
if (is_aes) {
|
||||
uint8_t aes_key[32];
|
||||
r = load_aes_key(aes_key, ef);
|
||||
@@ -1420,7 +1422,7 @@ static int cmd_pso() {
|
||||
return SW_WRONG_DATA();
|
||||
if (len != 2*key_size-1)
|
||||
return SW_WRONG_LENGTH();
|
||||
memcpy(kdata, file_read(ef->data+2), key_size);
|
||||
memcpy(kdata, file_get_data(ef), key_size);
|
||||
if (dek_decrypt(kdata, key_size) != 0) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
@@ -1460,7 +1462,7 @@ static int cmd_terminate_df() {
|
||||
file_t *retries;
|
||||
if (!(retries = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF)))
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
if (!has_pw3 && file_read_uint8(retries->data+2+6) > 0)
|
||||
if (!has_pw3 && *(file_get_data(retries)+6) > 0)
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
if (apdu.nc != 0)
|
||||
return SW_WRONG_LENGTH();
|
||||
@@ -1492,12 +1494,12 @@ static int cmd_internal_aut() {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
const uint8_t *algo = algorithm_attr_rsa2k+1;
|
||||
if (algo_ef && algo_ef->data) {
|
||||
algo = file_read(algo_ef->data+2);
|
||||
algo = file_get_data(algo_ef);
|
||||
}
|
||||
file_t *ef = search_by_fid(pk_aut, NULL, SPECIFY_EF);
|
||||
if (!ef)
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
if (wait_button(EF_UIF_AUT) == true)
|
||||
if (wait_button_pressed(EF_UIF_AUT) == true)
|
||||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||
int r = CCID_OK;
|
||||
if (algo[0] == ALGO_RSA) {
|
||||
@@ -1613,8 +1615,8 @@ static int cmd_import_data() {
|
||||
const uint8_t *algo = algorithm_attr_rsa2k+1;
|
||||
uint16_t algo_len = algorithm_attr_rsa2k[0];
|
||||
if (algo_ef && algo_ef->data) {
|
||||
algo = file_read(algo_ef->data+2);
|
||||
algo_len = file_read_uint16(algo_ef->data);
|
||||
algo = file_get_data(algo_ef);
|
||||
algo_len = file_get_size(algo_ef);
|
||||
}
|
||||
int r = 0;
|
||||
if (algo[0] == ALGO_RSA) {
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
#include "stdlib.h"
|
||||
#include <pico/stdlib.h>
|
||||
|
||||
#include "ccid2040.h"
|
||||
#include "hsm.h"
|
||||
#include "apdu.h"
|
||||
|
||||
extern bool has_pw1;
|
||||
extern bool has_pw3;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#define OPGP_VERSION_MINOR (OPGP_VERSION & 0xff)
|
||||
|
||||
|
||||
#define PIPGP_VERSION 0x0106
|
||||
#define PIPGP_VERSION 0x0108
|
||||
|
||||
#define PIPGP_VERSION_MAJOR ((PIPGP_VERSION >> 8) & 0xff)
|
||||
#define PIPGP_VERSION_MINOR (PIPGP_VERSION & 0xff)
|
||||
|
||||
Reference in New Issue
Block a user