In search of contributors to a Linux Chromebook fingerprint PAM module

What

Ability to unlock Linux (KDE lock screen, sudo) with the Chromebook’s fingerprint sensor. As of now, you can’t do that. I want to do that.

How

How to use ectool to use the fingerprint sensor

Try this on your Chromebook which has a fingerprint sensor.

Set the seed

sudo ectool --name=cros_fp fpseed aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

This is needed before enrolling fingers. It must be exactly 32 bytes. If you’re getting errors for other commands, you may need to set the seed again. When you upload templates you must use the same seed that you had when you enrolled the templates.

Enroll a finger

sudo ectool --name=cros_fp fpmode enroll

Then touch your finger to the sensor. Then run

sudo ectool --name=cros_fp fpmode

to check the fpmode. You should have to do this exactly 5 times to enroll a finger, but you may need to do it a few extra times if your finger didn’t get sensed properly.

If it says 0x30

That means it didn’t detect your finger. Press your finger to the sensor until the fpmode is not 0x30.

If it says 0x10

That means that it detected your finger, but it still needs more data to calibrate it. Run enroll again, press the same finger to the sensor, and check the mode again.

If it says 0x0

That means that your finger is enrolled.

Downloading the template

Choose a place where you want to save the template. I recommend making a fingers folder for your templates. Downloading the template lets you match the template even after the Chromebook suspends, shuts down, and ec resets.

sudo ectool --name=cros_fp fptemplate 0 > r1

You can replace r1 with any file name. I use r1 as an ID for right thumb. r2 would be right index finger, and so on.

Clearing the loaded templates

Before enrolling another finger, I recommend clearing the loaded templates to avoid errors. Remember to download the template before you clear templates.

sudo ectool --name=cros_fp fpmode reset_sensor

Uploading a saved template

sudo ectool --name=cros_fp fptemplate r1

Where r1 is the name/path to the file with the template.

Finding out the maximum number of fingerprint template slots

sudo ectool --name=cros_fp fpinfo

Sample output:

Fingerprint sensor: vendor 20435046 product 9 model 21f version 1
Image: size 160x160 8 bpp
Error flags: 
Dead pixels: UNKNOWN
Templates: version 4 size 5156 count 0/5 dirty bitmap 0

The key info is 0/5. It means that there are 5 slots total and 0 of them are currently being used.

Matching a finger

Before you do this, use fpinfo to check that you have at least 1 template loaded.

sudo ectool --name=cros_fp fpmode match

Then press a finger to test to the sensor. Then run

sudo ectool --name=cros_fp fpstats

Sample output:

FP stats (t0=115662613 us):
Last capture time:  90645 us
Last matching time: 180720 us (finger: 2)
Last overall time:  272723 us

This means that the test finger matched the template with the index 2 (it starts from 0).
Sample output:

FP stats (t0=2394100110 us):
Last capture time:  90756 us
Last matching time: Invalid
Last overall time:  Invalid

Invalid means that the test finger was not the same finger as any loaded templates.

The plan to implement fingerprint login

DBus interface

A program will run as root (to access /dev/cros_fp) and start a system DBus interface to allow interacting with the fingerprint sensor.

DBus client

Programs can run as normal users and interact with the dbus interface to access the fingerprint sensor as a normal user.

CLI

A CLI will be made which uses a DBus client to enroll fingerprints. This could be made into an app, but since you don’t really need to enroll fingerprints often, making a CLI makes more sense. No one’s stopping people from making an app though.

PAM Module

This function interacts with other programs to check if they should give you access to certain things. For example, KDE can interace with this function to unlock the lock screen if you press a valid finger to the sensor.

The plan is to write everything in Rust.

Who can contribute

  • Has a Chromebook with a fingerprint sensor
  • Is able to use ectool to manually enroll, download, upload, and match, and understand how to use the commands (I can help you learn)
  • Can contribute to Rust code (you can learn Rust)

How to contribute

Reply to this thread with any ideas, questions, or things you can do. I will be continueing development of GitHub - ChocolateLoverRaj/cros-fp-pam: PAM module for authenticating with fingerprint on Chromebooks in a few weeks. You can start sooner or later. Once I have a kind-of-working version, people who test it, report bugs, and hopefully find the cause and fix the bugs would be very helpful.

@Ultrabook u may be interested in this.

4 Likes

I would love to help, can we get an IM group going for this? Either Signal or XMPP/Jabber would work fine for me.

1 Like

Thanks for helping. I don’t have Signal or Jabber but I can download Jabber. I also have Matrix if that works for u. We could also just talk in this thread.

Perhaps you’re right, keeping it public may incentivize others to join in. I’m a relative newbie and use a drobit as a daily driver. Will need to get rid of that drallion I bought a couple of weeks ago since I can’t seem to get the EC to work on linux - but that doesn’t have a fingerprint reader anyway.

Would be great to have a summary of the project you’re working on, how it relates to GitHub - chrultrabook/libfprint-cros: WIP libfprint driver for Chromebooks and what kind of tasks (generally speaking) you’re needing help with at this very moment.

1 Like

At this point, the dbus interface and CLI are written and kind-of work. There are issues with consistency and loading fingerprint templates from files after enrolling them. My pam module is an alternative to libfprint specific to Chromebooks. THe reason why I’m not trying to add Chromebook fingerprint to libfprint is because libfprint is confusing, written in C (not Rust), and I tried and failed to setup a development environment before. If someone else wants to figure out libfprint stuff, I’m happy to help with the EC specific code.

Unfortunately I’ve never written Rust code before so it’ll be slow going for me to have to learn it as I go along. But I’d still love to find a way to support this project if I can! Since I’m new to the chrultrabook world, I do have a few more questions for now:

(1) What do you make of the lack of automatic EC firmware updates once Chrome OS is replaced? I’m not sure how often mrchromebook’s repo is updated to include EC firmware updates, but at the very least the script would need to be run again, which can be a challenge even for diligent but forgetful folks such as me.

(2) I’m guessing it would be a substantial amount of work to make another PAM that would work at the boot-level for LUKS support. What’re your thoughts?

(3) Are you aware of any efforts to provide a secure and reliable way to store persistent EC state info, so not everything EC-related needs to be done from scratch after every reboot? This would serve so many purposes: (a) solve the previous LUKS challenge (b) take away the need for (currently unencrypted) PAM templates (c) open up a whole range of other EC-related purposes eg. batterycutoff values becoming irrelevant for anyone using dualboot or live OS.

If you’re comfortable with C, you could try adding Chromebook fingerprints to libfprint, and I can help with the EC specific stuff. It’s ok if you’re a beginner at Rust. You can still help with planning the overall way it will work and testing it.

  1. I’m not sure how often Chromebooks on ChromeOS even get EC firmware updates. I don’t think it really matters if EC firmware updates are only once every few months.
  2. I’ve never heard of unlocking LUKS with fingerprint. I don’t think that would be worth it, and it might be a security problem.
  3. I’m not sure what you mean by EC state info.Things like keyboard light brightness can be saved and re-applied by the OS. Charge control is preserved even after rebooting into a different OS.

I can’t seem to get the enroll mode working for me. Doesn’t matter whether I touch the fingerprint reader or not:

❯ sudo ectool --name=cros_fp fpmode enroll
FP mode: (0x30) enroll+image

❯ sudo ectool --name=cros_fp fpmode
FP mode: (0x30) enroll+image

For me, the utility of any hardware-based security tool (TPM, fingerprint reader, FIDO key, etc) is greatly diminished if there are limits to its applications. To that end, I am holding out hope that we can get fingerprint functionality to work with LUKS eventually.

Keyboard brightness and charge control both reset anytime there’s a change to the BIOS settings (such as when booting a live OS from a USB drive).

So after you do fpmode enroll and touch the fingerprint reader, it still shows 0x30 instead of 0x10?

Also, you can try using the Rust ectool (mostly written by me). Install Rust and then run

cargo b
sudo ./target/debug/ectool fp-mode enroll-image enroll-session
sudo ./target/debug/ectool wait-event Fingerprint 9999999 fp

it will show you the percentage, and if there was an error.

This is how it looks like for me:

[rajas@nixos:~/Documents/crosec-rs]$ cargo b && sudo RUST_BACKTRACE=1 ./target/debug/ectool fp-mode enroll-image enroll-session
    Finished dev [unoptimized + debuginfo] target(s) in 0.30s
FP mode: 0b110000 (EnrollSession, EnrollImage)

[rajas@nixos:~/Documents/crosec-rs]$ cargo b
sudo ./target/debug/ectool fp-mode enroll-image enroll-session
sudo ./target/debug/ectool wait-event Fingerprint 9999999 fp
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
FP mode: 0b110000 (EnrollSession, EnrollImage)
EventHappened(
    Fingerprint(
        Enroll(
            EcMkbpEventFingerprintEnroll {
                percentage: 40,
                error: None,
            },
        ),
    ),
)

Correct.

hum on ultramarine crosec-rs on  main via 🦀 v1.78.0 
❯ sudo cargo b    
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s

hum on ultramarine crosec-rs on  main via 🦀 v1.78.0 
❯ sudo ./target/debug/ectool fp-mode enroll-image enroll-session
Hello command
EC says hello!
Version command
RO version:    drobit_v2.0.7540-147f8d37d1
RW version:    drobit_v2.0.10154-ea173525ac
Firmware copy: RW
Build info:    drobit_v2.0.10154-ea173525ac 2023-03-10 15:46:42 MrChromebox
Tool version:  0.1.0
Chip info command
Chip info:
  vendor:    Nuvoton
  name:      NPCX797F
  revision:  C.02

hum on ultramarine crosec-rs on  main via 🦀 v1.78.0 
❯ sudo ./target/debug/ectool wait-event Fingerprint 9999999 fp
Hello command
EC says hello!
Version command
RO version:    drobit_v2.0.7540-147f8d37d1
RW version:    drobit_v2.0.10154-ea173525ac
Firmware copy: RW
Build info:    drobit_v2.0.10154-ea173525ac 2023-03-10 15:46:42 MrChromebox
Tool version:  0.1.0
Chip info command
Chip info:
  vendor:    Nuvoton
  name:      NPCX797F
  revision:  C.02

You’re on the main branch. Use my more-commands branch

hum on ultramarine crosec-rs on  more-commands via 🦀 v1.78.0 
❯ sudo ./target/debug/ectool fp-mode enroll-image enroll-session
FP mode: 0b110000 (EnrollSession, EnrollImage)

hum on ultramarine crosec-rs on  more-commands via 🦀 v1.78.0 
❯ sudo ./target/debug/ectool wait-event Fingerprint 9999999 fp
error: invalid value 'Fingerprint' for '<EVENT_TYPE>'
  [possible values: key-matrix, host-event, sensor-fifo, buttons, switches, fingerprint, sysrq, host-event64, cec-event, cec-message, dp-alt-mode-entered, online-calibration, pchg]

  tip: a similar value exists: 'fingerprint'

For more information, try '--help'.

hum on ultramarine crosec-rs on  more-commands via 🦀 v1.78.0 
❯ sudo ./target/debug/ectool wait-event fingerprint 9999999 fp
error: unexpected argument 'fp' found

Usage: ectool wait-event [OPTIONS] <EVENT_TYPE> [TIMEOUT]

For more information, try '--help'.

I tried it without the ‘fp’ argument, and it seems to just sit there waiting for something until the timeout of “9999999” ms (or rather, until my hitting Ctrl C). Touching the fingerprint reader seems to not do anything. What am I missing here?

Oh sorry I changed the CLI slightly after sending the message. These commands should work:

cargo b
sudo ./target/debug/ectool fp-mode enroll-image enroll-session
sudo ./target/debug/ectool wait-event fingerprint --device fp

Alright, now we’re talking!

hum on ultramarine crosec-rs on  more-commands via 🦀 v1.78.0 
❯ sudo ./target/debug/ectool fp-mode enroll-image enroll-session
FP mode: 0b110000 (EnrollSession, EnrollImage)

hum on ultramarine crosec-rs on  more-commands via 🦀 v1.78.0 
❯ sudo ./target/debug/ectool wait-event fingerprint --device fp
EventHappened(
    Fingerprint(
        Enroll(
            EcMkbpEventFingerprintEnroll {
                percentage: 40,
                error: None,
            },
        ),
    ),
)

Keep doing it until it says 100%. Then run

sudo ./target/debug/ectool fp-mode match
sudo ./target/debug/ectool wait-event fingerprint --device fp

to see if matching works.

If it doesn’t work, it may be because you didn’t set the seed before enrolling.

Dunno what happened to make it stop working:

hum on ultramarine crosec-rs on  more-commands via 🦀 v1.78.0 
❯ sudo ./target/debug/ectool wait-event fingerprint --device fp     
EventHappened(
    Fingerprint(
        Enroll(
            EcMkbpEventFingerprintEnroll {
                percentage: 60,
                error: None,
            },
        ),
    ),
)

hum on ultramarine crosec-rs on  more-commands via 🦀 v1.78.0 
❯ sudo ./target/debug/ectool wait-event fingerprint --device fp
^C

hum on ultramarine crosec-rs on  more-commands via 🦀 v1.78.0 took 41s 
❯ sudo ./target/debug/ectool wait-event fingerprint --device fp
^C

hum on ultramarine crosec-rs on  more-commands via 🦀 v1.78.0 took 36s 

Also

❯ sudo ./target/debug/ectool fp-set-seed bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
Error: 
   0: command failed with status AccessDenied

Location:
   ectool/src/main.rs:242

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.

You need to use the fp-mode command before the wait-event command to tell it to do the next step.

This means that the seed is already set

Okay, so fp-mode match now works. But I can’t seem to be able to download a template with

sudo ./target/debug/ectool fp-download template 0

why not? What’s the error that you get?

Note: This step will fail if the fpseed is not set.