Migration to the new system of secure functions to derive keys based on OTP, if available, and pico_serial as a fallback. PIN is also an input vector, which defines a separated domain.

PIN is used to derive encryption key, derive session key and derive verifier. From session key is derived encryption key. As a consequence, MKEK functionalities are not necessary anymore, since key device is handled by this new set directly. Some MKEK functions are left for compatibility purposes and for the silent migration to new format.  It also applies for double_hash_pin and hash_multi, which are deprecated.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2025-10-08 00:33:23 +02:00
parent 51c13b0f0b
commit 898c88dc6d
5 changed files with 134 additions and 141 deletions

View File

@@ -44,6 +44,7 @@ uint32_t max_usage_time_period = 600 * 1000;
bool needs_power_cycle = false; bool needs_power_cycle = false;
static mbedtls_ecdh_context hkey; static mbedtls_ecdh_context hkey;
static bool hkey_init = false; static bool hkey_init = false;
extern int encrypt_keydev_f1(const uint8_t keydev[32]);
int beginUsingPinUvAuthToken(bool userIsPresent) { int beginUsingPinUvAuthToken(bool userIsPresent) {
paut.user_present = userIsPresent; paut.user_present = userIsPresent;
@@ -199,11 +200,7 @@ int decrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, uint16_t in
return -1; return -1;
} }
int authenticate(uint8_t protocol, int authenticate(uint8_t protocol, const uint8_t *key, const uint8_t *data, size_t len, uint8_t *sign) {
const uint8_t *key,
const uint8_t *data,
size_t len,
uint8_t *sign) {
uint8_t hmac[32]; uint8_t hmac[32];
int ret = int ret =
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), key, 32, data, len, hmac); mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), key, 32, data, len, hmac);
@@ -231,10 +228,10 @@ int verify(uint8_t protocol, const uint8_t *key, const uint8_t *data, uint16_t l
return ret; return ret;
} }
if (protocol == 1) { if (protocol == 1) {
return memcmp(sign, hmac, 16); return ct_memcmp(sign, hmac, 16);
} }
else if (protocol == 2) { else if (protocol == 2) {
return memcmp(sign, hmac, 32); return ct_memcmp(sign, hmac, 32);
} }
return -1; return -1;
} }
@@ -269,17 +266,15 @@ int pinUvAuthTokenUsageTimerObserver() {
return 0; return 0;
} }
int check_mkek_encrypted(const uint8_t *dhash) { int check_keydev_encrypted(const uint8_t pin_token[32]) {
if (file_get_size(ef_mkek) == MKEK_IV_SIZE + MKEK_KEY_SIZE) { if (file_get_data(ef_keydev) && *file_get_data(ef_keydev) == 0x01) {
hash_multi(dhash, 16, session_pin); // Only for storing MKEK uint8_t tmp_keydev[61];
uint8_t mkek[MKEK_SIZE] = {0}; tmp_keydev[0] = 0x02; // Change format to encrypted
memcpy(mkek, file_get_data(ef_mkek), MKEK_IV_SIZE + MKEK_KEY_SIZE); encrypt_with_aad(pin_token, file_get_data(ef_keydev) + 1, 32, tmp_keydev + 1);
int ret = store_mkek(mkek); DEBUG_DATA(tmp_keydev, sizeof(tmp_keydev));
mbedtls_platform_zeroize(mkek, sizeof(mkek)); file_put_data(ef_keydev, tmp_keydev, sizeof(tmp_keydev));
mbedtls_platform_zeroize(session_pin, sizeof(session_pin)); mbedtls_platform_zeroize(tmp_keydev, sizeof(tmp_keydev));
if (ret != PICOKEY_OK) { low_flash_available();
return CTAP2_ERR_PIN_AUTH_INVALID;
}
} }
return PICOKEY_OK; return PICOKEY_OK;
} }
@@ -294,11 +289,11 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
CborEncoder encoder, mapEncoder; CborEncoder encoder, mapEncoder;
CborValue map; CborValue map;
CborError error = CborNoError; CborError error = CborNoError;
CborByteString pinUvAuthParam = { 0 }, newPinEnc = { 0 }, pinHashEnc = { 0 }, kax = { 0 }, CborByteString pinUvAuthParam = { 0 }, newPinEnc = { 0 }, pinHashEnc = { 0 }, kax = { 0 }, kay = { 0 };
kay = { 0 };
CborCharString rpId = { 0 }; CborCharString rpId = { 0 };
CBOR_CHECK(cbor_parser_init(data, len, 0, &parser, &map)); CBOR_CHECK(cbor_parser_init(data, len, 0, &parser, &map));
uint64_t val_c = 1; uint64_t val_c = 1;
uint8_t keydev[32] = {0};
if (hkey_init == false) { if (hkey_init == false) {
initialize(); initialize();
} }
@@ -425,11 +420,12 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
hsh[1] = pin_len; hsh[1] = pin_len;
hsh[2] = 1; // New format indicator hsh[2] = 1; // New format indicator
mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), paddedNewPin, pin_len, dhash); mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), paddedNewPin, pin_len, dhash);
double_hash_pin_otp(dhash, 16, hsh + 3); pin_derive_verifier(dhash, 16, hsh + 3);
file_put_data(ef_pin, hsh, sizeof(hsh)); file_put_data(ef_pin, hsh, sizeof(hsh));
low_flash_available(); low_flash_available();
ret = check_mkek_encrypted(dhash); pin_derive_session(dhash, 16, session_pin);
ret = check_keydev_encrypted(session_pin);
if (ret != PICOKEY_OK) { if (ret != PICOKEY_OK) {
CBOR_ERROR(ret); CBOR_ERROR(ret);
} }
@@ -494,10 +490,10 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
double_hash_pin(paddedNewPin, 16, dhash); double_hash_pin(paddedNewPin, 16, dhash);
} }
else { else {
double_hash_pin_otp(paddedNewPin, 16, dhash); pin_derive_verifier(paddedNewPin, 16, dhash);
} }
if (memcmp(dhash, file_get_data(ef_pin) + off, 32) != 0) { if (ct_memcmp(dhash, file_get_data(ef_pin) + off, 32) != 0) {
regenerate(); regenerate();
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
if (retries == 0) { if (retries == 0) {
@@ -514,12 +510,25 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
if (off == 2) { if (off == 2) {
// Upgrade pin file to new format // Upgrade pin file to new format
pin_data[2] = 1; // New format indicator pin_data[2] = 1; // New format indicator
double_hash_pin_otp(paddedNewPin, 16, pin_data + 3); pin_derive_verifier(paddedNewPin, 16, pin_data + 3);
hash_multi(paddedNewPin, 16, session_pin);
ret = load_keydev(keydev);
if (ret != PICOKEY_OK) {
CBOR_ERROR(CTAP2_ERR_PIN_INVALID);
}
encrypt_keydev_f1(keydev);
} }
hash_multi(paddedNewPin, 16, session_pin); pin_derive_session(paddedNewPin, 16, session_pin);
pin_data[0] = MAX_PIN_RETRIES; pin_data[0] = MAX_PIN_RETRIES;
file_put_data(ef_pin, pin_data, sizeof(pin_data)); file_put_data(ef_pin, pin_data, sizeof(pin_data));
low_flash_available(); low_flash_available();
ret = check_keydev_encrypted(session_pin);
if (ret != PICOKEY_OK) {
CBOR_ERROR(ret);
}
new_pin_mismatches = 0; new_pin_mismatches = 0;
ret = decrypt((uint8_t)pinUvAuthProtocol, sharedSecret, newPinEnc.data, (uint16_t)newPinEnc.len, paddedNewPin); ret = decrypt((uint8_t)pinUvAuthProtocol, sharedSecret, newPinEnc.data, (uint16_t)newPinEnc.len, paddedNewPin);
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
@@ -541,35 +550,32 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
if (pin_len < minPin) { if (pin_len < minPin) {
CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION); CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION);
} }
// New PIN is valid and verified
ret = load_keydev(keydev);
if (ret != PICOKEY_OK) {
CBOR_ERROR(CTAP2_ERR_PIN_INVALID);
}
encrypt_keydev_f1(keydev);
mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), paddedNewPin, pin_len, dhash);
pin_derive_session(dhash, 16, session_pin);
ret = check_keydev_encrypted(session_pin);
if (ret != PICOKEY_OK) {
CBOR_ERROR(ret);
}
low_flash_available();
pin_data[0] = MAX_PIN_RETRIES; pin_data[0] = MAX_PIN_RETRIES;
pin_data[1] = pin_len; pin_data[1] = pin_len;
pin_data[2] = 1; // New format indicator pin_data[2] = 1; // New format indicator
mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), paddedNewPin, pin_len, dhash); pin_derive_verifier(dhash, 16, pin_data + 3);
double_hash_pin_otp(dhash, 16, pin_data + 3);
if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1 && if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1 && ct_memcmp(pin_data + 3, file_get_data(ef_pin) + 3, 32) == 0) {
memcmp(pin_data + 3, file_get_data(ef_pin) + 3, 32) == 0) {
CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION); CBOR_ERROR(CTAP2_ERR_PIN_POLICY_VIOLATION);
} }
uint8_t mkek[MKEK_SIZE] = {0};
ret = load_mkek(mkek);
if (ret != PICOKEY_OK) {
CBOR_ERROR(ret);
}
file_put_data(ef_pin, pin_data, sizeof(pin_data)); file_put_data(ef_pin, pin_data, sizeof(pin_data));
ret = check_mkek_encrypted(dhash);
if (ret != PICOKEY_OK) {
CBOR_ERROR(ret);
}
hash_multi(dhash, 16, session_pin);
ret = store_mkek(mkek);
mbedtls_platform_zeroize(mkek, sizeof(mkek));
if (ret != PICOKEY_OK) {
CBOR_ERROR(ret);
}
mbedtls_platform_zeroize(pin_data, sizeof(pin_data)); mbedtls_platform_zeroize(pin_data, sizeof(pin_data));
mbedtls_platform_zeroize(dhash, sizeof(dhash)); mbedtls_platform_zeroize(dhash, sizeof(dhash));
if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1) { if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1) {
@@ -642,11 +648,12 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
double_hash_pin(paddedNewPin, 16, dhash); double_hash_pin(paddedNewPin, 16, dhash);
} }
else { else {
double_hash_pin_otp(paddedNewPin, 16, dhash); pin_derive_verifier(paddedNewPin, 16, dhash);
} }
if (memcmp(dhash, file_get_data(ef_pin) + off, 32) != 0) { if (ct_memcmp(dhash, file_get_data(ef_pin) + off, 32) != 0) {
regenerate(); regenerate();
mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret)); mbedtls_platform_zeroize(sharedSecret, sizeof(sharedSecret));
mbedtls_platform_zeroize(dhash, sizeof(dhash));
if (retries == 0) { if (retries == 0) {
CBOR_ERROR(CTAP2_ERR_PIN_BLOCKED); CBOR_ERROR(CTAP2_ERR_PIN_BLOCKED);
} }
@@ -658,25 +665,31 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP2_ERR_PIN_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_INVALID);
} }
} }
mbedtls_platform_zeroize(dhash, sizeof(dhash));
ret = check_mkek_encrypted(paddedNewPin);
if (ret != PICOKEY_OK) {
CBOR_ERROR(ret);
}
hash_multi(paddedNewPin, 16, session_pin);
pin_data[0] = MAX_PIN_RETRIES;
new_pin_mismatches = 0;
if (off == 2) { if (off == 2) {
// Upgrade pin file to new format // Upgrade pin file to new format
pin_data[2] = 1; // New format indicator pin_data[2] = 1; // New format indicator
double_hash_pin_otp(paddedNewPin, 16, pin_data + 3); pin_derive_verifier(paddedNewPin, 16, pin_data + 3);
hash_multi(paddedNewPin, 16, session_pin);
ret = load_keydev(keydev);
if (ret != PICOKEY_OK) {
CBOR_ERROR(CTAP2_ERR_PIN_INVALID);
}
encrypt_keydev_f1(keydev);
} }
pin_derive_session(paddedNewPin, 16, session_pin);
ret = check_keydev_encrypted(session_pin);
if (ret != PICOKEY_OK) {
CBOR_ERROR(ret);
}
pin_data[0] = MAX_PIN_RETRIES;
new_pin_mismatches = 0;
file_put_data(ef_pin, pin_data, sizeof(pin_data)); file_put_data(ef_pin, pin_data, sizeof(pin_data));
mbedtls_platform_zeroize(pin_data, sizeof(pin_data)); mbedtls_platform_zeroize(pin_data, sizeof(pin_data));
mbedtls_platform_zeroize(dhash, sizeof(dhash));
low_flash_available(); low_flash_available();
file_t *ef_minpin = search_by_fid(EF_MINPINLEN, NULL, SPECIFY_EF); file_t *ef_minpin = search_by_fid(EF_MINPINLEN, NULL, SPECIFY_EF);
@@ -684,7 +697,6 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
CBOR_ERROR(CTAP2_ERR_PIN_INVALID); CBOR_ERROR(CTAP2_ERR_PIN_INVALID);
} }
uint8_t pinUvAuthToken_enc[32 + IV_SIZE], *pdata = NULL; uint8_t pinUvAuthToken_enc[32 + IV_SIZE], *pdata = NULL;
;
if (permissions & CTAP_PERMISSION_PCMR) { if (permissions & CTAP_PERMISSION_PCMR) {
ppaut.permissions = CTAP_PERMISSION_PCMR; ppaut.permissions = CTAP_PERMISSION_PCMR;
pdata = ppaut.data; pdata = ppaut.data;
@@ -722,6 +734,7 @@ err:
CBOR_FREE_BYTE_STRING(kax); CBOR_FREE_BYTE_STRING(kax);
CBOR_FREE_BYTE_STRING(kay); CBOR_FREE_BYTE_STRING(kay);
CBOR_FREE_BYTE_STRING(rpId); CBOR_FREE_BYTE_STRING(rpId);
mbedtls_platform_zeroize(keydev, sizeof(keydev));
if (error != CborNoError) { if (error != CborNoError) {
if (error == CborErrorImproperValue) { if (error == CborErrorImproperValue) {
return CTAP2_ERR_CBOR_UNEXPECTED_TYPE; return CTAP2_ERR_CBOR_UNEXPECTED_TYPE;

View File

@@ -204,7 +204,7 @@ int x509_create_cert(mbedtls_ecdsa_context *ecdsa, uint8_t *buffer, size_t buffe
return ret; return ret;
} }
int load_keydev(uint8_t *key) { int load_keydev(uint8_t key[32]) {
if (has_keydev_dec == false && !file_has_data(ef_keydev)) { if (has_keydev_dec == false && !file_has_data(ef_keydev)) {
return PICOKEY_ERR_MEMORY_FATAL; return PICOKEY_ERR_MEMORY_FATAL;
} }
@@ -213,13 +213,39 @@ int load_keydev(uint8_t *key) {
memcpy(key, keydev_dec, sizeof(keydev_dec)); memcpy(key, keydev_dec, sizeof(keydev_dec));
} }
else { else {
memcpy(key, file_get_data(ef_keydev), file_get_size(ef_keydev)); uint16_t fid_size = file_get_size(ef_keydev);
if (fid_size == 32) {
if (mkek_decrypt(key, 32) != PICOKEY_OK) { memcpy(key, file_get_data(ef_keydev), 32);
return PICOKEY_EXEC_ERROR; if (mkek_decrypt(key, 32) != PICOKEY_OK) {
return PICOKEY_EXEC_ERROR;
}
if (otp_key_1 && aes_decrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, key, 32) != PICOKEY_OK) {
return PICOKEY_EXEC_ERROR;
}
} }
if (otp_key_1 && aes_decrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, key, 32) != PICOKEY_OK) { else if (fid_size == 33 || fid_size == 61) {
return PICOKEY_EXEC_ERROR; uint8_t format = *file_get_data(ef_keydev);
if (format == 0x01 || format == 0x02) { // Format indicator
if (format == 0x02) {
uint8_t tmp_key[61];
memcpy(tmp_key, file_get_data(ef_keydev), sizeof(tmp_key));
int ret = decrypt_with_aad(session_pin, tmp_key + 1, 60, key);
if (ret != PICOKEY_OK) {
return PICOKEY_EXEC_ERROR;
}
}
else {
memcpy(key, file_get_data(ef_keydev) + 1, 32);
}
uint8_t kbase[32];
derive_kbase(kbase);
int ret = aes_decrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, key, 32);
if (ret != PICOKEY_OK) {
mbedtls_platform_zeroize(kbase, sizeof(kbase));
return PICOKEY_EXEC_ERROR;
}
mbedtls_platform_zeroize(kbase, sizeof(kbase));
}
} }
} }
@@ -315,6 +341,23 @@ int derive_key(const uint8_t *app_id, bool new_key, uint8_t *key_handle, int cur
return r; return r;
} }
int encrypt_keydev_f1(const uint8_t keydev[32]) {
uint8_t kdata[33] = {0};
kdata[0] = 0x01; // Format indicator
memcpy(kdata + 1, keydev, 32);
uint8_t kbase[32];
derive_kbase(kbase);
int ret = aes_encrypt(kbase, pico_serial_hash, 32 * 8, PICO_KEYS_AES_MODE_CBC, kdata + 1, 32);
mbedtls_platform_zeroize(kbase, sizeof(kbase));
if (ret != PICOKEY_OK) {
return ret;
}
ret = file_put_data(ef_keydev, kdata, 33);
mbedtls_platform_zeroize(kdata, sizeof(kdata));
low_flash_available();
return ret;
}
int scan_files_fido() { int scan_files_fido() {
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); ef_keydev_enc = search_by_fid(EF_KEY_DEV_ENC, NULL, SPECIFY_EF);
@@ -330,17 +373,16 @@ int scan_files_fido() {
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);
return ret; return ret;
} }
uint8_t kdata[64]; uint8_t keydev[32] = {0};
size_t key_size = 0; size_t key_size = 0;
ret = mbedtls_ecp_write_key_ext(&ecdsa, &key_size, kdata, sizeof(kdata)); ret = mbedtls_ecp_write_key_ext(&ecdsa, &key_size, keydev, sizeof(keydev));
if (ret != PICOKEY_OK) { if (ret != 0 || key_size != 32) {
return ret; mbedtls_platform_zeroize(keydev, sizeof(keydev));
mbedtls_ecdsa_free(&ecdsa);
return ret != 0 ? ret : PICOKEY_EXEC_ERROR;
} }
if (otp_key_1) { encrypt_keydev_f1(keydev);
ret = aes_encrypt(otp_key_1, NULL, 32 * 8, PICO_KEYS_AES_MODE_CBC, kdata, 32); mbedtls_platform_zeroize(keydev, sizeof(keydev));
}
ret = file_put_data(ef_keydev, kdata, (uint16_t)key_size);
mbedtls_platform_zeroize(kdata, sizeof(kdata));
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);
if (ret != PICOKEY_OK) { if (ret != PICOKEY_OK) {
return ret; return ret;
@@ -351,21 +393,6 @@ int scan_files_fido() {
else { else {
printf("FATAL ERROR: KEY DEV not found in memory!\r\n"); printf("FATAL ERROR: KEY DEV not found in memory!\r\n");
} }
if (ef_mkek) { // No encrypted MKEK
if (!file_has_data(ef_mkek)) {
uint8_t mkek[MKEK_IV_SIZE + MKEK_KEY_SIZE];
random_gen(NULL, mkek, sizeof(mkek));
file_put_data(ef_mkek, mkek, sizeof(mkek));
int ret = aes_encrypt_cfb_256(MKEK_KEY(mkek), MKEK_IV(mkek), file_get_data(ef_keydev), 32);
mbedtls_platform_zeroize(mkek, sizeof(mkek));
if (ret != 0) {
printf("FATAL ERROR: MKEK encryption failed!\r\n");
}
}
}
else {
printf("FATAL ERROR: MKEK not found in memory!\r\n");
}
ef_certdev = search_by_fid(EF_EE_DEV, NULL, SPECIFY_EF); ef_certdev = search_by_fid(EF_EE_DEV, NULL, SPECIFY_EF);
if (ef_certdev) { if (ef_certdev) {
if (!file_has_data(ef_certdev)) { if (!file_has_data(ef_certdev)) {
@@ -409,13 +436,6 @@ int scan_files_fido() {
printf("FATAL ERROR: Global counter not found in memory!\r\n"); printf("FATAL ERROR: Global counter not found in memory!\r\n");
} }
ef_pin = search_by_fid(EF_PIN, NULL, SPECIFY_EF); ef_pin = search_by_fid(EF_PIN, NULL, SPECIFY_EF);
if (file_get_size(ef_pin) == 18) { // Upgrade PIN storage
uint8_t pin_data[34] = { 0 }, dhash[32];
memcpy(pin_data, file_get_data(ef_pin), 18);
double_hash_pin(pin_data + 2, 16, dhash);
memcpy(pin_data + 2, dhash, 32);
file_put_data(ef_pin, pin_data, 34);
}
ef_authtoken = search_by_fid(EF_AUTHTOKEN, NULL, SPECIFY_EF); ef_authtoken = search_by_fid(EF_AUTHTOKEN, NULL, SPECIFY_EF);
if (ef_authtoken) { if (ef_authtoken) {
if (!file_has_data(ef_authtoken)) { if (!file_has_data(ef_authtoken)) {

View File

@@ -51,7 +51,7 @@ extern void init_fido();
extern mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve); extern mbedtls_ecp_group_id fido_curve_to_mbedtls(int curve);
extern int mbedtls_curve_to_fido(mbedtls_ecp_group_id id); extern int mbedtls_curve_to_fido(mbedtls_ecp_group_id id);
extern int fido_load_key(int curve, const uint8_t *cred_id, mbedtls_ecp_keypair *key); extern int fido_load_key(int curve, const uint8_t *cred_id, mbedtls_ecp_keypair *key);
extern int load_keydev(uint8_t *key); extern int load_keydev(uint8_t key[32]);
extern int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, uint16_t in_len, uint8_t *out); extern int encrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, uint16_t in_len, uint8_t *out);
extern int decrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, uint16_t in_len, uint8_t *out); extern int decrypt(uint8_t protocol, const uint8_t *key, const uint8_t *in, uint16_t in_len, uint8_t *out);
extern int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSecret); extern int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSecret);

View File

@@ -85,46 +85,6 @@ void release_mkek(uint8_t *mkek) {
mbedtls_platform_zeroize(mkek, MKEK_SIZE); mbedtls_platform_zeroize(mkek, MKEK_SIZE);
} }
int store_mkek(const uint8_t *mkek) {
uint8_t tmp_mkek[MKEK_SIZE];
if (mkek == NULL) {
const uint8_t *rd = random_bytes_get(MKEK_IV_SIZE + MKEK_KEY_SIZE);
memcpy(tmp_mkek, rd, MKEK_IV_SIZE + MKEK_KEY_SIZE);
}
else {
memcpy(tmp_mkek, mkek, MKEK_SIZE);
}
if (otp_key_1) {
mkek_masked(tmp_mkek, otp_key_1);
}
*(uint32_t *) MKEK_CHECKSUM(tmp_mkek) = crc32c(MKEK_KEY(tmp_mkek), MKEK_KEY_SIZE);
uint8_t tmp_mkek_pin[MKEK_SIZE];
memcpy(tmp_mkek_pin, tmp_mkek, MKEK_SIZE);
file_t *tf = search_file(EF_MKEK);
if (!tf) {
release_mkek(tmp_mkek);
release_mkek(tmp_mkek_pin);
return PICOKEY_ERR_FILE_NOT_FOUND;
}
aes_encrypt_cfb_256(session_pin, MKEK_IV(tmp_mkek_pin), MKEK_KEY(tmp_mkek_pin), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
file_put_data(tf, tmp_mkek_pin, MKEK_SIZE);
release_mkek(tmp_mkek_pin);
low_flash_available();
release_mkek(tmp_mkek);
return PICOKEY_OK;
}
int mkek_encrypt(uint8_t *data, uint16_t len) {
int r;
uint8_t mkek[MKEK_SIZE + 4];
if ((r = load_mkek(mkek)) != PICOKEY_OK) {
return r;
}
r = aes_encrypt_cfb_256(MKEK_KEY(mkek), MKEK_IV(mkek), data, len);
release_mkek(mkek);
return r;
}
int mkek_decrypt(uint8_t *data, uint16_t len) { int mkek_decrypt(uint8_t *data, uint16_t len) {
int r; int r;
uint8_t mkek[MKEK_SIZE + 4]; uint8_t mkek[MKEK_SIZE + 4];