[PATCH] Adding diversity for security

Tom Roeder tmroeder at google.com
Wed Oct 9 14:53:03 PDT 2013


  I'm glad you were able to set up the OpenSSL locking. I have a few comments on the code; see below. My high-level comment about the algorithm is that it looks like this is not an exact implementation of of SP 800-90A; see my comments for some (not all) of the differences.

  Also, someone familiar with the details of the X86 Target and other backend code should look at this, too, since I don't know much about the backend details.


================
Comment at: include/llvm/Support/RandomNumberGenerator.h:17
@@ +16,3 @@
+
+#ifndef RANDOMNUMBERGENERATOR_H_
+#define RANDOMNUMBERGENERATOR_H_
----------------
This should follow the style LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H (see other files in include/llvm)

================
Comment at: include/llvm/Support/RandomNumberGenerator.h:69
@@ +68,3 @@
+    uint64_t r;
+    while ((r = Random()) >= t) { /* NOOP */ }
+
----------------
Looks like the style here should be a semi-colon alone on a line. See, e.g., lib/CodeGen/MachineBasicBlock.cpp around the changes in this diff.

================
Comment at: include/llvm/Target/TargetOptions.h:53-55
@@ -52,4 +52,5 @@
           EnableFastISel(false), PositionIndependentExecutable(false),
-          EnableSegmentedStacks(false), UseInitArray(false), TrapFuncName(""),
-          FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard)
+          EnableSegmentedStacks(false), NOPInsertion(false), UseInitArray(false),
+          TrapFuncName(""), FloatABIType(FloatABI::Default),
+          AllowFPOpFusion(FPOpFusion::Standard)
     {}
----------------
It looks like this diff is missing at least one place that uses TargetOptions: in tools/lto/lto.cpp, there is a function lto_set_target_options that sets values in TargetOptions based on the command-line flags. Please change that too.

================
Comment at: lib/Support/RandomNumberGenerator.cpp:77-80
@@ +76,6 @@
+/// CTR_DRBG random number generator, with AES128 as the block
+/// cipher. In addition, the initial seed and additional entropy from
+/// the list of command-line arguments are ran through a standard
+/// PBKDF2 key stretching algorithm to produce enough bits to
+/// initialize the RNG.
+class OpenSSLRandomNumberGenerator : public RandomNumberGenerator {
----------------
You should probably note, then, that the entropy here depends almost entirely on the entropy in the seed, since the command-line arguments aren't going to have much, I assume. Do you have a sense of how many bits of entropy are needed here to make this construction secure in a given context?

>From Table 3 in SP 800-90A, it looks like the minimum entropy required for the construction that uses a key derivation function is the required security strength.

================
Comment at: lib/Support/RandomNumberGenerator.cpp:91-92
@@ +90,4 @@
+  // Noncopyable.
+  OpenSSLRandomNumberGenerator(const OpenSSLRandomNumberGenerator &other) LLVM_DELETED_FUNCTION;
+  OpenSSLRandomNumberGenerator &operator=(const OpenSSLRandomNumberGenerator &other) LLVM_DELETED_FUNCTION;
+
----------------
80-char limit (here and in a couple other places). Maybe reformat with clang-format --style=LLVM ?

================
Comment at: lib/Target/X86/NOPInsertion.cpp:103
@@ +102,3 @@
+        MachineInstr *NewMI = NULL;
+        unsigned reg = nopRegs[NOPCode][!!is64Bit];
+        switch (NOPCode) {
----------------
!! on bool is unnecessary

================
Comment at: tools/opt/opt.cpp:600-609
@@ -597,2 +599,12 @@
 
+  // Seed the RNG
+  std::string SeedData;
+  // If entropy already set (for predictable testing), ignore
+  if (RandomNumberGenerator::EntropyData.empty()) {
+    for (int i = 0; i < argc; ++i) {
+      SeedData += argv[i];
+    }
+    RandomNumberGenerator::EntropyData = SeedData;
+  }
+
   if (AnalyzeOnly && NoOutput) {
----------------
I think something similar to this will have to be added to llvm-lto to support nop code generation there, too. Maybe instead of repeating the same snippet everywhere, you could make this a function in RandomNumberGenerator. Something like AddSeedData?

================
Comment at: lib/Support/RandomNumberGenerator.cpp:153-154
@@ +152,4 @@
+    unsigned char Output[AES_BLOCK_SIZE];
+    AES_ctr128_encrypt(Plaintext, Output, AES_BLOCK_SIZE, &AESKey, IV,
+                       EcountBuffer, &Num);
+
----------------
See the description of the CTR_DRBG algorithm on page 58-59 of NIST SP 800-90A: the randomness generation process also needs to call an update function to change the secret state, including the key, each time. This is step 6 of CTR_DRBG Generate Process.

Also, it looks like there is supposed to be a reseed count that forces reseeding after a certain interval. Table 3 in SP 800-90A gives the recommended number of iterations for a given security strength.

================
Comment at: lib/Support/RandomNumberGenerator.cpp:112
@@ +111,3 @@
+    unsigned KeyLen = AES_KEY_LENGTH + 2*AES_BLOCK_SIZE;
+    unsigned char *SeedBuffer = new unsigned char[KeyLen];
+
----------------
AFAICT from SP 800-90A, the initial key is supposed to be 0, and subsequent reseeding  operations are supposed to use the existing key to generate a new one.


http://llvm-reviews.chandlerc.com/D1802



More information about the llvm-commits mailing list