UPDATE: FloatControl 1.8 is live and firmware is available for download: GitHub ZIP file - and instructions on YT: PIN locking
Objective
provide a simple method to prevent accidental writes to the wrong VESC by using a 4-digit PIN to write-lock your firmware. The more VESCs we have out there the more likely it is to happen that someone will change your boards settings (unintentionally or not)
Why not use “pairing”?
How does the proposed feature compare to pairing? Pairing is a tool-side mechanism that isn’t obeyed by 3rd party tools. Additionally pairing is UUID based making it impossible to go from memory if you quickly want to enable a friend’s phone to access your board, e.g. during a large event.
High level behavior
The new firmware will behave just like before by default. Once a PIN gets set by the user, firmware can be locked on boot or locked manually, PIN can only be set or cleared by passing in the prior PIN.
Once the controller is locked only read accesses can be performed until the user unlocks the controller.
Source Code
Submitted a pull request for review purposes only:
Pin lock - RFQ by surfdado · Pull Request #622 · vedderb/bldc (github.com)
Details:
1) PIN
PIN is
- 4 digits (we’re not trying to thwart sophisticated hackers here)
- stored in EEPROM, like odometer
- not written in AppCFG XML
- not written during backup/restore
- lost after firmware upgrade (needs to be set again)
- not lost when loading a new Float Package (loading new packages requires unlocking first)
- may be written via setting, but cannot be read by tools
- when PIN is set to 0, lock is removed
2) Firmware compatibility
I am adding this feature to my custom build of 6.2 (6.2 is in release state and can no longer be officially extended). Sources will be on my vesc_pkg fork on github.
To keep compatibility with 6.2, PIN can only be written/cleared using a custom API aka custom comm commands.
If the community (aka the VESC developer community) accepts this functionality it will become official part of firmware 6.5
If not, then you will have to once again use “surfdado firmware” if you want this feature…
3) Detailed Firmware Behavior
Firmware behavior when PIN==0 (lock removed)
-just as before, nothing changes
Firmware behavior when PIN>0 - but controller isn’t “locked”
- PIN can only be changed or cleared by passing the prior PIN
- PIN can also be cleared by loading new firmware
- everything else behaves the same
- controller can be locked by using the COMM_WRITE_LOCK command and passing a PIN that matches the stored PIN
Firmware behavior when PIN>0 - and controller is “locked”
- any read access is permitted at any time
- any write access is ignored unless the PIN is removed or writing is temporarily enabled
- once writes are temporarily allowed any write access will be honored until write lock is explicitly re-enabled
- resetting / power cycling a VESC with a PIN-lock and “lock_on_boot” set, will always make it boot locked
- USB loophole: write access is always permitted
** rationale: once you have physical access to the VESC you could also connect ST-Link and bypass it all anyways
4) New APIs / Commands:
-
COMM_LOCK_SETPIN (old PIN, new PIN, lock_on_boot): set new 4-digit PIN, provided the old PIN matches the saved one, set or don’t set the lock_on_boot flag
** returns a flag “did_set” to confirm that the PIN got set, also returns the new PIN to confirm that it worked
** Note: setting the pin does not immediately enable the write lock! -
COMM_WRITE_LOCK (PIN, Enable): enables/disables writing (provided passed PIN matches saved PIN)
** this command is ignored if the currently stored PIN is 0 (you cannot write-lock a board that doesn’t have a pin set)
** doesn’t return anything (call LOCK_STATUS to check) -
COMM_LOCK_STATUS: Passes the PIN and returns locking status
** 1) is a writelock currently active?
** 2) does the passed PIN match the stored PIN?
** 3) is the stored PIN == 0?
5) App Support:
Will Float Control support it?
of course it will - see a preview here: VESC Pin Locking - YouTube
the first version (TestFlight users only) will allow
- recognizing boards with firmware that supports locking
- display lock status when connected to such firmware
- allow setting/removing a PIN for their board
** once a PIN is set, it will be remembered so subsequent connects don’t require entering the PIN again - allow unlocking/locking their board
How about Android users?
we need a volunteer to add lock/unlock buttons to the Float Package App UI (for 6.2) - starting with version 6.5 the Vesc App will hopefully have this feature built-in
also, I’ve notified the “Floaty” app developer of this, so it might get added there as well
How shall apps perform write operations on a PIN-locked VESC?
a) temporarily enable writes and perform as many writes as desired, then re-enable write lock whenever desired
- pros: practically zero overhead
- cons: multi-BLE devices (e.g. with internal and external BLE) would still allow rogue connections and write accesses via the secondary BLE while unlocked!
b) wrap every single write access in write-enable / write-disable calls
- pros: most secure
- cons: overhead of 2 extra calls for any write-access
How to permanently remove PIN lock?
a) use the SetPin API and set 0 as the new pin (must also pass previous PIN to authenticate)
b) flash firmware via USB or ST-Link
c) in 6.5 we may also add a config setting field (write-only) to set the PIN with - tbd
How shall apps behave to deal with locked firmware?
Apps that do not add support for this feature can still connect to VESCs with locked firmware, but any command that changes the configuration of the VESC will fail. This is how the 6.2 VESC Tool/App will behave.It may even fail to load the float config / app ui, this is tbd.
Apps that want to support firmware with locking capability must follow these guidelines:
- when connecting, use the new COMM_LOCK_STATUS API to determine if a firmware is locked.
- apps must let the user enter a PIN number to unlock a board. It is up to the app to decide whether to cache the PIN or not so subsequent connects don’t require user action
- apps can now send this pin to the firmware to unlock the firmware as needed/desired
** it is up to the app to decide what kind of “security” to offer and whether to leave the board unlocked till power cycled - optional:
** apps can let the user manually lock/unlock the board
** apps can let the user set or change the PIN
What happens if I forget my PIN?
A PIN only makes sense if it’s not trivial to bypass it. Also, it’s only 4 digits - so don’t forget it!
Recovery via USB? Once the VESC Tool has support for this feature it will be possible to set a new PIN without specifying the old pin, as long as you’re connected via USB.
Recovery by mobile app? Impossible, remote connections will always require the old PIN to set a new PIN. But your mobile app should remember your PIN for you anyways.
What if the VESC Tool doesn’t yet support this feature (during beta testing) and I forgot my PIN?
Maybe you shouldn’t be a beta tester… but I will have a custom version of the VESC Tool available that will be able to do this. But you still will need USB access!!!