source: lib/sha1.c @ 80c2f3c

Last change on this file since 80c2f3c was 5ebff60, checked in by dequis <dx@…>, at 2015-02-20T22:50:54Z

Reindent everything to K&R style with tabs

Used uncrustify, with the configuration file in ./doc/uncrustify.cfg

Commit author set to "Indent <please@…>" so that it's easier to
skip while doing git blame.

  • Property mode set to 100644
File size: 2.4 KB
RevLine 
[34afea7]1#include "sha1.h"
[523fb23]2#include <string.h>
[e0a0a42]3#include <stdio.h>
[77bfd07]4
5
[34afea7]6void sha1_init(sha1_state_t *ctx)
[77bfd07]7{
[34afea7]8        *ctx = g_checksum_new(G_CHECKSUM_SHA1);
[77bfd07]9}
10
[34afea7]11void sha1_append(sha1_state_t *ctx, const guint8 * message_array, guint len)
[77bfd07]12{
[34afea7]13        g_checksum_update(*ctx, message_array, len);
[77bfd07]14}
15
[34afea7]16void sha1_finish(sha1_state_t *ctx, guint8 digest[SHA1_HASH_SIZE])
[77bfd07]17{
[34afea7]18        gsize digest_len = SHA1_HASH_SIZE;
[5ebff60]19
[34afea7]20        g_checksum_get_digest(*ctx, digest, &digest_len);
21        g_checksum_free(*ctx);
[77bfd07]22}
[523fb23]23
24#define HMAC_BLOCK_SIZE 64
25
26/* BitlBee addition: */
[34afea7]27void sha1_hmac(const char *key_, size_t key_len, const char *payload, size_t payload_len, guint8 digest[SHA1_HASH_SIZE])
[523fb23]28{
29        sha1_state_t sha1;
[34afea7]30        guint8 hash[SHA1_HASH_SIZE];
[5ebff60]31        guint8 key[HMAC_BLOCK_SIZE + 1];
[523fb23]32        int i;
[5ebff60]33
34        if (key_len == 0) {
35                key_len = strlen(key_);
36        }
37        if (payload_len == 0) {
38                payload_len = strlen(payload);
39        }
40
[523fb23]41        /* Create K. If our current key is >64 chars we have to hash it,
42           otherwise just pad. */
[5ebff60]43        memset(key, 0, HMAC_BLOCK_SIZE + 1);
44        if (key_len > HMAC_BLOCK_SIZE) {
45                sha1_init(&sha1);
46                sha1_append(&sha1, (guint8 *) key_, key_len);
47                sha1_finish(&sha1, key);
48        } else {
49                memcpy(key, key_, key_len);
[523fb23]50        }
[5ebff60]51
[523fb23]52        /* Inner part: H(K XOR 0x36, text) */
[5ebff60]53        sha1_init(&sha1);
54        for (i = 0; i < HMAC_BLOCK_SIZE; i++) {
[523fb23]55                key[i] ^= 0x36;
[5ebff60]56        }
57        sha1_append(&sha1, key, HMAC_BLOCK_SIZE);
58        sha1_append(&sha1, (const guint8 *) payload, payload_len);
59        sha1_finish(&sha1, hash);
60
[523fb23]61        /* Final result: H(K XOR 0x5C, inner stuff) */
[5ebff60]62        sha1_init(&sha1);
63        for (i = 0; i < HMAC_BLOCK_SIZE; i++) {
[523fb23]64                key[i] ^= 0x36 ^ 0x5c;
[5ebff60]65        }
66        sha1_append(&sha1, key, HMAC_BLOCK_SIZE);
67        sha1_append(&sha1, hash, SHA1_HASH_SIZE);
68        sha1_finish(&sha1, digest);
[523fb23]69}
[e0a0a42]70
71/* I think this follows the scheme described on:
72   http://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29
73   My random data comes from a SHA1 generator but hey, it's random enough for
74   me, and RFC 4122 looks way more complicated than I need this to be.
[5ebff60]75
[e0a0a42]76   Returns a value that must be free()d. */
[5ebff60]77char *sha1_random_uuid(sha1_state_t * context)
[e0a0a42]78{
[34afea7]79        guint8 dig[SHA1_HASH_SIZE];
[5ebff60]80        char *ret = g_new0(char, 40);   /* 36 chars + \0 */
[e0a0a42]81        int i, p;
[5ebff60]82
[e0a0a42]83        sha1_finish(context, dig);
[5ebff60]84        for (p = i = 0; i < 16; i++) {
85                if (i == 4 || i == 6 || i == 8 || i == 10) {
[e0a0a42]86                        ret[p++] = '-';
[5ebff60]87                }
88                if (i == 6) {
89                        dig[i] = (dig[i] & 0x0f) | 0x40;
90                }
91                if (i == 8) {
92                        dig[i] = (dig[i] & 0x30) | 0x80;
93                }
94
95                sprintf(ret + p, "%02x", dig[i]);
[e0a0a42]96                p += 2;
97        }
98        ret[p] = '\0';
[5ebff60]99
[e0a0a42]100        return ret;
101}
Note: See TracBrowser for help on using the repository browser.