summaryrefslogtreecommitdiff
path: root/src/hmac_md5.c
blob: 6b0fd0d7601d8353836c8e2a65f880430334eaa7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "hmac_md5.h"

#include "byte.h"

#include "global.h"
#include "md5.h"

/**
@file   hmac_md5
@brief  caculates HMAC digest from challenge + password (DJB version)
@param input:  unsigned char *text : pointer to challenge
               int text_len        : length of challenge
               unsigned char *key  : pointer to password
               int key_len         : length of password
      output: unsigned char *digest: pointer to calculated digest
*/

void hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len, unsigned char *digest)
{
  MD5_CTX context;
  unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
  unsigned char k_opad[65]; /* outer padding - key XORd with opad */
  unsigned char tk[16];
  int i;

  if (key_len > 64) {
    MD5_CTX tctx;
    MD5Init(&tctx);
    MD5Update(&tctx, key, key_len);
    MD5Final(tk, &tctx);
    key = tk;
    key_len = 16;
  }

  byte_zero(k_ipad, sizeof(k_ipad));
  byte_zero(k_opad, sizeof(k_opad));
  byte_copy(k_ipad, key_len, key);
  byte_copy(k_opad, key_len, key);

  for (i = 0; i < 64; i++) {
    k_ipad[i] ^= 0x36;
    k_opad[i] ^= 0x5c;
  }

  MD5Init(&context);                   /* init context for 1st pass */
  MD5Update(&context, k_ipad, 64);     /* start with inner pad */
  MD5Update(&context, text, text_len); /* then text of datagram */
  MD5Final(digest, &context);          /* finish up 1st pass */

  MD5Init(&context);               /* init context for 2nd pass */
  MD5Update(&context, k_opad, 64); /* start with outer pad */
  MD5Update(&context, digest, 16); /* then results of 1st hash */
  MD5Final(digest, &context);      /* finish up 2nd pass */
}