Added unlock config command to unlock the device at every boot with an external key.
Signed-off-by: trocotronic <trocotronic@redyc.com>
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
* 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 "ctap2_cbor.h"
|
#include "ctap2_cbor.h"
|
||||||
#include "fido.h"
|
#include "fido.h"
|
||||||
#include "ctap.h"
|
#include "ctap.h"
|
||||||
@@ -32,6 +33,8 @@
|
|||||||
|
|
||||||
static mbedtls_ecdh_context hkey;
|
static mbedtls_ecdh_context hkey;
|
||||||
static bool hkey_init = false;
|
static bool hkey_init = false;
|
||||||
|
extern uint8_t keydev_dec[32];
|
||||||
|
extern bool has_keydev_dec;
|
||||||
|
|
||||||
int cbor_config(const uint8_t *data, size_t len) {
|
int cbor_config(const uint8_t *data, size_t len) {
|
||||||
CborParser parser;
|
CborParser parser;
|
||||||
@@ -138,12 +141,9 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, pkey, 32));
|
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder2, pkey, 32));
|
||||||
CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2));
|
CBOR_CHECK(cbor_encoder_close_container(&mapEncoder, &mapEncoder2));
|
||||||
}
|
}
|
||||||
else if (vendorCommandId == CTAP_CONFIG_AUT) {
|
else if (vendorCommandId == CTAP_CONFIG_AUT || vendorCommandId == CTAP_CONFIG_UNLOCK) {
|
||||||
|
if (vendorCommandId == CTAP_CONFIG_AUT && !file_has_data(ef_keydev))
|
||||||
if (*file_get_data(ef_keydev) == 0x01) { // Already encrypted
|
|
||||||
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
|
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
|
||||||
}
|
|
||||||
|
|
||||||
if (kax.present == false || kay.present == false || alg == 0)
|
if (kax.present == false || kay.present == false || alg == 0)
|
||||||
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
|
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
|
||||||
|
|
||||||
@@ -190,22 +190,43 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
|
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_t *ef_keydev_enc = search_by_fid(EF_KEY_DEV_ENC, NULL, SPECIFY_EF);
|
if (vendorCommandId == CTAP_CONFIG_AUT) {
|
||||||
uint8_t key_dev_enc[12+32+16];
|
uint8_t key_dev_enc[12+32+16];
|
||||||
random_gen(NULL, key_dev_enc, 12);
|
random_gen(NULL, key_dev_enc, 12);
|
||||||
mbedtls_chachapoly_init(&chatx);
|
mbedtls_chachapoly_init(&chatx);
|
||||||
mbedtls_chachapoly_setkey(&chatx, vendorAutCt.data);
|
mbedtls_chachapoly_setkey(&chatx, vendorAutCt.data);
|
||||||
ret = mbedtls_chachapoly_encrypt_and_tag(&chatx, file_get_size(ef_keydev), key_dev_enc, NULL, 0, file_get_data(ef_keydev), key_dev_enc + 12, key_dev_enc + 12 + file_get_size(ef_keydev));
|
ret = mbedtls_chachapoly_encrypt_and_tag(&chatx, file_get_size(ef_keydev), key_dev_enc, NULL, 0, file_get_data(ef_keydev), key_dev_enc + 12, key_dev_enc + 12 + file_get_size(ef_keydev));
|
||||||
mbedtls_chachapoly_free(&chatx);
|
mbedtls_chachapoly_free(&chatx);
|
||||||
if (ret != 0){
|
if (ret != 0){
|
||||||
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
|
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_write_data_to_file(ef_keydev_enc, key_dev_enc, sizeof(key_dev_enc));
|
||||||
|
mbedtls_platform_zeroize(key_dev_enc, sizeof(key_dev_enc));
|
||||||
|
flash_write_data_to_file(ef_keydev, key_dev_enc, file_get_size(ef_keydev)); // Overwrite ef with 0
|
||||||
|
flash_write_data_to_file(ef_keydev, NULL, 0); // Set ef to 0 bytes
|
||||||
|
low_flash_available();
|
||||||
}
|
}
|
||||||
|
else if (vendorCommandId == CTAP_CONFIG_UNLOCK) {
|
||||||
|
if (!file_has_data(ef_keydev_enc))
|
||||||
|
CBOR_ERROR(CTAP2_ERR_INTEGRITY_FAILURE);
|
||||||
|
|
||||||
flash_write_data_to_file(ef_keydev_enc, key_dev_enc, sizeof(key_dev_enc));
|
uint8_t *keyenc = file_get_data(ef_keydev_enc);
|
||||||
low_flash_available();
|
size_t keyenc_len = file_get_size(ef_keydev_enc);
|
||||||
|
mbedtls_chachapoly_init(&chatx);
|
||||||
|
mbedtls_chachapoly_setkey(&chatx, vendorAutCt.data);
|
||||||
|
ret = mbedtls_chachapoly_auth_decrypt(&chatx, sizeof(keydev_dec), keyenc, NULL, 0, keyenc + keyenc_len - 16, keyenc + 12, keydev_dec);
|
||||||
|
mbedtls_chachapoly_free(&chatx);
|
||||||
|
if (ret != 0){
|
||||||
|
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
|
||||||
|
}
|
||||||
|
has_keydev_dec = true;
|
||||||
|
}
|
||||||
goto err; //No return
|
goto err; //No return
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_INVALID_SUBCOMMAND);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
|
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ int fido_unload();
|
|||||||
|
|
||||||
pinUvAuthToken_t paut = {0};
|
pinUvAuthToken_t paut = {0};
|
||||||
|
|
||||||
|
uint8_t keydev_dec[32];
|
||||||
|
bool has_keydev_dec = false;
|
||||||
|
|
||||||
const uint8_t fido_aid[] = {
|
const uint8_t fido_aid[] = {
|
||||||
8,
|
8,
|
||||||
0xA0, 0x00, 0x00, 0x06, 0x47, 0x2F, 0x00, 0x01
|
0xA0, 0x00, 0x00, 0x06, 0x47, 0x2F, 0x00, 0x01
|
||||||
@@ -117,9 +120,12 @@ int x509_create_cert(mbedtls_ecdsa_context *ecdsa, uint8_t *buffer, size_t buffe
|
|||||||
}
|
}
|
||||||
|
|
||||||
int load_keydev(uint8_t *key) {
|
int load_keydev(uint8_t *key) {
|
||||||
if (!ef_keydev || file_get_size(ef_keydev) == 0)
|
if (has_keydev_dec == false && !file_has_data(ef_keydev))
|
||||||
return CCID_ERR_MEMORY_FATAL;
|
return CCID_ERR_MEMORY_FATAL;
|
||||||
memcpy(key, file_get_data(ef_keydev), file_get_size(ef_keydev));
|
if (has_keydev_dec == true)
|
||||||
|
memcpy(key, keydev_dec, sizeof(keydev_dec));
|
||||||
|
else
|
||||||
|
memcpy(key, file_get_data(ef_keydev), file_get_size(ef_keydev));
|
||||||
//return mkek_decrypt(key, file_get_size(ef_keydev));
|
//return mkek_decrypt(key, file_get_size(ef_keydev));
|
||||||
return CCID_OK;
|
return CCID_OK;
|
||||||
}
|
}
|
||||||
@@ -201,8 +207,9 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int cur
|
|||||||
|
|
||||||
int scan_files(bool core1) {
|
int scan_files(bool core1) {
|
||||||
ef_keydev = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF);
|
ef_keydev = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF);
|
||||||
|
ef_keydev_enc = search_by_fid(EF_KEY_DEV_ENC, NULL, SPECIFY_EF);
|
||||||
if (ef_keydev) {
|
if (ef_keydev) {
|
||||||
if (!file_has_data(ef_keydev)) {
|
if (!file_has_data(ef_keydev) && !file_has_data(ef_keydev_enc)) {
|
||||||
printf("KEY DEVICE is empty. Generating SECP256R1 curve...");
|
printf("KEY DEVICE is empty. Generating SECP256R1 curve...");
|
||||||
mbedtls_ecdsa_context ecdsa;
|
mbedtls_ecdsa_context ecdsa;
|
||||||
mbedtls_ecdsa_init(&ecdsa);
|
mbedtls_ecdsa_init(&ecdsa);
|
||||||
|
|||||||
Reference in New Issue
Block a user