ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_chap-md5.c Source File

lwip_chap-md5.c

00001 /*
00002  * chap-md5.c - New CHAP/MD5 implementation.
00003  *
00004  * Copyright (c) 2003 Paul Mackerras. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *
00013  * 2. The name(s) of the authors of this software must not be used to
00014  *    endorse or promote products derived from this software without
00015  *    prior written permission.
00016  *
00017  * 3. Redistributions of any form whatsoever must retain the following
00018  *    acknowledgment:
00019  *    "This product includes software developed by Paul Mackerras
00020  *     <paulus@samba.org>".
00021  *
00022  * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
00023  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00024  * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
00025  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00026  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
00027  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
00028  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00029  */
00030 
00031 #include "netif/ppp/ppp_opts.h"
00032 #if PPP_SUPPORT && CHAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
00033 
00034 #if 0 /* UNUSED */
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #endif /* UNUSED */
00038 
00039 #include "netif/ppp/ppp_impl.h"
00040 
00041 #include "netif/ppp/chap-new.h"
00042 #include "netif/ppp/chap-md5.h"
00043 #include "netif/ppp/magic.h"
00044 #include "netif/ppp/pppcrypt.h"
00045 
00046 #define MD5_HASH_SIZE       16
00047 #define MD5_MIN_CHALLENGE   17
00048 #define MD5_MAX_CHALLENGE   24
00049 #define MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE     3   /* 2^3-1 = 7, 17+7 = 24 */
00050 
00051 #if PPP_SERVER
00052 static void chap_md5_generate_challenge(ppp_pcb *pcb, unsigned char *cp) {
00053     int clen;
00054     LWIP_UNUSED_ARG(pcb);
00055 
00056     clen = MD5_MIN_CHALLENGE + magic_pow(MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE);
00057     *cp++ = clen;
00058     magic_random_bytes(cp, clen);
00059 }
00060 
00061 static int chap_md5_verify_response(ppp_pcb *pcb, int id, const char *name,
00062              const unsigned char *secret, int secret_len,
00063              const unsigned char *challenge, const unsigned char *response,
00064              char *message, int message_space) {
00065     lwip_md5_context ctx;
00066     unsigned char idbyte = id;
00067     unsigned char hash[MD5_HASH_SIZE];
00068     int challenge_len, response_len;
00069     LWIP_UNUSED_ARG(name);
00070     LWIP_UNUSED_ARG(pcb);
00071 
00072     challenge_len = *challenge++;
00073     response_len = *response++;
00074     if (response_len == MD5_HASH_SIZE) {
00075         /* Generate hash of ID, secret, challenge */
00076         lwip_md5_init(&ctx);
00077         lwip_md5_starts(&ctx);
00078         lwip_md5_update(&ctx, &idbyte, 1);
00079         lwip_md5_update(&ctx, secret, secret_len);
00080         lwip_md5_update(&ctx, challenge, challenge_len);
00081         lwip_md5_finish(&ctx, hash);
00082         lwip_md5_free(&ctx);
00083 
00084         /* Test if our hash matches the peer's response */
00085         if (memcmp(hash, response, MD5_HASH_SIZE) == 0) {
00086             ppp_slprintf(message, message_space, "Access granted");
00087             return 1;
00088         }
00089     }
00090     ppp_slprintf(message, message_space, "Access denied");
00091     return 0;
00092 }
00093 #endif /* PPP_SERVER */
00094 
00095 static void chap_md5_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name,
00096                const unsigned char *challenge, const char *secret, int secret_len,
00097                unsigned char *private_) {
00098     lwip_md5_context ctx;
00099     unsigned char idbyte = id;
00100     int challenge_len = *challenge++;
00101     LWIP_UNUSED_ARG(our_name);
00102     LWIP_UNUSED_ARG(private_);
00103     LWIP_UNUSED_ARG(pcb);
00104 
00105     lwip_md5_init(&ctx);
00106     lwip_md5_starts(&ctx);
00107     lwip_md5_update(&ctx, &idbyte, 1);
00108     lwip_md5_update(&ctx, (const u_char *)secret, secret_len);
00109     lwip_md5_update(&ctx, challenge, challenge_len);
00110     lwip_md5_finish(&ctx, &response[1]);
00111     lwip_md5_free(&ctx);
00112     response[0] = MD5_HASH_SIZE;
00113 }
00114 
00115 const struct chap_digest_type md5_digest = {
00116     CHAP_MD5,       /* code */
00117 #if PPP_SERVER
00118     chap_md5_generate_challenge,
00119     chap_md5_verify_response,
00120 #endif /* PPP_SERVER */
00121     chap_md5_make_response,
00122     NULL,           /* check_success */
00123     NULL,           /* handle_failure */
00124 };
00125 
00126 #endif /* PPP_SUPPORT && CHAP_SUPPORT */