/* Copyright (c) 2015, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include "internal.h"

#include <openssl/crypto.h>
#include <openssl/rand.h>

#include <stdio.h>


#if !defined(OPENSSL_NO_THREADS)

#if defined(OPENSSL_WINDOWS)

OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
OPENSSL_MSVC_PRAGMA(warning(pop))

typedef HANDLE thread_t;

static DWORD WINAPI thread_run(LPVOID arg) {
  void (*thread_func)(void);
  /* VC really doesn't like casting between data and function pointers. */
  OPENSSL_memcpy(&thread_func, &arg, sizeof(thread_func));
  thread_func();
  return 0;
}

static int run_thread(thread_t *out_thread, void (*thread_func)(void)) {
  void *arg;
  /* VC really doesn't like casting between data and function pointers. */
  OPENSSL_memcpy(&arg, &thread_func, sizeof(arg));

  *out_thread = CreateThread(NULL /* security attributes */,
                             0 /* default stack size */, thread_run, arg,
                             0 /* run immediately */, NULL /* ignore id */);
  return *out_thread != NULL;
}

static int wait_for_thread(thread_t thread) {
  return WaitForSingleObject(thread, INFINITE) == 0;
}

#else

#include <pthread.h>
#include <string.h>
#include <time.h>

typedef pthread_t thread_t;

static void *thread_run(void *arg) {
  void (*thread_func)(void) = arg;
  thread_func();
  return NULL;
}

static int run_thread(thread_t *out_thread, void (*thread_func)(void)) {
  return pthread_create(out_thread, NULL /* default attributes */, thread_run,
                        thread_func) == 0;
}

static int wait_for_thread(thread_t thread) {
  return pthread_join(thread, NULL) == 0;
}

#endif  /* OPENSSL_WINDOWS */

static unsigned g_once_init_called = 0;

static void once_init(void) {
  g_once_init_called++;

  /* Sleep briefly so one |call_once_thread| instance will call |CRYPTO_once|
   * while the other is running this function. */
#if defined(OPENSSL_WINDOWS)
  Sleep(1 /* milliseconds */);
#else
  struct timespec req;
  OPENSSL_memset(&req, 0, sizeof(req));
  req.tv_nsec = 1000000;
  nanosleep(&req, NULL);
#endif
}

static CRYPTO_once_t g_test_once = CRYPTO_ONCE_INIT;

static void call_once_thread(void) {
  CRYPTO_once(&g_test_once, once_init);
}

static CRYPTO_once_t once_init_value = CRYPTO_ONCE_INIT;
static CRYPTO_once_t once_bss;

static struct CRYPTO_STATIC_MUTEX mutex_init_value = CRYPTO_STATIC_MUTEX_INIT;
static struct CRYPTO_STATIC_MUTEX mutex_bss;

static CRYPTO_EX_DATA_CLASS ex_data_class_value = CRYPTO_EX_DATA_CLASS_INIT;
static CRYPTO_EX_DATA_CLASS ex_data_class_bss;

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 thread1, thread2;
  if (!run_thread(&thread1, call_once_thread) ||
      !run_thread(&thread2, call_once_thread) ||
      !wait_for_thread(thread1) ||
      !wait_for_thread(thread2)) {
    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;
  }

  if (FIPS_mode()) {
    /* Our FIPS tooling currently requires that |CRYPTO_ONCE_INIT|,
     * |CRYPTO_STATIC_MUTEX_INIT| and |CRYPTO_EX_DATA_CLASS| are all zeros and
     * so can be placed in the BSS section. */
    if (OPENSSL_memcmp((void *)&once_init_value, (void *)&once_bss,
                       sizeof(CRYPTO_once_t)) != 0) {
      fprintf(stderr, "CRYPTO_ONCE_INIT did not expand to all zeros.\n");
      return 0;
    }

    if (OPENSSL_memcmp((void *)&mutex_init_value, (void *)&mutex_bss,
                       sizeof(struct CRYPTO_STATIC_MUTEX)) != 0) {
      fprintf(stderr, "CRYPTO_STATIC_MUTEX did not expand to all zeros.\n");
      return 0;
    }

    if (OPENSSL_memcmp((void *)&ex_data_class_value, (void *)&ex_data_class_bss,
                       sizeof(CRYPTO_EX_DATA_CLASS))) {
      fprintf(stderr,
              "CRYPTO_EX_DATA_CLASS_INIT did not expand to all zeros.\n");
      return 0;
    }
  }

  return 1;
}


static int g_test_thread_ok = 0;
static unsigned g_destructor_called_count = 0;

static void thread_local_destructor(void *arg) {
  if (arg == NULL) {
    return;
  }

  unsigned *count = arg;
  (*count)++;
}

static void thread_local_test_thread(void) {
  void *ptr = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_TEST);
  if (ptr != NULL) {
    return;
  }

  if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_TEST,
                               &g_destructor_called_count,
                               thread_local_destructor)) {
    return;
  }

  if (CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_TEST) !=
      &g_destructor_called_count) {
    return;
  }

  g_test_thread_ok = 1;
}

static void thread_local_test2_thread(void) {}

static int test_thread_local(void) {
  void *ptr = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_TEST);
  if (ptr != NULL) {
    fprintf(stderr, "Thread-local data was non-NULL at start.\n");
  }

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

  if (!g_test_thread_ok) {
    fprintf(stderr, "Thread-local data didn't work in thread.\n");
    return 0;
  }

  if (g_destructor_called_count != 1) {
    fprintf(stderr,
            "Destructor should have been called once, but actually called %u "
            "times.\n",
            g_destructor_called_count);
    return 0;
  }

  /* thread_local_test2_thread doesn't do anything, but it tests that the
   * thread destructor function works even if thread-local storage wasn't used
   * for a thread. */
  if (!run_thread(&thread, thread_local_test2_thread) ||
      !wait_for_thread(thread)) {
    fprintf(stderr, "thread failed.\n");
    return 0;
  }

  return 1;
}

static void rand_state_test_thread(void) {
  uint8_t buf[1];
  RAND_bytes(buf, sizeof(buf));
}

static int test_rand_state(void) {
  /* In FIPS mode, rand.c maintains a linked-list of thread-local data because
   * we're required to clear it on process exit. This test exercises removing a
   * value from that list. */
  uint8_t buf[1];
  RAND_bytes(buf, sizeof(buf));

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

  return 1;
}

int main(int argc, char **argv) {
  if (!test_once() ||
      !test_thread_local() ||
      !test_rand_state()) {
    return 1;
  }

  printf("PASS\n");
  return 0;
}

#else  /* OPENSSL_NO_THREADS */

int main(int argc, char **argv) {
  printf("PASS\n");
  return 0;
}

#endif
