Skip to content
This repository was archived by the owner on Nov 7, 2023. It is now read-only.

Conversation

@sergefdrv
Copy link
Contributor

@sergefdrv sergefdrv commented Jul 26, 2018

The replicas need to agree so that each peer has a single instance of USIG able to produce valid UIs. This is required to prevent a faulty replica from sending conflicting messages to different nodes in the consensus network. The current approach of capturing the USIG epoch value from the first valid UI received from a peer relies on a number of assumptions:

  • all replicas are initially correct,
  • each replica uses its unique USIG key pair per consensus protocol instance,
  • the first UI is generated using a single USIG instance per replica,
  • those first UIs are received and processed by all correct replicas before any replica becomes faulty in a sense that it starts generating and sending UIs using another USIG instance initialized with the same sealed key pair.

Those assumptions might be too strong in some environments. In that case, there should be a way for all correct replicas to agree on a single USIG instance identity per each replica and use that identity to verify UIs of received consensus messages.

Considering this, it seems to be most reasonable to move the current approach of achieving the agreement on USIG identity outside of the core protocol implementation.

This series does some refactoring to make it easier and eventually moves the USIG epoch handling from the core protocol implementation to the sample implementation of the external authentication interface.

@sergefdrv
Copy link
Contributor Author

@luthlee Could you please review this PR?

@sergefdrv
Copy link
Contributor Author

@ynamiki Somehow I don't seem to be able to request review from luthlee...

image

@sergefdrv
Copy link
Contributor Author

@ynamiki I wonder why this PR doesn't go through CI?

@sergefdrv sergefdrv force-pushed the remove-ui-epoch-handling-from-core-code branch from 1c704ad to e9aecea Compare July 26, 2018 15:12
@sergefdrv
Copy link
Contributor Author

@Naoya-Horiguchi @ynamiki Who of you would also like to review this PR?

nhoriguchi
nhoriguchi previously approved these changes Jul 26, 2018
@nhoriguchi
Copy link
Contributor

uh, I pushed review button in order to approve the first commit of this series, but a whole pull request was approved which is not yet intended. I don't see how to cancel my approval, but anyway I still continue to review to this.

@ynamiki
Copy link

ynamiki commented Jul 27, 2018

Somehow I don't seem to be able to request review from luthlee...

@sergefdrv Reviewers need to have read access to the repository. We have two options for give the access: 1) add to organization nec-blockchain (if luthlee is a member of your lab), or 2) add as an outside collaborator of this repository nec-blockchain/minbft. Which is preferred?

@ynamiki
Copy link

ynamiki commented Jul 27, 2018

I wonder why this PR doesn't go through CI?

@sergefdrv I have update settings in CircleCI to build forked pull requests. It will work at next commit (I have tested with #15).

@nhoriguchi
Copy link
Contributor

@sergefdrv, I don't get into details (I need learn existing code more..), I have a few feedbacks:

  • patch descriptions are nicely written and I felt easy to understand what you try to do.
  • you state in comment around usig_create_ui() "the epoch and counter values in little-endian byte order", I guess this is because it's required by hardware. If so, that's worth explaining in the comment.
  • time.Sleep() inserted for simulation mode had better be conditional by checking environment variable SGX_MODE.

@sergefdrv
Copy link
Contributor Author

sergefdrv commented Jul 27, 2018

The commits are shown in the pull request by GitHub in a weird way because of https://help.github.com/articles/why-are-my-commits-in-the-wrong-order/, isaacs/github#386.

@sergefdrv sergefdrv force-pushed the remove-ui-epoch-handling-from-core-code branch 2 times, most recently from 4f0f3f6 to bf79a36 Compare July 27, 2018 09:01
@sergefdrv
Copy link
Contributor Author

sergefdrv commented Jul 27, 2018

I rebased the commits with --ignore-date and they appear in the right order on GitHub. isaacs/github#386 (comment)

@sergefdrv
Copy link
Contributor Author

sergefdrv commented Jul 27, 2018

We have two options for give the access: 1) add to organization nec-blockchain (if luthlee is a member of your lab), or 2) add as an outside collaborator of this repository nec-blockchain/minbft. Which is preferred?

@ynamiki Please go ahead with option (1). She is from our lab 🙂

@sergefdrv
Copy link
Contributor Author

you state in comment around usig_create_ui() "the epoch and counter values in little-endian byte order", I guess this is because it's required by hardware. If so, that's worth explaining in the comment.

That is not really the requirement. It was just easier to do so. SGX is only available on Intel CPUs. Those are always little-endian. The signature payload is conveniently constructed as a "packed" C structure (see https://github.com/sergefdrv/minbft/blob/bf79a36638d99873ae5c28141c8410c7e4771abe/usig/sgx/enclave/usig.c#L30). That is why those numbers are in little endian. Changing to big endian would require adding more code in enclave, which is better to keep at minimun.

time.Sleep() inserted for simulation mode had better be conditional by checking environment variable SGX_MODE.

SGX_MODE determines the enclave build mode, but only at build time. It is not reliable indicator at runtime. For instance, bin/keytool generate mentioned in https://github.com/nec-blockchain/minbft#generating-keys can be invoked in a separate shell with no SGX_MODE set.

I was thinking of building both version of enclave and store them in separate files. Then one could chose the version to use at runtime. What do you think?

@sergefdrv
Copy link
Contributor Author

@Naoya-Horiguchi Please do not merge this PR until @luthlee has finished reviewing it.


usigID, err := MakeID(usig.Epoch(), usigPubKey)
require.NoError(t, err)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit test for the ParseID()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to pointing that out. I'll add a test for this.

// interface by utilizing SGX USIG to create/verify authentication
// tags.
// usigKeyFingerprint is a SHA256 hash of the USIG public key.
type usigKeyFingerprint [sha256.Size]byte
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you want to use a shorter hash output or truncate the output? SGX ECDSA is 256-bit, so the public key is 512-bit long. Your fingerprint only saves half the space.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking to truncate this to 64-bit fingerprint.

//
// Those assumptions might be too strong in some environments.
// In that case, there should be a way for all correct
// replicas to agree on a single USIG instance identity per
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a correct bootstrap/initialization stage, replicas are not required to be all correct.
Therefore, "in that case, a correct bootstrap is required for all replicas to first agree on...".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, there would be no need for all replicas to be initially correct. That is why only the correct replicas need to agree; up to f replicas could be faulty from the beginning and do not agree. I didn't want to emphasize how it should be achieved. It could be achieved at bootstrap phase or maybe some other way. But I'm considering to change the wording to: "In that case, all correct replicas are required to agree ..." Would that make sense?

@sergefdrv
Copy link
Contributor Author

time.Sleep() inserted for simulation mode

What we could also do is to make a pull request to change the way SGX simulation mode sets the seed value. If it gets accepted, we could get rid of this hack when the fix gets released. intel/linux-sgx#246 (comment)

@sergefdrv
Copy link
Contributor Author

I don't see how to cancel my approval

@Naoya-Horiguchi You could try this https://blog.github.com/2016-10-12-dismissing-reviews-on-pull-requests/

@ynamiki
Copy link

ynamiki commented Jul 27, 2018

Please go ahead with option (1). She is from our lab 🙂

I have invited @luthlee to nec-blockchain.

Sergey Fedorov added 9 commits July 27, 2018 14:39
SGX USIG public key in SGX_ECDSA key spec is a normal ECDSA key. Reuse
normal ECDSA key spec implementation to parse it.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
Current implementation of USIG authentication scheme does only support
SGX USIG. This is not easy to make generic because USIG identity
passed to VerifyUI is going to be highly depend on particular USIG
implementation. Current implementation uses serialized public key as
USIG identity. This does not reflect actual SGX USIG identity and is
going to change.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
We might want to have a dummy USIG implementation that would not
require SGX SDK to build it, but that should implement usig.USIG
interface rather than api.Authenticator.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
USIGEnclave instance is guaranteed to have an enclave instance
created. So the key sealing should never fail. If that happens,
there's nothing to do more; just give up and panic.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
This field is in fact a digital signature over a message digest, epoch
and counter values. It is an implementation detail that this signature
solely represent SGX USIG certificate.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
Currently there is no way to get the epoch value out of a SGX USIG
instance without creating a new UI, but that have a side effect of
increasing its counter value. This functionality is going to be useful
for composing a full USIG identity which is USIG public key combined
with the epoch value of the particular USIG instance.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
Now the epoch value can be directly retrieved once the enclave is
initialized, there is no need to do that each time a new UI is
assigned.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
This structure keeps only two fields now. Moreover, it may be confused
with actual UI structure defined in Go code.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
USIGEnclave is a wrapper around SGX enclave, it should not deal with
USIG API entities. USIG type, on the other hand, is implementation of
USIG interface. Thus, it is more appropriate to move UI construction
there.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
Sergey Fedorov added 8 commits July 27, 2018 14:39
The signature verification is a nontrivial separate step in verifying
a USIG UI. It makes sense to encapsulate it into a separate function,
close to the code which produces the signature and determines its
format.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
The public key alone doesn't really serve as USIG identity since
multiple instances of USIG enclave can be created on the same machine
initialized with the same sealed key pair. Those instances will share
the public key. However, each instance will have its unique epoch
value. So the epoch value combined with the public key make up the
actual USIG identity.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
MinBFT protocol does not actually define USIG epoch value. The notion
of the epoch value is specific to current SGX USIG implementation and
is used to determine full SGX USIG instance identity. These details
should not be handled by the core of MinBFT protocol. Move this to the
sample implementation of authentication external interface.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
The epoch value is an implementation detail of SGX USIG. The core
protocol should not be aware of this. Encapsulate the epoch value into
USIG certificate to make the sample USIG authentication be able to
extract it from the UI and update the captured epoch value.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
Big-endian byte order is conventionally used to marshal values to be
exchanged through the network. Follow that convention.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
USIG-based authentication scheme is actually assumed to guarantee
agreement on a single USIG instance per replica node among the peers.
State this requirement clearly in an API documentation comment.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
This is needed to ensure that each instance of USIG enclave gets
initialized with different random number generation seed if the
enclave is built in simulation mode.

Signed-off-by: Sergey Fedorov <sergey.fedorov@neclab.eu>
@sergefdrv sergefdrv force-pushed the remove-ui-epoch-handling-from-core-code branch from bf79a36 to 44780cf Compare July 27, 2018 12:39
@sergefdrv
Copy link
Contributor Author

@luthlee I have tried to address your comments. Sorry, I didn't know how GitHub handles it and force-pushed the changed series here. So there seem to be no way to compare with the previous revision. Next time I will follow some other approach as discussed in #12 .

@sergefdrv
Copy link
Contributor Author

@Naoya-Horiguchi Would you have more comments?

@nhoriguchi nhoriguchi dismissed their stale review August 3, 2018 01:27

because updated version will be posted.

@nhoriguchi
Copy link
Contributor

nhoriguchi commented Aug 3, 2018

I was thinking of building both version of enclave and store them in separate files. Then one could chose the version to use at runtime. What do you think?

I think that if this is easy enough, you can do it.

What we could also do is to make a pull request to change the way SGX simulation mode sets the seed value. If it gets accepted, we could get rid of this hack when the fix gets released. intel/linux-sgx#246 (comment)

That's the best scenario for us, so I hope your suggestion will be accepted.

@sergefdrv
Copy link
Contributor Author

@Naoya-Horiguchi Building both HW and simulation version of enclave would require significant change in enclave Makefile. This looks like a separate issue to address later.

As of changing SGX SDK code, it doesn't look like they are going to change it soon. We could propose the change ourselves. This is rather easy change, but somebody would need to take care of this.

@sergefdrv
Copy link
Contributor Author

@Naoya-Horiguchi Actually, changing the way the enclave is build wouldn't eliminate this workaround with 1 second delay. We would still use simulation mode in CI, for example. So the best way would be to propose the change to SGX SDK.

@sergefdrv
Copy link
Contributor Author

sergefdrv commented Aug 3, 2018

@Naoya-Horiguchi

because updated version will be posted

Sorry, the content of this pull request has been updated since your comment #14 (comment). Next time I will follow the approach as discussed in #12 .

@nhoriguchi
Copy link
Contributor

@sergefdrv thank you for the explanation. It seems to me that the RDRAND approach pointed out in the SGX SDK thread might be fine because code change is minimum (maybe calling sgx_read_rand() to generate a seed?) and we might avoid additional library dependency as in nanosecond approach. RDRAND is available since Ivy Bridge CPU, so most of our platform should have it.

@sergefdrv
Copy link
Contributor Author

@Naoya-Horiguchi

It seems to me that the RDRAND approach pointed out in the SGX SDK thread might be fine

I'm not sure if RDRAND would always be available in a could-based CI.

because code change is minimum (maybe calling sgx_read_rand() to generate a seed?)

We do not generate the seed ourselves, this is what SGX SDK does. We use sgx_read_rand() https://github.com/nec-blockchain/minbft/blob/master/usig/sgx/enclave/usig.c#L171 and sgx_ecc256_create_key_pair() https://github.com/nec-blockchain/minbft/blob/master/usig/sgx/enclave/usig.c#L119. The point is that any random number SGX SDK provides in simulation mode is based on a seed value captured at enclave creation time. It is currently the local time in seconds. That is SGX SDK implementation.

and we might avoid additional library dependency as in nanosecond approach.

I'm not sure what do you mean by additional library dependency. I was suggesting if some of us could prepare a patch for SGX SDK to use higher-precision timestamp for seeding the pseudo random number generation in simulation mode.

RDRAND is available since Ivy Bridge CPU, so most of our platform should have it.

I think anyone should be able to try our MinBFT implementation in simulation mode without any problem.

@nhoriguchi
Copy link
Contributor

@sergefdrv sorry for my lack of words. My previous comment was intended to tell about how we fix seed generation in SGX SDK as you said. I think we have 2 options: using nanosecond timestamp as a seed, and using sgx_read_rand() as a seed instead of second timestamp.

and we might avoid additional library dependency as in nanosecond approach.
I'm not sure what do you mean by additional library dependency.

sorry again. I just meant adding '#include " may be needed, but actually that introduces no problem.

I think anyone should be able to try our MinBFT implementation in simulation mode without any problem.

OK, so nanosecond approach is better.

I was suggesting if some of us could prepare a patch for SGX SDK to use higher-precision timestamp for seeding the pseudo random number generation in simulation mode.

If you are OK, can I try this?

@sergefdrv
Copy link
Contributor Author

@Naoya-Horiguchi

I think we have 2 options: using nanosecond timestamp as a seed, and using sgx_read_rand() as a seed instead of second timestamp.

I'm not sure if sgx_read_rand() would be available at the point of enclave simulation initialization. sgx_read_rand() is provided by SGX SDK for enclave trusted code, whereas PRNG seed value is initialized in untrusted code. My suggestion is to change https://github.com/intel/linux-sgx/blob/54cae063cd0d21be5fab28c0d4b81b073b5d0914/sdk/simulation/urtssim/enclave_creator_sim.cpp#L232 to something using clock_gettime() with CLOCK_MONOTONIC.

I was suggesting if some of us could prepare a patch for SGX SDK to use higher-precision timestamp for seeding the pseudo random number generation in simulation mode.

If you are OK, can I try this?

Please go ahead, I'll be focussed on implementing view change in MinBFT.

@sergefdrv
Copy link
Contributor Author

@Naoya-Horiguchi Would it be anything to change in this pull request, or can we merge it?

@nhoriguchi
Copy link
Contributor

@sergefdrv I'm fine to merge this series, thank you for your effort!

@sergefdrv sergefdrv merged commit f5a973b into hyperledger-labs:master Aug 6, 2018
@sergefdrv sergefdrv deleted the remove-ui-epoch-handling-from-core-code branch August 6, 2018 09:50
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants