Ejemplo n.º 1
0
static void ec_GFp_simple_mul_single(const EC_GROUP *group, EC_RAW_POINT *r,
                                     const EC_RAW_POINT *p,
                                     const EC_SCALAR *scalar) {
  // This is a generic implementation for uncommon curves that not do not
  // warrant a tuned one. It uses unsigned digits so that the doubling case in
  // |ec_GFp_simple_add| is always unreachable, erring on safety and simplicity.

  // Compute a table of the first 32 multiples of |p| (including infinity).
  EC_RAW_POINT precomp[32];
  ec_GFp_simple_point_set_to_infinity(group, &precomp[0]);
  ec_GFp_simple_point_copy(&precomp[1], p);
  for (size_t j = 2; j < OPENSSL_ARRAY_SIZE(precomp); j++) {
    if (j & 1) {
      ec_GFp_simple_add(group, &precomp[j], &precomp[1], &precomp[j - 1]);
    } else {
      ec_GFp_simple_dbl(group, &precomp[j], &precomp[j / 2]);
    }
  }

  // Divide bits in |scalar| into windows.
  unsigned bits = BN_num_bits(&group->order);
  int r_is_at_infinity = 1;
  for (unsigned i = bits - 1; i < bits; i--) {
    if (!r_is_at_infinity) {
      ec_GFp_simple_dbl(group, r, r);
    }
    if (i % 5 == 0) {
      // Compute the next window value.
      const size_t width = group->order.width;
      uint8_t window = bn_is_bit_set_words(scalar->words, width, i + 4) << 4;
      window |= bn_is_bit_set_words(scalar->words, width, i + 3) << 3;
      window |= bn_is_bit_set_words(scalar->words, width, i + 2) << 2;
      window |= bn_is_bit_set_words(scalar->words, width, i + 1) << 1;
      window |= bn_is_bit_set_words(scalar->words, width, i);

      // Select the entry in constant-time.
      EC_RAW_POINT tmp;
      OPENSSL_memset(&tmp, 0, sizeof(EC_RAW_POINT));
      for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(precomp); j++) {
        BN_ULONG mask = constant_time_eq_w(j, window);
        ec_felem_select(group, &tmp.X, mask, &precomp[j].X, &tmp.X);
        ec_felem_select(group, &tmp.Y, mask, &precomp[j].Y, &tmp.Y);
        ec_felem_select(group, &tmp.Z, mask, &precomp[j].Z, &tmp.Z);
      }

      if (r_is_at_infinity) {
        ec_GFp_simple_point_copy(r, &tmp);
        r_is_at_infinity = 0;
      } else {
        ec_GFp_simple_add(group, r, r, &tmp);
      }
    }
  }
  if (r_is_at_infinity) {
    ec_GFp_simple_point_set_to_infinity(group, r);
  }
}
Ejemplo n.º 2
0
DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) {
  out->d = (BN_ULONG *) kSmallFactorsLimbs;
  out->top = OPENSSL_ARRAY_SIZE(kSmallFactorsLimbs);
  out->dmax = out->top;
  out->neg = 0;
  out->flags = BN_FLG_STATIC_DATA;
}
Ejemplo n.º 3
0
static const SSL_ECDH_METHOD *method_from_nid(int nid) {
  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMethods); i++) {
    if (kMethods[i].nid == nid) {
      return &kMethods[i];
    }
  }
  return NULL;
}
Ejemplo n.º 4
0
static const SSL_ECDH_METHOD *method_from_group_id(uint16_t group_id) {
  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMethods); i++) {
    if (kMethods[i].group_id == group_id) {
      return &kMethods[i];
    }
  }
  return NULL;
}
Ejemplo n.º 5
0
static const SSL_ECDH_METHOD *method_from_name(const char *name, size_t len) {
  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMethods); i++) {
    if (len == strlen(kMethods[i].name) &&
        !strncmp(kMethods[i].name, name, len)) {
      return &kMethods[i];
    }
  }
  return NULL;
}
Ejemplo n.º 6
0
int main(void) {
  uint8_t buf[82], prk[EVP_MAX_MD_SIZE];
  size_t i, prk_len;

  CRYPTO_library_init();

  for (i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) {
    const hkdf_test_vector_t *test = &kTests[i];
    if (!HKDF_extract(prk, &prk_len, test->md_func(), test->ikm, test->ikm_len,
                      test->salt, test->salt_len)) {
      fprintf(stderr, "Call to HKDF_extract failed\n");
      ERR_print_errors_fp(stderr);
      return 1;
    }
    if (prk_len != test->prk_len ||
        memcmp(prk, test->prk, test->prk_len) != 0) {
      fprintf(stderr, "%zu: Resulting PRK does not match test vector\n", i);
      return 1;
    }
    if (!HKDF_expand(buf, test->out_len, test->md_func(), prk, prk_len,
                     test->info, test->info_len)) {
      fprintf(stderr, "Call to HKDF_expand failed\n");
      ERR_print_errors_fp(stderr);
      return 1;
    }
    if (memcmp(buf, test->out, test->out_len) != 0) {
      fprintf(stderr,
              "%zu: Resulting key material does not match test vector\n", i);
      return 1;
    }

    if (!HKDF(buf, test->out_len, test->md_func(), test->ikm, test->ikm_len,
              test->salt, test->salt_len, test->info, test->info_len)) {
      fprintf(stderr, "Call to HKDF failed\n");
      ERR_print_errors_fp(stderr);
      return 1;
    }
    if (memcmp(buf, test->out, test->out_len) != 0) {
      fprintf(stderr,
              "%zu: Resulting key material does not match test vector\n", i);
      return 1;
    }
  }

  printf("PASS\n");
  ERR_free_strings();
  return 0;
}
Ejemplo n.º 7
0
static int parse_key_type(CBS *cbs, int *out_type) {
  CBS oid;
  if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) {
    return 0;
  }

  for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) {
    const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i];
    if (CBS_len(&oid) == method->oid_len &&
        OPENSSL_memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) {
      *out_type = method->pkey_id;
      return 1;
    }
  }

  return 0;
}
Ejemplo n.º 8
0
int tls13_process_certificate(SSL_HANDSHAKE *hs, int allow_anonymous) {
  SSL *const ssl = hs->ssl;
  CBS cbs, context, certificate_list;
  CBS_init(&cbs, ssl->init_msg, ssl->init_num);
  if (!CBS_get_u8_length_prefixed(&cbs, &context) ||
      CBS_len(&context) != 0) {
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return 0;
  }

  const int retain_sha256 =
      ssl->server && ssl->retain_only_sha256_of_client_certs;
  int ret = 0;

  EVP_PKEY *pkey = NULL;
  STACK_OF(CRYPTO_BUFFER) *certs = sk_CRYPTO_BUFFER_new_null();
  if (certs == NULL) {
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (!CBS_get_u24_length_prefixed(&cbs, &certificate_list)) {
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    goto err;
  }

  while (CBS_len(&certificate_list) > 0) {
    CBS certificate, extensions;
    if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) ||
        !CBS_get_u16_length_prefixed(&certificate_list, &extensions) ||
        CBS_len(&certificate) == 0) {
      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
      OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
      goto err;
    }

    if (sk_CRYPTO_BUFFER_num(certs) == 0) {
      pkey = ssl_cert_parse_pubkey(&certificate);
      if (pkey == NULL) {
        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
        goto err;
      }
      /* TLS 1.3 always uses certificate keys for signing thus the correct
       * keyUsage is enforced. */
      if (!ssl_cert_check_digital_signature_key_usage(&certificate)) {
        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
        goto err;
      }

      if (retain_sha256) {
        /* Retain the hash of the leaf certificate if requested. */
        SHA256(CBS_data(&certificate), CBS_len(&certificate),
               ssl->s3->new_session->peer_sha256);
      }
    }

    CRYPTO_BUFFER *buf =
        CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool);
    if (buf == NULL ||
        !sk_CRYPTO_BUFFER_push(certs, buf)) {
      CRYPTO_BUFFER_free(buf);
      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }

    /* Parse out the extensions. */
    int have_status_request = 0, have_sct = 0;
    CBS status_request, sct;
    const SSL_EXTENSION_TYPE ext_types[] = {
        {TLSEXT_TYPE_status_request, &have_status_request, &status_request},
        {TLSEXT_TYPE_certificate_timestamp, &have_sct, &sct},
    };

    uint8_t alert;
    if (!ssl_parse_extensions(&extensions, &alert, ext_types,
                              OPENSSL_ARRAY_SIZE(ext_types),
                              0 /* reject unknown */)) {
      ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
      goto err;
    }

    /* All Certificate extensions are parsed, but only the leaf extensions are
     * stored. */
    if (have_status_request) {
      if (ssl->server || !ssl->ocsp_stapling_enabled) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
        goto err;
      }

      uint8_t status_type;
      CBS ocsp_response;
      if (!CBS_get_u8(&status_request, &status_type) ||
          status_type != TLSEXT_STATUSTYPE_ocsp ||
          !CBS_get_u24_length_prefixed(&status_request, &ocsp_response) ||
          CBS_len(&ocsp_response) == 0 ||
          CBS_len(&status_request) != 0) {
        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        goto err;
      }

      if (sk_CRYPTO_BUFFER_num(certs) == 1 &&
          !CBS_stow(&ocsp_response, &ssl->s3->new_session->ocsp_response,
                    &ssl->s3->new_session->ocsp_response_length)) {
        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
        goto err;
      }
    }

    if (have_sct) {
      if (ssl->server || !ssl->signed_cert_timestamps_enabled) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
        goto err;
      }

      if (!ssl_is_sct_list_valid(&sct)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        goto err;
      }

      if (sk_CRYPTO_BUFFER_num(certs) == 1 &&
          !CBS_stow(&sct,
                    &ssl->s3->new_session->tlsext_signed_cert_timestamp_list,
                    &ssl->s3->new_session
                         ->tlsext_signed_cert_timestamp_list_length)) {
        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
        goto err;
      }
    }
  }

  if (CBS_len(&cbs) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    goto err;
  }

  EVP_PKEY_free(hs->peer_pubkey);
  hs->peer_pubkey = pkey;
  pkey = NULL;

  sk_CRYPTO_BUFFER_pop_free(ssl->s3->new_session->certs, CRYPTO_BUFFER_free);
  ssl->s3->new_session->certs = certs;
  certs = NULL;

  if (!ssl_session_x509_cache_objects(ssl->s3->new_session)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    goto err;
  }

  if (sk_CRYPTO_BUFFER_num(ssl->s3->new_session->certs) == 0) {
    if (!allow_anonymous) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED);
      goto err;
    }

    /* OpenSSL returns X509_V_OK when no certificates are requested. This is
     * classed by them as a bug, but it's assumed by at least NGINX. */
    ssl->s3->new_session->verify_result = X509_V_OK;

    /* No certificate, so nothing more to do. */
    ret = 1;
    goto err;
  }

  ssl->s3->new_session->peer_sha256_valid = retain_sha256;

  if (!ssl_verify_cert_chain(ssl, &ssl->s3->new_session->verify_result,
                             ssl->s3->new_session->x509_chain)) {
    goto err;
  }

  ret = 1;

err:
  sk_CRYPTO_BUFFER_pop_free(certs, CRYPTO_BUFFER_free);
  EVP_PKEY_free(pkey);
  return ret;
}
Ejemplo n.º 9
0
//   True
const BN_ULONG kBoringSSLRSASqrtTwo[] = {
    TOBN(0xdea06241, 0xf7aa81c2), TOBN(0xf6a1be3f, 0xca221307),
    TOBN(0x332a5e9f, 0x7bda1ebf), TOBN(0x0104dc01, 0xfe32352f),
    TOBN(0xb8cf341b, 0x6f8236c7), TOBN(0x4264dabc, 0xd528b651),
    TOBN(0xf4d3a02c, 0xebc93e0c), TOBN(0x81394ab6, 0xd8fd0efd),
    TOBN(0xeaa4a089, 0x9040ca4a), TOBN(0xf52f120f, 0x836e582e),
    TOBN(0xcb2a6343, 0x31f3c84d), TOBN(0xc6d5a8a3, 0x8bb7e9dc),
    TOBN(0x460abc72, 0x2f7c4e33), TOBN(0xcab1bc91, 0x1688458a),
    TOBN(0x53059c60, 0x11bc337b), TOBN(0xd2202e87, 0x42af1f4e),
    TOBN(0x78048736, 0x3dfa2768), TOBN(0x0f74a85e, 0x439c7b4a),
    TOBN(0xa8b1fe6f, 0xdc83db39), TOBN(0x4afc8304, 0x3ab8a2c3),
    TOBN(0xed17ac85, 0x83339915), TOBN(0x1d6f60ba, 0x893ba84c),
    TOBN(0x597d89b3, 0x754abe9f), TOBN(0xb504f333, 0xf9de6484),
};
const size_t kBoringSSLRSASqrtTwoLen = OPENSSL_ARRAY_SIZE(kBoringSSLRSASqrtTwo);

// generate_prime sets |out| to a prime with length |bits| such that |out|-1 is
// relatively prime to |e|. If |p| is non-NULL, |out| will also not be close to
// |p|. |sqrt2| must be ⌊2^(bits-1)×√2⌋ (or a slightly overestimate for large
// sizes), and |pow2_bits_100| must be 2^(bits-100).
static int generate_prime(BIGNUM *out, int bits, const BIGNUM *e,
                          const BIGNUM *p, const BIGNUM *sqrt2,
                          const BIGNUM *pow2_bits_100, BN_CTX *ctx,
                          BN_GENCB *cb) {
  if (bits < 128 || (bits % BN_BITS2) != 0) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    return 0;
  }
  assert(BN_is_pow2(pow2_bits_100));
  assert(BN_is_bit_set(pow2_bits_100, bits - 100));
Ejemplo n.º 10
0
static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group,
                                             EC_RAW_POINT *r,
                                             const EC_SCALAR *g_scalar,
                                             const EC_RAW_POINT *p,
                                             const EC_SCALAR *p_scalar) {
#define P256_WSIZE_PUBLIC 4
  // Precompute multiples of |p|. p_pre_comp[i] is (2*i+1) * |p|.
  fe p_pre_comp[1 << (P256_WSIZE_PUBLIC-1)][3];
  fe_from_generic(p_pre_comp[0][0], &p->X);
  fe_from_generic(p_pre_comp[0][1], &p->Y);
  fe_from_generic(p_pre_comp[0][2], &p->Z);
  fe p2[3];
  point_double(p2[0], p2[1], p2[2], p_pre_comp[0][0], p_pre_comp[0][1],
               p_pre_comp[0][2]);
  for (size_t i = 1; i < OPENSSL_ARRAY_SIZE(p_pre_comp); i++) {
    point_add(p_pre_comp[i][0], p_pre_comp[i][1], p_pre_comp[i][2],
              p_pre_comp[i - 1][0], p_pre_comp[i - 1][1], p_pre_comp[i - 1][2],
              0 /* not mixed */, p2[0], p2[1], p2[2]);
  }

  // Set up the coefficients for |p_scalar|.
  int8_t p_wNAF[257];
  ec_compute_wNAF(group, p_wNAF, p_scalar, 256, P256_WSIZE_PUBLIC);

  // Set |ret| to the point at infinity.
  int skip = 1;  // Save some point operations.
  fe ret[3] = {{0},{0},{0}};
  for (int i = 256; i >= 0; i--) {
    if (!skip) {
      point_double(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2]);
    }

    // For the |g_scalar|, we use the precomputed table without the
    // constant-time lookup.
    if (i <= 31) {
      // First, look 32 bits upwards.
      uint64_t bits = get_bit(g_scalar->bytes, i + 224) << 3;
      bits |= get_bit(g_scalar->bytes, i + 160) << 2;
      bits |= get_bit(g_scalar->bytes, i + 96) << 1;
      bits |= get_bit(g_scalar->bytes, i + 32);
      point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], 1 /* mixed */,
                g_pre_comp[1][bits][0], g_pre_comp[1][bits][1],
                g_pre_comp[1][bits][2]);
      skip = 0;

      // Second, look at the current position.
      bits = get_bit(g_scalar->bytes, i + 192) << 3;
      bits |= get_bit(g_scalar->bytes, i + 128) << 2;
      bits |= get_bit(g_scalar->bytes, i + 64) << 1;
      bits |= get_bit(g_scalar->bytes, i);
      point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], 1 /* mixed */,
                g_pre_comp[0][bits][0], g_pre_comp[0][bits][1],
                g_pre_comp[0][bits][2]);
    }

    int digit = p_wNAF[i];
    if (digit != 0) {
      assert(digit & 1);
      int idx = digit < 0 ? (-digit) >> 1 : digit >> 1;
      fe *y = &p_pre_comp[idx][1], tmp;
      if (digit < 0) {
        fe_opp(tmp, p_pre_comp[idx][1]);
        y = &tmp;
      }
      if (!skip) {
        point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2],
                  0 /* not mixed */, p_pre_comp[idx][0], *y, p_pre_comp[idx][2]);
      } else {
        fe_copy(ret[0], p_pre_comp[idx][0]);
        fe_copy(ret[1], *y);
        fe_copy(ret[2], p_pre_comp[idx][2]);
        skip = 0;
      }
    }
  }