Esempio n. 1
0
int CRYPTO_set_thread_local(thread_local_data_t index, void *value,
                            thread_local_destructor_t destructor) {
  CRYPTO_once(&g_thread_local_init_once, thread_local_init);
  if (g_thread_local_failed) {
    destructor(value);
    return 0;
  }

  void **pointers = pthread_getspecific(g_thread_local_key);
  if (pointers == NULL) {
    pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS);
    if (pointers == NULL) {
      destructor(value);
      return 0;
    }
    memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS);
    if (pthread_setspecific(g_thread_local_key, pointers) != 0) {
      OPENSSL_free(pointers);
      destructor(value);
      return 0;
    }
  }

  if (pthread_mutex_lock(&g_destructors_lock) != 0) {
    destructor(value);
    return 0;
  }
  g_destructors[index] = destructor;
  pthread_mutex_unlock(&g_destructors_lock);

  pointers[index] = value;
  return 1;
}
Esempio n. 2
0
int CRYPTO_set_thread_local(thread_local_data_t index, void *value,
                            thread_local_destructor_t destructor) {
  CRYPTO_once(&g_thread_local_init_once, thread_local_init);
  if (g_thread_local_failed) {
    destructor(value);
    return 0;
  }

  void **pointers = TlsGetValue(g_thread_local_key);
  if (pointers == NULL) {
    pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS);
    if (pointers == NULL) {
      destructor(value);
      return 0;
    }
    memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS);
    if (TlsSetValue(g_thread_local_key, pointers) == 0) {
      OPENSSL_free(pointers);
      destructor(value);
      return 0;
    }
  }

  EnterCriticalSection(&g_destructors_lock);
  g_destructors[index] = destructor;
  LeaveCriticalSection(&g_destructors_lock);

  pointers[index] = value;
  return 1;
}
Esempio n. 3
0
static void NTAPI thread_local_destructor(PVOID module,
                                          DWORD reason, PVOID reserved) {
  (void)module;
  (void)reserved;

  if (DLL_THREAD_DETACH != reason && DLL_PROCESS_DETACH != reason) {
    return;
  }

  CRYPTO_once(&g_thread_local_init_once, thread_local_init);
  if (g_thread_local_failed) {
    return;
  }

  void **pointers = (void**) TlsGetValue(g_thread_local_key);
  if (pointers == NULL) {
    return;
  }

  thread_local_destructor_t destructors[NUM_OPENSSL_THREAD_LOCALS];

  EnterCriticalSection(&g_destructors_lock);
  memcpy(destructors, g_destructors, sizeof(destructors));
  LeaveCriticalSection(&g_destructors_lock);

  unsigned i;
  for (i = 0; i < NUM_OPENSSL_THREAD_LOCALS; i++) {
    if (destructors[i] != NULL) {
      destructors[i](pointers[i]);
    }
  }

  OPENSSL_free(pointers);
}
Esempio n. 4
0
void RAND_enable_fork_unsafe_buffering(int fd) {
  if (fd >= 0) {
    fd = dup(fd);
    if (fd < 0) {
      abort();
    }
  } else {
    fd = kUnset;
  }

  CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
  urandom_buffering_requested = 1;
  urandom_fd_requested = fd;
  CRYPTO_STATIC_MUTEX_unlock_write(&requested_lock);

  CRYPTO_once(&once, init_once);
  if (urandom_buffering != 1) {
    abort();  // Already initialized
  }

  if (fd >= 0) {
    if (urandom_fd == kHaveGetrandom) {
      close(fd);
    } else if (urandom_fd != fd) {
      abort();  // Already initialized.
    }
  }
}
Esempio n. 5
0
void CRYPTO_library_init(void) {
  // TODO(davidben): It would be tidier if this build knob could be replaced
  // with an internal lazy-init mechanism that would handle things correctly
  // in-library. https://crbug.com/542879
#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
  CRYPTO_once(&once, do_library_init);
#endif
}
Esempio n. 6
0
void *CRYPTO_get_thread_local(thread_local_data_t index) {
  CRYPTO_once(&g_thread_local_init_once, thread_local_init);
  if (g_thread_local_failed) {
    return NULL;
  }

  void **pointers = TlsGetValue(g_thread_local_key);
  if (pointers == NULL) {
    return NULL;
  }
  return pointers[index];
}
Esempio n. 7
0
void RAND_set_urandom_fd(int fd) {
  fd = dup(fd);
  if (fd < 0) {
    abort();
  }

  CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
  urandom_fd_requested = fd;
  CRYPTO_STATIC_MUTEX_unlock_write(&requested_lock);

  CRYPTO_once(&once, init_once);
  if (urandom_fd == kHaveGetrandom) {
    close(fd);
  } else if (urandom_fd != fd) {
    abort();  // Already initialized.
  }
}
Esempio n. 8
0
/* CRYPTO_sysrand puts |requested| random bytes into |out|. */
void CRYPTO_sysrand(uint8_t *out, size_t requested) {
  if (requested == 0) {
    return;
  }

  CRYPTO_once(&once, init_once);
  if (urandom_buffering && requested < BUF_SIZE) {
    struct rand_buffer *buf = get_thread_local_buffer();
    if (buf != NULL) {
      read_from_buffer(buf, out, requested);
      return;
    }
  }

  if (!fill_with_entropy(out, requested)) {
    abort();
  }
}
Esempio n. 9
0
static int test_once(void) {
  if (g_once_init_called != 0) {
    fprintf(stderr, "g_once_init_called was non-zero at start.\n");
    return 0;
  }

  thread_t thread;
  if (!run_thread(&thread, call_once_thread) ||
      !wait_for_thread(thread)) {
    fprintf(stderr, "thread failed.\n");
    return 0;
  }

  CRYPTO_once(&g_test_once, once_init);

  if (g_once_init_called != 1) {
    fprintf(stderr, "Expected init function to be called once, but found %u.\n",
            g_once_init_called);
    return 0;
  }

  return 1;
}
Esempio n. 10
0
static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
  const struct built_in_curve *curve = &OPENSSL_built_in_curves[built_in_index];
  EC_GROUP *group = NULL;
  EC_POINT *P = NULL;
  BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
  const EC_METHOD *meth;
  int ok = 0;

  BN_CTX *ctx = BN_CTX_new();
  if (ctx == NULL) {
    OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  const struct curve_data *data = curve->data;
  const unsigned param_len = data->param_len;
  const uint8_t *params = data->data;

  if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
      !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
      !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }

  if (curve->method != 0) {
    meth = curve->method();
    if (((group = ec_group_new(meth)) == NULL) ||
        (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
      goto err;
    }
  } else {
    if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
      goto err;
    }
  }

  if ((P = EC_POINT_new(group)) == NULL) {
    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    goto err;
  }

  if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
      !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }

  if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    goto err;
  }
  if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order) ||
      !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }

  CRYPTO_once(&built_in_curve_scalar_field_monts_once,
              built_in_curve_scalar_field_monts_init);
  if (built_in_curve_scalar_field_monts != NULL) {
    group->mont_data = built_in_curve_scalar_field_monts[built_in_index];
  }

  group->generator = P;
  P = NULL;
  ok = 1;

err:
  if (!ok) {
    EC_GROUP_free(group);
    group = NULL;
  }
  EC_POINT_free(P);
  BN_CTX_free(ctx);
  BN_free(p);
  BN_free(a);
  BN_free(b);
  BN_free(x);
  BN_free(y);
  return group;
}
Esempio n. 11
0
static void call_once_thread(void) {
  CRYPTO_once(&g_test_once, once_init);
}