Skip to content

Firmware : Adding Authentication gateway library to the mqtt messages (Closes #371)#413

Open
Yhya99 wants to merge 12 commits intomainfrom
Feature/371-firmware-no-authentication-for-the-broker
Open

Firmware : Adding Authentication gateway library to the mqtt messages (Closes #371)#413
Yhya99 wants to merge 12 commits intomainfrom
Feature/371-firmware-no-authentication-for-the-broker

Conversation

@Yhya99
Copy link
Collaborator

@Yhya99 Yhya99 commented Mar 22, 2026

Links

What & Why

-what it do is checking if the device sending message to krake is authenticated by the user or not by checking a preshard password of the device to the Krake using a webpage dashboard.

-why we doing this, to be able to control which device can publish Alarms to Krake and we can have some informations about the device eg(what is this device type, that it's status , and permissions, ...).

Validation / How to Verify

there's two steps to Verify:

  • first step : Run the demo project at the directory Firmware/AUTH_MQTT/MQTT_Gateway
  • Second step :test the gateway with GPAD API in the Krake (not yet ready)

Checklist

  • Only related changes
  • Folder structure respected, Firmware/AUTH_MQTT/MQTT_Gateway;
  • Validation steps written for Demo
  • Validation steps written for integrated Gateway in GPAD API

@Yhya99 Yhya99 linked an issue Mar 22, 2026 that may be closed by this pull request
@Yhya99 Yhya99 self-assigned this Mar 22, 2026

Device* getDevice(const String& id);
const std::map<String, Device>& getAllDevices() const { return m_devices.devices; }
void approveDevice(const String& id, const DevicePerms& perms, const char* psk = nullptr);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of these String uses, can they be converted over to std::array<char, size_t>? By requiring Strings that requires dynamic allocation. Unless necessary it's best we don't use dynamic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

most of strings used for id which is a key at the map for saving devices.
i use it here
std::map<String, Device> devices;

}

size_t cipherLen = len + RFC_8439_TAG_SIZE;
uint8_t* cipher = (uint8_t*)malloc(cipherLen);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not use malloc. That will 100% cause memory fragmentation due to dynamic memory allocation and no MMU.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, malloc is not safe to use i will try to use a fixed size buffer for the cipher
the esp32 have embedded MMU but cannot prevent from memory Fragmentation.

size_t encLen = chacha20_poly1305_encrypt(cipher, dev.enc_key, nonce,
(uint8_t*)deviceId.c_str(), deviceId.length(),
plaintext, len);
if (encLen == (size_t)-1) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a large number number of casts in this PR. Would you be able to leverage std::static_cast()?

As well, size_ts cannot be negative since they are unsigned values. What does casting -1 to a size_t accomplish?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the -1 with casting size_t it to return the maximum size of size_t type

at the library the return of the function chacha20_poly1305_encrypt
can be (size_t)-1 at failure MG_OVERLAPPING



// pointers overlap if the smaller either ahead of the end,
// or its end is before the start of the other
//
// s_size should be smaller or equal to b_size
#define MG_OVERLAPPING(s, s_size, b, b_size) \
  (MG_PM(s) < MG_PM((b) + (b_size))) && (MG_PM(b) < MG_PM((s) + (s_size)))

PORTABLE_8439_DECL size_t mg_chacha20_poly1305_encrypt(
    uint8_t *restrict cipher_text, const uint8_t key[RFC_8439_KEY_SIZE],
    const uint8_t nonce[RFC_8439_NONCE_SIZE], const uint8_t *restrict ad,
    size_t ad_size, const uint8_t *restrict plain_text,
    size_t plain_text_size) {
  size_t new_size = plain_text_size + RFC_8439_TAG_SIZE;
  if (MG_OVERLAPPING(plain_text, plain_text_size, cipher_text, new_size)) {
    return (size_t) -1;
  }
  chacha20_xor_stream(cipher_text, plain_text, plain_text_size, key, nonce, 1);
  poly1305_calculate_mac(cipher_text + plain_text_size, cipher_text,
                         plain_text_size, key, nonce, ad, ad_size);
  return new_size;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. That's in the library. I see you added the OVERLAPPING macro, but again, that raises the question of why have you reimplemented a lot of the functionality of the existing library? This adds a TREMENDOUS amount of code to maintain in our own project. Do you have a justification for why you have essentially just duplicated a library?

@TheBakedPotato
Copy link
Collaborator

This PR is 43,000 lines. That is an EXTREMEMLY large PR. This is far too large to be properly reviewed by others. Is there any way this can be broken into smaller PRs?

As well, the file chacha20.h states that file is from an original source. Is there another way you could depend on these files without copying and pasting them into our source code? The two benefits would be if the library has fixes, especially vulnerability fixes since this is a cryptography library, it will not require manual intervention to copy and paste the new file. Secondly it will reduce by a LARGE amount the size of the PR because then you are no longer committing source code that is technically an external library.

One way to accomplish including an external git repo as a dependency is add it as a git submodule.

Lastly, digging through the linked repo in the chacha20.h source file unless I'm mistaken, then functions defined are not identical to the source. Are you able to provide an explanation of WHY you had to change the files and essentially "reimplement" them yourself instead of relying a well established library which has a large amount of testing setup?

@@ -0,0 +1,37 @@
// Standalone ChaCha20-Poly1305 AEAD (RFC 8439)
// Extracted from Mongoose library (Public Domain)
// Original source: https://github.com/cesanta/mongoose
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are going to add in a library yourself and make modifications, please are the version and commit that you are referencing. As well, please state the license the original source is license under, like an example in the project's own source

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, but i wil not going to use the chacha20.h
i am going to use only two files of the library and remove all the extracted files

@Yhya99
Copy link
Collaborator Author

Yhya99 commented Mar 22, 2026

This PR is 43,000 lines. That is an EXTREMEMLY large PR. This is far too large to be properly reviewed by others. Is there any way this can be broken into smaller PRs?

As well, the file chacha20.h states that file is from an original source. Is there another way you could depend on these files without copying and pasting them into our source code? The two benefits would be if the library has fixes, especially vulnerability fixes since this is a cryptography library, it will not require manual intervention to copy and paste the new file. Secondly it will reduce by a LARGE amount the size of the PR because then you are no longer committing source code that is technically an external library.

One way to accomplish including an external git repo as a dependency is add it as a git submodule.

Lastly, digging through the linked repo in the chacha20.h source file unless I'm mistaken, then functions defined are not identical to the source. Are you able to provide an explanation of WHY you had to change the files and essentially "reimplement" them yourself instead of relying a well established library which has a large amount of testing setup?

I was tring to not compile all the file of the mongoose library i was need the encryption and hashing function which need to enable the TLS and compile all the TLS stack in the library.
so i was test the difference of the bin file size by turn off the tls and use needed functions in separated files.
but i found it just reduce the size by around 1kb so i found that most of the size is from the wifi stak of the esp32.
so i am going to use only the mongoose library two files.

using git submodule. is a good point i need to read more about it and how i can do it because i didn't use it before.

chacha20.h yes maybe i did some changes because i was facing some problem when receiving message and decrypt the message i got a bug that's memory access violation and the esp32 was rebooting. but the changes didn't solve it and found the problem with calling free() function. but i didn't turn the changes back because i was going to use the two files from mongoose library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Firmware, No Authentication for the Broker

2 participants