فهرست منبع

Save off adf_response before decryption since iv is mutated

Eric Betts 8 ماه پیش
والد
کامیت
0d08add355
1فایلهای تغییر یافته به همراه24 افزوده شده و 20 حذف شده
  1. 24 20
      seos_reader.c

+ 24 - 20
seos_reader.c

@@ -261,25 +261,39 @@ bool seos_reader_select_adf_response(
     params->cipher = rx_data[2];
     params->hash = rx_data[3];
 
+    memset(credential->adf_response, 0, sizeof(credential->adf_response));
+    size_t response_length = bit_buffer_get_size_bytes(rx_buffer) - offset - sizeof(success);
+    if(response_length > sizeof(credential->adf_response)) {
+        FURI_LOG_W(
+            TAG,
+            "adf_response too large %zu > %zu",
+            response_length,
+            sizeof(credential->adf_response));
+        response_length = sizeof(credential->adf_response);
+    }
+    memcpy(credential->adf_response, rx_data, response_length);
+
     size_t bufLen = 0;
     uint8_t clear[0x40];
     memset(clear, 0, sizeof(clear));
 
+    // Copy IV because mbedtls methods mutate it
     if(params->cipher == AES_128_CBC) {
-        size_t ivLen = 16;
-        bufLen = rx_data[5] - ivLen;
-        uint8_t* iv = (uint8_t*)rx_data + 6;
-        uint8_t* enc = (uint8_t*)rx_data + 6 + ivLen;
+        uint8_t iv[16];
+        memcpy(iv, rx_data + 6, sizeof(iv));
+        bufLen = rx_data[5] - sizeof(iv);
+        uint8_t* enc = (uint8_t*)rx_data + 6 + sizeof(iv);
+
         mbedtls_aes_context ctx;
         mbedtls_aes_init(&ctx);
         mbedtls_aes_setkey_dec(&ctx, SEOS_ADF1_PRIV_ENC, sizeof(SEOS_ADF1_PRIV_ENC) * 8);
         mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, bufLen, iv, enc, clear);
         mbedtls_aes_free(&ctx);
     } else if(params->cipher == TWO_KEY_3DES_CBC_MODE) {
-        size_t ivLen = 8;
-        bufLen = rx_data[5] - ivLen;
-        uint8_t* iv = (uint8_t*)rx_data + 6;
-        uint8_t* enc = (uint8_t*)rx_data + 6 + ivLen;
+        uint8_t iv[8];
+        memcpy(iv, rx_data + 6, sizeof(iv));
+        bufLen = rx_data[5] - sizeof(iv);
+        uint8_t* enc = (uint8_t*)rx_data + 6 + sizeof(iv);
 
         mbedtls_des3_context ctx;
         mbedtls_des3_init(&ctx);
@@ -305,18 +319,6 @@ bool seos_reader_select_adf_response(
         return false;
     }
 
-    memset(credential->adf_response, 0, sizeof(credential->adf_response));
-    size_t response_length = bit_buffer_get_size_bytes(rx_buffer) - offset - sizeof(success);
-    if(response_length > sizeof(credential->adf_response)) {
-        FURI_LOG_W(
-            TAG,
-            "adf_response too large %zu > %zu",
-            response_length,
-            sizeof(credential->adf_response));
-        response_length = sizeof(credential->adf_response);
-    }
-    memcpy(credential->adf_response, rx_data, response_length);
-
     uint8_t* diversifier = clear + 2 + oidLen + 2;
     memcpy(credential->diversifier, diversifier, credential->diversifier_len);
 
@@ -441,10 +443,12 @@ NfcCommand seos_state_machine(Seos* seos, Iso14443_4aPoller* iso14443_4a_poller)
         if(seos_reader_request_sio(seos_reader)) {
             SeosCredential* credential = seos_reader->credential;
             AuthParameters* params = &seos_reader->params;
+
             memcpy(credential->priv_key, params->priv_key, sizeof(credential->priv_key));
             memcpy(credential->auth_key, params->auth_key, sizeof(credential->auth_key));
             credential->adf_oid_len = SEOS_ADF_OID_LEN;
             memcpy(credential->adf_oid, SEOS_ADF_OID, sizeof(credential->adf_oid));
+
             view_dispatcher_send_custom_event(seos->view_dispatcher, SeosCustomEventReaderSuccess);
         }