updates.
[silc.git] / lib / silccrypt / silchmac.c
index 1edfb3813049610adf3f17f67cc704ea9a2b2b77..2c9147a84bbf709e4ff6c669f11b403a5a49fa73 100644 (file)
 /* List of dynamically registered HMACs. */
 SilcDList silc_hmac_list = NULL;
 
+/* Default hmacs for silc_hmac_register_default(). */
+SilcHmacObject silc_default_hmacs[] =
+{
+  { "hmac-sha1-96", 12 },
+  { "hmac-md5-96", 12 },
+  { "hmac-sha1", 20 },
+  { "hmac-md5", 16 },
+
+  { NULL, 0 }
+};
+
 /* Registers a new HMAC into the SILC. This function is used at the
    initialization of the SILC. */
 
-int silc_hmac_register(SilcHmacObject *hmac)
+bool silc_hmac_register(SilcHmacObject *hmac)
 {
   SilcHmacObject *new;
 
@@ -47,7 +58,7 @@ int silc_hmac_register(SilcHmacObject *hmac)
 
 /* Unregister a HMAC from the SILC. */
 
-int silc_hmac_unregister(SilcHmacObject *hmac)
+bool silc_hmac_unregister(SilcHmacObject *hmac)
 {
   SilcHmacObject *entry;
 
@@ -58,7 +69,7 @@ int silc_hmac_unregister(SilcHmacObject *hmac)
 
   silc_dlist_start(silc_hmac_list);
   while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
-    if (entry == hmac) {
+    if (hmac == SILC_ALL_HMACS || entry == hmac) {
       silc_dlist_del(silc_hmac_list, entry);
 
       if (silc_dlist_count(silc_hmac_list) == 0) {
@@ -73,12 +84,26 @@ int silc_hmac_unregister(SilcHmacObject *hmac)
   return FALSE;
 }
 
+/* Function that registers all the default hmacs (all builtin ones). 
+   The application may use this to register the default hmacs if
+   specific hmacs in any specific order is not wanted. */
+
+bool silc_hmac_register_default(void)
+{
+  int i;
+
+  for (i = 0; silc_default_hmacs[i].name; i++)
+    silc_hmac_register(&(silc_default_hmacs[i]));
+
+  return TRUE;
+}
+
 /* Allocates a new SilcHmac object of name of `name'.  The `hash' may
    be provided as argument.  If provided it is used as the hash function
    of the HMAC.  If it is NULL then the hash function is allocated and
    the name of the hash algorithm is derived from the `name'. */
 
-int silc_hmac_alloc(char *name, SilcHash hash, SilcHmac *new_hmac)
+bool silc_hmac_alloc(char *name, SilcHash hash, SilcHmac *new_hmac)
 {
   SilcHmacObject *entry;
 
@@ -133,14 +158,14 @@ void silc_hmac_free(SilcHmac hmac)
 
 /* Returns the length of the MAC that the HMAC will produce. */
 
-unsigned int silc_hmac_len(SilcHmac hmac)
+uint32 silc_hmac_len(SilcHmac hmac)
 {
   return hmac->hmac->len;
 }
 
 /* Returns TRUE if HMAC `name' is supported. */
 
-int silc_hmac_is_supported(const char *name)
+bool silc_hmac_is_supported(const char *name)
 {
   SilcHmacObject *entry;
 
@@ -188,8 +213,12 @@ char *silc_hmac_get_supported()
 /* Sets the HMAC key used in the HMAC creation */
 
 void silc_hmac_set_key(SilcHmac hmac, const unsigned char *key,
-                      unsigned int key_len)
+                      uint32 key_len)
 {
+  if (hmac->key) {
+    memset(hmac->key, 0, hmac->key_len);
+    silc_free(hmac->key);
+  }
   hmac->key = silc_calloc(key_len, sizeof(unsigned char));
   hmac->key_len = key_len;
   memcpy(hmac->key, key, key_len);
@@ -199,8 +228,8 @@ void silc_hmac_set_key(SilcHmac hmac, const unsigned char *key,
    return_hash argument. */
 
 void silc_hmac_make_internal(SilcHmac hmac, unsigned char *data,
-                            unsigned int data_len, unsigned char *key,
-                            unsigned int key_len, unsigned char *return_hash)
+                            uint32 data_len, unsigned char *key,
+                            uint32 key_len, unsigned char *return_hash)
 {
   SilcHash hash = hmac->hash;
   unsigned char inner_pad[hash->hash->block_len + 1];
@@ -246,14 +275,15 @@ void silc_hmac_make_internal(SilcHmac hmac, unsigned char *data,
   hash->hash->final(hash_context, mac);
   memcpy(return_hash, mac, hmac->hmac->len);
   memset(mac, 0, sizeof(mac));
+  silc_free(hash_context);
 }
 
 /* Create the HMAC. This is thee make_hmac function pointer.  This
    uses the internal key set with silc_hmac_set_key. */
 
 void silc_hmac_make(SilcHmac hmac, unsigned char *data,
-                   unsigned int data_len, unsigned char *return_hash,
-                   unsigned int *return_len)
+                   uint32 data_len, unsigned char *return_hash,
+                   uint32 *return_len)
 {
   silc_hmac_make_internal(hmac, data, data_len, hmac->key, 
                          hmac->key_len, return_hash);
@@ -265,10 +295,10 @@ void silc_hmac_make(SilcHmac hmac, unsigned char *data,
    key. The key is sent as argument to the function. */
 
 void silc_hmac_make_with_key(SilcHmac hmac, unsigned char *data,
-                            unsigned int data_len, 
-                            unsigned char *key, unsigned int key_len,
+                            uint32 data_len, 
+                            unsigned char *key, uint32 key_len,
                             unsigned char *return_hash,
-                            unsigned int *return_len)
+                            uint32 *return_len)
 {
   silc_hmac_make_internal(hmac, data, data_len, key, key_len, return_hash);
   if (return_len)
@@ -281,8 +311,8 @@ void silc_hmac_make_with_key(SilcHmac hmac, unsigned char *data,
    routine allows these dangerous truncations. */
 
 void silc_hmac_make_truncated(SilcHmac hmac, unsigned char *data,
-                             unsigned int data_len,
-                             unsigned int truncated_len,
+                             uint32 data_len,
+                             uint32 truncated_len,
                              unsigned char *return_hash)
 {
   unsigned char hvalue[hmac->hash->hash->hash_len];