blob: 83002683cd4a8850590d1816946582f184a6eb58 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001#include <stdlib.h>
2#include <string.h>
3#include <hmac.h>
4/**
5 Initialize an HMAC context.
6 @param hmac The HMAC state
7 @param hash The hash for HMAC
8 @param key The secret key
9 @param keylen The length of the secret key
10 @return 0 if successful
11*/
12int hmac_init(hmac_state *hmac, hash_param *hash, const unsigned char *key,
13 unsigned long keylen)
14{
15 unsigned int i;
16 unsigned char *buf;
17
18 hmac->hash = hash;
19
20 hmac->key = malloc(hmac->hash->blocksize);
21 buf = malloc(hmac->hash->blocksize);
22
23 /* assume keylen <= hmac blocksize */
24 memcpy(hmac->key, key, keylen);
25 memset(hmac->key + keylen, 0, hmac->hash->blocksize - keylen);
26
27 for (i = 0; i < hmac->hash->blocksize; i++)
28 buf[i] = hmac->key[i] ^ 0x36;
29
30 hmac->hash->init(hmac->hash->hash_state);
31 hmac->hash->process(hmac->hash->hash_state, buf, hmac->hash->blocksize);
32
33 free(buf);
34
35 return 0;
36}
37
38/**
39 Process data through HMAC
40 @param hmac The hmac state
41 @param in The data to send through HMAC
42 @param inlen The length of the data to HMAC
43 @return 0 if successful
44*/
45int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen)
46{
47 return hmac->hash->process(hmac->hash->hash_state, in, inlen);
48}
49
50/**
51 Terminate an LTC_HMAC session
52 @param hmac The LTC_HMAC state
53 @param out [out] The destination of the LTC_HMAC authentication tag
54 @param outlen [in/out] The max size and resulting size of the LTC_HMAC authentication tag
55 @return CRYPT_OK if successful
56*/
57int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen)
58{
59 unsigned int i;
60 unsigned char *buf, *isha;
61
62 buf = malloc(hmac->hash->blocksize);
63 isha = malloc(hmac->hash->hashsize);
64
65 hmac->hash->done(hmac->hash->hash_state, isha);
66
67 for (i = 0; i < hmac->hash->blocksize; i++)
68 buf[i] = hmac->key[i] ^ 0x5c;
69
70 hmac->hash->init(hmac->hash->hash_state);
71 hmac->hash->process(hmac->hash->hash_state, buf, hmac->hash->blocksize);
72 hmac->hash->process(hmac->hash->hash_state, isha, hmac->hash->hashsize);
73 hmac->hash->done(hmac->hash->hash_state, buf);
74
75 for (i = 0; i < hmac->hash->hashsize && i < (unsigned int)*outlen; i++)
76 out[i] = buf[i];
77
78 *outlen = i;
79
80 free(isha);
81 free(buf);
82 return 0;
83}