2 * chap-md5.c - New CHAP/MD5 implementation.
4 * Copyright (c) 2003 Paul Mackerras. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * 3. The name(s) of the authors of this software must not be used to
19 * endorse or promote products derived from this software without
20 * prior written permission.
22 * 4. Redistributions of any form whatsoever must retain the following
24 * "This product includes software developed by Paul Mackerras
25 * <paulus@samba.org>".
27 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
28 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
29 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
30 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
31 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
32 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
33 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
46 #define MD5_HASH_SIZE 16
47 #define MD5_MIN_CHALLENGE 16
48 #define MD5_MAX_CHALLENGE 24
51 chap_md5_generate_challenge(unsigned char *cp)
55 clen = (int)(drand48() * (MD5_MAX_CHALLENGE - MD5_MIN_CHALLENGE))
58 random_bytes(cp, clen);
62 chap_md5_verify_response(int id, char *name,
63 unsigned char *secret, int secret_len,
64 unsigned char *challenge, unsigned char *response,
65 char *message, int message_space)
68 unsigned char idbyte = id;
69 unsigned char hash[MD5_HASH_SIZE];
70 int challenge_len, response_len;
72 challenge_len = *challenge++;
73 response_len = *response++;
74 if (response_len == MD5_HASH_SIZE) {
75 /* Generate hash of ID, secret, challenge */
77 MD5Update(&ctx, &idbyte, 1);
78 MD5Update(&ctx, secret, secret_len);
79 MD5Update(&ctx, challenge, challenge_len);
82 /* Test if our hash matches the peer's response */
83 if (memcmp(hash, response, MD5_HASH_SIZE) == 0) {
84 slprintf(message, message_space, "Access granted");
88 slprintf(message, message_space, "Access denied");
93 chap_md5_make_response(unsigned char *response, int id, char *our_name,
94 unsigned char *challenge, char *secret, int secret_len,
95 unsigned char *private)
98 unsigned char idbyte = id;
99 int challenge_len = *challenge++;
102 MD5Update(&ctx, &idbyte, 1);
103 MD5Update(&ctx, secret, secret_len);
104 MD5Update(&ctx, challenge, challenge_len);
105 MD5Final(&response[1], &ctx);
106 response[0] = MD5_HASH_SIZE;
109 static struct chap_digest_type md5_digest = {
111 chap_md5_generate_challenge,
112 chap_md5_verify_response,
113 chap_md5_make_response,
114 NULL, /* check_success */
115 NULL, /* handle_failure */
121 chap_register_digest(&md5_digest);