[efi] Distribute available entropy within stack cookie

Several of the values used to compute a stack cookie (in the absence
of a viable entropy source) will tend to have either all-zeroes or
all-ones in the higher order bits.  Rotate the values in order to
distribute the (minimal) available entropy more evenly.

Suggested-by: Pete Beck <pete.beck@ioactive.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
diff --git a/src/interface/efi/efi_init.c b/src/interface/efi/efi_init.c
index df46bb1..284c39b 100644
--- a/src/interface/efi/efi_init.c
+++ b/src/interface/efi/efi_init.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <errno.h>
 #include <ipxe/init.h>
+#include <ipxe/rotate.h>
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/efi_driver.h>
 #include <ipxe/efi/Protocol/LoadedImage.h>
@@ -105,19 +106,29 @@
  */
 __attribute__ (( noinline )) unsigned long
 efi_stack_cookie ( EFI_HANDLE handle ) {
+	unsigned long cookie = 0;
+	unsigned int rotation = ( 8 * sizeof ( cookie ) / 4 );
 
 	/* There is no viable source of entropy available at this
 	 * point.  Construct a value that is at least likely to vary
 	 * between platforms and invocations.
-	 *
-	 * Ensure that the value contains a NUL byte, to act as a
+	 */
+	cookie ^= ( ( unsigned long ) handle );
+	cookie = roll ( cookie, rotation );
+	cookie ^= ( ( unsigned long ) &handle );
+	cookie = roll ( cookie, rotation );
+	cookie ^= profile_timestamp();
+	cookie = roll ( cookie, rotation );
+	cookie ^= build_id;
+
+	/* Ensure that the value contains a NUL byte, to act as a
 	 * runaway string terminator.  Construct the NUL using a shift
 	 * rather than a mask, to avoid losing valuable entropy in the
-	 * low-order bits.
+	 * lower-order bits.
 	 */
-	return ( ( ( ( unsigned long ) handle ) ^
-		   ( ( unsigned long ) &handle ) ^
-		   profile_timestamp() ^ build_id ) << 8 );
+	cookie <<= 8;
+
+	return cookie;
 }
 
 /**