2 * Heirloom mailx - a mail user agent derived from Berkeley Mail.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
9 Network Working Group H. Krawczyk
10 Request for Comments: 2104 IBM
11 Category: Informational M. Bellare
18 HMAC: Keyed-Hashing for Message Authentication
22 This memo provides information for the Internet community. This memo
23 does not specify an Internet standard of any kind. Distribution of
24 this memo is unlimited.
26 Appendix -- Sample Code
28 For the sake of illustration we provide the following sample code for
29 the implementation of HMAC-MD5 as well as some corresponding test
30 vectors (the code is based on MD5 code as described in [MD5]).
33 /* Sccsid @(#)hmac.c 1.8 (gritter) 3/4/06 */
44 unsigned char *text
, /* pointer to data stream */
45 int text_len
, /* length of data stream */
46 unsigned char *key
, /* pointer to authentication key */
47 int key_len
, /* length of authentication key */
48 void *digest
/* caller digest to be filled in */
53 unsigned char k_ipad
[65]; /* inner padding -
56 unsigned char k_opad
[65]; /* outer padding -
61 /* if key is longer than 64 bytes reset it to key=MD5(key) */
67 MD5Update(&tctx
, key
, key_len
);
75 * the HMAC_MD5 transform looks like:
77 * MD5(K XOR opad, MD5(K XOR ipad, text))
79 * where K is an n byte key
80 * ipad is the byte 0x36 repeated 64 times
81 * opad is the byte 0x5c repeated 64 times
82 * and text is the data being protected
85 /* start out by storing key in pads */
86 memset(k_ipad
, 0, sizeof k_ipad
);
87 memset(k_opad
, 0, sizeof k_opad
);
88 memcpy(k_ipad
, key
, key_len
);
89 memcpy(k_opad
, key
, key_len
);
91 /* XOR key with ipad and opad values */
92 for (i
=0; i
<64; i
++) {
99 MD5Init(&context
); /* init context for 1st
101 MD5Update(&context
, k_ipad
, 64); /* start with inner pad */
102 MD5Update(&context
, text
, text_len
); /* then text of datagram */
103 MD5Final(digest
, &context
); /* finish up 1st pass */
107 MD5Init(&context
); /* init context for 2nd
109 MD5Update(&context
, k_opad
, 64); /* start with outer pad */
110 MD5Update(&context
, digest
, 16); /* then results of 1st
112 MD5Final(digest
, &context
); /* finish up 2nd pass */