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