EuCrypt: Additional Check and a Note on Cosmetic Changes

March 15th, 2018 by Diana Coman

~ This is part of the EuCrypt series. Start with Introducing EuCrypt. ~

A very useful comment by Arjen (ave1) at my previous post on EuCrypt prompted me to have another look at all calls for random bits from the entropy source, throughout EuCrypt. As Arjen mentioned, it turns out that there is one lonely call for which the potential error flag (the number of octets read) is not directly checked by the caller. Since this is a sensitive issue (the call is in primegen.c precisely when attempting to find randomly a large prime number), I am adding this missing check there. As a result, EuCrypt's behaviour is now entirely uniform in this respect: any time EuCrypt requests a number of random bits from the entropy source, it does so in a loop, discarding any output that is less than/different from what it requested and insisting with the requests until satisfied.

The .vpatch contains the small change to the code, basically a loop around the request for random bits from the entropy source. To ensure that the whole V tree of EuCrypt remains neatly with a single leaf, namely this patch, I added also a short comment to the README file of EuCrypt stating this design principle of trying for as long as needed: "NB: EuCrypt aims to *keep trying* to accomplish a task. In particular, when entropy is needed, it will keep asking for as many random bits as it needs from the configured entropy source and it will not proceed unless those are provided." The change to the code is clear enough from the .vpatch itself:

+  int nread;
 	do {
-		get_random_octets_from( noctets, p, entropy_source );
+    do {
+      nread = get_random_octets_from( noctets, p, entropy_source );
+    } while ( nread != noctets );

Note that one can legitimately raise the concern (as Arjen did) that an inaccessible/in error state entropy source can therefore result in an infinite loop. This is true and it is intended behaviour: the entropy source is part of the environment in which EuCrypt runs and looking after it is outside of the scope of EuCrypt itself. Moreover, a working (and reliable) entropy source is simply a crucial pre-requisite for the tasks of EuCrypt and therefore I do not want it to proceed with anything at all when this pre-requisite is not met. An alternative solution would be to simply abort whatever EuCrypt was trying to do, as soon as the entropy source fails to provide the requested bits. However, this effectively means that EuCrypt will need to be restarted even if the environment is set up so that access to the entropy source is re-established. Basically this would add the restarting of EuCrypt and potential recovery of previous work as an additional task for the environment manager (whatever that might be) and I don't see at the moment the case for this. I'd much rather have EuCrypt keep trying, simply and stubbornly until the conditions are met and it can proceed with what it had to do. Should the caller prefer otherwise, they can of course have their own mechanisms in place and make their own decisions as to recovery options if the call to EuCrypt takes longer than they are willing to wait for. What EuCrypt promises is simple: it will NOT proceed with fewer random bits than it needs and it will KEEP trying to get them for as long as it takes or until it gets killed by the caller/outside forces.

It might be worth mentioning at this point that the design decision to re-open the entropy source for requests that are not made by the same caller / block of code provides also a bit of support for this approach of keep-trying-until-it-works-no-matter-what: as long as the string identifier for the entropy source is the same, the physical source can change seamlessly between uses by EuCrypt.

On a different, lighter note, having looked at a potential cosmetic patch to the whole library to replace all tabs with spaces and to ensure *everywhere* strict adherence to the coding style1 introduced midway through development, I can say that such a patch will weigh in at more than 2k lines for non-mpi components only, going above 9k lines when mpi is included as well. As such, I'm really in two minds whether it would be more useful than annoying. Perhaps have your say on this matter if you feel strongly about the tabs-to-spaces and 80 columns rule. Before you do, note however that all code written after those rules were adopted is already following them, of course. This being said, a review of the code is good at any time and the need for cosmetic changes is as good a time as any if not even better than many.

The eucrypt_check_nread.vpatch and my signature for it are as usual on my Reference Code Shelf and linked here as well, for your convenience:

  1. maximum 80 columns per line and various alignments 

Comments feed: RSS 2.0

Leave a Reply