diff --git a/cores/esp8266/Crypto.cpp b/cores/esp8266/Crypto.cpp index b2b40b3c06..e51a29b8b9 100644 --- a/cores/esp8266/Crypto.cpp +++ b/cores/esp8266/Crypto.cpp @@ -29,7 +29,7 @@ #include -namespace TypeCast = esp8266::TypeConversion; +namespace TypeCast = experimental::TypeConversion; namespace { diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index f385220eed..1127eef80e 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -542,7 +542,7 @@ uint8_t *EspClass::random(uint8_t *resultArray, const size_t outputSizeBytes) co * It should be noted that the ESP8266 has no Bluetooth functionality, so turning the WiFi off is likely to cause RANDOM_REG32 to use pseudo-random numbers. * * It is possible that yield() must be called on the ESP8266 to properly feed the hardware random number generator new bits, since there is only one processor core available. - * However, no feeding requirements are mentioned in the ESP32 documentation, and using yield() could possibly cause extended delays during nonce generation. + * However, no feeding requirements are mentioned in the ESP32 documentation, and using yield() could possibly cause extended delays during number generation. * Thus only delayMicroseconds() is used below. */ diff --git a/cores/esp8266/TypeConversion.cpp b/cores/esp8266/TypeConversion.cpp index 61a47858d4..371dee8baf 100644 --- a/cores/esp8266/TypeConversion.cpp +++ b/cores/esp8266/TypeConversion.cpp @@ -26,7 +26,7 @@ #include #include "TypeConversion.h" -namespace esp8266 +namespace experimental { namespace TypeConversion { diff --git a/cores/esp8266/TypeConversion.h b/cores/esp8266/TypeConversion.h index 6360eb9cbc..522170eff9 100644 --- a/cores/esp8266/TypeConversion.h +++ b/cores/esp8266/TypeConversion.h @@ -28,7 +28,7 @@ #include -namespace esp8266 +namespace experimental { namespace TypeConversion { diff --git a/doc/libraries.rst b/doc/libraries.rst index d99dfe71f0..fc44d46f5a 100644 --- a/doc/libraries.rst +++ b/doc/libraries.rst @@ -113,6 +113,8 @@ Some ESP-specific APIs related to deep sleep, RTC and flash memories are availab ``ESP.getCycleCount()`` returns the cpu instruction cycle count since start as an unsigned 32-bit. This is useful for accurate timing of very short actions like bit banging. +``ESP.random()`` should be used to generate true random numbers on the ESP. Returns an unsigned 32-bit integer with the random number. An alternate version is also available that fills an array of arbitrary length. Note that it seems as though the WiFi needs to be enabled to generate entropy for the random numbers, otherwise pseudo-random numbers are used. + ``ESP.checkFlashCRC()`` calculates the CRC of the program memory (not including any filesystems) and compares it to the one embedded in the image. If this call returns ``false`` then the flash has been corrupted. At that point, you may want to consider trying to send a MQTT message, to start a re-download of the application, blink a LED in an `SOS` pattern, etc. However, since the flash is known corrupted at this point there is no guarantee the app will be able to perform any of these operations, so in safety critical deployments an immediate shutdown to a fail-safe mode may be indicated. ``ESP.getVcc()`` may be used to measure supply voltage. ESP needs to reconfigure the ADC at startup in order for this feature to be available. Add the following line to the top of your sketch to use ``getVcc``: diff --git a/libraries/esp8266/examples/HelloCrypto/HelloCrypto.ino b/libraries/esp8266/examples/HelloCrypto/HelloCrypto.ino index e6c4c493ab..1fb90134c2 100644 --- a/libraries/esp8266/examples/HelloCrypto/HelloCrypto.ino +++ b/libraries/esp8266/examples/HelloCrypto/HelloCrypto.ino @@ -8,8 +8,7 @@ #include #include -namespace TypeCast = esp8266::TypeConversion; -using namespace experimental; +namespace TypeCast = experimental::TypeConversion; /** NOTE: Although we could define the strings below as normal String variables, @@ -38,34 +37,36 @@ void setup() { void loop() { // This serves only to demonstrate the library use. See the header file for a full list of functions. + using namespace experimental::crypto; + String exampleData = F("Hello Crypto World!"); Serial.println(String(F("This is our example data: ")) + exampleData); - uint8_t resultArray[crypto::SHA256::NATURAL_LENGTH] { 0 }; - uint8_t derivedKey[crypto::ENCRYPTION_KEY_LENGTH] { 0 }; + uint8_t resultArray[SHA256::NATURAL_LENGTH] { 0 }; + uint8_t derivedKey[ENCRYPTION_KEY_LENGTH] { 0 }; static uint32_t encryptionCounter = 0; // Generate the salt to use for HKDF uint8_t hkdfSalt[16] { 0 }; - crypto::getNonceGenerator()(hkdfSalt, sizeof hkdfSalt); + getNonceGenerator()(hkdfSalt, sizeof hkdfSalt); // Generate the key to use for HMAC and encryption - crypto::HKDF hkdfInstance(FPSTR(masterKey), (sizeof masterKey) - 1, hkdfSalt, sizeof hkdfSalt); // (sizeof masterKey) - 1 removes the terminating null value of the c-string + HKDF hkdfInstance(FPSTR(masterKey), (sizeof masterKey) - 1, hkdfSalt, sizeof hkdfSalt); // (sizeof masterKey) - 1 removes the terminating null value of the c-string hkdfInstance.produce(derivedKey, sizeof derivedKey); // Hash - crypto::SHA256::hash(exampleData.c_str(), exampleData.length(), resultArray); + SHA256::hash(exampleData.c_str(), exampleData.length(), resultArray); Serial.println(String(F("\nThis is the SHA256 hash of our example data, in HEX format:\n")) + TypeCast::uint8ArrayToHexString(resultArray, sizeof resultArray)); - Serial.println(String(F("This is the SHA256 hash of our example data, in HEX format, using String output:\n")) + crypto::SHA256::hash(exampleData)); + Serial.println(String(F("This is the SHA256 hash of our example data, in HEX format, using String output:\n")) + SHA256::hash(exampleData)); // HMAC // Note that HMAC output length is limited - crypto::SHA256::hmac(exampleData.c_str(), exampleData.length(), derivedKey, sizeof derivedKey, resultArray, sizeof resultArray); + SHA256::hmac(exampleData.c_str(), exampleData.length(), derivedKey, sizeof derivedKey, resultArray, sizeof resultArray); Serial.println(String(F("\nThis is the SHA256 HMAC of our example data, in HEX format:\n")) + TypeCast::uint8ArrayToHexString(resultArray, sizeof resultArray)); - Serial.println(String(F("This is the SHA256 HMAC of our example data, in HEX format, using String output:\n")) + crypto::SHA256::hmac(exampleData, derivedKey, sizeof derivedKey, crypto::SHA256::NATURAL_LENGTH)); + Serial.println(String(F("This is the SHA256 HMAC of our example data, in HEX format, using String output:\n")) + SHA256::hmac(exampleData, derivedKey, sizeof derivedKey, SHA256::NATURAL_LENGTH)); // Authenticated Encryption with Associated Data (AEAD) @@ -76,10 +77,10 @@ void loop() { Serial.println(String(F("\nThis is the data to encrypt: ")) + dataToEncrypt); // Note that the key must be ENCRYPTION_KEY_LENGTH long. - crypto::ChaCha20Poly1305::encrypt(dataToEncrypt.begin(), dataToEncrypt.length(), derivedKey, &encryptionCounter, sizeof encryptionCounter, resultingNonce, resultingTag); + ChaCha20Poly1305::encrypt(dataToEncrypt.begin(), dataToEncrypt.length(), derivedKey, &encryptionCounter, sizeof encryptionCounter, resultingNonce, resultingTag); Serial.println(String(F("Encrypted data: ")) + dataToEncrypt); - bool decryptionSucceeded = crypto::ChaCha20Poly1305::decrypt(dataToEncrypt.begin(), dataToEncrypt.length(), derivedKey, &encryptionCounter, sizeof encryptionCounter, resultingNonce, resultingTag); + bool decryptionSucceeded = ChaCha20Poly1305::decrypt(dataToEncrypt.begin(), dataToEncrypt.length(), derivedKey, &encryptionCounter, sizeof encryptionCounter, resultingNonce, resultingTag); encryptionCounter++; if (decryptionSucceeded) { diff --git a/libraries/esp8266/keywords.txt b/libraries/esp8266/keywords.txt index 6d4587bb82..7026966465 100644 --- a/libraries/esp8266/keywords.txt +++ b/libraries/esp8266/keywords.txt @@ -12,7 +12,6 @@ ESP KEYWORD1 -crypto KEYWORD1 nonceGeneratorType KEYWORD1 MD5 KEYWORD1 SHA1 KEYWORD1