+ SILC_LOG_DEBUG(("Registering new HMAC `%s'", hmac->name));
+
+ /* Check for existing */
+ if (silc_hmac_list) {
+ SilcHmacObject *entry;
+ silc_dlist_start(silc_hmac_list);
+ while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
+ if (!strcmp(entry->name, hmac->name))
+ return FALSE;
+ }
+ }
+
+ new = silc_calloc(1, sizeof(*new));
+ new->name = strdup(hmac->name);
+ new->len = hmac->len;
+
+ /* Add to list */
+ if (silc_hmac_list == NULL)
+ silc_hmac_list = silc_dlist_init();
+ silc_dlist_add(silc_hmac_list, new);
+
+ return TRUE;
+}
+
+/* Unregister a HMAC from the SILC. */
+
+bool silc_hmac_unregister(SilcHmacObject *hmac)
+{
+ SilcHmacObject *entry;
+
+ SILC_LOG_DEBUG(("Unregistering HMAC"));
+
+ if (!silc_hmac_list)
+ return FALSE;
+
+ silc_dlist_start(silc_hmac_list);
+ while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
+ if (hmac == SILC_ALL_HMACS || entry == hmac) {
+ silc_dlist_del(silc_hmac_list, entry);
+
+ if (silc_dlist_count(silc_hmac_list) == 0) {
+ silc_dlist_uninit(silc_hmac_list);
+ silc_hmac_list = NULL;
+ }
+
+ return TRUE;
+ }
+ }
+
+ 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'. */
+
+bool silc_hmac_alloc(char *name, SilcHash hash, SilcHmac *new_hmac)
+{
+ SilcHmacObject *entry;
+
+ SILC_LOG_DEBUG(("Allocating new HMAC"));
+
+ /* Allocate the new object */