2 * S-nail - a mail user agent derived from Berkeley Mail.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5 * Copyright (c) 2012 Steffen "Daode" Nurpmeso.
10 Network Working Group H. Krawczyk
11 Request for Comments: 2104 IBM
12 Category: Informational M. Bellare
19 HMAC: Keyed-Hashing for Message Authentication
23 This memo provides information for the Internet community. This memo
24 does not specify an Internet standard of any kind. Distribution of
25 this memo is unlimited.
27 Appendix -- Sample Code
29 For the sake of illustration we provide the following sample code for
30 the implementation of HMAC-MD5 as well as some corresponding test
31 vectors (the code is based on MD5 code as described in [MD5]).
38 typedef int avoid_empty_file_compiler_warning
;
47 unsigned char *text
, /* pointer to data stream */
48 int text_len
, /* length of data stream */
49 unsigned char *key
, /* pointer to authentication key */
50 int key_len
, /* length of authentication key */
51 void *digest
/* caller digest to be filled in */
56 unsigned char k_ipad
[65]; /* inner padding -
59 unsigned char k_opad
[65]; /* outer padding -
64 /* if key is longer than 64 bytes reset it to key=MD5(key) */
70 MD5Update(&tctx
, key
, key_len
);
78 * the HMAC_MD5 transform looks like:
80 * MD5(K XOR opad, MD5(K XOR ipad, text))
82 * where K is an n byte key
83 * ipad is the byte 0x36 repeated 64 times
84 * opad is the byte 0x5c repeated 64 times
85 * and text is the data being protected
88 /* start out by storing key in pads */
89 memset(k_ipad
, 0, sizeof k_ipad
);
90 memset(k_opad
, 0, sizeof k_opad
);
91 memcpy(k_ipad
, key
, key_len
);
92 memcpy(k_opad
, key
, key_len
);
94 /* XOR key with ipad and opad values */
95 for (i
=0; i
<64; i
++) {
102 MD5Init(&context
); /* init context for 1st
104 MD5Update(&context
, k_ipad
, 64); /* start with inner pad */
105 MD5Update(&context
, text
, text_len
); /* then text of datagram */
106 MD5Final(digest
, &context
); /* finish up 1st pass */
110 MD5Init(&context
); /* init context for 2nd
112 MD5Update(&context
, k_opad
, 64); /* start with outer pad */
113 MD5Update(&context
, digest
, 16); /* then results of 1st
115 MD5Final(digest
, &context
); /* finish up 2nd pass */