| /* |
| * This file is part of the flashrom project. |
| * |
| * Copyright (C) 2024 Matti Finder |
| * (written by Matti Finder <matti.finder@gmail.com>) |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; version 2 of the License. |
| * |
| * 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. |
| */ |
| |
| #ifndef __RPMC_H__ |
| #define __RPMC_H__ 1 |
| |
| #include <stdint.h> |
| #include "flash.h" // for flashctx |
| |
| /** |
| * @defgroup flashrom-rpmc RPMC operations |
| * @{ |
| */ |
| |
| #define RPMC_OP1_MSG_HEADER_LENGTH 4 |
| #define RPMC_SIGNATURE_LENGTH 32 |
| #define RPMC_COUNTER_LENGTH 4 |
| #define RPMC_KEY_DATA_LENGTH 4 |
| #define RPMC_TAG_LENGTH 12 |
| #define RPMC_HMAC_KEY_LENGTH 32 |
| #define RPMC_TRUNCATED_SIG_LENGTH 28 |
| |
| enum rpmc_result { |
| RPMC_SUCCESS = 0, |
| RPMC_ERROR_SPI_TRANSMISSION, |
| RPMC_ERROR_OPENSSL, |
| RPMC_ERROR_TAG_MISMATCH, |
| RPMC_ERROR_SIGNATURE_MISMATCH, |
| RPMC_ERROR_INTERNAL, |
| RPMC_ERROR_KEY_READ, |
| RPMC_ERROR_HARDENING_UNSUPPORTED, |
| RPMC_ERROR_COUNTER_OUT_OF_RANGE, |
| RPMC_ERROR_ROOT_KEY_OVERWRITE, |
| RPMC_ERROR_COUNTER_UNINITIALIZED, |
| RPMC_ERROR_COUNTER_DATA_MISMATCH, |
| RPMC_ERROR_HMAC_KEY_REGISTER_UNINITIALIZED, |
| RPMC_ERROR_WRONG_SIGNATURE |
| }; |
| |
| struct rpmc_status_register { |
| /* |
| * Values: |
| * 0b00000000 -> Power on state |
| * 0b10000000 -> Success |
| * 0b0xxxxxx1 -> Busy |
| * 0b0xxxxx1x -> Error: Root key register overwrite, |
| * counter Address out of range, |
| * truncated signature mismatch |
| * or monotonic counter uninitialized |
| * 0b0xxxx1xx -> Error: Signature mismatch, |
| * counter address out of range, |
| * cmdtype out of range |
| * or incorrect payload size |
| * 0b0xxx1xxx -> Error: Hmac key register uninitialized |
| * 0b0xx1xxxx -> Error: Counter data mismatch |
| * 0b0x1xxxxx -> Fatal device error |
| * |
| * Some bits might exclude others or their meaning might be dependent |
| * on previous commands. |
| * Read JESD260 or your device's data sheet for more details. |
| */ |
| uint8_t status; |
| unsigned char tag[RPMC_TAG_LENGTH]; |
| uint32_t counter_data; |
| unsigned char signature[RPMC_SIGNATURE_LENGTH]; |
| }; |
| |
| /** |
| * @brief Write root key on flashchip |
| * |
| * @param[in] flash Flash context which rpmc options will be used |
| * @param[in] keyfile Location of 32-byte key to use |
| * @param[in] counter_address Address of counter (starts at 0) |
| * |
| * @return The result of the operation |
| */ |
| enum rpmc_result rpmc_write_root_key(struct flashrom_flashctx *flash, |
| const char *keyfile, |
| unsigned int counter_address); |
| |
| /** |
| * @brief Update hmac key register |
| * |
| * @param[in] flash Flash context which rpmc options will be used |
| * @param[in] keyfile Location of 32-byte key to use |
| * @param[in] key_data 4-bytes of data to use as key data |
| * @param[in] counter_address Address of counter (starts at 0) |
| * |
| * @return The result of the operation |
| */ |
| enum rpmc_result rpmc_update_hmac_key(struct flashrom_flashctx *flash, |
| const char *keyfile, |
| uint32_t key_data, |
| unsigned int counter_address); |
| |
| /** |
| * @brief Increment monotonic counter value |
| * |
| * @param[in] flash Flash context which rpmc options will be used |
| * @param[in] keyfile Location of 32-byte key to use |
| * @param[in] key_data 4-bytes of data to use as key data |
| * @param[in] counter_address Address of counter (starts at 0) |
| * @param[in] previous_value Previous value of counter |
| * |
| * @return The result of the operation |
| */ |
| enum rpmc_result rpmc_increment_counter(struct flashrom_flashctx *flash, |
| const char *keyfile, |
| uint32_t key_data, |
| unsigned int counter_address, |
| uint32_t previous_value); |
| |
| /** |
| * @brief Get monotonic counter value |
| * |
| * @param[in] flash Flash context which rpmc options will be used |
| * @param[in] keyfile Location of 32-byte key to use |
| * @param[in] key_data 4-bytes of data to use as key data |
| * @param[in] counter_address Address of counter (starts at 0) |
| * @param[out] counter_value Pointer to write the counter value to |
| * |
| * @return The result of the operation |
| */ |
| enum rpmc_result rpmc_get_monotonic_counter(struct flashrom_flashctx *flash, |
| const char *keyfile, |
| uint32_t key_data, |
| unsigned int counter_address, |
| uint32_t *counter_value); |
| |
| /** |
| * @brief Read the full JESD260 extended status register |
| * |
| * @param[in] flash Flash context which rpmc options will be used |
| * @param[out] status Status register to write data into |
| * |
| * @return The result of the operation |
| */ |
| enum rpmc_result rpmc_read_data(struct flashrom_flashctx *flash, |
| struct rpmc_status_register *status); |
| |
| /** |
| * @brief Get a string description for rpmc result |
| * |
| * @param[in] value A rpmc result |
| * |
| * @return String description |
| */ |
| const char * rpmc_describe_result(enum rpmc_result value); |
| |
| /** @} */ /* end flashrom-rpmc */ |
| |
| #endif /* !__RPMC_H__ */ |