Isolate iconv(3) usage in a single place..
[s-mailx.git] / hmac.c
blob3c13a4ba56537fbe612180c3c4a3dcc327fd2c2c
1 /*
2 * Heirloom mailx - a mail user agent derived from Berkeley Mail.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5 */
6 /*
7 * Derived from:
9 Network Working Group H. Krawczyk
10 Request for Comments: 2104 IBM
11 Category: Informational M. Bellare
12 UCSD
13 R. Canetti
14 IBM
15 February 1997
18 HMAC: Keyed-Hashing for Message Authentication
20 Status of This Memo
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 */
35 #include "rcv.h"
36 #include "md5.h"
39 ** Function: hmac_md5
42 void
43 hmac_md5 (
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 */
52 MD5_CTX context;
53 unsigned char k_ipad[65]; /* inner padding -
54 * key XORd with ipad
56 unsigned char k_opad[65]; /* outer padding -
57 * key XORd with opad
59 unsigned char tk[16];
60 int i;
61 /* if key is longer than 64 bytes reset it to key=MD5(key) */
62 if (key_len > 64) {
64 MD5_CTX tctx;
66 MD5Init(&tctx);
67 MD5Update(&tctx, key, key_len);
68 MD5Final(tk, &tctx);
70 key = tk;
71 key_len = 16;
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++) {
93 k_ipad[i] ^= 0x36;
94 k_opad[i] ^= 0x5c;
97 * perform inner MD5
99 MD5Init(&context); /* init context for 1st
100 * pass */
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 */
105 * perform outer MD5
107 MD5Init(&context); /* init context for 2nd
108 * pass */
109 MD5Update(&context, k_opad, 64); /* start with outer pad */
110 MD5Update(&context, digest, 16); /* then results of 1st
111 * hash */
112 MD5Final(digest, &context); /* finish up 2nd pass */