mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Add HMAC-MD5 support for authenticating OTA updates (#7200)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		| @@ -169,6 +169,7 @@ esphome/components/he60r/* @clydebarrow | |||||||
| esphome/components/heatpumpir/* @rob-deutsch | esphome/components/heatpumpir/* @rob-deutsch | ||||||
| esphome/components/hitachi_ac424/* @sourabhjaiswal | esphome/components/hitachi_ac424/* @sourabhjaiswal | ||||||
| esphome/components/hm3301/* @freekode | esphome/components/hm3301/* @freekode | ||||||
|  | esphome/components/hmac_md5/* @dwmw2 | ||||||
| esphome/components/homeassistant/* @OttoWinter @esphome/core | esphome/components/homeassistant/* @OttoWinter @esphome/core | ||||||
| esphome/components/homeassistant/number/* @landonr | esphome/components/homeassistant/number/* @landonr | ||||||
| esphome/components/homeassistant/switch/* @Links2004 | esphome/components/homeassistant/switch/* @Links2004 | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								esphome/components/hmac_md5/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								esphome/components/hmac_md5/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | AUTO_LOAD = ["md5"] | ||||||
|  | CODEOWNERS = ["@dwmw2"] | ||||||
							
								
								
									
										56
									
								
								esphome/components/hmac_md5/hmac_md5.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								esphome/components/hmac_md5/hmac_md5.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | #include <cstdio> | ||||||
|  | #include <cstring> | ||||||
|  | #include "hmac_md5.h" | ||||||
|  | #include "esphome/core/helpers.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace hmac_md5 { | ||||||
|  | void HmacMD5::init(const uint8_t *key, size_t len) { | ||||||
|  |   uint8_t ipad[64], opad[64]; | ||||||
|  |  | ||||||
|  |   memset(ipad, 0, sizeof(ipad)); | ||||||
|  |   if (len > 64) { | ||||||
|  |     md5::MD5Digest keymd5; | ||||||
|  |     keymd5.init(); | ||||||
|  |     keymd5.add(key, len); | ||||||
|  |     keymd5.calculate(); | ||||||
|  |     keymd5.get_bytes(ipad); | ||||||
|  |   } else { | ||||||
|  |     memcpy(ipad, key, len); | ||||||
|  |   } | ||||||
|  |   memcpy(opad, ipad, sizeof(opad)); | ||||||
|  |  | ||||||
|  |   for (int i = 0; i < 64; i++) { | ||||||
|  |     ipad[i] ^= 0x36; | ||||||
|  |     opad[i] ^= 0x5c; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   this->ihash_.init(); | ||||||
|  |   this->ihash_.add(ipad, sizeof(ipad)); | ||||||
|  |  | ||||||
|  |   this->ohash_.init(); | ||||||
|  |   this->ohash_.add(opad, sizeof(opad)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HmacMD5::add(const uint8_t *data, size_t len) { this->ihash_.add(data, len); } | ||||||
|  |  | ||||||
|  | void HmacMD5::calculate() { | ||||||
|  |   uint8_t ibytes[16]; | ||||||
|  |  | ||||||
|  |   this->ihash_.calculate(); | ||||||
|  |   this->ihash_.get_bytes(ibytes); | ||||||
|  |  | ||||||
|  |   this->ohash_.add(ibytes, sizeof(ibytes)); | ||||||
|  |   this->ohash_.calculate(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HmacMD5::get_bytes(uint8_t *output) { this->ohash_.get_bytes(output); } | ||||||
|  |  | ||||||
|  | void HmacMD5::get_hex(char *output) { this->ohash_.get_hex(output); } | ||||||
|  |  | ||||||
|  | bool HmacMD5::equals_bytes(const uint8_t *expected) { return this->ohash_.equals_bytes(expected); } | ||||||
|  |  | ||||||
|  | bool HmacMD5::equals_hex(const char *expected) { return this->ohash_.equals_hex(expected); } | ||||||
|  |  | ||||||
|  | }  // namespace hmac_md5 | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										48
									
								
								esphome/components/hmac_md5/hmac_md5.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								esphome/components/hmac_md5/hmac_md5.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/defines.h" | ||||||
|  | #include "esphome/components/md5/md5.h" | ||||||
|  |  | ||||||
|  | #include <string> | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace hmac_md5 { | ||||||
|  |  | ||||||
|  | class HmacMD5 { | ||||||
|  |  public: | ||||||
|  |   HmacMD5() = default; | ||||||
|  |   ~HmacMD5() = default; | ||||||
|  |  | ||||||
|  |   /// Initialize a new MD5 digest computation. | ||||||
|  |   void init(const uint8_t *key, size_t len); | ||||||
|  |   void init(const char *key, size_t len) { this->init((const uint8_t *) key, len); } | ||||||
|  |   void init(const std::string &key) { this->init(key.c_str(), key.length()); } | ||||||
|  |  | ||||||
|  |   /// Add bytes of data for the digest. | ||||||
|  |   void add(const uint8_t *data, size_t len); | ||||||
|  |   void add(const char *data, size_t len) { this->add((const uint8_t *) data, len); } | ||||||
|  |  | ||||||
|  |   /// Compute the digest, based on the provided data. | ||||||
|  |   void calculate(); | ||||||
|  |  | ||||||
|  |   /// Retrieve the HMAC-MD5 digest as bytes. | ||||||
|  |   /// The output must be able to hold 16 bytes or more. | ||||||
|  |   void get_bytes(uint8_t *output); | ||||||
|  |  | ||||||
|  |   /// Retrieve the HMAC-MD5 digest as hex characters. | ||||||
|  |   /// The output must be able to hold 32 bytes or more. | ||||||
|  |   void get_hex(char *output); | ||||||
|  |  | ||||||
|  |   /// Compare the digest against a provided byte-encoded digest (16 bytes). | ||||||
|  |   bool equals_bytes(const uint8_t *expected); | ||||||
|  |  | ||||||
|  |   /// Compare the digest against a provided hex-encoded digest (32 bytes). | ||||||
|  |   bool equals_hex(const char *expected); | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   md5::MD5Digest ihash_; | ||||||
|  |   md5::MD5Digest ohash_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace hmac_md5 | ||||||
|  | }  // namespace esphome | ||||||
		Reference in New Issue
	
	Block a user