xref: /minix3/minix/lib/liblwip/dist/src/netif/ppp/chap-md5.c (revision 5d5fbe79c1b60734f34c69330aec5496644e8651)
1*5d5fbe79SDavid van Moolenbroek /*
2*5d5fbe79SDavid van Moolenbroek  * chap-md5.c - New CHAP/MD5 implementation.
3*5d5fbe79SDavid van Moolenbroek  *
4*5d5fbe79SDavid van Moolenbroek  * Copyright (c) 2003 Paul Mackerras. All rights reserved.
5*5d5fbe79SDavid van Moolenbroek  *
6*5d5fbe79SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
7*5d5fbe79SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
8*5d5fbe79SDavid van Moolenbroek  * are met:
9*5d5fbe79SDavid van Moolenbroek  *
10*5d5fbe79SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
11*5d5fbe79SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
12*5d5fbe79SDavid van Moolenbroek  *
13*5d5fbe79SDavid van Moolenbroek  * 2. The name(s) of the authors of this software must not be used to
14*5d5fbe79SDavid van Moolenbroek  *    endorse or promote products derived from this software without
15*5d5fbe79SDavid van Moolenbroek  *    prior written permission.
16*5d5fbe79SDavid van Moolenbroek  *
17*5d5fbe79SDavid van Moolenbroek  * 3. Redistributions of any form whatsoever must retain the following
18*5d5fbe79SDavid van Moolenbroek  *    acknowledgment:
19*5d5fbe79SDavid van Moolenbroek  *    "This product includes software developed by Paul Mackerras
20*5d5fbe79SDavid van Moolenbroek  *     <paulus@samba.org>".
21*5d5fbe79SDavid van Moolenbroek  *
22*5d5fbe79SDavid van Moolenbroek  * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
23*5d5fbe79SDavid van Moolenbroek  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
24*5d5fbe79SDavid van Moolenbroek  * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25*5d5fbe79SDavid van Moolenbroek  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26*5d5fbe79SDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27*5d5fbe79SDavid van Moolenbroek  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
28*5d5fbe79SDavid van Moolenbroek  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29*5d5fbe79SDavid van Moolenbroek  */
30*5d5fbe79SDavid van Moolenbroek 
31*5d5fbe79SDavid van Moolenbroek #include "netif/ppp/ppp_opts.h"
32*5d5fbe79SDavid van Moolenbroek #if PPP_SUPPORT && CHAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
33*5d5fbe79SDavid van Moolenbroek 
34*5d5fbe79SDavid van Moolenbroek #if 0 /* UNUSED */
35*5d5fbe79SDavid van Moolenbroek #include <stdlib.h>
36*5d5fbe79SDavid van Moolenbroek #include <string.h>
37*5d5fbe79SDavid van Moolenbroek #endif /* UNUSED */
38*5d5fbe79SDavid van Moolenbroek 
39*5d5fbe79SDavid van Moolenbroek #include "netif/ppp/ppp_impl.h"
40*5d5fbe79SDavid van Moolenbroek 
41*5d5fbe79SDavid van Moolenbroek #include "netif/ppp/chap-new.h"
42*5d5fbe79SDavid van Moolenbroek #include "netif/ppp/chap-md5.h"
43*5d5fbe79SDavid van Moolenbroek #include "netif/ppp/magic.h"
44*5d5fbe79SDavid van Moolenbroek #include "netif/ppp/pppcrypt.h"
45*5d5fbe79SDavid van Moolenbroek 
46*5d5fbe79SDavid van Moolenbroek #define MD5_HASH_SIZE		16
47*5d5fbe79SDavid van Moolenbroek #define MD5_MIN_CHALLENGE	17
48*5d5fbe79SDavid van Moolenbroek #define MD5_MAX_CHALLENGE	24
49*5d5fbe79SDavid van Moolenbroek #define MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE     3   /* 2^3-1 = 7, 17+7 = 24 */
50*5d5fbe79SDavid van Moolenbroek 
51*5d5fbe79SDavid van Moolenbroek #if PPP_SERVER
chap_md5_generate_challenge(ppp_pcb * pcb,unsigned char * cp)52*5d5fbe79SDavid van Moolenbroek static void chap_md5_generate_challenge(ppp_pcb *pcb, unsigned char *cp) {
53*5d5fbe79SDavid van Moolenbroek 	int clen;
54*5d5fbe79SDavid van Moolenbroek 	LWIP_UNUSED_ARG(pcb);
55*5d5fbe79SDavid van Moolenbroek 
56*5d5fbe79SDavid van Moolenbroek 	clen = MD5_MIN_CHALLENGE + magic_pow(MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE);
57*5d5fbe79SDavid van Moolenbroek 	*cp++ = clen;
58*5d5fbe79SDavid van Moolenbroek 	magic_random_bytes(cp, clen);
59*5d5fbe79SDavid van Moolenbroek }
60*5d5fbe79SDavid van Moolenbroek 
chap_md5_verify_response(ppp_pcb * pcb,int id,const char * name,const unsigned char * secret,int secret_len,const unsigned char * challenge,const unsigned char * response,char * message,int message_space)61*5d5fbe79SDavid van Moolenbroek static int chap_md5_verify_response(ppp_pcb *pcb, int id, const char *name,
62*5d5fbe79SDavid van Moolenbroek 			 const unsigned char *secret, int secret_len,
63*5d5fbe79SDavid van Moolenbroek 			 const unsigned char *challenge, const unsigned char *response,
64*5d5fbe79SDavid van Moolenbroek 			 char *message, int message_space) {
65*5d5fbe79SDavid van Moolenbroek 	lwip_md5_context ctx;
66*5d5fbe79SDavid van Moolenbroek 	unsigned char idbyte = id;
67*5d5fbe79SDavid van Moolenbroek 	unsigned char hash[MD5_HASH_SIZE];
68*5d5fbe79SDavid van Moolenbroek 	int challenge_len, response_len;
69*5d5fbe79SDavid van Moolenbroek 	LWIP_UNUSED_ARG(name);
70*5d5fbe79SDavid van Moolenbroek 	LWIP_UNUSED_ARG(pcb);
71*5d5fbe79SDavid van Moolenbroek 
72*5d5fbe79SDavid van Moolenbroek 	challenge_len = *challenge++;
73*5d5fbe79SDavid van Moolenbroek 	response_len = *response++;
74*5d5fbe79SDavid van Moolenbroek 	if (response_len == MD5_HASH_SIZE) {
75*5d5fbe79SDavid van Moolenbroek 		/* Generate hash of ID, secret, challenge */
76*5d5fbe79SDavid van Moolenbroek 		lwip_md5_init(&ctx);
77*5d5fbe79SDavid van Moolenbroek 		lwip_md5_starts(&ctx);
78*5d5fbe79SDavid van Moolenbroek 		lwip_md5_update(&ctx, &idbyte, 1);
79*5d5fbe79SDavid van Moolenbroek 		lwip_md5_update(&ctx, secret, secret_len);
80*5d5fbe79SDavid van Moolenbroek 		lwip_md5_update(&ctx, challenge, challenge_len);
81*5d5fbe79SDavid van Moolenbroek 		lwip_md5_finish(&ctx, hash);
82*5d5fbe79SDavid van Moolenbroek 		lwip_md5_free(&ctx);
83*5d5fbe79SDavid van Moolenbroek 
84*5d5fbe79SDavid van Moolenbroek 		/* Test if our hash matches the peer's response */
85*5d5fbe79SDavid van Moolenbroek 		if (memcmp(hash, response, MD5_HASH_SIZE) == 0) {
86*5d5fbe79SDavid van Moolenbroek 			ppp_slprintf(message, message_space, "Access granted");
87*5d5fbe79SDavid van Moolenbroek 			return 1;
88*5d5fbe79SDavid van Moolenbroek 		}
89*5d5fbe79SDavid van Moolenbroek 	}
90*5d5fbe79SDavid van Moolenbroek 	ppp_slprintf(message, message_space, "Access denied");
91*5d5fbe79SDavid van Moolenbroek 	return 0;
92*5d5fbe79SDavid van Moolenbroek }
93*5d5fbe79SDavid van Moolenbroek #endif /* PPP_SERVER */
94*5d5fbe79SDavid van Moolenbroek 
chap_md5_make_response(ppp_pcb * pcb,unsigned char * response,int id,const char * our_name,const unsigned char * challenge,const char * secret,int secret_len,unsigned char * private_)95*5d5fbe79SDavid van Moolenbroek static void chap_md5_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name,
96*5d5fbe79SDavid van Moolenbroek 		       const unsigned char *challenge, const char *secret, int secret_len,
97*5d5fbe79SDavid van Moolenbroek 		       unsigned char *private_) {
98*5d5fbe79SDavid van Moolenbroek 	lwip_md5_context ctx;
99*5d5fbe79SDavid van Moolenbroek 	unsigned char idbyte = id;
100*5d5fbe79SDavid van Moolenbroek 	int challenge_len = *challenge++;
101*5d5fbe79SDavid van Moolenbroek 	LWIP_UNUSED_ARG(our_name);
102*5d5fbe79SDavid van Moolenbroek 	LWIP_UNUSED_ARG(private_);
103*5d5fbe79SDavid van Moolenbroek 	LWIP_UNUSED_ARG(pcb);
104*5d5fbe79SDavid van Moolenbroek 
105*5d5fbe79SDavid van Moolenbroek 	lwip_md5_init(&ctx);
106*5d5fbe79SDavid van Moolenbroek 	lwip_md5_starts(&ctx);
107*5d5fbe79SDavid van Moolenbroek 	lwip_md5_update(&ctx, &idbyte, 1);
108*5d5fbe79SDavid van Moolenbroek 	lwip_md5_update(&ctx, (const u_char *)secret, secret_len);
109*5d5fbe79SDavid van Moolenbroek 	lwip_md5_update(&ctx, challenge, challenge_len);
110*5d5fbe79SDavid van Moolenbroek 	lwip_md5_finish(&ctx, &response[1]);
111*5d5fbe79SDavid van Moolenbroek 	lwip_md5_free(&ctx);
112*5d5fbe79SDavid van Moolenbroek 	response[0] = MD5_HASH_SIZE;
113*5d5fbe79SDavid van Moolenbroek }
114*5d5fbe79SDavid van Moolenbroek 
115*5d5fbe79SDavid van Moolenbroek const struct chap_digest_type md5_digest = {
116*5d5fbe79SDavid van Moolenbroek 	CHAP_MD5,		/* code */
117*5d5fbe79SDavid van Moolenbroek #if PPP_SERVER
118*5d5fbe79SDavid van Moolenbroek 	chap_md5_generate_challenge,
119*5d5fbe79SDavid van Moolenbroek 	chap_md5_verify_response,
120*5d5fbe79SDavid van Moolenbroek #endif /* PPP_SERVER */
121*5d5fbe79SDavid van Moolenbroek 	chap_md5_make_response,
122*5d5fbe79SDavid van Moolenbroek 	NULL,			/* check_success */
123*5d5fbe79SDavid van Moolenbroek 	NULL,			/* handle_failure */
124*5d5fbe79SDavid van Moolenbroek };
125*5d5fbe79SDavid van Moolenbroek 
126*5d5fbe79SDavid van Moolenbroek #endif /* PPP_SUPPORT && CHAP_SUPPORT */
127