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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Copyright 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
24 * Copyright 2003 The FreeRADIUS server project
33 #include "eap_types.h"
37 #include <rad_assert.h>
39 void eapsim_calculate_keys(struct eapsim_keys *ek)
43 unsigned char buf[256];
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]; */
59 #if defined(TEST_CASE) || defined(DUMP_EAPSIM_KEYS)
65 printf("SHA1buffer was: ");
66 for (i = 0; i < blen; i++) {
79 printf("%02x", buf[i]);
86 /* do the master key first */
88 SHA1Update(&context, buf, blen);
89 SHA1Final(ek->master_key, &context);
92 * now use the PRF to expand it, generated K_aut, K_encr,
95 fips186_2prf(ek->master_key, fk);
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 */
105 void eapsim_dump_mk(struct eapsim_keys *ek)
107 unsigned int i, j, k;
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]);
117 printf("\n nonce_mt: ");
118 for (i = 0; i < EAPSIM_NONCEMT_SIZE; i++) {
119 printf("%02x", ek->nonce_mt[i]);
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]);
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]);
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]);
143 printf("\n versionlist[%d]: ",ek->versionlistlen);
144 for (i = 0; i < ek->versionlistlen; i++) {
145 printf("%02x", ek->versionlist[i]);
148 printf("\n select %02x %02x\n",
149 ek->versionselect[0],
150 ek->versionselect[1]);
152 printf("\n\nOutput\n");
156 for (i = 0; i < sizeof(ek->master_key); i++) {
163 printf("%02x", ek->master_key[i]);
168 for (i = 0; i < sizeof(ek->K_aut); i++) {
175 printf("%02x", ek->K_aut[i]);
178 printf("\nK_encr: ");
180 for (i = 0; i < sizeof(ek->K_encr); i++) {
187 printf("%02x", ek->K_encr[i]);
192 for (i = 0; i < sizeof(ek->msk); i++) {
205 printf("%02x", ek->msk[i]);
209 for (i = 0; i < sizeof(ek->emsk); i++) {
222 printf("%02x", ek->emsk[i]);
231 struct eapsim_keys inputkey1 = {
232 {'e', 'a', 'p', 's','i','m' },
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},
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'},
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,
265 0xd1, 0xd2, 0xd3, 0xd4, /* SRES 1 */
266 0xe1, 0xe2, 0xe3, 0xe4,
267 0xf1, 0xf2, 0xf3, 0xf4,
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}, */
280 main(int argc, char *argv[])
282 struct eapsim_keys *ek;
286 eapsim_calculate_keys(ek);
291 eapsim_calculate_keys(ek);