source: lib/sha1.c @ d16e951

Last change on this file since d16e951 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
Line 
1#include "sha1.h"
2#include <string.h>
3#include <stdio.h>
4
5
6void sha1_init(sha1_state_t *ctx)
7{
8        *ctx = g_checksum_new(G_CHECKSUM_SHA1);
9}
10
11void sha1_append(sha1_state_t *ctx, const guint8 * message_array, guint len)
12{
13        g_checksum_update(*ctx, message_array, len);
14}
15
16void sha1_finish(sha1_state_t *ctx, guint8 digest[SHA1_HASH_SIZE])
17{
18        gsize digest_len = SHA1_HASH_SIZE;
19
20        g_checksum_get_digest(*ctx, digest, &digest_len);
21        g_checksum_free(*ctx);
22}
23
24#define HMAC_BLOCK_SIZE 64
25
26/* BitlBee addition: */
27void sha1_hmac(const char *key_, size_t key_len, const char *payload, size_t payload_len, guint8 digest[SHA1_HASH_SIZE])
28{
29        sha1_state_t sha1;
30        guint8 hash[SHA1_HASH_SIZE];
31        guint8 key[HMAC_BLOCK_SIZE + 1];
32        int i;
33
34        if (key_len == 0) {
35                key_len = strlen(key_);
36        }
37        if (payload_len == 0) {
38                payload_len = strlen(payload);
39        }
40
41        /* Create K. If our current key is >64 chars we have to hash it,
42           otherwise just pad. */
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);
50        }
51
52        /* Inner part: H(K XOR 0x36, text) */
53        sha1_init(&sha1);
54        for (i = 0; i < HMAC_BLOCK_SIZE; i++) {
55                key[i] ^= 0x36;
56        }
57        sha1_append(&sha1, key, HMAC_BLOCK_SIZE);
58        sha1_append(&sha1, (const guint8 *) payload, payload_len);
59        sha1_finish(&sha1, hash);
60
61        /* Final result: H(K XOR 0x5C, inner stuff) */
62        sha1_init(&sha1);
63        for (i = 0; i < HMAC_BLOCK_SIZE; i++) {
64                key[i] ^= 0x36 ^ 0x5c;
65        }
66        sha1_append(&sha1, key, HMAC_BLOCK_SIZE);
67        sha1_append(&sha1, hash, SHA1_HASH_SIZE);
68        sha1_finish(&sha1, digest);
69}
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.
75
76   Returns a value that must be free()d. */
77char *sha1_random_uuid(sha1_state_t * context)
78{
79        guint8 dig[SHA1_HASH_SIZE];
80        char *ret = g_new0(char, 40);   /* 36 chars + \0 */
81        int i, p;
82
83        sha1_finish(context, dig);
84        for (p = i = 0; i < 16; i++) {
85                if (i == 4 || i == 6 || i == 8 || i == 10) {
86                        ret[p++] = '-';
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]);
96                p += 2;
97        }
98        ret[p] = '\0';
99
100        return ret;
101}
Note: See TracBrowser for help on using the repository browser.