gcrypt: Don't use thread callbacks for newer versions of libgcrypt
[strongswan.git] / src / libstrongswan / plugins / gcrypt / gcrypt_plugin.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "gcrypt_plugin.h"
17
18 #include "gcrypt_hasher.h"
19 #include "gcrypt_crypter.h"
20 #include "gcrypt_rng.h"
21 #include "gcrypt_dh.h"
22 #include "gcrypt_rsa_private_key.h"
23 #include "gcrypt_rsa_public_key.h"
24
25 #include <library.h>
26 #include <utils/debug.h>
27 #include <threading/mutex.h>
28
29 #include <errno.h>
30 #include <gcrypt.h>
31 #include <pthread.h>
32
33 typedef struct private_gcrypt_plugin_t private_gcrypt_plugin_t;
34
35 /**
36 * private data of gcrypt_plugin
37 */
38 struct private_gcrypt_plugin_t {
39
40 /**
41 * public functions
42 */
43 gcrypt_plugin_t public;
44 };
45
46 #if GCRYPT_VERSION_NUMBER < 0x010600
47 /**
48 * Define gcrypt multi-threading callbacks as gcry_threads_pthread
49 */
50 GCRY_THREAD_OPTION_PTHREAD_IMPL;
51 #endif
52
53 METHOD(plugin_t, get_name, char*,
54 private_gcrypt_plugin_t *this)
55 {
56 return "gcrypt";
57 }
58
59 METHOD(plugin_t, get_features, int,
60 private_gcrypt_plugin_t *this, plugin_feature_t *features[])
61 {
62 static plugin_feature_t f[] = {
63 /* we provide threading-safe initialization of libgcrypt */
64 PLUGIN_PROVIDE(CUSTOM, "gcrypt-threading"),
65 /* crypters */
66 PLUGIN_REGISTER(CRYPTER, gcrypt_crypter_create),
67 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 16),
68 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 24),
69 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 32),
70 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
71 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
72 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
73 /* gcrypt only supports 128 bit blowfish */
74 PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 16),
75 #ifdef HAVE_GCRY_CIPHER_CAMELLIA
76 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 16),
77 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 24),
78 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 32),
79 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16),
80 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24),
81 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32),
82 #endif
83 PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0),
84 PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24),
85 PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8),
86 PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8),
87 PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 16),
88 PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 24),
89 PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 32),
90 PLUGIN_PROVIDE(CRYPTER, ENCR_TWOFISH_CBC, 16),
91 PLUGIN_PROVIDE(CRYPTER, ENCR_TWOFISH_CBC, 32),
92 /* hashers */
93 PLUGIN_REGISTER(HASHER, gcrypt_hasher_create),
94 PLUGIN_PROVIDE(HASHER, HASH_MD4),
95 PLUGIN_PROVIDE(HASHER, HASH_MD5),
96 PLUGIN_PROVIDE(HASHER, HASH_SHA1),
97 PLUGIN_PROVIDE(HASHER, HASH_SHA224),
98 PLUGIN_PROVIDE(HASHER, HASH_SHA256),
99 PLUGIN_PROVIDE(HASHER, HASH_SHA384),
100 PLUGIN_PROVIDE(HASHER, HASH_SHA512),
101 /* MODP DH groups */
102 PLUGIN_REGISTER(DH, gcrypt_dh_create),
103 PLUGIN_PROVIDE(DH, MODP_3072_BIT),
104 PLUGIN_PROVIDE(DH, MODP_4096_BIT),
105 PLUGIN_PROVIDE(DH, MODP_6144_BIT),
106 PLUGIN_PROVIDE(DH, MODP_8192_BIT),
107 PLUGIN_PROVIDE(DH, MODP_2048_BIT),
108 PLUGIN_PROVIDE(DH, MODP_2048_224),
109 PLUGIN_PROVIDE(DH, MODP_2048_256),
110 PLUGIN_PROVIDE(DH, MODP_1536_BIT),
111 PLUGIN_PROVIDE(DH, MODP_1024_BIT),
112 PLUGIN_PROVIDE(DH, MODP_1024_160),
113 PLUGIN_PROVIDE(DH, MODP_768_BIT),
114 PLUGIN_REGISTER(DH, gcrypt_dh_create_custom),
115 PLUGIN_PROVIDE(DH, MODP_CUSTOM),
116 /* RSA private/public key loading */
117 PLUGIN_REGISTER(PUBKEY, gcrypt_rsa_public_key_load, TRUE),
118 PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
119 PLUGIN_REGISTER(PRIVKEY, gcrypt_rsa_private_key_load, TRUE),
120 PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
121 PLUGIN_REGISTER(PRIVKEY_GEN, gcrypt_rsa_private_key_gen, FALSE),
122 PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
123 /* signature schemes, private */
124 #if GCRYPT_VERSION_NUMBER >= 0x010700
125 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
126 #endif
127 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
128 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_224),
129 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_256),
130 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_384),
131 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_512),
132 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
133 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
134 /* signature verification schemes */
135 #if GCRYPT_VERSION_NUMBER >= 0x010700
136 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS),
137 #endif
138 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
139 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_224),
140 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256),
141 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384),
142 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512),
143 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
144 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
145 /* random numbers */
146 PLUGIN_REGISTER(RNG, gcrypt_rng_create),
147 PLUGIN_PROVIDE(RNG, RNG_WEAK),
148 PLUGIN_PROVIDE(RNG, RNG_STRONG),
149 PLUGIN_PROVIDE(RNG, RNG_TRUE),
150 };
151 *features = f;
152 return countof(f);
153 }
154
155 METHOD(plugin_t, destroy, void,
156 private_gcrypt_plugin_t *this)
157 {
158 free(this);
159 }
160
161 /*
162 * see header file
163 */
164 plugin_t *gcrypt_plugin_create()
165 {
166 private_gcrypt_plugin_t *this;
167
168 #if GCRYPT_VERSION_NUMBER < 0x010600
169 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
170 #endif
171
172 if (!gcry_check_version(GCRYPT_VERSION))
173 {
174 DBG1(DBG_LIB, "libgcrypt version mismatch");
175 return NULL;
176 }
177
178 /* we currently do not use secure memory */
179 gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
180 if (lib->settings->get_bool(lib->settings, "%s.plugins.gcrypt.quick_random",
181 FALSE, lib->ns))
182 {
183 gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
184 }
185 gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
186
187 /* initialize static allocations we want to exclude from leak-detective */
188 gcry_create_nonce(NULL, 0);
189
190 INIT(this,
191 .public = {
192 .plugin = {
193 .get_name = _get_name,
194 .get_features = _get_features,
195 .destroy = _destroy,
196 },
197 },
198 );
199
200 return &this->public.plugin;
201 }