Cannot communicate with Grow r503 fingerprint sensor after setting password

I am constructing a fingerprint reader device for opening and closing doors. As the sensor and the NodeMCU controlling it will be placed outside, it needs to be tamper resistant. One of the measures is setting the password for the Grow R503 sensor.

I debugged my code first, so I had a working sensor. Then I added the “new_password” to the code, flashed and then changed the clause to “password”. Now I have lost communication to the sensor.

Serial debug log shows:

[09:41:51][E][fingerprint_grow:410]: Unknown response received from reader: 33
[09:41:51][E][fingerprint_grow:317]: Try led_control instead
[09:41:51][E][fingerprint_grow:410]: Unknown response received from reader: 33
[09:41:51][E][fingerprint_grow:317]: Try led_control instead
[09:41:51][E][fingerprint_grow:410]: Unknown response received from reader: 33
[09:41:51][E][fingerprint_grow:317]: Try led_control instead
[09:41:51][E][fingerprint_grow:198]: Wrong password
[09:41:51][E][component:112]: Component fingerprint_grow was marked as failed.
Serial port closed!

I have defined the password in the secrets file like this:
fingerprint_scanner: "0x01234567"

And then in the code for the NodeMCU first:
new_password: !secret fingerprint_scanner

and then
password: !secret fingerprint_scanner

I can see two possible issues with this:

  1. I shouldn’t have added the quotes around the password
  2. Does the secrets mechanism work with these commands

I tried converting the strings !secret, 0x01234567 and "0x01234567" to Hex and used the start of the result as password, but no luck.

Did I break my sensor, any tips anyone?

UPDATE:
I modified the C-source to print the password when checking. The int32 I see in the debug log is the INT value of the HEX value of the value in my secrets file. So something must have gone wrong setting the password. Any ideas? (I debugged before setting the password. At the end of debug I set my logging to WARN, so I didn’t the the actual value set in the logs when setting the password)

Did some debugging in the code to force the setting of the password, it will fail, but at least I get to see what password is set.

The password that is set, is different from the password used for access. And the password changes when I change something random in the Yaml file….

This doesn’t look good. Someone got any advice?

OK, I got it back. Eventually I rolled back to the exact YAML I had when setting the password and changed the source of fingerprint_grow.cpp to and set the password when checking the mail password failed (by adding a ! to the relevant if clause) and changed a log message to output on WARN.

This gave me yet a new password (probably a pointer address instead of the password), which I then tried. To my joy this did work. I guess I should make a bug report out of this.

EDIT:
See Setting the password for a Grow fingerprint sensor bricks the sensor · Issue #3387 · esphome/issues · GitHub for the bug report.

can you please explain what to I need to do for making the device back again?

IF YOU DO THIS THE WRONG WAY YOU’LL BLOWUP YOUR HA INSTALLATION

Go back to the exact same config you had for the fingerprint reader when changing the password.

Get fingerprint_grow.cpp from the source

Change line 53 like below and
if (this->check_password_()) {
to
if (!this->check_password_()) {

and line 205 in like
ESP_LOGI(TAG, "Setting new password: %d", *this->new_password_);
to
ESP_LOGE(TAG, "Setting new password: %d", *this->new_password_);
and save the file.

Then ssh into your box (safe mode off, to login directly to the hypervisor). Open a shell in the ESPHome docker container, like this:

➜  ~ docker ps | grep esp
001122aabbcc   ghcr.io/esphome/esphome-hassio-aarch64:2022.6.2             "/init"               8 days ago     Up 8 days                                                                   addon_5c53de3b_esphome
➜  ~ docker exec -it 001122aabbcc /bin/bash
root@5c53de3b-esphome:/#

Find the fingerprint_grow.cpp file and move it to a safe place

root@5c53de3b-esphome:/# cd /esphome/esphome/components/fingerprint_grow/
root@5c53de3b-esphome:/esphome/esphome/components/fingerprint_grow# ls
__init__.py  __pycache__  binary_sensor.py  fingerprint_grow.cpp  fingerprint_grow.h  sensor.py
root@5c53de3b-esphome:/esphome/esphome/components/fingerprint_grow# mv fingerprint_grow.cpp fingerprint_grow.cpp.save

Now copy the modified fingerprint_grow.cpp into the clipboard.

On your HA box in the ESP container do:
root@5c53de3b-esphome:/esphome/esphome/components/fingerprint_grow# cat - > fingerprint_grow.cpp

paste your contents and press ^C (ctrl-c)

Now you should have a modified sourcecode file.

Clean your build environment and reflash the ESP. On reboot of the ESP the password should be in the logs/console.

Once you have the password change the source back and exit the container:

oot@5c53de3b-esphome:/esphome/esphome/components/fingerprint_grow# mv fingerprint_grow.cpp.save fingerprint_grow.cpp
root@5c53de3b-esphome:/esphome/esphome/components/fingerprint_grow# exit

and exit SSH. Clean your build environment again, set the correct password in the config (do not set it again), and use the sensor.

First of all Thank you for all this work !!!
but unfortunately the password is still wrong :-
tried a lot of times
new_password 0x2B5DE3DE give me 1073691004

try 0x3FFF397C (which is the hex representation of your decimal password)

Comparing it to my own password; this is only slightly different from mine! Definitely something tricky going on here.

I brute forced my way in like so:
yaml:

external_components:
  - source:
      type: local
      path: my_components
    components:
      - fingerprint_grow

my_components/fingerprint_grow/fingerprint_grow.cpp

bool FingerprintGrowComponent::check_password_() {
  uint32_t uidx;
  uint8_t res=PASSWORD_FAIL;
  ESP_LOGD(TAG, "Checking password");
  for(uidx=0x3FFF0000; uidx<0xFFFFFFFF && res!=OK; uidx++) {
    ESP_LOGE(TAG, "Checking password: %d", uidx);
    this->password_=uidx;
    this->data_ = {VERIFY_PASSWORD, (uint8_t)(this->password_ >> 24), (uint8_t)(this->password_ >> 16),
                 (uint8_t)(this->password_ >> 8), (uint8_t)(this->password_ & 0xFF)};
    res=this->send_command_();
  }
  switch (res) {
    case OK:
      ESP_LOGD(TAG, "Password verified");
      return true;
    case PASSWORD_FAIL:
      ESP_LOGE(TAG, "Wrong password");
      break;
  }
  return false;
}

worked like a charm

2 Likes

Thanks , it took only 5 minutes to crack the password :slight_smile:
now the sensor is back again

1 Like

Hey I’m the one who co-wrote the integration. Sorry to nearly brick ur readers :see_no_evil:. My bad, I actually didn’t test the set password function.

@lancer73

I think lines 205 - 207 should be changed from:

  ESP_LOGI(TAG, "Setting new password: %d", *this->new_password_);
  this->data_ = {SET_PASSWORD, (uint8_t)(*this->new_password_ >> 24), (uint8_t)(*this->new_password_ >> 16),
                 (uint8_t)(*this->new_password_ >> 8), (uint8_t)(*this->new_password_ & 0xFF)};

to:

ESP_LOGI(TAG, "Setting new password: %d", this->new_password_);
 this->data_ = {SET_PASSWORD, (uint8_t)(this->new_password_ >> 24), (uint8_t)(this->new_password_ >> 16),
                (uint8_t)(this->new_password_ >> 8), (uint8_t)(this->new_password_ & 0xFF)};

What the code is doing is changing the password to the memore address where the password is stored. (Forgive me if I’m wrong, but it has been 20 years since I did something serious in C)

new_password_ is declared as a pointer variable, we need to dereference it with * to get the value.

The error is actually in fingerprint_grow.h:

void set_new_password(uint32_t new_password) { this->new_password_ = &new_password; }`

We can’t set the new_password_ pointer to the address of the new_password parameter, as it gets deallocated when the set_new_password() function returns. Learnt something new :joy:

The pr#3722 fix is not ideal as it prevents setting of new_password = 0xFFFFFFFF. I’ll come up with a proper fix soon. And I’ll be sure to test it this time.

1 Like

Thnx! And maybe also change the loglevel for the password change feedback. It is at informational level only and you certainly don’t want to miss the feedback from the call, so maybe elevate the loglevel of the change to “warning”.

(and when you set a password to 0xFFFFFFFF, punishment is well earned :wink: )

when i try this i get a error in esphome

Could not find init.py file for component fingerprint_grow. Please check the component is defined by this source (search path: /config/esphome/my_components/fingerprint_grow/init.py).