1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-12 01:53:07 +03:00

Add CryptoInterface library (#6961)

* - Add CryptoInterface library.

- Add TypeConversion core files.

* Fix compiler errors.

- Make HelloCrypto.ino stylish.

- Include assert.h in CryptoInterface.cpp.

* - Move base36 arrays to PROGMEM in TypeConversionFunctions.cpp.

- Add deprecated attribute to SHA1 and MD5 hashes.

- Remove _warningsEnabled since this has been replaced by the deprecated attribute.

- Prefix all getters with "get".

- Move all CryptoInterface functionality to the experimental namespace.

- Change formatting of core files.

- Improve comments.

* - Update keywords.txt.

* - Remove WiFi.disconnect() from setup() in HelloCrypto example since it no longer seems to be required.

* - Classify everything.

- Remove delay in setup() from HelloCrypto example since it does not seem to be required to prevent missing initial Serial prints.

- Mark type conversion functions as big endian.

- Update keywords.txt.

* - Remove namespace experimental.

- Create ESP.random functions in the core based on the defaultNonceGenerator code, and use these in defaultNonceGenerator.

- Rename CryptoInterface to esp8266::Crypto and move all functionality to the core.

- Remove need to #include <bearssl/bearssl.h> in the Crypto header file by changing br_hkdf_context to ::br_hkdf_context.

- Restyle code files for core usage.

* - Re-add namespace experimental.

- Improve comments.

* - Remove namespace esp8266.

- Rename namespace Crypto to namespace crypto.

Co-authored-by: Anders <andlo151@student.liu.se>
Co-authored-by: Develo <deveyes@gmail.com>
This commit is contained in:
aerlon
2020-04-29 03:25:10 +02:00
committed by GitHub
parent ec7644227e
commit 3c9a75f831
9 changed files with 1757 additions and 1 deletions

View File

@ -0,0 +1,97 @@
/**
This example demonstrates the usage of the ESP8266 Crypto implementation, which aims to contain easy-to-use cryptographic functions.
Crypto is currently primarily a frontend for the cryptographic library BearSSL which is used by `BearSSL::WiFiClientSecure` and `BearSSL::WiFiServerSecure` in the ESP8266 Arduino Core.
Extensive documentation can be found in the Crypto source code files and on the [BearSSL homepage](https://www.bearssl.org).
*/
#include <ESP8266WiFi.h>
#include <TypeConversion.h>
#include <Crypto.h>
namespace TypeCast = esp8266::TypeConversion;
using namespace experimental;
/**
NOTE: Although we could define the strings below as normal String variables,
here we are using PROGMEM combined with the FPSTR() macro (and also just the F() macro further down in the file).
The reason is that this approach will place the strings in flash memory which will help save RAM during program execution.
Reading strings from flash will be slower than reading them from RAM,
but this will be a negligible difference when printing them to Serial.
More on F(), FPSTR() and PROGMEM:
https://github.com/esp8266/Arduino/issues/1143
https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html
*/
constexpr char masterKey[] PROGMEM = "w86vn@rpfA O+S"; // Use 8 random characters or more
void setup() {
// Prevents the flash memory from being worn out, see: https://github.com/esp8266/Arduino/issues/1054 .
// This will however delay node WiFi start-up by about 700 ms. The delay is 900 ms if we otherwise would have stored the WiFi network we want to connect to.
WiFi.persistent(false);
Serial.begin(115200);
Serial.println();
Serial.println();
}
void loop() {
// This serves only to demonstrate the library use. See the header file for a full list of functions.
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 };
static uint32_t encryptionCounter = 0;
// Generate the salt to use for HKDF
uint8_t hkdfSalt[16] { 0 };
crypto::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
hkdfInstance.produce(derivedKey, sizeof derivedKey);
// Hash
crypto::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));
// HMAC
// Note that HMAC output length is limited
crypto::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));
// Authenticated Encryption with Associated Data (AEAD)
String dataToEncrypt = F("This data is not encrypted.");
uint8_t resultingNonce[12] { 0 }; // The nonce is always 12 bytes
uint8_t resultingTag[16] { 0 }; // The tag is always 16 bytes
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);
Serial.println(String(F("Encrypted data: ")) + dataToEncrypt);
bool decryptionSucceeded = crypto::ChaCha20Poly1305::decrypt(dataToEncrypt.begin(), dataToEncrypt.length(), derivedKey, &encryptionCounter, sizeof encryptionCounter, resultingNonce, resultingTag);
encryptionCounter++;
if (decryptionSucceeded) {
Serial.print(F("Decryption succeeded. Result: "));
} else {
Serial.print(F("Decryption failed. Result: "));
}
Serial.println(dataToEncrypt);
Serial.println(F("\n##########################################################################################################\n"));
delay(10000);
}

View File

@ -12,6 +12,18 @@
ESP KEYWORD1
crypto KEYWORD1
nonceGeneratorType KEYWORD1
MD5 KEYWORD1
SHA1 KEYWORD1
SHA224 KEYWORD1
SHA256 KEYWORD1
SHA384 KEYWORD1
SHA512 KEYWORD1
MD5SHA1 KEYWORD1
HKDF KEYWORD1
ChaCha20Poly1305 KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
@ -60,6 +72,21 @@ getResetInfo KEYWORD2
getResetInfoPtr KEYWORD2
eraseConfig KEYWORD2
getCycleCount KEYWORD2
random->KEYWORD2
setCtMinDataLength KEYWORD2
getCtMinDataLength KEYWORD2
setCtMaxDataLength KEYWORD2
getCtMaxDataLength KEYWORD2
setNonceGenerator KEYWORD2
getNonceGenerator KEYWORD2
hash KEYWORD2
hmac KEYWORD2
hmacCT KEYWORD2
init KEYWORD2
produce KEYWORD2
encrypt KEYWORD2
decrypt KEYWORD2
#######################################
# Constants (LITERAL1)
@ -79,6 +106,10 @@ WAKE_RF_DISABLED LITERAL1
ADC_VCC LITERAL1
ADC_TOUT LITERAL1
NATURAL_LENGTH LITERAL1
ENCRYPTION_KEY_LENGTH LITERAL1
CT_MAX_DIFF LITERAL1
#######################################
# namespace esp8266
#######################################

View File

@ -1,6 +1,6 @@
name=ESP8266
version=1.0
author=Simon Peter,Markus Sattler,Ivan Grokhotkov
author=Anders Löfgren,Simon Peter,Markus Sattler,Ivan Grokhotkov
maintainer=Ivan Grokhtkov <ivan@esp8266.com>
sentence=ESP8266 sketches examples
paragraph=