Beispiel #1
0
int RAND_bytes(uint8_t *out, size_t out_len) {
  static const uint8_t kZeroAdditionalData[32] = {0};
  RAND_bytes_with_additional_data(out, out_len, kZeroAdditionalData);
  return 1;
}
Beispiel #2
0
static int bn_rand_with_additional_data(BIGNUM *rnd, int bits, int top,
                                        int bottom,
                                        const uint8_t additional_data[32]) {
  uint8_t *buf = NULL;
  int ret = 0, bit, bytes, mask;

  if (rnd == NULL) {
    return 0;
  }

  if (top != BN_RAND_TOP_ANY && top != BN_RAND_TOP_ONE &&
      top != BN_RAND_TOP_TWO) {
    OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  if (bottom != BN_RAND_BOTTOM_ANY && bottom != BN_RAND_BOTTOM_ODD) {
    OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  if (bits == 0) {
    BN_zero(rnd);
    return 1;
  }

  bytes = (bits + 7) / 8;
  bit = (bits - 1) % 8;
  mask = 0xff << (bit + 1);

  buf = OPENSSL_malloc(bytes);
  if (buf == NULL) {
    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  /* Make a random number and set the top and bottom bits. */
  RAND_bytes_with_additional_data(buf, bytes, additional_data);

  if (top != BN_RAND_TOP_ANY) {
    if (top == BN_RAND_TOP_TWO && bits > 1) {
      if (bit == 0) {
        buf[0] = 1;
        buf[1] |= 0x80;
      } else {
        buf[0] |= (3 << (bit - 1));
      }
    } else {
      buf[0] |= (1 << bit);
    }
  }

  buf[0] &= ~mask;

  /* Set the bottom bit if requested, */
  if (bottom == BN_RAND_BOTTOM_ODD)  {
    buf[bytes - 1] |= 1;
  }

  if (!BN_bin2bn(buf, bytes, rnd)) {
    goto err;
  }

  ret = 1;

err:
  if (buf != NULL) {
    OPENSSL_cleanse(buf, bytes);
    OPENSSL_free(buf);
  }
  return (ret);
}