977311686f078f7b3ed00eb28de4bbf0622b26a7
[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 #include <rad_assert.h>
38
39 void eapsim_calculate_keys(struct eapsim_keys *ek)
40 {
41         SHA1_CTX context;
42         uint8_t fk[160];
43         unsigned char buf[256];
44         unsigned char *p;
45         unsigned int  blen;
46
47         p = buf;
48         memcpy(p, ek->identity, ek->identitylen);   p = p+ek->identitylen;
49         memcpy(p, ek->Kc[0], EAPSIM_Kc_SIZE);       p = p+EAPSIM_Kc_SIZE;
50         memcpy(p, ek->Kc[1], EAPSIM_Kc_SIZE);       p = p+EAPSIM_Kc_SIZE;
51         memcpy(p, ek->Kc[2], EAPSIM_Kc_SIZE);       p = p+EAPSIM_Kc_SIZE;
52         memcpy(p, ek->nonce_mt, sizeof(ek->nonce_mt)); p=p+sizeof(ek->nonce_mt);
53         memcpy(p, ek->versionlist, ek->versionlistlen);p=p+ek->versionlistlen;
54         memcpy(p, ek->versionselect, sizeof(ek->versionselect)); p=p+sizeof(ek->versionselect); 
55         /* *p++ = ek->versionselect[1]; */
56         
57         blen = p - buf;
58
59 #if defined(TEST_CASE) || defined(DUMP_EAPSIM_KEYS)
60         {
61           unsigned int i, j, k;
62           
63           j=0; k=0;
64           
65           printf("SHA1buffer was: ");
66           for (i = 0; i < blen; i++) {
67             if(j==4) {
68               printf("_");
69               j=0;
70             }
71             if(k==20) {
72               printf("\n                ");
73               k=0;
74               j=0;
75             } 
76             j++;
77             k++;
78
79             printf("%02x", buf[i]);
80           }
81           printf("\n");
82         }
83 #endif    
84
85           
86         /* do the master key first */
87         SHA1Init(&context);
88         SHA1Update(&context, buf, blen);
89         SHA1Final(ek->master_key, &context);
90
91         /*
92          * now use the PRF to expand it, generated K_aut, K_encr,
93          * MSK and EMSK.
94          */
95         fips186_2prf(ek->master_key, fk);
96
97         /* split up the result */
98         memcpy(ek->K_encr, fk +  0, 16);    /* 128 bits for encryption    */
99         memcpy(ek->K_aut,  fk + 16, EAPSIM_AUTH_SIZE); /*128 bits for auth */
100         memcpy(ek->msk,    fk + 32, 64);  /* 64 bytes for Master Session Key */
101         memcpy(ek->emsk,   fk + 96, 64);  /* 64- extended Master Session Key */
102 }
103
104
105 void eapsim_dump_mk(struct eapsim_keys *ek)
106 {
107         unsigned int i, j, k;
108
109         j=0; k=0;
110
111         printf("Input was: \n");
112         printf("   identity: (len=%d)", ek->identitylen);
113         for (i = 0; i < ek->identitylen; i++) {
114                 printf("%02x", ek->identity[i]);
115         }
116
117         printf("\n   nonce_mt: ");
118         for (i = 0; i < EAPSIM_NONCEMT_SIZE; i++) {
119                 printf("%02x", ek->nonce_mt[i]);
120         }
121
122         for (k = 0; k<3; k++) {
123                 printf("\n   rand%d: ", k);
124                 for (i = 0; i < EAPSIM_RAND_SIZE; i++) {
125                         printf("%02x", ek->rand[k][i]);
126                 }
127         }
128
129         for (k = 0; k<3; k++) {
130                 printf("\n   sres%d: ", k);
131                 for (i = 0; i < EAPSIM_SRES_SIZE; i++) {
132                         printf("%02x", ek->sres[k][i]);
133                 }
134         }
135
136         for (k = 0; k<3; k++) {
137                 printf("\n   Kc%d: ", k);
138                 for (i = 0; i < EAPSIM_Kc_SIZE; i++) {
139                         printf("%02x", ek->Kc[k][i]);
140                 }
141         }
142
143         printf("\n   versionlist[%d]: ",ek->versionlistlen);
144         for (i = 0; i < ek->versionlistlen; i++) {
145                 printf("%02x", ek->versionlist[i]);
146         }
147
148         printf("\n   select %02x %02x\n",
149                ek->versionselect[0], 
150                ek->versionselect[1]);
151
152         printf("\n\nOutput\n");
153
154         printf("mk:         ");
155         j=0; k=0;
156         for (i = 0; i < sizeof(ek->master_key); i++) {
157                 if(j==4) {
158                         printf("_");
159                         j=0;
160                 }
161                 j++;
162
163                 printf("%02x", ek->master_key[i]);
164         }
165
166         printf("\nK_aut:      ");
167         j=0; k=0;
168         for (i = 0; i < sizeof(ek->K_aut); i++) {
169                 if(j==4) {
170                         printf("_");
171                         j=0;
172                 }
173                 j++;
174
175                 printf("%02x", ek->K_aut[i]);
176         }
177
178         printf("\nK_encr:     ");
179         j=0; k=0;
180         for (i = 0; i < sizeof(ek->K_encr); i++) {
181                 if(j==4) {
182                         printf("_");
183                         j=0;
184                 }
185                 j++;
186
187                 printf("%02x", ek->K_encr[i]);
188         }
189
190         printf("\nmsk:        ");
191         j=0; k=0;
192         for (i = 0; i < sizeof(ek->msk); i++) {
193                 if(k==20) {
194                         printf("\n            ");
195                         k=0;
196                         j=0;
197                 } 
198                 if(j==4) {
199                         printf("_");
200                         j=0;
201                 }
202                 k++;
203                 j++;
204
205                 printf("%02x", ek->msk[i]);
206         }
207         printf("\nemsk:       ");
208         j=0; k=0;
209         for (i = 0; i < sizeof(ek->emsk); i++) {
210                 if(k==20) {
211                         printf("\n            ");
212                         k=0;
213                         j=0;
214                 } 
215                 if(j==4) {
216                         printf("_");
217                         j=0;
218                 }
219                 k++;
220                 j++;
221
222                 printf("%02x", ek->emsk[i]);
223         }
224         printf("\n");
225 }
226
227 #ifdef TEST_CASE
228
229 #include <assert.h>
230
231 struct eapsim_keys inputkey1 = {
232         {'e', 'a', 'p', 's','i','m' },
233         6,
234           0x4d, 0x6c, 0x40, 0xde, 0x48, 0x3a, 0xdd, 0x99,   /* nonce_mt */
235           0x50, 0x90, 0x2c, 0x40, 0x24, 0xce, 0x76, 0x5e,
236           0x89, 0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef,   /* chalX */
237           0x89, 0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef,
238           0x9a, 0xbc, 0xde, 0xf8, 0x9a, 0xbc, 0xde, 0xf8,
239           0x9a, 0xbc, 0xde, 0xf8, 0x9a, 0xbc, 0xde, 0xf8,
240           0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, 0x89,   
241           0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, 0x89,
242           0x12, 0x34, 0xab, 0xcd,                             /* sresX */
243           0x12, 0x34, 0xab, 0xcd, 
244           0x23, 0x4a, 0xbc, 0xd1, 
245           0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,  /* Kc */
246           0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87,
247           0x30, 0x41, 0x52, 0x63, 0x74, 0x85, 0x96, 0xa7,
248           {0x00, 0x02, 0x00, 0x01},
249           4,
250           0x00, 0x01 ,
251 };
252
253 struct eapsim_keys inputkey2 = {
254   {'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'},
255   27, 
256   0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,   /* nonce_mt */
257   0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
258   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
259   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,   /* chalX */
260   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
261   0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
262   0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
263   0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
264
265   0xd1, 0xd2, 0xd3, 0xd4,  /* SRES 1 */
266   0xe1, 0xe2, 0xe3, 0xe4, 
267   0xf1, 0xf2, 0xf3, 0xf4, 
268
269   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,   /* Kc */
270   0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
271   0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
272   /*   {0x00, 0x02, 0x00, 0x01}, */
273   {0x00, 0x01}, 
274   2,
275   0x00, 0x01 ,
276 };
277
278
279
280 main(int argc, char *argv[])
281 {
282         struct eapsim_keys *ek;
283
284         ek = &inputkey1;
285
286         eapsim_calculate_keys(ek);
287         eapsim_dump_mk(ek);
288
289         ek = &inputkey2;
290
291         eapsim_calculate_keys(ek);
292         eapsim_dump_mk(ek);
293 }
294 #endif
295
296         
297         
298
299
300
301 /*
302  * Local Variables:
303  * c-style: bsd
304  * End:
305  */