Posts
4545
Following
316
Followers
476
Linux kernel hacker and maintainer etc.

OpenPGP: 3AB05486C7752FE1
Imaginary kernel example would be /devtpmrm0 but given ability to break the bytestream apart and put it back together, be it either direction, it could be much more sophisticated than the existing.
0
0
0
As secondary priority, I want to have this ready for any linux-rust interactions because it would be the part of implementation I would be most concerned of. That is one reason I've ended up to a context-free and environment agnostic implementation like this.
1
0
0
Totally applicable also to be used in pre-boot loaders, operating system kernels etc. as it does what it does efficiently but is io-less (it does things right tho with AsRef and similar traits so to that it melts nicely to io-full world).
1
0
0

Jarkko Sakkinen

Edited 6 days 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
@oleksandr @jejb lol that is true :-) good catch (i was intuitively thinking that it is leaking length from some return value).
1
0
0
@oleksandr It's interesting because I don't recognize by eye 0x161 as TPM error code (I have to check this tho formally). I will take a look at it later this week, just my initial guess.

RT @jejb
1
0
0
In its simplicity this extends quite nicely:

├── protocol
│   ├── Cargo.toml
│   └── src
│   ├── envelope
│   │   ├── context_save_command.rs
│   │   ├── context_save_response.rs
│   │   ├── create_command.rs
│   │   ├── create_primary_command.rs
│   │   ├── create_primary_response.rs
│   │   ├── create_response.rs
│   │   ├── dictionary_attack_lock_reset_command.rs
│   │   ├── empty_response.rs
│   │   ├── evict_control_command.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
│   │   ├── tpm2b.rs
│   │   ├── tpm_alg_id.rs
│   │   ├── tpma_object.rs
│   │   ├── tpm_cap.rs
│   │   ├── tpm_cc.rs
│   │   ├── tpm_ecc_curve.rs
│   │   ├── tpml_pcr_selection.rs
│   │   ├── tpm_rc.rs
│   │   ├── tpm_rh.rs
│   │   ├── tpms_context.rs
│   │   ├── tpms_ecc_point.rs
│   │   ├── tpms_sensitive_create.rs
│   │   ├── tpm_st.rs
│   │   └── tpmt_public.rs
│   └── session
│   └── mod.rs

[session is still a bit stub]

It's fully no_std too and that is an invariant that will be maintained :-)
0
0
0
For exporting I was thinking first should exporting be just stdout but I think --export-file is find given you can always "--export-file /dev/stdout" (shortening the option to just --export tho).
1
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
I also realized that I've been misguided by the driver i've made myself because it works as expected, i.e. isolates concurrent users from accessing each other cryptographi assets. used pre-existing tpm stacks for results and many default to apparently to /dev/tpmrm0 🤷 And I don't really understand why I did not put it in first place to Gitlab for which I know even how to run local instance.
0
0
0

Jarkko Sakkinen

Edited 9 days 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
@notbobbytables in learning there's like two axes (or this is how i project learning at least): the axe of learning and the axe of learning how to learn ;-)
1
0
1
@notbobbytables the differentiating factor to those optimization guides (while not disregarding them by any means) is that it's really good writeup and really a perfected piece of text :-) e.g., it would be a great text to read in order to gain some of the gist of memory optimizations before reading technical guides such as the ones you linked.

i don't know if you've ever read "linkers and loaders" by stephen levy but it is also something i did enjoy many years ago (and still have hard copy) for being great text to get the gist of structure of executable binaries, which really gave me "philosophical" foundation to navigate in manuals and specification.

and some years earlier while at high school, i got my foundation for code optimization with pipeline architectures from https://www.goodreads.com/book/show/946151.Graphics_Programming_Black_Book.

these are more like guides to "read the actual guides" that build the foundation to read any optimization manuals, technical papers, specs and similar documentation :-)
1
0
1
@notbobbytables yeah well it's almost unique identifier, isn't it? :-)

or like "t-shirt level unique" even :-) would be odd if there was another cpumemory.pdf.
1
0
1

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

Without “| xargs -n 1 basename” would change the output stream to absolute path. With that in mind:

function cargo-registry
  argparse 'a/all' 'q/query=' -- $argv
  or return
  set -l q ""
  if set -q _flag_query
    set q "$_flag_query"
  else
    set q "$argv[1]"
  end
  set -l r \
    ~/.cargo/registry/src/index.crates.io-*/
  set -l dirs
  if set -q _flag_all
    set dirs (ls -d $r*/ 2>/dev/null)
  else
    set dirs (
      ls -d $r*/ 2>/dev/null \
      | xargs -n 1 basename
    )
  end
  if test -z "$q"
    printf '%s\n' $dirs \
    | sort
  else
    printf '%s\n' $dirs \
    | grep -i "$q" \
    | sort
  end
end

Results:

~ main
❯ cargo-registry | head -5
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

~ main
❯ cargo-registry -a | head -5
/Users/jarkko/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ab_glyph_rasterizer-0.1.9/
/Users/jarkko/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ab_glyph-0.2.31/
/Users/jarkko/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/accesskit_consumer-0.28.0/
/Users/jarkko/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/accesskit_macos-0.20.0/
/Users/jarkko/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/accesskit_winit-0.27.0/

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

~ main
❯ cargo-registry egui -a
/Users/jarkko/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/egui_glow-0.32.0/
/Users/jarkko/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/egui-0.32.0/
/Users/jarkko/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/egui-wgpu-0.32.0/
/Users/jarkko/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/egui-winit-0.32.0/
0
0
0

Jarkko Sakkinen

Edited 13 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
Show older