proxmark3/armsrc/desfire_key.c

157 lines
4.8 KiB
C
Raw Normal View History

2014-09-12 05:23:46 +08:00
/*-
* Copyright (C) 2010, Romain Tartiere.
*
2014-09-12 05:23:46 +08:00
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
2014-09-12 05:23:46 +08:00
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
2014-09-12 05:23:46 +08:00
* $Id$
*/
2017-01-21 17:25:29 +08:00
2014-10-07 01:42:50 +08:00
#include "desfire_key.h"
#include "string.h"
2014-09-12 05:23:46 +08:00
2019-03-10 07:00:59 +08:00
static inline void update_key_schedules(desfirekey_t key);
2014-09-12 05:23:46 +08:00
static inline void update_key_schedules(desfirekey_t key) {
2014-09-12 05:23:46 +08:00
// DES_set_key ((DES_cblock *)key->data, &(key->ks1));
// DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2));
// if (T_3K3DES == key->type) {
2019-03-10 07:00:59 +08:00
// DES_set_key ((DES_cblock *)(key->data + 16), &(key->ks3));
2014-09-12 05:23:46 +08:00
// }
}
void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key) {
2014-09-12 05:23:46 +08:00
uint8_t data[8];
2019-03-10 07:00:59 +08:00
memcpy(data, value, 8);
for (int n = 0; n < 8; n++)
2014-09-12 05:23:46 +08:00
data[n] &= 0xfe;
2019-03-10 07:00:59 +08:00
Desfire_des_key_new_with_version(data, key);
2014-09-12 05:23:46 +08:00
}
void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key) {
2019-03-10 07:00:59 +08:00
if (key != NULL) {
2019-03-10 03:34:41 +08:00
key->type = T_DES;
2019-03-10 07:00:59 +08:00
memcpy(key->data, value, 8);
memcpy(key->data + 8, value, 8);
update_key_schedules(key);
2019-03-10 03:34:41 +08:00
}
2014-09-12 05:23:46 +08:00
}
void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key) {
2014-09-12 05:23:46 +08:00
uint8_t data[16];
2019-03-10 07:00:59 +08:00
memcpy(data, value, 16);
for (int n = 0; n < 8; n++)
2014-09-12 05:23:46 +08:00
data[n] &= 0xfe;
2019-03-10 07:00:59 +08:00
for (int n = 8; n < 16; n++)
2014-09-12 05:23:46 +08:00
data[n] |= 0x01;
2019-03-10 07:00:59 +08:00
Desfire_3des_key_new_with_version(data, key);
2014-09-12 05:23:46 +08:00
}
void Desfire_3des_key_new_with_version(const uint8_t value[16], desfirekey_t key) {
2019-03-10 07:00:59 +08:00
if (key != NULL) {
2019-03-10 03:34:41 +08:00
key->type = T_3DES;
2019-03-10 07:00:59 +08:00
memcpy(key->data, value, 16);
memcpy(key->data + 16, value, 8);
update_key_schedules(key);
2019-03-10 03:34:41 +08:00
}
2014-09-12 05:23:46 +08:00
}
void Desfire_3k3des_key_new(const uint8_t value[24], desfirekey_t key) {
2014-09-12 05:23:46 +08:00
uint8_t data[24];
2019-03-10 07:00:59 +08:00
memcpy(data, value, 24);
for (int n = 0; n < 8; n++)
2014-09-12 05:23:46 +08:00
data[n] &= 0xfe;
2019-03-10 07:00:59 +08:00
Desfire_3k3des_key_new_with_version(data, key);
2014-09-12 05:23:46 +08:00
}
void Desfire_3k3des_key_new_with_version(const uint8_t value[24], desfirekey_t key) {
2019-03-10 07:00:59 +08:00
if (key != NULL) {
2019-03-10 03:34:41 +08:00
key->type = T_3K3DES;
2019-03-10 07:00:59 +08:00
memcpy(key->data, value, 24);
update_key_schedules(key);
2019-03-10 03:34:41 +08:00
}
2014-09-12 05:23:46 +08:00
}
void Desfire_aes_key_new(const uint8_t value[16], desfirekey_t key) {
2019-03-10 07:00:59 +08:00
Desfire_aes_key_new_with_version(value, 0, key);
2014-09-12 05:23:46 +08:00
}
void Desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version, desfirekey_t key) {
2014-10-07 01:42:50 +08:00
2019-03-10 03:34:41 +08:00
if (key != NULL) {
2019-03-10 07:00:59 +08:00
memcpy(key->data, value, 16);
2019-03-10 03:34:41 +08:00
key->type = T_AES;
key->aes_version = version;
}
2014-09-12 05:23:46 +08:00
}
uint8_t Desfire_key_get_version(desfirekey_t key) {
2014-09-12 05:23:46 +08:00
uint8_t version = 0;
for (int n = 0; n < 8; n++) {
version |= ((key->data[n] & 1) << (7 - n));
}
return version;
}
void Desfire_key_set_version(desfirekey_t key, uint8_t version) {
2014-09-12 05:23:46 +08:00
for (int n = 0; n < 8; n++) {
2019-03-10 07:00:59 +08:00
uint8_t version_bit = ((version & (1 << (7 - n))) >> (7 - n));
2014-09-12 05:23:46 +08:00
key->data[n] &= 0xfe;
key->data[n] |= version_bit;
if (key->type == T_DES) {
2019-03-10 07:00:59 +08:00
key->data[n + 8] = key->data[n];
2014-09-12 05:23:46 +08:00
} else {
// Write ~version to avoid turning a 3DES key into a DES key
2019-03-10 07:00:59 +08:00
key->data[n + 8] &= 0xfe;
key->data[n + 8] |= ~version_bit;
2014-09-12 05:23:46 +08:00
}
}
}
void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key) {
2014-09-12 05:23:46 +08:00
uint8_t buffer[24];
switch (authkey->type) {
2019-03-10 07:00:59 +08:00
case T_DES:
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
Desfire_des_key_new_with_version(buffer, key);
break;
case T_3DES:
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 4, 4);
memcpy(buffer + 12, rndb + 4, 4);
Desfire_3des_key_new_with_version(buffer, key);
break;
case T_3K3DES:
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 6, 4);
memcpy(buffer + 12, rndb + 6, 4);
memcpy(buffer + 16, rnda + 12, 4);
memcpy(buffer + 20, rndb + 12, 4);
Desfire_3k3des_key_new(buffer, key);
break;
case T_AES:
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 12, 4);
memcpy(buffer + 12, rndb + 12, 4);
Desfire_aes_key_new(buffer, key);
break;
2014-09-12 05:23:46 +08:00
}
2019-03-12 07:12:26 +08:00
}