~ubuntu-branches/ubuntu/hardy/freeradius/hardy-proposed

« back to all changes in this revision

Viewing changes to src/modules/rlm_eap/types/rlm_eap_tls/mppe_keys.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2006-12-16 20:45:11 UTC
  • mfrom: (3.1.10 feisty)
  • Revision ID: james.westby@ubuntu.com-20061216204511-3pbbsu4s8jtehsor
Tags: 1.1.3-3
Fix POSIX compliance problem in init script.  Closes: #403384. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * mppe_keys.c
3
 
 *
4
 
 * Version:     $Id: mppe_keys.c,v 1.3 2004/02/26 19:04:31 aland Exp $
5
 
 *
6
 
 *   This program is free software; you can redistribute it and/or modify
7
 
 *   it under the terms of the GNU General Public License as published by
8
 
 *   the Free Software Foundation; either version 2 of the License, or
9
 
 *   (at your option) any later version.
10
 
 *
11
 
 *   This program is distributed in the hope that it will be useful,
12
 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *   GNU General Public License for more details.
15
 
 *
16
 
 *   You should have received a copy of the GNU General Public License
17
 
 *   along with this program; if not, write to the Free Software
18
 
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 *
20
 
 * Copyright 2002  Axis Communications AB
21
 
 * Authors: Henrik Eriksson <henriken@axis.com> & Lars Viklund <larsv@axis.com>
22
 
 */
23
 
 
24
 
#include <openssl/hmac.h>
25
 
#include "eap_tls.h"
26
 
 
27
 
/*
28
 
 * Add value pair to reply
29
 
 */
30
 
static void add_reply(VALUE_PAIR** vp,
31
 
                      const char* name, const char* value, int len)
32
 
{
33
 
        VALUE_PAIR *reply_attr;
34
 
        reply_attr = pairmake(name, "", T_OP_EQ);
35
 
        if (!reply_attr) {
36
 
                DEBUG("rlm_eap_tls: "
37
 
                      "add_reply failed to create attribute %s: %s\n",
38
 
                      name, librad_errstr);
39
 
                return;
40
 
        }
41
 
 
42
 
        memcpy(reply_attr->strvalue, value, len);
43
 
        reply_attr->length = len;
44
 
        pairadd(vp, reply_attr);
45
 
}
46
 
 
47
 
/*
48
 
 * TLS PRF from RFC 2246
49
 
 */
50
 
static void P_hash(const EVP_MD *evp_md,
51
 
                   const unsigned char *secret, unsigned int secret_len,
52
 
                   const unsigned char *seed,   unsigned int seed_len,
53
 
                   unsigned char *out, unsigned int out_len)
54
 
{
55
 
        HMAC_CTX ctx_a, ctx_out;
56
 
        unsigned char a[HMAC_MAX_MD_CBLOCK];
57
 
        unsigned int size;
58
 
 
59
 
        HMAC_CTX_init(&ctx_a);
60
 
        HMAC_CTX_init(&ctx_out);
61
 
        HMAC_Init_ex(&ctx_a, secret, secret_len, evp_md, NULL);
62
 
        HMAC_Init_ex(&ctx_out, secret, secret_len, evp_md, NULL);
63
 
 
64
 
        size = HMAC_size(&ctx_out);
65
 
 
66
 
        /* Calculate A(1) */
67
 
        HMAC_Update(&ctx_a, seed, seed_len);
68
 
        HMAC_Final(&ctx_a, a, NULL);
69
 
 
70
 
        while (1) {
71
 
                /* Calculate next part of output */
72
 
                HMAC_Update(&ctx_out, a, size);
73
 
                HMAC_Update(&ctx_out, seed, seed_len);
74
 
 
75
 
                /* Check if last part */
76
 
                if (out_len < size) {
77
 
                        HMAC_Final(&ctx_out, a, NULL);
78
 
                        memcpy(out, a, out_len);
79
 
                        break;
80
 
                }
81
 
 
82
 
                /* Place digest in output buffer */
83
 
                HMAC_Final(&ctx_out, out, NULL);
84
 
                HMAC_Init_ex(&ctx_out, NULL, 0, NULL, NULL);
85
 
                out += size;
86
 
                out_len -= size;
87
 
 
88
 
                /* Calculate next A(i) */
89
 
                HMAC_Init_ex(&ctx_a, NULL, 0, NULL, NULL);
90
 
                HMAC_Update(&ctx_a, a, size);
91
 
                HMAC_Final(&ctx_a, a, NULL);
92
 
        }
93
 
 
94
 
        HMAC_CTX_cleanup(&ctx_a);
95
 
        HMAC_CTX_cleanup(&ctx_out);
96
 
        memset(a, 0, sizeof(a));
97
 
}
98
 
 
99
 
static void PRF(const unsigned char *secret, unsigned int secret_len,
100
 
                const unsigned char *seed,   unsigned int seed_len,
101
 
                unsigned char *out, unsigned char *buf, unsigned int out_len)
102
 
{
103
 
        unsigned int i;
104
 
        unsigned int len = (secret_len + 1) / 2;
105
 
        const unsigned char *s1 = secret;
106
 
        const unsigned char *s2 = secret + (secret_len - len);
107
 
 
108
 
        P_hash(EVP_md5(),  s1, len, seed, seed_len, out, out_len);
109
 
        P_hash(EVP_sha1(), s2, len, seed, seed_len, buf, out_len);
110
 
 
111
 
        for (i=0; i < out_len; i++) {
112
 
                out[i] ^= buf[i];
113
 
        }
114
 
}
115
 
 
116
 
#define EAPTLS_MPPE_KEY_LEN     32
117
 
 
118
 
#define EAPTLS_PRF_LABEL "ttls keying material"
119
 
 
120
 
/*
121
 
 *      Generate keys according to RFC 2716 and add to reply
122
 
 */
123
 
void eaptls_gen_mppe_keys(VALUE_PAIR **reply_vps, SSL *s,
124
 
                          const char *prf_label)
125
 
{
126
 
        unsigned char out[2*EAPTLS_MPPE_KEY_LEN], buf[2*EAPTLS_MPPE_KEY_LEN];
127
 
        unsigned char seed[64 + 2*SSL3_RANDOM_SIZE];
128
 
        unsigned char *p = seed;
129
 
        size_t prf_size;
130
 
 
131
 
        prf_size = strlen(prf_label);
132
 
 
133
 
        memcpy(p, prf_label, prf_size);
134
 
        p += prf_size;
135
 
 
136
 
        memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
137
 
        p += SSL3_RANDOM_SIZE;
138
 
        prf_size += SSL3_RANDOM_SIZE;
139
 
 
140
 
        memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
141
 
        prf_size += SSL3_RANDOM_SIZE;
142
 
 
143
 
        PRF(s->session->master_key, s->session->master_key_length,
144
 
            seed, prf_size, out, buf, sizeof(out));
145
 
 
146
 
        p = out;
147
 
        add_reply(reply_vps, "MS-MPPE-Recv-Key", p, EAPTLS_MPPE_KEY_LEN);
148
 
        p += EAPTLS_MPPE_KEY_LEN;
149
 
        add_reply(reply_vps, "MS-MPPE-Send-Key", p, EAPTLS_MPPE_KEY_LEN);
150
 
}
151
 
 
152
 
 
153
 
#define EAPTLS_PRF_CHALLENGE        "ttls challenge"
154
 
 
155
 
/*
156
 
 *      Generate the TTLS challenge
157
 
 *
158
 
 *      It's in the TLS module simply because it's only a few lines
159
 
 *      of code, and it needs access to the TLS PRF functions.
160
 
 */
161
 
void eapttls_gen_challenge(SSL *s, char *buffer, int size)
162
 
{
163
 
        unsigned char out[32], buf[32];
164
 
        unsigned char seed[sizeof(EAPTLS_PRF_CHALLENGE)-1 + 2*SSL3_RANDOM_SIZE];
165
 
        unsigned char *p = seed;
166
 
 
167
 
        memcpy(p, EAPTLS_PRF_CHALLENGE, sizeof(EAPTLS_PRF_CHALLENGE)-1);
168
 
        p += sizeof(EAPTLS_PRF_CHALLENGE)-1;
169
 
        memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
170
 
        p += SSL3_RANDOM_SIZE;
171
 
        memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
172
 
 
173
 
        PRF(s->session->master_key, s->session->master_key_length,
174
 
            seed, sizeof(seed), out, buf, sizeof(out));
175
 
 
176
 
        memcpy(buffer, out, size);
177
 
}