jbp.io Archive
11 June 2015

CVE-2015-1788: OpenSSL ECC binpoly denial of service

When parsing an ASN.1 ECParameters structure OpenSSL enters an infinite loop if the curve specified is over a specially malformed binary polynomial field.

This can be used to perform denial of service against any system which processes public keys, certificate requests or certificates. This includes TLS clients, TLS servers with client authentication enabled, and assorted offline certificate processing/issuance infrastructure.

PoC

$ curl https://binpoly.jbp.io:4433

or

$ openssl s_client -connect binpoly.jbp.io:4433

If you have an affected library, these commands will hang using lots of CPU. If you have a fixed library, you will get an error.

Note: this test server does not have a whole TLS stack. It talks just enough TLS to trigger the bug.

Disclosure timeline

Details

The following conditions are needed to trigger this bug:

  1. Invalid explitely-defined elliptic curve over a binary polynomial field. Named curves are not affected. Prime field curves are not affected. The polynomial should be irreducible mod 2; the bug is triggered when it is not.
  2. Compressed curve base point. The ECParameters processing code decompresses such points during parsing: this means the bug gets triggered earlier rather than later.

The bug itself is in BN_GF2m_mod_inv. This function contains a loop which will only complete if the polynomial it is operating over is irreducible.

Bug history

Discovery

The following trivial program parses a DER-encoded ECParameters structure.

#include <stdio.h>
#include <stdint.h>
#include <stdio.h>
#include <assert.h>

#include <openssl/ec.h>

int main(int argc, char **argv)
{
  unsigned char buf[1024];
  assert(argc == 2);
  FILE *f = fopen(argv[1], "rb");
  assert(f);
  size_t r = fread(buf, 1, 1024, f);
  printf("read = %zu\n", r);
  unsigned char *ptr = buf;
  EC_GROUP *ecg = d2i_ECPKParameters(NULL, &ptr, r);
  if (ecg)
    EC_GROUP_free(ecg);
  return 0;
}

This program and a few sample ECParameters encodings were given to American Fuzzy Lop. A full cycle took 22 hours.

Fork status

Original report