Posts
4803
Following
319
Followers
489
Linux kernel hacker and maintainer etc.

OpenPGP: 3AB05486C7752FE1

Jarkko Sakkinen

the next thing i do for tpm2_protocol is render out "rstest" and "hex" from cargo test and make my macro auto-generate roundtrip tests.

i'll also add a Makefile to the root with "make test" target. It will build the test binary with rustc and run the tests. Finally this will be added to the CI.
1
0
0

@mupuf I wrote the code so that i don’t end up dust-for-linux :D

I also learned that “macros_rules!” is the thing that you would want to learn first in Rust so that it would make any sense if you knew beforehand that it is the thing that you most want to learn :-) Without it super unproductive language and IMHO does not really pay the cost despite what ever “memory safety”. With “macro_rules!” you can consolidate those few dozen trait implementations into one single place :-) Then it is suddenly more productive language than C.

I drive the spec interpration and building with ~600 lines of trial and error fine-tune syntax tree macros :-) https://github.com/puavo-org/tpm2_library/blob/main/protocol/src/macro.rs

And then I can implement the spec like I was writing the spec:

tpm_struct!(
    #[derive(Debug, Default, PartialEq, Eq, Clone)]
    TpmStartAuthSessionCommand,
    TpmCc::StartAuthSession,
    true,
    true,
    2,
    {
        pub nonce_caller: Tpm2b,
        pub encrypted_salt: Tpm2b,
        pub session_type: TpmSe,
        pub symmetric: TpmtSymDefObject,
        pub auth_hash: TpmAlgId,
    }
);

And all the bidirectional marshalling and unmarshallinf magic will appear :-) Things like “async” are more like fixed structure threading framework type of stuff but does not convince at all what makes sense in the core language (neither does borrow checker at least not as “driving feature”), I mean we already have Java :-) ).

0
0
1

Jarkko Sakkinen

typoed rust-for-linux to my annoucement by accident as ust-for-linux ****
1
0
0

Jarkko Sakkinen

Edited 1 month ago
You can literally build identity function with this now :-) And yeah, I can say this with 100% confidence: nothing exactly like this in production usable form pre-exist. It's first of its kind.
0
0
0

Jarkko Sakkinen

This was nasty one to fix and took many days (and nights tbh) but now finally command parsing is fixed and all my tests pass:

https://github.com/puavo-org/tpm2_library/commit/7b0fc824bd341fb21c90a06b945f01feb1c20f5e

There's MS TPM 2.0 emulator and swtpm, and that's like all of command parsing and response synthesis I'm aware of. I.e. by practical means there was no useful existing work to take example of :-) I'm pretty happy and a bit proud too that I've reach unipolarity by writing Rust macros reflecting TCG specifications.

I don't have now known bugs in the protocol crate. I'm sure there's a bunch but still feels nice after 1.5 weeks of sleepless nights and 7K SLOC of code (protocol + cli).

#linux #kernel #rust #tpm
1
0
1

Jarkko Sakkinen

Edited 1 month ago
It's immature as hell but I think i've made correct base decisions (which you can only do at this point). Right now I'm fixing some macros because i did "final polishments before putting this out" and did some awful mistakes :-) This always happens. Yesterday morning things were better but then I started to tweak ...

I think, considering rust-linux, one interesting feature could be swtpms, which becomes realistic goal if you make right conclusions of what you're observing. I don't actually know could you create endosement infrastructure where swtpm instances have their endorsement keys certified by the TPM chip (which is endorsed by the manufacturer).

In the previous TPM stack implementations i think that core mistake that has been repeatedly made is thinking that you have a client and chip or emulator, which is not from technical perspective correct assesment.

QEMU is an emulator. TPM2 is a protocol. That is stating the obvious but for some reason that is the exact blind spot.
0
0
0
@lkundrak ya basically want to make sure that whoever intends to do that gets it done smoothly and such and so forth (if that ever happens even) :-) that is the positive angle i guess... and now it is done
0
0
0
@lkundrak ya i mean i don't want to end up in a situation where i see a rust patch set and i try to say that the code is just plain bad and it is interpreted me being toxic person :-) and all reported in the usual news outlets... i can relate to the pain and suffering some maintainers have had tbh.
1
0
0
@lkundrak it's also for the reasons that now i have my rust insurance :-) now i don't have to think about the topic further can focus on side quests
1
0
1

Jarkko Sakkinen

This makes me happy:

tpm_struct!(
    #[derive(Debug, PartialEq, Eq, Clone)]
    TpmPcrEventCommand,
    TpmCc::PcrEvent,
    TpmSt::Sessions,
    1,
    {
        pub event_data: Tpm2b,
    }
);

tpm_response!(
    #[derive(Debug, Default, PartialEq, Eq, Clone)]
    TpmPcrEventResponse,
    TpmCc::PcrEvent,
    TpmSt::Sessions,
    {
        pub digests: TpmlDigestValues,
    }
);

Also the types inside use the same system (in fact tpm_struct is shared macro with data types and commands). This will generate full parsing and building for both commands and responses - all without heap involved.

1
0
0
Here's another 3D print project: a mounting bracket for W1GHZ dual-band microwave feed horns (10 GHz + 24 GHz).

https://github.com/xjamesmorris/dual-band-10-24-ghz-feed-mount

#amateurradio #hamradio #3dprinting #rf #microwave
0
2
7
Licensing is used as security measure. I.e. crate itself is Apache/MIT but cli is strict GPL3. It's exactly because then you know that a binary is "accountable". It's a trick I've learned how Signal creates security layers via licensing (they show how AGPL can be commercially appealing pick).
0
0
0
I.e. want to write your own TPM emulator in one day? Now it is possible
1
0
0

Jarkko Sakkinen

Edited 1 month ago
the killer feature of the TPM stack itself compared to any other is to be able to speak in responses and interpret commands. For this use case you really only have MS TPM 2.0 simulator and swatpm as of today (swtpm is great tho). The protocol crate is made for interoperability layers of non-TPM crypto chips and hardware/software keystores alike.
1
0
0
@colinianking this is now 'tpm-scripts 2.0" ;-)
0
0
1

Jarkko Sakkinen

Edited 1 month ago
I'm ready to push this online, but not for a while tag a release because cli should be made to work optimally.

E.g., policy-secret is placeholder. it would much nicer to have "policy [--train] <expression>" with some combinatorial language.

It could take advantage of object references provided my baked-in stack machine:

1. Subcommands a take list of JSON objects from stdin and consume as many as they need from top of te stack.
2. Each subcommand then produce results to the top.

Of course some things come through arguments (e.g. for key creation I have "--persistent").

Also perhaps load and import should be combined to a single smart command. The point is that this is where I don't know what to do exactly and changes for cli interface are welcome :-) I'm now happy that I got allocs and panics away from protocol crate making it "linux-rust ready".

In the protocol crate itself there is one single puzzle where constant improvement makes sense both in kernel and user space: narrowing the delta between "SIZE" and "len()" of TpmSize trait. Ideally the delta would be zero t some point. To be usable in kernel I've now reach that goal (easily) but optimizing this equation makes it substantially better.
2
1
2

Jarkko Sakkinen

cannot even imagine what amazing things i end up doing with my zmodem2 crate implementation now that i've learned how to really put protocol shenanigans in place with rust ;-)
0
1
1

Jarkko Sakkinen

Edited 1 month ago

It also optimizes performance as that zeros out marshalling and unmarshalling. Internal representation can be buffer to which data structures are mapped.

For capacity it’s not exact science i.e.:

/// Buffer properties for an object.
pub trait TpmBuffer {
    /// Capacity at most required to strore an object implementing the type.
    const BUFFER_CAPACITY: usize;
   
    pub fn len() -> usize; 
}

E.g., for digest this would the maximum digest. For TPMT_PUBLIC capacity would 640 bytes to fit 4096-bit RSA key.

At runtime, however, the exact size is calculated by summing up “recursively”. Lengths also when summed up point the exact location in the byte stream where an attribute is located. I.e., it’s a zerocopy. I

0
0
0
Show older