1 /* Copyright (c) 2006-2010, UNINETT AS.
2 * Copyright (c) 2010, UNINETT AS, NORDUnet A/S.
3 * Copyright (c) 2010-2012, NORDUnet A/S. */
4 /* See LICENSE for licensing information. */
11 #include <nettle/sha.h>
12 #include <nettle/hmac.h>
13 #include "fticks_hashmac.h"
16 _format_hash(const uint8_t *hash, size_t out_len, uint8_t *out)
20 for (ir = 0, iw = 0; iw <= out_len - 3; ir++, iw += 2)
21 sprintf((char *) out + iw, "%02x", hash[ir % SHA256_DIGEST_SIZE]);
25 _hash(const uint8_t *in,
31 struct sha256_ctx ctx;
32 uint8_t hash[SHA256_DIGEST_SIZE];
35 sha256_update(&ctx, strlen((char *) in), in);
36 sha256_digest(&ctx, sizeof(hash), hash);
37 _format_hash(hash, out_len, out);
40 struct hmac_sha256_ctx ctx;
41 uint8_t hash[SHA256_DIGEST_SIZE];
43 hmac_sha256_set_key(&ctx, strlen((char *) key), key);
44 hmac_sha256_update(&ctx, strlen((char *) in), in);
45 hmac_sha256_digest(&ctx, sizeof(hash), hash);
46 _format_hash(hash, out_len, out);
50 /** Hash the Ethernet MAC address in \a IN, keying a HMAC with \a KEY
51 unless \a KEY is NULL. If \a KEY is null \a IN is hashed with an
52 ordinary cryptographic hash function such as SHA-2.
54 \a IN and \a KEY are NULL terminated strings.
56 \a IN is supposed to be an Ethernet MAC address and is sanitised
57 by lowercasing it, removing all but [0-9a-f] and truncating it at
58 the first ';' found. The truncation is done because RADIUS
59 supposedly has a praxis of tacking on SSID to the MAC address in
62 \return 0 on success, -ENOMEM on out of memory.
65 fticks_hashmac(const uint8_t *in,
70 uint8_t *in_copy = NULL;
74 in_copy = calloc(1, strlen((const char *) in) + 1);
78 /* Sanitise and lowercase 'in' into 'in_copy'. */
79 for (i = 0, p = in_copy; in[i] != '\0'; i++) {
84 if (in[i] >= '0' && in[i] <= '9') {
87 else if (tolower(in[i]) >= 'a' && tolower(in[i]) <= 'f') {
88 *p++ = tolower(in[i]);
92 _hash(in_copy, key, out_len, out);