1 /* 2 * Copyright (c) 2023-2024, Arm Limited. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * \file integrity_checker_drv.h 19 * \brief Driver for Arm Integrity Checker. 20 */ 21 22 #ifndef __INTEGRITY_CHECKER_DRV_H__ 23 #define __INTEGRITY_CHECKER_DRV_H__ 24 25 #include <stdint.h> 26 #include <stddef.h> 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #define INTEGRITY_CHECKER_CONFIG_REMAP_REGION_AM 4 33 34 #define INTEGRITY_CHECKER_OUTPUT_SIZE_ZERO_COUNT 4 35 #define INTEGRITY_CHECKER_OUTPUT_SIZE_CRC32 4 36 #define INTEGRITY_CHECKER_OUTPUT_SIZE_SHA256 32 37 38 #define INTEGRITY_CHECKER_REQUIRED_ALIGNMENT 8 39 40 enum integrity_checker_error_t { 41 INTEGRITY_CHECKER_ERROR_NONE = 0x0u, 42 INTEGRITY_CHECKER_ERROR_OUTPUT_BUFFER_TOO_SMALL, 43 INTEGRITY_CHECKER_ERROR_VALUE_BUFFER_TOO_SMALL, 44 INTEGRITY_CHECKER_ERROR_UNSUPPORTED_MODE, 45 INTEGRITY_CHECKER_ERROR_COMPARISON_FAILED, 46 INTEGRITY_CHECKER_ERROR_OPERATION_FAILED, 47 INTEGRITY_CHECKER_ERROR_INVALID_ALIGNMENT, 48 INTEGRITY_CHECKER_ERROR_INVALID_LENGTH, 49 }; 50 51 enum integrity_checker_mode_t { 52 INTEGRITY_CHECKER_MODE_ZERO_COUNT = 0b00, 53 INTEGRITY_CHECKER_MODE_CRC32 = 0b01, 54 INTEGRITY_CHECKER_MODE_SHA256 = 0b10, 55 }; 56 57 typedef struct { 58 uintptr_t region_base; /*!< The base of the region that will be remapped */ 59 size_t region_size; /*!< The size of the region that will be remapped */ 60 uintptr_t remap_base; /*!< The base of the region that mapped to */ 61 size_t remap_cpusel_offset; /*!< How much the remap will be incremented per cpu */ 62 } integrity_checker_remap_region_t; 63 64 /** 65 * \brief ARM Integrity Checker device configuration structure 66 */ 67 struct integrity_checker_dev_cfg_t { 68 const uintptr_t base; /*!< Integrity Checker base address */ 69 uint32_t remap_cpusel; 70 integrity_checker_remap_region_t remap_regions[INTEGRITY_CHECKER_CONFIG_REMAP_REGION_AM]; 71 }; 72 73 /** 74 * \brief ARM Integrity Checker device structure 75 */ 76 struct integrity_checker_dev_t { 77 const struct integrity_checker_dev_cfg_t *const cfg; /*!< Integrity Checker configuration */ 78 }; 79 80 /** 81 * \brief Compute an integrity value of a given buffer and 82 * output it. 83 * 84 * \param[in] dev The Integrity Checker device. 85 * \param[in] mode Which mode the Integrity Checker should use to 86 * calculate the integrity value. This may change the 87 * size of the output value. 88 * \param[in] data The buffer to calculate the integrity value from. 89 * \param[in] size The size of the data buffer. 90 * \param[out] value The buffer to write the integrity value into. 91 * \param[in] value_size The size of the buffer to write the integrity value 92 * into. 93 * \param[out] value_len The length of the outputted integrity value. This 94 * value can be NULL if the integrity value length 95 * isn't needed 96 * 97 * \return INTEGRITY_CHECKER_ERROR_NONE on success, otherwise 98 * a different integrity_checker_error_t. 99 */ 100 enum integrity_checker_error_t integrity_checker_compute_value(struct integrity_checker_dev_t *dev, 101 enum integrity_checker_mode_t mode, 102 const uint32_t *data, size_t size, 103 uint32_t *value, size_t value_size, 104 size_t *value_len); 105 106 /** 107 * \brief Check the integrity value of a given buffer against 108 * a given value. 109 * 110 * \param[in] dev The Integrity Checker device. 111 * \param[in] mode Which mode the Integrity Checker should use to 112 * calculate the integrity value. This may change the 113 * size that will be read from the value buffer. 114 * \param[in] data The buffer to calculate the integrity value from. 115 * \param[in] size The size of the data buffer. 116 * \param[in] value The buffer to read the integrity value from. 117 * \param[in] value_size The size of the buffer to read the integrity value 118 * from. 119 * 120 * \return INTEGRITY_CHECKER_ERROR_NONE on success, 121 * INTEGRITY_CHECKER_ERROR_COMPARISON_FAILED if the 122 * integrity value does not match the computed value, 123 * otherwise a different integrity_checker_error_t. 124 */ 125 enum integrity_checker_error_t integrity_checker_check_value(struct integrity_checker_dev_t *dev, 126 enum integrity_checker_mode_t mode, 127 const uint32_t *data, size_t size, 128 const uint32_t *value, size_t value_size); 129 130 131 #ifdef __cplusplus 132 } 133 #endif 134 135 #endif /* __INTEGRITY_CHECKER_DRV_H__ */ 136