Browse Source

Merge branch 'master' into strings

tags/v0.9.3
Holger Lubitz 17 years ago
parent
commit
58f5565eb0
66 changed files with 4027 additions and 734 deletions
  1. 1
    0
      src/Makefile
  2. 12
    0
      src/arch/i386/Config
  3. 1
    1
      src/arch/i386/core/relocate.c
  4. 0
    336
      src/arch/i386/core/udivmod64.c
  5. 7
    1
      src/arch/i386/drivers/net/undinet.c
  6. 62
    50
      src/arch/i386/image/bzimage.c
  7. 1
    1
      src/arch/i386/image/eltorito.c
  8. 1
    1
      src/arch/i386/image/multiboot.c
  9. 5
    8
      src/arch/i386/image/nbi.c
  10. 1
    1
      src/arch/i386/interface/pcbios/int13.c
  11. 2
    2
      src/arch/i386/interface/pxe/pxe_call.c
  12. 1
    0
      src/config.h
  13. 60
    0
      src/core/abft.c
  14. 3
    0
      src/core/config.c
  15. 78
    0
      src/core/filter.c
  16. 1
    1
      src/core/main.c
  17. 867
    0
      src/crypto/axtls/axtls_asn1.c
  18. 12
    25
      src/crypto/axtls/bigint.c
  19. 5
    5
      src/crypto/axtls/bigint.h
  20. 10
    5
      src/crypto/axtls/crypto.h
  21. 0
    3
      src/crypto/axtls/os_port.h
  22. 12
    18
      src/crypto/axtls/rsa.c
  23. 120
    0
      src/crypto/hmac.c
  24. 1
    1
      src/crypto/md5.c
  25. 4
    0
      src/drivers/bitbash/spi_bit.c
  26. 1
    1
      src/drivers/net/bnx2.c
  27. 1
    1
      src/drivers/net/ns83820.c
  28. 1
    1
      src/drivers/net/pcnet32.c
  29. 2
    2
      src/drivers/net/r8169.c
  30. 2
    2
      src/drivers/net/via-velocity.h
  31. 2
    1
      src/hci/commands/image_cmd.c
  32. 1
    12
      src/hci/mucurses/kb.c
  33. 1
    1
      src/hci/mucurses/slk.c
  34. 3
    0
      src/include/compiler.h
  35. 4
    0
      src/include/curses.h
  36. 35
    0
      src/include/gpxe/abft.h
  37. 8
    17
      src/include/gpxe/aoe.h
  38. 3
    0
      src/include/gpxe/ata.h
  39. 23
    6
      src/include/gpxe/dhcp.h
  40. 2
    0
      src/include/gpxe/errfile.h
  41. 75
    0
      src/include/gpxe/filter.h
  42. 30
    0
      src/include/gpxe/hmac.h
  43. 5
    0
      src/include/gpxe/http.h
  44. 9
    0
      src/include/gpxe/iscsi.h
  45. 1
    0
      src/include/gpxe/open.h
  46. 164
    5
      src/include/gpxe/tls.h
  47. 6
    0
      src/include/usr/aoeboot.h
  48. 8
    10
      src/interface/pxe/pxe_preboot.c
  49. 26
    0
      src/libgcc/__divdi3.c
  50. 26
    0
      src/libgcc/__moddi3.c
  51. 10
    0
      src/libgcc/__udivdi3.c
  52. 32
    0
      src/libgcc/__udivmoddi4.c
  53. 13
    0
      src/libgcc/__umoddi3.c
  54. 26
    0
      src/libgcc/libgcc.h
  55. 0
    2
      src/libgcc/memcpy.c
  56. 96
    34
      src/net/aoe.c
  57. 3
    2
      src/net/ndp.c
  58. 26
    19
      src/net/tcp/http.c
  59. 19
    28
      src/net/tcp/https.c
  60. 98
    18
      src/net/tcp/iscsi.c
  61. 1733
    0
      src/net/tls.c
  62. 129
    37
      src/net/udp/dhcp.c
  63. 0
    71
      src/tests/aoeboot.c
  64. 104
    0
      src/usr/aoeboot.c
  65. 8
    5
      src/usr/autoboot.c
  66. 24
    0
      src/usr/iscsiboot.c

+ 1
- 0
src/Makefile View File

@@ -145,6 +145,7 @@ DEBUG_TARGETS	+= dbg%.o c s
145 145
 
146 146
 # SRCDIRS lists all directories containing source files.
147 147
 #
148
+SRCDIRS		+= libgcc
148 149
 SRCDIRS		+= core
149 150
 SRCDIRS		+= proto
150 151
 SRCDIRS		+= net net/tcp net/udp

+ 12
- 0
src/arch/i386/Config View File

@@ -130,6 +130,18 @@ endif
130 130
 # this is almost always a win. the kernel uses it, too.
131 131
 CFLAGS+= -mpreferred-stack-boundary=2
132 132
 
133
+# use regparm for all functions - C functions called from assembly (or
134
+# vice versa) need __cdecl now
135
+CFLAGS+= -mregparm=3
136
+
137
+# use -mrtd (same __cdecl requirements as above)
138
+CFLAGS+= -mrtd
139
+
140
+# this is the logical complement to -mregparm=3. 
141
+# it doesn't currently buy us anything, but if anything ever tries
142
+# to return small structures, let's be prepared
143
+CFLAGS+= -freg-struct-return
144
+
133 145
 LDFLAGS+=	-N --no-check-sections
134 146
 
135 147
 ifeq "$(shell uname -s)" "FreeBSD"

+ 1
- 1
src/arch/i386/core/relocate.c View File

@@ -39,7 +39,7 @@ extern char _end[];
39 39
  * address space, and returns the physical address of the new location
40 40
  * to the prefix in %edi.
41 41
  */
42
-void relocate ( struct i386_all_regs *ix86 ) {
42
+__cdecl void relocate ( struct i386_all_regs *ix86 ) {
43 43
 	struct memory_map memmap;
44 44
 	unsigned long start, end, size, padded_size;
45 45
 	unsigned long new_start, new_end;

+ 0
- 336
src/arch/i386/core/udivmod64.c View File

@@ -1,336 +0,0 @@
1
-/*
2
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License as
6
- * published by the Free Software Foundation; either version 2 of the
7
- * License, or any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful, but
10
- * WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
- */
18
-
19
-/** @file
20
- *
21
- * 64-bit division
22
- *
23
- * The x86 CPU (386 upwards) has a divl instruction which will perform
24
- * unsigned division of a 64-bit dividend by a 32-bit divisor.  If the
25
- * resulting quotient does not fit in 32 bits, then a CPU exception
26
- * will occur.
27
- *
28
- * Unsigned integer division is expressed as solving 
29
- *
30
- *   x = d.q + r			0 <= q, 0 <= r < d
31
- *
32
- * given the dividend (x) and divisor (d), to find the quotient (q)
33
- * and remainder (r).
34
- *
35
- * The x86 divl instruction will solve
36
- *
37
- *   x = d.q + r			0 <= q, 0 <= r < d
38
- *
39
- * given x in the range 0 <= x < 2^64 and 1 <= d < 2^32, and causing a
40
- * hardware exception if the resulting q >= 2^32.
41
- *
42
- * We can therefore use divl only if we can prove that the conditions
43
- *
44
- *   0 <= x < 2^64
45
- *   1 <= d < 2^32
46
- *        q < 2^32
47
- *
48
- * are satisfied.
49
- *
50
- *
51
- * Case 1 : 1 <= d < 2^32
52
- * ======================
53
- *
54
- * We express x as
55
- *
56
- *   x = xh.2^32 + xl			0 <= xh < 2^32, 0 <= xl < 2^32	(1)
57
- *
58
- * i.e. split x into low and high dwords.  We then solve
59
- *
60
- *   xh = d.qh + r'			0 <= qh, 0 <= r' < d		(2)
61
- *
62
- * which we can do using a divl instruction since
63
- *
64
- *   0 <= xh < 2^64			since 0 <= xh < 2^32 from (1)	(3)
65
- *
66
- * and
67
- *
68
- *   1 <= d < 2^32			by definition of this Case	(4)
69
- *
70
- * and
71
- *
72
- *   d.qh = xh - r'			from (2)
73
- *   d.qh <= xh				since r' >= 0 from (2)
74
- *   qh <= xh				since d >= 1 from (2)
75
- *   qh < 2^32				since xh < 2^32 from (1)	(5)
76
- *
77
- * Having obtained qh and r', we then solve
78
- *
79
- *   ( r'.2^32 + xl ) = d.ql + r	0 <= ql, 0 <= r < d		(6)
80
- *
81
- * which we can do using another divl instruction since
82
- *
83
- *   xl <= 2^32 - 1			from (1), so
84
- *   r'.2^32 + xl <= ( r' + 1 ).2^32 - 1
85
- *   r'.2^32 + xl <= d.2^32 - 1		since r' < d from (2)
86
- *   r'.2^32 + xl < d.2^32						(7)
87
- *   r'.2^32 + xl < 2^64		since d < 2^32 from (4)		(8)
88
- *
89
- * and
90
- *
91
- *   1 <= d < 2^32			by definition of this Case	(9)
92
- *
93
- * and
94
- *
95
- *   d.ql = ( r'.2^32 + xl ) - r	from (6)
96
- *   d.ql <= r'.2^32 + xl		since r >= 0 from (6)
97
- *   d.ql < d.2^32			from (7)
98
- *   ql < 2^32				since d >= 1 from (2)		(10)
99
- *
100
- * This then gives us
101
- *
102
- *   x = xh.2^32 + xl			from (1)
103
- *   x = ( d.qh + r' ).2^32 + xl	from (2)
104
- *   x = d.qh.2^32 + ( r'.2^32 + xl )
105
- *   x = d.qh.2^32 + d.ql + r		from (3)
106
- *   x = d.( qh.2^32 + ql ) + r						(11)
107
- *
108
- * Letting
109
- *
110
- *   q = qh.2^32 + ql							(12)
111
- *
112
- * gives
113
- *
114
- *   x = d.q + r			from (11) and (12)
115
- *
116
- * which is the solution.
117
- *
118
- *
119
- * This therefore gives us a two-step algorithm:
120
- *
121
- *   xh = d.qh + r'			0 <= qh, 0 <= r' < d		(2)
122
- *   ( r'.2^32 + xl ) = d.ql + r	0 <= ql, 0 <= r < d		(6)
123
- *
124
- * which translates to
125
- *
126
- *   %edx:%eax = 0:xh
127
- *   divl d
128
- *   qh = %eax
129
- *   r' = %edx
130
- *
131
- *   %edx:%eax = r':xl
132
- *   divl d
133
- *   ql = %eax
134
- *   r = %edx
135
- *
136
- * Note that if
137
- *
138
- *   xh < d
139
- *
140
- * (which is a fast dword comparison) then the first divl instruction
141
- * can be omitted, since the answer will be
142
- *
143
- *   qh = 0
144
- *   r = xh
145
- *
146
- *
147
- * Case 2 : 2^32 <= d < 2^64
148
- * =========================
149
- *
150
- * We first express d as
151
- *
152
- *   d = dh.2^k + dl			2^31 <= dh < 2^32,
153
- *					0 <= dl < 2^k, 1 <= k <= 32	(1)
154
- *
155
- * i.e. find the highest bit set in d, subtract 32, and split d into
156
- * dh and dl at that point.
157
- *
158
- * We then express x as
159
- *
160
- *   x = xh.2^k + xl			0 <= xl < 2^k			(2)
161
- *
162
- * giving
163
- *
164
- *   xh.2^k = x - xl			from (2)
165
- *   xh.2^k <= x			since xl >= 0 from (1)
166
- *   xh.2^k < 2^64			since xh < 2^64 from (1)
167
- *   xh < 2^(64-k)							(3)
168
- *
169
- * We then solve the division
170
- *
171
- *   xh = dh.q' + r'	            		0 <= r' < dh		(4)
172
- *
173
- * which we can do using a divl instruction since
174
- *
175
- *   0 <= xh < 2^64			since x < 2^64 and xh < x
176
- *
177
- * and
178
- *
179
- *   1 <= dh < 2^32			from (1)
180
- *
181
- * and
182
- *
183
- *   dh.q' = xh - r'			from (4)
184
- *   dh.q' <= xh			since r' >= 0 from (4)
185
- *   dh.q' < 2^(64-k)			from (3)			(5)
186
- *   q'.2^31 <= dh.q'			since dh >= 2^31 from (1)	(6)
187
- *   q'.2^31 < 2^(64-k)			from (5) and (6)
188
- *   q' < 2^(33-k)
189
- *   q' < 2^32				since k >= 1 from (1)		(7)
190
- *
191
- * This gives us
192
- *
193
- *   xh.2^k = dh.q'.2^k + r'.2^k	from (4)
194
- *   x - xl = ( d - dl ).q' + r'.2^k	from (1) and (2)
195
- *   x = d.q' + ( r'.2^k + xl ) - dl.q'					(8)
196
- *
197
- * Now
198
- *
199
- *  r'.2^k + xl < r'.2^k + 2^k		since xl < 2^k from (2)
200
- *  r'.2^k + xl < ( r' + 1 ).2^k
201
- *  r'.2^k + xl < dh.2^k		since r' < dh from (4)
202
- *  r'.2^k + xl < ( d - dl )		from (1)			(9)
203
- *
204
- *
205
- * (missing)
206
- *
207
- *
208
- * This gives us two cases to consider:
209
- *
210
- * case (a):
211
- *
212
- *   dl.q' <= ( r'.2^k + xl )						(15a)
213
- *
214
- * in which case
215
- *
216
- *   x = d.q' + ( r'.2^k + xl - dl.q' )
217
- *
218
- * is a direct solution to the division, since
219
- *
220
- *   r'.2^k + xl < d			from (9)
221
- *   ( r'.2^k + xl - dl.q' ) < d	since dl >= 0 and q' >= 0
222
- *
223
- * and
224
- *
225
- *   0 <= ( r'.2^k + xl - dl.q' )	from (15a)
226
- *
227
- * case (b):
228
- *
229
- *   dl.q' > ( r'.2^k + xl )						(15b)
230
- *   
231
- * Express
232
- *
233
- *  x = d.(q'-1) + ( r'.2^k + xl ) + ( d - dl.q' )
234
- *  
235
- *   
236
- * (missing)
237
- *
238
- *
239
- * special case: k = 32 cannot be handled with shifts
240
- *
241
- * (missing)
242
- * 
243
- */
244
-
245
-#include <stdint.h>
246
-#include <assert.h>
247
-
248
-typedef uint64_t UDItype;
249
-
250
-struct uint64 {
251
-	uint32_t l;
252
-	uint32_t h;
253
-};
254
-
255
-static inline void udivmod64_lo ( const struct uint64 *x,
256
-				  const struct uint64 *d,
257
-				  struct uint64 *q,
258
-				  struct uint64 *r ) {
259
-	uint32_t r_dash;
260
-
261
-	q->h = 0;
262
-	r->h = 0;
263
-	r_dash = x->h;
264
-
265
-	if ( x->h >= d->l ) {
266
-		__asm__ ( "divl %2"
267
-			  : "=&a" ( q->h ), "=&d" ( r_dash )
268
-			  : "g" ( d->l ), "0" ( x->h ), "1" ( 0 ) );
269
-	}
270
-
271
-	__asm__ ( "divl %2"
272
-		  : "=&a" ( q->l ), "=&d" ( r->l )
273
-		  : "g" ( d->l ), "0" ( x->l ), "1" ( r_dash ) );
274
-}
275
-
276
-static void udivmod64 ( const struct uint64 *x,
277
-			const struct uint64 *d,
278
-			struct uint64 *q,
279
-			struct uint64 *r ) {
280
-
281
-	if ( d->h == 0 ) {
282
-		udivmod64_lo ( x, d, q, r );
283
-	} else {
284
-		assert ( 0 );
285
-		while ( 1 ) {};
286
-	}	
287
-}
288
-
289
-/**
290
- * 64-bit division with remainder
291
- *
292
- * @v x			Dividend
293
- * @v d			Divisor
294
- * @ret r		Remainder
295
- * @ret q		Quotient
296
- */
297
-UDItype __udivmoddi4 ( UDItype x, UDItype d, UDItype *r ) {
298
-	UDItype q;
299
-	UDItype *_x = &x;
300
-	UDItype *_d = &d;
301
-	UDItype *_q = &q;
302
-	UDItype *_r = r;
303
-
304
-	udivmod64 ( ( struct uint64 * ) _x, ( struct uint64 * ) _d,
305
-		    ( struct uint64 * ) _q, ( struct uint64 * ) _r );
306
-
307
-	assert ( ( x == ( ( d * q ) + (*r) ) ) );
308
-	assert ( (*r) < d );
309
-
310
-	return q;
311
-}
312
-
313
-/**
314
- * 64-bit division
315
- *
316
- * @v x			Dividend
317
- * @v d			Divisor
318
- * @ret q		Quotient
319
- */
320
-UDItype __udivdi3 ( UDItype x, UDItype d ) {
321
-	UDItype r;
322
-	return __udivmoddi4 ( x, d, &r );
323
-}
324
-
325
-/**
326
- * 64-bit modulus
327
- *
328
- * @v x			Dividend
329
- * @v d			Divisor
330
- * @ret q		Quotient
331
- */
332
-UDItype __umoddi3 ( UDItype x, UDItype d ) {
333
-	UDItype r;
334
-	__udivmoddi4 ( x, d, &r );
335
-	return r;
336
-}

+ 7
- 1
src/arch/i386/drivers/net/undinet.c View File

@@ -423,8 +423,14 @@ static void undinet_poll ( struct net_device *netdev ) {
423 423
 
424 424
 	if ( ! undinic->isr_processing ) {
425 425
 		/* Do nothing unless ISR has been triggered */
426
-		if ( ! undinet_isr_triggered() )
426
+		if ( ! undinet_isr_triggered() ) {
427
+			/* Allow interrupt to occur */
428
+			__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
429
+							   "nop\n\t"
430
+							   "nop\n\t"
431
+							   "cli\n\t" ) : : );
427 432
 			return;
433
+		}
428 434
 
429 435
 		/* Start ISR processing */
430 436
 		undinic->isr_processing = 1;

+ 62
- 50
src/arch/i386/image/bzimage.c View File

@@ -33,7 +33,6 @@
33 33
 #include <gpxe/uaccess.h>
34 34
 #include <gpxe/image.h>
35 35
 #include <gpxe/segment.h>
36
-#include <gpxe/memmap.h>
37 36
 #include <gpxe/init.h>
38 37
 #include <gpxe/initrd.h>
39 38
 
@@ -168,58 +167,78 @@ static int bzimage_set_cmdline ( struct image *image,
168 167
 }
169 168
 
170 169
 /**
171
- * Load initrd, if any
170
+ * Load initrds, if any
172 171
  *
173 172
  * @v image		bzImage image
174 173
  * @v exec_ctx		Execution context
175 174
  * @ret rc		Return status code
176 175
  */
177 176
 static int bzimage_load_initrd ( struct image *image,
178
-				 struct bzimage_exec_context *exec_ctx,
179
-				 struct image *initrd ) {
180
-	physaddr_t start = user_to_phys ( initrd->data, 0 );
177
+				 struct bzimage_exec_context *exec_ctx ) {
178
+	struct image *initrd;
179
+	size_t initrd_len;
180
+	size_t total_len = 0;
181
+	size_t offset = 0;
182
+	physaddr_t start;
181 183
 	int rc;
182 184
 
183
-	DBGC ( image, "bzImage %p loading initrd %p (%s)\n",
184
-	       image, initrd, initrd->name );
185
-	
186
-	/* Find a suitable start address */
187
-	if ( ( start + initrd->len ) <= exec_ctx->mem_limit ) {
188
-		/* Just use initrd in situ */
189
-		DBGC ( image, "bzImage %p using initrd as [%lx,%lx)\n",
190
-		       image, start, ( start + initrd->len ) );
191
-	} else {
192
-		for ( ; ; start -= 0x100000 ) {
193
-			/* Check that we're not going to overwrite the
194
-			 * kernel itself.  This check isn't totally
195
-			 * accurate, but errs on the side of caution.
196
-			 */
197
-			if ( start <= ( BZI_LOAD_HIGH_ADDR + image->len ) ) {
198
-				DBGC ( image, "bzImage %p could not find a "
199
-				       "location for initrd\n", image );
200
-				return -ENOBUFS;
201
-			}
202
-			/* Check that we are within the kernel's range */
203
-			if ( ( start + initrd->len ) > exec_ctx->mem_limit )
204
-				continue;
205
-			/* Prepare and verify segment */
206
-			if ( ( rc = prep_segment ( phys_to_user ( start ),
207
-						   initrd->len,
208
-						   initrd->len ) ) != 0 )
209
-				continue;
210
-			/* Copy to segment */
211
-			DBGC ( image, "bzImage %p relocating initrd to "
212
-			       "[%lx,%lx)\n", image, start,
213
-			       ( start + initrd->len ) );
214
-			memcpy_user ( phys_to_user ( start ), 0,
215
-				      initrd->data, 0, initrd->len );
216
-			break;
185
+	/* Add up length of all initrd images */
186
+	for_each_image ( initrd ) {
187
+		if ( initrd->type != &initrd_image_type )
188
+			continue;
189
+		initrd_len = ( ( initrd->len + 0x0f ) & ~0x0f );
190
+		total_len += initrd_len;
191
+	}
192
+
193
+	/* Give up if no initrd images found */
194
+	if ( ! total_len )
195
+		return 0;
196
+
197
+	/* Find a suitable start address.  Try 1MB boundaries,
198
+	 * starting from the downloaded kernel image itself and
199
+	 * working downwards until we hit an available region.
200
+	 */
201
+	for ( start = ( user_to_phys ( image->data, 0 ) & ~0xfffff ) ; ;
202
+	      start -= 0x100000 ) {
203
+		/* Check that we're not going to overwrite the
204
+		 * kernel itself.  This check isn't totally
205
+		 * accurate, but errs on the side of caution.
206
+		 */
207
+		if ( start <= ( BZI_LOAD_HIGH_ADDR + image->len ) ) {
208
+			DBGC ( image, "bzImage %p could not find a location "
209
+			       "for initrd\n", image );
210
+			return -ENOBUFS;
217 211
 		}
212
+		/* Check that we are within the kernel's range */
213
+		if ( ( start + total_len ) > exec_ctx->mem_limit )
214
+			continue;
215
+		/* Prepare and verify segment */
216
+		if ( ( rc = prep_segment ( phys_to_user ( start ), 0,
217
+					   total_len ) ) != 0 )
218
+			continue;
219
+		/* Use this address */
220
+		break;
218 221
 	}
219 222
 
223
+	/* Construct initrd */
224
+	DBGC ( image, "bzImage %p constructing initrd at [%lx,%lx)\n",
225
+	       image, start, ( start + total_len ) );
226
+	for_each_image ( initrd ) {
227
+		if ( initrd->type != &initrd_image_type )
228
+			continue;
229
+		initrd_len = ( ( initrd->len + 0x0f ) & ~0x0f );
230
+		DBGC ( image, "bzImage %p has initrd %p at [%lx,%lx)\n",
231
+		       image, initrd, ( start + offset ),
232
+		       ( start + offset + initrd->len ) );
233
+		memcpy_user ( phys_to_user ( start ), offset,
234
+			      initrd->data, 0, initrd->len );
235
+		offset += initrd_len;
236
+	}
237
+	assert ( offset == total_len );
238
+
220 239
 	/* Record initrd location */
221 240
 	exec_ctx->ramdisk_image = start;
222
-	exec_ctx->ramdisk_size = initrd->len;
241
+	exec_ctx->ramdisk_size = total_len;
223 242
 
224 243
 	return 0;
225 244
 }
@@ -234,7 +253,6 @@ static int bzimage_exec ( struct image *image ) {
234 253
 	struct bzimage_exec_context exec_ctx;
235 254
 	struct bzimage_header bzhdr;
236 255
 	const char *cmdline = ( image->cmdline ? image->cmdline : "" );
237
-	struct image *initrd;
238 256
 	int rc;
239 257
 
240 258
 	/* Initialise context */
@@ -262,15 +280,9 @@ static int bzimage_exec ( struct image *image ) {
262 280
 	if ( ( rc = bzimage_set_cmdline ( image, &exec_ctx, cmdline ) ) != 0 )
263 281
 		return rc;
264 282
 
265
-	/* Load an initrd, if one exists */
266
-	for_each_image ( initrd ) {
267
-		if ( initrd->type == &initrd_image_type ) {
268
-			if ( ( rc = bzimage_load_initrd ( image, &exec_ctx,
269
-							  initrd ) ) != 0 )
270
-				return rc;
271
-			break;
272
-		}
273
-	}
283
+	/* Load any initrds */
284
+	if ( ( rc = bzimage_load_initrd ( image, &exec_ctx ) ) != 0 )
285
+		return rc;
274 286
 
275 287
 	/* Update and store kernel header */
276 288
 	bzhdr.vid_mode = exec_ctx.vid_mode;

+ 1
- 1
src/arch/i386/image/eltorito.c View File

@@ -298,7 +298,7 @@ static int eltorito_load_disk ( struct image *image,
298 298
  * @v image		El Torito file
299 299
  * @ret rc		Return status code
300 300
  */
301
-int eltorito_load ( struct image *image ) {
301
+static int eltorito_load ( struct image *image ) {
302 302
 	struct eltorito_boot_entry boot_entry;
303 303
 	unsigned long bootcat_offset;
304 304
 	int rc;

+ 1
- 1
src/arch/i386/image/multiboot.c View File

@@ -360,7 +360,7 @@ static int multiboot_load_elf ( struct image *image ) {
360 360
  * @v image		Multiboot file
361 361
  * @ret rc		Return status code
362 362
  */
363
-int multiboot_load ( struct image *image ) {
363
+static int multiboot_load ( struct image *image ) {
364 364
 	struct multiboot_header_info hdr;
365 365
 	int rc;
366 366
 

+ 5
- 8
src/arch/i386/image/nbi.c View File

@@ -244,7 +244,7 @@ static int nbi_process_segments ( struct image *image,
244 244
  * @v image		NBI image
245 245
  * @ret rc		Return status code
246 246
  */
247
-int nbi_load ( struct image *image ) {
247
+static int nbi_load ( struct image *image ) {
248 248
 	struct imgheader imgheader;
249 249
 	int rc;
250 250
 
@@ -397,16 +397,13 @@ static int nbi_prepare_dhcp ( struct image *image ) {
397 397
 		return -ENODEV;
398 398
 	}
399 399
 
400
-	if ( ( rc = create_dhcp_packet ( boot_netdev, DHCPACK, basemem_packet,
401
-					 sizeof ( basemem_packet ),
402
-					 &dhcppkt ) ) != 0 ) {
400
+	if ( ( rc = create_dhcp_response ( boot_netdev, DHCPACK, NULL,
401
+					   basemem_packet,
402
+					   sizeof ( basemem_packet ),
403
+					   &dhcppkt ) ) != 0 ) {
403 404
 		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
404 405
 		return rc;
405 406
 	}
406
-	if ( ( rc = copy_dhcp_packet_options ( &dhcppkt, NULL ) ) != 0 ) {
407
-		DBGC ( image, "NBI %p failed to copy DHCP options\n", image );
408
-		return rc;
409
-	}
410 407
 
411 408
 	return 0;
412 409
 }

+ 1
- 1
src/arch/i386/interface/pcbios/int13.c View File

@@ -321,7 +321,7 @@ static int int13_get_extended_parameters ( struct int13_drive *drive,
321 321
  * INT 13 handler
322 322
  *
323 323
  */
324
-static void int13 ( struct i386_all_regs *ix86 ) {
324
+static __cdecl void int13 ( struct i386_all_regs *ix86 ) {
325 325
 	int command = ix86->regs.ah;
326 326
 	unsigned int bios_drive = ix86->regs.dl;
327 327
 	unsigned int original_bios_drive = bios_drive;

+ 2
- 2
src/arch/i386/interface/pxe/pxe_call.c View File

@@ -112,7 +112,7 @@ static PXENV_EXIT_t pxenv_unknown ( struct s_PXENV_UNKNOWN *pxenv_unknown ) {
112 112
  * @v es:di		Address of PXE parameter block
113 113
  * @ret ax		PXE exit code
114 114
  */
115
-void pxe_api_call ( struct i386_all_regs *ix86 ) {
115
+__cdecl void pxe_api_call ( struct i386_all_regs *ix86 ) {
116 116
 	int opcode = ix86->regs.bx;
117 117
 	userptr_t parameters = real_to_user ( ix86->segs.es, ix86->regs.di );
118 118
 	size_t param_len;
@@ -304,7 +304,7 @@ void pxe_api_call ( struct i386_all_regs *ix86 ) {
304 304
  * @v es:di		Address of PXE parameter block
305 305
  * @ret ax		PXE exit code
306 306
  */
307
-void pxe_loader_call ( struct i386_all_regs *ix86 ) {
307
+__cdecl void pxe_loader_call ( struct i386_all_regs *ix86 ) {
308 308
 	userptr_t uparams = real_to_user ( ix86->segs.es, ix86->regs.di );
309 309
 	struct s_UNDI_LOADER params;
310 310
 	PXENV_EXIT_t ret;

+ 1
- 0
src/config.h View File

@@ -73,6 +73,7 @@
73 73
 #define	DOWNLOAD_PROTO_TFTP	/* Trivial File Transfer Protocol */
74 74
 #undef	DOWNLOAD_PROTO_NFS	/* Network File System */
75 75
 #define	DOWNLOAD_PROTO_HTTP	/* Hypertext Transfer Protocol */
76
+#undef	DOWNLOAD_PROTO_HTTPS	/* Secure Hypertext Transfer Protocol */
76 77
 #undef	DOWNLOAD_PROTO_FTP	/* File Transfer Protocol */
77 78
 #undef	DOWNLOAD_PROTO_TFTM	/* Multicast Trivial File Transfer Protocol */
78 79
 #undef	DOWNLOAD_PROTO_SLAM	/* Scalable Local Area Multicast */

+ 60
- 0
src/core/abft.c View File

@@ -0,0 +1,60 @@
1
+/*
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <realmode.h>
20
+#include <gpxe/aoe.h>
21
+#include <gpxe/netdevice.h>
22
+#include <gpxe/abft.h>
23
+
24
+/** @file
25
+ *
26
+ * AoE Boot Firmware Table
27
+ *
28
+ */
29
+
30
+#define abftab __use_data16 ( abftab )
31
+/** The aBFT used by gPXE */
32
+struct abft_table __data16 ( abftab ) __attribute__ (( aligned ( 16 ) )) = {
33
+	/* ACPI header */
34
+	.acpi = {
35
+		.signature = ABFT_SIG,
36
+		.length = sizeof ( abftab ),
37
+		.revision = 1,
38
+		.oem_id = "FENSYS",
39
+		.oem_table_id = "gPXE",
40
+	},
41
+};
42
+
43
+/**
44
+ * Fill in all variable portions of aBFT
45
+ *
46
+ * @v aoe		AoE session
47
+ */
48
+void abft_fill_data ( struct aoe_session *aoe ) {
49
+
50
+	/* Fill in boot parameters */
51
+	abftab.shelf = aoe->major;
52
+	abftab.slot = aoe->minor;
53
+	memcpy ( abftab.mac, aoe->netdev->ll_addr, sizeof ( abftab.mac ) );
54
+
55
+	/* Update checksum */
56
+	acpi_fix_checksum ( &abftab.acpi );
57
+
58
+	DBG ( "AoE boot firmware table:\n" );
59
+	DBG_HD ( &abftab, sizeof ( abftab ) );
60
+}

+ 3
- 0
src/core/config.c View File

@@ -87,6 +87,9 @@ REQUIRE_OBJECT ( nfs );
87 87
 #ifdef DOWNLOAD_PROTO_HTTP
88 88
 REQUIRE_OBJECT ( http );
89 89
 #endif
90
+#ifdef DOWNLOAD_PROTO_HTTPS
91
+REQUIRE_OBJECT ( https );
92
+#endif
90 93
 #ifdef DOWNLOAD_PROTO_FTP
91 94
 REQUIRE_OBJECT ( ftp );
92 95
 #endif

+ 78
- 0
src/core/filter.c View File

@@ -0,0 +1,78 @@
1
+/*
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <gpxe/xfer.h>
20
+#include <gpxe/filter.h>
21
+
22
+/** @file
23
+ *
24
+ * Data transfer filters
25
+ *
26
+ */
27
+
28
+/*
29
+ * Pass-through methods to be used by filters which don't want to
30
+ * intercept all events.
31
+ *
32
+ */
33
+
34
+void filter_close ( struct xfer_interface *xfer, int rc ) {
35
+	struct xfer_interface *other = filter_other_half ( xfer );
36
+
37
+	xfer_close ( other, rc );
38
+}
39
+
40
+int filter_vredirect ( struct xfer_interface *xfer, int type,
41
+			va_list args ) {
42
+	struct xfer_interface *other = filter_other_half ( xfer );
43
+
44
+	return xfer_vredirect ( other, type, args );
45
+}
46
+
47
+int filter_seek ( struct xfer_interface *xfer, off_t offset, int whence ) {
48
+	struct xfer_interface *other = filter_other_half ( xfer );
49
+
50
+	return xfer_seek ( other, offset, whence );
51
+}
52
+
53
+size_t filter_window ( struct xfer_interface *xfer ) {
54
+	struct xfer_interface *other = filter_other_half ( xfer );
55
+
56
+	return xfer_window ( other );
57
+}
58
+
59
+struct io_buffer * filter_alloc_iob ( struct xfer_interface *xfer,
60
+				      size_t len ) {
61
+	struct xfer_interface *other = filter_other_half ( xfer );
62
+
63
+	return xfer_alloc_iob ( other, len );
64
+}
65
+
66
+int filter_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf,
67
+			 struct xfer_metadata *meta ) {
68
+	struct xfer_interface *other = filter_other_half ( xfer );
69
+
70
+	return xfer_deliver_iob_meta ( other, iobuf, meta );
71
+}
72
+
73
+int filter_deliver_raw ( struct xfer_interface *xfer, const void *data,
74
+			 size_t len ) {
75
+	struct xfer_interface *other = filter_other_half ( xfer );
76
+
77
+	return xfer_deliver_raw ( other, data, len );
78
+}

+ 1
- 1
src/core/main.c View File

@@ -24,7 +24,7 @@ Literature dealing with the network protocols:
24 24
  *
25 25
  * @ret rc		Return status code
26 26
  */
27
-int main ( void ) {
27
+__cdecl int main ( void ) {
28 28
 
29 29
 	initialise();
30 30
 	startup();

+ 867
- 0
src/crypto/axtls/axtls_asn1.c View File

@@ -0,0 +1,867 @@
1
+/*
2
+ *  Copyright(C) 2006 Cameron Rich
3
+ *
4
+ *  This library is free software; you can redistribute it and/or modify
5
+ *  it under the terms of the GNU Lesser General Public License as published by
6
+ *  the Free Software Foundation; either version 2.1 of the License, or
7
+ *  (at your option) any later version.
8
+ *
9
+ *  This library 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 Lesser General Public License for more details.
13
+ *
14
+ *  You should have received a copy of the GNU Lesser General Public License
15
+ *  along with this library; if not, write to the Free Software
16
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
+ */
18
+
19
+/**
20
+ * @file asn1.c
21
+ * 
22
+ * Some primitive asn methods for extraction rsa modulus information. It also
23
+ * is used for retrieving information from X.509 certificates.
24
+ */
25
+
26
+#include <stdio.h>
27
+#include <stdlib.h>
28
+#include <string.h>
29
+#include <time.h>
30
+#include "crypto.h"
31
+
32
+#define SIG_OID_PREFIX_SIZE     8
33
+
34
+#define SIG_TYPE_MD2            0x02
35
+#define SIG_TYPE_MD5            0x04
36
+#define SIG_TYPE_SHA1           0x05
37
+
38
+/* Must be an RSA algorithm with either SHA1 or MD5 for verifying to work */
39
+static const uint8_t sig_oid_prefix[SIG_OID_PREFIX_SIZE] = 
40
+{
41
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01
42
+};
43
+
44
+/* CN, O, OU */
45
+static const uint8_t g_dn_types[] = { 3, 10, 11 };
46
+
47
+static int get_asn1_length(const uint8_t *buf, int *offset)
48
+{
49
+    int len, i;
50
+
51
+    if (!(buf[*offset] & 0x80)) /* short form */
52
+    {
53
+        len = buf[(*offset)++];
54
+    }
55
+    else    /* long form */
56
+    {
57
+        int length_bytes = buf[(*offset)++]&0x7f;
58
+        len = 0;
59
+        for (i = 0; i < length_bytes; i++)
60
+        {
61
+            len <<= 8;
62
+            len += buf[(*offset)++];
63
+        }
64
+    }
65
+
66
+    return len;
67
+}
68
+
69
+/**
70
+ * Skip the ASN1.1 object type and its length. Get ready to read the object's
71
+ * data.
72
+ */
73
+int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type)
74
+{
75
+    if (buf[*offset] != obj_type)
76
+        return X509_NOT_OK;
77
+    (*offset)++;
78
+    return get_asn1_length(buf, offset);
79
+}
80
+
81
+/**
82
+ * Skip over an ASN.1 object type completely. Get ready to read the next
83
+ * object.
84
+ */
85
+int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type)
86
+{
87
+    int len;
88
+
89
+    if (buf[*offset] != obj_type)
90
+        return X509_NOT_OK;
91
+    (*offset)++;
92
+    len = get_asn1_length(buf, offset);
93
+    *offset += len;
94
+    return 0;
95
+}
96
+
97
+/**
98
+ * Read an integer value for ASN.1 data
99
+ * Note: This function allocates memory which must be freed by the user.
100
+ */
101
+int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object)
102
+{
103
+    int len;
104
+
105
+    if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0)
106
+        goto end_int_array;
107
+
108
+    *object = (uint8_t *)malloc(len);
109
+    memcpy(*object, &buf[*offset], len);
110
+    *offset += len;
111
+
112
+end_int_array:
113
+    return len;
114
+}
115
+
116
+#if 0
117
+
118
+/**
119
+ * Get all the RSA private key specifics from an ASN.1 encoded file 
120
+ */
121
+int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx)
122
+{
123
+    int offset = 7;
124
+    uint8_t *modulus, *priv_exp, *pub_exp;
125
+    int mod_len, priv_len, pub_len;
126
+#ifdef CONFIG_BIGINT_CRT
127
+    uint8_t *p, *q, *dP, *dQ, *qInv;
128
+    int p_len, q_len, dP_len, dQ_len, qInv_len;
129
+#endif
130
+
131
+    /* not in der format */
132
+    if (buf[0] != ASN1_SEQUENCE) /* basic sanity check */
133
+    {
134
+#ifdef CONFIG_SSL_FULL_MODE
135
+        printf("Error: This is not a valid ASN.1 file\n");
136
+#endif
137
+        return X509_INVALID_PRIV_KEY;
138
+    }
139
+
140
+    /* initialise the RNG */
141
+    RNG_initialize(buf, len);
142
+
143
+    mod_len = asn1_get_int(buf, &offset, &modulus);
144
+    pub_len = asn1_get_int(buf, &offset, &pub_exp);
145
+    priv_len = asn1_get_int(buf, &offset, &priv_exp);
146
+
147
+    if (mod_len <= 0 || pub_len <= 0 || priv_len <= 0)
148
+        return X509_INVALID_PRIV_KEY;
149
+
150
+#ifdef CONFIG_BIGINT_CRT
151
+    p_len = asn1_get_int(buf, &offset, &p);
152
+    q_len = asn1_get_int(buf, &offset, &q);
153
+    dP_len = asn1_get_int(buf, &offset, &dP);
154
+    dQ_len = asn1_get_int(buf, &offset, &dQ);
155
+    qInv_len = asn1_get_int(buf, &offset, &qInv);
156
+
157
+    if (p_len <= 0 || q_len <= 0 || dP_len <= 0 || dQ_len <= 0 || qInv_len <= 0)
158
+        return X509_INVALID_PRIV_KEY;
159
+
160
+    RSA_priv_key_new(rsa_ctx, 
161
+            modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len,
162
+            p, p_len, q, p_len, dP, dP_len, dQ, dQ_len, qInv, qInv_len);
163
+
164
+    free(p);
165
+    free(q);
166
+    free(dP);
167
+    free(dQ);
168
+    free(qInv);
169
+#else
170
+    RSA_priv_key_new(rsa_ctx, 
171
+            modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len);
172
+#endif
173
+
174
+    free(modulus);
175
+    free(priv_exp);
176
+    free(pub_exp);
177
+    return X509_OK;
178
+}
179
+
180
+/**
181
+ * Get the time of a certificate. Ignore hours/minutes/seconds.
182
+ */
183
+static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t)
184
+{
185
+    int ret = X509_NOT_OK, len, t_offset;
186
+    struct tm tm;
187
+
188
+    if (buf[(*offset)++] != ASN1_UTC_TIME)
189
+        goto end_utc_time;
190
+    len = get_asn1_length(buf, offset);
191
+    t_offset = *offset;
192
+
193
+    memset(&tm, 0, sizeof(struct tm));
194
+    tm.tm_year = (buf[t_offset] - '0')*10 + (buf[t_offset+1] - '0');
195
+
196
+    if (tm.tm_year <= 50)    /* 1951-2050 thing */
197
+    {
198
+        tm.tm_year += 100;
199
+    }
200
+
201
+    tm.tm_mon = (buf[t_offset+2] - '0')*10 + (buf[t_offset+3] - '0') - 1;
202
+    tm.tm_mday = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0');
203
+    *t = mktime(&tm);
204
+    *offset += len;
205
+    ret = X509_OK;
206
+
207
+end_utc_time:
208
+    return ret;
209
+}
210
+
211
+/**
212
+ * Get the version type of a certificate (which we don't actually care about)
213
+ */
214
+static int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
215
+{
216
+    int ret = X509_NOT_OK;
217
+
218
+    (*offset) += 2;        /* get past explicit tag */
219
+    if (asn1_skip_obj(cert, offset, ASN1_INTEGER))
220
+        goto end_version;
221
+
222
+    ret = X509_OK;
223
+end_version:
224
+    return ret;
225
+}
226
+
227
+/**
228
+ * Retrieve the notbefore and notafter certificate times.
229
+ */
230
+static int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
231
+{
232
+    return (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
233
+              asn1_get_utc_time(cert, offset, &x509_ctx->not_before) ||
234
+              asn1_get_utc_time(cert, offset, &x509_ctx->not_after));
235
+}
236
+
237
+/**
238
+ * Get the components of a distinguished name 
239
+ */
240
+static int asn1_get_oid_x520(const uint8_t *buf, int *offset)
241
+{
242
+    int dn_type = 0;
243
+    int len;
244
+
245
+    if ((len = asn1_next_obj(buf, offset, ASN1_OID)) < 0)
246
+        goto end_oid;
247
+
248
+    /* expect a sequence of 2.5.4.[x] where x is a one of distinguished name 
249
+       components we are interested in. */
250
+    if (len == 3 && buf[(*offset)++] == 0x55 && buf[(*offset)++] == 0x04)
251
+        dn_type = buf[(*offset)++];
252
+    else
253
+    {
254
+        *offset += len;     /* skip over it */
255
+    }
256
+
257
+end_oid:
258
+    return dn_type;
259
+}
260
+
261
+/**
262
+ * Obtain an ASN.1 printable string type.
263
+ */
264
+static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str)
265
+{
266
+    int len = X509_NOT_OK;
267
+
268
+    /* some certs have this awful crud in them for some reason */
269
+    if (buf[*offset] != ASN1_PRINTABLE_STR && 
270
+            buf[*offset] != ASN1_TELETEX_STR && buf[*offset] != ASN1_IA5_STR)
271
+        goto end_pnt_str;
272
+
273
+    (*offset)++;
274
+    len = get_asn1_length(buf, offset);
275
+    *str = (char *)malloc(len+1);       /* allow for null */
276
+    memcpy(*str, &buf[*offset], len);
277
+    (*str)[len] = 0;                    /* null terminate */
278
+    *offset += len;
279
+end_pnt_str:
280
+    return len;
281
+}
282
+
283
+/**
284
+ * Get the subject name (or the issuer) of a certificate.
285
+ */
286
+static int asn1_name(const uint8_t *cert, int *offset, char *dn[])
287
+{
288
+    int ret = X509_NOT_OK;
289
+    int dn_type;
290
+    char *tmp = NULL;
291
+
292
+    if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
293
+        goto end_name;
294
+
295
+    while (asn1_next_obj(cert, offset, ASN1_SET) >= 0)
296
+    {
297
+        int i, found = 0;
298
+
299
+        if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
300
+               (dn_type = asn1_get_oid_x520(cert, offset)) < 0)
301
+            goto end_name;
302
+
303
+        if (asn1_get_printable_str(cert, offset, &tmp) < 0)
304
+        {
305
+            free(tmp);
306
+            goto end_name;
307
+        }
308
+
309
+        /* find the distinguished named type */
310
+        for (i = 0; i < X509_NUM_DN_TYPES; i++)
311
+        {
312
+            if (dn_type == g_dn_types[i])
313
+            {
314
+                if (dn[i] == NULL)
315
+                {
316
+                    dn[i] = tmp;
317
+                    found = 1;
318
+                    break;
319
+                }
320
+            }
321
+        }
322
+
323
+        if (found == 0) /* not found so get rid of it */
324
+        {
325
+            free(tmp);
326
+        }
327
+    }
328
+
329
+    ret = X509_OK;
330
+end_name:
331
+    return ret;
332
+}
333
+
334
+/**
335
+ * Read the modulus and public exponent of a certificate.
336
+ */
337
+static int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
338
+{
339
+    int ret = X509_NOT_OK, mod_len, pub_len;
340
+    uint8_t *modulus, *pub_exp;
341
+
342
+    if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
343
+            asn1_skip_obj(cert, offset, ASN1_SEQUENCE) ||
344
+            asn1_next_obj(cert, offset, ASN1_BIT_STRING) < 0)
345
+        goto end_pub_key;
346
+
347
+    (*offset)++;
348
+
349
+    if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
350
+        goto end_pub_key;
351
+
352
+    mod_len = asn1_get_int(cert, offset, &modulus);
353
+    pub_len = asn1_get_int(cert, offset, &pub_exp);
354
+
355
+    RSA_pub_key_new(&x509_ctx->rsa_ctx, modulus, mod_len, pub_exp, pub_len);
356
+
357
+    free(modulus);
358
+    free(pub_exp);
359
+    ret = X509_OK;
360
+
361
+end_pub_key:
362
+    return ret;
363
+}
364
+
365
+#ifdef CONFIG_SSL_CERT_VERIFICATION
366
+/**
367
+ * Read the signature of the certificate.
368
+ */
369
+static int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
370
+{
371
+    int ret = X509_NOT_OK;
372
+
373
+    if (cert[(*offset)++] != ASN1_BIT_STRING)
374
+        goto end_sig;
375
+
376
+    x509_ctx->sig_len = get_asn1_length(cert, offset);
377
+    x509_ctx->signature = (uint8_t *)malloc(x509_ctx->sig_len);
378
+    memcpy(x509_ctx->signature, &cert[*offset], x509_ctx->sig_len);
379
+    *offset += x509_ctx->sig_len;
380
+    ret = X509_OK;
381
+
382
+end_sig:
383
+    return ret;
384
+}
385
+
386
+/*
387
+ * Compare 2 distinguished name components for equality 
388
+ * @return 0 if a match
389
+ */
390
+static int asn1_compare_dn_comp(const char *dn1, const char *dn2)
391
+{
392
+    int ret = 1;
393
+
394
+    if ((dn1 && dn2 == NULL) || (dn1 == NULL && dn2)) goto err_no_match;
395
+
396
+    ret = (dn1 && dn2) ? strcmp(dn1, dn2) : 0;
397
+
398
+err_no_match:
399
+    return ret;
400
+}
401
+
402
+/**
403
+ * Clean up all of the CA certificates.
404
+ */
405
+void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx)
406
+{
407
+    int i = 0;
408
+
409
+    while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
410
+    {
411
+        x509_free(ca_cert_ctx->cert[i]);
412
+        ca_cert_ctx->cert[i++] = NULL;
413
+    }
414
+
415
+    free(ca_cert_ctx);
416
+}
417
+
418
+/*
419
+ * Compare 2 distinguished names for equality 
420
+ * @return 0 if a match
421
+ */
422
+static int asn1_compare_dn(char * const dn1[], char * const dn2[])
423
+{
424
+    int i;
425
+
426
+    for (i = 0; i < X509_NUM_DN_TYPES; i++)
427
+    {
428
+        if (asn1_compare_dn_comp(dn1[i], dn2[i]))
429
+        {
430
+            return 1;
431
+        }
432
+    }
433
+
434
+    return 0;       /* all good */
435
+}
436
+
437
+/**
438
+ * Retrieve the signature from a certificate.
439
+ */
440
+const uint8_t *x509_get_signature(const uint8_t *asn1_sig, int *len)
441
+{
442
+    int offset = 0;
443
+    const uint8_t *ptr = NULL;
444
+
445
+    if (asn1_next_obj(asn1_sig, &offset, ASN1_SEQUENCE) < 0 || 
446
+            asn1_skip_obj(asn1_sig, &offset, ASN1_SEQUENCE))
447
+        goto end_get_sig;
448
+
449
+    if (asn1_sig[offset++] != ASN1_OCTET_STRING)
450
+        goto end_get_sig;
451
+    *len = get_asn1_length(asn1_sig, &offset);
452
+    ptr = &asn1_sig[offset];          /* all ok */
453
+
454
+end_get_sig:
455
+    return ptr;
456
+}
457
+
458
+#endif
459
+
460
+/**
461
+ * Read the signature type of the certificate. We only support RSA-MD5 and
462
+ * RSA-SHA1 signature types.
463
+ */
464
+static int asn1_signature_type(const uint8_t *cert, 
465
+                                int *offset, X509_CTX *x509_ctx)
466
+{
467
+    int ret = X509_NOT_OK, len;
468
+
469
+    if (cert[(*offset)++] != ASN1_OID)
470
+        goto end_check_sig;
471
+
472
+    len = get_asn1_length(cert, offset);
473
+
474
+    if (memcmp(sig_oid_prefix, &cert[*offset], SIG_OID_PREFIX_SIZE))
475
+        goto end_check_sig;     /* unrecognised cert type */
476
+
477
+    x509_ctx->sig_type = cert[*offset + SIG_OID_PREFIX_SIZE];
478
+
479
+    *offset += len;
480
+    if (asn1_skip_obj(cert, offset, ASN1_NULL))
481
+        goto end_check_sig;
482
+    ret = X509_OK;
483
+
484
+end_check_sig:
485
+    return ret;
486
+}
487
+
488
+/**
489
+ * Construct a new x509 object.
490
+ * @return 0 if ok. < 0 if there was a problem.
491
+ */
492
+int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
493
+{
494
+    int begin_tbs, end_tbs;
495
+    int ret = X509_NOT_OK, offset = 0, cert_size = 0;
496
+    X509_CTX *x509_ctx;
497
+    BI_CTX *bi_ctx;
498
+
499
+    *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
500
+    x509_ctx = *ctx;
501
+
502
+    /* get the certificate size */
503
+    asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE); 
504
+
505
+    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
506
+        goto end_cert;
507
+
508
+    begin_tbs = offset;         /* start of the tbs */
509
+    end_tbs = begin_tbs;        /* work out the end of the tbs */
510
+    asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);
511
+
512
+    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
513
+        goto end_cert;
514
+
515
+    if (cert[offset] == ASN1_EXPLICIT_TAG)   /* optional version */
516
+    {
517
+        if (asn1_version(cert, &offset, x509_ctx))
518
+            goto end_cert;
519
+    }
520
+
521
+    if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */ 
522
+            asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
523
+        goto end_cert;
524
+
525
+    /* make sure the signature is ok */
526
+    if (asn1_signature_type(cert, &offset, x509_ctx))
527
+    {
528
+        ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
529
+        goto end_cert;
530
+    }
531
+
532
+    if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) || 
533
+            asn1_validity(cert, &offset, x509_ctx) ||
534
+            asn1_name(cert, &offset, x509_ctx->cert_dn) ||
535
+            asn1_public_key(cert, &offset, x509_ctx))
536
+        goto end_cert;
537
+
538
+    bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
539
+
540
+#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
541
+    /* use the appropriate signature algorithm (either SHA1 or MD5) */
542
+    if (x509_ctx->sig_type == SIG_TYPE_MD5)
543
+    {
544
+        MD5_CTX md5_ctx;
545
+        uint8_t md5_dgst[MD5_SIZE];
546
+        MD5Init(&md5_ctx);
547
+        MD5Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
548
+        MD5Final(&md5_ctx, md5_dgst);
549
+        x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
550
+    }
551
+    else if (x509_ctx->sig_type == SIG_TYPE_SHA1)
552
+    {
553
+        SHA1_CTX sha_ctx;
554
+        uint8_t sha_dgst[SHA1_SIZE];
555
+        SHA1Init(&sha_ctx);
556
+        SHA1Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
557
+        SHA1Final(&sha_ctx, sha_dgst);
558
+        x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
559
+    }
560
+
561
+    offset = end_tbs;   /* skip the v3 data */
562
+    if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) || 
563
+            asn1_signature(cert, &offset, x509_ctx))
564
+        goto end_cert;
565
+#endif
566
+
567
+    if (len)
568
+    {
569
+        *len = cert_size;
570
+    }
571
+
572
+    ret = X509_OK;
573
+end_cert:
574
+
575
+#ifdef CONFIG_SSL_FULL_MODE
576
+    if (ret)
577
+    {
578
+        printf("Error: Invalid X509 ASN.1 file\n");
579
+    }
580
+#endif
581
+
582
+    return ret;
583
+}
584
+
585
+/**
586
+ * Free an X.509 object's resources.
587
+ */
588
+void x509_free(X509_CTX *x509_ctx)
589
+{
590
+    X509_CTX *next;
591
+    int i;
592
+
593
+    if (x509_ctx == NULL)       /* if already null, then don't bother */
594
+        return;
595
+
596
+    for (i = 0; i < X509_NUM_DN_TYPES; i++)
597
+    {
598
+        free(x509_ctx->ca_cert_dn[i]);
599
+        free(x509_ctx->cert_dn[i]);
600
+    }
601
+
602
+    free(x509_ctx->signature);
603
+
604
+#ifdef CONFIG_SSL_CERT_VERIFICATION 
605
+    if (x509_ctx->digest)
606
+    {
607
+        bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest);
608
+    }
609
+#endif
610
+
611
+    RSA_free(x509_ctx->rsa_ctx);
612
+
613
+    next = x509_ctx->next;
614
+    free(x509_ctx);
615
+    x509_free(next);        /* clear the chain */
616
+}
617
+
618
+#ifdef CONFIG_SSL_CERT_VERIFICATION
619
+/**
620
+ * Do some basic checks on the certificate chain.
621
+ *
622
+ * Certificate verification consists of a number of checks:
623
+ * - A root certificate exists in the certificate store.
624
+ * - The date of the certificate is after the start date.
625
+ * - The date of the certificate is before the finish date.
626
+ * - The certificate chain is valid.
627
+ * - That the certificate(s) are not self-signed.
628
+ * - The signature of the certificate is valid.
629
+ */
630
+int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert) 
631
+{
632
+    int ret = X509_OK, i = 0;
633
+    bigint *cert_sig;
634
+    X509_CTX *next_cert = NULL;
635
+    BI_CTX *ctx;
636
+    bigint *mod, *expn;
637
+    struct timeval tv;
638
+    int match_ca_cert = 0;
639
+
640
+    if (cert == NULL || ca_cert_ctx == NULL)
641
+    {
642
+        ret = X509_VFY_ERROR_NO_TRUSTED_CERT;       
643
+        goto end_verify;
644
+    }
645
+
646
+    /* last cert in the chain - look for a trusted cert */
647
+    if (cert->next == NULL)
648
+    {
649
+        while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
650
+        {
651
+            if (asn1_compare_dn(cert->ca_cert_dn,
652
+                                        ca_cert_ctx->cert[i]->cert_dn) == 0)
653
+            {
654
+                match_ca_cert = 1;
655
+                break;
656
+            }
657
+
658
+            i++;
659
+        }
660
+
661
+        if (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
662
+        {
663
+            next_cert = ca_cert_ctx->cert[i];
664
+        }
665
+        else    /* trusted cert not found */
666
+        {
667
+            ret = X509_VFY_ERROR_NO_TRUSTED_CERT;       
668
+            goto end_verify;
669
+        }
670
+    }
671
+    else
672
+    {
673
+        next_cert = cert->next;
674
+    }
675
+
676
+    gettimeofday(&tv, NULL);
677
+
678
+    /* check the not before date */
679
+    if (tv.tv_sec < cert->not_before)
680
+    {
681
+        ret = X509_VFY_ERROR_NOT_YET_VALID;
682
+        goto end_verify;
683
+    }
684
+
685
+    /* check the not after date */
686
+    if (tv.tv_sec > cert->not_after)
687
+    {
688
+        ret = X509_VFY_ERROR_EXPIRED;
689
+        goto end_verify;
690
+    }
691
+
692
+    /* check the chain integrity */
693
+    if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn))
694
+    {
695
+        ret = X509_VFY_ERROR_INVALID_CHAIN;
696
+        goto end_verify;
697
+    }
698
+
699
+    /* check for self-signing */
700
+    if (!match_ca_cert && asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
701
+    {
702
+        ret = X509_VFY_ERROR_SELF_SIGNED;
703
+        goto end_verify;
704
+    }
705
+
706
+    /* check the signature */
707
+    ctx = cert->rsa_ctx->bi_ctx;
708
+    mod = next_cert->rsa_ctx->m;
709
+    expn = next_cert->rsa_ctx->e;
710
+    cert_sig = RSA_sign_verify(ctx, cert->signature, cert->sig_len, 
711
+            bi_clone(ctx, mod), bi_clone(ctx, expn));
712
+
713
+    if (cert_sig)
714
+    {
715
+        ret = cert->digest ?    /* check the signature */
716
+            bi_compare(cert_sig, cert->digest) :
717
+            X509_VFY_ERROR_UNSUPPORTED_DIGEST;
718
+        bi_free(ctx, cert_sig);
719
+
720
+        if (ret)
721
+            goto end_verify;
722
+    }
723
+    else
724
+    {
725
+        ret = X509_VFY_ERROR_BAD_SIGNATURE;
726
+        goto end_verify;
727
+    }
728
+
729
+    /* go down the certificate chain using recursion. */
730
+    if (ret == 0 && cert->next)
731
+    {
732
+        ret = x509_verify(ca_cert_ctx, next_cert);
733
+    }
734
+
735
+end_verify:
736
+    return ret;
737
+}
738
+#endif
739
+
740
+#if defined (CONFIG_SSL_FULL_MODE)
741
+/**
742
+ * Used for diagnostics.
743
+ */
744
+void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert) 
745
+{
746
+    if (cert == NULL)
747
+        return;
748
+
749
+    printf("----------------   CERT DEBUG   ----------------\n");
750
+    printf("* CA Cert Distinguished Name\n");
751
+    if (cert->ca_cert_dn[X509_COMMON_NAME])
752
+    {
753
+        printf("Common Name (CN):\t%s\n", cert->ca_cert_dn[X509_COMMON_NAME]);
754
+    }
755
+
756
+    if (cert->ca_cert_dn[X509_ORGANIZATION])
757
+    {
758
+        printf("Organization (O):\t%s\n", cert->ca_cert_dn[X509_ORGANIZATION]);
759
+    }
760
+
761
+    if (cert->ca_cert_dn[X509_ORGANIZATIONAL_TYPE])
762
+    {
763
+        printf("Organizational Unit (OU): %s\n", 
764
+                cert->ca_cert_dn[X509_ORGANIZATIONAL_TYPE]);
765
+    }
766
+
767
+    printf("* Cert Distinguished Name\n");
768
+    if (cert->cert_dn[X509_COMMON_NAME])
769
+    {
770
+        printf("Common Name (CN):\t%s\n", cert->cert_dn[X509_COMMON_NAME]);
771
+    }
772
+
773
+    if (cert->cert_dn[X509_ORGANIZATION])
774
+    {
775
+        printf("Organization (O):\t%s\n", cert->cert_dn[X509_ORGANIZATION]);
776
+    }
777
+
778
+    if (cert->cert_dn[X509_ORGANIZATIONAL_TYPE])
779
+    {
780
+        printf("Organizational Unit (OU): %s\n", 
781
+                cert->cert_dn[X509_ORGANIZATIONAL_TYPE]);
782
+    }
783
+
784
+    printf("Not Before:\t\t%s", ctime(&cert->not_before));
785
+    printf("Not After:\t\t%s", ctime(&cert->not_after));
786
+    printf("RSA bitsize:\t\t%d\n", cert->rsa_ctx->num_octets*8);
787
+    printf("Sig Type:\t\t");
788
+    switch (cert->sig_type)
789
+    {
790
+        case SIG_TYPE_MD5:
791
+            printf("MD5\n");
792
+            break;
793
+        case SIG_TYPE_SHA1:
794
+            printf("SHA1\n");
795
+            break;
796
+        case SIG_TYPE_MD2:
797
+            printf("MD2\n");
798
+            break;
799
+        default:
800
+            printf("Unrecognized: %d\n", cert->sig_type);
801
+            break;
802
+    }
803
+
804
+    printf("Verify:\t\t\t");
805
+
806
+    if (ca_cert_ctx)
807
+    {
808
+        x509_display_error(x509_verify(ca_cert_ctx, cert));
809
+    }
810
+
811
+    printf("\n");
812
+#if 0
813
+    print_blob("Signature", cert->signature, cert->sig_len);
814
+    bi_print("Modulus", cert->rsa_ctx->m);
815
+    bi_print("Pub Exp", cert->rsa_ctx->e);
816
+#endif
817
+
818
+    if (ca_cert_ctx)
819
+    {
820
+        x509_print(ca_cert_ctx, cert->next);
821
+    }
822
+}
823
+
824
+void x509_display_error(int error)
825
+{
826
+    switch (error)
827
+    {
828
+        case X509_NOT_OK:
829
+            printf("X509 not ok");
830
+            break;
831
+
832
+        case X509_VFY_ERROR_NO_TRUSTED_CERT:
833
+            printf("No trusted cert is available");
834
+            break;
835
+
836
+        case X509_VFY_ERROR_BAD_SIGNATURE:
837
+            printf("Bad signature");
838
+            break;
839
+
840
+        case X509_VFY_ERROR_NOT_YET_VALID:
841
+            printf("Cert is not yet valid");
842
+            break;
843
+
844
+        case X509_VFY_ERROR_EXPIRED:
845
+            printf("Cert has expired");
846
+            break;
847
+
848
+        case X509_VFY_ERROR_SELF_SIGNED:
849
+            printf("Cert is self-signed");
850
+            break;
851
+
852
+        case X509_VFY_ERROR_INVALID_CHAIN:
853
+            printf("Chain is invalid (check order of certs)");
854
+            break;
855
+
856
+        case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
857
+            printf("Unsupported digest");
858
+            break;
859
+
860
+        case X509_INVALID_PRIV_KEY:
861
+            printf("Invalid private key");
862
+            break;
863
+    }
864
+}
865
+#endif      /* CONFIG_SSL_FULL_MODE */
866
+
867
+#endif

+ 12
- 25
src/crypto/axtls/bigint.c View File

@@ -77,23 +77,14 @@ static void check(const bigint *bi);
77 77
  */
78 78
 BI_CTX *bi_initialize(void)
79 79
 {
80
+    /* calloc() sets everything to zero */
80 81
     BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
81
-
82
-    ctx->active_list = NULL;
83
-    ctx->active_count = 0;
84
-    ctx->free_list = NULL;
85
-    ctx->free_count = 0;
86
-    ctx->mod_offset = 0;
87
-#ifdef CONFIG_BIGINT_MONTGOMERY
88
-    ctx->use_classical = 0;
89
-#endif
90
-
82
+   
91 83
     /* the radix */
92 84
     ctx->bi_radix = alloc(ctx, 2); 
93 85
     ctx->bi_radix->comps[0] = 0;
94 86
     ctx->bi_radix->comps[1] = 1;
95 87
     bi_permanent(ctx->bi_radix);
96
-
97 88
     return ctx;
98 89
 }
99 90
 
@@ -285,7 +276,7 @@ bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
285 276
  * @param bia [in]  A bigint.
286 277
  * @param bib [in]  Another bigint.
287 278
  * @param is_negative [out] If defined, indicates that the result was negative.
288
- * is_negative may be NULL.
279
+ * is_negative may be null.
289 280
  * @return The result of the subtraction. The result is always positive.
290 281
  */
291 282
 bigint *bi_subtract(BI_CTX *ctx, 
@@ -482,7 +473,7 @@ bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
482 473
 /*
483 474
  * Perform an integer divide on a bigint.
484 475
  */
485
-static bigint *bi_int_divide(__unused BI_CTX *ctx, bigint *biR, comp denom)
476
+static bigint *bi_int_divide(BI_CTX *ctx __unused, bigint *biR, comp denom)
486 477
 {
487 478
     int i = biR->size - 1;
488 479
     long_comp r = 0;
@@ -781,7 +772,9 @@ void bi_free_mod(BI_CTX *ctx, int mod_offset)
781 772
  */
782 773
 static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
783 774
 {
784
-    int i, j, i_plus_j, n = bia->size, t = bib->size;
775
+    int i, j, i_plus_j;
776
+    int n = bia->size; 
777
+    int t = bib->size;
785 778
     bigint *biR = alloc(ctx, n + t);
786 779
     comp *sr = biR->comps;
787 780
     comp *sa = bia->comps;
@@ -1059,7 +1052,7 @@ static bigint *alloc(BI_CTX *ctx, int size)
1059 1052
 #ifdef CONFIG_SSL_FULL_MODE
1060 1053
             printf("alloc: refs was not 0\n");
1061 1054
 #endif
1062
-            abort();
1055
+            abort();    /* create a stack trace from a core dump */
1063 1056
         }
1064 1057
 
1065 1058
         more_comps(biR, size);
@@ -1220,7 +1213,7 @@ static bigint *comp_mod(bigint *bi, int mod)
1220 1213
 /*
1221 1214
  * Barrett reduction has no need for some parts of the product, so ignore bits
1222 1215
  * of the multiply. This routine gives Barrett its big performance
1223
- * improvements over classical/Montgomery reduction methods. 
1216
+ * improvements over Classical/Montgomery reduction methods. 
1224 1217
  */
1225 1218
 static bigint *partial_multiply(BI_CTX *ctx, bigint *bia, bigint *bib, 
1226 1219
         int inner_partial, int outer_partial)
@@ -1293,10 +1286,10 @@ static bigint *partial_multiply(BI_CTX *ctx, bigint *bia, bigint *bib,
1293 1286
 }
1294 1287
 
1295 1288
 /**
1296
- * @brief Perform a single barrett reduction.
1289
+ * @brief Perform a single Barrett reduction.
1297 1290
  * @param ctx [in]  The bigint session context.
1298 1291
  * @param bi [in]  A bigint.
1299
- * @return The result of the barrett reduction.
1292
+ * @return The result of the Barrett reduction.
1300 1293
  */
1301 1294
 bigint *bi_barrett(BI_CTX *ctx, bigint *bi)
1302 1295
 {
@@ -1308,7 +1301,7 @@ bigint *bi_barrett(BI_CTX *ctx, bigint *bi)
1308 1301
     check(bi);
1309 1302
     check(bim);
1310 1303
 
1311
-    /* use classical method instead  - Barrett cannot help here */
1304
+    /* use Classical method instead  - Barrett cannot help here */
1312 1305
     if (bi->size > k*2)
1313 1306
     {
1314 1307
         return bi_mod(ctx, bi);
@@ -1397,9 +1390,7 @@ bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
1397 1390
 
1398 1391
 #ifdef CONFIG_BIGINT_SLIDING_WINDOW
1399 1392
     for (j = i; j > 32; j /= 5) /* work out an optimum size */
1400
-    {
1401 1393
         window_size++;
1402
-    }
1403 1394
 
1404 1395
     /* work out the slide constants */
1405 1396
     precompute_slide_window(ctx, window_size, bi);
@@ -1420,15 +1411,11 @@ bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
1420 1411
             int part_exp = 0;
1421 1412
 
1422 1413
             if (l < 0)  /* LSB of exponent will always be 1 */
1423
-            {
1424 1414
                 l = 0;
1425
-            }
1426 1415
             else
1427 1416
             {
1428 1417
                 while (exp_bit_is_one(biexp, l) == 0)
1429
-                {
1430 1418
                     l++;    /* go back up */
1431
-                }
1432 1419
             }
1433 1420
 
1434 1421
             /* build up the section of the exponent */

+ 5
- 5
src/crypto/axtls/bigint.h View File

@@ -74,14 +74,14 @@ bigint *bi_str_import(BI_CTX *ctx, const char *data);
74 74
  * appropriate reduction technique (which is bi_mod() when doing classical
75 75
  * reduction).
76 76
  */
77
-#if defined(CONFIG_BIGINT_CLASSICAL)
78
-#define bi_residue(A, B)         bi_mod(A, B)
77
+#if defined(CONFIG_BIGINT_MONTGOMERY)
78
+#define bi_residue(A, B)         bi_mont(A, B)
79
+bigint *bi_mont(BI_CTX *ctx, bigint *bixy);
79 80
 #elif defined(CONFIG_BIGINT_BARRETT)
80 81
 #define bi_residue(A, B)         bi_barrett(A, B)
81 82
 bigint *bi_barrett(BI_CTX *ctx, bigint *bi);
82
-#else   /* CONFIG_BIGINT_MONTGOMERY */
83
-#define bi_residue(A, B)         bi_mont(A, B)
84
-bigint *bi_mont(BI_CTX *ctx, bigint *bixy);
83
+#else /* if defined(CONFIG_BIGINT_CLASSICAL) */
84
+#define bi_residue(A, B)         bi_mod(A, B)
85 85
 #endif
86 86
 
87 87
 #ifdef CONFIG_BIGINT_SQUARE

+ 10
- 5
src/crypto/axtls/crypto.h View File

@@ -124,7 +124,12 @@ void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
124 124
 void RNG_initialize(const uint8_t *seed_buf, int size);
125 125
 void RNG_terminate(void);
126 126
 void get_random(int num_rand_bytes, uint8_t *rand_data);
127
-void get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
127
+//void get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
128
+
129
+#include <string.h>
130
+static inline void get_random_NZ(int num_rand_bytes, uint8_t *rand_data) {
131
+	memset ( rand_data, 0x01, num_rand_bytes );
132
+}
128 133
 
129 134
 /**************************************************************************
130 135
  * RSA declarations 
@@ -163,15 +168,15 @@ void RSA_pub_key_new(RSA_CTX **rsa_ctx,
163 168
         const uint8_t *modulus, int mod_len,
164 169
         const uint8_t *pub_exp, int pub_len);
165 170
 void RSA_free(RSA_CTX *ctx);
166
-int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
171
+int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
167 172
         int is_decryption);
168
-bigint *RSA_private(RSA_CTX *c, bigint *bi_msg);
173
+bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg);
169 174
 #ifdef CONFIG_SSL_CERT_VERIFICATION
170 175
 bigint *RSA_raw_sign_verify(RSA_CTX *c, bigint *bi_msg);
171 176
 bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
172 177
         bigint *modulus, bigint *pub_exp);
173
-bigint *RSA_public(RSA_CTX *c, bigint *bi_msg);
174
-int RSA_encrypt(RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, 
178
+bigint *RSA_public(const RSA_CTX *c, bigint *bi_msg);
179
+int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, 
175 180
         uint8_t *out_data, int is_signing);
176 181
 void RSA_print(const RSA_CTX *ctx);
177 182
 #endif

+ 0
- 3
src/crypto/axtls/os_port.h View File

@@ -27,9 +27,6 @@ static inline void close ( int fd __unused ) {
27 27
 }
28 28
 
29 29
 typedef void FILE;
30
-#define SEEK_SET 0
31
-#define SEEK_CUR 0
32
-#define SEEK_END 0
33 30
 
34 31
 static inline FILE * fopen ( const char *filename __unused,
35 32
 			     const char *mode __unused ) {

+ 12
- 18
src/crypto/axtls/rsa.c View File

@@ -28,7 +28,7 @@
28 28
 #include "crypto.h"
29 29
 
30 30
 #ifdef CONFIG_BIGINT_CRT
31
-static bigint *bi_crt(RSA_CTX *rsa, bigint *bi);
31
+static bigint *bi_crt(const RSA_CTX *rsa, bigint *bi);
32 32
 #endif
33 33
 
34 34
 void RSA_priv_key_new(RSA_CTX **ctx, 
@@ -72,7 +72,7 @@ void RSA_pub_key_new(RSA_CTX **ctx,
72 72
 {
73 73
     RSA_CTX *rsa_ctx;
74 74
     BI_CTX *bi_ctx = bi_initialize();
75
-    *ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX));   /* reset to all 0 */
75
+    *ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX));
76 76
     rsa_ctx = *ctx;
77 77
     rsa_ctx->bi_ctx = bi_ctx;
78 78
     rsa_ctx->num_octets = (mod_len & 0xFFF0);
@@ -126,8 +126,8 @@ void RSA_free(RSA_CTX *rsa_ctx)
126 126
  * @return  The number of bytes that were originally encrypted. -1 on error.
127 127
  * @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
128 128
  */
129
-int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
130
-        int is_decryption)
129
+int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, 
130
+                            uint8_t *out_data, int is_decryption)
131 131
 {
132 132
     int byte_size = ctx->num_octets;
133 133
     uint8_t *block;
@@ -155,10 +155,9 @@ int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
155 155
     if (is_decryption == 0) /* PKCS1.5 signing pads with "0xff"s */
156 156
     {
157 157
         while (block[i++] == 0xff && i < byte_size);
158
+
158 159
         if (block[i-2] != 0xff)
159
-        {
160 160
             i = byte_size;     /*ensure size is 0 */   
161
-        }
162 161
     }
163 162
     else                    /* PKCS1.5 encryption padding is random */
164 163
 #endif
@@ -169,9 +168,7 @@ int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
169 168
 
170 169
     /* get only the bit we want */
171 170
     if (size > 0)
172
-    {
173 171
         memcpy(out_data, &block[i], size);
174
-    }
175 172
     
176 173
     free(block);
177 174
     return size ? size : -1;
@@ -180,7 +177,7 @@ int RSA_decrypt(RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
180 177
 /**
181 178
  * Performs m = c^d mod n
182 179
  */
183
-bigint *RSA_private(RSA_CTX *c, bigint *bi_msg)
180
+bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg)
184 181
 {
185 182
 #ifdef CONFIG_BIGINT_CRT
186 183
     return bi_crt(c, bi_msg);
@@ -197,7 +194,7 @@ bigint *RSA_private(RSA_CTX *c, bigint *bi_msg)
197 194
  * This should really be in bigint.c (and was at one stage), but needs 
198 195
  * access to the RSA_CTX context...
199 196
  */
200
-static bigint *bi_crt(RSA_CTX *rsa, bigint *bi)
197
+static bigint *bi_crt(const RSA_CTX *rsa, bigint *bi)
201 198
 {
202 199
     BI_CTX *ctx = rsa->bi_ctx;
203 200
     bigint *m1, *m2, *h;
@@ -245,7 +242,7 @@ void RSA_print(const RSA_CTX *rsa_ctx)
245 242
 /**
246 243
  * Performs c = m^e mod n
247 244
  */
248
-bigint *RSA_public(RSA_CTX *c, bigint *bi_msg)
245
+bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg)
249 246
 {
250 247
     c->bi_ctx->mod_offset = BIGINT_M_OFFSET;
251 248
     return bi_mod_power(c->bi_ctx, bi_msg, c->e);
@@ -255,7 +252,7 @@ bigint *RSA_public(RSA_CTX *c, bigint *bi_msg)
255 252
  * Use PKCS1.5 for encryption/signing.
256 253
  * see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
257 254
  */
258
-int RSA_encrypt(RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, 
255
+int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, 
259 256
         uint8_t *out_data, int is_signing)
260 257
 {
261 258
     int byte_size = ctx->num_octets;
@@ -273,10 +270,7 @@ int RSA_encrypt(RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
273 270
     else /* randomize the encryption padding with non-zero bytes */   
274 271
     {
275 272
         out_data[1] = 2;
276
-        memset(&out_data[2], 0x01, num_pads_needed);
277
-#if 0
278 273
         get_random_NZ(num_pads_needed, &out_data[2]);
279
-#endif
280 274
     }
281 275
 
282 276
     out_data[2+num_pads_needed] = 0;
@@ -291,18 +285,19 @@ int RSA_encrypt(RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
291 285
 }
292 286
 
293 287
 #if 0
294
-
295 288
 /**
296 289
  * Take a signature and decrypt it.
297 290
  */
298 291
 bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
299 292
         bigint *modulus, bigint *pub_exp)
300 293
 {
301
-    uint8_t *block = (uint8_t *)malloc(sig_len);
294
+    uint8_t *block;
302 295
     int i, size;
303 296
     bigint *decrypted_bi, *dat_bi;
304 297
     bigint *bir = NULL;
305 298
 
299
+    block = (uint8_t *)malloc(sig_len);
300
+
306 301
     /* decrypt */
307 302
     dat_bi = bi_import(ctx, sig, sig_len);
308 303
     ctx->mod_offset = BIGINT_M_OFFSET;
@@ -332,7 +327,6 @@ bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
332 327
     free(block);
333 328
     return bir;
334 329
 }
335
-
336 330
 #endif
337 331
 
338 332
 #endif  /* CONFIG_SSL_CERT_VERIFICATION */

+ 120
- 0
src/crypto/hmac.c View File

@@ -0,0 +1,120 @@
1
+/*
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+/**
20
+ * @file
21
+ *
22
+ * Keyed-Hashing for Message Authentication
23
+ */
24
+
25
+#include <string.h>
26
+#include <assert.h>
27
+#include <gpxe/crypto.h>
28
+#include <gpxe/hmac.h>
29
+
30
+/**
31
+ * Reduce HMAC key length
32
+ *
33
+ * @v digest		Digest algorithm to use
34
+ * @v digest_ctx	Digest context
35
+ * @v key		Key
36
+ * @v key_len		Length of key
37
+ */
38
+static void hmac_reduce_key ( struct crypto_algorithm *digest,
39
+			      void *key, size_t *key_len ) {
40
+	uint8_t digest_ctx[digest->ctxsize];
41
+
42
+	digest_init ( digest, digest_ctx );
43
+	digest_update ( digest, digest_ctx, key, *key_len );
44
+	digest_final ( digest, digest_ctx, key );
45
+	*key_len = digest->digestsize;
46
+}
47
+
48
+/**
49
+ * Initialise HMAC
50
+ *
51
+ * @v digest		Digest algorithm to use
52
+ * @v digest_ctx	Digest context
53
+ * @v key		Key
54
+ * @v key_len		Length of key
55
+ *
56
+ * The length of the key should be less than the block size of the
57
+ * digest algorithm being used.  (If the key length is greater, it
58
+ * will be replaced with its own digest, and key_len will be updated
59
+ * accordingly).
60
+ */
61
+void hmac_init ( struct crypto_algorithm *digest, void *digest_ctx,
62
+		 void *key, size_t *key_len ) {
63
+	unsigned char k_ipad[digest->blocksize];
64
+	unsigned int i;
65
+
66
+	/* Reduce key if necessary */
67
+	if ( *key_len > sizeof ( k_ipad ) )
68
+		hmac_reduce_key ( digest, key, key_len );
69
+
70
+	/* Construct input pad */
71
+	memset ( k_ipad, 0, sizeof ( k_ipad ) );
72
+	memcpy ( k_ipad, key, *key_len );
73
+	for ( i = 0 ; i < sizeof ( k_ipad ) ; i++ ) {
74
+		k_ipad[i] ^= 0x36;
75
+	}
76
+	
77
+	/* Start inner hash */
78
+	digest_init ( digest, digest_ctx );
79
+	digest_update ( digest, digest_ctx, k_ipad, sizeof ( k_ipad ) );
80
+}
81
+
82
+/**
83
+ * Finalise HMAC
84
+ *
85
+ * @v digest		Digest algorithm to use
86
+ * @v digest_ctx	Digest context
87
+ * @v key		Key
88
+ * @v key_len		Length of key
89
+ * @v hmac		HMAC digest to fill in
90
+ *
91
+ * The length of the key should be less than the block size of the
92
+ * digest algorithm being used.  (If the key length is greater, it
93
+ * will be replaced with its own digest, and key_len will be updated
94
+ * accordingly).
95
+ */
96
+void hmac_final ( struct crypto_algorithm *digest, void *digest_ctx,
97
+		  void *key, size_t *key_len, void *hmac ) {
98
+	unsigned char k_opad[digest->blocksize];
99
+	unsigned int i;
100
+
101
+	/* Reduce key if necessary */
102
+	if ( *key_len > sizeof ( k_opad ) )
103
+		hmac_reduce_key ( digest, key, key_len );
104
+
105
+	/* Construct output pad */
106
+	memset ( k_opad, 0, sizeof ( k_opad ) );
107
+	memcpy ( k_opad, key, *key_len );
108
+	for ( i = 0 ; i < sizeof ( k_opad ) ; i++ ) {
109
+		k_opad[i] ^= 0x5c;
110
+	}
111
+	
112
+	/* Finish inner hash */
113
+	digest_final ( digest, digest_ctx, hmac );
114
+
115
+	/* Perform outer hash */
116
+	digest_init ( digest, digest_ctx );
117
+	digest_update ( digest, digest_ctx, k_opad, sizeof ( k_opad ) );
118
+	digest_update ( digest, digest_ctx, hmac, digest->digestsize );
119
+	digest_final ( digest, digest_ctx, hmac );
120
+}

+ 1
- 1
src/crypto/md5.c View File

@@ -54,7 +54,7 @@ static u32 __md5step f4(u32 b, u32 c, u32 d)
54 54
 	return ( c ^ ( b | ~d ) );
55 55
 }
56 56
 
57
-struct md5_step md5_steps[4] = {
57
+static struct md5_step md5_steps[4] = {
58 58
 	{
59 59
 		.f = f1,
60 60
 		.coefficient = 1,

+ 4
- 0
src/drivers/bitbash/spi_bit.c View File

@@ -153,6 +153,10 @@ static int spi_bit_rw ( struct spi_bus *bus, struct spi_device *device,
153 153
 		= container_of ( bus, struct spi_bit_basher, bus );
154 154
 	uint32_t tmp;
155 155
 
156
+	/* Set clock line to idle state */
157
+	write_bit ( &spibit->basher, SPI_BIT_SCLK, 
158
+		    ( bus->mode & SPI_MODE_CPOL ) );
159
+
156 160
 	/* Assert chip select on specified slave */
157 161
 	spi_bit_set_slave_select ( spibit, device->slave, SELECT_SLAVE );
158 162
 

+ 1
- 1
src/drivers/net/bnx2.c View File

@@ -43,7 +43,7 @@ static struct bss {
43 43
 	struct statistics_block stats_blk;
44 44
 } bnx2_bss;
45 45
 
46
-struct bnx2 bnx2;
46
+static struct bnx2 bnx2;
47 47
 
48 48
 static struct flash_spec flash_table[] =
49 49
 {

+ 1
- 1
src/drivers/net/ns83820.c View File

@@ -364,7 +364,7 @@ struct ring_desc {
364 364
 #endif
365 365
 
366 366
 /* Private Storage for the NIC */
367
-struct ns83820_private {
367
+static struct ns83820_private {
368 368
 	u8 *base;
369 369
 	int up;
370 370
 	long idle;

+ 1
- 1
src/drivers/net/pcnet32.c View File

@@ -67,7 +67,7 @@ static struct nic_operations pcnet32_operations;
67 67
 
68 68
 /* End Etherboot Specific */
69 69
 
70
-int cards_found /* __initdata */ ;
70
+static int cards_found = 0 /* __initdata */ ;
71 71
 
72 72
 #ifdef REMOVE
73 73
 /* FIXME: Remove these they are probably pointless */

+ 2
- 2
src/drivers/net/r8169.c View File

@@ -400,7 +400,7 @@ static void rtl8169_hw_PHY_config(struct nic *nic __unused);
400 400
 //      20-16   5-bit GMII/MII register address
401 401
 //      15-0    16-bit GMII/MII register data
402 402
 //=================================================================
403
-void RTL8169_WRITE_GMII_REG(unsigned long ioaddr, int RegAddr, int value)
403
+static void RTL8169_WRITE_GMII_REG(unsigned long ioaddr, int RegAddr, int value)
404 404
 {
405 405
 	int i;
406 406
 
@@ -418,7 +418,7 @@ void RTL8169_WRITE_GMII_REG(unsigned long ioaddr, int RegAddr, int value)
418 418
 }
419 419
 
420 420
 //=================================================================
421
-int RTL8169_READ_GMII_REG(unsigned long ioaddr, int RegAddr)
421
+static int RTL8169_READ_GMII_REG(unsigned long ioaddr, int RegAddr)
422 422
 {
423 423
 	int i, value = -1;
424 424
 

+ 2
- 2
src/drivers/net/via-velocity.h View File

@@ -1204,7 +1204,7 @@ struct velocity_info_tbl {
1204 1204
 	u32 flags;
1205 1205
 };
1206 1206
 
1207
-struct velocity_info_tbl *info;
1207
+static struct velocity_info_tbl *info;
1208 1208
 
1209 1209
 #define mac_hw_mibs_init(regs) {\
1210 1210
 	BYTE_REG_BITS_ON(MIBCR_MIBFRZ,&((regs)->MIBCR));\
@@ -1768,7 +1768,7 @@ struct velocity_opt {
1768 1768
 #define TX_DESC_MAX     256
1769 1769
 #define TX_DESC_DEF     TX_DESC_MIN
1770 1770
 
1771
-struct velocity_info {
1771
+static struct velocity_info {
1772 1772
 //      struct list_head list;
1773 1773
 
1774 1774
 	struct pci_device *pdev;

+ 2
- 1
src/hci/commands/image_cmd.c View File

@@ -45,7 +45,8 @@
45 45
  * @v nargs		Argument count
46 46
  * @v args		Argument list
47 47
  */
48
-void imgfill_cmdline ( struct image *image, unsigned int nargs, char **args ) {
48
+static void imgfill_cmdline ( struct image *image, unsigned int nargs, 
49
+                              char **args ) {
49 50
 	size_t used = 0;
50 51
 
51 52
 	image->cmdline[0] = '\0';

+ 1
- 12
src/hci/mucurses/kb.c View File

@@ -19,18 +19,7 @@ int m_delay; /*
19 19
 bool m_echo;
20 20
 bool m_cbreak;
21 21
 
22
-/**
23
- * Check KEY_ code supported status
24
- *
25
- * @v kc	keycode value to check
26
- * @ret TRUE	KEY_* supported
27
- * @ret FALSE	KEY_* unsupported
28
- */
29
-int has_key ( int kc __unused ) {
30
-	return TRUE;
31
-}
32
-
33
-int _wgetc ( WINDOW *win ) {
22
+static int _wgetc ( WINDOW *win ) {
34 23
 	int timer, c;
35 24
 
36 25
 	if ( win == NULL )

+ 1
- 1
src/hci/mucurses/slk.c View File

@@ -50,7 +50,7 @@ struct _softlabelkeys {
50 50
 	short saved_pair;
51 51
 };
52 52
 
53
-struct _softlabelkeys *slks;
53
+static struct _softlabelkeys *slks;
54 54
 
55 55
 /*
56 56
   I either need to break the primitives here, or write a collection of

+ 3
- 0
src/include/compiler.h View File

@@ -276,6 +276,9 @@ extern void dbg_hex_dump_da ( unsigned long dispaddr,
276 276
 /** Declare a variable or data structure as unused. */
277 277
 #define __unused __attribute__ (( unused ))
278 278
 
279
+/** Apply standard C calling conventions */
280
+#define __cdecl __attribute__ (( cdecl , regparm(0) ))
281
+
279 282
 /**
280 283
  * Declare a function as used.
281 284
  *

+ 4
- 0
src/include/curses.h View File

@@ -566,6 +566,10 @@ static inline bool has_colors ( void ) {
566 566
 	return TRUE;
567 567
 }
568 568
 
569
+static inline int has_key ( int kc __unused ) {
570
+	return TRUE;
571
+}
572
+
569 573
 static inline int hline ( chtype ch, int n ) {
570 574
 	return whline ( stdscr, ch, n );
571 575
 }

+ 35
- 0
src/include/gpxe/abft.h View File

@@ -0,0 +1,35 @@
1
+#ifndef _GPXE_ABFT_H
2
+#define _GPXE_ABFT_H
3
+
4
+/** @file
5
+ *
6
+ * AoE boot firmware table
7
+ *
8
+ */
9
+
10
+#include <stdint.h>
11
+#include <gpxe/acpi.h>
12
+#include <gpxe/if_ether.h>
13
+
14
+/** AoE boot firmware table signature */
15
+#define ABFT_SIG "aBFT"
16
+
17
+/**
18
+ * AoE Boot Firmware Table (aBFT)
19
+ */
20
+struct abft_table {
21
+	/** ACPI header */
22
+	struct acpi_description_header acpi;
23
+	/** AoE shelf */
24
+	uint16_t shelf;
25
+	/** AoE slot */
26
+	uint8_t slot;
27
+	/** Reserved */
28
+	uint8_t reserved_a;
29
+	/** MAC address */
30
+	uint8_t mac[ETH_ALEN];
31
+} __attribute__ (( packed ));
32
+
33
+extern void abft_fill_data ( struct aoe_session *aoe );
34
+
35
+#endif /* _GPXE_ABFT_H */

+ 8
- 17
src/include/gpxe/aoe.h View File

@@ -81,6 +81,9 @@ struct aoehdr {
81 81
 
82 82
 /** An AoE session */
83 83
 struct aoe_session {
84
+	/** Reference counter */
85
+	struct refcnt refcnt;
86
+
84 87
 	/** List of all AoE sessions */
85 88
 	struct list_head list;
86 89
 
@@ -103,8 +106,8 @@ struct aoe_session {
103 106
 	unsigned int status;
104 107
 	/** Byte offset within command's data buffer */
105 108
 	unsigned int command_offset;
106
-	/** Asynchronous operation for this command */
107
-	struct async async;
109
+	/** Return status code for command */
110
+	int rc;
108 111
 
109 112
 	/** Retransmission timer */
110 113
 	struct retry_timer timer;
@@ -116,20 +119,8 @@ struct aoe_session {
116 119
 /** Maximum number of sectors per packet */
117 120
 #define AOE_MAX_COUNT 2
118 121
 
119
-extern void aoe_open ( struct aoe_session *aoe );
120
-extern void aoe_close ( struct aoe_session *aoe );
121
-extern int aoe_issue ( struct aoe_session *aoe,
122
-		       struct ata_command *command,
123
-		       struct async *parent );
124
-
125
-/** An AoE device */
126
-struct aoe_device {
127
-	/** ATA device interface */
128
-	struct ata_device ata;
129
-	/** AoE protocol instance */
130
-	struct aoe_session aoe;
131
-};
132
-
133
-extern int init_aoedev ( struct aoe_device *aoedev );
122
+extern void aoe_detach ( struct ata_device *ata );
123
+extern int aoe_attach ( struct ata_device *ata, struct net_device *netdev,
124
+			const char *root_path );
134 125
 
135 126
 #endif /* _GPXE_AOE_H */

+ 3
- 0
src/include/gpxe/ata.h View File

@@ -4,6 +4,7 @@
4 4
 #include <stdint.h>
5 5
 #include <gpxe/blockdev.h>
6 6
 #include <gpxe/uaccess.h>
7
+#include <gpxe/refcnt.h>
7 8
 
8 9
 /** @file
9 10
  *
@@ -195,6 +196,8 @@ struct ata_device {
195 196
 	 */
196 197
 	int ( * command ) ( struct ata_device *ata,
197 198
 			    struct ata_command *command );
199
+	/** Backing device */
200
+	struct refcnt *backend;
198 201
 };
199 202
 
200 203
 extern int init_atadev ( struct ata_device *ata );

+ 23
- 6
src/include/gpxe/dhcp.h View File

@@ -168,6 +168,19 @@ struct job_interface;
168 168
  */
169 169
 #define DHCP_EB_SIADDR DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 3 )
170 170
 
171
+/** Network device descriptor
172
+ *
173
+ * Byte 0 is the bus type ID; remaining bytes depend on the bus type.
174
+ *
175
+ * PCI devices:
176
+ * Byte 0 : 1 (PCI)
177
+ * Byte 1 : PCI vendor ID MSB
178
+ * Byte 2 : PCI vendor ID LSB
179
+ * Byte 3 : PCI device ID MSB
180
+ * Byte 4 : PCI device ID LSB
181
+ */
182
+#define DHCP_EB_BUS_ID DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb1 )
183
+
171 184
 /** BIOS drive number
172 185
  *
173 186
  * This is the drive number for a drive emulated via INT 13.  0x80 is
@@ -503,15 +516,19 @@ extern void find_global_dhcp_ipv4_option ( unsigned int tag,
503 516
 					   struct in_addr *inp );
504 517
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
505 518
 				 unsigned int tag );
519
+
506 520
 extern int apply_dhcp_options ( struct dhcp_option_block *options );
507 521
 extern int apply_global_dhcp_options ( void );
508 522
 
509
-extern struct dhcp_option_block dhcp_request_options;
510
-extern int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype,
511
-				void *data, size_t max_len,
512
-				struct dhcp_packet *dhcppkt );
513
-extern int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
514
-				      struct dhcp_option_block *options );
523
+extern int create_dhcp_request ( struct net_device *netdev, int msgtype,
524
+				 struct dhcp_option_block *options,
525
+				 void *data, size_t max_len,
526
+				 struct dhcp_packet *dhcppkt );
527
+extern int create_dhcp_response ( struct net_device *netdev, int msgtype,
528
+				  struct dhcp_option_block *options,
529
+				  void *data, size_t max_len,
530
+				  struct dhcp_packet *dhcppkt );
531
+
515 532
 extern int start_dhcp ( struct job_interface *job, struct net_device *netdev,
516 533
 			int (*register_options) ( struct net_device *,
517 534
 						  struct dhcp_option_block * ));

+ 2
- 0
src/include/gpxe/errfile.h View File

@@ -115,6 +115,8 @@
115 115
 #define ERRFILE_cipher		      ( ERRFILE_OTHER | 0x00090000 )
116 116
 #define ERRFILE_image_cmd	      ( ERRFILE_OTHER | 0x000a0000 )
117 117
 #define ERRFILE_uri_test	      ( ERRFILE_OTHER | 0x000b0000 )
118
+#define ERRFILE_ibft		      ( ERRFILE_OTHER | 0x000c0000 )
119
+#define ERRFILE_tls		      ( ERRFILE_OTHER | 0x000d0000 )
118 120
 
119 121
 /** @} */
120 122
 

+ 75
- 0
src/include/gpxe/filter.h View File

@@ -0,0 +1,75 @@
1
+#ifndef _GPXE_FILTER_H
2
+#define _GPXE_FILTER_H
3
+
4
+/** @file
5
+ *
6
+ * Data transfer filters
7
+ *
8
+ */
9
+
10
+#include <stddef.h>
11
+#include <gpxe/xfer.h>
12
+
13
+/**
14
+ * Half of a data transfer filter
15
+ *
16
+ * Embed two of these structures within a structure implementing a
17
+ * data transfer filter, and intialise with filter_init().  You can
18
+ * then use the filter_xxx() methods as the data transfer interface
19
+ * methods as required.
20
+ */
21
+struct xfer_filter_half {
22
+	/** Data transfer interface */
23
+	struct xfer_interface xfer;
24
+	/** Other half of the data transfer filter */
25
+	struct xfer_filter_half *other;
26
+};
27
+
28
+/**
29
+ * Get data transfer interface for the other half of a data transfer filter
30
+ *
31
+ * @v xfer		Data transfer interface
32
+ * @ret other		Other half's data transfer interface
33
+ */
34
+static inline __attribute__ (( always_inline )) struct xfer_interface *
35
+filter_other_half ( struct xfer_interface *xfer ) {
36
+	struct xfer_filter_half *half = 
37
+		container_of ( xfer, struct xfer_filter_half, xfer );
38
+	return &half->other->xfer;
39
+}
40
+
41
+extern void filter_close ( struct xfer_interface *xfer, int rc );
42
+extern int filter_vredirect ( struct xfer_interface *xfer, int type,
43
+			      va_list args );
44
+extern int filter_seek ( struct xfer_interface *xfer, off_t offset,
45
+			 int whence );
46
+extern size_t filter_window ( struct xfer_interface *xfer );
47
+extern struct io_buffer * filter_alloc_iob ( struct xfer_interface *xfer,
48
+					     size_t len );
49
+extern int filter_deliver_iob ( struct xfer_interface *xfer,
50
+				struct io_buffer *iobuf,
51
+				struct xfer_metadata *meta );
52
+extern int filter_deliver_raw ( struct xfer_interface *xfer, const void *data,
53
+				size_t len );
54
+
55
+/**
56
+ * Initialise a data transfer filter
57
+ *
58
+ * @v left		"Left" half of the filter
59
+ * @v left_op		Data transfer interface operations for "left" half
60
+ * @v right		"Right" half of the filter
61
+ * @v right_op		Data transfer interface operations for "right" half
62
+ * @v refcnt		Containing object reference counter, or NULL
63
+ */
64
+static inline void filter_init ( struct xfer_filter_half *left,
65
+				 struct xfer_interface_operations *left_op,
66
+				 struct xfer_filter_half *right,
67
+				 struct xfer_interface_operations *right_op,
68
+				 struct refcnt *refcnt ) {
69
+	xfer_init ( &left->xfer, left_op, refcnt );
70
+	xfer_init ( &right->xfer, right_op, refcnt );
71
+	left->other = right;
72
+	right->other = left;
73
+}
74
+
75
+#endif /* _GPXE_FILTER_H */

+ 30
- 0
src/include/gpxe/hmac.h View File

@@ -0,0 +1,30 @@
1
+#ifndef _GPXE_HMAC_H
2
+#define _GPXE_HMAC_H
3
+
4
+/** @file
5
+ *
6
+ * Keyed-Hashing for Message Authentication
7
+ */
8
+
9
+#include <gpxe/crypto.h>
10
+
11
+/**
12
+ * Update HMAC
13
+ *
14
+ * @v digest		Digest algorithm to use
15
+ * @v digest_ctx	Digest context
16
+ * @v data		Data
17
+ * @v len		Length of data
18
+ */
19
+static inline void hmac_update ( struct crypto_algorithm *digest,
20
+				 void *digest_ctx, const void *data,
21
+				 size_t len ) {
22
+	digest_update ( digest, digest_ctx, data, len );
23
+}
24
+
25
+extern void hmac_init ( struct crypto_algorithm *digest, void *digest_ctx,
26
+			void *key, size_t *key_len );
27
+extern void hmac_final ( struct crypto_algorithm *digest, void *digest_ctx,
28
+			 void *key, size_t *key_len, void *hmac );
29
+
30
+#endif /* _GPXE_HMAC_H */

+ 5
- 0
src/include/gpxe/http.h View File

@@ -13,4 +13,9 @@
13 13
 /** HTTPS default port */
14 14
 #define HTTPS_PORT 443
15 15
 
16
+extern int http_open_filter ( struct xfer_interface *xfer, struct uri *uri,
17
+			      unsigned int default_port,
18
+			      int ( * filter ) ( struct xfer_interface *,
19
+						 struct xfer_interface ** ) );
20
+
16 21
 #endif /* _GPXE_HTTP_H */

+ 9
- 0
src/include/gpxe/iscsi.h View File

@@ -8,6 +8,7 @@
8 8
  */
9 9
 
10 10
 #include <stdint.h>
11
+#include <gpxe/socket.h>
11 12
 #include <gpxe/scsi.h>
12 13
 #include <gpxe/chap.h>
13 14
 #include <gpxe/refcnt.h>
@@ -501,6 +502,8 @@ struct iscsi_session {
501 502
 	char *target_iqn;
502 503
 	/** Logical Unit Number (LUN) */
503 504
 	uint64_t lun;
505
+	/** Target socket address (recorded only for iBFT) */
506
+	struct sockaddr target_sockaddr;
504 507
 
505 508
 	/** Session status
506 509
 	 *
@@ -514,6 +517,11 @@ struct iscsi_session {
514 517
 	 * Reset upon a successful connection.
515 518
 	 */
516 519
 	int retry_count;
520
+
521
+	/** Username (if any) */
522
+	char *username;
523
+	/** Password (if any) */
524
+	char *password;
517 525
 	/** CHAP challenge/response */
518 526
 	struct chap_challenge chap;
519 527
 
@@ -641,5 +649,6 @@ struct iscsi_session {
641 649
 
642 650
 extern int iscsi_attach ( struct scsi_device *scsi, const char *root_path );
643 651
 extern void iscsi_detach ( struct scsi_device *scsi );
652
+extern const char * iscsi_initiator_iqn ( void );
644 653
 
645 654
 #endif /* _GPXE_ISCSI_H */

+ 1
- 0
src/include/gpxe/open.h View File

@@ -7,6 +7,7 @@
7 7
  *
8 8
  */
9 9
 
10
+#include <stdarg.h>
10 11
 #include <gpxe/tables.h>
11 12
 
12 13
 struct xfer_interface;

+ 164
- 5
src/include/gpxe/tls.h View File

@@ -1,12 +1,171 @@
1 1
 #ifndef _GPXE_TLS_H
2 2
 #define _GPXE_TLS_H
3 3
 
4
-#include <errno.h>
4
+/**
5
+ * @file
6
+ *
7
+ * Transport Layer Security Protocol
8
+ */
5 9
 
6
-struct stream_application;
10
+#include <stdint.h>
11
+#include <gpxe/refcnt.h>
12
+#include <gpxe/filter.h>
13
+#include <gpxe/process.h>
14
+#include <gpxe/crypto.h>
15
+#include <gpxe/md5.h>
16
+#include <gpxe/sha1.h>
7 17
 
8
-static inline int add_tls ( struct stream_application *app __unused ) {
9
-	return -ENOTSUP;
10
-}
18
+/** A TLS header */
19
+struct tls_header {
20
+	/** Content type
21
+	 *
22
+	 * This is a TLS_TYPE_XXX constant
23
+	 */
24
+	uint8_t type;
25
+	/** Protocol version
26
+	 *
27
+	 * This is a TLS_VERSION_XXX constant
28
+	 */
29
+	uint16_t version;
30
+	/** Length of payload */
31
+	uint16_t length;
32
+} __attribute__ (( packed ));
33
+
34
+/** TLS version 1.0 */
35
+#define TLS_VERSION_TLS_1_0 0x0301
36
+
37
+/** TLS version 1.1 */
38
+#define TLS_VERSION_TLS_1_1 0x0302
39
+
40
+/** Change cipher content type */
41
+#define TLS_TYPE_CHANGE_CIPHER 20
42
+
43
+/** Alert content type */
44
+#define TLS_TYPE_ALERT 21
45
+
46
+/** Handshake content type */
47
+#define TLS_TYPE_HANDSHAKE 22
48
+
49
+/** Application data content type */
50
+#define TLS_TYPE_DATA 23
51
+
52
+/* Handshake message types */
53
+#define TLS_HELLO_REQUEST 0
54
+#define TLS_CLIENT_HELLO 1
55
+#define TLS_SERVER_HELLO 2
56
+#define TLS_CERTIFICATE 11
57
+#define TLS_SERVER_KEY_EXCHANGE 12
58
+#define TLS_CERTIFICATE_REQUEST 13
59
+#define TLS_SERVER_HELLO_DONE 14
60
+#define TLS_CERTIFICATE_VERIFY 15
61
+#define TLS_CLIENT_KEY_EXCHANGE 16
62
+#define TLS_FINISHED 20
63
+
64
+/* TLS alert levels */
65
+#define TLS_ALERT_WARNING 1
66
+#define TLS_ALERT_FATAL 2
67
+
68
+/* TLS cipher specifications */
69
+#define TLS_RSA_WITH_NULL_MD5 0x0001
70
+#define TLS_RSA_WITH_NULL_SHA 0x0002
71
+#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002f
72
+#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
73
+
74
+/** TLS RX state machine state */
75
+enum tls_rx_state {
76
+	TLS_RX_HEADER = 0,
77
+	TLS_RX_DATA,
78
+};
79
+
80
+/** TLS TX state machine state */
81
+enum tls_tx_state {
82
+	TLS_TX_NONE = 0,
83
+	TLS_TX_CLIENT_HELLO,
84
+	TLS_TX_CLIENT_KEY_EXCHANGE,
85
+	TLS_TX_CHANGE_CIPHER,
86
+	TLS_TX_FINISHED,
87
+	TLS_TX_DATA
88
+};
89
+
90
+/** A TLS cipher specification */
91
+struct tls_cipherspec {
92
+	/** Public-key encryption algorithm */
93
+	struct crypto_algorithm *pubkey;
94
+	/** Bulk encryption cipher algorithm */
95
+	struct crypto_algorithm *cipher;
96
+	/** MAC digest algorithm */
97
+	struct crypto_algorithm *digest;
98
+	/** Key length */
99
+	size_t key_len;
100
+	/** Dynamically-allocated storage */
101
+	void *dynamic;
102
+	/** Public key encryption context */
103
+	void *pubkey_ctx;
104
+	/** Bulk encryption cipher context */
105
+	void *cipher_ctx;
106
+	/** Next bulk encryption cipher context (TX only) */
107
+	void *cipher_next_ctx;
108
+	/** MAC secret */
109
+	void *mac_secret;
110
+};
111
+
112
+/** A TLS session */
113
+struct tls_session {
114
+	/** Reference counter */
115
+	struct refcnt refcnt;
116
+
117
+	/** Plaintext stream */
118
+	struct xfer_filter_half plainstream;
119
+	/** Ciphertext stream */
120
+	struct xfer_filter_half cipherstream;
121
+
122
+	/** Current TX cipher specification */
123
+	struct tls_cipherspec tx_cipherspec;
124
+	/** Next TX cipher specification */
125
+	struct tls_cipherspec tx_cipherspec_pending;
126
+	/** Current RX cipher specification */
127
+	struct tls_cipherspec rx_cipherspec;
128
+	/** Next RX cipher specification */
129
+	struct tls_cipherspec rx_cipherspec_pending;
130
+	/** Premaster secret */
131
+	uint8_t pre_master_secret[48];
132
+	/** Master secret */
133
+	uint8_t master_secret[48];
134
+	/** Server random bytes */
135
+	uint8_t server_random[32];
136
+	/** Client random bytes */
137
+	uint8_t client_random[32];
138
+	/** MD5 context for handshake verification */
139
+	uint8_t handshake_md5_ctx[MD5_CTX_SIZE];
140
+	/** SHA1 context for handshake verification */
141
+	uint8_t handshake_sha1_ctx[SHA1_CTX_SIZE];
142
+
143
+	/** Hack: server RSA public key */
144
+	uint8_t *rsa_mod;
145
+	size_t rsa_mod_len;
146
+	uint8_t *rsa_pub_exp;
147
+	size_t rsa_pub_exp_len;
148
+
149
+	/** TX sequence number */
150
+	uint64_t tx_seq;
151
+	/** TX state */
152
+	enum tls_tx_state tx_state;
153
+	/** TX process */
154
+	struct process process;
155
+
156
+	/** RX sequence number */
157
+	uint64_t rx_seq;
158
+	/** RX state */
159
+	enum tls_rx_state rx_state;
160
+	/** Offset within current RX state */
161
+	size_t rx_rcvd;
162
+	/** Current received record header */
163
+	struct tls_header rx_header;
164
+	/** Current received raw data buffer */
165
+	void *rx_data;
166
+};
167
+
168
+extern int add_tls ( struct xfer_interface *xfer,
169
+		     struct xfer_interface **next );
11 170
 
12 171
 #endif /* _GPXE_TLS_H */

+ 6
- 0
src/include/usr/aoeboot.h View File

@@ -0,0 +1,6 @@
1
+#ifndef _USR_AOEBOOT_H
2
+#define _USR_AOEBOOT_H
3
+
4
+extern int aoeboot ( const char *root_path );
5
+
6
+#endif /* _USR_AOEBOOT_H */

+ 8
- 10
src/interface/pxe/pxe_preboot.c View File

@@ -69,10 +69,12 @@ PXENV_EXIT_t pxenv_unload_stack ( struct s_PXENV_UNLOAD_STACK *unload_stack ) {
69 69
 PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
70 70
 				     *get_cached_info ) {
71 71
 	struct dhcp_packet dhcppkt;
72
+	int ( * dhcp_packet_creator ) ( struct net_device *, int,
73
+					struct dhcp_option_block *, void *,
74
+					size_t, struct dhcp_packet * );
75
+	unsigned int msgtype;
72 76
 	void *data = NULL;
73 77
 	size_t len;
74
-	int msgtype;
75
-	struct dhcp_option_block *options;
76 78
 	userptr_t buffer;
77 79
 	int rc;
78 80
 
@@ -102,21 +104,17 @@ PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
102 104
 
103 105
 	/* Construct DHCP packet */
104 106
 	if ( get_cached_info->PacketType == PXENV_PACKET_TYPE_DHCP_DISCOVER ) {
107
+		dhcp_packet_creator = create_dhcp_request;
105 108
 		msgtype = DHCPDISCOVER;
106
-		options = &dhcp_request_options;
107 109
 	} else {
110
+		dhcp_packet_creator = create_dhcp_response;
108 111
 		msgtype = DHCPACK;
109
-		options = NULL;
110 112
 	}
111
-	if ( ( rc = create_dhcp_packet ( pxe_netdev, msgtype, data, len,
112
-					 &dhcppkt ) ) != 0 ) {
113
+	if ( ( rc = dhcp_packet_creator ( pxe_netdev, msgtype, NULL,
114
+					  data, len, &dhcppkt ) ) != 0 ) {
113 115
 		DBG ( " failed to build packet" );
114 116
 		goto err;
115 117
 	}
116
-	if ( ( rc = copy_dhcp_packet_options ( &dhcppkt, options ) ) != 0 ) {
117
-		DBG ( " failed to copy options" );
118
-		goto err;
119
-	}
120 118
 
121 119
 	/* Overwrite filename to work around Microsoft RIS bug */
122 120
 	if ( pxe_ris_filename ) {

+ 26
- 0
src/libgcc/__divdi3.c View File

@@ -0,0 +1,26 @@
1
+/*
2
+ * arch/i386/libgcc/__divdi3.c
3
+ */
4
+
5
+#include "libgcc.h"
6
+
7
+LIBGCC int64_t __divdi3(int64_t num, int64_t den)
8
+{
9
+  int minus = 0;
10
+  int64_t v;
11
+
12
+  if ( num < 0 ) {
13
+    num = -num;
14
+    minus = 1;
15
+  }
16
+  if ( den < 0 ) {
17
+    den = -den;
18
+    minus ^= 1;
19
+  }
20
+
21
+  v = __udivmoddi4(num, den, NULL);
22
+  if ( minus )
23
+    v = -v;
24
+
25
+  return v;
26
+}

+ 26
- 0
src/libgcc/__moddi3.c View File

@@ -0,0 +1,26 @@
1
+/*
2
+ * arch/i386/libgcc/__moddi3.c
3
+ */
4
+
5
+#include "libgcc.h"
6
+
7
+LIBGCC int64_t __moddi3(int64_t num, int64_t den)
8
+{
9
+  int minus = 0;
10
+  int64_t v;
11
+
12
+  if ( num < 0 ) {
13
+    num = -num;
14
+    minus = 1;
15
+  }
16
+  if ( den < 0 ) {
17
+    den = -den;
18
+    minus ^= 1;
19
+  }
20
+
21
+  (void) __udivmoddi4(num, den, (uint64_t *)&v);
22
+  if ( minus )
23
+    v = -v;
24
+
25
+  return v;
26
+}

+ 10
- 0
src/libgcc/__udivdi3.c View File

@@ -0,0 +1,10 @@
1
+/*
2
+ * arch/i386/libgcc/__divdi3.c
3
+ */
4
+
5
+#include "libgcc.h"
6
+
7
+LIBGCC uint64_t __udivdi3(uint64_t num, uint64_t den)
8
+{
9
+  return __udivmoddi4(num, den, NULL);
10
+}

+ 32
- 0
src/libgcc/__udivmoddi4.c View File

@@ -0,0 +1,32 @@
1
+#include "libgcc.h"
2
+
3
+LIBGCC uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p)
4
+{
5
+  uint64_t quot = 0, qbit = 1;
6
+
7
+  if ( den == 0 ) {
8
+    return 1/((unsigned)den); /* Intentional divide by zero, without
9
+				 triggering a compiler warning which
10
+				 would abort the build */
11
+  }
12
+
13
+  /* Left-justify denominator and count shift */
14
+  while ( (int64_t)den >= 0 ) {
15
+    den <<= 1;
16
+    qbit <<= 1;
17
+  }
18
+
19
+  while ( qbit ) {
20
+    if ( den <= num ) {
21
+      num -= den;
22
+      quot += qbit;
23
+    }
24
+    den >>= 1;
25
+    qbit >>= 1;
26
+  }
27
+
28
+  if ( rem_p )
29
+    *rem_p = num;
30
+
31
+  return quot;
32
+}

+ 13
- 0
src/libgcc/__umoddi3.c View File

@@ -0,0 +1,13 @@
1
+/*
2
+ * arch/i386/libgcc/__umoddi3.c
3
+ */
4
+
5
+#include "libgcc.h"
6
+
7
+LIBGCC uint64_t __umoddi3(uint64_t num, uint64_t den)
8
+{
9
+  uint64_t v;
10
+
11
+  (void) __udivmoddi4(num, den, &v);
12
+  return v;
13
+}

+ 26
- 0
src/libgcc/libgcc.h View File

@@ -0,0 +1,26 @@
1
+#ifndef _LIBGCC_H
2
+#define _LIBGCC_H
3
+
4
+#include <stdint.h>
5
+#include <stddef.h>
6
+
7
+/*
8
+ * It seems as though gcc expects its implicit arithmetic functions to
9
+ * be cdecl, even if -mrtd is specified.  This is somewhat
10
+ * inconsistent; for example, if -mregparm=3 is used then the implicit
11
+ * functions do become regparm(3).
12
+ *
13
+ * The implicit calls to memcpy() and memset() which gcc can generate
14
+ * do not seem to have this inconsistency; -mregparm and -mrtd affect
15
+ * them in the same way as any other function.
16
+ *
17
+ */
18
+#define LIBGCC __attribute__ (( cdecl ))
19
+
20
+extern LIBGCC uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem);
21
+extern LIBGCC uint64_t __udivdi3(uint64_t num, uint64_t den);
22
+extern LIBGCC uint64_t __umoddi3(uint64_t num, uint64_t den);
23
+extern LIBGCC int64_t __divdi3(int64_t num, int64_t den);
24
+extern LIBGCC int64_t __moddi3(int64_t num, int64_t den);
25
+
26
+#endif /* _LIBGCC_H */

src/core/gcc_implicit.c → src/libgcc/memcpy.c View File

@@ -1,6 +1,4 @@
1 1
 /** @file
2
- *
3
- * gcc implicit functions
4 2
  *
5 3
  * gcc sometimes likes to insert implicit calls to memcpy().
6 4
  * Unfortunately, there doesn't seem to be any way to prevent it from

+ 96
- 34
src/net/aoe.c View File

@@ -19,6 +19,7 @@
19 19
 #include <stddef.h>
20 20
 #include <string.h>
21 21
 #include <stdio.h>
22
+#include <stdlib.h>
22 23
 #include <errno.h>
23 24
 #include <assert.h>
24 25
 #include <byteswap.h>
@@ -29,7 +30,7 @@
29 30
 #include <gpxe/uaccess.h>
30 31
 #include <gpxe/ata.h>
31 32
 #include <gpxe/netdevice.h>
32
-#include <gpxe/async.h>
33
+#include <gpxe/process.h>
33 34
 #include <gpxe/aoe.h>
34 35
 
35 36
 /** @file
@@ -43,6 +44,14 @@ struct net_protocol aoe_protocol;
43 44
 /** List of all AoE sessions */
44 45
 static LIST_HEAD ( aoe_sessions );
45 46
 
47
+static void aoe_free ( struct refcnt *refcnt ) {
48
+	struct aoe_session *aoe =
49
+		container_of ( refcnt, struct aoe_session, refcnt );
50
+
51
+	netdev_put ( aoe->netdev );
52
+	free ( aoe );
53
+}
54
+
46 55
 /**
47 56
  * Mark current AoE command complete
48 57
  *
@@ -55,8 +64,8 @@ static void aoe_done ( struct aoe_session *aoe, int rc ) {
55 64
 	aoe->command->cb.cmd_stat = aoe->status;
56 65
 	aoe->command = NULL;
57 66
 
58
-	/* Mark async operation as complete */
59
-	async_done ( &aoe->async, rc );
67
+	/* Mark operation as complete */
68
+	aoe->rc = rc;
60 69
 }
61 70
 
62 71
 /**
@@ -265,46 +274,99 @@ struct net_protocol aoe_protocol __net_protocol = {
265 274
 	.rx = aoe_rx,
266 275
 };
267 276
 
268
-/**
269
- * Open AoE session
270
- *
271
- * @v aoe		AoE session
272
- */
273
-void aoe_open ( struct aoe_session *aoe ) {
274
-	memcpy ( aoe->target, ethernet_protocol.ll_broadcast,
275
-		 sizeof ( aoe->target ) );
276
-	aoe->tag = AOE_TAG_MAGIC;
277
-	aoe->timer.expired = aoe_timer_expired;
278
-	list_add ( &aoe->list, &aoe_sessions );
279
-}
280
-
281
-/**
282
- * Close AoE session
283
- *
284
- * @v aoe		AoE session
285
- */
286
-void aoe_close ( struct aoe_session *aoe ) {
287
-	list_del ( &aoe->list );
288
-}
289
-
290 277
 /**
291 278
  * Issue ATA command via an open AoE session
292 279
  *
293
- * @v aoe		AoE session
280
+ * @v ata		ATA device
294 281
  * @v command		ATA command
295
- * @v parent		Parent asynchronous operation
296 282
  * @ret rc		Return status code
297
- *
298
- * Only one command may be issued concurrently per session.  This call
299
- * is non-blocking; use async_wait() to wait for the command to
300
- * complete.
301 283
  */
302
-int aoe_issue ( struct aoe_session *aoe, struct ata_command *command,
303
-		struct async *parent ) {
284
+static int aoe_command ( struct ata_device *ata,
285
+			 struct ata_command *command ) {
286
+	struct aoe_session *aoe =
287
+		container_of ( ata->backend, struct aoe_session, refcnt );
288
+	int rc;
289
+
304 290
 	aoe->command = command;
305 291
 	aoe->status = 0;
306 292
 	aoe->command_offset = 0;
307 293
 	aoe_send_command ( aoe );
308
-	async_init ( &aoe->async, &default_async_operations, parent );
294
+
295
+	aoe->rc = -EINPROGRESS;
296
+	while ( aoe->rc == -EINPROGRESS )
297
+		step();
298
+	rc = aoe->rc;
299
+
300
+	return rc;
301
+}
302
+
303
+static int aoe_detached_command ( struct ata_device *ata __unused,
304
+				  struct ata_command *command __unused ) {
305
+	return -ENODEV;
306
+}
307
+
308
+void aoe_detach ( struct ata_device *ata ) {
309
+	struct aoe_session *aoe =
310
+		container_of ( ata->backend, struct aoe_session, refcnt );
311
+
312
+	stop_timer ( &aoe->timer );
313
+	ata->command = aoe_detached_command;
314
+	list_del ( &aoe->list );
315
+	ref_put ( ata->backend );
316
+	ata->backend = NULL;
317
+}
318
+
319
+static int aoe_parse_root_path ( struct aoe_session *aoe,
320
+				 const char *root_path ) {
321
+	char *ptr;
322
+
323
+	if ( strncmp ( root_path, "aoe:", 4 ) != 0 )
324
+		return -EINVAL;
325
+	ptr = ( ( char * ) root_path + 4 );
326
+
327
+	if ( *ptr++ != 'e' )
328
+		return -EINVAL;
329
+
330
+	aoe->major = strtoul ( ptr, &ptr, 10 );
331
+	if ( *ptr++ != '.' )
332
+		return -EINVAL;
333
+
334
+	aoe->minor = strtoul ( ptr, &ptr, 10 );
335
+	if ( *ptr )
336
+		return -EINVAL;
337
+
309 338
 	return 0;
310 339
 }
340
+
341
+int aoe_attach ( struct ata_device *ata, struct net_device *netdev,
342
+		 const char *root_path ) {
343
+	struct aoe_session *aoe;
344
+	int rc;
345
+
346
+	/* Allocate and initialise structure */
347
+	aoe = zalloc ( sizeof ( *aoe ) );
348
+	if ( ! aoe )
349
+		return -ENOMEM;
350
+	aoe->refcnt.free = aoe_free;
351
+	aoe->netdev = netdev_get ( netdev );
352
+	memcpy ( aoe->target, ethernet_protocol.ll_broadcast,
353
+		 sizeof ( aoe->target ) );
354
+	aoe->tag = AOE_TAG_MAGIC;
355
+	aoe->timer.expired = aoe_timer_expired;
356
+
357
+	/* Parse root path */
358
+	if ( ( rc = aoe_parse_root_path ( aoe, root_path ) ) != 0 )
359
+		goto err;
360
+
361
+	/* Attach parent interface, transfer reference to connection
362
+	 * list, and return
363
+	 */
364
+	ata->backend = ref_get ( &aoe->refcnt );
365
+	ata->command = aoe_command;
366
+	list_add ( &aoe->list, &aoe_sessions );
367
+	return 0;
368
+
369
+ err:
370
+	ref_put ( &aoe->refcnt );
371
+	return rc;
372
+}

+ 3
- 2
src/net/ndp.c View File

@@ -65,8 +65,9 @@ ndp_find_entry ( struct in6_addr *in6 ) {
65 65
  * @v ll_addr	Link-layer address
66 66
  * @v state	State of the entry - one of the NDP_STATE_XXX values
67 67
  */
68
-void add_ndp_entry ( struct net_device *netdev, struct in6_addr *in6,
69
-		     void *ll_addr, int state ) {
68
+static void 
69
+add_ndp_entry ( struct net_device *netdev, struct in6_addr *in6,
70
+		void *ll_addr, int state ) {
70 71
 	struct ndp_entry *ndp;
71 72
 	ndp = &ndp_table[next_new_ndp_entry++ % NUM_NDP_ENTRIES];
72 73
 

+ 26
- 19
src/net/tcp/http.c View File

@@ -40,7 +40,6 @@
40 40
 #include <gpxe/tcpip.h>
41 41
 #include <gpxe/process.h>
42 42
 #include <gpxe/linebuf.h>
43
-#include <gpxe/tls.h>
44 43
 #include <gpxe/http.h>
45 44
 
46 45
 /** HTTP receive state */
@@ -459,15 +458,21 @@ static struct xfer_interface_operations http_xfer_operations = {
459 458
 };
460 459
 
461 460
 /**
462
- * Initiate an HTTP connection
461
+ * Initiate an HTTP connection, with optional filter
463 462
  *
464 463
  * @v xfer		Data transfer interface
465 464
  * @v uri		Uniform Resource Identifier
465
+ * @v default_port	Default port number
466
+ * @v filter		Filter to apply to socket, or NULL
466 467
  * @ret rc		Return status code
467 468
  */
468
-int http_open ( struct xfer_interface *xfer, struct uri *uri ) {
469
+int http_open_filter ( struct xfer_interface *xfer, struct uri *uri,
470
+		       unsigned int default_port,
471
+		       int ( * filter ) ( struct xfer_interface *xfer,
472
+					  struct xfer_interface **next ) ) {
469 473
 	struct http_request *http;
470 474
 	struct sockaddr_tcpip server;
475
+	struct xfer_interface *socket;
471 476
 	int rc;
472 477
 
473 478
 	/* Sanity checks */
@@ -486,20 +491,17 @@ int http_open ( struct xfer_interface *xfer, struct uri *uri ) {
486 491
 
487 492
 	/* Open socket */
488 493
 	memset ( &server, 0, sizeof ( server ) );
489
-	server.st_port = htons ( uri_port ( http->uri, HTTP_PORT ) );
490
-	if ( ( rc = xfer_open_named_socket ( &http->socket, SOCK_STREAM,
494
+	server.st_port = htons ( uri_port ( http->uri, default_port ) );
495
+	socket = &http->socket;
496
+	if ( filter ) {
497
+		if ( ( rc = filter ( socket, &socket ) ) != 0 )
498
+			goto err;
499
+	}
500
+	if ( ( rc = xfer_open_named_socket ( socket, SOCK_STREAM,
491 501
 					     ( struct sockaddr * ) &server,
492 502
 					     uri->host, NULL ) ) != 0 )
493 503
 		goto err;
494 504
 
495
-#if 0
496
-	if ( strcmp ( http->uri->scheme, "https" ) == 0 ) {
497
-		st->st_port = htons ( uri_port ( http->uri, HTTPS_PORT ) );
498
-		if ( ( rc = add_tls ( &http->stream ) ) != 0 )
499
-			goto err;
500
-	}
501
-#endif
502
-
503 505
 	/* Attach to parent interface, mortalise self, and return */
504 506
 	xfer_plug_plug ( &http->xfer, xfer );
505 507
 	ref_put ( &http->refcnt );
@@ -513,14 +515,19 @@ int http_open ( struct xfer_interface *xfer, struct uri *uri ) {
513 515
 	return rc;
514 516
 }
515 517
 
518
+/**
519
+ * Initiate an HTTP connection
520
+ *
521
+ * @v xfer		Data transfer interface
522
+ * @v uri		Uniform Resource Identifier
523
+ * @ret rc		Return status code
524
+ */
525
+static int http_open ( struct xfer_interface *xfer, struct uri *uri ) {
526
+	return http_open_filter ( xfer, uri, HTTP_PORT, NULL );
527
+}
528
+
516 529
 /** HTTP URI opener */
517 530
 struct uri_opener http_uri_opener __uri_opener = {
518 531
 	.scheme	= "http",
519 532
 	.open	= http_open,
520 533
 };
521
-
522
-/** HTTPS URI opener */
523
-struct uri_opener https_uri_opener __uri_opener = {
524
-	.scheme	= "https",
525
-	.open	= http_open,
526
-};

src/drivers/ata/aoedev.c → src/net/tcp/https.c View File

@@ -1,5 +1,5 @@
1 1
 /*
2
- * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 3
  *
4 4
  * This program is free software; you can redistribute it and/or
5 5
  * modify it under the terms of the GNU General Public License as
@@ -16,40 +16,31 @@
16 16
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 17
  */
18 18
 
19
-#include <stddef.h>
20
-#include <gpxe/async.h>
21
-#include <gpxe/aoe.h>
22
-
23
-/** @file
19
+/**
20
+ * @file
24 21
  *
25
- * AoE ATA device
22
+ * Secure Hyper Text Transfer Protocol (HTTPS)
26 23
  *
27 24
  */
28 25
 
26
+#include <stddef.h>
27
+#include <gpxe/open.h>
28
+#include <gpxe/tls.h>
29
+#include <gpxe/http.h>
30
+
29 31
 /**
30
- * Issue ATA command via AoE device
32
+ * Initiate an HTTPS connection
31 33
  *
32
- * @v ata		ATA device
33
- * @v command		ATA command
34
+ * @v xfer		Data transfer interface
35
+ * @v uri		Uniform Resource Identifier
34 36
  * @ret rc		Return status code
35 37
  */
36
-static int aoe_command ( struct ata_device *ata,
37
-			 struct ata_command *command ) {
38
-	struct aoe_device *aoedev
39
-		= container_of ( ata, struct aoe_device, ata );
40
-	struct async async;
41
-
42
-	return async_block ( &async, aoe_issue ( &aoedev->aoe, command,
43
-						 &async ) );
38
+static int https_open ( struct xfer_interface *xfer, struct uri *uri ) {
39
+	return http_open_filter ( xfer, uri, HTTPS_PORT, add_tls );
44 40
 }
45 41
 
46
-/**
47
- * Initialise AoE device
48
- *
49
- * @v aoedev		AoE device
50
- */
51
-int init_aoedev ( struct aoe_device *aoedev ) {
52
-	aoedev->ata.command = aoe_command;
53
-	aoe_open ( &aoedev->aoe );
54
-	return init_atadev ( &aoedev->ata );
55
-}
42
+/** HTTPS URI opener */
43
+struct uri_opener https_uri_opener __uri_opener = {
44
+	.scheme	= "https",
45
+	.open	= https_open,
46
+};

+ 98
- 18
src/net/tcp/iscsi.c View File

@@ -41,16 +41,16 @@
41 41
  */
42 42
 
43 43
 /** iSCSI initiator name (explicitly specified) */
44
-char *iscsi_initiator_iqn;
44
+static char *iscsi_explicit_initiator_iqn;
45 45
 
46 46
 /** Default iSCSI initiator name (constructed from hostname) */
47
-char *iscsi_default_initiator_iqn;
47
+static char *iscsi_default_initiator_iqn;
48 48
 
49 49
 /** iSCSI username */
50
-char *iscsi_username;
50
+static char *iscsi_username;
51 51
 
52 52
 /** iSCSI password */
53
-char *iscsi_password;
53
+static char *iscsi_password;
54 54
 
55 55
 static void iscsi_start_tx ( struct iscsi_session *iscsi );
56 56
 static void iscsi_start_login ( struct iscsi_session *iscsi );
@@ -78,6 +78,8 @@ static void iscsi_free ( struct refcnt *refcnt ) {
78 78
 
79 79
 	free ( iscsi->target_address );
80 80
 	free ( iscsi->target_iqn );
81
+	free ( iscsi->username );
82
+	free ( iscsi->password );
81 83
 	chap_finish ( &iscsi->chap );
82 84
 	iscsi_rx_buffered_data_done ( iscsi );
83 85
 	free ( iscsi );
@@ -436,22 +438,16 @@ static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
436 438
  */
437 439
 static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
438 440
 					       void *data, size_t len ) {
439
-	char *initiator_iqn;
440 441
 	unsigned int used = 0;
441 442
 	unsigned int i;
442 443
 
443 444
 	if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) {
444
-		initiator_iqn = iscsi_initiator_iqn;
445
-		if ( ! initiator_iqn )
446
-			initiator_iqn = iscsi_default_initiator_iqn;
447
-		if ( ! initiator_iqn )
448
-			initiator_iqn = "iqn.2000-09.org.etherboot:UNKNOWN";
449 445
 		used += ssnprintf ( data + used, len - used,
450 446
 				    "InitiatorName=%s%c"
451 447
 				    "TargetName=%s%c"
452 448
 				    "SessionType=Normal%c"
453 449
 				    "AuthMethod=CHAP,None%c",
454
-				    initiator_iqn, 0,
450
+				    iscsi_initiator_iqn(), 0,
455 451
 				    iscsi->target_iqn, 0, 0, 0 );
456 452
 	}
457 453
 
@@ -460,10 +456,10 @@ static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
460 456
 	}
461 457
 	
462 458
 	if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) &&
463
-	     iscsi_username ) {
459
+	     iscsi->username ) {
464 460
 		used += ssnprintf ( data + used, len - used,
465 461
 				    "CHAP_N=%s%cCHAP_R=0x",
466
-				    iscsi_username, 0 );
462
+				    iscsi->username, 0 );
467 463
 		for ( i = 0 ; i < iscsi->chap.response_len ; i++ ) {
468 464
 			used += ssnprintf ( data + used, len - used, "%02x",
469 465
 					    iscsi->chap.response[i] );
@@ -647,9 +643,9 @@ static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
647 643
 	 * challenge.
648 644
 	 */
649 645
 	chap_set_identifier ( &iscsi->chap, identifier );
650
-	if ( iscsi_password ) {
651
-		chap_update ( &iscsi->chap, iscsi_password,
652
-			      strlen ( iscsi_password ) );
646
+	if ( iscsi->password ) {
647
+		chap_update ( &iscsi->chap, iscsi->password,
648
+			      strlen ( iscsi->password ) );
653 649
 	}
654 650
 
655 651
 	return 0;
@@ -1279,10 +1275,43 @@ static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) {
1279 1275
 	}
1280 1276
 }
1281 1277
 
1278
+/**
1279
+ * Handle redirection event
1280
+ *
1281
+ * @v socket		Transport layer interface
1282
+ * @v type		Location type
1283
+ * @v args		Remaining arguments depend upon location type
1284
+ * @ret rc		Return status code
1285
+ */
1286
+static int iscsi_vredirect ( struct xfer_interface *socket, int type,
1287
+			     va_list args ) {
1288
+	struct iscsi_session *iscsi =
1289
+		container_of ( socket, struct iscsi_session, socket );
1290
+	va_list tmp;
1291
+	struct sockaddr *peer;
1292
+
1293
+	/* Intercept redirects to a LOCATION_SOCKET and record the IP
1294
+	 * address for the iBFT.  This is a bit of a hack, but avoids
1295
+	 * inventing an ioctl()-style call to retrieve the socket
1296
+	 * address from a data-xfer interface.
1297
+	 */
1298
+	if ( type == LOCATION_SOCKET ) {
1299
+		va_copy ( tmp, args );
1300
+		( void ) va_arg ( tmp, int ); /* Discard "semantics" */
1301
+		peer = va_arg ( tmp, struct sockaddr * );
1302
+		memcpy ( &iscsi->target_sockaddr, peer,
1303
+			 sizeof ( iscsi->target_sockaddr ) );
1304
+		va_end ( tmp );
1305
+	}
1306
+
1307
+	return xfer_vopen ( socket, type, args );
1308
+}
1309
+			     
1310
+
1282 1311
 /** iSCSI socket operations */
1283 1312
 static struct xfer_interface_operations iscsi_socket_operations = {
1284 1313
 	.close		= iscsi_socket_close,
1285
-	.vredirect	= xfer_vopen,
1314
+	.vredirect	= iscsi_vredirect,
1286 1315
 	.seek		= ignore_xfer_seek,
1287 1316
 	.window		= unlimited_xfer_window,
1288 1317
 	.alloc_iob	= default_xfer_alloc_iob,
@@ -1460,6 +1489,32 @@ static int iscsi_parse_root_path ( struct iscsi_session *iscsi,
1460 1489
 	return 0;
1461 1490
 }
1462 1491
 
1492
+/**
1493
+ * Set iSCSI authentication details
1494
+ *
1495
+ * @v iscsi		iSCSI session
1496
+ * @v username		Username, if any
1497
+ * @v password		Password, if any
1498
+ * @ret rc		Return status code
1499
+ */
1500
+static int iscsi_set_auth ( struct iscsi_session *iscsi,
1501
+			    const char *username, const char *password ) {
1502
+
1503
+	if ( username ) {
1504
+		iscsi->username = strdup ( username );
1505
+		if ( ! iscsi->username )
1506
+			return -ENOMEM;
1507
+	}
1508
+
1509
+	if ( password ) {
1510
+		iscsi->password = strdup ( password );
1511
+		if ( ! iscsi->password )
1512
+			return -ENOMEM;
1513
+	}
1514
+
1515
+	return 0;
1516
+}
1517
+
1463 1518
 /**
1464 1519
  * Attach iSCSI interface
1465 1520
  *
@@ -1482,6 +1537,10 @@ int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) {
1482 1537
 	/* Parse root path */
1483 1538
 	if ( ( rc = iscsi_parse_root_path ( iscsi, root_path ) ) != 0 )
1484 1539
 		goto err;
1540
+	/* Set fields not specified by root path */
1541
+	if ( ( rc = iscsi_set_auth ( iscsi, iscsi_username,
1542
+				     iscsi_password ) ) != 0 )
1543
+		goto err;
1485 1544
 
1486 1545
 	/* Sanity checks */
1487 1546
 	if ( ! iscsi->target_address ) {
@@ -1533,7 +1592,7 @@ static int apply_dhcp_iscsi_string ( unsigned int tag,
1533 1592
 	/* Identify string and prefix */
1534 1593
 	switch ( tag ) {
1535 1594
 	case DHCP_ISCSI_INITIATOR_IQN:
1536
-		string = &iscsi_initiator_iqn;
1595
+		string = &iscsi_explicit_initiator_iqn;
1537 1596
 		break;
1538 1597
 	case DHCP_EB_USERNAME:
1539 1598
 		string = &iscsi_username;
@@ -1584,3 +1643,24 @@ struct dhcp_option_applicator dhcp_iscsi_applicators[] __dhcp_applicator = {
1584 1643
 		.apply = apply_dhcp_iscsi_string,
1585 1644
 	},
1586 1645
 };
1646
+
1647
+/****************************************************************************
1648
+ *
1649
+ * Initiator name
1650
+ *
1651
+ */
1652
+
1653
+/**
1654
+ * Get iSCSI initiator IQN
1655
+ *
1656
+ * @v iscsi		iSCSI session
1657
+ * @ret rc		Return status code
1658
+ */
1659
+const char * iscsi_initiator_iqn ( void ) {
1660
+
1661
+	if ( iscsi_explicit_initiator_iqn )
1662
+		return iscsi_explicit_initiator_iqn;
1663
+	if ( iscsi_default_initiator_iqn )
1664
+		return iscsi_default_initiator_iqn;
1665
+	return "iqn.2000-09.org.etherboot:UNKNOWN";
1666
+}

+ 1733
- 0
src/net/tls.c
File diff suppressed because it is too large
View File


+ 129
- 37
src/net/udp/dhcp.c View File

@@ -24,6 +24,7 @@
24 24
 #include <byteswap.h>
25 25
 #include <gpxe/if_ether.h>
26 26
 #include <gpxe/netdevice.h>
27
+#include <gpxe/device.h>
27 28
 #include <gpxe/xfer.h>
28 29
 #include <gpxe/open.h>
29 30
 #include <gpxe/job.h>
@@ -108,7 +109,7 @@ static uint32_t dhcp_xid ( struct net_device *netdev ) {
108 109
 }
109 110
 
110 111
 /** Options common to all DHCP requests */
111
-struct dhcp_option_block dhcp_request_options = {
112
+static struct dhcp_option_block dhcp_request_options = {
112 113
 	.data = dhcp_request_options_data,
113 114
 	.max_len = sizeof ( dhcp_request_options_data ),
114 115
 	.len = sizeof ( dhcp_request_options_data ),
@@ -270,8 +271,8 @@ static int copy_dhcp_packet_encap_options ( struct dhcp_packet *dhcppkt,
270 271
  * @c options may specify a single options block, or be left as NULL
271 272
  * in order to copy options from all registered options blocks.
272 273
  */
273
-int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
274
-			       struct dhcp_option_block *options ) {
274
+static int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
275
+				      struct dhcp_option_block *options ) {
275 276
 	return copy_dhcp_packet_encap_options ( dhcppkt, options, 0 );
276 277
 }
277 278
 
@@ -289,9 +290,10 @@ int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
289 290
  * dhcp_packet structure that can be passed to
290 291
  * set_dhcp_packet_option() or copy_dhcp_packet_options().
291 292
  */
292
-int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype,
293
-			 void *data, size_t max_len,
294
-			 struct dhcp_packet *dhcppkt ) {
293
+static int create_dhcp_packet ( struct net_device *netdev,
294
+				unsigned int msgtype,
295
+				void *data, size_t max_len,
296
+				struct dhcp_packet *dhcppkt ) {
295 297
 	struct dhcphdr *dhcphdr = data;
296 298
 	int rc;
297 299
 
@@ -473,6 +475,121 @@ static struct dhcp_option_block * dhcp_parse ( const struct dhcphdr *dhcphdr,
473 475
 	return options;
474 476
 }
475 477
 
478
+/****************************************************************************
479
+ *
480
+ * Whole-packet construction
481
+ *
482
+ */
483
+
484
+/** DHCP network device descriptor */
485
+struct dhcp_netdev_desc {
486
+	/** Bus type ID */
487
+	uint8_t type;
488
+	/** Vendor ID */
489
+	uint16_t vendor;
490
+	/** Device ID */
491
+	uint16_t device;
492
+} __attribute__ (( packed ));
493
+
494
+/**
495
+ * Create DHCP request
496
+ *
497
+ * @v netdev		Network device
498
+ * @v msgtype		DHCP message type
499
+ * @v options		DHCP server response options, or NULL
500
+ * @v data		Buffer for DHCP packet
501
+ * @v max_len		Size of DHCP packet buffer
502
+ * @v dhcppkt		DHCP packet structure to fill in
503
+ * @ret rc		Return status code
504
+ */
505
+int create_dhcp_request ( struct net_device *netdev, int msgtype,
506
+			  struct dhcp_option_block *options,
507
+			  void *data, size_t max_len,
508
+			  struct dhcp_packet *dhcppkt ) {
509
+	struct device_description *desc = &netdev->dev->desc;
510
+	struct dhcp_netdev_desc dhcp_desc;
511
+	int rc;
512
+
513
+	/* Create DHCP packet */
514
+	if ( ( rc = create_dhcp_packet ( netdev, msgtype, data, max_len,
515
+					 dhcppkt ) ) != 0 ) {
516
+		DBG ( "DHCP could not create DHCP packet: %s\n",
517
+		      strerror ( rc ) );
518
+		return rc;
519
+	}
520
+
521
+	/* Copy in options common to all requests */
522
+	if ( ( rc = copy_dhcp_packet_options ( dhcppkt,
523
+					       &dhcp_request_options )) !=0 ){
524
+		DBG ( "DHCP could not set common DHCP options: %s\n",
525
+		      strerror ( rc ) );
526
+		return rc;
527
+	}
528
+
529
+	/* Copy any required options from previous server repsonse */
530
+	if ( options ) {
531
+		if ( ( rc = copy_dhcp_packet_option ( dhcppkt, options,
532
+					  DHCP_SERVER_IDENTIFIER,
533
+					  DHCP_SERVER_IDENTIFIER ) ) != 0 ) {
534
+			DBG ( "DHCP could not set server identifier "
535
+			      "option: %s\n", strerror ( rc ) );
536
+			return rc;
537
+		}
538
+		if ( ( rc = copy_dhcp_packet_option ( dhcppkt, options,
539
+					  DHCP_EB_YIADDR,
540
+					  DHCP_REQUESTED_ADDRESS ) ) != 0 ) {
541
+			DBG ( "DHCP could not set requested address "
542
+			      "option: %s\n", strerror ( rc ) );
543
+			return rc;
544
+		}
545
+	}
546
+
547
+	/* Add options to identify the network device */
548
+	dhcp_desc.type = desc->bus_type;
549
+	dhcp_desc.vendor = htons ( desc->vendor );
550
+	dhcp_desc.device = htons ( desc->device );
551
+	if ( ( rc = set_dhcp_packet_option ( dhcppkt, DHCP_EB_BUS_ID,
552
+					     &dhcp_desc,
553
+					     sizeof ( dhcp_desc ) ) ) != 0 ) {
554
+		DBG ( "DHCP could not set bus ID option: %s\n",
555
+		      strerror ( rc ) );
556
+		return rc;
557
+	}
558
+
559
+	return 0;
560
+}
561
+
562
+/**
563
+ * Create DHCP response
564
+ *
565
+ * @v netdev		Network device
566
+ * @v msgtype		DHCP message type
567
+ * @v options		DHCP options, or NULL
568
+ * @v data		Buffer for DHCP packet
569
+ * @v max_len		Size of DHCP packet buffer
570
+ * @v dhcppkt		DHCP packet structure to fill in
571
+ * @ret rc		Return status code
572
+ */
573
+int create_dhcp_response ( struct net_device *netdev, int msgtype,
574
+			   struct dhcp_option_block *options,
575
+			   void *data, size_t max_len,
576
+			   struct dhcp_packet *dhcppkt ) {
577
+	int rc;
578
+
579
+	/* Create packet and copy in options */
580
+	if ( ( rc = create_dhcp_packet ( netdev, msgtype, data, max_len,
581
+					 dhcppkt ) ) != 0 ) {
582
+		DBG ( " failed to build packet" );
583
+		return rc;
584
+	}
585
+	if ( ( rc = copy_dhcp_packet_options ( dhcppkt, options ) ) != 0 ) {
586
+		DBG ( " failed to copy options" );
587
+		return rc;
588
+	}
589
+
590
+	return 0;
591
+}
592
+
476 593
 /****************************************************************************
477 594
  *
478 595
  * DHCP to UDP interface
@@ -556,8 +673,8 @@ static int dhcp_send_request ( struct dhcp_session *dhcp ) {
556 673
 	struct xfer_metadata meta = {
557 674
 		.netdev = dhcp->netdev,
558 675
 	};
559
-	struct dhcp_packet dhcppkt;
560 676
 	struct io_buffer *iobuf;
677
+	struct dhcp_packet dhcppkt;
561 678
 	int rc;
562 679
 	
563 680
 	DBGC ( dhcp, "DHCP %p transmitting %s\n",
@@ -577,40 +694,15 @@ static int dhcp_send_request ( struct dhcp_session *dhcp ) {
577 694
 		return -ENOMEM;
578 695
 
579 696
 	/* Create DHCP packet in temporary buffer */
580
-	if ( ( rc = create_dhcp_packet ( dhcp->netdev, dhcp->state,
581
-					 iobuf->data, iob_tailroom ( iobuf ),
582
-					 &dhcppkt ) ) != 0 ) {
583
-		DBGC ( dhcp, "DHCP %p could not create DHCP packet: %s\n",
697
+	if ( ( rc = create_dhcp_request ( dhcp->netdev, dhcp->state,
698
+					  dhcp->options, iobuf->data,
699
+					  iob_tailroom ( iobuf ),
700
+					  &dhcppkt ) ) != 0 ) {
701
+		DBGC ( dhcp, "DHCP %p could not construct DHCP request: %s\n",
584 702
 		       dhcp, strerror ( rc ) );
585 703
 		goto done;
586 704
 	}
587 705
 
588
-	/* Copy in options common to all requests */
589
-	if ( ( rc = copy_dhcp_packet_options ( &dhcppkt,
590
-					       &dhcp_request_options ) ) != 0){
591
-		DBGC ( dhcp, "DHCP %p could not set common DHCP options: %s\n",
592
-		       dhcp, strerror ( rc ) );
593
-		goto done;
594
-	}
595
-
596
-	/* Copy any required options from previous server repsonse */
597
-	if ( dhcp->options ) {
598
-		if ( ( rc = copy_dhcp_packet_option ( &dhcppkt, dhcp->options,
599
-					    DHCP_SERVER_IDENTIFIER,
600
-					    DHCP_SERVER_IDENTIFIER ) ) != 0 ) {
601
-			DBGC ( dhcp, "DHCP %p could not set server identifier "
602
-			       "option: %s\n", dhcp, strerror ( rc ) );
603
-			goto done;
604
-		}
605
-		if ( ( rc = copy_dhcp_packet_option ( &dhcppkt, dhcp->options,
606
-					    DHCP_EB_YIADDR,
607
-					    DHCP_REQUESTED_ADDRESS ) ) != 0 ) {
608
-			DBGC ( dhcp, "DHCP %p could not set requested address "
609
-			       "option: %s\n", dhcp, strerror ( rc ) );
610
-			goto done;
611
-		}
612
-	}
613
-
614 706
 	/* Transmit the packet */
615 707
 	iob_put ( iobuf, dhcppkt.len );
616 708
 	rc = xfer_deliver_iob_meta ( &dhcp->xfer, iobuf, &meta );

+ 0
- 71
src/tests/aoeboot.c View File

@@ -1,71 +0,0 @@
1
-#include <stdint.h>
2
-#include <stdlib.h>
3
-#include <stdio.h>
4
-#include <errno.h>
5
-#include <console.h>
6
-#include <gpxe/netdevice.h>
7
-#include <gpxe/aoe.h>
8
-#include <int13.h>
9
-
10
-static struct aoe_device test_aoedev = {
11
-	.aoe = {
12
-		.major = 0,
13
-		.minor = 0,
14
-	},
15
-};
16
-
17
-static int aoe_parse ( const char *aoename, struct aoe_session *aoe ) {
18
-	char *ptr = ( ( char * ) aoename );
19
-
20
-	if ( *ptr++ != 'e' )
21
-		return -EINVAL;
22
-
23
-	aoe->major = strtoul ( ptr, &ptr, 10 );
24
-	if ( *ptr++ != '.' )
25
-		return -EINVAL;
26
-
27
-	aoe->minor = strtoul ( ptr, &ptr, 10 );
28
-	if ( *ptr )
29
-		return -EINVAL;
30
-
31
-	return 0;
32
-}
33
-
34
-int test_aoeboot ( struct net_device *netdev, const char *aoename,
35
-		   unsigned int drivenum ) {
36
-	struct int13_drive drive;
37
-	int rc;
38
-
39
-	printf ( "Attempting to boot from AoE device %s via %s\n",
40
-		 aoename, netdev->name );
41
-
42
-	if ( ( rc = aoe_parse ( aoename, &test_aoedev.aoe ) ) != 0 ) {
43
-		printf ( "Invalid AoE device name \"%s\"\n", aoename );
44
-		return rc;
45
-	}
46
-
47
-	printf ( "Initialising AoE device e%d.%d\n",
48
-		 test_aoedev.aoe.major, test_aoedev.aoe.minor );
49
-	test_aoedev.aoe.netdev = netdev;
50
-	if ( ( rc = init_aoedev ( &test_aoedev ) ) != 0 ) {
51
-		printf ( "Could not reach AoE device e%d.%d\n",
52
-			 test_aoedev.aoe.major, test_aoedev.aoe.minor );
53
-		return rc;
54
-	}
55
-
56
-	memset ( &drive, 0, sizeof ( drive ) );
57
-	drive.drive = drivenum;
58
-	drive.blockdev = &test_aoedev.ata.blockdev;
59
-	register_int13_drive ( &drive );
60
-	printf ( "Registered AoE device e%d.%d as BIOS drive %#02x\n",
61
-		 test_aoedev.aoe.major, test_aoedev.aoe.minor, drive.drive );
62
-
63
-	printf ( "Booting from BIOS drive %#02x\n", drive.drive );
64
-	rc = int13_boot ( drive.drive );
65
-	printf ( "Boot failed\n" );
66
-
67
-	printf ( "Unregistering BIOS drive %#02x\n", drive.drive );
68
-	unregister_int13_drive ( &drive );
69
-
70
-	return rc;
71
-}

+ 104
- 0
src/usr/aoeboot.c View File

@@ -0,0 +1,104 @@
1
+#include <stdint.h>
2
+#include <string.h>
3
+#include <stdio.h>
4
+#include <byteswap.h>
5
+#include <gpxe/aoe.h>
6
+#include <gpxe/ata.h>
7
+#include <gpxe/netdevice.h>
8
+#include <gpxe/dhcp.h>
9
+#include <gpxe/abft.h>
10
+#include <int13.h>
11
+#include <usr/aoeboot.h>
12
+
13
+/**
14
+ * AoE boot information block
15
+ *
16
+ * Must be placed at 40:f0.
17
+ *
18
+ * This structure needs to be replaced by an ACPI table or similar.
19
+ */
20
+struct aoe_boot_info {
21
+	/** Must be 0x01 */
22
+	uint8_t one;
23
+	/** Client MAC address */
24
+	uint8_t client[ETH_ALEN];
25
+	/** Server MAC address */
26
+	uint8_t server[ETH_ALEN];
27
+	/** Shelf number */
28
+	uint16_t shelf;
29
+	/** Slot number */
30
+	uint8_t slot;
31
+} __attribute__ (( packed ));
32
+
33
+/**
34
+ * Guess boot network device
35
+ *
36
+ * @ret netdev		Boot network device
37
+ */
38
+static struct net_device * guess_boot_netdev ( void ) {
39
+	struct net_device *boot_netdev;
40
+
41
+	/* Just use the first network device */
42
+	for_each_netdev ( boot_netdev ) {
43
+		return boot_netdev;
44
+	}
45
+
46
+	return NULL;
47
+}
48
+
49
+int aoeboot ( const char *root_path ) {
50
+	struct ata_device ata;
51
+	struct int13_drive drive;
52
+	int rc;
53
+
54
+	memset ( &ata, 0, sizeof ( ata ) );
55
+	memset ( &drive, 0, sizeof ( drive ) );
56
+
57
+	printf ( "AoE booting from %s\n", root_path );
58
+
59
+	/* FIXME: ugly, ugly hack */
60
+	struct net_device *netdev = guess_boot_netdev();
61
+
62
+	if ( ( rc = aoe_attach ( &ata, netdev, root_path ) ) != 0 ) {
63
+		printf ( "Could not attach AoE device: %s\n",
64
+			 strerror ( rc ) );
65
+		goto error_attach;
66
+	}
67
+	if ( ( rc = init_atadev ( &ata ) ) != 0 ) {
68
+		printf ( "Could not initialise AoE device: %s\n",
69
+			 strerror ( rc ) );
70
+		goto error_init;
71
+	}
72
+
73
+	/* FIXME: ugly, ugly hack */
74
+	struct aoe_session *aoe =
75
+		container_of ( ata.backend, struct aoe_session, refcnt );
76
+	struct aoe_boot_info boot_info;
77
+	boot_info.one = 0x01;
78
+	memcpy ( boot_info.client, netdev->ll_addr,
79
+		 sizeof ( boot_info.client ) );
80
+	memcpy ( boot_info.server, aoe->target,
81
+		 sizeof ( boot_info.server ) );
82
+	boot_info.shelf = htons ( aoe->major );
83
+	boot_info.slot = aoe->minor;
84
+	copy_to_real ( 0x40, 0xf0, &boot_info, sizeof ( boot_info ) );
85
+
86
+	abft_fill_data ( aoe );
87
+
88
+	drive.drive = find_global_dhcp_num_option ( DHCP_EB_BIOS_DRIVE );
89
+	drive.blockdev = &ata.blockdev;
90
+
91
+	register_int13_drive ( &drive );
92
+	printf ( "Registered as BIOS drive %#02x\n", drive.drive );
93
+	printf ( "Booting from BIOS drive %#02x\n", drive.drive );
94
+	rc = int13_boot ( drive.drive );
95
+	printf ( "Boot failed\n" );
96
+
97
+	printf ( "Unregistering BIOS drive %#02x\n", drive.drive );
98
+	unregister_int13_drive ( &drive );
99
+
100
+ error_init:
101
+	aoe_detach ( &ata );
102
+ error_attach:
103
+	return rc;
104
+}

+ 8
- 5
src/usr/autoboot.c View File

@@ -27,6 +27,7 @@
27 27
 #include <usr/dhcpmgmt.h>
28 28
 #include <usr/imgmgmt.h>
29 29
 #include <usr/iscsiboot.h>
30
+#include <usr/aoeboot.h>
30 31
 #include <usr/autoboot.h>
31 32
 
32 33
 /** @file
@@ -88,13 +89,15 @@ static int boot_filename ( const char *filename ) {
88 89
  * @ret rc		Return status code
89 90
  */
90 91
 static int boot_root_path ( const char *root_path ) {
91
-	int rc;
92 92
 
93 93
 	/* Quick hack */
94
-	if ( ( rc = iscsiboot ( root_path ) ) != 0 )
95
-		return rc;
94
+	if ( strncmp ( root_path, "iscsi:", 6 ) == 0 ) {
95
+		return iscsiboot ( root_path );
96
+	} else if ( strncmp ( root_path, "aoe:", 4 ) == 0 ) {
97
+		return aoeboot ( root_path );
98
+	}
96 99
 
97
-	return 0;
100
+	return -ENOTSUP;
98 101
 }
99 102
 
100 103
 /**
@@ -103,7 +106,7 @@ static int boot_root_path ( const char *root_path ) {
103 106
  * @v netdev		Network device
104 107
  * @ret rc		Return status code
105 108
  */
106
-int netboot ( struct net_device *netdev ) {
109
+static int netboot ( struct net_device *netdev ) {
107 110
 	char buf[256];
108 111
 	int rc;
109 112
 

+ 24
- 0
src/usr/iscsiboot.c View File

@@ -3,9 +3,27 @@
3 3
 #include <stdio.h>
4 4
 #include <gpxe/iscsi.h>
5 5
 #include <gpxe/dhcp.h>
6
+#include <gpxe/netdevice.h>
7
+#include <gpxe/ibft.h>
6 8
 #include <int13.h>
7 9
 #include <usr/iscsiboot.h>
8 10
 
11
+/**
12
+ * Guess boot network device
13
+ *
14
+ * @ret netdev		Boot network device
15
+ */
16
+static struct net_device * guess_boot_netdev ( void ) {
17
+	struct net_device *boot_netdev;
18
+
19
+	/* Just use the first network device */
20
+	for_each_netdev ( boot_netdev ) {
21
+		return boot_netdev;
22
+	}
23
+
24
+	return NULL;
25
+}
26
+
9 27
 int iscsiboot ( const char *root_path ) {
10 28
 	struct scsi_device scsi;
11 29
 	struct int13_drive drive;
@@ -30,6 +48,12 @@ int iscsiboot ( const char *root_path ) {
30 48
 	drive.drive = find_global_dhcp_num_option ( DHCP_EB_BIOS_DRIVE );
31 49
 	drive.blockdev = &scsi.blockdev;
32 50
 
51
+	/* FIXME: ugly, ugly hack */
52
+	struct net_device *netdev = guess_boot_netdev();
53
+	struct iscsi_session *iscsi =
54
+		container_of ( scsi.backend, struct iscsi_session, refcnt );
55
+	ibft_fill_data ( netdev, iscsi );
56
+
33 57
 	register_int13_drive ( &drive );
34 58
 	printf ( "Registered as BIOS drive %#02x\n", drive.drive );
35 59
 	printf ( "Booting from BIOS drive %#02x\n", drive.drive );

Loading…
Cancel
Save