xref: /third_party/lwip/src/netif/ppp/chap-md5.c (revision 195972f6)
1195972f6Sopenharmony_ci/*
2195972f6Sopenharmony_ci * chap-md5.c - New CHAP/MD5 implementation.
3195972f6Sopenharmony_ci *
4195972f6Sopenharmony_ci * Copyright (c) 2003 Paul Mackerras. All rights reserved.
5195972f6Sopenharmony_ci *
6195972f6Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
7195972f6Sopenharmony_ci * modification, are permitted provided that the following conditions
8195972f6Sopenharmony_ci * are met:
9195972f6Sopenharmony_ci *
10195972f6Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright
11195972f6Sopenharmony_ci *    notice, this list of conditions and the following disclaimer.
12195972f6Sopenharmony_ci *
13195972f6Sopenharmony_ci * 2. The name(s) of the authors of this software must not be used to
14195972f6Sopenharmony_ci *    endorse or promote products derived from this software without
15195972f6Sopenharmony_ci *    prior written permission.
16195972f6Sopenharmony_ci *
17195972f6Sopenharmony_ci * 3. Redistributions of any form whatsoever must retain the following
18195972f6Sopenharmony_ci *    acknowledgment:
19195972f6Sopenharmony_ci *    "This product includes software developed by Paul Mackerras
20195972f6Sopenharmony_ci *     <paulus@samba.org>".
21195972f6Sopenharmony_ci *
22195972f6Sopenharmony_ci * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
23195972f6Sopenharmony_ci * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
24195972f6Sopenharmony_ci * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25195972f6Sopenharmony_ci * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26195972f6Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27195972f6Sopenharmony_ci * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
28195972f6Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29195972f6Sopenharmony_ci */
30195972f6Sopenharmony_ci
31195972f6Sopenharmony_ci#include "netif/ppp/ppp_opts.h"
32195972f6Sopenharmony_ci#if PPP_SUPPORT && CHAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
33195972f6Sopenharmony_ci
34195972f6Sopenharmony_ci#if 0 /* UNUSED */
35195972f6Sopenharmony_ci#include <stdlib.h>
36195972f6Sopenharmony_ci#include <string.h>
37195972f6Sopenharmony_ci#endif /* UNUSED */
38195972f6Sopenharmony_ci
39195972f6Sopenharmony_ci#include "netif/ppp/ppp_impl.h"
40195972f6Sopenharmony_ci
41195972f6Sopenharmony_ci#include "netif/ppp/chap-new.h"
42195972f6Sopenharmony_ci#include "netif/ppp/chap-md5.h"
43195972f6Sopenharmony_ci#include "netif/ppp/magic.h"
44195972f6Sopenharmony_ci#include "netif/ppp/pppcrypt.h"
45195972f6Sopenharmony_ci
46195972f6Sopenharmony_ci#define MD5_HASH_SIZE		16
47195972f6Sopenharmony_ci#define MD5_MIN_CHALLENGE	17
48195972f6Sopenharmony_ci#define MD5_MAX_CHALLENGE	24
49195972f6Sopenharmony_ci#define MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE     3   /* 2^3-1 = 7, 17+7 = 24 */
50195972f6Sopenharmony_ci
51195972f6Sopenharmony_ci#if PPP_SERVER
52195972f6Sopenharmony_cistatic void chap_md5_generate_challenge(ppp_pcb *pcb, unsigned char *cp) {
53195972f6Sopenharmony_ci	int clen;
54195972f6Sopenharmony_ci	LWIP_UNUSED_ARG(pcb);
55195972f6Sopenharmony_ci
56195972f6Sopenharmony_ci	clen = MD5_MIN_CHALLENGE + magic_pow(MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE);
57195972f6Sopenharmony_ci	*cp++ = clen;
58195972f6Sopenharmony_ci	magic_random_bytes(cp, clen);
59195972f6Sopenharmony_ci}
60195972f6Sopenharmony_ci
61195972f6Sopenharmony_cistatic int chap_md5_verify_response(ppp_pcb *pcb, int id, const char *name,
62195972f6Sopenharmony_ci			 const unsigned char *secret, int secret_len,
63195972f6Sopenharmony_ci			 const unsigned char *challenge, const unsigned char *response,
64195972f6Sopenharmony_ci			 char *message, int message_space) {
65195972f6Sopenharmony_ci	lwip_md5_context ctx;
66195972f6Sopenharmony_ci	unsigned char idbyte = id;
67195972f6Sopenharmony_ci	unsigned char hash[MD5_HASH_SIZE];
68195972f6Sopenharmony_ci	int challenge_len, response_len;
69195972f6Sopenharmony_ci	LWIP_UNUSED_ARG(name);
70195972f6Sopenharmony_ci	LWIP_UNUSED_ARG(pcb);
71195972f6Sopenharmony_ci
72195972f6Sopenharmony_ci	challenge_len = *challenge++;
73195972f6Sopenharmony_ci	response_len = *response++;
74195972f6Sopenharmony_ci	if (response_len == MD5_HASH_SIZE) {
75195972f6Sopenharmony_ci		/* Generate hash of ID, secret, challenge */
76195972f6Sopenharmony_ci		lwip_md5_init(&ctx);
77195972f6Sopenharmony_ci		lwip_md5_starts(&ctx);
78195972f6Sopenharmony_ci		lwip_md5_update(&ctx, &idbyte, 1);
79195972f6Sopenharmony_ci		lwip_md5_update(&ctx, secret, secret_len);
80195972f6Sopenharmony_ci		lwip_md5_update(&ctx, challenge, challenge_len);
81195972f6Sopenharmony_ci		lwip_md5_finish(&ctx, hash);
82195972f6Sopenharmony_ci		lwip_md5_free(&ctx);
83195972f6Sopenharmony_ci
84195972f6Sopenharmony_ci		/* Test if our hash matches the peer's response */
85195972f6Sopenharmony_ci		if (memcmp(hash, response, MD5_HASH_SIZE) == 0) {
86195972f6Sopenharmony_ci			ppp_slprintf(message, message_space, "Access granted");
87195972f6Sopenharmony_ci			return 1;
88195972f6Sopenharmony_ci		}
89195972f6Sopenharmony_ci	}
90195972f6Sopenharmony_ci	ppp_slprintf(message, message_space, "Access denied");
91195972f6Sopenharmony_ci	return 0;
92195972f6Sopenharmony_ci}
93195972f6Sopenharmony_ci#endif /* PPP_SERVER */
94195972f6Sopenharmony_ci
95195972f6Sopenharmony_cistatic void chap_md5_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name,
96195972f6Sopenharmony_ci		       const unsigned char *challenge, const char *secret, int secret_len,
97195972f6Sopenharmony_ci		       unsigned char *private_) {
98195972f6Sopenharmony_ci	lwip_md5_context ctx;
99195972f6Sopenharmony_ci	unsigned char idbyte = id;
100195972f6Sopenharmony_ci	int challenge_len = *challenge++;
101195972f6Sopenharmony_ci	LWIP_UNUSED_ARG(our_name);
102195972f6Sopenharmony_ci	LWIP_UNUSED_ARG(private_);
103195972f6Sopenharmony_ci	LWIP_UNUSED_ARG(pcb);
104195972f6Sopenharmony_ci
105195972f6Sopenharmony_ci	lwip_md5_init(&ctx);
106195972f6Sopenharmony_ci	lwip_md5_starts(&ctx);
107195972f6Sopenharmony_ci	lwip_md5_update(&ctx, &idbyte, 1);
108195972f6Sopenharmony_ci	lwip_md5_update(&ctx, (const u_char *)secret, secret_len);
109195972f6Sopenharmony_ci	lwip_md5_update(&ctx, challenge, challenge_len);
110195972f6Sopenharmony_ci	lwip_md5_finish(&ctx, &response[1]);
111195972f6Sopenharmony_ci	lwip_md5_free(&ctx);
112195972f6Sopenharmony_ci	response[0] = MD5_HASH_SIZE;
113195972f6Sopenharmony_ci}
114195972f6Sopenharmony_ci
115195972f6Sopenharmony_ciconst struct chap_digest_type md5_digest = {
116195972f6Sopenharmony_ci	CHAP_MD5,		/* code */
117195972f6Sopenharmony_ci#if PPP_SERVER
118195972f6Sopenharmony_ci	chap_md5_generate_challenge,
119195972f6Sopenharmony_ci	chap_md5_verify_response,
120195972f6Sopenharmony_ci#endif /* PPP_SERVER */
121195972f6Sopenharmony_ci	chap_md5_make_response,
122195972f6Sopenharmony_ci	NULL,			/* check_success */
123195972f6Sopenharmony_ci	NULL,			/* handle_failure */
124195972f6Sopenharmony_ci};
125195972f6Sopenharmony_ci
126195972f6Sopenharmony_ci#endif /* PPP_SUPPORT && CHAP_SUPPORT */
127