Beispiel #1
0
int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx,
                            int do_trial_division, BN_GENCB *cb) {
  if (BN_cmp(a, BN_value_one()) <= 0) {
    return 0;
  }

  /* first look for small factors */
  if (!BN_is_odd(a)) {
    /* a is even => a is prime if and only if a == 2 */
    return BN_is_word(a, 2);
  }

  /* Enhanced Miller-Rabin does not work for three. */
  if (BN_is_word(a, 3)) {
    return 1;
  }

  if (do_trial_division) {
    for (int i = 1; i < NUMPRIMES; i++) {
      BN_ULONG mod = BN_mod_word(a, primes[i]);
      if (mod == (BN_ULONG)-1) {
        return -1;
      }
      if (mod == 0) {
        return BN_is_word(a, primes[i]);
      }
    }

    if (!BN_GENCB_call(cb, 1, -1)) {
      return -1;
    }
  }

  int ret = -1;
  BN_CTX *ctx_allocated = NULL;
  if (ctx == NULL) {
    ctx_allocated = BN_CTX_new();
    if (ctx_allocated == NULL) {
      return -1;
    }
    ctx = ctx_allocated;
  }

  enum bn_primality_result_t result;
  if (!BN_enhanced_miller_rabin_primality_test(&result, a, checks, ctx, cb)) {
    goto err;
  }

  ret = (result == bn_probably_prime);

err:
  BN_CTX_free(ctx_allocated);
  return ret;
}
Beispiel #2
0
int RSA_check_fips(RSA *key) {
  if (RSA_is_opaque(key)) {
    /* Opaque keys can't be checked. */
    OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
    return 0;
  }

  if (!RSA_check_key(key)) {
    return 0;
  }

  BN_CTX *ctx = BN_CTX_new();
  if (ctx == NULL) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    return 0;
  }

  BIGNUM small_gcd;
  BN_init(&small_gcd);

  int ret = 1;

  /* Perform partial public key validation of RSA keys (SP 800-89 5.3.3). */
  enum bn_primality_result_t primality_result;
  if (BN_num_bits(key->e) <= 16 ||
      BN_num_bits(key->e) > 256 ||
      !BN_is_odd(key->n) ||
      !BN_is_odd(key->e) ||
      !BN_gcd(&small_gcd, key->n, g_small_factors(), ctx) ||
      !BN_is_one(&small_gcd) ||
      !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n,
                                               BN_prime_checks, ctx, NULL) ||
      primality_result != bn_non_prime_power_composite) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
    ret = 0;
  }

  BN_free(&small_gcd);
  BN_CTX_free(ctx);

  if (!ret || key->d == NULL || key->p == NULL) {
    /* On a failure or on only a public key, there's nothing else can be
     * checked. */
    return ret;
  }

  /* FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG,
   * section 9.9, it is not known whether |rsa| will be used for signing or
   * encryption, so either pair-wise consistency self-test is acceptable. We
   * perform a signing test. */
  uint8_t data[32] = {0};
  unsigned sig_len = RSA_size(key);
  uint8_t *sig = OPENSSL_malloc(sig_len);
  if (sig == NULL) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    return 0;
  }

  if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    ret = 0;
    goto cleanup;
  }
#if defined(BORINGSSL_FIPS_BREAK_RSA_PWCT)
  data[0] = ~data[0];
#endif
  if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    ret = 0;
  }

cleanup:
  OPENSSL_free(sig);

  return ret;
}