[Cryptography] tail recursion in C [was Re: "NSA-linked Cisco exploit poses bigger threat than previously thought"]

Henry Baker hbaker1 at pipeline.com
Sat Aug 27 12:00:51 EDT 2016


At 09:31 PM 8/26/2016, D. Hugh Redelmeier wrote:
>| From: Ron Garret <ron at flownet.com>
>
>|  You can't GOTO a label outside of the current function.  That 
>| makes it impossible to implement tail recursion in pure C unless you 
>| compile your entire program into a single C function.
>
>If the last act of a function is to call another function, that call
>can be compiled as a goto (plus some conversion of the current
>function's activation record into the parameters for the new
>function).  Tail recursion optimization is a special case of this.
>
>This is purely an implementation feature.  I cannot think of anything
>in C that precludes this optimization.  Just culture?
>
>This optimization confuses programmers trying to debug the result,
>but then so do many optimizations.
>
>Slide to crypto relevance:
>
>Optimization can destroy some properties that one might have
>intentionally coded into a program.
>
>If you carefully coded all paths through a loop to take the same time (to 
>avoid timing sidechannel attacks) an optimizer might re-introduce them.  
>
>If you clear variables to avoid having sensitive values laying around, an 
>optimizer might detect that the clearing is redundant and eliminate it.
>
>GCC optimization has been known to eliminate assert calls that would
>have fired.  Technically, these optimizations were correct but the
>result was unsafe for human programmers.  Roughly, if your code
>dereferences a pointer, that tells the compiler that it may assume
>that the pointer is non-Null; a subsequent test of that pointer for
>NULL may then be assumed to yield false.

There are clever ways to do "tail recursion" in C:

http://home.pipeline.com/~hbaker1/CheneyMTA.html

http://home.pipeline.com/~hbaker1/CheneyMTA.pdf

Although my paper doesn't provide the particular optimization in the
Gnu C compiler, there is (or used to be!) a switch that tells the Gnu
C compiler that certain calls aren't coming back, so don't bother
emitting any more code.

(Note also that the Intel x86 -- and most likely the x64, as well --
includes a hardware lookaside cache that attempts to avoid memory
references for stack pushes & pops for return addresses.  This cache
will get totally discombobulated if you use x86 stack instructions
for non-nested behavior.  Furthermore, there are some new architectural
"features" that attempt to outlaw non-nested behavior completely, in
order to try to stop "return-oriented programming" (ROP) which is
more-and-more utilized for exploits.)



More information about the cryptography mailing list