2 * eapcrypto.c Common key derivation routines for EAP/SIM.
4 * The development of the EAP/SIM support was funded by Internet Foundation
5 * Austria (http://www.nic.at/ipa).
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.
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.
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
23 * Copyright 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
24 * Copyright 2003,2006 The FreeRADIUS server project
28 #include <freeradius-devel/ident.h>
31 #include <freeradius-devel/autoconf.h>
36 #include "eap_types.h"
38 #include <freeradius-devel/sha1.h>
40 void eapsim_calculate_keys(struct eapsim_keys *ek)
44 unsigned char buf[256];
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]; */
60 #if defined(TEST_CASE) || defined(DUMP_EAPSIM_KEYS)
66 printf("SHA1buffer was: ");
67 for (i = 0; i < blen; i++) {
80 printf("%02x", buf[i]);
87 /* do the master key first */
88 fr_SHA1Init(&context);
89 fr_SHA1Update(&context, buf, blen);
90 fr_SHA1Final(ek->master_key, &context);
93 * now use the PRF to expand it, generated K_aut, K_encr,
96 fips186_2prf(ek->master_key, fk);
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 */
106 void eapsim_dump_mk(struct eapsim_keys *ek)
108 unsigned int i, j, k;
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]);
118 printf("\n nonce_mt: ");
119 for (i = 0; i < EAPSIM_NONCEMT_SIZE; i++) {
120 printf("%02x", ek->nonce_mt[i]);
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]);
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]);
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]);
144 printf("\n versionlist[%d]: ",ek->versionlistlen);
145 for (i = 0; i < ek->versionlistlen; i++) {
146 printf("%02x", ek->versionlist[i]);
149 printf("\n select %02x %02x\n",
150 ek->versionselect[0],
151 ek->versionselect[1]);
153 printf("\n\nOutput\n");
157 for (i = 0; i < sizeof(ek->master_key); i++) {
164 printf("%02x", ek->master_key[i]);
169 for (i = 0; i < sizeof(ek->K_aut); i++) {
176 printf("%02x", ek->K_aut[i]);
179 printf("\nK_encr: ");
181 for (i = 0; i < sizeof(ek->K_encr); i++) {
188 printf("%02x", ek->K_encr[i]);
193 for (i = 0; i < sizeof(ek->msk); i++) {
206 printf("%02x", ek->msk[i]);
210 for (i = 0; i < sizeof(ek->emsk); i++) {
223 printf("%02x", ek->emsk[i]);
232 struct eapsim_keys inputkey1 = {
233 {'e', 'a', 'p', 's','i','m' },
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},
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'},
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,
266 0xd1, 0xd2, 0xd3, 0xd4, /* SRES 1 */
267 0xe1, 0xe2, 0xe3, 0xe4,
268 0xf1, 0xf2, 0xf3, 0xf4,
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}, */
281 main(int argc, char *argv[])
283 struct eapsim_keys *ek;
287 eapsim_calculate_keys(ek);
292 eapsim_calculate_keys(ek);