1 /* 2 * Copyright 2021 Google LLC 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 #ifndef PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_H_ 17 #define PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_H_ 18 19 #include <libcr51sign/cr51_image_descriptor.h> 20 #include <stdbool.h> 21 #include <stddef.h> 22 23 #ifdef __cplusplus 24 extern "C" 25 { 26 #endif 27 28 #define LIBCR51SIGN_SHA256_DIGEST_SIZE 32 29 #define LIBCR51SIGN_SHA512_DIGEST_SIZE 64 30 31 #define LIBCR51SIGN_MAX_REGION_COUNT 16 32 33 // Currently RSA4096 (in bytes). 34 #define LIBCR51SIGN_MAX_SIGNATURE_SIZE 512 35 36 #define IMAGE_MAUV_DATA_MAX_SIZE (128) 37 38 // List of common error codes that can be returned 39 enum libcr51sign_validation_failure_reason 40 { 41 // All PayloadRegionState fields are valid & authenticated. 42 LIBCR51SIGN_SUCCESS = 0, 43 44 // Descriptor sanity check failed. None of the following 45 // PayloadRegionState fields are valid/populated. 46 LIBCR51SIGN_ERROR_RUNTIME_FAILURE = 1, 47 LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR = 2, 48 LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR = 3, 49 50 // All fields are populated but may not be authentic. 51 LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY = 4, 52 LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED = 5, 53 LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED = 6, 54 LIBCR51SIGN_ERROR_UNTRUSTED_KEY = 7, 55 LIBCR51SIGN_ERROR_INVALID_SIGNATURE = 8, 56 LIBCR51SIGN_ERROR_INVALID_HASH = 9, 57 LIBCR51SIGN_ERROR_INVALID_HASH_TYPE = 10, 58 // Invalid argument 59 LIBCR51SIGN_ERROR_INVALID_ARGUMENT = 11, 60 LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC = 12, 61 LIBCR51SIGN_ERROR_INVALID_CONTEXT = 13, 62 LIBCR51SIGN_ERROR_INVALID_INTERFACE = 14, 63 LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME = 15, 64 // Invalid image region 65 LIBCR51SIGN_ERROR_INVALID_REGION_INPUT = 16, 66 LIBCR51SIGN_ERROR_INVALID_REGION_SIZE = 17, 67 LIBCR51SIGN_ERROR_INVALID_IMAGE_MAUV_DATA = 18, 68 LIBCR51SIGN_ERROR_RETRIEVING_STORED_IMAGE_MAUV_DATA = 19, 69 LIBCR51SIGN_ERROR_STORING_NEW_IMAGE_MAUV_DATA = 20, 70 LIBCR51SIGN_ERROR_STORED_IMAGE_MAUV_DOES_NOT_ALLOW_UPDATE_TO_PAYLOAD = 21, 71 LIBCR51SIGN_ERROR_VALID_IMAGE_BUT_NEW_IMAGE_MAUV_DATA_NOT_STORED = 22, 72 LIBCR51SIGN_ERROR_STORED_IMAGE_MAUV_EXPECTS_PAYLOAD_IMAGE_MAUV = 23, 73 // Client did not find any stored MAUV in system 74 LIBCR51SIGN_NO_STORED_MAUV_FOUND = 24, 75 LIBCR51SIGN_ERROR_MAX = 25, 76 }; 77 78 struct libcr51sign_ctx 79 { 80 // Absolute image start offset 81 uint32_t start_offset; 82 // Absolute image end offset 83 uint32_t end_offset; 84 size_t block_size; 85 enum image_family current_image_family; 86 enum image_type current_image_type; 87 // keyring_len - number of keys in @a keyring 88 int keyring_len; 89 // valid_key - index of valid key on success 90 size_t* valid_key; 91 // keyring - array of pointers to public keys 92 const void* keyring; 93 void* priv; 94 struct image_descriptor descriptor; 95 }; 96 97 struct libcr51sign_intf 98 { 99 // @func read read data from the image into a buffer 100 // 101 // @param[in] ctx - context struct 102 // @param[in] offset - bytes to seek into the image before reading 103 // @param[in] count - number of bytes to read 104 // @param[out] buf - pointer to buffer where result will be written 105 // 106 // @return nonzero on error, zero on success 107 108 int (*read)(const void*, uint32_t, uint32_t, uint8_t*); 109 110 // @func hash_init get ready to compute a hash 111 // 112 // @param[in] ctx - context struct 113 // @param[in] hash_type - type of hash function to use 114 // 115 // @return nonzero on error, zero on success 116 117 int (*hash_init)(const void*, enum hash_type); 118 119 // @func hash_update add data to the hash 120 // 121 // @param[in] ctx - context struct 122 // @param[in] buf - data to add to hash 123 // @param[in] count - number of bytes of data to add 124 // @param[in] hash_type - type of hash function to use 125 // 126 // @return nonzero on error, zero on success 127 128 int (*hash_update)(void*, const uint8_t*, size_t); 129 130 // Note this is a combination of an spi_nor_read() with spi_transaction() 131 // It is the responsibility of the caller to synchronize with other 132 // potential SPI clients / transactions. Collapsing the SPI stack results in 133 // a 2x throughput improvement (~20s -> ~10s to verify an Indus image with 134 // SHA256 HW acceleration). 135 // 136 // The caller is responsible for calling DCRYPTO_init()/HASH_final(). 137 138 int (*read_and_hash_update)(void* ctx, uint32_t offset, uint32_t size); 139 140 // @func hash_final finish hash calculation 141 // 142 // @param[in] ctx - context struct 143 // @param[out] hash - buffer to write hash to 144 // @param[in] hash_type - type of hash function to use 145 // 146 // @return nonzero on error, zero on success 147 148 int (*hash_final)(void*, uint8_t*); 149 150 // @func verify check that the signature is valid for given hashed data 151 // 152 // @param[in] ctx - context struct 153 // @param[in] scheme - type of signature, hash, etc. 154 // @param[in] sig - signature blob 155 // @param[in] sig_len - length of signature in bytes 156 // @param[in] data - pre-hashed data to verify 157 // @param[in] data_len - length of hashed data in bytes 158 // 159 // @return nonzero on error, zero on success 160 161 int (*verify_signature)(const void*, enum signature_scheme, const uint8_t*, 162 size_t, const uint8_t*, size_t); 163 164 // @func verify check that if the prod to dev downgrade/ hardware allowlist 165 // is allowed 166 // @return true: if allowed 167 // false: if not allowed 168 // BMC would return always false or pass a NULL pointer 169 // If NULL, treated as if the function always returns false. 170 171 bool (*prod_to_dev_downgrade_allowed)(); 172 173 // @func returns true if the current firmware is running in production mode. 174 // @return true: if in production mode 175 // false: if in any non-production mode 176 177 bool (*is_production_mode)(); 178 179 // @func returns true if the descriptor image size is valid. 180 bool (*image_size_valid)(size_t); 181 182 // @func Retrieve MAUV data currently stored in the system 183 // @param[in] ctx - context struct 184 // @param[out] current_image_mauv - Buffer to store the retrieved MAUV data 185 // @param[out] current_image_mauv_size - Number of bytes retrieved and 186 // stored 187 // in `current_image_mauv` 188 // @param[in] max_image_mauv_size - Maximum number of bytes to retrieve for 189 // MAUV data 190 // 191 // @return LIBCR51SIGN_SUCCESS: when MAUV is present in the system and 192 // retrieved successfully 193 // LIBCR51SIGN_NO_STORED_MAUV_FOUND: when MAUV is not present in the 194 // system (we are trusting the 195 // client here to return this 196 // value truthfully) 197 // other non-zero values: any other error scenario (like read 198 // failure, 199 // data corruption, etc.) 200 int (*retrieve_stored_image_mauv_data)(const void*, uint8_t* const, 201 uint32_t* const, const uint32_t); 202 203 // @func Store new MAUV data in the system 204 // @param[in] ctx - context struct 205 // @param[in] new_image_mauv - Buffer containing new MAUV data to be stored 206 // @param[in] new_image_mauv_size - Size of MAUV data in `new_image_mauv` 207 // buffer 208 // 209 // @return LIBCR51SIGN_SUCCESS: when new MAUV data is stored successfully. 210 // Non-zero value otherwise 211 int (*store_new_image_mauv_data)(const void*, const uint8_t* const, 212 const uint32_t); 213 }; 214 215 struct libcr51sign_validated_regions 216 { 217 uint32_t region_count; 218 struct image_region image_regions[LIBCR51SIGN_MAX_REGION_COUNT]; 219 }; 220 221 // Check whether the signature on the image is valid. 222 // Validates the authenticity of an EEPROM image. Scans for & validates the 223 // signature on the image descriptor. If the descriptor validates, hashes the 224 // rest of the image to verify its integrity. 225 // 226 // @param[in] ctx - context which describes the image and holds opaque private 227 // data for the user of the library 228 // @param[in] intf - function pointers which interface to the current system 229 // and environment 230 // @param[out] image_regions - image_region pointer to an array for the output 231 // 232 // @return nonzero on error, zero on success 233 234 enum libcr51sign_validation_failure_reason libcr51sign_validate( 235 const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf, 236 struct libcr51sign_validated_regions* image_regions); 237 238 // Function to convert error code to string format 239 // @param[in] ec - error code 240 // @return error code in string format 241 242 const char* libcr51sign_errorcode_to_string( 243 enum libcr51sign_validation_failure_reason ec); 244 245 // Returns the hash_type for a given signature scheme 246 // @param[in] scheme - signature scheme 247 // @param[out] type - hash_type supported by given signature_scheme 248 // 249 // @return nonzero on error, zero on success 250 251 enum libcr51sign_validation_failure_reason get_hash_type_from_signature( 252 enum signature_scheme scheme, enum hash_type* type); 253 254 #ifdef __cplusplus 255 } // extern "C" 256 #endif 257 258 #endif // PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_H_ 259