rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame^] | 1 | #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 | */ |
| 12 | int 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 | */ |
| 45 | int 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 | */ |
| 57 | int 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 | } |