1 /* 2 * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #pragma once 8 #include <stdbool.h> 9 10 #include "esp_hmac.h" 11 #include "esp_err.h" 12 #include "esp_ds_err.h" 13 #include "soc/soc_caps.h" 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 #define ESP_DS_IV_BIT_LEN 128 20 #define ESP_DS_IV_LEN (ESP_DS_IV_BIT_LEN / 8) 21 #define ESP_DS_SIGNATURE_MAX_BIT_LEN SOC_RSA_MAX_BIT_LEN 22 #define ESP_DS_SIGNATURE_MD_BIT_LEN 256 23 #define ESP_DS_SIGNATURE_M_PRIME_BIT_LEN 32 24 #define ESP_DS_SIGNATURE_L_BIT_LEN 32 25 #define ESP_DS_SIGNATURE_PADDING_BIT_LEN 64 26 27 /* Length of parameter 'C' stored in flash, in bytes 28 - Operands Y, M and r_bar; each equal to maximum RSA bit length 29 - Operand MD (message digest); 256 bits 30 - Operands M' and L; each 32 bits 31 - Operand beta (padding value; 64 bits 32 */ 33 #define ESP_DS_C_LEN (((ESP_DS_SIGNATURE_MAX_BIT_LEN * 3 \ 34 + ESP_DS_SIGNATURE_MD_BIT_LEN \ 35 + ESP_DS_SIGNATURE_M_PRIME_BIT_LEN \ 36 + ESP_DS_SIGNATURE_L_BIT_LEN \ 37 + ESP_DS_SIGNATURE_PADDING_BIT_LEN) / 8)) 38 39 typedef struct esp_ds_context esp_ds_context_t; 40 41 typedef enum { 42 ESP_DS_RSA_1024 = (1024 / 32) - 1, 43 ESP_DS_RSA_2048 = (2048 / 32) - 1, 44 ESP_DS_RSA_3072 = (3072 / 32) - 1, 45 ESP_DS_RSA_4096 = (4096 / 32) - 1 46 } esp_digital_signature_length_t; 47 48 /** 49 * Encrypted private key data. Recommended to store in flash in this format. 50 * 51 * @note This struct has to match to one from the ROM code! This documentation is mostly taken from there. 52 */ 53 typedef struct esp_digital_signature_data { 54 /** 55 * RSA LENGTH register parameters 56 * (number of words in RSA key & operands, minus one). 57 * 58 * This value must match the length field encrypted and stored in 'c', 59 * or invalid results will be returned. (The DS peripheral will 60 * always use the value in 'c', not this value, so an attacker can't 61 * alter the DS peripheral results this way, it will just truncate or 62 * extend the message and the resulting signature in software.) 63 * 64 * @note In IDF, the enum type length is the same as of type unsigned, so they can be used interchangably. 65 * See the ROM code for the original declaration of struct \c ets_ds_data_t. 66 */ 67 esp_digital_signature_length_t rsa_length; 68 69 /** 70 * IV value used to encrypt 'c' 71 */ 72 uint32_t iv[ESP_DS_IV_BIT_LEN / 32]; 73 74 /** 75 * Encrypted Digital Signature parameters. Result of AES-CBC encryption 76 * of plaintext values. Includes an encrypted message digest. 77 */ 78 uint8_t c[ESP_DS_C_LEN]; 79 } esp_ds_data_t; 80 81 /** 82 * Plaintext parameters used by Digital Signature. 83 * 84 * This is only used for encrypting the RSA parameters by calling esp_ds_encrypt_params(). 85 * Afterwards, the result can be stored in flash or in other persistent memory. 86 * The encryption is a prerequisite step before any signature operation can be done. 87 * 88 * @note 89 * Y, M, Rb, & M_Prime must all be in little endian format. 90 */ 91 typedef struct { 92 uint32_t Y[ESP_DS_SIGNATURE_MAX_BIT_LEN / 32]; //!< RSA exponent 93 uint32_t M[ESP_DS_SIGNATURE_MAX_BIT_LEN / 32]; //!< RSA modulus 94 uint32_t Rb[ESP_DS_SIGNATURE_MAX_BIT_LEN / 32]; //!< RSA r inverse operand 95 uint32_t M_prime; //!< RSA M prime operand 96 uint32_t length; //!< RSA length in words (32 bit) 97 } esp_ds_p_data_t; 98 99 /** 100 * @brief Sign the message with a hardware key from specific key slot. 101 * The function calculates a plain RSA signature with help of the DS peripheral. 102 * The RSA encryption operation is as follows: 103 * Z = XY mod M where, 104 * Z is the signature, X is the input message, 105 * Y and M are the RSA private key parameters. 106 * 107 * This function is a wrapper around \c esp_ds_finish_sign() and \c esp_ds_start_sign(), so do not use them 108 * in parallel. 109 * It blocks until the signing is finished and then returns the signature. 110 * 111 * @note 112 * Please see note section of \c esp_ds_start_sign() for more details about the input parameters. 113 * 114 * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes, and those 115 bytes must be in little endian format. It is your responsibility to apply your hash function 116 and padding before calling this function, if required. (e.g. message = padding(hash(inputMsg))) 117 * @param data the encrypted signing key data (AES encrypted RSA key + IV) 118 * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the 119 * signing key data 120 * @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long 121 * 122 * @return 123 * - ESP_OK if successful, the signature was written to the parameter \c signature. 124 * - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0 125 * - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key 126 * - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object 127 * - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component 128 * - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid. 129 * - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though 130 * since the message digest matches. 131 */ 132 esp_err_t esp_ds_sign(const void *message, 133 const esp_ds_data_t *data, 134 hmac_key_id_t key_id, 135 void *signature); 136 137 /** 138 * @brief Start the signing process. 139 * 140 * This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing 141 * process. 142 * The function calculates a plain RSA signature with help of the DS peripheral. 143 * The RSA encryption operation is as follows: 144 * Z = XY mod M where, 145 * Z is the signature, X is the input message, 146 * Y and M are the RSA private key parameters. 147 * 148 * @note 149 * This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call 150 * \c esp_ds_finish_sign() in a timely manner. 151 * The numbers Y, M, Rb which are a part of esp_ds_data_t should be provided in little endian format 152 * and should be of length equal to the RSA private key bit length 153 * The message length in bits should also be equal to the RSA private key bit length. 154 * No padding is applied to the message automatically, Please ensure the message is appropriate padded before 155 * calling the API. 156 * 157 * @param message the message to be signed; its length should be (data->rsa_length + 1)*4 bytes, and those 158 bytes must be in little endian format. It is your responsibility to apply your hash function 159 and padding before calling this function, if required. (e.g. message = padding(hash(inputMsg))) 160 * @param data the encrypted signing key data (AES encrypted RSA key + IV) 161 * @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the 162 * signing key data 163 * @param esp_ds_ctx the context object which is needed for finishing the signing process later 164 * 165 * @return 166 * - ESP_OK if successful, the ds operation was started now and has to be finished with \c esp_ds_finish_sign() 167 * - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0 168 * - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key 169 * - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object 170 * - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component 171 */ 172 esp_err_t esp_ds_start_sign(const void *message, 173 const esp_ds_data_t *data, 174 hmac_key_id_t key_id, 175 esp_ds_context_t **esp_ds_ctx); 176 177 /** 178 * Return true if the DS peripheral is busy, otherwise false. 179 * 180 * @note Only valid if \c esp_ds_start_sign() was called before. 181 */ 182 bool esp_ds_is_busy(void); 183 184 /** 185 * @brief Finish the signing process. 186 * 187 * @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long, 188 the resultant signature bytes shall be written in little endian format. 189 * @param esp_ds_ctx the context object retreived by \c esp_ds_start_sign() 190 * 191 * @return 192 * - ESP_OK if successful, the ds operation has been finished and the result is written to signature. 193 * - ESP_ERR_INVALID_ARG if one of the parameters is NULL 194 * - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid. 195 * This means that the encrypted RSA key parameters are invalid, indicating that they may have been tampered 196 * with or indicating a flash error, etc. 197 * - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though 198 * since the message digest matches (see TRM for more details). 199 */ 200 esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx); 201 202 /** 203 * @brief Encrypt the private key parameters. 204 * 205 * The encryption is a prerequisite step before any signature operation can be done. 206 * It is not strictly necessary to use this encryption function, the encryption could also happen on an external 207 * device. 208 * 209 * @param data Output buffer to store encrypted data, suitable for later use generating signatures. 210 * @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time. 211 * @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process 212 * is done and 'data' is stored. 213 * @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the 214 * corresponding HMAC key will be stored to efuse and then permanently erased. 215 * 216 * @note 217 * The numbers Y, M, Rb which are a part of esp_ds_data_t should be provided in little endian format 218 * and should be of length equal to the RSA private key bit length 219 * The message length in bits should also be equal to the RSA private key bit length. 220 * No padding is applied to the message automatically, Please ensure the message is appropriate padded before 221 * calling the API. 222 * 223 * @return 224 * - ESP_OK if successful, the ds operation has been finished and the result is written to signature. 225 * - ESP_ERR_INVALID_ARG if one of the parameters is NULL or p_data->rsa_length is too long 226 */ 227 esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data, 228 const void *iv, 229 const esp_ds_p_data_t *p_data, 230 const void *key); 231 232 #ifdef __cplusplus 233 } 234 #endif 235