Add trunc and truncf.
[dragonfly.git] / contrib / wpa_supplicant-0.4.9 / eap_md5.c
1 /*
2  * WPA Supplicant / EAP-MD5
3  * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17
18 #include "common.h"
19 #include "eap_i.h"
20 #include "wpa_supplicant.h"
21 #include "config_ssid.h"
22 #include "md5.h"
23 #include "crypto.h"
24
25
26 static void * eap_md5_init(struct eap_sm *sm)
27 {
28         return (void *) 1;
29 }
30
31
32 static void eap_md5_deinit(struct eap_sm *sm, void *priv)
33 {
34 }
35
36
37 static u8 * eap_md5_process(struct eap_sm *sm, void *priv,
38                             struct eap_method_ret *ret,
39                             const u8 *reqData, size_t reqDataLen,
40                             size_t *respDataLen)
41 {
42         struct wpa_ssid *config = eap_get_config(sm);
43         const struct eap_hdr *req;
44         struct eap_hdr *resp;
45         const u8 *pos, *challenge;
46         u8 *rpos;
47         int challenge_len;
48         size_t len;
49         const u8 *addr[3];
50         size_t elen[3];
51
52         if (config == NULL || config->password == NULL) {
53                 wpa_printf(MSG_INFO, "EAP-MD5: Password not configured");
54                 eap_sm_request_password(sm, config);
55                 ret->ignore = TRUE;
56                 return NULL;
57         }
58
59         pos = eap_hdr_validate(EAP_TYPE_MD5, reqData, reqDataLen, &len);
60         if (pos == NULL || len == 0) {
61                 wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame (pos=%p len=%lu)",
62                            pos, (unsigned long) len);
63                 ret->ignore = TRUE;
64                 return NULL;
65         }
66         req = (const struct eap_hdr *) reqData;
67         challenge_len = *pos++;
68         if (challenge_len == 0 ||
69             challenge_len > len - 1) {
70                 wpa_printf(MSG_INFO, "EAP-MD5: Invalid challenge "
71                            "(challenge_len=%d len=%lu)",
72                            challenge_len, (unsigned long) len);
73                 ret->ignore = TRUE;
74                 return NULL;
75         }
76         ret->ignore = FALSE;
77         challenge = pos;
78         wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge",
79                     challenge, challenge_len);
80
81         wpa_printf(MSG_DEBUG, "EAP-MD5: generating Challenge Response");
82         ret->methodState = METHOD_DONE;
83         ret->decision = DECISION_UNCOND_SUCC;
84         ret->allowNotifications = TRUE;
85
86         *respDataLen = sizeof(struct eap_hdr) + 1 + 1 + MD5_MAC_LEN;
87         resp = malloc(*respDataLen);
88         if (resp == NULL)
89                 return NULL;
90         resp->code = EAP_CODE_RESPONSE;
91         resp->identifier = req->identifier;
92         resp->length = host_to_be16(*respDataLen);
93         rpos = (u8 *) (resp + 1);
94         *rpos++ = EAP_TYPE_MD5;
95         *rpos++ = MD5_MAC_LEN; /* Value-Size */
96
97         addr[0] = &resp->identifier;
98         elen[0] = 1;
99         addr[1] = config->password;
100         elen[1] = config->password_len;
101         addr[2] = challenge;
102         elen[2] = challenge_len;
103         md5_vector(3, addr, elen, rpos);
104         wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", rpos, MD5_MAC_LEN);
105
106         return (u8 *) resp;
107 }
108
109
110 const struct eap_method eap_method_md5 =
111 {
112         .method = EAP_TYPE_MD5,
113         .name = "MD5",
114         .init = eap_md5_init,
115         .deinit = eap_md5_deinit,
116         .process = eap_md5_process,
117 };