The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
fips186prf.c
Go to the documentation of this file.
1 /*
2  * GPLv2 LICENSE:
3  *
4  * This program is is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or (at
7  * your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  */
19 
20 /*
21  * BSD LICENSE:
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  * notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  * notice, this list of conditions and the following disclaimer in the
30  * documentation and/or other materials provided with the distribution.
31  * 3. Neither the name of The NetBSD Foundation nor the names of its
32  * contributors may be used to endorse or promote products derived
33  * from this software without specific prior written permission.
34  */
35 
36 /**
37  * $Id: 2f9da199428902824666050e86c23d5345f526f9 $
38  * @file src/lib/eap_aka_sim/fips186prf.c
39  * @brief EAP sim protocol encoders and decoders.
40  *
41  * The development of the EAP/SIM support was funded by Internet Foundation
42  * Austria (http://www.nic.at/ipa).
43  *
44  * This code was written from scratch by Michael Richardson, and is
45  * dual licensed under both GPL and BSD.
46  *
47  * @copyright 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
48  * @copyright 2003-2016 The FreeRADIUS server project
49  */
50 RCSID("$Id: 2f9da199428902824666050e86c23d5345f526f9 $")
51 
52 #include <freeradius-devel/util/sha1.h>
53 #include "base.h"
54 
55 /*
56  * we do it in 8-bit chunks, because we have to keep the numbers
57  * in network byte order (i.e. MSB)
58  *
59  * make it a structure so that we can do structure assignments.
60  */
61 typedef struct {
62  uint8_t p[20];
63 } onesixty;
64 
65 static void onesixty_add_mod(onesixty *sum, onesixty *a, onesixty *b)
66 {
67  uint32_t s;
68  int i, carry;
69 
70  carry = 0;
71  for(i = 19; i >= 0; i--) {
72  s = a->p[i] + b->p[i] + carry;
73  sum->p[i] = s & 0xff;
74  carry = s >> 8;
75  }
76 }
77 
78 /** Implement the FIPS-186-2 PRF to derive keying material from the MK
79  *
80  * run the FIPS-186-2 PRF on the given Master Key (160 bits)
81  * in order to derive 1280 bits (160 bytes) of keying data from
82  * it.
83  *
84  * Given that in EAP-SIM, this is coming from a 64-bit Kc it seems
85  * like an awful lot of "randomness" to pull out..
86  *
87  * @param[out] out Buffer to contain the data derived from the mk.
88  * @param[in] mk The master key we use to derive all other keying
89  * data.
90  */
91 void fr_aka_sim_fips186_2prf(uint8_t out[static 160], uint8_t mk[static 20])
92 {
94  int j;
95  onesixty xval, xkey, w_0, w_1, sum, one;
96  uint8_t *f;
97  uint8_t zeros[64];
98 
99  /*
100  * let XKEY := MK,
101  *
102  * Step 3: For j = 0 to 3 do
103  * a. XVAL = XKEY
104  * b. w_0 = SHA1(XVAL)
105  * c. XKEY = (1 + XKEY + w_0) mod 2^160
106  * d. XVAL = XKEY
107  * e. w_1 = SHA1(XVAL)
108  * f. XKEY = (1 + XKEY + w_1) mod 2^160
109  * 3.3 x_j = w_0|w_1
110  *
111  */
112  memcpy(&xkey, mk, sizeof(xkey));
113 
114  /* make the value 1 */
115  memset(&one, 0, sizeof(one));
116  one.p[19]=1;
117 
118  f = out;
119 
120  for (j = 0; j < 4; j++) {
121  /* a. XVAL = XKEY */
122  xval = xkey;
123 
124  /* b. w_0 = SHA1(XVAL) */
126 
127  memset(zeros + 20, 0, sizeof(zeros) - 20);
128  memcpy(zeros, xval.p, 20);
129 #ifndef WITH_OPENSSL_SHA1
131 #else
133 #endif
135 
136  /* c. XKEY = (1 + XKEY + w_0) mod 2^160 */
137  onesixty_add_mod(&sum, &xkey, &w_0);
138  onesixty_add_mod(&xkey, &sum, &one);
139 
140  /* d. XVAL = XKEY */
141  xval = xkey;
142 
143  /* e. w_1 = SHA1(XVAL) */
145 
146  memset(zeros + 20, 0, sizeof(zeros) - 20);
147  memcpy(zeros, xval.p, 20);
148 #ifndef WITH_OPENSSL_SHA1
150 #else
152 #endif
154 
155  /* f. XKEY = (1 + XKEY + w_1) mod 2^160 */
156  onesixty_add_mod(&sum, &xkey, &w_1);
157  onesixty_add_mod(&xkey, &sum, &one);
158 
159  /* now store it away */
160  memcpy(f, &w_0, 20);
161  f += 20;
162 
163  memcpy(f, &w_1, 20);
164  f += 20;
165  }
166 }
167 
168 #ifdef TESTING_FIPS186_PRF
169 /*
170  * cc fips186prf.c -g3 -Wall -DTESTING_FIPS186_PRF -DHAVE_DLFCN_H -DWITH_TLS -I../../../../ -I../../../ -I ../base/ -I /usr/local/opt/openssl/include/ -include ../include/build.h -L /usr/local/opt/openssl/lib/ -l ssl -l crypto -l talloc -L ../../../../../build/lib/local/.libs/ -lfreeradius-server -lfreeradius-tls -lfreeradius-util -o test_fips186prf && ./test_fips186prf
171  */
172 #include <freeradius-devel/util/acutest.h>
173 
174 /*
175  * test vectors
176  * from http://csrc.nist.gov/CryptoToolkit/dss/Examples-1024bit.pdf
177  *
178  * page 5
179  *
180  * XKEY= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6
181  * XSEED= 00000000 00000000 00000000 00000000 00000000
182  *
183  *
184  * The first loop through step 3.2 provides:
185  *
186  * XVAL= bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6
187  *
188  * Using the routine in Appendix 3.3, Constructing The Function G From SHA-1,
189  * in step 3.2.b of the Change Notice algorithm for computing values of x
190  * provides:
191  *
192  * w[0]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614
193  *
194  *
195  * The following value is the updated XKEY value from step 3.2.c:
196  *
197  * XKEY= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb
198  *
199  * The second loop through step 3.2 provides:
200  *
201  * XVAL= dd734ee0 bd0bcd3b adbaeb27 dd1eaa59 76803ecb
202  *
203  * Using the routine in Appendix 3.3, Constructing The Function G From SHA-1,
204  * in step 3.2.b of the Change Notice algorithm for computing values of x
205  * provides:
206  *
207  * w[1]= 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116
208  *
209  * The following value is the updated XKEY value from step 3.2.c:
210  *
211  *
212  * XKEY= 19df679b 881b3991 6875fea0 6b3f8191 19a78fe2
213  *
214  * Step 3.3 provides the following values:
215  *
216  * w[0] || w[1]= 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614
217  * 3c6c18ba cb0f6c55 babb1378 8e20d737 a3275116
218  *
219  */
220 
221 static uint8_t xkey[] = { 0xbd, 0x02, 0x9b, 0xbe, 0x7f, 0x51, 0x96, 0x0b,
222  0xcf, 0x9e, 0xdb, 0x2b, 0x61, 0xf0, 0x6f, 0x0f,
223  0xeb, 0x5a, 0x38, 0xb6 };
224 
225 static uint8_t exp[] = { 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f,
226  0xde, 0x1c, 0x0f, 0xfc, 0x7b, 0x2e, 0x3b, 0x49,
227  0x8b, 0x26, 0x06, 0x14, 0x3c, 0x6c, 0x18, 0xba,
228  0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78,
229  0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16 };
230 
231 static void test_fips186prf(void)
232 {
233  uint8_t res[160];
234 
235  fr_sim_fips186_2prf(res, xkey);
236 
237  TEST_CHECK(memcmp(exp, res, sizeof(exp)) == 0);
238 }
239 
240 
241 TEST_LIST = {
242  { "test_fips186prf", test_fips186prf },
243  { NULL }
244 };
245 
246 #endif
#define TEST_CHECK(cond)
Definition: acutest.h:85
#define TEST_LIST
Definition: acutest.h:62
static int context
Definition: radmin.c:71
#define RCSID(id)
Definition: build.h:444
uint8_t p[20]
Definition: fips186prf.c:62
void fr_aka_sim_fips186_2prf(uint8_t out[static 160], uint8_t mk[static 20])
Implement the FIPS-186-2 PRF to derive keying material from the MK.
Definition: fips186prf.c:91
static void onesixty_add_mod(onesixty *sum, onesixty *a, onesixty *b)
Definition: fips186prf.c:65
unsigned int uint32_t
Definition: merged_model.c:33
unsigned char uint8_t
Definition: merged_model.c:30
static const uint8_t zeros[RADIUS_AUTH_VECTOR_LENGTH]
Definition: radsniff.c:1262
void fr_sha1_init(fr_sha1_ctx *context)
Definition: sha1.c:93
void fr_sha1_final_no_len(uint8_t digest[static SHA1_DIGEST_LENGTH], fr_sha1_ctx *context)
Definition: sha1.c:174
void fr_sha1_transform(uint32_t state[static 5], uint8_t const buffer[static 64])
Definition: sha1.c:35
Master include file to access all functions and structures in the library.
static size_t char ** out
Definition: value.h:984