import from HEAD
[freeradius.git] / src / modules / rlm_eap / libeap / eapcrypto.c
1 /*
2  * eapcrypto.c      Common key derivation routines for EAP/SIM.
3  *
4  * The development of the EAP/SIM support was funded by Internet Foundation
5  * Austria (http://www.nic.at/ipa).
6  *
7  * Version:     $Id$
8  *
9  *   This program is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU General Public License as published by
11  *   the Free Software Foundation; either version 2 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This program is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with this program; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  * Copyright 2003  Michael Richardson <mcr@sandelman.ottawa.on.ca>
24  * Copyright 2003  The FreeRADIUS server project
25  *
26  */
27
28 #include "autoconf.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32
33 #include "eap_types.h"
34 #include "eap_sim.h"
35 #include "sha1.h"
36
37 void eapsim_calculate_keys(struct eapsim_keys *ek)
38 {
39         SHA1_CTX context;
40         uint8_t fk[160];
41         unsigned char buf[256];
42         unsigned char *p;
43         unsigned int  blen;
44
45         p = buf;
46         memcpy(p, ek->identity, ek->identitylen);   p = p+ek->identitylen;
47         memcpy(p, ek->Kc[0], EAPSIM_Kc_SIZE);       p = p+EAPSIM_Kc_SIZE;
48         memcpy(p, ek->Kc[1], EAPSIM_Kc_SIZE);       p = p+EAPSIM_Kc_SIZE;
49         memcpy(p, ek->Kc[2], EAPSIM_Kc_SIZE);       p = p+EAPSIM_Kc_SIZE;
50         memcpy(p, ek->nonce_mt, sizeof(ek->nonce_mt)); p=p+sizeof(ek->nonce_mt);
51         memcpy(p, ek->versionlist, ek->versionlistlen);p=p+ek->versionlistlen;
52         memcpy(p, ek->versionselect, sizeof(ek->versionselect)); p=p+sizeof(ek->versionselect);
53         /* *p++ = ek->versionselect[1]; */
54
55         blen = p - buf;
56
57 #if defined(TEST_CASE) || defined(DUMP_EAPSIM_KEYS)
58         {
59           unsigned int i, j, k;
60
61           j=0; k=0;
62
63           printf("SHA1buffer was: ");
64           for (i = 0; i < blen; i++) {
65             if(j==4) {
66               printf("_");
67               j=0;
68             }
69             if(k==20) {
70               printf("\n                ");
71               k=0;
72               j=0;
73             }
74             j++;
75             k++;
76
77             printf("%02x", buf[i]);
78           }
79           printf("\n");
80         }
81 #endif
82
83
84         /* do the master key first */
85         SHA1Init(&context);
86         SHA1Update(&context, buf, blen);
87         SHA1Final(ek->master_key, &context);
88
89         /*
90          * now use the PRF to expand it, generated K_aut, K_encr,
91          * MSK and EMSK.
92          */
93         fips186_2prf(ek->master_key, fk);
94
95         /* split up the result */
96         memcpy(ek->K_encr, fk +  0, 16);    /* 128 bits for encryption    */
97         memcpy(ek->K_aut,  fk + 16, EAPSIM_AUTH_SIZE); /*128 bits for auth */
98         memcpy(ek->msk,    fk + 32, 64);  /* 64 bytes for Master Session Key */
99         memcpy(ek->emsk,   fk + 96, 64);  /* 64- extended Master Session Key */
100 }
101
102
103 void eapsim_dump_mk(struct eapsim_keys *ek)
104 {
105         unsigned int i, j, k;
106
107         j=0; k=0;
108
109         printf("Input was: \n");
110         printf("   identity: (len=%d)", ek->identitylen);
111         for (i = 0; i < ek->identitylen; i++) {
112                 printf("%02x", ek->identity[i]);
113         }
114
115         printf("\n   nonce_mt: ");
116         for (i = 0; i < EAPSIM_NONCEMT_SIZE; i++) {
117                 printf("%02x", ek->nonce_mt[i]);
118         }
119
120         for (k = 0; k<3; k++) {
121                 printf("\n   rand%d: ", k);
122                 for (i = 0; i < EAPSIM_RAND_SIZE; i++) {
123                         printf("%02x", ek->rand[k][i]);
124                 }
125         }
126
127         for (k = 0; k<3; k++) {
128                 printf("\n   sres%d: ", k);
129                 for (i = 0; i < EAPSIM_SRES_SIZE; i++) {
130                         printf("%02x", ek->sres[k][i]);
131                 }
132         }
133
134         for (k = 0; k<3; k++) {
135                 printf("\n   Kc%d: ", k);
136                 for (i = 0; i < EAPSIM_Kc_SIZE; i++) {
137                         printf("%02x", ek->Kc[k][i]);
138                 }
139         }
140
141         printf("\n   versionlist[%d]: ",ek->versionlistlen);
142         for (i = 0; i < ek->versionlistlen; i++) {
143                 printf("%02x", ek->versionlist[i]);
144         }
145
146         printf("\n   select %02x %02x\n",
147                ek->versionselect[0],
148                ek->versionselect[1]);
149
150         printf("\n\nOutput\n");
151
152         printf("mk:         ");
153         j=0; k=0;
154         for (i = 0; i < sizeof(ek->master_key); i++) {
155                 if(j==4) {
156                         printf("_");
157                         j=0;
158                 }
159                 j++;
160
161                 printf("%02x", ek->master_key[i]);
162         }
163
164         printf("\nK_aut:      ");
165         j=0; k=0;
166         for (i = 0; i < sizeof(ek->K_aut); i++) {
167                 if(j==4) {
168                         printf("_");
169                         j=0;
170                 }
171                 j++;
172
173                 printf("%02x", ek->K_aut[i]);
174         }
175
176         printf("\nK_encr:     ");
177         j=0; k=0;
178         for (i = 0; i < sizeof(ek->K_encr); i++) {
179                 if(j==4) {
180                         printf("_");
181                         j=0;
182                 }
183                 j++;
184
185                 printf("%02x", ek->K_encr[i]);
186         }
187
188         printf("\nmsk:        ");
189         j=0; k=0;
190         for (i = 0; i < sizeof(ek->msk); i++) {
191                 if(k==20) {
192                         printf("\n            ");
193                         k=0;
194                         j=0;
195                 }
196                 if(j==4) {
197                         printf("_");
198                         j=0;
199                 }
200                 k++;
201                 j++;
202
203                 printf("%02x", ek->msk[i]);
204         }
205         printf("\nemsk:       ");
206         j=0; k=0;
207         for (i = 0; i < sizeof(ek->emsk); i++) {
208                 if(k==20) {
209                         printf("\n            ");
210                         k=0;
211                         j=0;
212                 }
213                 if(j==4) {
214                         printf("_");
215                         j=0;
216                 }
217                 k++;
218                 j++;
219
220                 printf("%02x", ek->emsk[i]);
221         }
222         printf("\n");
223 }
224
225 #ifdef TEST_CASE
226
227 #include <assert.h>
228
229 struct eapsim_keys inputkey1 = {
230         {'e', 'a', 'p', 's','i','m' },
231         6,
232           0x4d, 0x6c, 0x40, 0xde, 0x48, 0x3a, 0xdd, 0x99,   /* nonce_mt */
233           0x50, 0x90, 0x2c, 0x40, 0x24, 0xce, 0x76, 0x5e,
234           0x89, 0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef,   /* chalX */
235           0x89, 0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef,
236           0x9a, 0xbc, 0xde, 0xf8, 0x9a, 0xbc, 0xde, 0xf8,
237           0x9a, 0xbc, 0xde, 0xf8, 0x9a, 0xbc, 0xde, 0xf8,
238           0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, 0x89,
239           0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, 0x89,
240           0x12, 0x34, 0xab, 0xcd,                             /* sresX */
241           0x12, 0x34, 0xab, 0xcd,
242           0x23, 0x4a, 0xbc, 0xd1,
243           0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,  /* Kc */
244           0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87,
245           0x30, 0x41, 0x52, 0x63, 0x74, 0x85, 0x96, 0xa7,
246           {0x00, 0x02, 0x00, 0x01},
247           4,
248           0x00, 0x01 ,
249 };
250
251 struct eapsim_keys inputkey2 = {
252   {'1','2','4','4','0','7','0','1','0','0','0','0','0','0','0','1','@','e','a','p','s','i','m','.','f','o','o'},
253   27,
254   0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,   /* nonce_mt */
255   0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
256   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
257   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,   /* chalX */
258   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
259   0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
260   0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
261   0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
262
263   0xd1, 0xd2, 0xd3, 0xd4,  /* SRES 1 */
264   0xe1, 0xe2, 0xe3, 0xe4,
265   0xf1, 0xf2, 0xf3, 0xf4,
266
267   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,   /* Kc */
268   0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
269   0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
270   /*   {0x00, 0x02, 0x00, 0x01}, */
271   {0x00, 0x01},
272   2,
273   0x00, 0x01 ,
274 };
275
276
277
278 main(int argc, char *argv[])
279 {
280         struct eapsim_keys *ek;
281
282         ek = &inputkey1;
283
284         eapsim_calculate_keys(ek);
285         eapsim_dump_mk(ek);
286
287         ek = &inputkey2;
288
289         eapsim_calculate_keys(ek);
290         eapsim_dump_mk(ek);
291 }
292 #endif
293
294
295
296
297
298
299 /*
300  * Local Variables:
301  * c-style: bsd
302  * End:
303  */