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