1 // Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 #include <stdint.h> 22 #include <stdbool.h> 23 24 #define ETS_DS_MAX_BITS 3072 25 26 #define ETS_DS_IV_LEN 16 27 28 /* Length of parameter 'C' stored in flash (not including IV) 29 30 Comprises encrypted Y, M, rinv, md (32), mprime (4), length (4), padding (8) 31 32 Note that if ETS_DS_MAX_BITS<4096, 'C' needs to be split up when writing to hardware 33 */ 34 #define ETS_DS_C_LEN ((ETS_DS_MAX_BITS * 3 / 8) + 32 + 8 + 8) 35 36 /* Encrypted ETS data. Recommended to store in flash in this format. 37 */ 38 typedef struct { 39 /* RSA LENGTH register parameters 40 * (number of words in RSA key & operands, minus one). 41 * 42 * 43 * This value must match the length field encrypted and stored in 'c', 44 * or invalid results will be returned. (The DS peripheral will 45 * always use the value in 'c', not this value, so an attacker can't 46 * alter the DS peripheral results this way, it will just truncate or 47 * extend the message and the resulting signature in software.) 48 */ 49 unsigned rsa_length; 50 51 /* IV value used to encrypt 'c' */ 52 uint8_t iv[ETS_DS_IV_LEN]; 53 54 /* Encrypted Digital Signature parameters. Result of AES-CBC encryption 55 of plaintext values. Includes an encrypted message digest. 56 */ 57 uint8_t c[ETS_DS_C_LEN]; 58 } ets_ds_data_t; 59 60 typedef enum { 61 ETS_DS_OK, 62 ETS_DS_INVALID_PARAM, /* Supplied parameters are invalid */ 63 ETS_DS_INVALID_KEY, /* HMAC peripheral failed to supply key */ 64 ETS_DS_INVALID_PADDING, /* 'c' decrypted with invalid padding */ 65 ETS_DS_INVALID_DIGEST, /* 'c' decrypted with invalid digest */ 66 } ets_ds_result_t; 67 68 void ets_ds_enable(void); 69 70 void ets_ds_disable(void); 71 72 73 /* 74 * @brief Start signing a message (or padded message digest) using the Digital Signature peripheral 75 * 76 * - @param message Pointer to message (or padded digest) containing the message to sign. Should be 77 * (data->rsa_length + 1)*4 bytes long. @param data Pointer to DS data. Can be a pointer to data 78 * in flash. 79 * 80 * Caller must have already called ets_ds_enable() and ets_hmac_calculate_downstream() before calling 81 * this function, and is responsible for calling ets_ds_finish_sign() and then 82 * ets_hmac_invalidate_downstream() afterwards. 83 * 84 * @return ETS_DS_OK if signature is in progress, ETS_DS_INVALID_PARAM if param is invalid, 85 * EST_DS_INVALID_KEY if key or HMAC peripheral is configured incorrectly. 86 */ 87 ets_ds_result_t ets_ds_start_sign(const void *message, const ets_ds_data_t *data); 88 89 90 /* 91 * @brief Returns true if the DS peripheral is busy following a call to ets_ds_start_sign() 92 * 93 * A result of false indicates that a call to ets_ds_finish_sign() will not block. 94 * 95 * Only valid if ets_ds_enable() has been called. 96 */ 97 bool ets_ds_is_busy(void); 98 99 100 /* @brief Finish signing a message using the Digital Signature peripheral 101 * 102 * Must be called after ets_ds_start_sign(). Can use ets_ds_busy() to wait until 103 * peripheral is no longer busy. 104 * 105 * - @param signature Pointer to buffer to contain the signature. Should be 106 * (data->rsa_length + 1)*4 bytes long. 107 * - @param data Should match the 'data' parameter passed to ets_ds_start_sign() 108 * 109 * @param ETS_DS_OK if signing succeeded, ETS_DS_INVALID_PARAM if param is invalid, 110 * ETS_DS_INVALID_DIGEST or ETS_DS_INVALID_PADDING if there is a problem with the 111 * encrypted data digest or padding bytes (in case of ETS_DS_INVALID_PADDING, a 112 * digest is produced anyhow.) 113 */ 114 ets_ds_result_t ets_ds_finish_sign(void *signature, const ets_ds_data_t *data); 115 116 117 /* Plaintext parameters used by Digital Signature. 118 119 Not used for signing with DS peripheral, but can be encrypted 120 in-device by calling ets_ds_encrypt_params() 121 */ 122 typedef struct { 123 uint32_t Y[ETS_DS_MAX_BITS / 32]; 124 uint32_t M[ETS_DS_MAX_BITS / 32]; 125 uint32_t Rb[ETS_DS_MAX_BITS / 32]; 126 uint32_t M_prime; 127 uint32_t length; 128 } ets_ds_p_data_t; 129 130 typedef enum { 131 ETS_DS_KEY_HMAC, /* The HMAC key (as stored in efuse) */ 132 ETS_DS_KEY_AES, /* The AES key (as derived from HMAC key by HMAC peripheral in downstream mode) */ 133 } ets_ds_key_t; 134 135 /* @brief Encrypt DS parameters suitable for storing and later use with DS peripheral 136 * 137 * @param data Output buffer to store encrypted data, suitable for later use generating signatures. 138 * @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time. 139 * @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process is done and 'data' is stored. 140 * @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the corresponding HMAC key will be stored to efuse and then permanently erased. 141 * @param key_type Type of key stored in 'key' (either the AES-256 DS key, or an HMAC DS key from which the AES DS key is derived using HMAC peripheral) 142 * 143 * @return ETS_DS_INVALID_PARAM if any parameter is invalid, or ETS_DS_OK if 'data' is successfully generated from the input parameters. 144 */ 145 ets_ds_result_t ets_ds_encrypt_params(ets_ds_data_t *data, const void *iv, const ets_ds_p_data_t *p_data, const void *key, ets_ds_key_t key_type); 146 147 148 #ifdef __cplusplus 149 } 150 #endif 151