Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of signature/checksum generation #1058

Open
jklmnn opened this issue May 30, 2022 · 5 comments
Open

Handling of signature/checksum generation #1058

jklmnn opened this issue May 30, 2022 · 5 comments
Labels
architectural decision Discussion of design decision model Related to model package (e.g., model verification) specification Related to specification package (e.g., specification parsing)

Comments

@jklmnn
Copy link
Member

jklmnn commented May 30, 2022

Context and Problem Statement

Some messages require a signature or checksum at the end of the message. This field is usually calculated from the whole message either including the signature field zeroed out or excluding it. Currently there is no good way to do this in sessions. The only option is to allow the creation of a message without a signature (which may contradict the original standard of the protocol), pass that to the platform and then copy the message with the original field values into a new buffer and add the signature to this message.

Considered Options

O1 Update aggregate

One approach is to allow updating a field in a message. Since that alters the path in the message graph an update has to initialize all fields from the updated one to the end of the message.
This approach allows the creation of a message with a zeroed out signature field and updating just the signature after it has been calculated. Protocols that require the signature field to be omitted have to do that on the platform.

Msg := Message (A => 1, B => 3, C => 4, D => 5);
Msg'Update (C => 6, D => 7);

+ Flexible, applicable to different situations.
+ Prevents duplication of message creation.
+ Doesn't require a separate copy of the message.
Doesn't work well if the signature is not at the end of the message.
Requires the platform to omit the zeroed out signature field if needed.

O2 Incomplete messages

This approach allows the message to be incomplete and the incomplete message to be passed to the platform for signature generation. The others keyword can only be placed at the beginning or at the end of a message aggregate. If placed at the end it signals that the message is incomplete and only the specified fields are known. If placed at the beginning it indicates that the previously set fields are used and that the aggregate will begin with the next field. Both can be combined to partially complete an incomplete message.

Msg := Message (A => 1, B => 2, others => <>);
Msg := Message (others => <>, C => 3, others => <>);
Msg := Message (others => <>, D => 4);

+ Allows partial setting of messages.
Doesn't allow reuse of existing messages.
Message has to be checked to be complete in some contexts.
Only allows signatures at the end of the message.

O3 Nested messages

This approach uses an unsigned and a signed message type. The unsigned message type does not contain the signature field an can be used to pass it to a platform function generating the signature. Once the signature is known it is just inserted into the signed message.

   type Unsigned_Message is
      message
         ...
      end message;

   type Signed_Message is
      message
         Message : Unsigned_Message;
         Signature : Opaque;
      end message;

+ No separate copy required.
+ Closest to the currently available features (only #446 is required)
Does not work with signature fields not at the end of the message at all.
Introduces unnecessary complexity into the message structure.
Doesn't support signatures that require the signature field to be present but zero.

O4 #276

+/ see #276.

O5 #1067

+ Flexible, applicable to different situations.
+ Prevents duplication of message creation.
+ Doesn't require a separate copy of the message.
Doesn't work well if the signature is not at the end of the path that must be signed.

Decision Outcome

TBD

@jklmnn jklmnn created this issue from a note in RecordFlux 0.6 (To do) May 30, 2022
@jklmnn jklmnn added model Related to model package (e.g., model verification) architectural decision Discussion of design decision specification Related to specification package (e.g., specification parsing) labels May 30, 2022
@treiher
Copy link
Collaborator

treiher commented May 30, 2022

I'm not convinced that allowing incomplete messages in a session specification would be a good idea. For the described use case, you would also have to allow passing incomplete messages to functions to create the signature.

Another solution could be the specification of two message types:

   type Unsigned_Message is
      message
         ...
      end message;

   type Signed_Message is
      message
         Message : Unsigned_Message;
         Signature : Opaque;
      end message;

The current semantics of inner messages makes using such messages cumbersome, but there is already another ticket to address that (#446).

@jklmnn
Copy link
Member Author

jklmnn commented May 30, 2022

Passing incomplete messages to platform functions doesn't really work because I can't pass the message until I created one and at that point I need it to be complete.

I thought about using an inner unsigned message but I wanted to avoid that as I think it increases the code size further.

@jklmnn
Copy link
Member Author

jklmnn commented May 30, 2022

Thinking about it, using an inner message without the signature may be an improvement as it avoids copying the original data around to recreate the message. I'll try that.

@treiher
Copy link
Collaborator

treiher commented May 30, 2022

You are right, the current way how inner messages are represented could be quite bad for the code size. Signed_Message would essentially a copy of Unsigned_Message with one additional field. I think the code size could be optimized by using Opaque and a refinement for the inner message.

   type Unsigned_Message is
      message
         ...
      end message;

   type Signed_Message is
      message
         Message : Opaque;
         Signature : Opaque;
      end message;

   for Signed_Message use (Message => Unsigned_Message);

Would this work for your use case? Unfortunately, I'm not sure how well this is supported by the code generator.

@jklmnn
Copy link
Member Author

jklmnn commented May 30, 2022

While this would generally work I'm not sure if we want to introduce refinements in SPDM again after we put the effort in to remove them.

@jklmnn jklmnn changed the title Handling of incomplete messages Handling of signature/checksum generation May 31, 2022
@senier senier removed this from To do in RecordFlux 0.6 Aug 23, 2022
@senier senier added this to To do in RecordFlux Future via automation Aug 23, 2022
@senier senier moved this from To do to Long-term in RecordFlux Future Aug 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
architectural decision Discussion of design decision model Related to model package (e.g., model verification) specification Related to specification package (e.g., specification parsing)
Projects
No open projects
Development

No branches or pull requests

2 participants