- 
                Notifications
    
You must be signed in to change notification settings  - Fork 23
 
Remove USIG epoch handling from core code #14
Remove USIG epoch handling from core code #14
Conversation
| 
           @luthlee Could you please review this PR?  | 
    
| 
           @ynamiki Somehow I don't seem to be able to request review from luthlee...  | 
    
| 
           @ynamiki I wonder why this PR doesn't go through CI?  | 
    
1c704ad    to
    e9aecea      
    Compare
  
    | 
           @Naoya-Horiguchi @ynamiki Who of you would also like to review this PR?  | 
    
| 
           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.  | 
    
          
 @sergefdrv Reviewers need to have read access to the repository. We have two options for give the access: 1) add to organization   | 
    
          
 @sergefdrv I have update settings in CircleCI to build forked pull requests. It will work at next commit (I have tested with #15).  | 
    
| 
           @sergefdrv, I don't get into details (I need learn existing code more..), I have a few feedbacks: 
  | 
    
| 
           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.  | 
    
4f0f3f6    to
    bf79a36      
    Compare
  
    | 
           I rebased the commits with   | 
    
          
 @ynamiki Please go ahead with option (1). She is from our lab 🙂  | 
    
          
 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. 
 
 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?  | 
    
| 
           @Naoya-Horiguchi Please do not merge this PR until @luthlee has finished reviewing it.  | 
    
| 
               | 
          ||
| usigID, err := MakeID(usig.Epoch(), usigPubKey) | ||
| require.NoError(t, err) | ||
| 
               | 
          
There was a problem hiding this comment.
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()
There was a problem hiding this comment.
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.
        
          
                sample/authentication/crypto.go
              
                Outdated
          
        
      | // 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 | 
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
        
          
                sample/authentication/crypto.go
              
                Outdated
          
        
      | // | ||
| // 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 | 
There was a problem hiding this comment.
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...".
There was a problem hiding this comment.
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?
          
 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)  | 
    
          
 @Naoya-Horiguchi You could try this https://blog.github.com/2016-10-12-dismissing-reviews-on-pull-requests/  | 
    
          
 I have invited @luthlee to   | 
    
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>
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>
bf79a36    to
    44780cf      
    Compare
  
    | 
           @Naoya-Horiguchi Would you have more comments?  | 
    
because updated version will be posted.
          
 I think that if this is easy enough, you can do it. 
 That's the best scenario for us, so I hope your suggestion will be accepted.  | 
    
| 
           @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.  | 
    
| 
           @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.  | 
    
| 
           @Naoya-Horiguchi 
 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 .  | 
    
| 
           @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.  | 
    
| 
           @Naoya-Horiguchi 
 I'm not sure if RDRAND would always be available in a could-based CI. 
 We do not generate the seed ourselves, this is what SGX SDK does. We use  
 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. 
 I think anyone should be able to try our MinBFT implementation in simulation mode without any problem.  | 
    
| 
           @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. 
 sorry again. I just meant adding '#include " may be needed, but actually that introduces no problem. 
 OK, so nanosecond approach is better. 
 If you are OK, can I try this?  | 
    
| 
           @Naoya-Horiguchi 
 I'm not sure if  
 
 Please go ahead, I'll be focussed on implementing view change in MinBFT.  | 
    
| 
           @Naoya-Horiguchi Would it be anything to change in this pull request, or can we merge it?  | 
    
| 
           @sergefdrv I'm fine to merge this series, thank you for your effort!  | 
    

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:
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.