Posts
4913
Following
326
Followers
491
Linux kernel hacker and maintainer etc.

OpenPGP: 3AB05486C7752FE1

Jarkko Sakkinen

Edited 2 months ago
The design that I'm aiming with this cli interface is that it would be usable for TPM2 interaction for application written shell (bash, fish etc.) scripting languages (i.e. password managers and similar).

When it starts to be easy to combine the subcommands in script this should be in fairly good state.

Import and load support keys in ASN.1 format, which is used by kernel for loading trusted keys. Software crypto for now is with libssl bindings as it is sort for safe-play for crypto (CVEs, security hotfixes, auditing) and also it is what I'm most used to in kernel development (and that is what I ultimately care about).
0
0
1

Jarkko Sakkinen

Edited 2 months ago
After playing seriously with Rust's declrative macros for the first time instead of just using them I got pretty neat results. This is because I intend to keep tpm2_protocol depdency free so that it could be used in-kernel if that is ever feasible.

This is how I declare command bodies now in the implementation:

tpm_command!(
TpmStartAuthSessionCommand,
TpmCc::StartAuthSession,
TpmSt::NoSessions,
2,
pub nonce_caller: Tpm2b,
pub encrypted_salt: Tpm2b,
pub session_type: TpmSe,
pub symmetric: TpmtSymDefObject,
pub auth_hash: TpmAlgId,
);

[2 is in fact number handles]

This will generate the command and implement traits for marshalling AND unmarshalling command. Both are implemented in-depth for all TCG specification types across the board.

Another simpler example is TPML_* from the specification:

tpml!(TpmlAlgProperty, TpmsAlgProperty);
tpml!(TpmlDigest, Tpm2b);
tpml!(TpmlDigestValues, TpmtHa);
tpml!(TpmlHandle, u32);
tpml!(TpmlPcrSelection, TpmsPcrSelection);

And TPM2B_*:

tpm2b!(full; Tpm2bAttest, TpmsAttest);
tpm2b!(full; Tpm2bContextData, TpmsContextData);
tpm2b!(full; Tpm2bCreationData, TpmsCreationData);
tpm2b!(full; Tpm2bEccPoint, TpmsEccPoint);
tpm2b!(full; Tpm2bEncryptedSecret, TpmuEncryptedSecret);
tpm2b!(full; Tpm2bIdObject, TpmsIdObject);
tpm2b!(full; Tpm2bNvPublic, TpmsNvPublic);
tpm2b!(full; Tpm2bSensitive, TpmtSensitive);
tpm2b!(full; Tpm2bTemplate, TpmtPublic);

I find this really fascinating :-)

#rust #rustlang #linux #kernel #tpm
1
1
1

Jarkko Sakkinen

Edited 2 months ago
i'd be interested on seeing a new version of /dev/tpmrm0 that would take advantage of my protocol marshaler/unmarshaler.

it's about 5k of rust code but large portion of that is just architectural types.

the first problem is the hardest: what to call the new at this point still imaginary device :-)

it's a post initcall use case just like /dev/tpmrm0 e..g, use by systemd (afaik tbh have not checked) where as hardware interfacing stuff would be tedious given tight bindings to to the boot. thus, it is not extremely hard to implement in linux-rust as long as the device can turn on before PID 1.

benefits could be e.g., to simplify TPM code in daemons such as systemd, if the resource manager would do a better job servicing their requirements.

#linux #tpm #rust #rustlang
1
0
0

Jarkko Sakkinen

Edited 2 months ago
Regex filtered search for algorithms in the TPM chip and the format used for algorithms in tpm2-cli.

Some other idioms are context: and nvram: as sinks for output.
0
0
0

Jarkko Sakkinen

I'm making sure the cli works nicely before pushing to Gitlab for some days. It is at least much saner looking already (IMHO) than tpm2-tools.
0
0
1

Jarkko Sakkinen

It's always a good sign when things converge like this :-) I reached unipolarity (can assemble and disassemble to both directions) with the TPM2 architectural structures I've already included (~40% of the spec) in tpm2_protocol.

pub trait Command<'a>: Marshal + Unmarshal<'a> {
const COMMAND_CODE: TpmCc;
const COMMAND_TAG: TpmSt;
}

pub trait Response<'a>: Marshal + Unmarshal<'a> {
const COMMAND_CODE: TpmCc;
const COMMAND_TAG: TpmSt;
}
0
0
0

Jarkko Sakkinen

Edited 3 months ago
tpm2_protocol is turning into quite cool crate:

1. It's a no_std crate that uses Rust's type system describe TPM commands and responses in the same resolution as the spec.
2. It marshals also responses and unmarshals commands.
3. It's not a stack. it's stackless implementation of types.

These properties allow to nest and glue it to TSS2 and any other pre-existing TPM stack.

Also it could be theoretically used to implement a chip since it is designed to run also bare metal and has been designed to be skimpy on resources ;-)

Hopefully next week get this out...
2
0
1

Jarkko Sakkinen

This is amount of spec types I uncarved from tpm2-scripts and redefined Rust types:

```
creation_ticket.rs
mod.rs
tpm2b_public.rs
tpm2b.rs
tpm2b_sensitive_create.rs
tpm_alg_id.rs
tpma_object.rs
tpma_session.rs
tpm_cap.rs
tpm_cc.rs
tpm_ecc_curve.rs
tpml_digest.rs
tpml_digest_values.rs
tpml_pcr_selection.rs
tpm_rc.rs
tpm_rh.rs
tpms_auth_command.rs
tpms_auth_response.rs
tpms_context.rs
tpms_ecc_point.rs
tpm_se.rs
tpms_keyedhash_parms.rs
tpms_pcr_selection.rs
tpms_pcr_select.rs
tpms_sensitive_create.rs
tpms_symcipher_parms.rs
tpm_st.rs
tpmt_ha.rs
tpmt_kdf_scheme.rs
tpmt_public.rs
tpmt_scheme.rs
tpmt_sym_def_object.rs
tpmu_ha.rs
tpmu_public_id.rs
tpmu_public_parms.rs
```

This is horribly slow process as first because it is not as mechanical process one might think. There's lot of scattered per-type quirks. But as this grows this becomes less and less of pain :-)

I define "completed" status for every type that they must serialize and deserialize, which creates constraints that make them feasible for mock testing for instance.
0
0
0

Jarkko Sakkinen

With the idea how to organize TPM2 protocol in my resurrected tpm2_library and trying how they work in tpm2-cli, this starts produce usable results and working code:

❯ sudo RUST_LOG=trace target/debug/tpm2-cli create-primary -H owner ecc --curve nist-p256
2025-08-05T07:51:22.223171Z DEBUG tpm2_cli::tpm: Opening device: /dev/tpmrm0
2025-08-05T07:51:22.223258Z TRACE tpm2_cli::tpm: Command:
2025-08-05T07:51:22.223283Z TRACE tpm2_cli::tpm: 0000: 80 02 00 00 00 43 00 00 01 31 40 00 00 01 00 00
2025-08-05T07:51:22.223298Z TRACE tpm2_cli::tpm: 0010: 00 09 40 00 00 09 00 00 00 00 00 00 04 00 00 00
2025-08-05T07:51:22.223310Z TRACE tpm2_cli::tpm: 0020: 00 00 1a 00 23 00 0b 00 03 00 72 00 00 00 06 00
2025-08-05T07:51:22.223326Z TRACE tpm2_cli::tpm: 0030: 80 00 43 00 10 00 03 00 10 00 00 00 00 00 00 00
2025-08-05T07:51:22.223335Z TRACE tpm2_cli::tpm: 0040: 00 00 00
2025-08-05T07:51:22.467218Z TRACE tpm2_cli::tpm: Response Header:
2025-08-05T07:51:22.467308Z TRACE tpm2_cli::tpm: 0000: 80 02 00 00 01 1a 00 00 00 00
2025-08-05T07:51:22.467332Z TRACE tpm2_cli::tpm: Response Body:
2025-08-05T07:51:22.467363Z TRACE tpm2_cli::tpm: 0000: 80 ff ff ff 00 00 01 03 00 5a 00 23 00 0b 00 03
2025-08-05T07:51:22.467393Z TRACE tpm2_cli::tpm: 0010: 00 72 00 00 00 06 00 80 00 43 00 10 00 03 00 10
2025-08-05T07:51:22.467421Z TRACE tpm2_cli::tpm: 0020: 00 20 a7 a6 81 0c 1c 1e 49 00 6f 24 69 12 22 e5
2025-08-05T07:51:22.467455Z TRACE tpm2_cli::tpm: 0030: af 6f 2a 47 65 ed 8e 68 4a 9f 16 e9 03 db 5a 42
2025-08-05T07:51:22.467485Z TRACE tpm2_cli::tpm: 0040: 5c 0a 00 20 57 7c e3 94 59 4c ab 5b 46 49 32 9a
2025-08-05T07:51:22.467516Z TRACE tpm2_cli::tpm: 0050: be 04 e9 9e 8f 21 6d 3d 86 53 42 c3 48 20 40 dd
2025-08-05T07:51:22.467545Z TRACE tpm2_cli::tpm: 0060: fc 83 95 f2 00 37 00 00 00 00 00 20 e3 b0 c4 42
2025-08-05T07:51:22.467572Z TRACE tpm2_cli::tpm: 0070: 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4
2025-08-05T07:51:22.467600Z TRACE tpm2_cli::tpm: 0080: 64 9b 93 4c a4 95 99 1b 78 52 b8 55 01 00 10 00
2025-08-05T07:51:22.467631Z TRACE tpm2_cli::tpm: 0090: 04 40 00 00 01 00 04 40 00 00 01 00 00 00 20 5d
2025-08-05T07:51:22.467661Z TRACE tpm2_cli::tpm: 00a0: a0 41 ba c0 ee 31 35 ae bb 0c ad fb a4 97 c6 a1
2025-08-05T07:51:22.467690Z TRACE tpm2_cli::tpm: 00b0: 87 7f ae 83 2d d3 d1 f8 f7 a8 71 b8 25 e8 54 80
2025-08-05T07:51:22.467720Z TRACE tpm2_cli::tpm: 00c0: 21 40 00 00 01 00 20 52 97 3a e0 e3 f0 a2 4e a3
2025-08-05T07:51:22.467750Z TRACE tpm2_cli::tpm: 00d0: 49 de 48 4c 75 d3 5d b8 ea b7 d3 d6 e2 f9 63 22
2025-08-05T07:51:22.467780Z TRACE tpm2_cli::tpm: 00e0: 73 f5 bb db 1b ae 84 00 22 00 0b 82 79 ad e2 be
2025-08-05T07:51:22.467809Z TRACE tpm2_cli::tpm: 00f0: 16 9a 3c b5 20 69 67 97 1b ee 93 bc be c8 fe d3
2025-08-05T07:51:22.467840Z TRACE tpm2_cli::tpm: 0100: cc b4 e6 bd 02 0a 69 48 d7 23 dc 00 00 01 00 00
0x80ffffff

❯ sudo target/debug/tpm2-cli create-primary -H owner ecc --curve nist-p256
0x80ffffff

❯ sudo target/debug/tpm2-cli create-primary -H owner --export-file primary.ctx ecc --curve nist-p256

I'll still need to check that this at least can feature wise in par with tpm2-scripts (mainly cphash functionality) and that tpm2_protocol does not have immediate glitches when implementing features to tpm2-cli. Also since tpm2_protocol is Apache/MIT and tpm2_cli I add a bit features to make sure that right parts
of the code are in the "correct basket".

I'm also looking into if I could make TPM protocol assets fit into the constrainsts of bincode and serde, and since it is looking good I finish this feature too.

Sunday I got there feature-wise but only at the end realized I was creating a wrong thing. Now I prepare the code base a bit, test etc. and the I put this to Gitlab :-)

#tpm #linux
1
1
1

Jarkko Sakkinen

this is how i'm reorganizing tpm2_library that i resurrected yesterday:

protocol
├── Cargo.toml
└── src
├── envelope
│   ├── create_primary_command.rs
│   ├── create_primary_response.rs
│   ├── create_response.rs
│   ├── dictionary_attack_lock_reset_command.rs
│   ├── empty_response.rs
│   ├── flush_context_command.rs
│   ├── get_capability_command.rs
│   ├── get_capability_response.rs
│   └── mod.rs
├── lib.rs
├── object
│   ├── creation_ticket.rs
│   ├── mod.rs
│   ├── tpm2b_data.rs
│   ├── tpm_alg_id.rs
│   ├── tpma_object.rs
│   ├── tpml_pcr_selection.rs
│   ├── tpms_sensitive_create.rs
│   └── tpmt_public.rs

and further:

1. object "registry" is a flat and fat given that there is standard body doing "intelligent hashing", i.e. TCG is my UUID algorithm for that directory. agreed that the de-facto names are ugly but it is ugly AND clean :-) it is known to scale with the spec from the get go to foreseeable future making it ugly, clean and super stable.
2. all objects marshal and unmarshhal.
3. envelope is also flat as i have unidirectionality as constraint and both commands and responses translate bytestream and back.

this api is aimed to work for clients and emulators. i have no interest to write a simulator but it's still easy to figure out how to make that useful: the same crate can be used to implement TPM interaction and tests can use it to mock the TPM chip interaction :-)

[and it will appear to gitlab anytime soon]

#tpm #linux #tss
0
0
0

Jarkko Sakkinen

Edited 3 months ago

I’m finally updating tpm2_library crates which provide near spec idiomatic naming balanced with Rust conventions, marshalling/unmarshalling, parsing displaying error codes with parameter numbers etc.

The protocol crate is aiming to be no_std style IO free crate. In fact I aim to polish it to the level that it would be equally useful and complete for both clients and TPM emulators to take advantage of and given the use purpose having super-conservative list of deps:

[dependencies] bitflags = { workspace = true } strum = { workspace = true } strum_macros = { workspace = true }

The idea how naming goes is easiest to demostrate with TPM_CC type form TPM2 Structures specification. Let’s randomly pick TPM_CC_EvictControl, which is use for transient-persistent and persistent-evicted conversions.

EDIT: So, uhm, I’ll setting it up the project to Gitlab. Was doing too many things at once :-) I moved the repo away from Codeberg some weeks ago to get more CI quota basically but Github was not the right move. Gitlab is a better fit because I already do kernel CI there, keyutils is hosted in Gitlab and I’ve had less luck running actions locally with “act” than “gitlab-ci-local” (https://github.com/firecow/gitlab-ci-local).

I have already placeholder for it in Gitlab but it is probably better sleep first and do after (and make sure that everything works).

[*] https://github.com/ColinIanKing/tpm2-scripts Thanks for @colinianking again for preservation! It came for use now …

#tpm #linux #kernel

1
0
0

Jarkko Sakkinen

probably the most time standing tutorial i've ever read is cpumemory.pdf. still from time to take a peak on it because it is such a great refresher :-)
1
0
0

Jarkko Sakkinen

Edited 3 months ago
Fun fact: Finnish signal intelligence agency is called "SIGINT"
0
1
6

Jarkko Sakkinen

This is a fish function:

function cargo-registry --argument-names query
  set -l r \
    ~/.cargo/registry/src/index.crates.io-*/
  set -l c (
    ls -d $r*/ 2>/dev/null \
    | xargs -n 1 basename
  )

  if test -z "$query"
    printf '%s\n' $c \
    | sort
  else
    printf '%s\n' $c \
    | grep -i "$query" \
    | sort
  end
end

And what it does is:

❯ cargo-registry|head
ab_glyph_rasterizer-0.1.9
ab_glyph-0.2.31
accesskit_consumer-0.28.0
accesskit_macos-0.20.0
accesskit_winit-0.27.0
accesskit-0.19.0
adler2-2.0.1
adler2-2.0.1
ahash-0.8.12
ahash-0.8.12
aho-corasick-1.1.3
allocator-api2-0.2.21
allocator-api2-0.2.21
anstream-0.6.19
anstream-0.6.19
anstyle-1.0.11
anstyle-1.0.11
anstyle-parse-0.2.7
anstyle-parse-0.2.7
anstyle-query-1.1.3
# ...

And also:

❯ cargo-registry egui
egui_glow-0.32.0
egui-0.32.0
egui-wgpu-0.32.0
egui-winit-0.32.0

#fish #shell

1
0
1

Jarkko Sakkinen

Edited 3 months ago
derive_more is a gem when it comes to rust crates

makes is so much less involved
0
0
0

Jarkko Sakkinen

Edited 3 months ago
USB is interesting in the way that identifying USB devices is a non-existent feature.

E.g., a librarian for USB mass storage would have to base identifying to filesystem labels, and obviously user would have to have a process for labeling for that to actually work.

And if a malicious stick is attached, as long as it provides sane description of itself (i.e. naming a legit device, vendor, class etc.), computer can't tell the difference.
1
0
0

Jarkko Sakkinen

Edited 3 months ago

This is as done as lsiommu can ever be, or at least as far as I’m concerned so it’s a release time:

https://github.com/puavo-org/lsiommu/releases/tag/1.0.0

I.e. I spent last night making it do less from the almost nothing it was doing already ;-) That’s the point of these tools…

That enumerated to:

  • Reverted back to heap sort.
  • Carved 64 kB of data section for JSON builder.
  • Hammered STRING_BUFFER() to migrate most of the strings to stack (except JSON builder
  • Bunch of fixes…

This sums up to zero mallocs from the main application (while libudev probably does bunch of them when not compiled with make DISCOVER=sysfs).

Motivation to do was this shitty python script:

#!/usr/bin/env python3
#
# Copyright (c) 2022-2023 Jarkko Sakkinen <jarkko.sakkinen@iki.fi>

import os
import sys

IOMMU_SYSFS = '/sys/kernel/iommu_groups'
IOMMU_GROUP_MAX = 128 # an arbitrary choice

def get_iommu_devices():
    groups = [None for group in range(IOMMU_GROUP_MAX)]

    with os.scandir(IOMMU_SYSFS) as group_it:
        for group in group_it:
            devices = []

            group_sysfs = IOMMU_SYSFS + '/' + group.name + '/devices'
            with os.scandir(group_sysfs) as device_it:
                for device in device_it:
                    devices.append(device.name)

            index = int(group.name)
            if index >= IOMMU_GROUP_MAX:
                print('Overflow')
                sys.exit(1)

            groups[index] = devices

    return groups

if __name__ == "__main__":
    groups = get_iommu_devices()

    for i in range(len(groups)):
        group = groups[i]
        if group == None:
            break

        print('IOMMU Group %d' % (i))

        group.sort()

        for device in group:
            # FIXME: Replace with pure Python code:
            os.system('lspci -nns ' + device)

#linux #kernel #iommu #kvm

0
0
0

Jarkko Sakkinen

I'm happy now with mailweb for my own needs but I wrote down in detail the tasks for expanding it to TUI file managers:

https://codeberg.org/jarkko/mailweb/issues

I could easily cope with approaches if it makes sense to me. I just wrote, mainly as a reminder, steps to a working implementation done if I really had to :-)
0
0
0

Jarkko Sakkinen

i'll add text/plain support to mailweb in the next update. it's obsolete feature for mutt or aerc but for file manager such as midnight command and ranger that'll make it a generic email file opener as it shows eml/mbox files correctly (i.e. with pics not cids).

With "--browse" it just forwards the result to the mime handler.
0
0
0
Show older