Merge branch '2.5.x' into HEAD
authorMark Wooding <mdw@distorted.org.uk>
Sat, 23 Dec 2023 14:33:00 +0000 (14:33 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 23 Dec 2023 14:33:00 +0000 (14:33 +0000)
* 2.5.x:
  rand/rand.c (rand_gate): Evolve r->ibits in a more sensible manner.
  rand/rand.c (rand_getgood): Stretch the output buffer if necessary.

1  2 
rand/rand.c

diff --combined rand/rand.c
@@@ -161,17 -161,24 +161,17 @@@ CPU_DISPATCH(static, return, int, quick
  
  static int trivial_quick(rand_pool *r) { return (-1); }
  
 -#if __GNUC__ && (CPUFAM_X86 || CPUFAM_AMD64)
 -static int rdrand_quick(rand_pool *r)
 -{
 -  unsigned long rr;
 -  int i = 16;
 -
 -  __asm__ ("0: rdrand %0; jc 9f; dec %1; jnz 0b; 9:"
 -         : "=r" (rr), "=r" (i) : "1" (i) : "cc");
 -  if (!i) return (-1);
 -  rand_add(r, &rr, sizeof(rr), 8*sizeof(rr));
 -  return (0);
 -}
 +#if CPUFAM_X86 || CPUFAM_AMD64
 +extern int rand_quick_x86ish_rdrand(rand_pool */*r*/);
 +extern int rand_quick_x86ish_rdseed(rand_pool */*r*/);
  #endif
  
  static quick__functype *pick_quick(void)
  {
 -#if __GNUC__ && (CPUFAM_X86 || CPUFAM_AMD64)
 -  DISPATCH_PICK_COND(rand_quick, rdrand_quick,
 +#if CPUFAM_X86 || CPUFAM_AMD64
 +  DISPATCH_PICK_COND(rand_quick, rand_quick_x86ish_rdseed,
 +                   cpu_feature_p(CPUFEAT_X86_RDSEED));
 +  DISPATCH_PICK_COND(rand_quick, rand_quick_x86ish_rdrand,
                     cpu_feature_p(CPUFEAT_X86_RDRAND));
  #endif
    DISPATCH_PICK_FALLBACK(rand_quick, trivial_quick);
@@@ -254,7 -261,9 +254,7 @@@ void rand_add(rand_pool *r, const void 
    const octet *c = p;
    int i, rot;
  
 -#if RAND_POOLSZ != 128
 -#  error Polynomial in rand_add is out of date.  Fix it.
 -#endif
 +  STATIC_ASSERT(RAND_POOLSZ == 128, "Polynomial doesn't match pool size");
  
    RAND_RESOLVE(r);
  
@@@ -307,8 -316,6 +307,8 @@@ void rand_gate(rand_pool *r
    HASH_CTX hc;
    CIPHER_CTX cc;
  
 +  STATIC_ASSERT(CIPHER_KEYSZ <= HASH_SZ, "rand cipher keysize too long");
 +
    RAND_RESOLVE(r);
    QUICK(r);
  
  
    /* --- Now mangle all of the data based on the hash --- */
  
 -  assert(CIPHER_KEYSZ <= HASH_SZ);
    CIPHER_INIT(&cc, h, CIPHER_KEYSZ, 0);
    CIPHER_ENCRYPT(&cc, r->pool, r->pool, RAND_POOLSZ);
    CIPHER_ENCRYPT(&cc, r->buf, r->buf, RAND_BUFSZ);
    r->o = RAND_SECSZ;
    r->obits += r->ibits;
    if (r->obits > RAND_OBITS) {
-     r->ibits = r->obits - r->ibits;
+     r->ibits = r->obits - RAND_OBITS;
      r->obits = RAND_OBITS;
    } else
      r->ibits = 0;
@@@ -359,8 -367,6 +359,8 @@@ void rand_stretch(rand_pool *r
    HASH_CTX hc;
    CIPHER_CTX cc;
  
 +  STATIC_ASSERT(CIPHER_KEYSZ <= HASH_SZ, "rand cipher keysize too long");
 +
    RAND_RESOLVE(r);
    QUICK(r);
  
  
    /* --- Now mangle the buffer based on the hash --- */
  
 -  assert(CIPHER_KEYSZ <= HASH_SZ);
    CIPHER_INIT(&cc, h, CIPHER_KEYSZ, 0);
    CIPHER_ENCRYPT(&cc, r->buf, r->buf, RAND_BUFSZ);
    BURN(cc);
@@@ -475,11 -482,15 +475,15 @@@ void rand_getgood(rand_pool *r, void *p
        chunk = r->obits / 8;
      }
  
-     if (chunk + r->o > RAND_BUFSZ)
+     if (chunk + r->o <= RAND_BUFSZ) {
+       memcpy(o, r->buf + r->o, chunk);
+       r->o += chunk;
+     } else {
        chunk = RAND_BUFSZ - r->o;
+       memcpy(o, r->buf + r->o, chunk);
+       rand_stretch(r);
+     }
  
-     memcpy(o, r->buf + r->o, chunk);
-     r->o += chunk;
      r->obits -= chunk * 8;
      o += chunk;
      sz -= chunk;