mirror of
https://github.com/polhenarejos/pico-openpgp.git
synced 2026-06-20 17:23:51 +02:00
Compare commits
6 Commits
f34cdac00b
...
f2fe6dd5c2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2fe6dd5c2 | ||
|
|
1a24a9ed1b | ||
|
|
b62573a6bd | ||
|
|
58a9d9cf97 | ||
|
|
bc9681e7b0 | ||
|
|
c39b87019e |
@@ -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:
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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,12 +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[] = {
|
const uint8_t algorithm_attr_ed25519[] = {
|
||||||
10,
|
10,
|
||||||
ALGO_EDDSA,
|
ALGO_EDDSA,
|
||||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01
|
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);
|
||||||
@@ -306,7 +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_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);
|
||||||
@@ -333,7 +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_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;
|
||||||
|
|||||||
@@ -26,4 +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_ed25519[];
|
||||||
|
extern const uint8_t algorithm_attr_ed448[];
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -574,7 +574,7 @@ int load_private_key_ecdsa(mbedtls_ecp_keypair *ctx, file_t *fkey, bool use_dek)
|
|||||||
}
|
}
|
||||||
mbedtls_platform_zeroize(kdata, sizeof(kdata));
|
mbedtls_platform_zeroize(kdata, sizeof(kdata));
|
||||||
#ifdef MBEDTLS_EDDSA_C
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
if (ctx->grp.id == MBEDTLS_ECP_DP_ED25519) {
|
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);
|
r = mbedtls_ecp_point_edwards(&ctx->grp, &ctx->Q, &ctx->d, random_gen, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -630,6 +630,9 @@ mbedtls_ecp_group_id get_ec_group_id_from_attr(const uint8_t *algo, size_t algo_
|
|||||||
else if (memcmp(algorithm_attr_ed25519 + 2, algo, algo_len) == 0) {
|
else if (memcmp(algorithm_attr_ed25519 + 2, algo, algo_len) == 0) {
|
||||||
return MBEDTLS_ECP_DP_ED25519;
|
return MBEDTLS_ECP_DP_ED25519;
|
||||||
}
|
}
|
||||||
|
else if (memcmp(algorithm_attr_ed448 + 2, algo, algo_len) == 0) {
|
||||||
|
return MBEDTLS_ECP_DP_ED448;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return MBEDTLS_ECP_DP_NONE;
|
return MBEDTLS_ECP_DP_NONE;
|
||||||
}
|
}
|
||||||
@@ -750,8 +753,8 @@ int ecdsa_sign(mbedtls_ecp_keypair *ctx,
|
|||||||
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
#ifdef MBEDTLS_EDDSA_C
|
#ifdef MBEDTLS_EDDSA_C
|
||||||
if (ctx->grp.id == MBEDTLS_ECP_DP_ED25519) {
|
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, 64, out_len, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
|
r = mbedtls_eddsa_write_signature(ctx, data, data_len, out, 114, out_len, MBEDTLS_EDDSA_PURE, NULL, 0, random_gen, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user