]> git.ipfire.org Git - people/ms/strongswan.git/blob - src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
f97c57b8f142ad0f87cb5c13ce9dcd0ae5548868
[people/ms/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 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 16),
74 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 24),
75 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 32),
76 /* gcrypt only supports 128 bit blowfish */
77 PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 16),
78 #ifdef HAVE_GCRY_CIPHER_CAMELLIA
79 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 16),
80 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 24),
81 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 32),
82 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16),
83 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24),
84 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32),
85 #endif
86 PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0),
87 PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24),
88 PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8),
89 PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8),
90 PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 16),
91 PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 24),
92 PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 32),
93 PLUGIN_PROVIDE(CRYPTER, ENCR_TWOFISH_CBC, 16),
94 PLUGIN_PROVIDE(CRYPTER, ENCR_TWOFISH_CBC, 32),
95 /* hashers */
96 PLUGIN_REGISTER(HASHER, gcrypt_hasher_create),
97 PLUGIN_PROVIDE(HASHER, HASH_MD4),
98 PLUGIN_PROVIDE(HASHER, HASH_MD5),
99 PLUGIN_PROVIDE(HASHER, HASH_SHA1),
100 PLUGIN_PROVIDE(HASHER, HASH_SHA224),
101 PLUGIN_PROVIDE(HASHER, HASH_SHA256),
102 PLUGIN_PROVIDE(HASHER, HASH_SHA384),
103 PLUGIN_PROVIDE(HASHER, HASH_SHA512),
104 /* MODP DH groups */
105 PLUGIN_REGISTER(DH, gcrypt_dh_create),
106 PLUGIN_PROVIDE(DH, MODP_3072_BIT),
107 PLUGIN_PROVIDE(DH, MODP_4096_BIT),
108 PLUGIN_PROVIDE(DH, MODP_6144_BIT),
109 PLUGIN_PROVIDE(DH, MODP_8192_BIT),
110 PLUGIN_PROVIDE(DH, MODP_2048_BIT),
111 PLUGIN_PROVIDE(DH, MODP_2048_224),
112 PLUGIN_PROVIDE(DH, MODP_2048_256),
113 PLUGIN_PROVIDE(DH, MODP_1536_BIT),
114 PLUGIN_PROVIDE(DH, MODP_1024_BIT),
115 PLUGIN_PROVIDE(DH, MODP_1024_160),
116 PLUGIN_PROVIDE(DH, MODP_768_BIT),
117 PLUGIN_REGISTER(DH, gcrypt_dh_create_custom),
118 PLUGIN_PROVIDE(DH, MODP_CUSTOM),
119 /* RSA private/public key loading */
120 PLUGIN_REGISTER(PUBKEY, gcrypt_rsa_public_key_load, TRUE),
121 PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
122 PLUGIN_REGISTER(PRIVKEY, gcrypt_rsa_private_key_load, TRUE),
123 PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
124 PLUGIN_REGISTER(PRIVKEY_GEN, gcrypt_rsa_private_key_gen, FALSE),
125 PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
126 /* signature schemes, private */
127 #if GCRYPT_VERSION_NUMBER >= 0x010700
128 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
129 #endif
130 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
131 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_224),
132 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_256),
133 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_384),
134 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_512),
135 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
136 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
137 /* signature verification schemes */
138 #if GCRYPT_VERSION_NUMBER >= 0x010700
139 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS),
140 #endif
141 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
142 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_224),
143 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256),
144 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384),
145 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512),
146 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
147 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
148 /* random numbers */
149 PLUGIN_REGISTER(RNG, gcrypt_rng_create),
150 PLUGIN_PROVIDE(RNG, RNG_WEAK),
151 PLUGIN_PROVIDE(RNG, RNG_STRONG),
152 PLUGIN_PROVIDE(RNG, RNG_TRUE),
153 };
154 *features = f;
155 return countof(f);
156 }
157
158 METHOD(plugin_t, destroy, void,
159 private_gcrypt_plugin_t *this)
160 {
161 free(this);
162 }
163
164 /*
165 * see header file
166 */
167 plugin_t *gcrypt_plugin_create()
168 {
169 private_gcrypt_plugin_t *this;
170 u_char *dummy[1];
171
172 #if GCRYPT_VERSION_NUMBER < 0x010600
173 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
174 #endif
175
176 if (!gcry_check_version(GCRYPT_VERSION))
177 {
178 DBG1(DBG_LIB, "libgcrypt version mismatch");
179 return NULL;
180 }
181
182 /* we currently do not use secure memory */
183 gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
184 if (lib->settings->get_bool(lib->settings, "%s.plugins.gcrypt.quick_random",
185 FALSE, lib->ns))
186 {
187 gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
188 }
189 gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
190
191 /* initialize static allocations we want to exclude from leak-detective */
192 gcry_create_nonce(dummy, sizeof(dummy));
193
194 INIT(this,
195 .public = {
196 .plugin = {
197 .get_name = _get_name,
198 .get_features = _get_features,
199 .destroy = _destroy,
200 },
201 },
202 );
203
204 return &this->public.plugin;
205 }