/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "avb_ab_flow.h"

bool avb_ab_data_verify_and_byteswap(const AvbABData* src, AvbABData* dest) {
  /* Ensure magic is correct. */
  if (avb_safe_memcmp(src->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) {
    avb_error("Magic is incorrect.\n");
    return false;
  }

  avb_memcpy(dest, src, sizeof(AvbABData));
  dest->crc32 = avb_be32toh(dest->crc32);

  /* Ensure we don't attempt to access any fields if the major version
   * is not supported.
   */
  if (dest->version_major > AVB_AB_MAJOR_VERSION) {
    avb_error("No support for given major version.\n");
    return false;
  }

  /* Bail if CRC32 doesn't match. */
  if (dest->crc32 !=
      avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t))) {
    avb_error("CRC32 does not match.\n");
    return false;
  }

  return true;
}

void avb_ab_data_update_crc_and_byteswap(const AvbABData* src,
                                         AvbABData* dest) {
  avb_memcpy(dest, src, sizeof(AvbABData));
  dest->crc32 = avb_htobe32(
      avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t)));
}

void avb_ab_data_init(AvbABData* data) {
  avb_memset(data, '\0', sizeof(AvbABData));
  avb_memcpy(data->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN);
  data->version_major = AVB_AB_MAJOR_VERSION;
  data->version_minor = AVB_AB_MINOR_VERSION;
  data->slots[0].priority = AVB_AB_MAX_PRIORITY;
  data->slots[0].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  data->slots[0].successful_boot = 0;
  data->slots[1].priority = AVB_AB_MAX_PRIORITY - 1;
  data->slots[1].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  data->slots[1].successful_boot = 0;
}

/* The AvbABData struct is stored 2048 bytes into the 'misc' partition
 * following the 'struct bootloader_message' field. The struct is
 * compatible with the guidelines in bootable/recovery/bootloader.h -
 * e.g. it is stored in the |slot_suffix| field, starts with a
 * NUL-byte, and is 32 bytes long.
 */
#define AB_METADATA_MISC_PARTITION_OFFSET 2048

AvbIOResult avb_ab_data_read(AvbABOps* ab_ops, AvbABData* data) {
  AvbOps* ops = ab_ops->ops;
  AvbABData serialized;
  AvbIOResult io_ret;
  size_t num_bytes_read;

  io_ret = ops->read_from_partition(ops,
                                    "misc",
                                    AB_METADATA_MISC_PARTITION_OFFSET,
                                    sizeof(AvbABData),
                                    &serialized,
                                    &num_bytes_read);
  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
    return AVB_IO_RESULT_ERROR_OOM;
  } else if (io_ret != AVB_IO_RESULT_OK ||
             num_bytes_read != sizeof(AvbABData)) {
    avb_error("Error reading A/B metadata.\n");
    return AVB_IO_RESULT_ERROR_IO;
  }

  if (!avb_ab_data_verify_and_byteswap(&serialized, data)) {
    avb_error(
        "Error validating A/B metadata from disk. "
        "Resetting and writing new A/B metadata to disk.\n");
    avb_ab_data_init(data);
    return avb_ab_data_write(ab_ops, data);
  }

  return AVB_IO_RESULT_OK;
}

AvbIOResult avb_ab_data_write(AvbABOps* ab_ops, const AvbABData* data) {
  AvbOps* ops = ab_ops->ops;
  AvbABData serialized;
  AvbIOResult io_ret;

  avb_ab_data_update_crc_and_byteswap(data, &serialized);
  io_ret = ops->write_to_partition(ops,
                                   "misc",
                                   AB_METADATA_MISC_PARTITION_OFFSET,
                                   sizeof(AvbABData),
                                   &serialized);
  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
    return AVB_IO_RESULT_ERROR_OOM;
  } else if (io_ret != AVB_IO_RESULT_OK) {
    avb_error("Error writing A/B metadata.\n");
    return AVB_IO_RESULT_ERROR_IO;
  }
  return AVB_IO_RESULT_OK;
}

static bool slot_is_bootable(AvbABSlotData* slot) {
  return slot->priority > 0 &&
         (slot->successful_boot || (slot->tries_remaining > 0));
}

static void slot_set_unbootable(AvbABSlotData* slot) {
  slot->priority = 0;
  slot->tries_remaining = 0;
  slot->successful_boot = 0;
}

/* Ensure all unbootable and/or illegal states are marked as the
 * canonical 'unbootable' state, e.g. priority=0, tries_remaining=0,
 * and successful_boot=0.
 */
static void slot_normalize(AvbABSlotData* slot) {
  if (slot->priority > 0) {
    if (slot->tries_remaining == 0 && !slot->successful_boot) {
      /* We've exhausted all tries -> unbootable. */
      slot_set_unbootable(slot);
    }
    if (slot->tries_remaining > 0 && slot->successful_boot) {
      /* Illegal state - avb_ab_mark_slot_successful() will clear
       * tries_remaining when setting successful_boot.
       */
      slot_set_unbootable(slot);
    }
  } else {
    slot_set_unbootable(slot);
  }
}

static const char* slot_suffixes[2] = {"_a", "_b"};

/* Helper function to load metadata - returns AVB_IO_RESULT_OK on
 * success, error code otherwise.
 */
static AvbIOResult load_metadata(AvbABOps* ab_ops,
                                 AvbABData* ab_data,
                                 AvbABData* ab_data_orig) {
  AvbIOResult io_ret;

  io_ret = ab_ops->read_ab_metadata(ab_ops, ab_data);
  if (io_ret != AVB_IO_RESULT_OK) {
    avb_error("I/O error while loading A/B metadata.\n");
    return io_ret;
  }
  *ab_data_orig = *ab_data;

  /* Ensure data is normalized, e.g. illegal states will be marked as
   * unbootable and all unbootable states are represented with
   * (priority=0, tries_remaining=0, successful_boot=0).
   */
  slot_normalize(&ab_data->slots[0]);
  slot_normalize(&ab_data->slots[1]);
  return AVB_IO_RESULT_OK;
}

/* Writes A/B metadata to disk only if it has changed - returns
 * AVB_IO_RESULT_OK on success, error code otherwise.
 */
static AvbIOResult save_metadata_if_changed(AvbABOps* ab_ops,
                                            AvbABData* ab_data,
                                            AvbABData* ab_data_orig) {
  if (avb_safe_memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) {
    avb_debug("Writing A/B metadata to disk.\n");
    return ab_ops->write_ab_metadata(ab_ops, ab_data);
  }
  return AVB_IO_RESULT_OK;
}

AvbABFlowResult avb_ab_flow(AvbABOps* ab_ops,
                            const char* const* requested_partitions,
                            AvbSlotVerifyFlags flags,
                            AvbHashtreeErrorMode hashtree_error_mode,
                            AvbSlotVerifyData** out_data) {
  AvbOps* ops = ab_ops->ops;
  AvbSlotVerifyData* slot_data[2] = {NULL, NULL};
  AvbSlotVerifyData* data = NULL;
  AvbABFlowResult ret;
  AvbABData ab_data, ab_data_orig;
  size_t slot_index_to_boot, n;
  AvbIOResult io_ret;
  bool saw_and_allowed_verification_error = false;

  io_ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
    ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
    goto out;
  } else if (io_ret != AVB_IO_RESULT_OK) {
    ret = AVB_AB_FLOW_RESULT_ERROR_IO;
    goto out;
  }

  /* Validate all bootable slots. */
  for (n = 0; n < 2; n++) {
    if (slot_is_bootable(&ab_data.slots[n])) {
      AvbSlotVerifyResult verify_result;
      bool set_slot_unbootable = false;

      verify_result = avb_slot_verify(ops,
                                      requested_partitions,
                                      slot_suffixes[n],
                                      flags,
                                      hashtree_error_mode,
                                      &slot_data[n]);
      switch (verify_result) {
        case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
          ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
          goto out;

        case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
          ret = AVB_AB_FLOW_RESULT_ERROR_IO;
          goto out;

        case AVB_SLOT_VERIFY_RESULT_OK:
          break;

        case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
        case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
          /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
           * these mean game over.
           */
          set_slot_unbootable = true;
          break;

        /* explicit fallthrough. */
        case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
        case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
        case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
          if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
            /* Do nothing since we allow this. */
            avb_debugv("Allowing slot ",
                       slot_suffixes[n],
                       " which verified "
                       "with result ",
                       avb_slot_verify_result_to_string(verify_result),
                       " because "
                       "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
                       "is set.\n",
                       NULL);
            saw_and_allowed_verification_error = true;
          } else {
            set_slot_unbootable = true;
          }
          break;

        case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
          ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
          goto out;
          /* Do not add a 'default:' case here because of -Wswitch. */
      }

      if (set_slot_unbootable) {
        avb_errorv("Error verifying slot ",
                   slot_suffixes[n],
                   " with result ",
                   avb_slot_verify_result_to_string(verify_result),
                   " - setting unbootable.\n",
                   NULL);
        slot_set_unbootable(&ab_data.slots[n]);
      }
    }
  }

  if (slot_is_bootable(&ab_data.slots[0]) &&
      slot_is_bootable(&ab_data.slots[1])) {
    if (ab_data.slots[1].priority > ab_data.slots[0].priority) {
      slot_index_to_boot = 1;
    } else {
      slot_index_to_boot = 0;
    }
  } else if (slot_is_bootable(&ab_data.slots[0])) {
    slot_index_to_boot = 0;
  } else if (slot_is_bootable(&ab_data.slots[1])) {
    slot_index_to_boot = 1;
  } else {
    /* No bootable slots! */
    avb_error("No bootable slots found.\n");
    ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
    goto out;
  }

  /* Update stored rollback index such that the stored rollback index
   * is the largest value supporting all currently bootable slots. Do
   * this for every rollback index location.
   */
  for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
    uint64_t rollback_index_value = 0;

    if (slot_data[0] != NULL && slot_data[1] != NULL) {
      uint64_t a_rollback_index = slot_data[0]->rollback_indexes[n];
      uint64_t b_rollback_index = slot_data[1]->rollback_indexes[n];
      rollback_index_value =
          (a_rollback_index < b_rollback_index ? a_rollback_index
                                               : b_rollback_index);
    } else if (slot_data[0] != NULL) {
      rollback_index_value = slot_data[0]->rollback_indexes[n];
    } else if (slot_data[1] != NULL) {
      rollback_index_value = slot_data[1]->rollback_indexes[n];
    }

    if (rollback_index_value != 0) {
      uint64_t current_rollback_index_value;
      io_ret = ops->read_rollback_index(ops, n, &current_rollback_index_value);
      if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
        ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
        goto out;
      } else if (io_ret != AVB_IO_RESULT_OK) {
        avb_error("Error getting rollback index for slot.\n");
        ret = AVB_AB_FLOW_RESULT_ERROR_IO;
        goto out;
      }
      if (current_rollback_index_value != rollback_index_value) {
        io_ret = ops->write_rollback_index(ops, n, rollback_index_value);
        if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
          ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
          goto out;
        } else if (io_ret != AVB_IO_RESULT_OK) {
          avb_error("Error setting stored rollback index.\n");
          ret = AVB_AB_FLOW_RESULT_ERROR_IO;
          goto out;
        }
      }
    }
  }

  /* Finally, select this slot. */
  avb_assert(slot_data[slot_index_to_boot] != NULL);
  data = slot_data[slot_index_to_boot];
  slot_data[slot_index_to_boot] = NULL;
  if (saw_and_allowed_verification_error) {
    avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
    ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
  } else {
    ret = AVB_AB_FLOW_RESULT_OK;
  }

  /* ... and decrement tries remaining, if applicable. */
  if (!ab_data.slots[slot_index_to_boot].successful_boot &&
      ab_data.slots[slot_index_to_boot].tries_remaining > 0) {
    ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
  }

out:
  io_ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  if (io_ret != AVB_IO_RESULT_OK) {
    if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
      ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
    } else {
      ret = AVB_AB_FLOW_RESULT_ERROR_IO;
    }
    if (data != NULL) {
      avb_slot_verify_data_free(data);
      data = NULL;
    }
  }

  for (n = 0; n < 2; n++) {
    if (slot_data[n] != NULL) {
      avb_slot_verify_data_free(slot_data[n]);
    }
  }

  if (out_data != NULL) {
    *out_data = data;
  } else {
    if (data != NULL) {
      avb_slot_verify_data_free(data);
    }
  }

  return ret;
}

AvbIOResult avb_ab_mark_slot_active(AvbABOps* ab_ops,
                                    unsigned int slot_number) {
  AvbABData ab_data, ab_data_orig;
  unsigned int other_slot_number;
  AvbIOResult ret;

  avb_assert(slot_number < 2);

  ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  if (ret != AVB_IO_RESULT_OK) {
    goto out;
  }

  /* Make requested slot top priority, unsuccessful, and with max tries. */
  ab_data.slots[slot_number].priority = AVB_AB_MAX_PRIORITY;
  ab_data.slots[slot_number].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
  ab_data.slots[slot_number].successful_boot = 0;

  /* Ensure other slot doesn't have as high a priority. */
  other_slot_number = 1 - slot_number;
  if (ab_data.slots[other_slot_number].priority == AVB_AB_MAX_PRIORITY) {
    ab_data.slots[other_slot_number].priority = AVB_AB_MAX_PRIORITY - 1;
  }

  ret = AVB_IO_RESULT_OK;

out:
  if (ret == AVB_IO_RESULT_OK) {
    ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  }
  return ret;
}

AvbIOResult avb_ab_mark_slot_unbootable(AvbABOps* ab_ops,
                                        unsigned int slot_number) {
  AvbABData ab_data, ab_data_orig;
  AvbIOResult ret;

  avb_assert(slot_number < 2);

  ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  if (ret != AVB_IO_RESULT_OK) {
    goto out;
  }

  slot_set_unbootable(&ab_data.slots[slot_number]);

  ret = AVB_IO_RESULT_OK;

out:
  if (ret == AVB_IO_RESULT_OK) {
    ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  }
  return ret;
}

AvbIOResult avb_ab_mark_slot_successful(AvbABOps* ab_ops,
                                        unsigned int slot_number) {
  AvbABData ab_data, ab_data_orig;
  AvbIOResult ret;

  avb_assert(slot_number < 2);

  ret = load_metadata(ab_ops, &ab_data, &ab_data_orig);
  if (ret != AVB_IO_RESULT_OK) {
    goto out;
  }

  if (!slot_is_bootable(&ab_data.slots[slot_number])) {
    avb_error("Cannot mark unbootable slot as successful.\n");
    ret = AVB_IO_RESULT_OK;
    goto out;
  }

  ab_data.slots[slot_number].tries_remaining = 0;
  ab_data.slots[slot_number].successful_boot = 1;

  ret = AVB_IO_RESULT_OK;

out:
  if (ret == AVB_IO_RESULT_OK) {
    ret = save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
  }
  return ret;
}

const char* avb_ab_flow_result_to_string(AvbABFlowResult result) {
  const char* ret = NULL;

  switch (result) {
    case AVB_AB_FLOW_RESULT_OK:
      ret = "OK";
      break;

    case AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR:
      ret = "OK_WITH_VERIFICATION_ERROR";
      break;

    case AVB_AB_FLOW_RESULT_ERROR_OOM:
      ret = "ERROR_OOM";
      break;

    case AVB_AB_FLOW_RESULT_ERROR_IO:
      ret = "ERROR_IO";
      break;

    case AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS:
      ret = "ERROR_NO_BOOTABLE_SLOTS";
      break;

    case AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT:
      ret = "ERROR_INVALID_ARGUMENT";
      break;
      /* Do not add a 'default:' case here because of -Wswitch. */
  }

  if (ret == NULL) {
    avb_error("Unknown AvbABFlowResult value.\n");
    ret = "(unknown)";
  }

  return ret;
}
