Merge branch 'master' into small-fixes

This commit is contained in:
Pol Henarejos 2022-11-03 15:48:33 +01:00 committed by GitHub
commit f1058ea611
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 236 additions and 25 deletions

View File

@ -120,8 +120,8 @@ int cmd_decrypt_asym() {
size_t olen = 0; size_t olen = 0;
res_APDU[0] = 0x04; res_APDU[0] = 0x04;
r = mbedtls_ecdh_calc_secret(&ctx, &olen, res_APDU+1, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL); r = mbedtls_ecdh_calc_secret(&ctx, &olen, res_APDU+1, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL);
mbedtls_ecdh_free(&ctx);
if (r != 0) { if (r != 0) {
mbedtls_ecdh_free(&ctx);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
if (p2 == ALGO_EC_DH) if (p2 == ALGO_EC_DH)
@ -161,7 +161,6 @@ int cmd_decrypt_asym() {
} }
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
mbedtls_ecdh_free(&ctx);
} }
else else
return SW_WRONG_P1P2(); return SW_WRONG_P1P2();

View File

@ -19,7 +19,7 @@
#include "mbedtls/ecdsa.h" #include "mbedtls/ecdsa.h"
#include "crypto_utils.h" #include "crypto_utils.h"
#include "sc_hsm.h" #include "sc_hsm.h"
#include "cvc.h"
#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E #define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E
#define MOD_ADD( N ) \ #define MOD_ADD( N ) \
@ -72,29 +72,24 @@ int cmd_derive_asym() {
return SW_DATA_INVALID(); return SW_DATA_INVALID();
} }
r = mbedtls_mpi_add_mod(&ctx.grp, &nd, &ctx.d, &a); r = mbedtls_mpi_add_mod(&ctx.grp, &nd, &ctx.d, &a);
mbedtls_mpi_free(&a);
if (r != 0) { if (r != 0) {
mbedtls_ecdsa_free(&ctx); mbedtls_ecdsa_free(&ctx);
mbedtls_mpi_free(&a);
mbedtls_mpi_free(&nd); mbedtls_mpi_free(&nd);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
r = mbedtls_mpi_copy(&ctx.d, &nd); r = mbedtls_mpi_copy(&ctx.d, &nd);
mbedtls_mpi_free(&nd);
if (r != 0) { if (r != 0) {
mbedtls_ecdsa_free(&ctx); mbedtls_ecdsa_free(&ctx);
mbedtls_mpi_free(&a);
mbedtls_mpi_free(&nd);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
r = store_keys(&ctx, HSM_KEY_EC, dest_id); r = store_keys(&ctx, HSM_KEY_EC, dest_id);
if (r != CCID_OK) { if (r != CCID_OK) {
mbedtls_ecdsa_free(&ctx); mbedtls_ecdsa_free(&ctx);
mbedtls_mpi_free(&a);
mbedtls_mpi_free(&nd);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
mbedtls_ecdsa_free(&ctx); mbedtls_ecdsa_free(&ctx);
mbedtls_mpi_free(&a);
mbedtls_mpi_free(&nd);
} }
else else
return SW_WRONG_DATA(); return SW_WRONG_DATA();

View File

@ -15,14 +15,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "common.h"
#include "mbedtls/ecdh.h"
#include "sc_hsm.h" #include "sc_hsm.h"
#include "hardware/rtc.h" #include "hardware/rtc.h"
#include "files.h" #include "files.h"
#include "random.h"
#include "kek.h"
#include "mbedtls/hkdf.h"
#include "mbedtls/chachapoly.h"
int cmd_extras() { int cmd_extras() {
if (P2(apdu) != 0x0)
return SW_INCORRECT_P1P2();
if (P1(apdu) == 0xA) { //datetime operations if (P1(apdu) == 0xA) { //datetime operations
if (P2(apdu) != 0x0)
return SW_INCORRECT_P1P2();
if (apdu.nc == 0) { if (apdu.nc == 0) {
datetime_t dt; datetime_t dt;
if (!rtc_get_datetime(&dt)) if (!rtc_get_datetime(&dt))
@ -52,6 +58,8 @@ int cmd_extras() {
} }
} }
else if (P1(apdu) == 0x6) { //dynamic options else if (P1(apdu) == 0x6) { //dynamic options
if (P2(apdu) != 0x0)
return SW_INCORRECT_P1P2();
if (apdu.nc > sizeof(uint8_t)) if (apdu.nc > sizeof(uint8_t))
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
uint16_t opts = get_device_options(); uint16_t opts = get_device_options();
@ -66,6 +74,86 @@ int cmd_extras() {
low_flash_available(); low_flash_available();
} }
} }
else if (P1(apdu) == 0x3A) { // secure lock
if (apdu.nc == 0) {
return SW_WRONG_LENGTH();
}
if (P2(apdu) == 0x01) { // Key Agreement
mbedtls_ecdh_context hkey;
mbedtls_ecdh_init(&hkey);
mbedtls_ecdh_setup(&hkey, MBEDTLS_ECP_DP_SECP256R1);
int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.d, &hkey.ctx.mbed_ecdh.Q, random_gen, NULL);
mbedtls_mpi_lset(&hkey.ctx.mbed_ecdh.Qp.Z, 1);
ret = mbedtls_ecp_point_read_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Qp, apdu.data, apdu.nc);
if (ret != 0) {
mbedtls_ecdh_free(&hkey);
return SW_WRONG_DATA();
}
memcpy(mse.Qpt, apdu.data, sizeof(mse.Qpt));
uint8_t buf[MBEDTLS_ECP_MAX_BYTES];
size_t olen = 0;
ret = mbedtls_ecdh_calc_secret(&hkey, &olen, buf, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL);
if (ret != 0) {
mbedtls_ecdh_free(&hkey);
mbedtls_platform_zeroize(buf, sizeof(buf));
return SW_WRONG_DATA();
}
ret = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), NULL, 0, buf, olen, mse.Qpt, sizeof(mse.Qpt), mse.key_enc, sizeof(mse.key_enc));
mbedtls_platform_zeroize(buf, sizeof(buf));
if (ret != 0) {
mbedtls_ecdh_free(&hkey);
return SW_EXEC_ERROR();
}
ret = mbedtls_ecp_point_write_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, res_APDU, 4096);
mbedtls_ecdh_free(&hkey);
if (ret != 0) {
return SW_EXEC_ERROR();
}
mse.init = true;
res_APDU_size = olen;
}
else if (P2(apdu) == 0x02 || P2(apdu) == 0x03 || P2(apdu) == 0x04) {
if (mse.init == false)
return SW_COMMAND_NOT_ALLOWED();
int ret = mse_decrypt_ct(apdu.data, apdu.nc);
if (ret != 0) {
return SW_WRONG_DATA();
}
if (P2(apdu) == 0x02 || P2(apdu) == 0x04) { // Enable
uint16_t opts = get_device_options();
uint8_t newopts[] = { opts >> 8, (opts & 0xff) };
if ((P2(apdu) == 0x02 && !(opts & HSM_OPT_SECURE_LOCK)) || (P2(apdu) == 0x04 && (opts & HSM_OPT_SECURE_LOCK))) {
uint16_t tfids[] = { EF_MKEK, EF_MKEK_SO };
for (int t = 0; t < sizeof(tfids)/sizeof(uint16_t); t++) {
file_t *tf = search_by_fid(tfids[t], NULL, SPECIFY_EF);
if (tf) {
uint8_t *tmp = (uint8_t *)calloc(1, file_get_size(tf));
memcpy(tmp, file_get_data(tf), file_get_size(tf));
for (int i = 0; i < MKEK_KEY_SIZE; i++) {
MKEK_KEY(tmp)[i] ^= apdu.data[i];
}
flash_write_data_to_file(tf, tmp, file_get_size(tf));
free(tmp);
}
}
}
if (P2(apdu) == 0x02)
newopts[0] |= HSM_OPT_SECURE_LOCK >> 8;
else if (P2(apdu) == 0x04)
newopts[0] &= ~HSM_OPT_SECURE_LOCK >> 8;
file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
flash_write_data_to_file(tf, newopts, sizeof(newopts));
low_flash_available();
}
else if (P2(apdu) == 0x03) {
memcpy(mkek_mask, apdu.data, apdu.nc);
has_mkek_mask = true;
}
}
}
else else
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
return SW_OK(); return SW_OK();

View File

@ -80,7 +80,7 @@ int cmd_general_authenticate() {
sm_derive_all_keys(derived, olen); sm_derive_all_keys(derived, olen);
uint8_t *t = (uint8_t *)calloc(1, pubkey_len+16); uint8_t *t = (uint8_t *)calloc(1, pubkey_len+16);
memcpy(t, "\x7F\x49\x3F\x06\x0A", 5); memcpy(t, "\x7F\x49\x4F\x06\x0A", 5);
if (sm_get_protocol() == MSE_AES) if (sm_get_protocol() == MSE_AES)
memcpy(t+5, OID_ID_CA_ECDH_AES_CBC_CMAC_128, 10); memcpy(t+5, OID_ID_CA_ECDH_AES_CBC_CMAC_128, 10);
t[15] = 0x86; t[15] = 0x86;

View File

@ -122,14 +122,18 @@ int cmd_keypair_gen() {
} }
} }
if ((res_APDU_size = asn1_cvc_aut(&ecdsa, HSM_KEY_EC, res_APDU, 4096, ext, ext_len)) == 0) { if ((res_APDU_size = asn1_cvc_aut(&ecdsa, HSM_KEY_EC, res_APDU, 4096, ext, ext_len)) == 0) {
return SW_EXEC_ERROR(); if (ext)
} free(ext);
ret = store_keys(&ecdsa, HSM_KEY_EC, key_id);
if (ret != CCID_OK) {
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
if (ext)
free(ext);
ret = store_keys(&ecdsa, HSM_KEY_EC, key_id);
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);
if (ret != CCID_OK) {
return SW_EXEC_ERROR();
}
} }
} }
@ -142,8 +146,8 @@ int cmd_keypair_gen() {
ret = flash_write_data_to_file(fpk, res_APDU, res_APDU_size); ret = flash_write_data_to_file(fpk, res_APDU, res_APDU_size);
if (ret != 0) if (ret != 0)
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
if (apdu.ne == 0) //if (apdu.ne == 0)
apdu.ne = res_APDU_size; // apdu.ne = res_APDU_size;
low_flash_available(); low_flash_available();
return SW_OK(); return SW_OK();
} }

View File

@ -68,7 +68,7 @@ size_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, siz
size_t b_size = mbedtls_mpi_size(&ecdsa->grp.B), g_size = 1+mbedtls_mpi_size(&ecdsa->grp.G.X)+mbedtls_mpi_size(&ecdsa->grp.G.X); size_t b_size = mbedtls_mpi_size(&ecdsa->grp.B), g_size = 1+mbedtls_mpi_size(&ecdsa->grp.G.X)+mbedtls_mpi_size(&ecdsa->grp.G.X);
size_t o_size = mbedtls_mpi_size(&ecdsa->grp.N), y_size = 1+mbedtls_mpi_size(&ecdsa->Q.X)+mbedtls_mpi_size(&ecdsa->Q.X); size_t o_size = mbedtls_mpi_size(&ecdsa->grp.N), y_size = 1+mbedtls_mpi_size(&ecdsa->Q.X)+mbedtls_mpi_size(&ecdsa->Q.X);
size_t c_size = 1; size_t c_size = 1;
size_t ptot_size = asn1_len_tag(0x81, p_size), atot_size = asn1_len_tag(0x82, a_size ? a_size : (pointA[ecdsa->grp.id] ? p_size : 0)); size_t ptot_size = asn1_len_tag(0x81, p_size), atot_size = asn1_len_tag(0x82, a_size ? a_size : (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6 ? p_size : 1));
size_t btot_size = asn1_len_tag(0x83, b_size), gtot_size = asn1_len_tag(0x84, g_size); size_t btot_size = asn1_len_tag(0x83, b_size), gtot_size = asn1_len_tag(0x84, g_size);
size_t otot_size = asn1_len_tag(0x85, o_size), ytot_size = asn1_len_tag(0x86, y_size); size_t otot_size = asn1_len_tag(0x85, o_size), ytot_size = asn1_len_tag(0x86, y_size);
size_t ctot_size = asn1_len_tag(0x87, c_size); size_t ctot_size = asn1_len_tag(0x87, c_size);
@ -90,11 +90,12 @@ size_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, siz
*p++ = 0x82; p += format_tlv_len(a_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.A, p, a_size); p += a_size; *p++ = 0x82; p += format_tlv_len(a_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.A, p, a_size); p += a_size;
} }
else { //mbedtls does not set point A for some curves else { //mbedtls does not set point A for some curves
if (pointA[ecdsa->grp.id]) { if (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6) {
*p++ = 0x82; p += format_tlv_len(p_size, p); memcpy(p, pointA[ecdsa->grp.id], p_size); p += p_size; *p++ = 0x82; p += format_tlv_len(p_size, p); memcpy(p, pointA[ecdsa->grp.id], p_size); p += p_size;
} }
else { else {
*p++ = 0x82; p += format_tlv_len(0, p); *p++ = 0x82; p += format_tlv_len(1, p);
*p++ = 0x0;
} }
} }
//B //B

View File

@ -27,10 +27,13 @@
#include "mbedtls/cmac.h" #include "mbedtls/cmac.h"
#include "mbedtls/rsa.h" #include "mbedtls/rsa.h"
#include "mbedtls/ecdsa.h" #include "mbedtls/ecdsa.h"
#include "mbedtls/chachapoly.h"
#include "files.h" #include "files.h"
extern bool has_session_pin, has_session_sopin; extern bool has_session_pin, has_session_sopin;
extern uint8_t session_pin[32], session_sopin[32]; extern uint8_t session_pin[32], session_sopin[32];
uint8_t mkek_mask[MKEK_KEY_SIZE];
bool has_mkek_mask = false;
#define POLY 0xedb88320 #define POLY 0xedb88320
@ -65,6 +68,12 @@ int load_mkek(uint8_t *mkek) {
} }
if (pin == NULL) //Should never happen if (pin == NULL) //Should never happen
return CCID_EXEC_ERROR; return CCID_EXEC_ERROR;
if (has_mkek_mask) {
for (int i = 0; i < MKEK_KEY_SIZE; i++) {
MKEK_KEY(mkek)[i] ^= mkek_mask[i];
}
}
int ret = aes_decrypt_cfb_256(pin, MKEK_IV(mkek), MKEK_KEY(mkek), MKEK_KEY_SIZE+MKEK_KEY_CS_SIZE); int ret = aes_decrypt_cfb_256(pin, MKEK_IV(mkek), MKEK_KEY(mkek), MKEK_KEY_SIZE+MKEK_KEY_CS_SIZE);
if (ret != 0) if (ret != 0)
return CCID_EXEC_ERROR; return CCID_EXEC_ERROR;
@ -73,6 +82,17 @@ int load_mkek(uint8_t *mkek) {
return CCID_OK; return CCID_OK;
} }
mse_t mse = {.init = false};
int mse_decrypt_ct(uint8_t *data, size_t len) {
mbedtls_chachapoly_context chatx;
mbedtls_chachapoly_init(&chatx);
mbedtls_chachapoly_setkey(&chatx, mse.key_enc + 12);
int ret = mbedtls_chachapoly_auth_decrypt(&chatx, len - 16, mse.key_enc, mse.Qpt, 65, data + len - 16, data, data);
mbedtls_chachapoly_free(&chatx);
return ret;
}
int load_dkek(uint8_t id, uint8_t *dkek) { int load_dkek(uint8_t id, uint8_t *dkek) {
file_t *tf = search_dynamic_file(EF_DKEK+id); file_t *tf = search_dynamic_file(EF_DKEK+id);
if (!tf) if (!tf)

View File

@ -18,6 +18,8 @@
#ifndef _DKEK_H_ #ifndef _DKEK_H_
#define _DKEK_H_ #define _DKEK_H_
#include "crypto_utils.h"
extern int load_mkek(uint8_t *); extern int load_mkek(uint8_t *);
extern int store_mkek(const uint8_t *); extern int store_mkek(const uint8_t *);
extern int save_dkek_key(uint8_t, const uint8_t *key); extern int save_dkek_key(uint8_t, const uint8_t *key);
@ -45,4 +47,16 @@ extern int dkek_decode_key(uint8_t, void *key_ctx, const uint8_t *in, size_t in_
#define MKEK_CHECKSUM(p) (MKEK_KEY(p)+MKEK_KEY_SIZE) #define MKEK_CHECKSUM(p) (MKEK_KEY(p)+MKEK_KEY_SIZE)
#define DKEK_KEY_SIZE (32) #define DKEK_KEY_SIZE (32)
extern uint8_t mkek_mask[MKEK_KEY_SIZE];
extern bool has_mkek_mask;
typedef struct mse {
uint8_t Qpt[65];
uint8_t key_enc[12 + 32];
bool init;
} mse_t;
extern mse_t mse;
extern int mse_decrypt_ct(uint8_t *, size_t);
#endif #endif

View File

@ -647,7 +647,9 @@ static const cmd_t cmds[] = {
}; };
int sc_hsm_process_apdu() { int sc_hsm_process_apdu() {
sm_unwrap(); int r = sm_unwrap();
if (r != CCID_OK)
return SW_DATA_INVALID();
for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) { for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) {
if (cmd->ins == INS(apdu)) { if (cmd->ins == INS(apdu)) {
int r = cmd->cmd_handler(); int r = cmd->cmd_handler();

View File

@ -77,6 +77,7 @@ extern const uint8_t sc_hsm_aid[];
#define HSM_OPT_RRC_RESET_ONLY 0x0020 #define HSM_OPT_RRC_RESET_ONLY 0x0020
#define HSM_OPT_BOOTSEL_BUTTON 0x0100 #define HSM_OPT_BOOTSEL_BUTTON 0x0100
#define HSM_OPT_KEY_COUNTER_ALL 0x0200 #define HSM_OPT_KEY_COUNTER_ALL 0x0200
#define HSM_OPT_SECURE_LOCK 0x0400
#define PRKD_PREFIX 0xC4 /* Hi byte in file identifier for PKCS#15 PRKD objects */ #define PRKD_PREFIX 0xC4 /* Hi byte in file identifier for PKCS#15 PRKD objects */
#define CD_PREFIX 0xC8 /* Hi byte in file identifier for PKCS#15 CD objects */ #define CD_PREFIX 0xC8 /* Hi byte in file identifier for PKCS#15 CD objects */

91
tools/pico-hsm-tool.py Executable file → Normal file
View File

@ -33,10 +33,21 @@ try:
from cvc.asn1 import ASN1 from cvc.asn1 import ASN1
from cvc.oid import oid2scheme from cvc.oid import oid2scheme
from cvc.utils import scheme_rsa from cvc.utils import scheme_rsa
from cryptography.hazmat.primitives.asymmetric import ec
except ModuleNotFoundError: except ModuleNotFoundError:
print('ERROR: cvc module not found! Install pycvc package.\nTry with `pip install pycvc`') print('ERROR: cvc module not found! Install pycvc package.\nTry with `pip install pycvc`')
sys.exit(-1) sys.exit(-1)
try:
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
from cryptography.hazmat.primitives import hashes
except ModuleNotFoundError:
print('ERROR: cryptography module not found! Install cryptography package.\nTry with `pip install cryptography`')
sys.exit(-1)
import json import json
import urllib.request import urllib.request
import base64 import base64
@ -44,9 +55,20 @@ from binascii import hexlify
import sys import sys
import argparse import argparse
import os import os
import platform
from datetime import datetime from datetime import datetime
from argparse import RawTextHelpFormatter from argparse import RawTextHelpFormatter
if (platform.system() == 'Windows'):
from secure_key import windows as skey
elif (platform.system() == 'Linux'):
from secure_key import linux as skey
elif (platform.system() == 'Darwin'):
from secure_key import macos as skey
else:
print('ERROR: platform not supported')
sys.exit(-1)
class APDUResponse(Exception): class APDUResponse(Exception):
def __init__(self, sw1, sw2): def __init__(self, sw1, sw2):
self.sw1 = sw1 self.sw1 = sw1
@ -98,6 +120,9 @@ def parse_args():
parser_opts.add_argument('opt', choices=['button', 'counter'], help='Button: press-to-confirm button.\nCounter: every generated key has an internal counter.') parser_opts.add_argument('opt', choices=['button', 'counter'], help='Button: press-to-confirm button.\nCounter: every generated key has an internal counter.')
parser_opts.add_argument('onoff', choices=['on', 'off'], help='Toggles state ON or OFF', metavar='ON/OFF', nargs='?') parser_opts.add_argument('onoff', choices=['on', 'off'], help='Toggles state ON or OFF', metavar='ON/OFF', nargs='?')
parser_secure = subparser.add_parser('secure', help='Manages security of Pico Fido.')
parser_secure.add_argument('subcommand', choices=['enable', 'disable', 'unlock'], help='Enables, disables or unlocks the security.')
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -276,8 +301,68 @@ def opts(card, args):
elif (args.subcommand == 'get'): elif (args.subcommand == 'get'):
print(f'Option {args.opt.upper()} is {"ON" if current & opt else "OFF"}') print(f'Option {args.opt.upper()} is {"ON" if current & opt else "OFF"}')
class SecureLock:
def __init__(self, card):
self.card = card
def mse(self):
sk = ec.generate_private_key(ec.SECP256R1())
pn = sk.public_key().public_numbers()
self.__pb = sk.public_key().public_bytes(Encoding.X962, PublicFormat.UncompressedPoint)
ret = send_apdu(self.card, [0x80, 0x64], 0x3A, 0x01, list(self.__pb))
pk = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(), bytes(ret))
shared_key = sk.exchange(ec.ECDH(), pk)
xkdf = HKDF(
algorithm=hashes.SHA256(),
length=12+32,
salt=None,
info=self.__pb
)
kdf_out = xkdf.derive(shared_key)
self.__key_enc = kdf_out[12:]
self.__iv = kdf_out[:12]
def encrypt_chacha(self, data):
chacha = ChaCha20Poly1305(self.__key_enc)
ct = chacha.encrypt(self.__iv, data, self.__pb)
return ct
def unlock_device(self):
ct = self.get_skey()
send_apdu(self.card, [0x80, 0x64], 0x3A, 0x03, list(ct))
def _get_key_device(self):
return skey.get_secure_key()
def get_skey(self):
self.mse()
ct = self.encrypt_chacha(self._get_key_device())
return ct
def enable_device_aut(self):
ct = self.get_skey()
send_apdu(self.card, [0x80, 0x64], 0x3A, 0x02, list(ct))
def disable_device_aut(self):
ct = self.get_skey()
send_apdu(self.card, [0x80, 0x64], 0x3A, 0x04, list(ct))
def secure(card, args):
slck = SecureLock(card)
if (args.subcommand == 'enable'):
slck.enable_device_aut()
elif (args.subcommand == 'unlock'):
slck.unlock_device()
elif (args.subcommand == 'disable'):
slck.disable_device_aut()
def main(args): def main(args):
print('Pico HSM Tool v1.4') print('Pico HSM Tool v1.6')
print('Author: Pol Henarejos') print('Author: Pol Henarejos')
print('Report bugs to https://github.com/polhenarejos/pico-hsm/issues') print('Report bugs to https://github.com/polhenarejos/pico-hsm/issues')
print('') print('')
@ -305,6 +390,8 @@ def main(args):
rtc(card, args) rtc(card, args)
elif (args.command == 'options'): elif (args.command == 'options'):
opts(card, args) opts(card, args)
elif (args.command == 'secure'):
secure(card, args)
def run(): def run():
args = parse_args() args = parse_args()