ROBODoc documented the SILC Hash Interface and improved
authorPekka Riikonen <priikone@silcnet.org>
Sat, 15 Jun 2002 19:38:36 +0000 (19:38 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 15 Jun 2002 19:38:36 +0000 (19:38 +0000)
the interface a bit too.

13 files changed:
CHANGES
TODO
apps/silcd/protocol.c
lib/silcclient/protocol.c
lib/silccrypt/DIRECTORY
lib/silccrypt/sha1.c
lib/silccrypt/silchash.c
lib/silccrypt/silchash.h
lib/silccrypt/silchmac.c
lib/silccrypt/silchmac.h
lib/silccrypt/silcpkcs.c
lib/silccrypt/silcrng.c
lib/silcske/silcske.c

diff --git a/CHANGES b/CHANGES
index 715fed19e6918cd78d4c867f1465b7d89b114f69..64943042eba94e8cb83f1bfdc82e47868b940974 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,11 @@ Sat Jun 15 18:23:39 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
          server statistics into /tmp directory.  Affected file is
          silcd/silcd.c.
 
+       * ROBODoc documented the lib/silccrypt/silchash.h.  Improved
+         the SILC Hash Interface also.  Added new functions
+         silc_hash_get_name, silc_hash_init, silc_hash_update and
+         silc_hash_final.  Affected file lib/silccrypt/silchash.c.
+
 Sat Jun 15 12:09:14 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Added some better info printing for client during connecting.
diff --git a/TODO b/TODO
index 737c025e68ce61a4b0631b2f5f378c7e6de24fa2..c09bd0be9bdd3c22f8d9d53a2b7711f03c08615a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -55,8 +55,6 @@ Manual (Do these to 0.9.x).
 
  o ROBOdoc documenting missing from lib/silcutil/silcfileutil.h.
 
- o ROBOdoc documenting missing from lib/silccrypt/silchash.h.
-
  o ROBOdoc documenting missing from lib/silccrypt/silccipher.h.
 
  o ROBOdoc documenting missing from lib/silccrypt/silcpkcs.h.
index 6aa3ac93b54cb432493347297b4c5d26aab35340..75eb86ed70906707402d6143279145f87e9b5082 100644 (file)
@@ -291,13 +291,14 @@ int silc_server_protocol_ke_set_keys(SilcServer server,
   idata->rekey->ske_group = silc_ske_group_get_number(group);
 
   /* Save the hash */
-  if (!silc_hash_alloc(hash->hash->name, &idata->hash)) {
+  if (!silc_hash_alloc(silc_hash_get_name(hash), &idata->hash)) {
     silc_cipher_free(idata->send_key);
     silc_cipher_free(idata->receive_key);
     silc_hmac_free(idata->hmac_send);
     silc_hmac_free(idata->hmac_receive);
     silc_free(conn_data);
-    SILC_LOG_ERROR(("Cannot allocate algorithm: %s", hash->hash->name));
+    SILC_LOG_ERROR(("Cannot allocate algorithm: %s", 
+                   silc_hash_get_name(hash)));
     return FALSE;
   }
 
@@ -314,7 +315,7 @@ int silc_server_protocol_ke_set_keys(SilcServer server,
                 sock->hostname, sock->ip,
                 idata->send_key->cipher->name,
                 (char *)silc_hmac_get_name(idata->hmac_send),
-                idata->hash->hash->name, 
+                silc_hash_get_name(idata->hash),
                 ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : ""));
 
   return TRUE;
@@ -590,7 +591,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
        */
       SilcSKEKeyMaterial *keymat;
       int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
-      int hash_len = ctx->ske->prop->hash->hash->hash_len;
+      int hash_len = silc_hash_len(ctx->ske->prop->hash);
 
       /* Process the key material */
       keymat = silc_calloc(1, sizeof(*keymat));
@@ -1236,7 +1237,7 @@ void silc_server_protocol_rekey_generate(SilcServer server,
   SilcIDListData idata = (SilcIDListData)ctx->sock->user_data;
   SilcSKEKeyMaterial *keymat;
   SilcUInt32 key_len = silc_cipher_get_key_len(idata->send_key);
-  SilcUInt32 hash_len = idata->hash->hash->hash_len;
+  SilcUInt32 hash_len = silc_hash_len(idata->hash);
 
   SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
                  send ? "sending" : "receiving"));
@@ -1265,7 +1266,7 @@ silc_server_protocol_rekey_generate_pfs(SilcServer server,
   SilcIDListData idata = (SilcIDListData)ctx->sock->user_data;
   SilcSKEKeyMaterial *keymat;
   SilcUInt32 key_len = silc_cipher_get_key_len(idata->send_key);
-  SilcUInt32 hash_len = idata->hash->hash->hash_len;
+  SilcUInt32 hash_len = silc_hash_len(idata->hash);
   unsigned char *tmpbuf;
   SilcUInt32 klen;
 
index 4e955a6efc4797e73cdfb9566146702098be40c4..e2f6454cab852c34ae93d1eb0f9a543a0ed8dab1 100644 (file)
@@ -161,7 +161,7 @@ void silc_client_protocol_ke_set_keys(SilcSKE ske,
   conn->rekey->ske_group = silc_ske_group_get_number(group);
 
   /* Save the HASH function */
-  silc_hash_alloc(hash->hash->name, &conn->hash);
+  silc_hash_alloc(silc_hash_get_name(hash), &conn->hash);
 }
 
 /* Checks the version string of the server. */
@@ -450,7 +450,7 @@ SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
        */
       SilcSKEKeyMaterial *keymat;
       int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
-      int hash_len = ctx->ske->prop->hash->hash->hash_len;
+      int hash_len = silc_hash_len(ctx->ske->prop->hash);
 
       /* Process the key material */
       keymat = silc_calloc(1, sizeof(*keymat));
@@ -792,7 +792,7 @@ silc_client_protocol_rekey_generate(SilcClient client,
   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
   SilcSKEKeyMaterial *keymat;
   SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
-  SilcUInt32 hash_len = conn->hash->hash->hash_len;
+  SilcUInt32 hash_len = silc_hash_len(conn->hash);
 
   SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
                  send ? "sending" : "receiving"));
@@ -821,7 +821,7 @@ silc_client_protocol_rekey_generate_pfs(SilcClient client,
   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
   SilcSKEKeyMaterial *keymat;
   SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
-  SilcUInt32 hash_len = conn->hash->hash->hash_len;
+  SilcUInt32 hash_len = silc_hash_len(conn->hash);
   unsigned char *tmpbuf;
   SilcUInt32 klen;
 
index 370ccdc261f4caad9575b79f13ae2aa13c2cca7b..8ed7268597f88f63b4fe9f5376791b96d60ac85c 100644 (file)
@@ -4,8 +4,8 @@
 @LINK=silcrng_intro.html:Introduction to SILC RNG
 @LINK=silcrng.html:SILC RNG Interface
 @LINK=silchmac.html:SILC HMAC Interface
+@LINK=silchash.html:SILC Hash Interface
 @LINK=silccipher.html:SILC Cipher API
-@LINK=silchash.html:SILC Hash API
 @LINK=silcpkcs.html:SILC PKCS API
 -->
 
index 9c6465c67dda095f4284135e0e74ef76a75b2ca6..c75be8662245c5e822e952fc411475a17d8acafd 100644 (file)
@@ -20,7 +20,7 @@ SILC_HASH_API_INIT(sha1)
 
 SILC_HASH_API_UPDATE(sha1)
 {
-  SHA1Update((SHA1_CTX *)context, data, len);
+  SHA1Update((SHA1_CTX *)context, (unsigned char *)data, len);
 }
 
 SILC_HASH_API_FINAL(sha1)
index 5e740df5c9baebe29d528b3997e38ee321dc05f9..52419b0b296635091e1eff4b3cb2343d494242e3 100644 (file)
 #include "md5.h"
 #include "sha1.h"
 
+/* The main SILC hash structure. */
+struct SilcHashStruct {
+  SilcHashObject *hash;
+  void *context;
+};
+
 #ifndef SILC_EPOC
 /* List of dynamically registered hash functions. */
 SilcDList silc_hash_list = NULL;
@@ -159,7 +165,6 @@ bool silc_hash_alloc(const unsigned char *name, SilcHash *new_hash)
     *new_hash = silc_calloc(1, sizeof(**new_hash));
     (*new_hash)->hash = entry;
     (*new_hash)->context = silc_calloc(1, entry->context_len());
-    (*new_hash)->make_hash = silc_hash_make;
     return TRUE;
   }
 
@@ -183,6 +188,20 @@ SilcUInt32 silc_hash_len(SilcHash hash)
   return hash->hash->hash_len;
 }
 
+/* Returns the block lenght of the hash. */
+
+SilcUInt32 silc_hash_block_len(SilcHash hash)
+{
+  return hash->hash->block_len;
+}
+
+/* Returns the name of the hash function */
+
+const char *silc_hash_get_name(SilcHash hash)
+{
+  return hash->hash->name;
+}
+
 /* Returns TRUE if hash algorithm `name' is supported. */
 
 bool silc_hash_is_supported(const unsigned char *name)
@@ -254,14 +273,36 @@ char *silc_hash_get_supported(void)
 
 void silc_hash_make(SilcHash hash, const unsigned char *data, 
                    SilcUInt32 len, unsigned char *return_hash)
+{
+  silc_hash_init(hash);
+  silc_hash_update(hash, data, len);
+  silc_hash_final(hash, return_hash);
+}
+
+void silc_hash_init(SilcHash hash)
 {
   hash->hash->init(hash->context);
-  hash->hash->update(hash->context, (unsigned char *)data, len);
+}
+
+void silc_hash_update(SilcHash hash, const unsigned char *data,
+                     SilcUInt32 data_len)
+{
+  hash->hash->update(hash->context, (unsigned char *)data, data_len);
+}
+
+void silc_hash_final(SilcHash hash, unsigned char *return_hash)
+{
   hash->hash->final(hash->context, return_hash);
 }
 
+void silc_hash_transform(SilcHash hash, SilcUInt32 *state,
+                        const unsigned char *data)
+{
+  hash->hash->transform(state, data);
+}
+
 /* Creates fingerprint of the data. If `hash' is NULL SHA1 is used as
-   default hash function. The returned fingerprint must be free's by the
+   default hash function. The returned fingerprint must be freed by the
    caller. */
 
 char *silc_hash_fingerprint(SilcHash hash, const unsigned char *data,
index cf4a6be4a7e4dd4c6c7a7216acaa5023ce6ff5f6..b076d55f110e1c71dda133d6ed4797f3f2bc4d32 100644 (file)
@@ -1,16 +1,15 @@
 /*
 
-  silchash.h
+  silchash.h 
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2001 Pekka Riikonen
+  Copyright (C) 1999 - 2002 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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-  
+  the Free Software Foundation; version 2 of the License.
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #ifndef SILCHASH_H
 #define SILCHASH_H
 
-/* The default Silc hash object to represent any hash function in SILC. */
+/****h* silccrypt/SILC Hash Interface
+ *
+ * DESCRIPTION
+ *
+ *    This is the interface for hash functions which are used to create
+ *    message digests.  The routines are used in various cryptographic
+ *    operations.  SILC Hash Interface is used for example by the
+ *    SILC HMAC Interface (SilcHmac).
+ *
+ ***/
+
+/****s* silccrypt/SilcHashAPI/SilcHash
+ *
+ * NAME
+ * 
+ *    typedef struct SilcHashStruct *SilcHash;
+ *
+ * DESCRIPTION
+ *
+ *    This context is the actual hash function context and is allocated
+ *    by silc_hash_alloc and given as argument usually to all
+ *    silc_hash_* functions.  It is freed by the silc_hash_free
+ *    function.
+ *
+ ***/
+typedef struct SilcHashStruct *SilcHash;
+
+/****s* silccrypt/SilcHashAPI/SilcHashObject
+ *
+ * NAME
+ * 
+ *    typedef struct { ... } SilcHashObject;
+ *
+ * DESCRIPTION
+ *
+ *    This structure represents one hash function.  The hash function's
+ *    name, digest length and block length are defined in the structure.
+ *    This structure is then given as argument to the silc_hash_register.
+ *    That function is used to register all hash functions into SILC.
+ *    They can be then allocated by the name found in this structure by
+ *    calling the silc_hash_alloc.
+ *
+ ***/
 typedef struct {
   char *name;
   SilcUInt32 hash_len;
   SilcUInt32 block_len;
 
   void (*init)(void *);
-  void (*update)(void *, unsigned char *, SilcUInt32);
+  void (*update)(void *, const unsigned char *, SilcUInt32);
   void (*final)(void *, unsigned char *);
-  void (*transform)(SilcUInt32 *, unsigned char *);
+  void (*transform)(SilcUInt32 *, const unsigned char *);
   SilcUInt32 (*context_len)();
 } SilcHashObject;
 
-/* The main SILC hash structure. Use SilcHash instead of SilcHashStruct.
-   Also remember that SilcHash is a pointer. */
-typedef struct SilcHashStruct {
-  SilcHashObject *hash;
-  void *context;
-
-  void (*make_hash)(struct SilcHashStruct *, const unsigned char *, 
-                   SilcUInt32, unsigned char *);
-} *SilcHash;
-
 /* Marks for all hash functions. This can be used in silc_hash_unregister
    to unregister all hash function at once. */
 #define SILC_ALL_HASH_FUNCTIONS ((SilcHashObject *)1)
@@ -72,30 +103,313 @@ extern DLLAPI const SilcHashObject silc_default_hash[];
 /* Macros that can be used to declare SILC Hash API functions. */
 #define SILC_HASH_API_INIT(hash)               \
 void silc_##hash##_init(void *context)
-#define SILC_HASH_API_UPDATE(hash)                             \
-void silc_##hash##_update(void *context, unsigned char *data,  \
-                                       SilcUInt32 len)
+#define SILC_HASH_API_UPDATE(hash)                                     \
+void silc_##hash##_update(void *context, const unsigned char *data,    \
+                          SilcUInt32 len)
 #define SILC_HASH_API_FINAL(hash)                              \
 void silc_##hash##_final(void *context, unsigned char *digest)
 #define SILC_HASH_API_TRANSFORM(hash)                                  \
-void silc_##hash##_transform(SilcUInt32 *state,                        \
-                                         unsigned char *buffer)
+void silc_##hash##_transform(SilcUInt32 *state,        const unsigned char *buffer)
 #define SILC_HASH_API_CONTEXT_LEN(hash)                \
 SilcUInt32 silc_##hash##_context_len()
 
 /* Prototypes */
+
+/****f* silccrypt/SilcHashAPI/silc_hash_register
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_hash_register(const SilcHashObject *hash);
+ *
+ * DESCRIPTION
+ *
+ *    Registers a new hash function into the SILC.  This function is used
+ *    at the initialization of the SILC.  All registered hash functions
+ *    should be unregistered with silc_hash_unregister.  The `hash' includes
+ *    the name of the hash function, digest length and block length.  Usually
+ *    this function is not called directly.  Instead, application can call
+ *    the silc_hash_register_default to register all default hash functions
+ *    that are builtin the sources.  Returns FALSE on error.
+ *
+ ***/
 bool silc_hash_register(const SilcHashObject *hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_unregister
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_hash_unregister(SilcHashObject *hash);
+ *
+ * DESCRIPTION
+ *
+ *    Unregister a hash function from SILC by the SilcHashObject `hash'.
+ *    This should be called for all registered hash functions.  Returns
+ *    FALSE on error.
+ *
+ ***/
 bool silc_hash_unregister(SilcHashObject *hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_register_default
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_hash_register_default(void);
+ *
+ * DESCRIPTION
+ *
+ *    Registers all default hash functions into the SILC.  These are the
+ *    hash functions that are builtin in the sources.  See the list of
+ *    default hash functions in the silchash.c source file.  The application
+ *    may use this to register default hash functions if specific hash
+ *    function in any specific order is not wanted (application's
+ *    configuration usually may decide the order of the registration, in
+ *    which case this function should not be used).
+ *
+ ***/
 bool silc_hash_register_default(void);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_alloc
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_hash_alloc(const unsigned char *name, SilcHash *new_hash);
+ *
+ * DESCRIPTION
+ *
+ *    Allocates a new SilcHash object of name of `name'.  The new allocated
+ *    hash function is returned into `new_hash' pointer.  This function
+ *    returns FALSE if such hash function does not exist.
+ *
+ ***/
 bool silc_hash_alloc(const unsigned char *name, SilcHash *new_hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_free
+ *
+ * SYNOPSIS
+ *
+ *    void silc_hash_free(SilcHash hash);
+ *
+ * DESCRIPTION
+ *
+ *    Frees the allocated hash function context.
+ *
+ ***/
 void silc_hash_free(SilcHash hash);
-SilcUInt32 silc_hash_len(SilcHash hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_is_supported
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_hash_is_supported(const unsigned char *name);
+ *
+ * DESCRIPTION
+ *
+ *    Returns TRUE if the hash function indicated by the `name' exists.
+ *
+ ***/
 bool silc_hash_is_supported(const unsigned char *name);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_get_supported
+ *
+ * SYNOPSIS
+ *
+ *    char *silc_hash_get_supported(void);
+ *
+ * DESCRIPTION
+ *
+ *    Returns comma (`,') separated list of registered hash functions  This
+ *    is used for example when sending supported hash function list during
+ *    the SILC Key Exchange protocol (SKE).  The caller must free the returned
+ *    pointer.
+ *
+ ***/
 char *silc_hash_get_supported(void);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_len
+ *
+ * SYNOPSIS
+ *
+ *    SilcUInt32 silc_hash_len(SilcHash hash);
+ *
+ * DESCRIPTION
+ *
+ *    Returns the length of the message digest the hash function produce.
+ *
+ ***/
+SilcUInt32 silc_hash_len(SilcHash hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_block_len
+ *
+ * SYNOPSIS
+ *
+ *    SilcUInt32 silc_hash_block_len(SilcHash hash);
+ *
+ * DESCRIPTION
+ *
+ *    Returns the block length of the hash function.
+ *
+ ***/
+SilcUInt32 silc_hash_block_len(SilcHash hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_get_name
+ *
+ * SYNOPSIS
+ *
+ *    const char *silc_hash_get_name(SilcHash hash);
+ *
+ * DESCRIPTION
+ *
+ *    Returns the name of the hash function indicated by the `hash' context.
+ *
+ ***/
+const char *silc_hash_get_name(SilcHash hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_make
+ *
+ * SYNOPSIS
+ *
+ *    void silc_hash_make(SilcHash hash, const unsigned char *data,
+ *                        SilcUInt32 len, unsigned char *return_hash);
+ *
+ * DESCRIPTION
+ *
+ *    Computes the message digest (hash) out of the data indicated by
+ *    `data' of length of `len' bytes.  Returns the message digest to the
+ *    `return_hash' buffer which must be at least of the size of the
+ *    message digest the `hash' produces.
+ *
+ ***/
 void silc_hash_make(SilcHash hash, const unsigned char *data,
                    SilcUInt32 len, unsigned char *return_hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_init
+ *
+ * SYNOPSIS
+ *
+ *    void silc_hash_init(SilcHash hash);
+ *
+ * DESCRIPTION
+ *
+ *    Sometimes calling the silc_hash_make might not be the most optimal
+ *    case of computing digests.  If you have a lot of different data
+ *    that you need to put together for computing a digest you may either
+ *    put them into a buffer and compute the digest from the buffer by
+ *    calling the silc_hash_make, or you can use the silc_hash_init,
+ *    silc_hash_update and silc_hash_final to do the digest.  This function
+ *    prepares the allocated hash function context for this kind of digest 
+ *    computation.  To add the data to be used in the digest computation
+ *    call the silc_hash_update function.
+ *
+ ***/
+void silc_hash_init(SilcHash hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_update
+ *
+ * SYNOPSIS
+ *
+ *    void silc_hash_update(SilcHash hash, const unsigned char *data,
+ *                          SilcUInt32 data_len);
+ *
+ * DESCRIPTION
+ *
+ *    This function may be called to add data to be used in the digest
+ *    computation.  This can be called multiple times to add data from
+ *    many sources before actually computing the digest.  Once you've
+ *    added all the data you need you can call the silc_hash_final to
+ *    actually produce the message digest value.
+ *
+ * EXAMPLE
+ *
+ *    unsigned char digest[20];
+ *
+ *    silc_hash_init(hash);
+ *    silc_hash_update(hash, data, data_len);
+ *    silc_hash_update(hash, more_data, more_data_len);
+ *    silc_hash_final(hash, digest);
+ *
+ ***/
+void silc_hash_update(SilcHash hash, const unsigned char *data,
+                     SilcUInt32 data_len);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_final
+ *
+ * SYNOPSIS
+ *
+ *    void silc_hash_final(SilcHash hash, unsigned char *return_hash);
+ *
+ * DESCRIPTION
+ *
+ *    This function is used to produce the final message digest from
+ *    the data that has been added to the hash function context by calling
+ *    the silc_hash_update function.  The digest is copied in to the
+ *    `return_hash' pointer which must be at least the size that
+ *    the silc_hash_len returns.
+ *
+ ***/
+void silc_hash_final(SilcHash hash, unsigned char *return_hash);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_transform
+ *
+ * SYNOPSIS
+ *
+ *    void silc_hash_transform(SilcHash hash, SilcUInt32 *state,
+ *                             const unsigned char *data);
+ *
+ * DESCRIPTION
+ *
+ *    This is special function for calling the hash function's internal
+ *    digest generation function.  The size of the `state' array and the
+ *    sizeof the `data' buffer is hash function specific and must be
+ *    known by the caller.  Usually this function is not needed.
+ *
+ ***/
+void silc_hash_transform(SilcHash hash, SilcUInt32 *state,
+                        const unsigned char *data);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_fingerprint
+ *
+ * SYNOPSIS
+ *
+ *    char *silc_hash_fingerprint(SilcHash hash, const unsigned char *data,
+ *                                SilcUInt32 data_len);
+ *
+ * DESCRIPTION
+ *
+ *    Utility function which can be used to create a textual fingerprint
+ *    out of the data indicated by `data' of length of `data_len' bytes.
+ *    If `hash' is NULL then SHA1 hash function is used automatically.
+ *    The caller must free the returned string.
+ *
+ *    Example output could be:
+ *      41BF 5C2E 4149 039A 3917  831F 65C4 0A69 F98B 0A4D
+ *
+ ***/
 char *silc_hash_fingerprint(SilcHash hash, const unsigned char *data,
                            SilcUInt32 data_len);
+
+/****f* silccrypt/SilcHashAPI/silc_hash_babbleprint
+ *
+ * SYNOPSIS
+ *
+ *    char *silc_hash_babbleprint(SilcHash hash, const unsigned char *data,
+ *                                SilcUInt32 data_len);
+ *
+ * DESCRIPTION
+ *
+ *    Utility function which can be used to create a textual bableprint
+ *    out of the data indicated by `data' of length of `data_len' bytes.
+ *    If `hash' is NULL then SHA1 hash function is used automatically.
+ *    The caller must free the returned string.
+ *
+ *    The babbleprint is same as fingerprint but encoded in a form which
+ *    makes it easier to pronounce.  When verifying fingerprint for example
+ *    over a phone call, the babbleprint makes it easier to read the
+ *    fingerprint.
+ *
+ *    Example output could be:
+ *      xiber-zulad-vubug-noban-puvyc-labac-zonos-gedik-novem-rudog-tyxix
+ *
+ ***/
 char *silc_hash_babbleprint(SilcHash hash, const unsigned char *data,
                            SilcUInt32 data_len);
 
index dfde14da034cb6333c9da80c2863d9c6cf0759c5..970cc6001d1736c90d0909d835910e2322fbc390 100644 (file)
 struct SilcHmacStruct {
   SilcHmacObject *hmac;
   SilcHash hash;
-  bool allocated_hash;         /* TRUE if the hash was allocated */
 
   unsigned char *key;
   SilcUInt32 key_len;
 
   unsigned char inner_pad[64];
   unsigned char outer_pad[64];
-  void *hash_context;
+  bool allocated_hash;         /* TRUE if the hash was allocated */
 };
 
 #ifndef SILC_EPOC
@@ -54,18 +53,21 @@ static void silc_hmac_init_internal(SilcHmac hmac, unsigned char *key,
                                    SilcUInt32 key_len)
 {
   SilcHash hash = hmac->hash;
+  SilcUInt32 block_len;
   unsigned char hvalue[20];
   int i;
 
   memset(hmac->inner_pad, 0, sizeof(hmac->inner_pad));
   memset(hmac->outer_pad, 0, sizeof(hmac->outer_pad));
 
+  block_len = silc_hash_block_len(hash);
+
   /* If the key length is more than block size of the hash function, the
      key is hashed. */
-  if (key_len > hash->hash->block_len) {
+  if (key_len > block_len) {
     silc_hash_make(hash, key, key_len, hvalue);
     key = hvalue;
-    key_len = hash->hash->hash_len;
+    key_len = silc_hash_len(hash);
   }
 
   /* Copy the key into the pads */
@@ -73,7 +75,7 @@ static void silc_hmac_init_internal(SilcHmac hmac, unsigned char *key,
   memcpy(hmac->outer_pad, key, key_len);
 
   /* XOR the key with pads */
-  for (i = 0; i < hash->hash->block_len; i++) {
+  for (i = 0; i < block_len; i++) {
     hmac->inner_pad[i] ^= 0x36;
     hmac->outer_pad[i] ^= 0x5c;
   }
@@ -234,7 +236,6 @@ void silc_hmac_free(SilcHmac hmac)
       silc_free(hmac->key);
     }
 
-    silc_free(hmac->hash_context);
     silc_free(hmac);
   }
 }
@@ -408,15 +409,9 @@ void silc_hmac_init_with_key(SilcHmac hmac, const unsigned char *key,
                             SilcUInt32 key_len)
 {
   SilcHash hash = hmac->hash;
-
   silc_hmac_init_internal(hmac, hmac->key, hmac->key_len);
-
-  if (!hmac->hash_context)
-    hmac->hash_context = silc_calloc(1, hash->hash->context_len());
-
-  hash->hash->init(hmac->hash_context);
-  hash->hash->update(hmac->hash_context, hmac->inner_pad, 
-                    hash->hash->block_len);
+  silc_hash_init(hash);
+  silc_hash_update(hash, hmac->inner_pad, silc_hash_block_len(hash));
 }
 
 /* Add data to be used in the MAC computation. */
@@ -425,7 +420,7 @@ void silc_hmac_update(SilcHmac hmac, const unsigned char *data,
                      SilcUInt32 data_len)
 {
   SilcHash hash = hmac->hash;
-  hash->hash->update(hmac->hash_context, (unsigned char *)data, data_len);
+  silc_hash_update(hash, data, data_len);
 }
 
 /* Compute the final MAC. */
@@ -436,12 +431,11 @@ void silc_hmac_final(SilcHmac hmac, unsigned char *return_hash,
   SilcHash hash = hmac->hash;
   unsigned char mac[20];
 
-  hash->hash->final(hmac->hash_context, mac);
-  hash->hash->init(hmac->hash_context);
-  hash->hash->update(hmac->hash_context, hmac->outer_pad, 
-                    hash->hash->block_len);
-  hash->hash->update(hmac->hash_context, mac, hash->hash->hash_len);
-  hash->hash->final(hmac->hash_context, mac);
+  silc_hash_final(hash, mac);
+  silc_hash_init(hash);
+  silc_hash_update(hash, hmac->outer_pad, silc_hash_block_len(hash));
+  silc_hash_update(hash, mac, silc_hash_len(hash));
+  silc_hash_final(hash, mac);
   memcpy(return_hash, mac, hmac->hmac->len);
   memset(mac, 0, sizeof(mac));
 
index ae9ab2e3d35b4cdfdc4c9b0e3e0833de6ecad17f..c9b3bed046e6227cb247bf8e3fb2df9e8d136efa 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1999 - 2001 Pekka Riikonen
+  Copyright (C) 1999 - 2002 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
index 8aa9d516e8867ff986e230cad3ffe098edc5533a..0a5bd31bad465cdf72faa422f10fe8f18d015517 100644 (file)
@@ -361,7 +361,7 @@ int silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
   int ret;
 
   silc_hash_make(hash, src, src_len, hashr);
-  hash_len = hash->hash->hash_len;
+  hash_len = silc_hash_len(hash);
 
   SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
 
@@ -385,7 +385,7 @@ int silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
   int ret;
 
   silc_hash_make(hash, data, data_len, hashr);
-  hash_len = hash->hash->hash_len;
+  hash_len = silc_hash_len(hash);
 
   SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
 
index 3d7b031ad5543ccd5f5901761f9d54813791a11a..4fa86fa4f37d0066be9a3fd05af6102a8e2f2fd4 100644 (file)
@@ -399,7 +399,7 @@ static void silc_rng_stir_pool(SilcRng rng)
 
   /* First CFB pass */
   for (i = 0; i < SILC_RNG_POOLSIZE; i += 5) {
-    rng->sha1->hash->transform(iv, rng->key);
+    silc_hash_transform(rng->sha1, iv, rng->key);
     iv[0] = rng->pool[i] ^= iv[0];
     iv[1] = rng->pool[i + 1] ^= iv[1];
     iv[2] = rng->pool[i + 2] ^= iv[2];
@@ -412,7 +412,7 @@ static void silc_rng_stir_pool(SilcRng rng)
 
   /* Second CFB pass */
   for (i = 0; i < SILC_RNG_POOLSIZE; i += 5) {
-    rng->sha1->hash->transform(iv, rng->key);
+    silc_hash_transform(rng->sha1, iv, rng->key);
     iv[0] = rng->pool[i] ^= iv[0];
     iv[1] = rng->pool[i + 1] ^= iv[1];
     iv[2] = rng->pool[i + 2] ^= iv[2];
index 756d505d52f78f536c822ee02494d2839aa5c159..5e277b838b142c7008c51397d677e2cd52f6c8d0 100644 (file)
@@ -1695,7 +1695,7 @@ static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
 
   /* Make the hash */
   silc_hash_make(ske->prop->hash, buf->data, buf->len, return_hash);
-  *return_hash_len = ske->prop->hash->hash->hash_len;
+  *return_hash_len = silc_hash_len(ske->prop->hash);
 
   if (initiator == FALSE) {
     SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);