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