diff --git a/HACKING b/HACKING index 1b4ea65..7f546f4 100644 --- a/HACKING +++ b/HACKING @@ -70,3 +70,15 @@ infrastructure ready for hacking the new card support: knows... - _tag_free() SHALL free all resources allocated for the tag (surprising, isn't it?) + + +Various guidelines +------------------ + + - If a given card has different cryptographic modes, you SHOULD use + switch/cases to handle specific branches of code, even when applicable to + only one cypher. The idea is that if you don't provide support for all + cryptographic schemes, or if an evolution of the card provides more + cryptographic possibilities, when adding support for a new cypher, the + compiler can warn the developer about unhandled values in switch + statements. Please refer to the Mifare DESFire code for an example. diff --git a/libfreefare/mifare_desfire.c b/libfreefare/mifare_desfire.c index f42c69e..c58464d 100644 --- a/libfreefare/mifare_desfire.c +++ b/libfreefare/mifare_desfire.c @@ -395,8 +395,14 @@ authenticate (MifareTag tag, uint8_t cmd, uint8_t key_no, MifareDESFireKey key) MIFARE_DESFIRE (tag)->session_key = mifare_desfire_session_key_new (PCD_RndA, PICC_RndB, key); memset (MIFARE_DESFIRE (tag)->ivect, 0, MAX_CRYPTO_BLOCK_SIZE); - if (MIFARE_DESFIRE (tag)->session_key->type == T_AES) + switch (MIFARE_DESFIRE (tag)->session_key->type) { + case T_DES: + case T_3DES: + break; + case T_AES: cmac_generate_subkeys (MIFARE_DESFIRE (tag)->session_key); + break; + } return 0; } @@ -1196,10 +1202,16 @@ read_data (MifareTag tag, uint8_t command, uint8_t file_no, off_t offset, size_t BUFFER_APPEND_LE (cmd, offset, 3, sizeof (off_t)); BUFFER_APPEND_LE (cmd, length, 3, sizeof (size_t)); - // FIXME This is somewhat done in mifare_cryto_preprocess_data (or should be!!) uint8_t ocs = cs; - if ((MIFARE_DESFIRE (tag)->session_key) && (MIFARE_DESFIRE (tag)->session_key->type == T_AES) && (cs | MDCM_MACED)) { - cs = MDCM_PLAIN; + if ((MIFARE_DESFIRE (tag)->session_key) && (cs | MDCM_MACED)) { + switch (MIFARE_DESFIRE (tag)->session_key->type) { + case T_DES: + case T_3DES: + break; + case T_AES: + cs = MDCM_PLAIN; + break; + } } uint8_t *p = mifare_cryto_preprocess_data (tag, cmd, &__cmd_n, 8, cs | CMAC_COMMAND); cs = ocs; diff --git a/libfreefare/mifare_desfire_authenticate.c b/libfreefare/mifare_desfire_authenticate.c index 499efe6..258500f 100644 --- a/libfreefare/mifare_desfire_authenticate.c +++ b/libfreefare/mifare_desfire_authenticate.c @@ -403,12 +403,20 @@ mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, off_t o memcpy (res, data, *nbytes); if (!(communication_settings & NO_CRC)) { // ... CRC ... + switch (key->type) { + case T_DES: + case T_3DES: iso14443a_crc_append ((uint8_t *)res + offset, *nbytes - offset); - } else { - bzero ((uint8_t *) res + *nbytes, 2); + *nbytes += 2; + break; + case T_AES: + // Never reached. + abort (); + break; + } } // ... and 0 padding - memset ((uint8_t *)(res) + *nbytes + 2, 0, edl - *nbytes - 2); + memset ((uint8_t *)(res) + *nbytes, 0, edl - *nbytes); *nbytes = edl;