5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
22 /************************** Types and definitions ***************************/
24 #define SILC_ACC_KEY_MAGIC 0xfde09137
26 SILC_PKCS_GET_ALGORITHM(silc_acc_pkcs_get_algorithm);
27 SILC_PKCS_IMPORT_PUBLIC_KEY_FILE(silc_acc_pkcs_import_public_key_file);
28 SILC_PKCS_IMPORT_PUBLIC_KEY(silc_acc_pkcs_import_public_key);
29 SILC_PKCS_EXPORT_PUBLIC_KEY_FILE(silc_acc_pkcs_export_public_key_file);
30 SILC_PKCS_EXPORT_PUBLIC_KEY(silc_acc_pkcs_export_public_key);
31 SILC_PKCS_PUBLIC_KEY_BITLEN(silc_acc_pkcs_public_key_bitlen);
32 SILC_PKCS_PUBLIC_KEY_COPY(silc_acc_pkcs_public_key_copy);
33 SILC_PKCS_PUBLIC_KEY_COMPARE(silc_acc_pkcs_public_key_compare);
34 SILC_PKCS_PUBLIC_KEY_FREE(silc_acc_pkcs_public_key_free);
35 SILC_PKCS_IMPORT_PRIVATE_KEY_FILE(silc_acc_pkcs_import_private_key_file);
36 SILC_PKCS_IMPORT_PRIVATE_KEY(silc_acc_pkcs_import_private_key);
37 SILC_PKCS_EXPORT_PRIVATE_KEY_FILE(silc_acc_pkcs_export_private_key_file);
38 SILC_PKCS_EXPORT_PRIVATE_KEY(silc_acc_pkcs_export_private_key);
39 SILC_PKCS_PRIVATE_KEY_BITLEN(silc_acc_pkcs_private_key_bitlen);
40 SILC_PKCS_PRIVATE_KEY_FREE(silc_acc_pkcs_private_key_free);
41 SILC_PKCS_ENCRYPT(silc_acc_pkcs_encrypt);
42 SILC_PKCS_DECRYPT(silc_acc_pkcs_decrypt);
43 SILC_PKCS_SIGN(silc_acc_pkcs_sign);
44 SILC_PKCS_VERIFY(silc_acc_pkcs_verify);
46 /* Accelerator public key */
49 int pkcs_index; /* Accelerator PKCS index */
50 SilcAccelerator acc; /* The accelerator */
51 void *context; /* Accelerator context */
52 SilcPublicKey accelerated; /* Associated public key */
53 } *SilcAcceleratorPublicKey;
55 /* Accelerator private key */
58 int pkcs_index; /* Accelerator PKCS index */
59 SilcAccelerator acc; /* The accelerator */
60 void *context; /* Accelerator context */
61 SilcPrivateKey accelerated; /* Associated private key */
62 } *SilcAcceleratorPrivateKey;
64 /*************************** Accelerator PKCS API ***************************/
66 /* The PKCS API for the accelerated public key and private key is simply
67 a wrapper for the underlaying key. Encrypt, decrypt, sign and verify
68 operations are accelerated by calling the accelerator operations. */
70 const SilcPKCSObject silc_acc_pkcs =
75 silc_acc_pkcs_get_algorithm,
76 silc_acc_pkcs_import_public_key_file,
77 silc_acc_pkcs_import_public_key,
78 silc_acc_pkcs_export_public_key_file,
79 silc_acc_pkcs_export_public_key,
80 silc_acc_pkcs_public_key_bitlen,
81 silc_acc_pkcs_public_key_copy,
82 silc_acc_pkcs_public_key_compare,
83 silc_acc_pkcs_public_key_free,
84 silc_acc_pkcs_import_private_key_file,
85 silc_acc_pkcs_import_private_key,
86 silc_acc_pkcs_export_private_key_file,
87 silc_acc_pkcs_export_private_key,
88 silc_acc_pkcs_private_key_bitlen,
89 silc_acc_pkcs_private_key_free,
92 silc_acc_pkcs_encrypt,
93 silc_acc_pkcs_decrypt,
98 SILC_PKCS_GET_ALGORITHM(silc_acc_pkcs_get_algorithm)
100 SilcAcceleratorPublicKey pub = public_key;
101 return pub->accelerated->pkcs->get_algorithm(pub->accelerated->pkcs,
102 pub->accelerated->public_key);
105 SILC_PKCS_IMPORT_PUBLIC_KEY_FILE(silc_acc_pkcs_import_public_key_file)
107 /* Not implemented */
111 SILC_PKCS_IMPORT_PUBLIC_KEY(silc_acc_pkcs_import_public_key)
113 /* Not implemented */
117 SILC_PKCS_EXPORT_PUBLIC_KEY_FILE(silc_acc_pkcs_export_public_key_file)
119 SilcAcceleratorPublicKey pub = public_key;
120 return pub->accelerated->pkcs->
121 export_public_key_file(pub->accelerated->pkcs, NULL,
122 pub->accelerated->public_key,
126 SILC_PKCS_EXPORT_PUBLIC_KEY(silc_acc_pkcs_export_public_key)
128 SilcAcceleratorPublicKey pub = public_key;
129 return pub->accelerated->pkcs->export_public_key(pub->accelerated->pkcs,
131 pub->accelerated->public_key,
135 SILC_PKCS_PUBLIC_KEY_BITLEN(silc_acc_pkcs_public_key_bitlen)
137 SilcAcceleratorPublicKey pub = public_key;
138 return pub->accelerated->pkcs->
139 public_key_bitlen(pub->accelerated->pkcs,
140 pub->accelerated->public_key);
143 SILC_PKCS_PUBLIC_KEY_COPY(silc_acc_pkcs_public_key_copy)
145 SilcAcceleratorPublicKey pub = public_key;
146 return pub->accelerated->pkcs->public_key_copy(pub->accelerated->pkcs,
147 pub->accelerated->public_key);
150 SILC_PKCS_PUBLIC_KEY_COMPARE(silc_acc_pkcs_public_key_compare)
152 SilcAcceleratorPublicKey pub;
155 if (pub->magic == SILC_ACC_KEY_MAGIC)
156 key2 = pub->accelerated->public_key;
160 return pub->accelerated->pkcs->
161 public_key_compare(pub->accelerated->pkcs,
162 pub->accelerated->public_key, key2);
165 SILC_PKCS_IMPORT_PRIVATE_KEY_FILE(silc_acc_pkcs_import_private_key_file)
167 /* Not implemented */
171 SILC_PKCS_IMPORT_PRIVATE_KEY(silc_acc_pkcs_import_private_key)
173 /* Not implemented */
177 SILC_PKCS_EXPORT_PRIVATE_KEY_FILE(silc_acc_pkcs_export_private_key_file)
179 SilcAcceleratorPrivateKey prv = private_key;
180 return prv->accelerated->pkcs->
181 export_private_key_file(prv->accelerated->pkcs, stack,
182 prv->accelerated->private_key, passphrase,
183 passphrase_len, encoding, rng, ret_len);
186 SILC_PKCS_EXPORT_PRIVATE_KEY(silc_acc_pkcs_export_private_key)
188 SilcAcceleratorPrivateKey prv = private_key;
189 return prv->accelerated->pkcs->
190 export_private_key(prv->accelerated->pkcs, stack,
191 prv->accelerated->private_key, ret_len);
194 SILC_PKCS_PRIVATE_KEY_BITLEN(silc_acc_pkcs_private_key_bitlen)
196 SilcAcceleratorPrivateKey prv = private_key;
197 return prv->accelerated->pkcs->
198 private_key_bitlen(prv->accelerated->pkcs,
199 prv->accelerated->private_key);
202 SILC_PKCS_PUBLIC_KEY_FREE(silc_acc_pkcs_public_key_free)
204 SilcAcceleratorPublicKey pub = public_key;
205 pub->acc->pkcs[pub->pkcs_index].
206 public_key_free(&pub->acc->pkcs[pub->pkcs_index], pub->context);
209 SILC_PKCS_PRIVATE_KEY_FREE(silc_acc_pkcs_private_key_free)
211 SilcAcceleratorPrivateKey prv = private_key;
212 prv->acc->pkcs[prv->pkcs_index].
213 private_key_free(&prv->acc->pkcs[prv->pkcs_index], prv->context);
216 SILC_PKCS_ENCRYPT(silc_acc_pkcs_encrypt)
218 SilcAcceleratorPublicKey pub = public_key;
221 return pub->acc->pkcs[pub->pkcs_index].encrypt(
222 &pub->acc->pkcs[pub->pkcs_index], pub->context, src,
223 src_len, rng, encrypt_cb, context);
226 SILC_PKCS_DECRYPT(silc_acc_pkcs_decrypt)
228 SilcAcceleratorPrivateKey prv = private_key;
231 return prv->acc->pkcs[prv->pkcs_index].decrypt(
232 &prv->acc->pkcs[prv->pkcs_index], prv->context, src,
233 src_len, decrypt_cb, context);
236 SILC_PKCS_SIGN(silc_acc_pkcs_sign)
238 SilcAcceleratorPrivateKey prv = private_key;
241 return prv->acc->pkcs[prv->pkcs_index].sign(
242 &prv->acc->pkcs[prv->pkcs_index], prv->context, src,
243 src_len, compute_hash, hash, sign_cb, context);
246 SILC_PKCS_VERIFY(silc_acc_pkcs_verify)
248 SilcAcceleratorPublicKey pub = public_key;
251 return pub->acc->pkcs[pub->pkcs_index].verify(
252 &pub->acc->pkcs[pub->pkcs_index], pub->context,
253 signature, signature_len, data, data_len, hash,
257 /*************************** SILC Accelerator API ***************************/
259 /* Accelerate public key */
261 SilcPublicKey silc_acc_public_key(SilcAccelerator acc,
262 SilcPublicKey public_key)
264 SilcPublicKey pubkey;
265 SilcAcceleratorPublicKey acc_pubkey;
266 const SilcPKCSAlgorithm *alg;
269 if (!acc || !public_key)
272 SILC_LOG_DEBUG(("Accelerate public key %p with accelerator %s",
273 public_key, acc->name));
276 SILC_LOG_ERROR(("Accelerator '%s' does not support public key "
277 "acceleration", acc->name));
281 /* Check that accelerator supports this public key algorithm */
282 alg = silc_pkcs_get_algorithm(public_key);
285 for (i = 0; acc->pkcs[i].name; i++) {
286 if ((!strcmp(acc->pkcs[i].name, alg->name) &&
287 !strcmp(acc->pkcs[i].scheme, alg->scheme)) ||
288 !strcmp(acc->pkcs[i].name, "any")) {
294 SILC_LOG_DEBUG(("Accelerator %s does not support %s/%s acceleration",
295 alg->name, alg->scheme));
299 pubkey = silc_calloc(1, sizeof(*pubkey));
303 /* Allocate PKCS operations */
304 pubkey->pkcs = silc_calloc(1, sizeof(*pubkey->pkcs));
309 *pubkey->pkcs = silc_acc_pkcs;
310 pubkey->pkcs->type = silc_pkcs_get_type(public_key);
311 pubkey->alg = silc_pkcs_get_algorithm(public_key);
313 /* Allocate accelerator public key */
314 acc_pubkey = silc_calloc(1, sizeof(*acc_pubkey));
316 silc_free(pubkey->pkcs);
320 acc_pubkey->magic = SILC_ACC_KEY_MAGIC;
321 acc_pubkey->accelerated = public_key;
322 acc_pubkey->acc = acc;
323 acc_pubkey->pkcs_index = i;
325 /* Accelerate the public key. Returns accelerator context. */
326 if (!acc->pkcs->import_public_key(&acc->pkcs[i], public_key, 0,
327 &acc_pubkey->context)) {
328 SILC_LOG_ERROR(("Error accelerating public key with accelerator '%s'",
330 silc_free(acc_pubkey);
331 silc_free(pubkey->pkcs);
335 pubkey->public_key = acc_pubkey;
337 SILC_LOG_DEBUG(("New accelerated public key %p", pubkey));
342 /* Accelerate private key */
344 SilcPrivateKey silc_acc_private_key(SilcAccelerator acc,
345 SilcPrivateKey private_key)
347 SilcPrivateKey privkey;
348 SilcAcceleratorPrivateKey acc_privkey;
349 const SilcPKCSAlgorithm *alg;
352 if (!acc || !private_key)
355 SILC_LOG_DEBUG(("Accelerate private key %p with accelerator %s",
356 private_key, acc->name));
359 SILC_LOG_ERROR(("Accelerator '%s' does not support private key "
360 "acceleration", acc->name));
364 /* Check that accelerator supports this private key algorithm */
365 alg = silc_pkcs_get_algorithm(private_key);
368 for (i = 0; acc->pkcs[i].name; i++) {
369 if ((!strcmp(acc->pkcs[i].name, alg->name) &&
370 !strcmp(acc->pkcs[i].scheme, alg->scheme)) ||
371 !strcmp(acc->pkcs[i].name, "any")) {
377 SILC_LOG_DEBUG(("Accelerator %s does not support %s/%s acceleration",
378 alg->name, alg->scheme));
382 privkey = silc_calloc(1, sizeof(*privkey));
386 /* Allocate PKCS operations */
387 privkey->pkcs = silc_calloc(1, sizeof(*privkey->pkcs));
388 if (!privkey->pkcs) {
392 *privkey->pkcs = silc_acc_pkcs;
393 privkey->pkcs->type = silc_pkcs_get_type(private_key);
394 privkey->alg = silc_pkcs_get_algorithm(private_key);
396 /* Allocate accelerator public key */
397 acc_privkey = silc_calloc(1, sizeof(*acc_privkey));
399 silc_free(privkey->pkcs);
403 acc_privkey->magic = SILC_ACC_KEY_MAGIC;
404 acc_privkey->accelerated = private_key;
405 acc_privkey->acc = acc;
406 acc_privkey->pkcs_index = i;
408 /* Accelerate the public key. Returns accelerator context. */
409 if (!acc->pkcs->import_private_key(&acc->pkcs[i], private_key, 0,
410 &acc_privkey->context)) {
411 SILC_LOG_ERROR(("Error accelerating private key with accelerator '%s'",
413 silc_free(acc_privkey);
414 silc_free(privkey->pkcs);
418 privkey->private_key = acc_privkey;
420 SILC_LOG_DEBUG(("New accelerated private key %p", privkey));
425 /* Get associated public key */
427 SilcPublicKey silc_acc_get_public_key(SilcAccelerator acc,
428 SilcPublicKey public_key)
430 SilcAcceleratorPublicKey pubkey;
435 if (public_key->pkcs->get_algorithm != silc_acc_pkcs_get_algorithm)
438 pubkey = public_key->public_key;
440 return pubkey->accelerated;
443 /* Get associated private key */
445 SilcPrivateKey silc_acc_get_private_key(SilcAccelerator acc,
446 SilcPrivateKey private_key)
448 SilcAcceleratorPrivateKey privkey;
453 if (private_key->pkcs->get_algorithm != silc_acc_pkcs_get_algorithm)
456 privkey = private_key->private_key;
458 return privkey->accelerated;