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 SILC_PKCS_GET_ALGORITHM(silc_acc_pkcs_get_algorithm);
25 SILC_PKCS_IMPORT_PUBLIC_KEY_FILE(silc_acc_pkcs_import_public_key_file);
26 SILC_PKCS_IMPORT_PUBLIC_KEY(silc_acc_pkcs_import_public_key);
27 SILC_PKCS_EXPORT_PUBLIC_KEY_FILE(silc_acc_pkcs_export_public_key_file);
28 SILC_PKCS_EXPORT_PUBLIC_KEY(silc_acc_pkcs_export_public_key);
29 SILC_PKCS_PUBLIC_KEY_BITLEN(silc_acc_pkcs_public_key_bitlen);
30 SILC_PKCS_PUBLIC_KEY_COPY(silc_acc_pkcs_public_key_copy);
31 SILC_PKCS_PUBLIC_KEY_COMPARE(silc_acc_pkcs_public_key_compare);
32 SILC_PKCS_PUBLIC_KEY_FREE(silc_acc_pkcs_public_key_free);
33 SILC_PKCS_IMPORT_PRIVATE_KEY_FILE(silc_acc_pkcs_import_private_key_file);
34 SILC_PKCS_IMPORT_PRIVATE_KEY(silc_acc_pkcs_import_private_key);
35 SILC_PKCS_EXPORT_PRIVATE_KEY_FILE(silc_acc_pkcs_export_private_key_file);
36 SILC_PKCS_EXPORT_PRIVATE_KEY(silc_acc_pkcs_export_private_key);
37 SILC_PKCS_PRIVATE_KEY_BITLEN(silc_acc_pkcs_private_key_bitlen);
38 SILC_PKCS_PRIVATE_KEY_FREE(silc_acc_pkcs_private_key_free);
39 SILC_PKCS_ENCRYPT(silc_acc_pkcs_encrypt);
40 SILC_PKCS_DECRYPT(silc_acc_pkcs_decrypt);
41 SILC_PKCS_SIGN(silc_acc_pkcs_sign);
42 SILC_PKCS_VERIFY(silc_acc_pkcs_verify);
44 /* Accelerator public key */
46 int pkcs_index; /* Accelerator PKCS index */
47 SilcAccelerator acc; /* The accelerator */
48 void *context; /* Accelerator context */
49 SilcPublicKey accelerated; /* Associated public key */
50 } *SilcAcceleratorPublicKey;
52 /* Accelerator private key */
54 int pkcs_index; /* Accelerator PKCS index */
55 SilcAccelerator acc; /* The accelerator */
56 void *context; /* Accelerator context */
57 SilcPrivateKey accelerated; /* Associated private key */
58 } *SilcAcceleratorPrivateKey;
60 /*************************** Accelerator PKCS API ***************************/
62 /* The PKCS API for the accelerated public key and private key is simply
63 a wrapper for the underlaying key. Encrypt, decrypt, sign and verify
64 operations are accelerated by calling the accelerator operations. */
66 const SilcPKCSObject silc_acc_pkcs =
71 silc_acc_pkcs_get_algorithm,
72 silc_acc_pkcs_import_public_key_file,
73 silc_acc_pkcs_import_public_key,
74 silc_acc_pkcs_export_public_key_file,
75 silc_acc_pkcs_export_public_key,
76 silc_acc_pkcs_public_key_bitlen,
77 silc_acc_pkcs_public_key_copy,
78 silc_acc_pkcs_public_key_compare,
79 silc_acc_pkcs_public_key_free,
80 silc_acc_pkcs_import_private_key_file,
81 silc_acc_pkcs_import_private_key,
82 silc_acc_pkcs_export_private_key_file,
83 silc_acc_pkcs_export_private_key,
84 silc_acc_pkcs_private_key_bitlen,
85 silc_acc_pkcs_private_key_free,
88 silc_acc_pkcs_encrypt,
89 silc_acc_pkcs_decrypt,
94 SILC_PKCS_GET_ALGORITHM(silc_acc_pkcs_get_algorithm)
96 SilcAcceleratorPublicKey pub = public_key;
97 return pub->accelerated->pkcs->get_algorithm(pub->accelerated->pkcs,
98 pub->accelerated->public_key);
101 SILC_PKCS_IMPORT_PUBLIC_KEY_FILE(silc_acc_pkcs_import_public_key_file)
103 /* Not implemented */
107 SILC_PKCS_IMPORT_PUBLIC_KEY(silc_acc_pkcs_import_public_key)
109 /* Not implemented */
113 SILC_PKCS_EXPORT_PUBLIC_KEY_FILE(silc_acc_pkcs_export_public_key_file)
115 SilcAcceleratorPublicKey pub = public_key;
116 return pub->accelerated->pkcs->
117 export_public_key_file(pub->accelerated->pkcs, NULL,
118 pub->accelerated->public_key,
122 SILC_PKCS_EXPORT_PUBLIC_KEY(silc_acc_pkcs_export_public_key)
124 SilcAcceleratorPublicKey pub = public_key;
125 return pub->accelerated->pkcs->export_public_key(pub->accelerated->pkcs,
127 pub->accelerated->public_key,
131 SILC_PKCS_PUBLIC_KEY_BITLEN(silc_acc_pkcs_public_key_bitlen)
133 SilcAcceleratorPublicKey pub = public_key;
134 return pub->accelerated->pkcs->
135 public_key_bitlen(pub->accelerated->pkcs,
136 pub->accelerated->public_key);
139 SILC_PKCS_PUBLIC_KEY_COPY(silc_acc_pkcs_public_key_copy)
141 SilcAcceleratorPublicKey pub = public_key;
142 return pub->accelerated->pkcs->public_key_copy(pub->accelerated->pkcs,
143 pub->accelerated->public_key);
146 SILC_PKCS_PUBLIC_KEY_COMPARE(silc_acc_pkcs_public_key_compare)
152 SILC_PKCS_IMPORT_PRIVATE_KEY_FILE(silc_acc_pkcs_import_private_key_file)
157 SILC_PKCS_IMPORT_PRIVATE_KEY(silc_acc_pkcs_import_private_key)
162 SILC_PKCS_EXPORT_PRIVATE_KEY_FILE(silc_acc_pkcs_export_private_key_file)
167 SILC_PKCS_EXPORT_PRIVATE_KEY(silc_acc_pkcs_export_private_key)
172 SILC_PKCS_PRIVATE_KEY_BITLEN(silc_acc_pkcs_private_key_bitlen)
177 SILC_PKCS_PUBLIC_KEY_FREE(silc_acc_pkcs_public_key_free)
182 SILC_PKCS_PRIVATE_KEY_FREE(silc_acc_pkcs_private_key_free)
187 SILC_PKCS_ENCRYPT(silc_acc_pkcs_encrypt)
189 SilcAcceleratorPublicKey pub = public_key;
192 return pub->acc->pkcs[pub->pkcs_index].encrypt(
193 &pub->acc->pkcs[pub->pkcs_index], pub->context, src,
194 src_len, rng, encrypt_cb, context);
197 SILC_PKCS_DECRYPT(silc_acc_pkcs_decrypt)
199 SilcAcceleratorPrivateKey prv = private_key;
202 return prv->acc->pkcs[prv->pkcs_index].decrypt(
203 &prv->acc->pkcs[prv->pkcs_index], prv->context, src,
204 src_len, decrypt_cb, context);
207 SILC_PKCS_SIGN(silc_acc_pkcs_sign)
209 SilcAcceleratorPrivateKey prv = private_key;
212 return prv->acc->pkcs[prv->pkcs_index].sign(
213 &prv->acc->pkcs[prv->pkcs_index], prv->context, src,
214 src_len, compute_hash, hash, sign_cb, context);
217 SILC_PKCS_VERIFY(silc_acc_pkcs_verify)
219 SilcAcceleratorPublicKey pub = public_key;
222 return pub->acc->pkcs[pub->pkcs_index].verify(
223 &pub->acc->pkcs[pub->pkcs_index], pub->context,
224 signature, signature_len, data, data_len, hash,
228 /*************************** SILC Accelerator API ***************************/
230 /* Accelerate public key */
232 SilcPublicKey silc_acc_public_key(SilcAccelerator acc,
233 SilcPublicKey public_key)
235 SilcPublicKey pubkey;
236 SilcAcceleratorPublicKey acc_pubkey;
237 const SilcPKCSAlgorithm *alg;
240 if (!acc || !public_key)
243 SILC_LOG_DEBUG(("Accelerate public key %p with accelerator %s",
244 public_key, acc->name));
247 SILC_LOG_ERROR(("Accelerator '%s' does not support public key "
248 "acceleration", acc->name));
252 /* Check that accelerator supports this public key algorithm */
253 alg = silc_pkcs_get_algorithm(public_key);
256 for (i = 0; acc->pkcs[i].name; i++) {
257 if ((!strcmp(acc->pkcs[i].name, alg->name) &&
258 !strcmp(acc->pkcs[i].scheme, alg->scheme)) ||
259 !strcmp(acc->pkcs[i].name, "any")) {
265 SILC_LOG_DEBUG(("Accelerator %s does not support %s/%s acceleration",
266 alg->name, alg->scheme));
270 pubkey = silc_calloc(1, sizeof(*pubkey));
274 /* Allocate PKCS operations */
275 pubkey->pkcs = silc_calloc(1, sizeof(*pubkey->pkcs));
280 *pubkey->pkcs = silc_acc_pkcs;
281 pubkey->pkcs->type = silc_pkcs_get_type(public_key);
283 /* Allocate accelerator public key */
284 acc_pubkey = silc_calloc(1, sizeof(*acc_pubkey));
286 silc_free(pubkey->pkcs);
290 acc_pubkey->accelerated = public_key;
291 acc_pubkey->acc = acc;
292 acc_pubkey->pkcs_index = i;
294 /* Accelerate the public key. Returns accelerator context. */
295 if (!acc->pkcs->import_public_key(&acc->pkcs[i], public_key, 0,
296 &acc_pubkey->context)) {
297 SILC_LOG_ERROR(("Error accelerating public key with accelerator '%s'",
299 silc_free(acc_pubkey);
300 silc_free(pubkey->pkcs);
304 pubkey->public_key = acc_pubkey;
306 SILC_LOG_DEBUG(("New accelerated public key %p", pubkey));
311 /* Accelerate private key */
313 SilcPrivateKey silc_acc_private_key(SilcAccelerator acc,
314 SilcPrivateKey private_key)
316 SilcPrivateKey privkey;
317 SilcAcceleratorPrivateKey acc_privkey;
318 const SilcPKCSAlgorithm *alg;
321 if (!acc || !private_key)
324 SILC_LOG_DEBUG(("Accelerate private key %p with accelerator %s",
325 private_key, acc->name));
328 SILC_LOG_ERROR(("Accelerator '%s' does not support private key "
329 "acceleration", acc->name));
333 /* Check that accelerator supports this private key algorithm */
334 alg = silc_pkcs_get_algorithm(private_key);
337 for (i = 0; acc->pkcs[i].name; i++) {
338 if ((!strcmp(acc->pkcs[i].name, alg->name) &&
339 !strcmp(acc->pkcs[i].scheme, alg->scheme)) ||
340 !strcmp(acc->pkcs[i].name, "any")) {
346 SILC_LOG_DEBUG(("Accelerator %s does not support %s/%s acceleration",
347 alg->name, alg->scheme));
351 privkey = silc_calloc(1, sizeof(*privkey));
355 /* Allocate PKCS operations */
356 privkey->pkcs = silc_calloc(1, sizeof(*privkey->pkcs));
357 if (!privkey->pkcs) {
361 *privkey->pkcs = silc_acc_pkcs;
362 privkey->pkcs->type = silc_pkcs_get_type(private_key);
364 /* Allocate accelerator public key */
365 acc_privkey = silc_calloc(1, sizeof(*acc_privkey));
367 silc_free(privkey->pkcs);
371 acc_privkey->accelerated = private_key;
372 acc_privkey->acc = acc;
373 acc_privkey->pkcs_index = i;
375 /* Accelerate the public key. Returns accelerator context. */
376 if (!acc->pkcs->import_private_key(&acc->pkcs[i], private_key, 0,
377 &acc_privkey->context)) {
378 SILC_LOG_ERROR(("Error accelerating private key with accelerator '%s'",
380 silc_free(acc_privkey);
381 silc_free(privkey->pkcs);
385 privkey->private_key = acc_privkey;
387 SILC_LOG_DEBUG(("New accelerated private key %p", privkey));
392 /* Get associated public key */
394 SilcPublicKey silc_acc_get_public_key(SilcAccelerator acc,
395 SilcPublicKey public_key)
397 SilcAcceleratorPublicKey pubkey;
402 if (public_key->pkcs->get_algorithm != silc_acc_pkcs_get_algorithm)
405 pubkey = public_key->public_key;
407 return pubkey->accelerated;
410 /* Get associated private key */
412 SilcPrivateKey silc_acc_get_private_key(SilcAccelerator acc,
413 SilcPrivateKey private_key)
415 SilcAcceleratorPrivateKey privkey;
420 if (private_key->pkcs->get_algorithm != silc_acc_pkcs_get_algorithm)
423 privkey = private_key->private_key;
425 return privkey->accelerated;