X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Fsilchash.c;h=4bb91087de51a278d8478aefd2cbc773f54a221c;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=819a2fab377fdeadafa1d54fd7597f63d9df93db;hpb=d8d491f554988814894c0573211e31cfeca0a4e5;p=silc.git diff --git a/lib/silccrypt/silchash.c b/lib/silccrypt/silchash.c index 819a2fab..4bb91087 100644 --- a/lib/silccrypt/silchash.c +++ b/lib/silccrypt/silchash.c @@ -47,6 +47,16 @@ bool silc_hash_register(SilcHashObject *hash) SILC_LOG_DEBUG(("Registering new hash function `%s'", hash->name)); + /* Check for existing */ + if (silc_hash_list) { + SilcHashObject *entry; + silc_dlist_start(silc_hash_list); + while ((entry = silc_dlist_get(silc_hash_list)) != SILC_LIST_END) { + if (!strcmp(entry->name, hash->name)) + return FALSE; + } + } + new = silc_calloc(1, sizeof(*new)); new->name = strdup(hash->name); new->hash_len = hash->hash_len; @@ -144,7 +154,7 @@ void silc_hash_free(SilcHash hash) /* Returns the length of the hash digest. */ -uint32 silc_hash_len(SilcHash hash) +SilcUInt32 silc_hash_len(SilcHash hash) { return hash->hash->hash_len; } @@ -195,7 +205,7 @@ char *silc_hash_get_supported(void) /* Creates the hash value and returns it to the return_hash argument. */ void silc_hash_make(SilcHash hash, const unsigned char *data, - uint32 len, unsigned char *return_hash) + SilcUInt32 len, unsigned char *return_hash) { hash->hash->init(hash->context); hash->hash->update(hash->context, (unsigned char *)data, len); @@ -207,34 +217,91 @@ void silc_hash_make(SilcHash hash, const unsigned char *data, caller. */ char *silc_hash_fingerprint(SilcHash hash, const unsigned char *data, - uint32 data_len) + SilcUInt32 data_len) { - char fingerprint[64], *cp; + SilcHash new_hash = NULL; unsigned char h[32]; - int i; + char *ret; - if (!hash) - silc_hash_alloc("sha1", &hash); + if (!hash) { + silc_hash_alloc("sha1", &new_hash); + hash = new_hash; + } silc_hash_make(hash, data, data_len, h); - - memset(fingerprint, 0, sizeof(fingerprint)); - cp = fingerprint; - for (i = 0; i < hash->hash->hash_len; i++) { - snprintf(cp, sizeof(fingerprint), "%02X", h[i]); - cp += 2; + ret = silc_fingerprint(h, hash->hash->hash_len); + + if (new_hash != NULL) + silc_hash_free(new_hash); + return ret; +} + +static const char vo[]= "aeiouy"; +static const char co[]= "bcdfghklmnprstvzx"; + +/* Creates a babbleprint (Bubble Babble Encoding, developed by Antti + Huima (draft-huima-babble-01.txt)), by first computing real fingerprint + using `hash' or if NULL, then using SHA1, and then encoding the + fingerprint to the babbleprint. */ + +char *silc_hash_babbleprint(SilcHash hash, const unsigned char *data, + SilcUInt32 data_len) +{ + SilcHash new_hash = NULL; + char *babbleprint; + unsigned char hval[32]; + unsigned int a, b, c, d, e, check; + int i, k, out_len; + + if (!hash) { + silc_hash_alloc("sha1", &new_hash); + hash = new_hash; + } + + /* Take fingerprint */ + silc_hash_make(hash, data, data_len, hval); + + /* Encode babbleprint */ + out_len = (((hash->hash->hash_len + 1) / 2) + 1) * 6; + babbleprint = silc_calloc(out_len, sizeof(*babbleprint)); + babbleprint[0] = co[16]; + + check = 1; + for (i = 0, k = 1; i < hash->hash->hash_len - 1; i += 2, k += 6) { + a = (((hval[i] >> 6) & 3) + check) % 6; + b = (hval[i] >> 2) & 15; + c = ((hval[i] & 3) + (check / 6)) % 6; + d = (hval[i + 1] >> 4) & 15; + e = hval[i + 1] & 15; + + check = ((check * 5) + (hval[i] * 7) + hval[i + 1]) % 36; - if ((i + 1) % 2 == 0) - snprintf(cp++, sizeof(fingerprint), " "); + babbleprint[k + 0] = vo[a]; + babbleprint[k + 1] = co[b]; + babbleprint[k + 2] = vo[c]; + babbleprint[k + 3] = co[d]; + babbleprint[k + 4] = '-'; + babbleprint[k + 5] = co[e]; + } - if ((i + 1) % 10 == 0) - snprintf(cp++, sizeof(fingerprint), " "); + if ((hash->hash->hash_len % 2) != 0) { + a = (((hval[i] >> 6) & 3) + check) % 6; + b = (hval[i] >> 2) & 15; + c = ((hval[i] & 3) + (check / 6)) % 6; + babbleprint[k + 0] = vo[a]; + babbleprint[k + 1] = co[b]; + babbleprint[k + 2] = vo[c]; + } else { + a = check % 6; + b = 16; + c = check / 6; + babbleprint[k + 0] = vo[a]; + babbleprint[k + 1] = co[b]; + babbleprint[k + 2] = vo[c]; } - i--; - if ((i + 1) % 2 == 0) - cp[-2] = 0; - if ((i + 1) % 10 == 0) - cp[-1] = 0; - - return strdup(fingerprint); + babbleprint[k + 3] = co[16]; + + if (new_hash != NULL) + silc_hash_free(new_hash); + return babbleprint; }