joeycastillo / Sensor-Watch

A board replacement for the classic Casio F-91W wristwatch
Other
1.17k stars 233 forks source link

Totp LFS face fails with certain codes and messes up the file system on physical watch #392

Closed madhogs closed 2 months ago

madhogs commented 5 months ago

I was trying out the totp lfs face with the same codes as I use on the normal totp face but it not only fails with a watch reset but seems to cause some kind of filesystem breakage when it does. Steps to recreate:

  1. Flash board with current main branch, with addition of totp_face_lfs.
  2. Open a serial connection (I used minicom) and run the following (these are example codes with the same format as my real ones):
    echo otpauth://totp/Aaaaaaa?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBAA&period=30&digits=6&issuer=AA&algorithm=SHA1 > totp_uris.txt
    echo otpauth://totp/Bbbbb?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PBB&period=30&digits=6&issuer=BB&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Ccccccc?secret=JBSWY3DPEHPK3PCC&period=30&digits=6&issuer=CC&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Ddddddd?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PDD&period=30&digits=6&issuer=DD&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Eeeeeeeeeeeeeee?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBSWY3DPEE&period=30&digits=6&issuer=EE&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Fffffffffffff?secret=JBSWY3DPEHPK3PXPJBSWY3DPFF&period=30&digits=6&issuer=FF&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Gggggggggggg?secret=JBSWY3DPEHPK3PGG&period=30&digits=6&issuer=GG&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Hhhhhhhhhhhh?secret=JBSWY3DPEHPK3PHH&period=30&digits=6&issuer=HH&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Iiiiiiiiiiiiii?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PII&period=30&digits=6&issuer=II&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Jjjjjjjjjj?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PJJ&period=30&digits=6&issuer=JJ&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Kkkkkkkkkkkk?secret=JBSWY3DPEHPK3PXPJBSWY3DPKK&period=30&digits=6&issuer=KK&algorithm=SHA1 >> totp_uris.txt
    echo otpauth://totp/Llllll?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PLL&period=30&digits=6&issuer=LL&algorithm=SHA1 >> totp_uris.txt
  3. The above should have succeeded and you can see the above in the totp_uris.txt file.
  4. Boot the physical watch and navigate to the totp lfs face.
  5. When scrolling through the codes, it will loop after 4 (only AA <-> DD) in the above.
  6. Navigating away from the lfs face now by pushing the mode button causes a hard reset of the watch.
  7. If you now connect the board again to the computer via the usb port it will continuously flash red and the filesystem cannot be accessed (double clicking the button still works to flash it fortunately).

To fix the watch again after following the above I had to modify filesystem_init in filesystem.c to format the lfs storage on boot.

The above is all on the RED board.

Also just to clarify this is an issue on the totp_face_lfs only, the regular totp_face works fine with no issues.

matheusmoreira commented 5 months ago

I assume you are running bash. Please double check whether your TOTP input files are correct. The code you posted does not do what you think it does. The & is a command separator that runs the previous command in a subprocess.

This:

echo otpauth://totp/Aaaaaaa?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBAA&period=30&digits=6&issuer=AA&algorithm=SHA1

Will really execute this:

echo otpauth://totp/Aaaaaaa?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBAA &
period=30 &
digits=6 &
issuer=AA &
algorithm=SHA1

So it could be that your file contains only this line:

otpauth://totp/Aaaaaaa?secret=JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXPJBAA

I don't quite remember if the TOTP LFS parser can handle that format with missing parameters.

wryun commented 5 months ago

My guess is that the lfs face behaved poorly when it ran out of memory and that the littlefs code did as well, though I'm currently using totp_lfs with 10 or so codes and haven't noticed any issues. Sorry about this! Didn't realise how tight it was when I wrote it like that.

You can check @matheusmoreira's theory by using cat.

I'll probably rewrite it to reparse the lines each time to avoid any memory issues.

madhogs commented 5 months ago

@matheusmoreira The environment in the serial connection does not interpret the & symbol. I have double checked with quotes too but it makes no difference, the totp_uris.txt file looks correct, see below image. image

@wryun I think that makese sense, I have a feeling this is a bug in both the lfs face (probably running out of memory as you suggested) and the filesystem code (failures seem to break it completely and it has to be reformatted).

matheusmoreira commented 5 months ago

The environment in the serial connection does not interpret the & symbol.

I see, I assumed that was being run on a normal Linux command line. It makes sense now, thank you for confirming.

My guess is that the lfs face behaved poorly when it ran out of memory

Probably... The regular TOTP face also ran into out of memory issues when I refactored it, and I used dynamic memory allocation because I read the LFS face code and thought it was alright. Fixed it by keeping most of the encoded data in static memory and only decoding the current TOTP code to RAM.