paper: Secure Autonomous Scripting

Thread created automatically to discuss a document in CD-Media.

Secure Autonomous Scripting
by: brennonbrimhall

We introduce JavaScript-based autonomous scripting for Java teams. The scripts are secured using cryptographic digital signatures.

6844 had an amazing time at the Utah Regional. While we had some mechanical issues (for those who weren’t watching the regional, we had intake failures that caused us to transform our robot into an Everybot-style dumper in about 15 minutes between matches), we also had some solid programming. We detail one of our more cool programming projects - a secure autonomous scripting system that we used in each match without issue.

secure-autonomous-scripting.pdf (318 KB)

I’m curious about your rationale for taking this approach. You use both a hash and a signature. I get the use of the hash – make an easy comparison to make sure you transferred things correctly. But, why the signature? Do you have some suspicion that someone other than you would have loaded code on your robot?

I would recommend reading up on “modern” packaging software such as apt and pacman, as well as “modern” deployment software such as docker. Using both a hash and a signature are very common practice.

Reference documentation
Apt: https://wiki.debian.org/SecureApt
Pacman: https://wiki.archlinux.org/index.php/Pacman/Package_signing
Docker: https://docs.docker.com/engine/security/trust/content_trust/#image-tags-and-content-trust

I agree that having signatures is probably a bit excessive in the context of FRC, but FRC is about learning, and this is an excellent project to learn packaging and deployment software.

This is incorrect. We describe using a hash in the paper because it’s part of the foundation for understanding a digital signature. Sorry for the confusion. You’ll notice that we aren’t hashing things in the source code we provide.

Do you have some suspicion that someone other than you would have loaded code on your robot?

As I’ve been involved in FRC, I’ve developed what I would consider a rather healthy paranoia.* Some of my first experiences with robots were ones that had so many issues that being in the pits was like playing whack-a-mole. I’ve come to find that I value my ability to trust something, whether that something is hardware or software. Having a digital signature helps to maintain that trust - not only that it isn’t corrupted, but that it came from me.

Our personal implementation was that the scripts were on a flash drive (we also wrote some custom logging code that would have maxed out the roboRIO’s disk pretty fast, so we were already using it). I don’t think that someone else would take our flash drive, covertly change code on it, and plug it back in, but I would rather anticipate that possibility and prepare for it than be bitten by it when it mattered.

  • For the record, my first championship experience was 2012. For those who weren’t there, I’d suggest reading up on some FRC history as to why that might encourage me to be proactive about security. Not everyone in FIRST understands Gracious Professionalism and Coopertition.

Nice paper. I’m excited to see TeX in FRC.

I’m more interested in the features of checking the scripts for corruption over considering a nefarious party, although even this is a bit of an extreme edge case even if your auto modes are on a flash drive or something.

What benefits does this process have over changing parameters using the dashboard?

Is it possible to string together complex series of actions and make decisions? Could you activate WPILib Commands, or make decisions based on Game-specific data string?

Again, very nice system.

The thing about apt, docker, etc, is that you need to be able to trust that the file you are getting is from the sender and that no one is pretending to be the sender or intercepting the transmission. I get that this needs a signature. I wouldn’t bank online without such mechanisms. My point is that in the FRC problem, both sides of the link are controlled. The team controls the laptop and the team controls the RoboRIO.

So, unless one suspects someone else changed the code, then the hash should suffice for providing a check on correctness. Kudos for exploring a technology, but it’s probably overkill.

To nickbrickmaster’s point, something to correct for latent corruption (i.e. the file is corrupted after the transfer) is also interesting and may bring more benefit than the signed transfer. Something like a Reed-Solomon encoded file and hash could be interesting to explore.

The digital signature also verifies integrity. If the file is corrupted somehow, the signature will not match the script.

What benefits does this process have over changing parameters using the dashboard?

We’ve had lots of troubles with SmartDashboard. Shuffleboard seems better (we used it at competition as part of this system), but still isn’t perfect. We also don’t use the command-based paradigm, so a lot of the automagic of the dashboards just doesn’t work.

This also lets us have multiple computers going - we can have the drivers driving on the driver station, one programmer on the main robot code/watching the riolog, and another few programmers working on auto modes.

Is it possible to string together complex series of actions and make decisions? Could you activate WPILib Commands, or make decisions based on Game-specific data string?

Yes. While we haven’t done it, you can use the fully-qualified name of the Java type to create a Java object in the JavaScript runtime if you’re interested in sticking to the Command-based framework. Nashorn also provides a load() function that you could use to compose auto scripts from other auto scripts.

Again, very nice system.

Thanks! We’re pretty pleased with how it turned out.

I don’t agree. The team doesn’t control the roboRIO unless they somehow lock it up right after each match, since we can’t change the default passwords inconsequentially (found that one out the hard way). For the same reasons, you don’t control the radio.

You also don’t control the laptop. Since we’ve already established that the roboRIO credentials (including root) are public and unchangeable, there’s no way to prove to the roboRIO that you’re special and privileged by some OS mechanism. So any laptop will do just fine for a malicious actor who’s trying to SSH in and knows what they’re doing. The only way to prove that you’re special and privileged is via an asymmetrical cryptosystem, and the simplest way to do that is to generate digital signatures for your scripts.

To nickbrickmaster’s point, something to correct for latent corruption (i.e. the file is corrupted after the transfer) is also interesting and may bring more benefit than the signed transfer. Something like a Reed-Solomon encoded file and hash could be interesting to explore.

The signatures are not checked during the transfer. They are checked just previous to when the scripts are parsed and cast into Invocables. As mentioned above, corruption would cause the signature verification to fail.

I note on Page 7 a constraint which may have to be addressed if you’d like the system to be fully secure:


The team secures the public key on the roboRIO such that it cannot be modified by a malicious actor.

FRC is very much a “if you have physical access, you have root access” type of deal. Locking down the lvuser and admin accounts is one way around the problem, but this makes a lot of tools (like the RoboRIO imaging tool) unable to run since they assume a blank password. Furthermore, they can be reset with a USB drive if you know the right file to load, and have a bit of time.

That being said, autonomous scripting is a really good way around rapid development if you don’t need very fast loops. We used Groovy scripts at one point, which can be both dynamically loaded into the JVM as well as compiled into a class file, which gives you the rapid prototyping as well as the ability to run fast after you’ve nailed the implementation. You do lose the sandboxing, though.

Nice job on the paper, it was a good read.

Our experience with changing passwords was more drastic. We actually lost the ability to SSH into the roboRIO. It was very strange - we could get in a few times, but then it would lock up. We had to use that magic NI USB file you’ve mentioned to get back in. This happened multiple times. So, moral of the story - you can’t even count on the OS security facilities. I’m not sure if others have experienced our issues, but there were a few threads that talked about similar symptoms from similar actions.

That’s why we suggest having the public key be compiled into the JAR. It’s at least as secure as the JAR itself. If anyone can arbitrarily alter the JAR, they can have the RIO run arbitrary code, including code that doesn’t verify autonomous signatures.

As someone who has experienced the magic NI USB process, getting back into the system via the USB backdoor took a more than just a “bit of time.” All in all, it was about an hour long process which required me to have constant access. In my view, someone could only do this during lunch or a really long break between robot uses. But yes, this is a vulnerability, and one that isn’t fixable or mitigable at my access level by design.

That being said, autonomous scripting is a really good way around rapid development if you don’t need very fast loops. We used Groovy scripts at one point, which can be both dynamically loaded into the JVM as well as compiled into a class file, which gives you the rapid prototyping as well as the ability to run fast after you’ve nailed the implementation. You do lose the sandboxing, though.

None of our scripts looped, so we never considered that issue. I’ll have to do some more digging. I wonder if you could do some cool stuff in Kotlin, have it compile to JavaScript when you want the sandboxing, and have it compile to bytecode when you want the speed…

Nice job on the paper, it was a good read.

Thanks!