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 The FreeRADIUS server project
28 #include <freeradius-devel/autoconf.h>
33 #include "eap_types.h"
35 #include <freeradius-devel/sha1.h>
37 void eapsim_calculate_keys(struct eapsim_keys *ek)
41 unsigned char buf[256];
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]; */
57 #if defined(TEST_CASE) || defined(DUMP_EAPSIM_KEYS)
63 printf("SHA1buffer was: ");
64 for (i = 0; i < blen; i++) {
77 printf("%02x", buf[i]);
84 /* do the master key first */
86 SHA1Update(&context, buf, blen);
87 SHA1Final(ek->master_key, &context);
90 * now use the PRF to expand it, generated K_aut, K_encr,
93 fips186_2prf(ek->master_key, fk);
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 */
103 void eapsim_dump_mk(struct eapsim_keys *ek)
105 unsigned int i, j, k;
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]);
115 printf("\n nonce_mt: ");
116 for (i = 0; i < EAPSIM_NONCEMT_SIZE; i++) {
117 printf("%02x", ek->nonce_mt[i]);
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]);
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]);
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]);
141 printf("\n versionlist[%d]: ",ek->versionlistlen);
142 for (i = 0; i < ek->versionlistlen; i++) {
143 printf("%02x", ek->versionlist[i]);
146 printf("\n select %02x %02x\n",
147 ek->versionselect[0],
148 ek->versionselect[1]);
150 printf("\n\nOutput\n");
154 for (i = 0; i < sizeof(ek->master_key); i++) {
161 printf("%02x", ek->master_key[i]);
166 for (i = 0; i < sizeof(ek->K_aut); i++) {
173 printf("%02x", ek->K_aut[i]);
176 printf("\nK_encr: ");
178 for (i = 0; i < sizeof(ek->K_encr); i++) {
185 printf("%02x", ek->K_encr[i]);
190 for (i = 0; i < sizeof(ek->msk); i++) {
203 printf("%02x", ek->msk[i]);
207 for (i = 0; i < sizeof(ek->emsk); i++) {
220 printf("%02x", ek->emsk[i]);
229 struct eapsim_keys inputkey1 = {
230 {'e', 'a', 'p', 's','i','m' },
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},
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'},
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,
263 0xd1, 0xd2, 0xd3, 0xd4, /* SRES 1 */
264 0xe1, 0xe2, 0xe3, 0xe4,
265 0xf1, 0xf2, 0xf3, 0xf4,
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}, */
278 main(int argc, char *argv[])
280 struct eapsim_keys *ek;
284 eapsim_calculate_keys(ek);
289 eapsim_calculate_keys(ek);