I believe I have found a method by which a rogue Iroha peer would be able to sign a block any required number of times, using its own keypair, in a manner that would pass chain validation.
The attack method is not yet fully proven, however I’ve been able to demonstrate multiple signing of a proposal, and the code for validating blocks is sufficiently similar that I can find no reason why the same method would not be applicable. In any event. I’d still like to create a working proof of concept if that is possible, but I’m badly out of time so far as the Nettitude assessment of Iroha is concerned, and I don’t think I’ll be able to do that without assistance from those more familiar with the code.
I’m nervous about saying this, in case there turns out to be a flaw in the method, but I suspect the impact of this finding would be “critical” if it fully checks out.
I’ve not entered this into Jira yet, since the submission form I have access to appears to lack the field needed to mark it as a security issue.
In outline, the method is as follows.
The root cause is that when signatures are assembled into a set, they are considered distinct if either (a) the public keys are different or (b) the cryptographic signature blobs are different. Furthermore, in order to determine how many signatures have been applied, the method used is to simply count the number of signatures in the set. The unspoken assumption is that if the same keypair is used to sign the same data more than once, then the signature blobs will be identical and will not therefore be counted separately once they have been added to the set.
This is all well and good for a standard implementation of ed25519, because (unlike most digital signature algorithms) it uses a ‘deterministic nonce’ – specifically, instead of generating a block of random data, it instead uses a deterministic hash based on the input parameters. So, if you repeatedly sign the same data with the same keypair, using standard ed25519, you will get the same signature blob every time.
However, whilst the specification says that you are supposed to use this deterministic method, the data in question is just functioning as a nonce – and the algorithm will continue working quite happily if you choose something different, like a random number. So, what I did was modify a copy of the iroha-ed25519 library to do this, build and install it, and then build Iorha against that library. The result is that if you then have Iroha sign something twice, the two signature blobs are different.
Now, you might ask why I’m considering it an attack if the attacker needs to tamper with the crypto implementation. The reason is that he need only do this on the node that he wants to turn malicious. The other nodes in the network can carry on running with unmodified crypto, and they will be able to correctly verify signatures regardless of whether it was the tampered or untampered implementation used to generate them. (In other words, it is only the signing function which needs to be modified – not the verification function.)
To confirm this, Nettitude arranged for a new proposal to be signed three times by the same account, then submitted to the Iroha daemon. The proposal passed validation, with signatures.size() equal to 3 inside the function StatefulValidatorImpl::signaturesSubset. This goes most of the way to showing that the security of multi-signatory accounts can be violated (corresponding to issue
IR-2, which has been put into Jira). However, it appears likely that the same can be done for blocks – with much more serious consequences.
The mitigation is to check, by one means or another, that the public keys in a given set of signatures are distinct – not merely that the combination of signatures and public keys are distinct.
I need to finish the writeup for the security assessment now, but if someone familiar with the code were able to take an initial view on the viability and severity of this attack method in the next couple of days then that would be most helpful. Also, if it were possible to talk me through the data flow for signing a block – with a view to adding some additional, illicit signatures – then I can have another go at a proof of concept.
(Finally, if this does check out, Nettitude would be most grateful if a CVE number could be allocated – I understand you have a process for arranging this.)