diff --git a/doc/Doxyfile b/doc/Doxyfile index 07cafe22..6c6e448d 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1536,7 +1536,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = CRYPTO_DOC # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/libraries/Crypto/AES.h b/libraries/Crypto/AES.h index 22b8ae4f..63adc6df 100644 --- a/libraries/Crypto/AES.h +++ b/libraries/Crypto/AES.h @@ -25,6 +25,15 @@ #include "BlockCipher.h" +// Determine which AES implementation to export to applications. +#if defined(ESP32) +#define CRYPTO_AES_ESP32 1 +#else +#define CRYPTO_AES_DEFAULT 1 +#endif + +#if defined(CRYPTO_AES_DEFAULT) || defined(CRYPTO_DOC) + class AESTiny128; class AESTiny256; class AESSmall128; @@ -177,4 +186,71 @@ private: uint8_t reverse[16]; }; +#endif // CRYPTO_AES_DEFAULT + +#if defined(CRYPTO_AES_ESP32) + +// "hwcrypto/aes.h" includes "rom/aes.h" which defines global enums for +// AES128, AES192, and AES256. The enum definitions interfere with the +// definition of the same-named classes below. The #define's and #undef's +// here work around the problem by defining the enums to different names. +#define AES128 AES128_enum +#define AES192 AES192_enum +#define AES256 AES256_enum +#include "hwcrypto/aes.h" +#undef AES128 +#undef AES192 +#undef AES256 + +class AESCommon : public BlockCipher +{ +public: + virtual ~AESCommon(); + + size_t blockSize() const; + size_t keySize() const; + + bool setKey(const uint8_t *key, size_t len); + + void encryptBlock(uint8_t *output, const uint8_t *input); + void decryptBlock(uint8_t *output, const uint8_t *input); + + void clear(); + +protected: + AESCommon(uint8_t keySize); + +private: + esp_aes_context ctx; +}; + +class AES128 : public AESCommon +{ +public: + AES128() : AESCommon(16) {} + virtual ~AES128(); +}; + +class AES192 : public AESCommon +{ +public: + AES192() : AESCommon(24) {} + virtual ~AES192(); +}; + +class AES256 : public AESCommon +{ +public: + AES256() : AESCommon(32) {} + virtual ~AES256(); +}; + +// The ESP32 AES context is so small that it already qualifies as "tiny". +typedef AES128 AESTiny128; +typedef AES256 AESTiny256; +typedef AES128 AESSmall128; +typedef AES256 AESSmall256; + +#endif // CRYPTO_AES_ESP32 + #endif diff --git a/libraries/Crypto/AES128.cpp b/libraries/Crypto/AES128.cpp index aaf23396..533e1936 100644 --- a/libraries/Crypto/AES128.cpp +++ b/libraries/Crypto/AES128.cpp @@ -24,6 +24,8 @@ #include "Crypto.h" #include +#if defined(CRYPTO_AES_DEFAULT) || defined(CRYPTO_DOC) + /** * \class AES128 AES.h * \brief AES block cipher with 128-bit keys. @@ -350,3 +352,5 @@ void AESSmall128::clear() clean(reverse); AESTiny128::clear(); } + +#endif // CRYPTO_AES_DEFAULT diff --git a/libraries/Crypto/AES192.cpp b/libraries/Crypto/AES192.cpp index 7c1d0a48..57055d31 100644 --- a/libraries/Crypto/AES192.cpp +++ b/libraries/Crypto/AES192.cpp @@ -24,6 +24,8 @@ #include "Crypto.h" #include +#if defined(CRYPTO_AES_DEFAULT) || defined(CRYPTO_DOC) + /** * \class AES192 AES.h * \brief AES block cipher with 192-bit keys. @@ -96,3 +98,5 @@ bool AES192::setKey(const uint8_t *key, size_t len) return true; } + +#endif // CRYPTO_AES_DEFAULT diff --git a/libraries/Crypto/AES256.cpp b/libraries/Crypto/AES256.cpp index a7975ae3..1540d8f9 100644 --- a/libraries/Crypto/AES256.cpp +++ b/libraries/Crypto/AES256.cpp @@ -24,6 +24,8 @@ #include "Crypto.h" #include +#if defined(CRYPTO_AES_DEFAULT) || defined(CRYPTO_DOC) + /** * \class AES256 AES.h * \brief AES block cipher with 256-bit keys. @@ -395,3 +397,5 @@ void AESSmall256::clear() clean(reverse); AESTiny256::clear(); } + +#endif // CRYPTO_AES_DEFAULT diff --git a/libraries/Crypto/AESCommon.cpp b/libraries/Crypto/AESCommon.cpp index 3f7af201..aee6d32f 100644 --- a/libraries/Crypto/AESCommon.cpp +++ b/libraries/Crypto/AESCommon.cpp @@ -24,6 +24,8 @@ #include "Crypto.h" #include "utility/ProgMemUtil.h" +#if defined(CRYPTO_AES_DEFAULT) || defined(CRYPTO_DOC) + /** * \class AESCommon AES.h * \brief Abstract base class for AES block ciphers. @@ -357,3 +359,5 @@ void AESCommon::applySbox(uint8_t *output, const uint8_t *input) } /** @endcond */ + +#endif // CRYPTO_AES_DEFAULT diff --git a/libraries/Crypto/AESEsp32.cpp b/libraries/Crypto/AESEsp32.cpp new file mode 100644 index 00000000..72a86469 --- /dev/null +++ b/libraries/Crypto/AESEsp32.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2018 Southern Storm Software, Pty Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "AES.h" +#include "Crypto.h" +#include + +// AES implementation for ESP32 using the hardware crypto module. + +#if defined(CRYPTO_AES_ESP32) + +AESCommon::AESCommon(uint8_t keySize) +{ + ctx.key_bytes = keySize; +} + +AESCommon::~AESCommon() +{ + clean(ctx.key, sizeof(ctx.key)); +} + +size_t AESCommon::blockSize() const +{ + return 16; +} + +size_t AESCommon::keySize() const +{ + return ctx.key_bytes; +} + +bool AESCommon::setKey(const uint8_t *key, size_t len) +{ + if (len == ctx.key_bytes) { + // Do the effect of esp_aes_setkey() which is just a memcpy(). + memcpy(ctx.key, key, len); + return true; + } + return false; +} + +void AESCommon::encryptBlock(uint8_t *output, const uint8_t *input) +{ + esp_aes_encrypt(&ctx, input, output); +} + +void AESCommon::decryptBlock(uint8_t *output, const uint8_t *input) +{ + esp_aes_decrypt(&ctx, input, output); +} + +void AESCommon::clear() +{ + clean(ctx.key, sizeof(ctx.key)); +} + +AES128::~AES128() +{ +} + +AES192::~AES192() +{ +} + +AES256::~AES256() +{ +} + +#endif // CRYPTO_AES_ESP32 diff --git a/libraries/Crypto/library.json b/libraries/Crypto/library.json index 916a75e7..97966085 100644 --- a/libraries/Crypto/library.json +++ b/libraries/Crypto/library.json @@ -1,6 +1,6 @@ { "name": "Crypto", - "version": "0.1.4", + "version": "0.1.5", "keywords": "AES128,AES192,AES256,Speck,CTR,CFB,CBC,OFB,EAX,GCM,XTS,ChaCha,ChaChaPoly,EAX,GCM,SHA256,SHA512,SHA3_256,SHA3_512,BLAKE2s,BLAKE2b,SHAKE128,SHAKE256,Poly1305,GHASH,OMAC,Curve25519,Ed25519,P521,RNG,NOISE", "description": "Arduino CryptoLibs - All cryptographic algorithms have been optimized for 8-bit Arduino platforms like the Uno", "authors":