iPXE
rbg.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  *
00023  * Alternatively, you may distribute this code in source or binary
00024  * form, with or without modification, provided that the following
00025  * conditions are met:
00026  *
00027  *  1. Redistributions of source code must retain the above copyright
00028  *     notice, this list of conditions and the above disclaimer.
00029  *
00030  *  2. Redistributions in binary form must reproduce the above
00031  *     copyright notice, this list of conditions and the above
00032  *     disclaimer in the documentation and/or other materials provided
00033  *     with the distribution.
00034  */
00035 
00036 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00037 
00038 /** @file
00039  *
00040  * RBG mechanism
00041  *
00042  * This mechanism is designed to comply with ANS X9.82 Part 4 (April
00043  * 2011 Draft) Section 10.  This standard is unfortunately not freely
00044  * available.
00045  *
00046  * The chosen RBG design is that of a DRBG with a live entropy source
00047  * with no conditioning function.  Only a single security strength is
00048  * supported.  No seedfile is used since there may be no non-volatile
00049  * storage available.  The system UUID is used as the personalisation
00050  * string.
00051  */
00052 
00053 #include <stdint.h>
00054 #include <string.h>
00055 #include <ipxe/init.h>
00056 #include <ipxe/settings.h>
00057 #include <ipxe/uuid.h>
00058 #include <ipxe/crypto.h>
00059 #include <ipxe/drbg.h>
00060 #include <ipxe/rbg.h>
00061 
00062 /** The RBG */
00063 struct random_bit_generator rbg;
00064 
00065 /**
00066  * Start up RBG
00067  *
00068  * @ret rc              Return status code
00069  *
00070  * This is the RBG_Startup function defined in ANS X9.82 Part 4 (April
00071  * 2011 Draft) Section 9.1.2.2.
00072  */
00073 static int rbg_startup ( void ) {
00074         union uuid uuid;
00075         int len;
00076         int rc;
00077 
00078         /* Try to obtain system UUID for use as personalisation
00079          * string, in accordance with ANS X9.82 Part 3-2007 Section
00080          * 8.5.2.  If no UUID is available, proceed without a
00081          * personalisation string.
00082          */
00083         if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) {
00084                 rc = len;
00085                 DBGC ( &rbg, "RBG could not fetch personalisation string: "
00086                        "%s\n", strerror ( rc ) );
00087                 len = 0;
00088         }
00089 
00090         /* Instantiate DRBG */
00091         if ( ( rc = drbg_instantiate ( &rbg.state, &uuid, len ) ) != 0 ) {
00092                 DBGC ( &rbg, "RBG could not instantiate DRBG: %s\n",
00093                        strerror ( rc ) );
00094                 return rc;
00095         }
00096 
00097         return 0;
00098 }
00099 
00100 /**
00101  * Shut down RBG
00102  *
00103  */
00104 static void rbg_shutdown ( void ) {
00105 
00106         /* Uninstantiate DRBG */
00107         drbg_uninstantiate ( &rbg.state );
00108 }
00109 
00110 /** RBG startup function */
00111 static void rbg_startup_fn ( void ) {
00112 
00113         /* Start up RBG.  There is no way to report an error at this
00114          * stage, but a failed startup will result in an invalid DRBG
00115          * that refuses to generate bits.
00116          */
00117         rbg_startup();
00118 }
00119 
00120 /** RBG shutdown function */
00121 static void rbg_shutdown_fn ( int booting __unused ) {
00122 
00123         /* Shut down RBG */
00124         rbg_shutdown();
00125 }
00126 
00127 /** RBG startup table entry */
00128 struct startup_fn startup_rbg __startup_fn ( STARTUP_NORMAL ) = {
00129         .startup = rbg_startup_fn,
00130         .shutdown = rbg_shutdown_fn,
00131 };