Added synchronous and asynchronous PKCS calls.
authorPekka Riikonen <priikone@silcnet.org>
Wed, 5 Mar 2008 18:56:38 +0000 (20:56 +0200)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 5 Mar 2008 18:56:38 +0000 (20:56 +0200)
The synchronous calls, like silc_pkcs_sign, are compatible with 1.1
Toolkit.  The async calls can be used with accelerated keys.

TODO
distdir/crypto
lib/silcacc/silcacc_pkcs.c
lib/silcacc/softacc_pkcs.c
lib/silccrypt/silcpkcs.c
lib/silccrypt/silcpkcs.h
lib/silccrypt/tests/test_cipher.c
lib/silccrypt/tests/test_hmacsha256.c
lib/silcssh/silcssh_pkcs.c

diff --git a/TODO b/TODO
index 65b6a4e92497711c93c08d8995a97419db3f204e..f9600f6b31de97cb937e0c40371cad53f3a26575 100644 (file)
--- a/TODO
+++ b/TODO
@@ -14,25 +14,6 @@ to silc-devel mailing list or appear on 'silc' channel on SILCNet.
 Crypto Library, lib/silccrypt/
 ==============================
 
- o SilcHmac must be replaced with generic SilcMac so that we can add
-   others than just HMAC algorithms.  Backwards support (via #define's)
-   must be preserved.
-
- o Change the DSA implementation to support FIPS186-3.  This means that
-   the q length is determined by the key length.  Also note that specific
-   hash functions must be used with different q lengths.
-
- o AES CBC is missing proper alignment code (see silc_1_1_branch).
-
- o The asynchronous functions to perhaps to _async to preserve backwards
-   compatibility with synchronous versions, and make easier to migrate
-   from 1.1 to 1.2.
-
- o Do GCC vs ICC benchmarks of all key algorithms.
-
- o silc_pkcs_public_key_alloc should accept also SILC_PKCS_ANY as argument
-   and try all supported PKCS until one succeeds (ala load_public_key).
-
  o Add fingerprint to SilcSILCPublicKey and retrieval to silcpk.h, and
    possibly to silcpkcs.h.
 
@@ -43,10 +24,50 @@ Crypto Library, lib/silccrypt/
                             const char **hash_algorithm,
                             SilcUInt32 *fingerprint_len);
 
- o Add DSA support to SILC public key.
+ o Add CMAC and maybe others.  Change needs rewrite of the internals of
+   the SILC Mac API, currently it's suitable only for HMACs.
 
  o Global RNG must be changed to use SILC Global API.
 
+ o Add FIPS compliant RNG.
+
+ o Implement the defined SilcDH API.  The definition is in
+   lib/silccrypt/silcdh.h.  Make sure it is asynchronous so that it can
+   be accelerated.  Also take into account that it could use elliptic
+   curves.
+
+ o Add ECDSA support.
+
+ o Add ECDH support.
+
+ o Add PKCS#1 RSAES-OAEP and RSASSA-PSS.
+
+ o Do GCC vs ICC benchmarks of all key algorithms.
+
+ o Add DSA support to SILC public key.
+
+ o The asynchronous functions to perhaps to _async to preserve backwards
+   compatibility with synchronous versions, and make easier to migrate
+   from 1.1 to 1.2. (***DONE)
+
+ o AES CBC is missing proper alignment code. (***DONE)
+
+ o silc_pkcs_public_key_alloc should accept also SILC_PKCS_ANY as argument
+   and try all supported PKCS until one succeeds. (***DONE)
+
+ o Associate a default hash function with all PKCS algorithms.  User can
+   override it in silc_pkcs_sign.  DSA with FIPS186-3 determines the
+   hash algorithm by the key length. (***DONE)
+
+ o Document all cipher names, hash names, mac names, pkcs names. (***DONE)
+
+ o SilcHmac must be replaced with generic SilcMac so that we can add
+   others than just HMAC algorithms.  Backwards support (via #define's)
+   must be preserved. (***DONE)
+
+ o Change the DSA implementation to support FIPS186-3.  This means that
+   the q length is determined by the key length.  (***DONE)
+
  o Add silc_crypto_init and silc_crypto_uninit.  The _init should take
    SilcStack that will act as global memory pool for all of crypto
    library.  It should not be necessary anymore to separately register
@@ -66,18 +87,9 @@ Crypto Library, lib/silccrypt/
 
  o Add DSS support. (***DONE)
 
- o Implement the defined SilcDH API.  The definition is in
-   lib/silccrypt/silcdh.h.  Make sure it is asynchronous so that it can
-   be accelerated.  Also take into account that it could use elliptic
-   curves.
-
  o All cipher, hash, hmac etc. allocation routines should take their name
    in as const char * not const unsigned char *. (***DONE)
 
- o Add ECDSA support.
-
- o Add ECDH support.
-
 
 SKR Library, lib/silcskr/
 =========================
@@ -126,7 +138,13 @@ SKR Library, lib/silcskr/
 SILC Accelerator Library
 ========================
 
- o Diffie-Hellman acceleration
+ o Diffie-Hellman software acceleration.
+
+ o Hardware acceleration through OCF (OCF-Linux,
+   http://ocf-linux.sourceforge.net).
+
+ o VIA Padlock support. See http://www.logix.cz/michal/devel/padlock/ and
+   Gladman's code.
 
  o SILC Accelerator API.  Provides generic way to use different kind of
    accelerators.  Basically implements SILC PKCS API so that SilcPublicKey
@@ -161,9 +179,8 @@ lib/silcmath
  o The SILC MP API function must start returning indication of success
    and failure of the operation. (***DONE)
 
- o Do SilcStack support for silc_mp_init, silc_mp_init_size and other
-   any other MP function (including utility ones) that may allocate
-   memory. (***DONE)
+ o Do SilcStack support for silc_mp_init and other MP function
+   (including utility ones) that may allocate memory. (***DONE)
 
 
 lib/silcasn1
@@ -219,3 +236,15 @@ lib/silcpkix
 ============
 
  o PKIX implementation
+
+
+lib/silccms
+===========
+
+ o Cryptographic Message Syntax (RFC 3852), the former PKCS #7
+
+
+lib/silcsmime
+=============
+
+ o S/MIME (RFC 3851)
index c3292dfdcf4d6c54922a4ab0527267f9e47d1a38..1799c4c95488a16140cbd57b93ce5700cd329fe6 100644 (file)
@@ -4,10 +4,11 @@ bug-report silc-devel@lists.silcnet.org
 prereq 1.3.2
 
 # License
-license distdir/CRYPTO
-include distdir/GPL GPL
-include distdir/BSD BSD
-license-header distdir/GPL-header distdir/CRYPTO-header
+license distdir/GPL
+#license distdir/CRYPTO
+#include distdir/GPL GPL
+#include distdir/BSD BSD
+#license-header distdir/GPL-header distdir/CRYPTO-header
 
 # Distdefs
 define SILC_DIST_SSH
index cc666880811b635db25652f8c69b5a2da000a639..9a0dba5cabdb330d46257a15f73ac65c60258e41 100644 (file)
@@ -252,7 +252,8 @@ SILC_PKCS_VERIFY(silc_acc_pkcs_verify)
   /* Accelerate */
   return pub->acc->pkcs[pub->pkcs_index].verify(
                       &pub->acc->pkcs[pub->pkcs_index], pub->context,
-                      signature, signature_len, data, data_len, hash, rng,
+                      signature, signature_len, data, data_len,
+                      compute_hash, hash, rng,
                       verify_cb, context);
 }
 
index a3e9f6a2c3b479bf99208cbd16af5f8bf39bc54b..5524859caa1f1924a8bf7c785cbd15c652261fcb 100644 (file)
@@ -198,23 +198,25 @@ void silc_softacc_pkcs_thread(SilcSchedule schedule, void *context)
   /* Call the operation */
   switch (e->type) {
   case SILC_SOFTACC_ENCRYPT:
-    silc_pkcs_encrypt(e->key.public_key, e->src, e->src_len, e->rng,
-                     silc_softacc_pkcs_data_cb, e);
+    silc_pkcs_encrypt_async(e->key.public_key, e->src, e->src_len, e->rng,
+                           silc_softacc_pkcs_data_cb, e);
     break;
 
   case SILC_SOFTACC_DECRYPT:
-    silc_pkcs_decrypt(e->key.private_key, e->src, e->src_len,
-                     silc_softacc_pkcs_data_cb, e);
+    silc_pkcs_decrypt_async(e->key.private_key, e->src, e->src_len,
+                           silc_softacc_pkcs_data_cb, e);
     break;
 
   case SILC_SOFTACC_SIGN:
-    silc_pkcs_sign(e->key.private_key, e->src, e->src_len, e->compute_hash,
-                  e->hash, e->rng, silc_softacc_pkcs_data_cb, e);
+    silc_pkcs_sign_async(e->key.private_key, e->src, e->src_len,
+                        e->compute_hash, e->hash, e->rng,
+                        silc_softacc_pkcs_data_cb, e);
     break;
 
   case SILC_SOFTACC_VERIFY:
-    silc_pkcs_verify(e->key.public_key, e->src, e->src_len, e->data,
-                    e->data_len, e->hash, silc_softacc_pkcs_verify_cb, e);
+    silc_pkcs_verify_async(e->key.public_key, e->src, e->src_len, e->data,
+                          e->data_len, e->compute_hash, e->hash,
+                          silc_softacc_pkcs_verify_cb, e);
     break;
   }
 }
@@ -453,6 +455,7 @@ SILC_PKCS_ALG_VERIFY(silc_softacc_verify)
   e->src_len = signature_len;
   e->data = silc_smemdup(stack, data, data_len);
   e->data_len = data_len;
+  e->compute_hash = compute_hash;
   e->hash = hash;
   e->key.public_key = pubkey->key;
   e->cb.verify_cb = verify_cb;
index 6b8e68fb0f367bec3b1d590457bbd338efcb84fc..d32f92fe3a95542df5f690cb611cd3383f90fa19 100644 (file)
@@ -171,7 +171,7 @@ const SilcPKCSAlgorithm silc_default_pkcs_alg[] =
     silc_pkcs1_verify
   },
 
-  /* DSS */
+  /* DSS, FIPS186-3 */
   {
     "dsa",
     "dss",
@@ -193,6 +193,28 @@ const SilcPKCSAlgorithm silc_default_pkcs_alg[] =
     silc_dsa_verify
   },
 
+  /* DSS, FIPS186-2 */
+  {
+    "dsa",
+    "dss-fips186-2",
+    "sha1",
+    silc_dsa_generate_key,
+    silc_dsa_import_public_key,
+    silc_dsa_export_public_key,
+    silc_dsa_public_key_bitlen,
+    silc_dsa_public_key_copy,
+    silc_dsa_public_key_compare,
+    silc_dsa_public_key_free,
+    silc_dsa_import_private_key,
+    silc_dsa_export_private_key,
+    silc_dsa_private_key_bitlen,
+    silc_dsa_private_key_free,
+    silc_dsa_encrypt,
+    silc_dsa_decrypt,
+    silc_dsa_sign,
+    silc_dsa_verify
+  },
+
 #ifdef SILC_DIST_SSH
   /* PKCS #1, SSH2 style public keys */
   {
@@ -216,12 +238,12 @@ const SilcPKCSAlgorithm silc_default_pkcs_alg[] =
     silc_pkcs1_verify
   },
 
-  /* DSS, SSH2 style public keys */
+  /* DSS FIPS186-2, SSH2 style public keys */
   {
     "dsa",
     "ssh",
     "sha1,sha224,sha256,sha384,sha512",
-    silc_dsa_generate_key,
+    silc_dsa_fips186_2_generate_key,
     silc_ssh_dsa_import_public_key,
     silc_ssh_dsa_export_public_key,
     silc_dsa_public_key_bitlen,
@@ -636,24 +658,41 @@ SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
   if (!public_key)
     return FALSE;
 
-  pkcs = silc_pkcs_find_pkcs(type);
-  public_key->pkcs = (SilcPKCSObject *)pkcs;
-  if (!public_key->pkcs) {
-    silc_free(public_key);
-    return FALSE;
-  }
+  if (type == SILC_PKCS_ANY) {
+    /* Try loading all types until one succeeds. */
+    for (type = SILC_PKCS_SILC; type <= SILC_PKCS_SPKI; type++) {
+      pkcs = (SilcPKCSObject *)silc_pkcs_find_pkcs(type);
+      if (!pkcs)
+       continue;
 
-  /* Import the PKCS public key */
-  if (!pkcs->import_public_key(pkcs, NULL, key, key_len,
-                              &public_key->public_key,
-                              &public_key->alg)) {
-    silc_free(public_key);
-    return FALSE;
-  }
+      /* Import the PKCS public key */
+      if (pkcs->import_public_key(pkcs, NULL, key, key_len,
+                                 &public_key->public_key,
+                                 &public_key->alg)) {
+       public_key->pkcs = (SilcPKCSObject *)pkcs;
+       *ret_public_key = public_key;
+       return TRUE;
+      }
+    }
+  } else {
+    pkcs = silc_pkcs_find_pkcs(type);
+    public_key->pkcs = (SilcPKCSObject *)pkcs;
+    if (!public_key->pkcs) {
+      silc_free(public_key);
+      return FALSE;
+    }
 
-  *ret_public_key = public_key;
+    /* Import the PKCS public key */
+    if (pkcs->import_public_key(pkcs, NULL, key, key_len,
+                               &public_key->public_key,
+                               &public_key->alg)) {
+      *ret_public_key = public_key;
+      return TRUE;
+    }
+  }
 
-  return TRUE;
+  silc_free(public_key);
+  return FALSE;
 }
 
 /* Frees the public key */
@@ -757,13 +796,73 @@ void silc_pkcs_private_key_free(SilcPrivateKey private_key)
   silc_free(private_key);
 }
 
+/* PKCS operation context */
+typedef struct {
+  unsigned char *dst;
+  SilcUInt32 *dst_len;
+  SilcUInt32 dst_size;
+  SilcBool result;
+} SilcPKCSOperation;
+
+/* Encrypt, decrypt, sign callback */
+
+static void silc_pkcs_op_cb(SilcBool success,
+                           const unsigned char *data,
+                           SilcUInt32 data_len, void *context)
+{
+  SilcPKCSOperation *ctx = context;
+
+  ctx->result = success;
+
+  if (!success)
+    return;
+
+  if (data_len > ctx->dst_size) {
+    ctx->result = FALSE;
+    return;
+  }
+
+  memcpy(ctx->dst, data, data_len);
+  if (ctx->dst_len)
+    *ctx->dst_len = data_len;
+}
+
+/* Verify callback */
+
+static void silc_pkcs_verify_cb(SilcBool success, void *context)
+{
+  SilcPKCSOperation *ctx = context;
+  ctx->result = success;
+}
+
 /* Encrypts */
 
-SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
-                                    unsigned char *src, SilcUInt32 src_len,
-                                    SilcRng rng,
-                                    SilcPKCSEncryptCb encrypt_cb,
-                                    void *context)
+SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
+                          unsigned char *src, SilcUInt32 src_len,
+                          unsigned char *dst, SilcUInt32 dst_size,
+                          SilcUInt32 *dst_len, SilcRng rng)
+{
+  SilcPKCSOperation ctx;
+
+  ctx.dst = dst;
+  ctx.dst_size = dst_size;
+  ctx.dst_len = dst_len;
+
+  public_key->pkcs->encrypt(public_key->pkcs,
+                           public_key->public_key, src, src_len,
+                           rng, silc_pkcs_op_cb, &ctx);
+
+  return ctx.result;
+}
+
+/* Encrypts, async */
+
+SilcAsyncOperation
+silc_pkcs_encrypt_async(SilcPublicKey public_key,
+                       unsigned char *src, SilcUInt32 src_len,
+                       SilcRng rng,
+                       SilcPKCSEncryptCb encrypt_cb,
+                       void *context)
 {
   return public_key->pkcs->encrypt(public_key->pkcs,
                                   public_key->public_key, src, src_len,
@@ -772,10 +871,31 @@ SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
 
 /* Decrypts */
 
-SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
-                                    unsigned char *src, SilcUInt32 src_len,
-                                    SilcPKCSDecryptCb decrypt_cb,
-                                    void *context)
+SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
+                          unsigned char *src, SilcUInt32 src_len,
+                          unsigned char *dst, SilcUInt32 dst_size,
+                          SilcUInt32 *dst_len)
+{
+  SilcPKCSOperation ctx;
+
+  ctx.dst = dst;
+  ctx.dst_size = dst_size;
+  ctx.dst_len = dst_len;
+
+  private_key->pkcs->decrypt(private_key->pkcs,
+                            private_key->private_key, src, src_len,
+                            silc_pkcs_op_cb, &ctx);
+
+  return ctx.result;
+}
+
+/* Decrypts, async */
+
+SilcAsyncOperation
+silc_pkcs_decrypt_async(SilcPrivateKey private_key,
+                       unsigned char *src, SilcUInt32 src_len,
+                       SilcPKCSDecryptCb decrypt_cb,
+                       void *context)
 {
   return private_key->pkcs->decrypt(private_key->pkcs,
                                    private_key->private_key, src, src_len,
@@ -784,14 +904,36 @@ SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
 
 /* Generates signature */
 
-SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
-                                 unsigned char *src,
-                                 SilcUInt32 src_len,
-                                 SilcBool compute_hash,
-                                 SilcHash hash,
-                                 SilcRng rng,
-                                 SilcPKCSSignCb sign_cb,
-                                 void *context)
+SilcBool silc_pkcs_sign(SilcPrivateKey private_key,
+                       unsigned char *src, SilcUInt32 src_len,
+                       unsigned char *dst, SilcUInt32 dst_size,
+                       SilcUInt32 *dst_len, SilcBool compute_hash,
+                       SilcHash hash, SilcRng rng)
+{
+  SilcPKCSOperation ctx;
+
+  ctx.dst = dst;
+  ctx.dst_size = dst_size;
+  ctx.dst_len = dst_len;
+
+  private_key->pkcs->sign(private_key->pkcs,
+                         private_key->private_key, src, src_len,
+                         compute_hash, hash, rng,
+                         silc_pkcs_op_cb, &ctx);
+
+  return ctx.result;
+}
+
+/* Generates signature, async */
+
+SilcAsyncOperation silc_pkcs_sign_async(SilcPrivateKey private_key,
+                                       unsigned char *src,
+                                       SilcUInt32 src_len,
+                                       SilcBool compute_hash,
+                                       SilcHash hash,
+                                       SilcRng rng,
+                                       SilcPKCSSignCb sign_cb,
+                                       void *context)
 {
   return private_key->pkcs->sign(private_key->pkcs,
                                 private_key->private_key, src, src_len,
@@ -800,18 +942,41 @@ SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
 
 /* Verifies signature */
 
-SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
-                                   unsigned char *signature,
-                                   SilcUInt32 signature_len,
-                                   unsigned char *data,
-                                   SilcUInt32 data_len,
-                                   SilcHash hash,
-                                   SilcPKCSVerifyCb verify_cb,
-                                   void *context)
+SilcBool silc_pkcs_verify(SilcPublicKey public_key,
+                         unsigned char *signature,
+                         SilcUInt32 signature_len,
+                         unsigned char *data,
+                         SilcUInt32 data_len,
+                         SilcBool compute_hash,
+                         SilcHash hash)
+{
+  SilcPKCSOperation ctx;
+
+  public_key->pkcs->verify(public_key->pkcs,
+                          public_key->public_key, signature,
+                          signature_len, data, data_len,
+                          compute_hash, hash, NULL,
+                          silc_pkcs_verify_cb, &ctx);
+
+  return ctx.result;
+}
+
+/* Verifies signature, async */
+
+SilcAsyncOperation silc_pkcs_verify_async(SilcPublicKey public_key,
+                                         unsigned char *signature,
+                                         SilcUInt32 signature_len,
+                                         unsigned char *data,
+                                         SilcUInt32 data_len,
+                                         SilcBool compute_hash,
+                                         SilcHash hash,
+                                         SilcPKCSVerifyCb verify_cb,
+                                         void *context)
 {
   return public_key->pkcs->verify(public_key->pkcs,
                                  public_key->public_key, signature,
-                                 signature_len, data, data_len, hash, NULL,
+                                 signature_len, data, data_len,
+                                 compute_hash, hash, NULL,
                                  verify_cb, context);
 }
 
index 66bebbbc7280f7f9f7195db45dea979dbeaf5f02..d97d9c603870764af8617a99ff804beb169c8648 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2007 Pekka Riikonen
+  Copyright (C) 1997 - 2008 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@
 typedef struct SilcPKCSAlgorithmStruct SilcPKCSAlgorithm;
 typedef struct SilcPKCSObjectStruct SilcPKCSObject;
 
-/****d* silccrypt/SilcPKCSAPI/SilcPKCSType
+/****d* silccrypt/SilcPKCSType
  *
  * NAME
  *
@@ -57,7 +57,80 @@ typedef enum {
 } SilcPKCSType;
 /***/
 
-/****s* silccrypt/SilcPKCSAPI/SilcPublicKey
+/****d* silccrypt/SilcPKCSAlgorithms
+ *
+ * NAME
+ *
+ *    PKCS Algorithms
+ *
+ * DESCRIPTION
+ *
+ *    Supported PKCS algorithm names.  These names can be given as argument
+ *    to silc_pkcs_find_algorithm.  See also SilcPKCSSchemes.
+ *
+ * SOURCE
+ */
+#define SILC_PKCS_ALG_RSA    "rsa"         /* RSA algorithm */
+#define SILC_PKCS_ALG_DSA    "dsa"        /* DSA algorithm */
+/***/
+
+/****d* silccrypt/SilcPKCSSchemes
+ *
+ * NAME
+ *
+ *    PKCS Algorithm Schemes
+ *
+ * DESCRIPTION
+ *
+ *    Supported PKCS algorithm scheme names.  Different algorithms can be
+ *    implemented in different ways to conform differnet standards and
+ *    protocols.  The scheme defines these ways.  The scheme is given as
+ *    argument to silc_pkcs_find_algorithm.
+ *
+ * SOURCE
+ */
+
+/* PKCS #1 version 2.x.  This performs RSASSA-PKCS-v1_5 and RSAES-PKCS-v1_5
+   with hash OID in the signature data (signature with appendix).  This can
+   be used with SILC_PKCS_ALG_RSA.  Default hash function used with
+   signatures is SHA-1. */
+#define SILC_PKCS_SCHEME_PKCS1          "pkcs1"
+
+/* PKCS #1 version 2.x.  Same as SILC_PKCS_SCHEME_PKCS1 but the hash OID
+   is not present in the signature data.  This can be used with
+   SILC_PKCS_ALG_RSA.  Default hash function used with signatures is SHA-1. */
+#define SILC_PKCS_SCHEME_PKCS1_NO_OID   "pkcs1-no-oid"
+
+/* The Digital Signature Standard, FIPS 186-3.  The latest DSS standard
+   version.  The key parameters and hash function used are derived
+   automatically by the key length and the signature length is variable.
+   This can be used with SILC_PKCS_ALG_DSA. */
+#define SILC_PKCS_SCHEME_DSS            "dss"
+
+/* The Digital Signature Standard, FIPS 186-2.  Same as the
+   SILC_PKCS_SCHEME_DSS but the signature length is always 160 bits and
+   hash function used is SHA-1.  This is the most widely used DSS version
+   (<= year 2008).  This can be used with SILC_PKCS_ALG_DSA.  This is
+   compatible with SILC_PKCS_ALG_DSS when verifying signatures, but cannot
+   necessarily create compatible signature. */
+#define SILC_PKCS_SCHEME_DSS_FIPS186_2  "dss-fips186-2"
+
+#ifdef SILC_DIST_SSH
+/* The SSH2 protocol scheme.  This can be used with SILC_PKCS_ALG_RSA and
+   SILC_PKCS_ALG_DSA.  When used the algorithms behave as defined in the
+   SSH2 protocol. */
+#define SILC_PKCS_SCHEME_SSH            "ssh"
+#endif /* SILC_DIST_SSH */
+
+#ifdef SILC_DIST_PGP
+/* The OpenPGP protocol scheme.  This can be used with SILC_PKCS_ALG_RSA and
+   SILC_PKCS_ALG_DSA.  When used the algorithms behave as defined in the
+   OpenPGP protocol. */
+#define SILC_PKCS_SCHEME_OPENPGP        "openpgp"
+#endif /* SILC_DIST_PGP */
+/***/
+
+/****s* silccrypt/SilcPublicKey
  *
  * NAME
  *
@@ -80,7 +153,7 @@ typedef struct SilcPublicKeyStruct {
 } *SilcPublicKey;
 /***/
 
-/****s* silccrypt/SilcPKCSAPI/SilcPrivateKey
+/****s* silccrypt/SilcPrivateKey
  *
  * NAME
  *
@@ -102,7 +175,7 @@ typedef struct SilcPrivateKeyStruct {
 } *SilcPrivateKey;
 /***/
 
-/****d* silccrypt/SilcPKCSAPI/SilcPKCSFileEncoding
+/****d* silccrypt/SilcPKCSFileEncoding
  *
  * NAME
  *
@@ -120,7 +193,7 @@ typedef enum {
 } SilcPKCSFileEncoding;
 /***/
 
-/****f* silccrypt/SilcPKCSAPI/SilcPKCSEncryptCb
+/****f* silccrypt/SilcPKCSEncryptCb
  *
  * SYNOPSIS
  *
@@ -142,7 +215,7 @@ typedef void (*SilcPKCSEncryptCb)(SilcBool success,
                                  SilcUInt32 encrypted_len,
                                  void *context);
 
-/****f* silccrypt/SilcPKCSAPI/SilcPKCSDecryptCb
+/****f* silccrypt/SilcPKCSDecryptCb
  *
  * SYNOPSIS
  *
@@ -164,7 +237,7 @@ typedef void (*SilcPKCSDecryptCb)(SilcBool success,
                                  SilcUInt32 decrypted_len,
                                  void *context);
 
-/****f* silccrypt/SilcPKCSAPI/SilcPKCSSignCb
+/****f* silccrypt/SilcPKCSSignCb
  *
  * SYNOPSIS
  *
@@ -186,7 +259,7 @@ typedef void (*SilcPKCSSignCb)(SilcBool success,
                               SilcUInt32 signature_len,
                               void *context);
 
-/****f* silccrypt/SilcPKCSAPI/SilcPKCSVerifyCb
+/****f* silccrypt/SilcPKCSVerifyCb
  *
  * SYNOPSIS
  *
@@ -215,7 +288,7 @@ extern DLLAPI const SilcPKCSAlgorithm silc_default_pkcs_alg[];
 
 /* Prototypes */
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_register
+/****f* silccrypt/silc_pkcs_register
  *
  * SYNOPSIS
  *
@@ -223,18 +296,18 @@ extern DLLAPI const SilcPKCSAlgorithm silc_default_pkcs_alg[];
  *
  * DESCRIPTION
  *
- *    Registers a new PKCS into the crypto library.  This function is used
- *    at the initialization of an application.  All registered PKCSs
- *    should be unregistered with silc_pkcs_unregister.  The `pkcs' includes
- *    the name of the PKCS and member functions for the algorithm.  Usually
- *    this function is not called directly.  Instead, application can call
- *    the silc_pkcs_register_default to register all PKCSs that are
- *    builtin the sources.  Returns FALSE on error.
+ *    Registers a new PKCS into the crypto library.  This function can be
+ *    used at the initialization of an application.  All registered PKCSs
+ *    should be unregistered with silc_pkcs_unregister.  Usually this
+ *    function is not needed.  The default PKCSs  are automatically
+ *    registered.  This can be used to change the order of the registered
+ *    PKCSs by re-registering them in desired order, or add new PKCSs.
+ *    Returns FALSE on error.
  *
  ***/
 SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister
+/****f* silccrypt/silc_pkcs_unregister
  *
  * SYNOPSIS
  *
@@ -247,7 +320,7 @@ SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
  ***/
 SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_register
+/****f* silccrypt/silc_pkcs_algorithm_register
  *
  * SYNOPSIS
  *
@@ -256,13 +329,13 @@ SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
  * DESCRIPTION
  *
  *    Registers a new PKCS Algorithm into crypto library.  This function
- *    is used at the initialization of an application.  All registered PKCS
-*     algorithms should be unregistered with silc_pkcs_unregister.
+ *    can be used at the initialization of an application.  All registered
+ *    PKCS algorithms should be unregistered with silc_pkcs_unregister.
  *
  ***/
 SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_unregister
+/****f* silccrypt/silc_pkcs_algorithm_unregister
  *
  * SYNOPSIS
  *
@@ -275,7 +348,7 @@ SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
  ***/
 SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_register_default
+/****f* silccrypt/silc_pkcs_register_default
  *
  * SYNOPSIS
  *
@@ -284,13 +357,13 @@ SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
  * DESCRIPTION
  *
  *    Registers all the default PKCS (all builtin PKCS) and PKCS algorithms.
- *    The application may use this to register the default PKCS if specific
- *    PKCS in any specific order is not wanted.  Returns FALSE on error.
+ *    Application need not call this directly.  By calling silc_crypto_init
+ *    this function is called.
  *
  ***/
 SilcBool silc_pkcs_register_default(void);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister_all
+/****f* silccrypt/silc_pkcs_unregister_all
  *
  * SYNOPSIS
  *
@@ -299,11 +372,13 @@ SilcBool silc_pkcs_register_default(void);
  * DESCRIPTION
  *
  *    Unregister all PKCS and PKCS algorithms. Returns FALSE on error.
+ *    Application need not call this directly.  By calling silc_crypto_init
+ *    this function is called.
  *
  ***/
 SilcBool silc_pkcs_unregister_all(void);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_supported
+/****f* silccrypt/silc_pkcs_get_supported
  *
  * SYNOPSIS
  *
@@ -316,7 +391,7 @@ SilcBool silc_pkcs_unregister_all(void);
  ***/
 char *silc_pkcs_get_supported(void);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_pkcs
+/****f* silccrypt/silc_pkcs_find_pkcs
  *
  * SYNOPSIS
  *
@@ -329,7 +404,7 @@ char *silc_pkcs_get_supported(void);
  ***/
 const SilcPKCSObject *silc_pkcs_find_pkcs(SilcPKCSType type);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_algorithm
+/****f* silccrypt/silc_pkcs_find_algorithm
  *
  * SYNOPSIS
  *
@@ -339,13 +414,16 @@ const SilcPKCSObject *silc_pkcs_find_pkcs(SilcPKCSType type);
  * DESCRIPTION
  *
  *    Finds PKCS algorithm context by the algorithm name `algorithm' and
- *    the algorithm scheme `scheme'.  The `scheme' may be NULL.
+ *    the algorithm scheme `scheme'.  The `scheme' may be NULL.  Usually
+ *    this function is not needed unless you need low level access to the
+ *    algorithm implementations.  Usually this is used when implementing
+ *    support to new PKCS type.
  *
  ***/
 const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
                                                  const char *scheme);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_pkcs
+/****f* silccrypt/silc_pkcs_get_pkcs
  *
  * SYNOPSIS
  *
@@ -359,7 +437,7 @@ const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
  ***/
 const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_algorithm
+/****f* silccrypt/silc_pkcs_get_algorithm
  *
  * SYNOPSIS
  *
@@ -373,7 +451,7 @@ const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
  ***/
 const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_name
+/****f* silccrypt/silc_pkcs_get_name
  *
  * SYNOPSIS
  *
@@ -387,7 +465,7 @@ const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
  ***/
 const char *silc_pkcs_get_name(void *key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_type
+/****f* silccrypt/silc_pkcs_get_type
  *
  * SYNOPSIS
  *
@@ -401,7 +479,7 @@ const char *silc_pkcs_get_name(void *key);
  ***/
 SilcPKCSType silc_pkcs_get_type(void *key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_pkcs
+/****f* silccrypt/silc_pkcs_public_key_get_pkcs
  *
  * SYNOPSIS
  *
@@ -421,7 +499,7 @@ SilcPKCSType silc_pkcs_get_type(void *key);
 void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
                                    SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_pkcs
+/****f* silccrypt/silc_pkcs_private_key_get_pkcs
  *
  * SYNOPSIS
  *
@@ -441,7 +519,7 @@ void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
 void *silc_pkcs_private_key_get_pkcs(SilcPKCSType type,
                                     SilcPrivateKey private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_alloc
+/****f* silccrypt/silc_pkcs_public_key_alloc
  *
  * SYNOPSIS
  *
@@ -464,7 +542,7 @@ SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
                                    SilcUInt32 key_len,
                                    SilcPublicKey *ret_public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_free
+/****f* silccrypt/silc_pkcs_public_key_free
  *
  * SYNOPSIS
  *
@@ -479,7 +557,7 @@ SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
  ***/
 void silc_pkcs_public_key_free(SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_export
+/****f* silccrypt/silc_pkcs_public_key_export
  *
  * SYNOPSIS
  *
@@ -501,7 +579,7 @@ unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
                                           SilcPublicKey public_key,
                                           SilcUInt32 *ret_len);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_len
+/****f* silccrypt/silc_pkcs_public_key_get_len
  *
  * SYNOPSIS
  *
@@ -514,7 +592,7 @@ unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
  ***/
 SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_compare
+/****f* silccrypt/silc_pkcs_public_key_compare
  *
  * SYNOPSIS
  *
@@ -529,7 +607,7 @@ SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
  ***/
 SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_copy
+/****f* silccrypt/silc_pkcs_public_key_copy
  *
  * SYNOPSIS
  *
@@ -543,7 +621,7 @@ SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2);
  ***/
 SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_alloc
+/****f* silccrypt/silc_pkcs_private_key_alloc
  *
  * SYNOPSIS
  *
@@ -567,7 +645,7 @@ SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
                                     SilcUInt32 key_len,
                                     SilcPrivateKey *ret_private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_len
+/****f* silccrypt/silc_pkcs_private_key_get_len
  *
  * SYNOPSIS
  *
@@ -580,7 +658,7 @@ SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
  ***/
 SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_free
+/****f* silccrypt/silc_pkcs_private_key_free
  *
  * SYNOPSIS
  *
@@ -595,15 +673,41 @@ SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
  ***/
 void silc_pkcs_private_key_free(SilcPrivateKey private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_encrypt
+/****f* silccrypt/silc_pkcs_encrypt
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
+ *                               unsigned char *src, SilcUInt32 src_len,
+ *                               unsigned char *dst, SilcUInt32 dst_size,
+ *                               SilcUInt32 *dst_len, SilcRng rng);
+ *
+ * DESCRIPTION
+ *
+ *    Encrypts with the public key.  Returns FALSE on error.  The length
+ *    the encrypted data is returned to `dst_len' if it is non-NULL.
+ *
+ *    This call cannot be used if `public_key' is accelerated.  All
+ *    accelerators are usually asynchronous and the function will return
+ *    before the encryption has been done.  In this case the
+ *    silc_pkcs_encrypt_async should be used.
+ *
+ ***/
+SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
+                          unsigned char *src, SilcUInt32 src_len,
+                          unsigned char *dst, SilcUInt32 dst_size,
+                          SilcUInt32 *dst_len, SilcRng rng);
+
+/****f* silccrypt/silc_pkcs_encrypt_async
  *
  * SYNOPSIS
  *
- *    SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
- *                                         unsigned char *src,
- *                                         SilcUInt32 src_len, SilcRng rng,
- *                                         SilcPKCSEncryptCb encrypt_cb,
- *                                         void *context);
+ *    SilcAsyncOperation
+ *    silc_pkcs_encrypt_async(SilcPublicKey public_key,
+ *                            unsigned char *src,
+ *                            SilcUInt32 src_len, SilcRng rng,
+ *                            SilcPKCSEncryptCb encrypt_cb,
+ *                            void *context);
  *
  * DESCRIPTION
  *
@@ -613,21 +717,47 @@ void silc_pkcs_private_key_free(SilcPrivateKey private_key);
  *    the asynchronous operation cannot be controlled.
  *
  ***/
-SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
-                                    unsigned char *src,
-                                    SilcUInt32 src_len, SilcRng rng,
-                                    SilcPKCSEncryptCb encrypt_cb,
-                                    void *context);
+SilcAsyncOperation silc_pkcs_encrypt_async(SilcPublicKey public_key,
+                                          unsigned char *src,
+                                          SilcUInt32 src_len, SilcRng rng,
+                                          SilcPKCSEncryptCb encrypt_cb,
+                                          void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_decrypt
+/****f* silccrypt/silc_pkcs_decrypt
  *
  * SYNOPSIS
  *
- *    SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
- *                                         unsigned char *src,
- *                                         SilcUInt32 src_len,
- *                                         SilcPKCSDecryptCb decrypt_cb,
- *                                         void *context);
+ *    SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
+ *                               unsigned char *src, SilcUInt32 src_len,
+ *                               unsigned char *dst, SilcUInt32 dst_size,
+ *                               SilcUInt32 *dst_len);
+ *
+ * DESCRIPTION
+ *
+ *    Decrypts with the private key.  Returns FALSE on error.  The length
+ *    of the decrypted data is returned to `dst_len' if it is non-NULL.
+ *
+ *    This call cannot be used if `public_key' is accelerated.  All
+ *    accelerators are usually asynchronous and the function will return
+ *    before the decryption has been done.  In this case the
+ *    silc_pkcs_decrypt_async should be used.
+ *
+ ***/
+SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
+                          unsigned char *src, SilcUInt32 src_len,
+                          unsigned char *dst, SilcUInt32 dst_size,
+                          SilcUInt32 *dst_len);
+
+/****f* silccrypt/silc_pkcs_decrypt_async
+ *
+ * SYNOPSIS
+ *
+ *    SilcAsyncOperation
+ *    silc_pkcs_decrypt_async(SilcPrivateKey private_key,
+ *                            unsigned char *src,
+ *                            SilcUInt32 src_len,
+ *                            SilcPKCSDecryptCb decrypt_cb,
+ *                            void *context);
  *
  * DESCRIPTION
  *
@@ -637,79 +767,146 @@ SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
  *    the asynchronous operation cannot be controlled.
  *
  ***/
-SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
-                                    unsigned char *src, SilcUInt32 src_len,
-                                    SilcPKCSDecryptCb decrypt_cb,
-                                    void *context);
+SilcAsyncOperation
+silc_pkcs_decrypt_async(SilcPrivateKey private_key,
+                       unsigned char *src, SilcUInt32 src_len,
+                       SilcPKCSDecryptCb decrypt_cb,
+                       void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_sign
+/****f* silccrypt/silc_pkcs_sign
  *
  * SYNOPSIS
  *
- *    SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
- *                                      unsigned char *src,
- *                                      SilcUInt32 src_len,
- *                                      SilcBool compute_hash,
- *                                      SilcHash hash,
- *                                      SilcRng rng,
- *                                      SilcPKCSSignCb sign_cb,
- *                                      void *context);
+ *    SilcBool silc_pkcs_sign(SilcPrivateKey private_key,
+ *                            unsigned char *src, SilcUInt32 src_len,
+ *                            unsigned char *dst, SilcUInt32 dst_size,
+ *                            SilcUInt32 *dst_len, SilcBool compute_hash,
+ *                            SilcHash hash, SilcRng rng);
+ *
+ * DESCRIPTION
+ *
+ *    Computes signature with the private key.  If `compute_hash' is TRUE
+ *    the `hash' will be used to compute a message digest over the `src'.
+ *    The `hash' is NULL the default hash function is used.  The `rng'
+ *    should always be provided.  The length of the signature is returned
+ *    to `dst_len' is it is non-NULL.
+ *
+ *    This call cannot be used if `public_key' is accelerated.  All
+ *    accelerators are usually asynchronous and the function will return
+ *    before the signagture has been done.  In this case the
+ *    silc_pkcs_sign_async should be used.
+ *
+ ***/
+SilcBool silc_pkcs_sign(SilcPrivateKey private_key,
+                       unsigned char *src, SilcUInt32 src_len,
+                       unsigned char *dst, SilcUInt32 dst_size,
+                       SilcUInt32 *dst_len, SilcBool compute_hash,
+                       SilcHash hash, SilcRng rng);
+
+/****f* silccrypt/silc_pkcs_sign_async
+ *
+ * SYNOPSIS
+ *
+ *    SilcAsyncOperation silc_pkcs_sign_async(SilcPrivateKey private_key,
+ *                                            unsigned char *src,
+ *                                            SilcUInt32 src_len,
+ *                                            SilcBool compute_hash,
+ *                                            SilcHash hash,
+ *                                            SilcRng rng,
+ *                                            SilcPKCSSignCb sign_cb,
+ *                                            void *context);
  *
  * DESCRIPTION
  *
  *    Computes signature with the private key.  The `sign_cb' will be called
  *    to deliver the signature data.  If `compute_hash' is TRUE the `hash'
  *    will be used to compute a message digest over the `src'.  The `hash'
- *    must always be valid.  The `rng' should always be provided.  The
- *    signature operation may be asynchronous if the `private_key' is
- *    accelerated private key.  If this returns NULL the asynchronous
- *    operation cannot be controlled.
- *
- ***/
-SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
-                                 unsigned char *src,
-                                 SilcUInt32 src_len,
-                                 SilcBool compute_hash,
-                                 SilcHash hash,
-                                 SilcRng rng,
-                                 SilcPKCSSignCb sign_cb,
-                                 void *context);
+ *    is NULL the default hash function is used.  The `rng' should always
+ *    be provided.  The signature operation may be asynchronous if the
+ *    `private_key' is accelerated private key.  If this returns NULL the
+ *    asynchronous operation cannot be controlled.
+ *
+ ***/
+SilcAsyncOperation silc_pkcs_sign_async(SilcPrivateKey private_key,
+                                       unsigned char *src,
+                                       SilcUInt32 src_len,
+                                       SilcBool compute_hash,
+                                       SilcHash hash,
+                                       SilcRng rng,
+                                       SilcPKCSSignCb sign_cb,
+                                       void *context);
+
+/****f* silccrypt/silc_pkcs_verify
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_pkcs_verify(SilcPublicKey public_key,
+ *                              unsigned char *signature,
+ *                              SilcUInt32 signature_len,
+ *                              unsigned char *data,
+ *                              SilcUInt32 data_len,
+ *                              SilcBool compute_hash,
+ *                              SilcHash hash);
+ *
+ * DESCRIPTION
+ *
+ *    Verifies signature.  The 'signature' is verified against the 'data'.
+ *    If `compute_hash' hash is TRUE the `hash' will be used in verification.
+ *    If `hash' is NULL, the hash algorithm to be used is retrieved from the
+ *    signature.  If it isn't present in the signature the default hash
+ *    function is used.  The `rng' is usually not needed and may be NULL.
+ *
+ *    This call cannot be used if `public_key' is accelerated.  All
+ *    accelerators are usually asynchronous and the function will return
+ *    before the verification has been done.  In this case the
+ *    silc_pkcs_verify_async should be used.
+ *
+ ***/
+SilcBool silc_pkcs_verify(SilcPublicKey public_key,
+                         unsigned char *signature,
+                         SilcUInt32 signature_len,
+                         unsigned char *data,
+                         SilcUInt32 data_len,
+                         SilcBool compute_hash,
+                         SilcHash hash);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_verify
+/****f* silccrypt/silc_pkcs_verify_async
  *
  * SYNOPSIS
  *
- *    SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
- *                                        unsigned char *signature,
- *                                        SilcUInt32 signature_len,
- *                                        unsigned char *data,
- *                                        SilcUInt32 data_len,
- *                                        SilcHash hash,
- *                                        SilcPKCSVerifyCb verify_cb,
- *                                        void *context);
+ *    SilcAsyncOperation silc_pkcs_verify_async(SilcPublicKey public_key,
+ *                                              unsigned char *signature,
+ *                                              SilcUInt32 signature_len,
+ *                                              unsigned char *data,
+ *                                              SilcUInt32 data_len,
+ *                                              SilcBool compute_hash,
+ *                                              SilcHash hash,
+ *                                              SilcPKCSVerifyCb verify_cb,
+ *                                              void *context);
  *
  * DESCRIPTION
  *
  *    Verifies signature.  The `verify_cb' will be called to deliver the
  *    result of the verification process.  The 'signature' is verified against
- *    the 'data'.  If the `hash' is non-NULL then the `data' will hashed
- *    before verification.  If the `hash' is NULL, then the hash algorithm
- *    to be used is retrieved from the signature.  If it isn't present in the
- *    signature the verification is done as is without hashing.  The `rng'
- *    is usually not needed and may be NULL.  If this returns NULL the
- *    asynchronous operation cannot be controlled.
+ *    the 'data'.  If `compute_hash' hash is TRUE the `hash' will be used in
+ *    verification.  If `hash' is NULL, the hash algorithm to be used is
+ *    retrieved from the signature.  If it isn't present in the signature the
+ *    default hash function is used.  The `rng' is usually not needed and
+ *    may be NULL.  If this returns NULL the asynchronous operation cannot
+ *    be controlled.
  *
  ***/
-SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
-                                   unsigned char *signature,
-                                   SilcUInt32 signature_len,
-                                   unsigned char *data,
-                                   SilcUInt32 data_len,
-                                   SilcHash hash,
-                                   SilcPKCSVerifyCb verify_cb,
-                                   void *context);
+SilcAsyncOperation silc_pkcs_verify_async(SilcPublicKey public_key,
+                                         unsigned char *signature,
+                                         SilcUInt32 signature_len,
+                                         unsigned char *data,
+                                         SilcUInt32 data_len,
+                                         SilcBool compute_hash,
+                                         SilcHash hash,
+                                         SilcPKCSVerifyCb verify_cb,
+                                         void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_public_key
+/****f* silccrypt/silc_pkcs_load_public_key
  *
  * SYNOPSIS
  *
@@ -729,7 +926,7 @@ SilcBool silc_pkcs_load_public_key(const char *filename,
                                   SilcPKCSType type,
                                   SilcPublicKey *ret_public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_public_key
+/****f* silccrypt/silc_pkcs_save_public_key
  *
  * SYNOPSIS
  *
@@ -747,7 +944,7 @@ SilcBool silc_pkcs_save_public_key(const char *filename,
                                   SilcPublicKey public_key,
                                   SilcPKCSFileEncoding encoding);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_private_key
+/****f* silccrypt/silc_pkcs_load_private_key
  *
  * SYNOPSIS
  *
@@ -773,7 +970,7 @@ SilcBool silc_pkcs_load_private_key(const char *filename,
                                    SilcPKCSType type,
                                    SilcPrivateKey *ret_private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_private_key
+/****f* silccrypt/silc_pkcs_save_private_key
  *
  * SYNOPSIS
  *
@@ -798,7 +995,7 @@ SilcBool silc_pkcs_save_private_key(const char *filename,
                                    SilcPKCSFileEncoding encoding,
                                    SilcRng rng);
 
-/****f* silccrypt/SilcPKCSAPI/silc_hash_public_key
+/****f* silccrypt/silc_hash_public_key
  *
  * SYNOPSIS
  *
@@ -812,7 +1009,7 @@ SilcBool silc_pkcs_save_private_key(const char *filename,
  ***/
 SilcUInt32 silc_hash_public_key(void *key, void *user_context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_hash_public_key_compare
+/****f* silccrypt/silc_hash_public_key_compare
  *
  * SYNOPSIS
  *
index 3041e6a6dc4f3ac5313969b654561cffca5f5f1d..390871e4e3a03b840cfe449f77baa2357389a857 100644 (file)
@@ -21,7 +21,7 @@
 
 #define ENC_LEN 0x00100000     /* enc data len (at least) */
 #define ENC_ROUND 512          /* enc rounds (at least) */
-#define ENC_MIN_TIME 3.0        /* seconds to run the test (at least) */
+#define ENC_MIN_TIME 8.0        /* seconds to run the test (at least) */
 
 SilcTimerStruct timer;
 SilcCipher cipher;
index d9d687a0a2f92b9cc9bf96533428ff035795d316..b33a761f1b5be54d9a011008722c4abe2bbd0286 100644 (file)
@@ -1,4 +1,4 @@
-#include "silc.h"
+#include "silccrypto.h"
 
 /* Test vectors from draft-ietf-ipsec-ciph-sha-256-01.txt */
 
@@ -39,21 +39,19 @@ int main(int argc, char **argv)
     silc_log_set_debug_string("*crypt*,*hash*,*sha256*,*hmac*");
   }
 
-  SILC_LOG_DEBUG(("Registering builtin hash functions"));
-  silc_hash_register_default();
-  silc_hmac_register_default();
+  silc_crypto_init(NULL);
 
   SILC_LOG_DEBUG(("Allocating sha256 HMAC"));
-  if (!silc_hmac_alloc("hmac-sha256", NULL, &hmac)) {
+  if (!silc_mac_alloc("hmac-sha256", &hmac)) {
     SILC_LOG_DEBUG(("Allocating sha256 HMAC failed"));
     goto err;
   }
 
   /* First test vector */
   SILC_LOG_DEBUG(("First test vector"));
-  silc_hmac_init_with_key(hmac, key1, key1_len);
-  silc_hmac_update(hmac, data1, strlen(data1));
-  silc_hmac_final(hmac, digest, &len);
+  silc_mac_init_with_key(hmac, key1, key1_len);
+  silc_mac_update(hmac, data1, strlen(data1));
+  silc_mac_final(hmac, digest, &len);
   SILC_LOG_HEXDUMP(("Key"), (unsigned char *)key1, key1_len);
   SILC_LOG_HEXDUMP(("Message"), (unsigned char *)data1, strlen(data1));
   SILC_LOG_HEXDUMP(("Digest"), digest, len);
@@ -66,9 +64,9 @@ int main(int argc, char **argv)
 
   /* Second test vector */
   SILC_LOG_DEBUG(("Second test vector"));
-  silc_hmac_init_with_key(hmac, key2, key2_len);
-  silc_hmac_update(hmac, data2, strlen(data2));
-  silc_hmac_final(hmac, digest, &len);
+  silc_mac_init_with_key(hmac, key2, key2_len);
+  silc_mac_update(hmac, data2, strlen(data2));
+  silc_mac_final(hmac, digest, &len);
   SILC_LOG_HEXDUMP(("Key"), (unsigned char *)key2, key2_len);
   SILC_LOG_HEXDUMP(("Message"), (unsigned char *)data2, strlen(data2));
   SILC_LOG_HEXDUMP(("Digest"), digest, len);
@@ -81,9 +79,9 @@ int main(int argc, char **argv)
 
   /* Third test vector */
   SILC_LOG_DEBUG(("Third test vector"));
-  silc_hmac_init_with_key(hmac, key3, key3_len);
-  silc_hmac_update(hmac, data3, strlen(data3));
-  silc_hmac_final(hmac, digest, &len);
+  silc_mac_init_with_key(hmac, key3, key3_len);
+  silc_mac_update(hmac, data3, strlen(data3));
+  silc_mac_final(hmac, digest, &len);
   SILC_LOG_HEXDUMP(("Key"), (unsigned char *)key3, key3_len);
   SILC_LOG_HEXDUMP(("Message"), (unsigned char *)data3, strlen(data3));
   SILC_LOG_HEXDUMP(("Digest"), digest, len);
@@ -97,9 +95,9 @@ int main(int argc, char **argv)
   /* Fourth test vector */
   SILC_LOG_DEBUG(("Fourth test vector"));
   memset(key4, '\xaa', key4_len);
-  silc_hmac_init_with_key(hmac, key4, key4_len);
-  silc_hmac_update(hmac, data4, strlen(data4));
-  silc_hmac_final(hmac, digest, &len);
+  silc_mac_init_with_key(hmac, key4, key4_len);
+  silc_mac_update(hmac, data4, strlen(data4));
+  silc_mac_final(hmac, digest, &len);
   SILC_LOG_HEXDUMP(("Key"), (unsigned char *)key4, key4_len);
   SILC_LOG_HEXDUMP(("Message"), (unsigned char *)data4, sizeof(data4));
   SILC_LOG_HEXDUMP(("Digest"), digest, len);
@@ -116,8 +114,8 @@ int main(int argc, char **argv)
   SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
   fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");
 
-  silc_hmac_free(hmac);
-  silc_hash_unregister_all();
-  silc_hmac_unregister_all();
+  silc_mac_free(hmac);
+  silc_crypto_uninit();
+
   return success;
 }
index d119b3d5d94143ecc08ad5b73369282323361593..3772a79bc22f0631f63fc052e3f70b43ca3eaadf 100644 (file)
@@ -573,7 +573,7 @@ SILC_PKCS_IMPORT_PRIVATE_KEY_FILE(silc_pkcs_ssh_import_private_key_file)
   }
 
   /* Decode the private key */
-  ret = silc_pkcs_ssh_import_private_key(pkcs, alg, NULL, 0, filedata, 
+  ret = silc_pkcs_ssh_import_private_key(pkcs, alg, NULL, 0, filedata,
                                         filedata_len, (void *)&privkey,
                                         ret_alg);
   silc_free(data);
@@ -1046,7 +1046,7 @@ SILC_PKCS_VERIFY(silc_pkcs_ssh_verify)
   /* Verify */
   op = pubkey->pkcs->verify(pubkey->pkcs, pubkey->public_key,
                            signature, signature_len,
-                           data, data_len, hash, rng,
+                           data, data_len, compute_hash, hash, rng,
                            verify_cb, context);
 
   silc_free(signame);