/** * @file crypto.h * @brief Lightweight AES-128-CBC + HMAC-SHA256 for STM32G474 * * Uses STM32G474 hardware AES (CRYP peripheral) for acceleration. * HMAC-SHA256 uses software implementation (mbedTLS or built-in). * * Hardware AES on G474: ~28 cycles/block vs ~300 cycles/block software. * 128KB firmware decrypt: ~15ms (HW AES) vs ~500ms (SW AES). */ #ifndef _CRYPTO_H_ #define _CRYPTO_H_ #include #include #include /* ==================== AES-128-CBC (Hardware CRYP) ==================== */ /** * @brief Initialize CRYP peripheral for AES-128-CBC decryption * @param key AES-128 key (16 bytes) */ void CRYPTO_AES_Init(const uint8_t *key); /** * @brief Deinitialize CRYP peripheral (power save) */ void CRYPTO_AES_Deinit(void); /** * @brief AES-128-CBC decrypt a data buffer in-place * * Decrypts data in-place. First 16 bytes are the IV. * PKCS7 padding is NOT removed by this function. * * @param data Input: IV(16) + ciphertext. Output: plaintext. * @param len Total length (must be multiple of 16, >= 32) * @return true on success, false on error */ bool CRYPTO_AES_CBC_Decrypt(uint8_t *data, uint32_t len); /* ==================== HMAC-SHA256 (Software) ==================== */ /** * @brief Compute HMAC-SHA256 * * @param key HMAC key * @param key_len Key length in bytes * @param data Input data * @param data_len Data length * @param mac Output buffer (32 bytes) */ void CRYPTO_HMAC_SHA256(const uint8_t *key, uint32_t key_len, const uint8_t *data, uint32_t data_len, uint8_t *mac); /** * @brief Verify HMAC-SHA256 tag (constant-time comparison) * * @param key HMAC key * @param key_len Key length * @param data Data that was authenticated * @param data_len Data length * @param tag Expected MAC tag (32 bytes) * @return true if match, false otherwise */ bool CRYPTO_HMAC_Verify(const uint8_t *key, uint32_t key_len, const uint8_t *data, uint32_t data_len, const uint8_t *tag); /* ==================== High-level OTA Helpers ==================== */ /** * @brief OTA firmware packet structure for decryption * * Firmware encrypted format (from PC tool): * +-----------+--------------------+------------+ * | IV (16B) | AES-CBC ciphertext | HMAC (32B) | * +-----------+--------------------+------------+ */ #define OTA_ENC_IV_SIZE 16 #define OTA_ENC_HMAC_SIZE 32 #define OTA_ENC_OVERHEAD (OTA_ENC_IV_SIZE + OTA_ENC_HMAC_SIZE) /** * @brief Decrypt and verify OTA firmware buffer * * Verifies HMAC first (before decryption), then AES-CBC decrypts. * * @param enc_buf Encrypted buffer (IV + ciphertext + HMAC) * @param enc_len Total encrypted data length * @param aes_key AES-128 key (16 bytes) * @param hmac_key HMAC key (32 bytes) * @param out_buf Output buffer for plaintext firmware (must be large enough) * @param out_len Output plaintext length (written by function) * @return true on success, false on HMAC mismatch or decrypt error */ bool CRYPTO_OTA_DecryptFirmware(const uint8_t *enc_buf, uint32_t enc_len, const uint8_t *aes_key, const uint8_t *hmac_key, uint8_t *out_buf, uint32_t *out_len); #endif /* _CRYPTO_H_ */