Posts
4507
Following
316
Followers
477
Linux kernel hacker and maintainer etc.

OpenPGP: 3AB05486C7752FE1

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 yesterday

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 6 days 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 6 days ago
derive_more is a gem when it comes to rust crates

makes is so much less involved
0
0
0

Jarkko Sakkinen

Edited 7 days 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 8 days 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

Jarkko Sakkinen

i wanted to change the name of my html mail tool multidepart as it is used by some funding organization or similar:

https://www.eiturbanmobility.eu/projects/multidepart/

the new name is mailweb as it is a tool that literally does that i.e., it converts text/html mail to a static website (despite archaic) ;-)

https://crates.io/crates/mailweb

also bumped the minor to add clarity for the change.
0
0
0

Jarkko Sakkinen

Through some indeterministic process that I don't understand from time to time I have to "warn up" gpg to not fail on "git tag -s" like this:

❯ git tag -s ihatemylife
error: gpg failed to sign the data
error: unable to sign the tag
The tag message has been left in .git/TAG_EDITMSG

~/work/codeberg.org/jarkko/multidepart main ⇡
❯ gpg -s README.md

After the latter command, tag signing suddenly works.

#git #gpg #yubikey
0
0
1

Jarkko Sakkinen

i've been using 2021 edition of rust up until now because i only now realized that i need to run rustup update occasionally :-)

i was wondering for months shouldn't 2024 be out and why i'm stuck with 2021 edition lol.

rust starts to be mature enough that probably once next version is debian is out i start to use distro toolchain (if kernel requires newer my [buildroot](https://codeberg.org/jarkko/linux-tpmdd-test) shenanigans will provide me a toolchain :-) ), which is like where any native language should evolve.

this is what i do with python i.e., work in the limits of distribution packaged stuff. it makes software translate more easily and your upstream is in a way always ready for packaging.
1
1
1

Jarkko Sakkinen

great now the deps are in the reasonable level for this type of tool :-) (and meson replaced with plain make).

using cjson was not a great idea in the first place as when doing json output for small and trivial low-level tools like this instead of dumping big continuous json string is also really the best option (vs pretty printing).

maybe i soon tag a release and put this debian packaging pipeline :-)
0
0
0

Jarkko Sakkinen

Edited 10 days ago

I’m using mutt so need to ask this before updating readme.

This what I have for mutt:

macro index F10 "<pipe-message>multidepart --browse\n" "View HTML in browser"
macro pager F10 "<pipe-message>multidepart --browse\n" "View HTML in browser"

This is what I presume would be correct for aerc (in ~/.config/aerc/binds.conf):

[messages]
F10= :pipe -p multidepart --browse<Enter>
[view]
F10= :pipe -p multidepart --browse<Enter>

Does that look about right?

#aerc #mutt #email #html

1
0
1

Jarkko Sakkinen

Edited 10 days ago
Something i had forgotten from crates.io: never use "license-file" in Cargo.toml. It's broken, and crates.io leaves the license undefined.
1
0
0

Jarkko Sakkinen

This is along the lines clone of viewhtmlmail (popular among #mutt users).

https://codeberg.org/jarkko/multidepart

It's pretty much done for crates.io at least :-)

#email
1
1
0

Jarkko Sakkinen

One perhaps not so obvious observations from Rust that at least I've gathered over time is answer to this question:

- There are traits and dynamic traits.
- Which one to pick by defacto?

Dynamic traits are most of the time the best pick in my opinion, and I base it on:

1. Smaller binary size.
2. Shorter compilation times.

#rust #rustlang
1
1
3
Show older