Support optional WANT_MD5 configuration
[s-mailx.git] / hmac.c
blob1b74d0ec67d6e9f72eb81adb248250f59b372ae2
1 /*
2 * Heirloom mailx - 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.
6 */
7 /*
8 * Derived from:
10 Network Working Group H. Krawczyk
11 Request for Comments: 2104 IBM
12 Category: Informational M. Bellare
13 UCSD
14 R. Canetti
15 IBM
16 February 1997
19 HMAC: Keyed-Hashing for Message Authentication
21 Status of This Memo
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]).
34 /* Sccsid @(#)hmac.c 1.8 (gritter) 3/4/06 */
36 #include "rcv.h"
37 #include "md5.h"
39 #ifndef USE_MD5
40 typedef int avoid_empty_file_compiler_warning;
41 #else
44 ** Function: hmac_md5
47 void
48 hmac_md5 (
49 unsigned char *text, /* pointer to data stream */
50 int text_len, /* length of data stream */
51 unsigned char *key, /* pointer to authentication key */
52 int key_len, /* length of authentication key */
53 void *digest /* caller digest to be filled in */
57 MD5_CTX context;
58 unsigned char k_ipad[65]; /* inner padding -
59 * key XORd with ipad
61 unsigned char k_opad[65]; /* outer padding -
62 * key XORd with opad
64 unsigned char tk[16];
65 int i;
66 /* if key is longer than 64 bytes reset it to key=MD5(key) */
67 if (key_len > 64) {
69 MD5_CTX tctx;
71 MD5Init(&tctx);
72 MD5Update(&tctx, key, key_len);
73 MD5Final(tk, &tctx);
75 key = tk;
76 key_len = 16;
80 * the HMAC_MD5 transform looks like:
82 * MD5(K XOR opad, MD5(K XOR ipad, text))
84 * where K is an n byte key
85 * ipad is the byte 0x36 repeated 64 times
86 * opad is the byte 0x5c repeated 64 times
87 * and text is the data being protected
90 /* start out by storing key in pads */
91 memset(k_ipad, 0, sizeof k_ipad);
92 memset(k_opad, 0, sizeof k_opad);
93 memcpy(k_ipad, key, key_len);
94 memcpy(k_opad, key, key_len);
96 /* XOR key with ipad and opad values */
97 for (i=0; i<64; i++) {
98 k_ipad[i] ^= 0x36;
99 k_opad[i] ^= 0x5c;
102 * perform inner MD5
104 MD5Init(&context); /* init context for 1st
105 * pass */
106 MD5Update(&context, k_ipad, 64); /* start with inner pad */
107 MD5Update(&context, text, text_len); /* then text of datagram */
108 MD5Final(digest, &context); /* finish up 1st pass */
110 * perform outer MD5
112 MD5Init(&context); /* init context for 2nd
113 * pass */
114 MD5Update(&context, k_opad, 64); /* start with outer pad */
115 MD5Update(&context, digest, 16); /* then results of 1st
116 * hash */
117 MD5Final(digest, &context); /* finish up 2nd pass */
119 #endif /* USE_MD5 */