File: openssl.cpp

package info (click to toggle)
encfs 1.9.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster
  • size: 13,560 kB
  • sloc: cpp: 77,790; python: 9,665; xml: 3,888; sh: 995; perl: 866; makefile: 513; ansic: 213; sed: 16; exp: 16
file content (105 lines) | stat: -rw-r--r-- 3,034 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*****************************************************************************
 * Author:   Valient Gough <vgough@pobox.com>
 *
 *****************************************************************************
 * Copyright (c) 2007, Valient Gough
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "openssl.h"

#include <cstdlib>
#include <openssl/crypto.h>
#include <pthread.h>

#define NO_DES
#include <openssl/rand.h>
#include <openssl/ssl.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif

#include "Error.h"

namespace encfs {

unsigned long pthreads_thread_id() { return (unsigned long)pthread_self(); }

static pthread_mutex_t *crypto_locks = nullptr;
void pthreads_locking_callback(int mode, int n, const char *caller_file,
                               int caller_line) {
  (void)caller_file;
  (void)caller_line;

  if (crypto_locks == nullptr) {
    VLOG(1) << "Allocating " << CRYPTO_num_locks() << " locks for OpenSSL";
    crypto_locks = new pthread_mutex_t[CRYPTO_num_locks()];
    for (int i = 0; i < CRYPTO_num_locks(); ++i) {
      pthread_mutex_init(crypto_locks + i, nullptr);
    }
  }

  if ((mode & CRYPTO_LOCK) != 0) {
    pthread_mutex_lock(crypto_locks + n);
  } else {
    pthread_mutex_unlock(crypto_locks + n);
  }
}

void pthreads_locking_cleanup() {
  if (crypto_locks != nullptr) {
    for (int i = 0; i < CRYPTO_num_locks(); ++i) {
      pthread_mutex_destroy(crypto_locks + i);
    }
    delete[] crypto_locks;
    crypto_locks = nullptr;
  }
}

void openssl_init(bool threaded) {
  // initialize the SSL library
  SSL_load_error_strings();
  SSL_library_init();

  unsigned int randSeed = 0;
  RAND_bytes((unsigned char *)&randSeed, sizeof(randSeed));
  srand(randSeed);

#ifndef OPENSSL_NO_ENGINE
  /* Load all bundled ENGINEs into memory and make them visible */
  ENGINE_load_builtin_engines();
  /* Register all of them for every algorithm they collectively implement */
  ENGINE_register_all_complete();
#endif  // NO_ENGINE

  if (threaded) {
    // provide locking functions to OpenSSL since we'll be running with
    // threads accessing openssl in parallel.
    CRYPTO_set_id_callback(pthreads_thread_id);
    CRYPTO_set_locking_callback(pthreads_locking_callback);
  }
}

void openssl_shutdown(bool threaded) {
#ifndef OPENSSL_NO_ENGINE
  ENGINE_cleanup();
#endif

  if (threaded) {
    pthreads_locking_cleanup();
  }
}

}  // namespace encfs