All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
eapcrypto.c
Go to the documentation of this file.
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: f57714b6df9164afdccad0b73138c3c0e6f1b141 $
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 RCSID("$Id: f57714b6df9164afdccad0b73138c3c0e6f1b141 $")
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 
33 #include "eap_types.h"
34 #include "eap_sim.h"
35 #include <freeradius-devel/sha1.h>
36 
38 {
39  fr_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  fr_sha1_init(&context);
86  fr_sha1_update(&context, buf, blen);
87  fr_sha1_final(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  printf("Input was: \n");
108  printf(" identity: (len=%u)", ek->identitylen);
109  for (i = 0; i < ek->identitylen; i++) {
110  printf("%02x", ek->identity[i]);
111  }
112 
113  printf("\n nonce_mt: ");
114  for (i = 0; i < EAPSIM_NONCEMT_SIZE; i++) {
115  printf("%02x", ek->nonce_mt[i]);
116  }
117 
118  for (k = 0; k<3; k++) {
119  printf("\n rand%u: ", k);
120  for (i = 0; i < EAPSIM_RAND_SIZE; i++) {
121  printf("%02x", ek->rand[k][i]);
122  }
123  }
124 
125  for (k = 0; k<3; k++) {
126  printf("\n sres%u: ", k);
127  for (i = 0; i < EAPSIM_SRES_SIZE; i++) {
128  printf("%02x", ek->sres[k][i]);
129  }
130  }
131 
132  for (k = 0; k<3; k++) {
133  printf("\n Kc%u: ", k);
134  for (i = 0; i < EAPSIM_KC_SIZE; i++) {
135  printf("%02x", ek->Kc[k][i]);
136  }
137  }
138 
139  printf("\n versionlist[%d]: ",ek->versionlistlen);
140  for (i = 0; i < ek->versionlistlen; i++) {
141  printf("%02x", ek->versionlist[i]);
142  }
143 
144  printf("\n select %02x %02x\n",
145  ek->versionselect[0],
146  ek->versionselect[1]);
147 
148  printf("\n\nOutput\n");
149 
150  printf("mk: ");
151  j=0;
152  for (i = 0; i < sizeof(ek->master_key); i++) {
153  if(j==4) {
154  printf("_");
155  j=0;
156  }
157  j++;
158 
159  printf("%02x", ek->master_key[i]);
160  }
161 
162  printf("\nK_aut: ");
163  j=0;
164  for (i = 0; i < sizeof(ek->K_aut); i++) {
165  if(j==4) {
166  printf("_");
167  j=0;
168  }
169  j++;
170 
171  printf("%02x", ek->K_aut[i]);
172  }
173 
174  printf("\nK_encr: ");
175  j=0;
176  for (i = 0; i < sizeof(ek->K_encr); i++) {
177  if(j==4) {
178  printf("_");
179  j=0;
180  }
181  j++;
182 
183  printf("%02x", ek->K_encr[i]);
184  }
185 
186  printf("\nmsk: ");
187  j=0; k=0;
188  for (i = 0; i < sizeof(ek->msk); i++) {
189  if(k==20) {
190  printf("\n ");
191  k=0;
192  j=0;
193  }
194  if(j==4) {
195  printf("_");
196  j=0;
197  }
198  k++;
199  j++;
200 
201  printf("%02x", ek->msk[i]);
202  }
203  printf("\nemsk: ");
204  j=0; k=0;
205  for (i = 0; i < sizeof(ek->emsk); i++) {
206  if(k==20) {
207  printf("\n ");
208  k=0;
209  j=0;
210  }
211  if(j==4) {
212  printf("_");
213  j=0;
214  }
215  k++;
216  j++;
217 
218  printf("%02x", ek->emsk[i]);
219  }
220  printf("\n");
221 }
222 
223 #ifdef TEST_CASE
224 
225 #include <assert.h>
226 
227 struct eapsim_keys inputkey1 = {
228  {'e', 'a', 'p', 's','i','m' },
229  6,
230  0x4d, 0x6c, 0x40, 0xde, 0x48, 0x3a, 0xdd, 0x99, /* nonce_mt */
231  0x50, 0x90, 0x2c, 0x40, 0x24, 0xce, 0x76, 0x5e,
232  0x89, 0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, /* chalX */
233  0x89, 0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef,
234  0x9a, 0xbc, 0xde, 0xf8, 0x9a, 0xbc, 0xde, 0xf8,
235  0x9a, 0xbc, 0xde, 0xf8, 0x9a, 0xbc, 0xde, 0xf8,
236  0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, 0x89,
237  0xab, 0xcd, 0xef, 0x89, 0xab, 0xcd, 0xef, 0x89,
238  0x12, 0x34, 0xab, 0xcd, /* sresX */
239  0x12, 0x34, 0xab, 0xcd,
240  0x23, 0x4a, 0xbc, 0xd1,
241  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, /* Kc */
242  0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87,
243  0x30, 0x41, 0x52, 0x63, 0x74, 0x85, 0x96, 0xa7,
244  {0x00, 0x02, 0x00, 0x01},
245  4,
246  0x00, 0x01 ,
247 };
248 
249 struct eapsim_keys inputkey2 = {
250  {'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'},
251  27,
252  0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, /* nonce_mt */
253  0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
254  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
255  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* chalX */
256  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
257  0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
258  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
259  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
260 
261  0xd1, 0xd2, 0xd3, 0xd4, /* SRES 1 */
262  0xe1, 0xe2, 0xe3, 0xe4,
263  0xf1, 0xf2, 0xf3, 0xf4,
264 
265  0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* Kc */
266  0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
267  0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
268  /* {0x00, 0x02, 0x00, 0x01}, */
269  {0x00, 0x01},
270  2,
271  0x00, 0x01 ,
272 };
273 
274 
275 
276 main(int argc, char *argv[])
277 {
278  struct eapsim_keys *ek;
279 
280  ek = &inputkey1;
281 
283  eapsim_dump_mk(ek);
284 
285  ek = &inputkey2;
286 
288  eapsim_dump_mk(ek);
289 }
290 #endif
291 
292 
293 
294 
295 
296 
297 /*
298  * Local Variables:
299  * c-style: bsd
300  * End:
301  */
void fr_sha1_update(fr_sha1_ctx *context, uint8_t const *data, size_t len)
Definition: sha1.c:106
uint8_t msk[64]
Definition: eap_sim.h:102
#define EAPSIM_AUTH_SIZE
Definition: eap_sim.h:84
uint8_t sres[3][EAPSIM_SRES_SIZE]
Definition: eap_sim.h:92
uint8_t versionselect[2]
Definition: eap_sim.h:96
void fr_sha1_init(fr_sha1_ctx *context)
Definition: sha1.c:94
#define EAPSIM_KC_SIZE
Definition: eap_sim.h:81
void fips186_2prf(uint8_t mk[20], uint8_t finalkey[160])
Definition: fips186prf.c:100
#define EAPSIM_NONCEMT_SIZE
Definition: eap_sim.h:83
uint8_t emsk[64]
Definition: eap_sim.h:103
uint8_t rand[3][EAPSIM_RAND_SIZE]
Definition: eap_sim.h:91
uint8_t K_encr[16]
Definition: eap_sim.h:101
void fr_sha1_final(uint8_t digest[20], fr_sha1_ctx *context)
Definition: sha1.c:132
uint8_t identity[MAX_STRING_LEN]
Definition: eap_sim.h:88
uint8_t K_aut[EAPSIM_AUTH_SIZE]
Definition: eap_sim.h:100
uint8_t Kc[3][EAPSIM_KC_SIZE]
Definition: eap_sim.h:93
uint8_t versionlist[MAX_STRING_LEN]
Definition: eap_sim.h:94
void eapsim_dump_mk(struct eapsim_keys *ek)
Definition: eapcrypto.c:103
uint8_t master_key[20]
Definition: eap_sim.h:99
void eapsim_calculate_keys(struct eapsim_keys *ek)
Definition: eapcrypto.c:37
#define EAPSIM_SRES_SIZE
Definition: eap_sim.h:79
int main(int argc, char *argv[])
Definition: radattr.c:959
uint8_t versionlistlen
Definition: eap_sim.h:95
uint8_t nonce_mt[EAPSIM_NONCEMT_SIZE]
Definition: eap_sim.h:90
#define RCSID(id)
Definition: build.h:135
#define EAPSIM_RAND_SIZE
Definition: eap_sim.h:80
unsigned int identitylen
Definition: eap_sim.h:89